Project
Loading...
Searching...
No Matches
Detector.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14#include "TPCSimulation/Point.h"
17
18#include "DetectorsBase/Stack.h"
20
21#include "FairVolume.h" // for FairVolume
22
23#include "TVirtualMC.h" // for TVirtualMC, gMC
24
25#include <cstddef> // for NULL
26
27#include "FairGeoVolume.h"
28#include "FairGeoNode.h"
29#include "FairGeoLoader.h"
30#include "FairGeoInterface.h"
31#include "FairRun.h"
32#include "FairRuntimeDb.h"
33#include <fairlogger/Logger.h>
34#include "FairRootManager.h"
35
36#include "TSystem.h"
37#include "TVirtualMC.h"
38
39#include "TFile.h"
40
41// geo stuff
42#include "TGeoManager.h"
43#include "TGeoVolume.h"
44#include "TGeoPcon.h"
45#include "TGeoTube.h"
46#include "TGeoCone.h"
47#include "TGeoPgon.h"
48#include "TGeoTrd1.h"
49#include "TGeoCompositeShape.h"
50#include "TGeoPara.h"
51#include "TGeoPhysicalNode.h"
52#include "TGeoArb8.h"
53#include "TGeoMatrix.h"
54
56
57#include <iostream>
58#include <cmath>
59
60using std::cout;
61using std::endl;
62using std::ifstream;
63using std::ios_base;
64using namespace o2::tpc;
65
66namespace
67{
68// Half-size of the boxes standing in for the half-space cuts of the TPC support structures.
69// Ten times the largest solid any of them is subtracted from, and small compared to the TPC.
70constexpr double kHalfSpaceReach = 100.;
71} // namespace
72
73Detector::Detector(Bool_t active) : o2::base::DetImpl<Detector>("TPC", active), mGeoFileName()
74{
75 for (int i = 0; i < Sector::MAXSECTOR; ++i) {
76 mHitsPerSectorCollection[i] = o2::utils::createSimVector<o2::tpc::HitGroup>(); // new std::vector<o2::tpc::HitGroup>;
77 }
78}
79
80// forward default constructor
81Detector::Detector() : o2::tpc::Detector(kTRUE) {}
82
84 : o2::base::DetImpl<Detector>(rhs),
85 mHitCounter(0),
86 mElectronCounter(0),
87 mStepCounter(0),
88 mGeoFileName(rhs.mGeoFileName)
89{
90 for (int i = 0; i < Sector::MAXSECTOR; ++i) {
91 mHitsPerSectorCollection[i] = o2::utils::createSimVector<o2::tpc::HitGroup>(); // new std::vector<o2::tpc::HitGroup>;new std::vector<o2::tpc::HitGroup>;
92 }
93}
94
96{
97 for (int i = 0; i < Sector::MAXSECTOR; ++i) {
98 // mHitsPerSectorCollection[i]->clear();
99 o2::utils::freeSimVector(mHitsPerSectorCollection[i]);
100 }
101 std::cout << "Produced hits " << mHitCounter << "\n";
102 std::cout << "Produced electrons " << mElectronCounter << "\n";
103 std::cout << "Stepping called " << mStepCounter << "\n";
104}
105
107{
108 // Define the list of sensitive volumes
109 defineSensitiveVolumes();
110}
111
112Bool_t Detector::ProcessHits(FairVolume* vol)
113{
114 mStepCounter++;
115 auto& gasParam = ParameterGas::Instance();
116 auto& detParam = ParameterDetector::Instance();
117 const Int_t kMaxDistRef = 15; // maximal difference between 2 stored references - the parameter should be 15 cm as default
118 static Double_t lastReferenceR = 0; // keeps last reference point in radius (cm)
119
120 /* This method is called from the MC stepping for the sensitive volume only */
121 // LOG(info) << "tpc::ProcessHits";
122 const double trackCharge = fMC->TrackCharge();
123 if (static_cast<int>(trackCharge) == 0) {
124
125 // set a very large step size for neutral particles
126 fMC->SetMaxStep(1.e10);
127 return kFALSE; // take only charged particles
128 }
129
130 // ===| SET THE LENGTH OF THE NEXT ENERGY LOSS STEP |=========================
131 // (We do this first so we can skip out of the method in the following
132 // Eloss->Ionization part.)
133 //
134 // In all cases we have multiple collisions and we use 2mm (+ some
135 // random shift to avoid binning effects), which was tuned for GEANT4, see
136 // https://indico.cern.ch/event/316891/contributions/732168/
137
138 const double rnd = fMC->GetRandom()->Rndm();
139 fMC->SetMaxStep(0.2 + (2. * rnd - 1.) * 0.05); // 2 mm +- rndm*0.5mm step
140
141 // ===| check active sector |=================================================
142 //
143 // Get the sector ID and check if the sector is active
144 static thread_local TLorentzVector position;
145 fMC->TrackPosition(position);
146 // for processing reasons in the digitizer, the sectors are shifted by -10deg, so sector 0 will be
147 // from -10 - +10 deg instead of 0-20 and so on
148 const int sectorID = static_cast<int>(Sector::ToShiftedSector(position.X(), position.Y(), position.Z()));
149 // const int sectorID = static_cast<int>(Sector::ToSector(position.X(), position.Y(), position.Z()));
150 // TODO: Temporary hack to process only one sector
151 // if (sectorID != 0) return kFALSE;
152
153 // ---| momentum and beta gamma |---
154 static TLorentzVector momentum; // static to make avoid creation/deletion of this expensive object
155 fMC->TrackMomentum(momentum);
156
157 const float time = fMC->TrackTime() * 1.0e9;
158 const int trackID = fMC->GetStack()->GetCurrentTrackNumber();
159 const int detID = vol->getMCid();
160 o2::data::Stack* stack = (o2::data::Stack*)fMC->GetStack();
161 if (fMC->IsTrackEntering() || fMC->IsTrackExiting()) {
162 stack->addTrackReference(o2::TrackReference(position.X(), position.Y(), position.Z(), momentum.X(), momentum.Y(),
163 momentum.Z(), fMC->TrackLength(), time, trackID, GetDetId()));
164 lastReferenceR = fMC->TrackLength();
165 }
166 if (TMath::Abs(lastReferenceR - fMC->TrackLength()) > kMaxDistRef) {
167 stack->addTrackReference(o2::TrackReference(position.X(), position.Y(), position.Z(), momentum.X(), momentum.Y(),
168 momentum.Z(), fMC->TrackLength(), time, trackID, GetDetId()));
169 lastReferenceR = fMC->TrackLength();
170 }
171
172 // ---| remove clusters between the IFC and the FC strips |---
173 // those should not enter the active readout area
174 // do coarse selection before, to limit number of transformations
175 if (detParam.ExcludeFCGap) {
176 const auto rCluster = std::sqrt(position.X() * position.X() + position.Y() * position.Y());
177 const float rodRin = 81.5 + 2.2; // radial position of the inner field cage rods + radial size of the field cage rods
178 const float rodRout = 254.25 + 2.2; // radial position of the outer field cage rods + radial size of the field cage rods
179 const float fcLxIn = 82.428409; // position of the inner FC strips in local x = cos(10 deg) * rodRin;
180 const float fcLxOut = 252.55395; // position of the outer FC strips in local x = cos(10 deg) * rodRin;
181
182 if (rCluster < rodRin || rCluster > fcLxOut) {
183 const int sectorIDnonShift = static_cast<int>(Sector::ToSector(position.X(), position.Y(), position.Z()));
184 const double alpha = TMath::DegToRad() * (10. + sectorIDnonShift * 20.);
185 const double cs = std::cos(-alpha), sn = std::sin(-alpha);
186 const auto localX = position.X() * cs - position.Y() * sn;
187 // fine cut
188 if (localX < fcLxIn || localX > fcLxOut) {
189 return kFALSE;
190 }
191 }
192 }
193
194 // ===| CONVERT THE ENERGY LOSS TO IONIZATION ELECTRONS |=====================
195 //
196 // The energy loss is implemented directly below and taken GEANT3,
197 // ILOSS model 5 (in gfluct.F), which gives
198 // the energy loss in a single collision (NA49 model).
199 // TODO: Add discussion about drawback
200
201 Int_t numberOfElectrons = 0;
202 // I.H. - the type expected in addHit is short
203
204 // ---| Stepsize in cm |---
205 const double stepSize = fMC->TrackStep();
206
207 double betaGamma = momentum.P() / fMC->TrackMass();
208 betaGamma = TMath::Max(betaGamma, 7.e-3); // protection against too small bg
209
210 // ---| number of primary ionisations per cm |---
211 const double primaryElectronsPerCM =
212 gasParam.Nprim * BetheBlochAleph(static_cast<float>(betaGamma), gasParam.BetheBlochParam[0],
213 gasParam.BetheBlochParam[1], gasParam.BetheBlochParam[2],
214 gasParam.BetheBlochParam[3], gasParam.BetheBlochParam[4]);
215
216 // ---| mean number of collisions and random for this event |---
217 const double meanNcoll = stepSize * trackCharge * trackCharge * primaryElectronsPerCM;
218 const int nColl = static_cast<int>(fMC->GetRandom()->Poisson(meanNcoll));
219
220 // Variables needed to generate random powerlaw distributed energy loss
221 const double alpha_p1 = 1. - gasParam.Exp; // NA49/G3 value
222 const double oneOverAlpha_p1 = 1. / alpha_p1;
223 const double eMin = gasParam.Ipot;
224 const double eMax = gasParam.Eend;
225 const double kMin = TMath::Power(eMin, alpha_p1);
226 const double kMax = TMath::Power(eMax, alpha_p1);
227 const double wIon = gasParam.Wion;
228
229 for (Int_t n = 0; n < nColl; n++) {
230 // Use GEANT3 / NA49 expression:
231 // P(eDep) ~ k * edep^-gasParam.getExp()
232 // eMin(~I) < eDep < eMax(300 electrons)
233 // k fixed so that Int_Emin^EMax P(Edep) = 1.
234 const double rndm = fMC->GetRandom()->Rndm();
235 const double eDep = TMath::Power((kMax - kMin) * rndm + kMin, oneOverAlpha_p1);
236 int nel_step = static_cast<int>(((eDep - eMin) / wIon) + 1);
237 nel_step = TMath::Min(nel_step, gasParam.MaxElePerStep); // 300 electrons corresponds to 10 keV
238 numberOfElectrons += nel_step;
239 }
240
241 // LOG(info) << "tpc::AddHit" << FairLogger::endl << "Eloss: "
242 //<< fMC->Edep() << ", Nelectrons: "
243 //<< numberOfElectrons;
244
245 if (numberOfElectrons <= 0) { // Could maybe be smaller than 0 due to the Gamma function
246 return kFALSE;
247 }
248
249 // ADD HIT
250 static thread_local int oldTrackId = trackID;
251 static thread_local int oldDetId = detID;
252 static thread_local int groupCounter = 0;
253 static thread_local int oldSectorId = sectorID;
254
255 // a new group is starting -> put it into the container
256 static thread_local HitGroup* currentgroup = nullptr;
257 if (groupCounter == 0) {
258 mHitsPerSectorCollection[sectorID]->emplace_back(trackID);
259 currentgroup = &(mHitsPerSectorCollection[sectorID]->back());
260 }
261 if (trackID == oldTrackId && oldSectorId == sectorID) {
262 groupCounter++;
263 mHitCounter++;
264 mElectronCounter += numberOfElectrons;
265 currentgroup->addHit(position.X(), position.Y(), position.Z(), time, numberOfElectrons);
266
267 // add last buffered hit, which was not yet added to the currentgroup
268 if (mHitLast.GetEnergyLoss() >= 0) {
269 currentgroup->addHit(mHitLast.GetX(), mHitLast.GetY(), mHitLast.GetZ(), mHitLast.GetTime(), mHitLast.GetEnergyLoss());
270 mHitLast.mELoss = -1;
271 groupCounter++;
272 mHitCounter++;
273 mElectronCounter += mHitLast.GetEnergyLoss();
274 }
275 }
276 // finish group
277 else {
278 oldTrackId = trackID;
279 oldSectorId = sectorID;
280 groupCounter = 0;
281
282 // buffer this hit, otherwise it wouldnt be stored in the HitGroup
283 mHitLast = ElementalHit(position.X(), position.Y(), position.Z(), time, numberOfElectrons);
284 }
285
286 // LOG(info) << "tpc::AddHit" << FairLogger::endl
287 //<< " -- " << trackNumberID <<"," << volumeID << " " << vol->GetName()
288 //<< ", Pos: (" << position.X() << ", " << position.Y() <<", "<< position.Z()<< ", " << r << ") "
289 //<< ", Mom: (" << momentum.Px() << ", " << momentum.Py() << ", " << momentum.Pz() << ") "
290 //<< " Time: "<< time <<", Len: " << length << ", Nelectrons: " <<
291 // numberOfElectrons;
292 // I.H. - the code above does not compile if uncommented
293
294 // Increment number of Detector det points in TParticle
295 stack->addHit(GetDetId());
296
297 return kTRUE;
298}
299
301{
302 if (!o2::utils::ShmManager::Instance().isOperational()) {
303 for (int i = 0; i < Sector::MAXSECTOR; ++i) {
304 mHitsPerSectorCollection[i]->clear();
305 }
306 }
307}
308
310{
317 auto* mgr = FairRootManager::Instance();
318 for (int i = 0; i < Sector::MAXSECTOR; ++i) {
319 mgr->RegisterAny(getHitBranchNames(i).c_str(), mHitsPerSectorCollection[i], kTRUE);
320 }
321}
322
324{
325 for (int i = 0; i < Sector::MAXSECTOR; ++i) {
326 // cout << "CLEARED (reset) hitsCollection " << i << " " << mHitsPerSectorCollection[i] << endl;
327 mHitsPerSectorCollection[i]->clear();
328 }
329}
330
332{
333 // Create the detector materials
334 CreateMaterials();
335
336 // Load geometry
337 // LoadGeometryFromFile();
338 ConstructTPCGeometry();
339}
340
341void Detector::CreateMaterials()
342{
343 //-----------------------------------------------
344 // Create Materials for for TPC simulations
345 //-----------------------------------------------
346
347 //-----------------------------------------------------------------
348 // Origin: Marek Kowalski IFJ, Krakow, Marek.Kowalski@ifj.edu.pl
349 //-----------------------------------------------------------------
350
351 const auto& gasParam = ParameterGas::Instance();
352
353 Int_t iSXFLD = 2;
354 Float_t sXMGMX = 10.0;
355 // init the field tracking params
357
358 Float_t amat[7]; // atomic numbers
359 Float_t zmat[7]; // z
360 Float_t wmat[7]; // proportions
361
362 Float_t density;
363
364 // TODO: load pressure and temperature values from CCDB
365 const Double_t pressure = gasParam.Pressure; // in mbar
366 const Double_t temperature = gasParam.Temperature + 273.15; // in K
367
368 // densities were taken for these values
369 const Double_t t1 = 293.15; // 20°C in K
370 const Double_t p1 = 1013.25; // 1 atm in mbars
371
372 // sanity check - temperature between 10 and 30 deg, pressure between 800 and 1200 mbar
373 Double_t ptCorr = 1.;
374 if (TMath::Abs(temperature - 293.15) > 10. || TMath::Abs(pressure - 1000.) > 200.) {
375 ptCorr = 1.;
376 } else {
377 ptCorr = (pressure * t1) / (p1 * temperature);
378 }
379 LOG(info) << "Setting gas density correction to: " << ptCorr;
380
381 //***************** Gases *************************
382
383 //--------------------------------------------------------------
384 // gases - air and CO2
385 //--------------------------------------------------------------
386
387 // CO2
388
389 amat[0] = 12.011;
390 amat[1] = 15.9994;
391
392 zmat[0] = 6.;
393 zmat[1] = 8.;
394
395 wmat[0] = 0.2729;
396 wmat[1] = 0.7271;
397
398 density = 1.842e-3;
399
400 o2::base::Detector::Mixture(10, "CO2", amat, zmat, density * ptCorr, 2, wmat);
401 //
402 // Air
403 //
404 amat[0] = 15.9994;
405 amat[1] = 14.007;
406 //
407 zmat[0] = 8.;
408 zmat[1] = 7.;
409 //
410 wmat[0] = 0.233;
411 wmat[1] = 0.767;
412 //
413 density = 0.001205;
414
415 o2::base::Detector::Mixture(11, "Air", amat, zmat, density * ptCorr, 2, wmat);
416
417 //----------------------------------------------------------------
418 // drift gases 5 mixtures, 5 materials
419 //----------------------------------------------------------------
420 //
421 // Drift gases 1 - nonsensitive, 2 - sensitive, 3 - for Kr
422 // Composition by % of volume, values at 20deg and 1 atm.
423 //
424 // get the geometry title - defined in Config.C
425 //
426 //--------------------------------------------------------------
427 // predefined gases, composition taken from param file
428 //--------------------------------------------------------------
429 TString names[6] = {"Ne", "Ar", "CO2", "N", "CF4", "CH4"};
430 TString gname;
431
433 // container in the future
434 Float_t comp[6] = {90. / 105., 0., 10. / 105., 5. / 105., 0., 0.};
435 // indices:
436 // 0-Ne, 1-Ar, 2-CO2, 3-N, 4-CF4, 5-CH4
437 //
438 // elements' masses
439 //
440 amat[0] = 20.18; // Ne
441 amat[1] = 39.95; // Ar
442 amat[2] = 12.011; // C
443 amat[3] = 15.9994; // O
444 amat[4] = 14.007; // N
445 amat[5] = 18.998; // F
446 amat[6] = 1.; // H
447 //
448 // elements' atomic numbers
449 //
450 //
451 zmat[0] = 10.; // Ne
452 zmat[1] = 18.; // Ar
453 zmat[2] = 6.; // C
454 zmat[3] = 8.; // O
455 zmat[4] = 7.; // N
456 zmat[5] = 9.; // F
457 zmat[6] = 1.; // H
458 //
459 // Mol masses
460 //
461 Float_t wmol[6];
462 wmol[0] = 20.18; // Ne
463 wmol[1] = 39.948; // Ar
464 wmol[2] = 44.0098; // CO2
465 wmol[3] = 2. * 14.0067; // N2
466 wmol[4] = 88.0046; // CF4
467 wmol[5] = 16.011; // CH4
468 //
469 Float_t wtot = 0.; // total mass of the mixture
470 for (Int_t i = 0; i < 6; i++) {
471 wtot += *(comp + i) * wmol[i];
472 }
473 wmat[0] = comp[0] * amat[0] / wtot; // Ne
474 wmat[1] = comp[1] * amat[1] / wtot; // Ar
475 wmat[2] = (comp[2] * amat[2] + comp[4] * amat[2] + comp[5] * amat[2]) / wtot; // C
476 wmat[3] = comp[2] * amat[3] * 2. / wtot; // O
477 wmat[4] = comp[3] * amat[4] * 2. / wtot; // N
478 wmat[5] = comp[4] * amat[5] * 4. / wtot; // F
479 wmat[6] = comp[5] * amat[6] * 4. / wtot; // H
480 //
481 // densities (NTP)
482 //
483 Float_t dens[6] = {0.839e-3, 1.661e-3, 1.842e-3, 1.165e-3, 3.466e-3, 0.668e-3};
484 //
485 density = 0.;
486 for (Int_t i = 0; i < 6; i++) {
487 density += comp[i] * dens[i];
488 }
489 //
490 // names
491 //
492 Int_t cnt = 0;
493 for (Int_t i = 0; i < 6; i++) {
494 if (comp[i]) {
495 if (cnt) {
496 gname += "-";
497 }
498 gname += names[i];
499 cnt++;
500 }
501 }
502 TString gname1, gname2, gname3;
503 gname1 = gname + "-1";
504 gname2 = gname + "-2";
505 gname3 = gname + "-3";
506 //
507 // take only elements with nonzero weights
508 //
509 Float_t amat1[6], zmat1[6], wmat1[6];
510 cnt = 0;
511 for (Int_t i = 0; i < 7; i++) {
512 if (wmat[i]) {
513 zmat1[cnt] = zmat[i];
514 amat1[cnt] = amat[i];
515 wmat1[cnt] = wmat[i];
516 cnt++;
517 }
518 }
519
520 //
521 o2::base::Detector::Mixture(12, gname1.Data(), amat1, zmat1, density * ptCorr, cnt, wmat1); // nonsensitive
522 o2::base::Detector::Mixture(13, gname2.Data(), amat1, zmat1, density * ptCorr, cnt, wmat1); // sensitive
523 o2::base::Detector::Mixture(40, gname3.Data(), amat1, zmat1, density * ptCorr, cnt, wmat1); // sensitive Kr
524
525 //----------------------------------------------------------------------
526 // solid materials
527 //----------------------------------------------------------------------
528
529 // Kevlar C14H22O2N2
530
531 amat[0] = 12.011;
532 amat[1] = 1.;
533 amat[2] = 15.999;
534 amat[3] = 14.006;
535
536 zmat[0] = 6.;
537 zmat[1] = 1.;
538 zmat[2] = 8.;
539 zmat[3] = 7.;
540
541 wmat[0] = 14.;
542 wmat[1] = 22.;
543 wmat[2] = 2.;
544 wmat[3] = 2.;
545
546 density = 1.45;
547
548 o2::base::Detector::Mixture(14, "Kevlar", amat, zmat, density, -4, wmat);
549
550 // NOMEX
551
552 amat[0] = 12.011;
553 amat[1] = 1.;
554 amat[2] = 15.999;
555 amat[3] = 14.006;
556
557 zmat[0] = 6.;
558 zmat[1] = 1.;
559 zmat[2] = 8.;
560 zmat[3] = 7.;
561
562 wmat[0] = 14.;
563 wmat[1] = 22.;
564 wmat[2] = 2.;
565 wmat[3] = 2.;
566
567 density = 0.029;
568
569 o2::base::Detector::Mixture(15, "NOMEX", amat, zmat, density, -4, wmat);
570
571 // Makrolon C16H18O3
572
573 amat[0] = 12.011;
574 amat[1] = 1.;
575 amat[2] = 15.999;
576
577 zmat[0] = 6.;
578 zmat[1] = 1.;
579 zmat[2] = 8.;
580
581 wmat[0] = 16.;
582 wmat[1] = 18.;
583 wmat[2] = 3.;
584
585 density = 1.2;
586
587 o2::base::Detector::Mixture(16, "Makrolon", amat, zmat, density, -3, wmat);
588
589 // Tedlar C2H3F
590
591 amat[0] = 12.011;
592 amat[1] = 1.;
593 amat[2] = 18.998;
594
595 zmat[0] = 6.;
596 zmat[1] = 1.;
597 zmat[2] = 9.;
598
599 wmat[0] = 2.;
600 wmat[1] = 3.;
601 wmat[2] = 1.;
602
603 density = 1.71;
604
605 o2::base::Detector::Mixture(17, "Tedlar", amat, zmat, density, -3, wmat);
606
607 // Mylar C5H4O2
608
609 amat[0] = 12.011;
610 amat[1] = 1.;
611 amat[2] = 15.9994;
612
613 zmat[0] = 6.;
614 zmat[1] = 1.;
615 zmat[2] = 8.;
616
617 wmat[0] = 5.;
618 wmat[1] = 4.;
619 wmat[2] = 2.;
620
621 density = 1.39;
622
623 o2::base::Detector::Mixture(18, "Mylar", amat, zmat, density, -3, wmat);
624 // material for "prepregs"
625 // Epoxy - C14 H20 O3
626 // Quartz SiO2
627 // Carbon C
628 // prepreg1 60% C-fiber, 40% epoxy (vol)
629 amat[0] = 12.011;
630 amat[1] = 1.;
631 amat[2] = 15.994;
632
633 zmat[0] = 6.;
634 zmat[1] = 1.;
635 zmat[2] = 8.;
636
637 wmat[0] = 0.923;
638 wmat[1] = 0.023;
639 wmat[2] = 0.054;
640
641 density = 1.859;
642
643 o2::base::Detector::Mixture(19, "Prepreg1", amat, zmat, density, 3, wmat);
644
645 // prepreg2 60% glass-fiber, 40% epoxy
646
647 amat[0] = 12.01;
648 amat[1] = 1.;
649 amat[2] = 15.994;
650 amat[3] = 28.086;
651
652 zmat[0] = 6.;
653 zmat[1] = 1.;
654 zmat[2] = 8.;
655 zmat[3] = 14.;
656
657 wmat[0] = 0.194;
658 wmat[1] = 0.023;
659 wmat[2] = 0.443;
660 wmat[3] = 0.34;
661
662 density = 1.82;
663
664 o2::base::Detector::Mixture(20, "Prepreg2", amat, zmat, density, 4, wmat);
665
666 // prepreg3 50% glass-fiber, 50% epoxy
667
668 amat[0] = 12.01;
669 amat[1] = 1.;
670 amat[2] = 15.994;
671 amat[3] = 28.086;
672
673 zmat[0] = 6.;
674 zmat[1] = 1.;
675 zmat[2] = 8.;
676 zmat[3] = 14.;
677
678 wmat[0] = 0.257;
679 wmat[1] = 0.03;
680 wmat[2] = 0.412;
681 wmat[3] = 0.3;
682
683 density = 1.725;
684
685 o2::base::Detector::Mixture(21, "Prepreg3", amat, zmat, density, 4, wmat);
686
687 // G10 60% SiO2 40% epoxy
688
689 amat[0] = 12.01;
690 amat[1] = 1.;
691 amat[2] = 15.994;
692 amat[3] = 28.086;
693
694 zmat[0] = 6.;
695 zmat[1] = 1.;
696 zmat[2] = 8.;
697 zmat[3] = 14.;
698
699 wmat[0] = 0.194;
700 wmat[1] = 0.023;
701 wmat[2] = 0.443;
702 wmat[3] = 0.340;
703
704 density = 1.7;
705
706 o2::base::Detector::Mixture(22, "G10", amat, zmat, density, 4, wmat);
707
708 // Al
709
710 amat[0] = 26.98;
711 zmat[0] = 13.;
712
713 density = 2.7;
714
715 o2::base::Detector::Material(23, "Al", amat[0], zmat[0], density, 999., 999.);
716
717 // Si (for electronics
718
719 amat[0] = 28.086;
720 zmat[0] = 14.;
721
722 density = 2.33;
723
724 o2::base::Detector::Material(24, "Si", amat[0], zmat[0], density, 999., 999.);
725
726 // Cu
727
728 amat[0] = 63.546;
729 zmat[0] = 29.;
730
731 density = 8.96;
732
733 o2::base::Detector::Material(25, "Cu", amat[0], zmat[0], density, 999., 999.);
734
735 // brass
736
737 amat[0] = 63.546;
738 zmat[0] = 29.;
739 //
740 amat[1] = 65.409;
741 zmat[1] = 30.;
742 //
743 wmat[0] = 0.6;
744 wmat[1] = 0.4;
745
746 //
747 density = 8.23;
748
749 //
750 o2::base::Detector::Mixture(33, "Brass", amat, zmat, density, 2, wmat);
751
752 // Epoxy - C14 H20 O3
753
754 amat[0] = 12.011;
755 amat[1] = 1.;
756 amat[2] = 15.9994;
757
758 zmat[0] = 6.;
759 zmat[1] = 1.;
760 zmat[2] = 8.;
761
762 wmat[0] = 14.;
763 wmat[1] = 20.;
764 wmat[2] = 3.;
765
766 density = 1.25;
767
768 o2::base::Detector::Mixture(26, "Epoxy", amat, zmat, density, -3, wmat);
769
770 // Epoxy - C14 H20 O3 for glue
771
772 amat[0] = 12.011;
773 amat[1] = 1.;
774 amat[2] = 15.9994;
775
776 zmat[0] = 6.;
777 zmat[1] = 1.;
778 zmat[2] = 8.;
779
780 wmat[0] = 14.;
781 wmat[1] = 20.;
782 wmat[2] = 3.;
783
784 density = 1.25;
785
786 density *= 1.25;
787
788 o2::base::Detector::Mixture(35, "Epoxy1", amat, zmat, density, -3, wmat);
789 //
790 // epoxy film - 90% epoxy, 10% glass fiber
791 //
792 amat[0] = 12.01;
793 amat[1] = 1.;
794 amat[2] = 15.994;
795 amat[3] = 28.086;
796
797 zmat[0] = 6.;
798 zmat[1] = 1.;
799 zmat[2] = 8.;
800 zmat[3] = 14.;
801
802 wmat[0] = 0.596;
803 wmat[1] = 0.071;
804 wmat[2] = 0.257;
805 wmat[3] = 0.076;
806
807 density = 1.345;
808
809 o2::base::Detector::Mixture(34, "Epoxy-film", amat, zmat, density, 4, wmat);
810
811 // Plexiglas C5H8O2
812
813 amat[0] = 12.011;
814 amat[1] = 1.;
815 amat[2] = 15.9994;
816
817 zmat[0] = 6.;
818 zmat[1] = 1.;
819 zmat[2] = 8.;
820
821 wmat[0] = 5.;
822 wmat[1] = 8.;
823 wmat[2] = 2.;
824
825 density = 1.18;
826
827 o2::base::Detector::Mixture(27, "Plexiglas", amat, zmat, density, -3, wmat);
828
829 // Carbon
830
831 amat[0] = 12.011;
832 zmat[0] = 6.;
833 density = 2.265;
834
835 o2::base::Detector::Material(28, "C", amat[0], zmat[0], density, 999., 999.);
836
837 // Fe (steel for the inner heat screen)
838
839 amat[0] = 55.845;
840
841 zmat[0] = 26.;
842
843 density = 7.87;
844
845 o2::base::Detector::Material(29, "Fe", amat[0], zmat[0], density, 999., 999.);
846 //
847 // Peek - (C6H4-O-OC6H4-O-C6H4-CO)n
848 amat[0] = 12.011;
849 amat[1] = 1.;
850 amat[2] = 15.9994;
851
852 zmat[0] = 6.;
853 zmat[1] = 1.;
854 zmat[2] = 8.;
855
856 wmat[0] = 19.;
857 wmat[1] = 12.;
858 wmat[2] = 3.;
859 //
860 density = 1.3;
861 //
862 o2::base::Detector::Mixture(30, "Peek", amat, zmat, density, -3, wmat);
863 //
864 // Ceramics - Al2O3
865 //
866 amat[0] = 26.98;
867 amat[1] = 15.9994;
868
869 zmat[0] = 13.;
870 zmat[1] = 8.;
871
872 wmat[0] = 2.;
873 wmat[1] = 3.;
874
875 density = 3.97;
876
877 o2::base::Detector::Mixture(31, "Alumina", amat, zmat, density, -2, wmat);
878 //
879 // Ceramics for resistors
880 //
881 amat[0] = 26.98;
882 amat[1] = 15.9994;
883
884 zmat[0] = 13.;
885 zmat[1] = 8.;
886
887 wmat[0] = 2.;
888 wmat[1] = 3.;
889
890 density = 3.97;
891 //
892 density *= 1.25;
893
894 o2::base::Detector::Mixture(36, "Alumina1", amat, zmat, density, -2, wmat);
895 //
896 // liquids
897 //
898
899 // water
900
901 amat[0] = 1.;
902 amat[1] = 15.9994;
903
904 zmat[0] = 1.;
905 zmat[1] = 8.;
906
907 wmat[0] = 2.;
908 wmat[1] = 1.;
909
910 density = 1.;
911
912 o2::base::Detector::Mixture(32, "Water", amat, zmat, density, -2, wmat);
913
914 //----------------------------------------------------------
915 // tracking media for gases
916 //----------------------------------------------------------
917
918 o2::base::Detector::Medium(kAir, "Air", 11, 0, iSXFLD, sXMGMX, 10., 999., .1, .01, .1);
919 o2::base::Detector::Medium(kDriftGas1, "DriftGas1", 12, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
920 o2::base::Detector::Medium(kDriftGas2, "DriftGas2", 13, 1, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
921 o2::base::Detector::Medium(kCO2, "CO2", 10, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
922 o2::base::Detector::Medium(kDriftGas3, "DriftGas3", 40, 1, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
923 //-----------------------------------------------------------
924 // tracking media for solids
925 //-----------------------------------------------------------
926
927 o2::base::Detector::Medium(kAl, "Al", 23, 0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
928 o2::base::Detector::Medium(kKevlar, "Kevlar", 14, 0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
929 o2::base::Detector::Medium(kNomex, "Nomex", 15, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
930 o2::base::Detector::Medium(kMakrolon, "Makrolon", 16, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
931 o2::base::Detector::Medium(kMylar, "Mylar", 18, 0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
932 o2::base::Detector::Medium(kTedlar, "Tedlar", 17, 0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
933 //
934 o2::base::Detector::Medium(kPrepreg1, "Prepreg1", 19, 0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
935 o2::base::Detector::Medium(kPrepreg2, "Prepreg2", 20, 0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
936 o2::base::Detector::Medium(kPrepreg3, "Prepreg3", 21, 0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
937 o2::base::Detector::Medium(kEpoxy, "Epoxy", 26, 0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
938
939 o2::base::Detector::Medium(kCu, "Cu", 25, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
940 o2::base::Detector::Medium(kSi, "Si", 24, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
941 o2::base::Detector::Medium(kG10, "G10", 22, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
942 o2::base::Detector::Medium(kPlexiglas, "Plexiglas", 27, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
943 o2::base::Detector::Medium(kSteel, "Steel", 29, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
944 o2::base::Detector::Medium(kPeek, "Peek", 30, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
945 o2::base::Detector::Medium(kAlumina, "Alumina", 31, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
946 o2::base::Detector::Medium(kWater, "Water", 32, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
947 o2::base::Detector::Medium(kBrass, "Brass", 33, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
948 o2::base::Detector::Medium(kEpoxyfm, "Epoxyfm", 34, 0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
949 o2::base::Detector::Medium(kEpoxy1, "Epoxy1", 35, 0, iSXFLD, sXMGMX, 10., 999., .1, .0005, .001);
950 o2::base::Detector::Medium(kAlumina1, "Alumina1", 36, 0, iSXFLD, sXMGMX, 10., 999., .1, .001, .001);
951}
952
953void Detector::ConstructTPCGeometry()
954{
955 //
956 // Create the geometry of Time Projection Chamber version 2
957 //
958 // Begin_Html
959 /*
960 * <img src="picts/AliTPC.gif">
961 */
962 // End_Html
963 // Begin_Html
964 /*
965 * <img src="picts/AliTPCv2Tree.gif">
966 */
967 // End_Html
968
969 //----------------------------------------------------------
970 // This geometry is written using TGeo class
971 // Firstly the shapes are defined, and only then the volumes
972 // What is recognized by the MC are volumes
973 //----------------------------------------------------------
974 //
975 // tpc - this will be the mother volume
976 //
977
978 // if (!mParam) {
979 // LOG(error) << "TPC Parameters not available, cannot create Geometry";
980 // return;
981 // }
982
983 //
984 // here I define a volume TPC
985 // retrive the medium name with "TPC_" as a leading string
986 //
987 auto* tpc = new TGeoPcon(0., 360., 30); // 30 sections
988 //
989 tpc->DefineSection(0, -289.6, 77., 278.);
990 tpc->DefineSection(1, -262.1, 77., 278.);
991 //
992 tpc->DefineSection(2, -262.1, 83.1, 278.);
993 tpc->DefineSection(3, -260., 83.1, 278.);
994 //
995 tpc->DefineSection(4, -260., 70., 278.);
996 tpc->DefineSection(5, -259.6, 70., 278.);
997 //
998 tpc->DefineSection(6, -259.6, 68.1, 278.);
999 tpc->DefineSection(7, -253.6, 68.1, 278.);
1000 //
1001 tpc->DefineSection(8, -253.6, 67.88, 278.); // hs
1002 tpc->DefineSection(9, -74.0, 60.68, 278.); // hs
1003 //
1004 tpc->DefineSection(10, -74.0, 60.1, 278.);
1005 tpc->DefineSection(11, -73.3, 60.1, 278.);
1006 //
1007 tpc->DefineSection(12, -73.3, 56.9, 278.);
1008 tpc->DefineSection(13, -68.5, 56.9, 278.);
1009 //
1010 tpc->DefineSection(14, -68.5, 60., 278.);
1011 tpc->DefineSection(15, -64.7, 60., 278.);
1012 //
1013 tpc->DefineSection(16, -64.7, 56.9, 278.);
1014 tpc->DefineSection(17, 73.3, 56.9, 278.);
1015 //
1016 tpc->DefineSection(18, 73.3, 60.1, 278.);
1017 tpc->DefineSection(19, 74.0, 60.1, 278.);
1018 //
1019 tpc->DefineSection(20, 74.0, 60.68, 278.); // hs
1020 tpc->DefineSection(21, 253.6, 65.38, 278.); // hs
1021 //
1022 tpc->DefineSection(22, 253.6, 65.6, 278.);
1023 tpc->DefineSection(23, 259.6, 65.6, 278.);
1024 //
1025 tpc->DefineSection(24, 259.6, 70.0, 278.);
1026 tpc->DefineSection(25, 260., 70.0, 278.);
1027 //
1028 tpc->DefineSection(26, 260., 83.1, 278.);
1029 tpc->DefineSection(27, 262.1, 83.1, 278.);
1030 //
1031 tpc->DefineSection(28, 262.1, 77., 278);
1032 tpc->DefineSection(29, 289.6, 77., 278.);
1033 //
1034 TGeoMedium* m1 = gGeoManager->GetMedium("TPC_Air");
1035 auto* v1 = new TGeoVolume("TPC_M", tpc, m1);
1036 //
1037 // drift volume - sensitive volume, extended beyond the
1038 // endcaps, because of the alignment
1039 //
1040 auto* dvol = new TGeoPcon(0., 360., 6);
1041 dvol->DefineSection(0, -260., 74.5, 264.4);
1042 dvol->DefineSection(1, -253.6, 74.5, 264.4);
1043 //
1044 dvol->DefineSection(2, -253.6, 76.6774, 258.);
1045 dvol->DefineSection(3, 253.6, 76.6774, 258.);
1046 //
1047 dvol->DefineSection(4, 253.6, 74.5, 264.4);
1048 dvol->DefineSection(5, 260., 74.5, 264.4);
1049 //
1050 TGeoMedium* m5 = gGeoManager->GetMedium("TPC_DriftGas2");
1051 auto* v9 = new TGeoVolume("TPC_Drift", dvol, m5);
1052 //
1053 v1->AddNode(v9, 1);
1054 //
1055 // outer insulator
1056 //
1057 auto* tpco = new TGeoPcon(0., 360., 6); // insulator
1058 //
1059 tpco->DefineSection(0, -256.6, 264.8, 278.);
1060 tpco->DefineSection(1, -253.6, 264.8, 278.);
1061 //
1062 tpco->DefineSection(2, -253.6, 258., 278.);
1063 tpco->DefineSection(3, 250.6, 258., 278.);
1064 //
1065 tpco->DefineSection(4, 250.6, 258., 275.5);
1066 tpco->DefineSection(5, 253.6, 258., 275.5);
1067 //
1068 TGeoMedium* m2 = gGeoManager->GetMedium("TPC_CO2");
1069 auto* v2 = new TGeoVolume("TPC_OI", tpco, m2);
1070 //
1071 TGeoRotation* segrot; // segment rotations
1072 //
1073 // outer containment vessel
1074 //
1075 auto* tocv = new TGeoPcon(0., 360., 6); // containment vessel
1076 //
1077 tocv->DefineSection(0, -256.6, 264.8, 278.);
1078 tocv->DefineSection(1, -253.6, 264.8, 278.);
1079 //
1080 tocv->DefineSection(2, -253.6, 274.8124, 278.);
1081 tocv->DefineSection(3, 247.6, 274.8124, 278.);
1082 //
1083 tocv->DefineSection(4, 247.6, 270.4, 278.);
1084 tocv->DefineSection(5, 250.6, 270.4, 278.);
1085 //
1086 TGeoMedium* m3 = gGeoManager->GetMedium("TPC_Al");
1087 auto* v3 = new TGeoVolume("TPC_OCV", tocv, m3);
1088 //
1089 auto* to1 = new TGeoTubeSeg(274.8174, 277.995, 252.1, 0., 59.9); // epoxy
1090 auto* to2 = new TGeoTubeSeg(274.8274, 277.985, 252.1, 0., 59.9); // tedlar
1091 auto* to3 = new TGeoTubeSeg(274.8312, 277.9812, 252.1, 0., 59.9); // prepreg2
1092 auto* to4 = new TGeoTubeSeg(274.9062, 277.9062, 252.1, 0., 59.9); // nomex
1093 auto* tog5 = new TGeoTubeSeg(274.8174, 277.995, 252.1, 59.9, 60.); // epoxy
1094 //
1095 TGeoMedium* sm1 = gGeoManager->GetMedium("TPC_Epoxy");
1096 TGeoMedium* sm2 = gGeoManager->GetMedium("TPC_Tedlar");
1097 TGeoMedium* sm3 = gGeoManager->GetMedium("TPC_Prepreg2");
1098 TGeoMedium* sm4 = gGeoManager->GetMedium("TPC_Nomex");
1099 //
1100 TGeoMedium* smep = gGeoManager->GetMedium("TPC_Epoxy1");
1101 //
1102 auto* tov1 = new TGeoVolume("TPC_OCV1", to1, sm1);
1103 auto* tov2 = new TGeoVolume("TPC_OCV2", to2, sm2);
1104 auto* tov3 = new TGeoVolume("TPC_OCV3", to3, sm3);
1105 auto* tov4 = new TGeoVolume("TPC_OCV4", to4, sm4);
1106 auto* togv5 = new TGeoVolume("TPC_OCVG5", tog5, sm1);
1107 //
1108 TGeoMedium* mhs = gGeoManager->GetMedium("TPC_Steel");
1109 TGeoMedium* m12 = gGeoManager->GetMedium("TPC_Water");
1110 //-------------------------------------------------------
1111 // Tpc Outer Field Cage
1112 // daughters - composite (sandwich)
1113 //-------------------------------------------------------
1114
1115 auto* tofc = new TGeoPcon(0., 360., 6);
1116 //
1117 tofc->DefineSection(0, -253.6, 258., 269.6);
1118 tofc->DefineSection(1, -250.6, 258., 269.6);
1119 //
1120 tofc->DefineSection(2, -250.6, 258., 260.0676);
1121 tofc->DefineSection(3, 250.6, 258., 260.0676);
1122 //
1123 tofc->DefineSection(4, 250.6, 258., 275.5);
1124 tofc->DefineSection(5, 253.6, 258., 275.5);
1125 //
1126 auto* v4 = new TGeoVolume("TPC_TOFC", tofc, m3);
1127 // sandwich
1128 auto* tf1 = new TGeoTubeSeg(258.0, 260.0676, 252.1, 0., 59.9); // tedlar
1129 auto* tf2 = new TGeoTubeSeg(258.0038, 260.0638, 252.1, 0., 59.9); // prepreg3
1130 auto* tf3 = new TGeoTubeSeg(258.0338, 260.0338, 252.1, 0., 59.9); // nomex
1131 auto* tfg4 = new TGeoTubeSeg(258.0, 260.0676, 252.1, 59.9, 60.); // epoxy glue
1132 //
1133 TGeoMedium* sm5 = gGeoManager->GetMedium("TPC_Prepreg3");
1134 //
1135 auto* tf1v = new TGeoVolume("TPC_OFC1", tf1, sm2);
1136 auto* tf2v = new TGeoVolume("TPC_OFC2", tf2, sm5);
1137 auto* tf3v = new TGeoVolume("TPC_OFC3", tf3, sm4);
1138 auto* tfg4v = new TGeoVolume("TPC_OFCG4", tfg4, smep);
1139 //
1140 // outer part - positioning
1141 //
1142 tov1->AddNode(tov2, 1);
1143 tov2->AddNode(tov3, 1);
1144 tov3->AddNode(tov4, 1); // ocv
1145 //
1146 tf1v->AddNode(tf2v, 1);
1147 tf2v->AddNode(tf3v, 1); // ofc
1148 //
1149 auto* t200 = new TGeoVolumeAssembly("TPC_OCVSEG");
1150 auto* t300 = new TGeoVolumeAssembly("TPC_OFCSEG");
1151 //
1152 // assembly OCV and OFC
1153 //
1154 // 1st - no rotation
1155 t200->AddNode(tov1, 1);
1156 t200->AddNode(togv5, 1);
1157 t300->AddNode(tf1v, 1);
1158 t300->AddNode(tfg4v, 1);
1159 // 2nd - rotation 60 deg
1160 segrot = new TGeoRotation();
1161 segrot->RotateZ(60.);
1162 t200->AddNode(tov1, 2, segrot);
1163 t200->AddNode(togv5, 2, segrot);
1164 t300->AddNode(tf1v, 2, segrot);
1165 t300->AddNode(tfg4v, 2, segrot);
1166 // 3rd rotation 120 deg
1167 segrot = new TGeoRotation();
1168 segrot->RotateZ(120.);
1169 t200->AddNode(tov1, 3, segrot);
1170 t200->AddNode(togv5, 3, segrot);
1171 t300->AddNode(tf1v, 3, segrot);
1172 t300->AddNode(tfg4v, 3, segrot);
1173 // 4th rotation 180 deg
1174 segrot = new TGeoRotation();
1175 segrot->RotateZ(180.);
1176 t200->AddNode(tov1, 4, segrot);
1177 t200->AddNode(togv5, 4, segrot);
1178 t300->AddNode(tf1v, 4, segrot);
1179 t300->AddNode(tfg4v, 4, segrot);
1180 // 5th rotation 240 deg
1181 segrot = new TGeoRotation();
1182 segrot->RotateZ(240.);
1183 t200->AddNode(tov1, 5, segrot);
1184 t200->AddNode(togv5, 5, segrot);
1185 t300->AddNode(tf1v, 5, segrot);
1186 t300->AddNode(tfg4v, 5, segrot);
1187 // 6th rotation 300 deg
1188 segrot = new TGeoRotation();
1189 segrot->RotateZ(300.);
1190 t200->AddNode(tov1, 6, segrot);
1191 t200->AddNode(togv5, 6, segrot);
1192 t300->AddNode(tf1v, 6, segrot);
1193 t300->AddNode(tfg4v, 6, segrot);
1194 //
1195 v3->AddNode(t200, 1, new TGeoTranslation(0., 0., -1.5));
1196 v4->AddNode(t300, 1);
1197 //
1198 v2->AddNode(v3, 1);
1199 v2->AddNode(v4, 1);
1200 //
1201 v1->AddNode(v2, 1);
1202 //
1203 // Outer field cage guard rings. Inner placed in the drift gas, outer placed in the outer insulator (CO2)
1204 //
1205 auto* ogri = new TGeoTube(257.985, 258., 0.6); // placed in the drift volume
1206 auto* ogro = new TGeoTube(260.0676, 260.0826, 0.6); // placed in the outer insulator
1207 //
1208 auto* ogriv = new TGeoVolume("TPC_OGRI", ogri, m3);
1209 auto* ogrov = new TGeoVolume("TPC_OGRO", ogro, m3);
1210 //
1211 for (Int_t i = 0; i < 24; i++) {
1212 v9->AddNode(ogriv, (i + 1), new TGeoTranslation(0., 0., (i + 1) * 10));
1213 v9->AddNode(ogriv, (i + 25), new TGeoTranslation(0., 0., -(i + 1) * 10));
1214 v2->AddNode(ogrov, (i + 1), new TGeoTranslation(0., 0., (i + 1) * 10));
1215 v2->AddNode(ogrov, (i + 25), new TGeoTranslation(0., 0., -(i + 1) * 10));
1216 }
1217 //--------------------------------------------------------------------
1218 // Tpc Inner INsulator (CO2)
1219 // the cones, the central drum and the inner f.c. sandwich with a piece
1220 // of the flane will be placed in the TPC
1221 //--------------------------------------------------------------------
1222 auto* tpci = new TGeoPcon(0., 360., 4);
1223 //
1224 tpci->DefineSection(0, -253.6, 68.4, 76.6774);
1225 tpci->DefineSection(1, -74.0, 61.2, 76.6774);
1226 //
1227 tpci->DefineSection(2, 74.0, 61.2, 76.6774);
1228 //
1229 tpci->DefineSection(3, 253.6, 65.9, 76.6774);
1230 //
1231 auto* v5 = new TGeoVolume("TPC_INI", tpci, m2);
1232 //
1233 // now the inner field cage - only part of flanges (2 copies)
1234 //
1235 auto* tif1 = new TGeoTube(69.9, 76.6774, 1.5);
1236 auto* v6 = new TGeoVolume("TPC_IFC1", tif1, m3);
1237 //
1238 //---------------------------------------------------------
1239 // Tpc Inner Containment vessel - Muon side
1240 //---------------------------------------------------------
1241 auto* tcms = new TGeoPcon(0., 360., 10);
1242 //
1243 tcms->DefineSection(0, -259.1, 68.1, 74.2);
1244 tcms->DefineSection(1, -253.6, 68.1, 74.2);
1245 //
1246 tcms->DefineSection(2, -253.6, 68.1, 68.4);
1247 tcms->DefineSection(3, -74.0, 60.9, 61.2);
1248 //
1249 tcms->DefineSection(4, -74.0, 60.1, 61.2);
1250 tcms->DefineSection(5, -73.3, 60.1, 61.2);
1251 //
1252 tcms->DefineSection(6, -73.3, 56.9, 61.2);
1253 tcms->DefineSection(7, -73.0, 56.9, 61.2);
1254 //
1255 tcms->DefineSection(8, -73.0, 56.9, 58.8);
1256 tcms->DefineSection(9, -71.3, 56.9, 58.8);
1257 //
1258 auto* v7 = new TGeoVolume("TPC_ICVM", tcms, m3);
1259 //------------------------------------------------
1260 // Heat screen muon side
1261 //------------------------------------------------
1262
1263 auto* thsm = new TGeoCone(89.8, 67.88, 68.1, 60.68, 60.9);
1264 auto* thsmw = new TGeoCone(89.8, 67.94, 68.04, 60.74, 60.84);
1265 auto* hvsm = new TGeoVolume("TPC_HSM", thsm, mhs); // steel
1266 auto* hvsmw = new TGeoVolume("TPC_HSMW", thsmw, m12); // water
1267 // assembly heat screen muon
1268 hvsm->AddNode(hvsmw, 1);
1269 //-----------------------------------------------
1270 // inner containment vessel - shaft side
1271 //-----------------------------------------------
1272 auto* tcss = new TGeoPcon(0., 360., 10);
1273 //
1274 tcss->DefineSection(0, 71.3, 56.9, 58.8);
1275 tcss->DefineSection(1, 73.0, 56.9, 58.8);
1276 //
1277 tcss->DefineSection(2, 73.0, 56.9, 61.2);
1278 tcss->DefineSection(3, 73.3, 56.9, 61.2);
1279 //
1280 tcss->DefineSection(4, 73.3, 60.1, 61.2);
1281 tcss->DefineSection(5, 74.0, 60.1, 61.2);
1282 //
1283 tcss->DefineSection(6, 74.0, 60.9, 61.2);
1284 tcss->DefineSection(7, 253.6, 65.6, 65.9);
1285 //
1286 tcss->DefineSection(8, 253.6, 65.6, 74.2);
1287 tcss->DefineSection(9, 258.1, 65.6, 74.2);
1288 //
1289 auto* v8 = new TGeoVolume("TPC_ICVS", tcss, m3);
1290 //-------------------------------------------------
1291 // Heat screen shaft side
1292 //--------------------------------------------------
1293 auto* thss = new TGeoCone(89.8, 60.68, 60.9, 65.38, 65.6);
1294 auto* thssw = new TGeoCone(89.8, 60.74, 60.84, 65.44, 65.54);
1295 auto* hvss = new TGeoVolume("TPC_HSS", thss, mhs); // steel
1296 auto* hvssw = new TGeoVolume("TPC_HSSW", thssw, m12); // water
1297 // assembly heat screen shaft
1298 hvss->AddNode(hvssw, 1);
1299 //-----------------------------------------------
1300 // Inner field cage
1301 // define 4 parts and make an assembly
1302 //-----------------------------------------------
1303 // part1 - Al - 2 copies
1304 auto* t1 = new TGeoTube(76.6774, 78.845, 0.75);
1305 auto* tv1 = new TGeoVolume("TPC_IFC2", t1, m3);
1306 // sandwich - outermost parts - 2 copies
1307 //
1308 // segment outermost
1309 //
1310 auto* t2 = new TGeoTubeSeg(76.6774, 78.845, 74.175, 350., 109.4); // tedlar 38 microns
1311 auto* t3 = new TGeoTubeSeg(76.6812, 78.8412, 74.175, 350., 109.4); // prepreg2 500 microns
1312 auto* t4 = new TGeoTubeSeg(76.7312, 78.7912, 74.175, 350., 109.4); // prepreg3 300 microns
1313 auto* t5 = new TGeoTubeSeg(76.7612, 78.7612, 74.175, 350., 109.4); // nomex 2 cm
1314 auto* tepox1 = new TGeoTubeSeg(76.6774, 78.845, 74.175, 109.4, 110.); // epoxy
1315 auto* tpr1 = new TGeoTubeSeg(78.845, 78.885, 74.175, 109., 111.);
1316
1317 // volumes for the outer part
1318 auto* tv2 = new TGeoVolume("TPC_IFC3", t2, sm2);
1319 auto* tv3 = new TGeoVolume("TPC_IFC4", t3, sm3);
1320 auto* tv4 = new TGeoVolume("TPC_IFC5", t4, sm5);
1321 auto* tv5 = new TGeoVolume("TPC_IFC6", t5, sm4);
1322 auto* tvep1 = new TGeoVolume("TPC_IFEPOX1", tepox1, smep);
1323 auto* tvpr1 = new TGeoVolume("TPC_PRSTR1", tpr1, sm2);
1324 //
1325 // middle parts - 2 copies
1326 //
1327 // segment middle
1328 //
1329 auto* t6 = new TGeoTubeSeg(76.6774, 78.795, 5., 350., 109.4); // tedlar 38 microns
1330 auto* t7 = new TGeoTubeSeg(76.6812, 78.7912, 5., 350., 109.4); // prepreg2 250 microns
1331 auto* t8 = new TGeoTubeSeg(76.7062, 78.7662, 5., 350., 109.4); // prepreg3 300 microns
1332 auto* t9 = new TGeoTubeSeg(76.7362, 78.7362, 5., 350., 109.4); // nomex 2 cm
1333 auto* tepox2 = new TGeoTubeSeg(76.6774, 78.795, 5., 109.4, 110.); // epoxy
1334 auto* tpr2 = new TGeoTubeSeg(78.795, 78.835, 5., 109., 111.);
1335 // volumes for the middle part
1336 auto* tv6 = new TGeoVolume("TPC_IFC7", t6, sm2);
1337 auto* tv7 = new TGeoVolume("TPC_IFC8", t7, sm3);
1338 auto* tv8 = new TGeoVolume("TPC_IFC9", t8, sm5);
1339 auto* tv9 = new TGeoVolume("TPC_IFC10", t9, sm4);
1340 auto* tvep2 = new TGeoVolume("TPC_IFEPOX2", tepox2, smep);
1341 auto* tvpr2 = new TGeoVolume("TPC_PRSTR2", tpr2, sm2);
1342 // central part - 1 copy
1343 //
1344 // segment central part
1345 //
1346 auto* t10 = new TGeoTubeSeg(76.6774, 78.785, 93.75, 350., 109.4); // tedlar 38 microns
1347 auto* t11 = new TGeoTubeSeg(76.6812, 78.7812, 93.75, 350., 109.4); // prepreg3 500 microns
1348 auto* t12 = new TGeoTubeSeg(76.7312, 78.7312, 93.75, 350., 109.4); // nomex 2 cm
1349 auto* tepox3 = new TGeoTubeSeg(76.6774, 78.785, 93.75, 109.4, 110.); // epoxy
1350 auto* tpr3 = new TGeoTubeSeg(78.785, 78.825, 93.75, 109., 111.);
1351 // volumes for the central part
1352 auto* tv10 = new TGeoVolume("TPC_IFC11", t10, sm2);
1353 auto* tv11 = new TGeoVolume("TPC_IFC12", t11, sm5);
1354 auto* tv12 = new TGeoVolume("TPC_IFC13", t12, sm4);
1355 auto* tvep3 = new TGeoVolume("TPC_IFEPOX3", tepox3, smep);
1356 auto* tvpr3 = new TGeoVolume("TPC_PRSTR3", tpr3, sm2);
1357 //
1358 // creating a sandwich for the outer par,t tv2 is the mother
1359 //
1360 tv2->AddNode(tv3, 1);
1361 tv3->AddNode(tv4, 1);
1362 tv4->AddNode(tv5, 1);
1363 //
1364 // creating a sandwich for the middle part, tv6 is the mother
1365 //
1366 tv6->AddNode(tv7, 1);
1367 tv7->AddNode(tv8, 1);
1368 tv8->AddNode(tv9, 1);
1369 //
1370 // creating a sandwich for the central part, tv10 is the mother
1371 //
1372 tv10->AddNode(tv11, 1);
1373 tv11->AddNode(tv12, 1);
1374 //
1375 auto* tv100 = new TGeoVolumeAssembly("TPC_IFC"); // ifc itself - 3 segments
1376
1377 //
1378 // first segment - no rotation
1379 //
1380 // central
1381 tv100->AddNode(tv10, 1); // sandwich
1382 tv100->AddNode(tvep3, 1); // epoxy
1383 tv100->AddNode(tvpr3, 1); // prepreg strip
1384 // middle
1385 tv100->AddNode(tv6, 1, new TGeoTranslation(0., 0., -98.75)); // sandwich1
1386 tv100->AddNode(tv6, 2, new TGeoTranslation(0., 0., 98.75)); // sandwich2
1387 tv100->AddNode(tvep2, 1, new TGeoTranslation(0., 0., -98.75)); // epoxy
1388 tv100->AddNode(tvep2, 2, new TGeoTranslation(0., 0., 98.75)); // epoxy
1389 tv100->AddNode(tvpr2, 1, new TGeoTranslation(0., 0., -98.75)); // prepreg strip
1390 tv100->AddNode(tvpr2, 2, new TGeoTranslation(0., 0., 98.75));
1391 // outer
1392 tv100->AddNode(tv2, 1, new TGeoTranslation(0., 0., -177.925)); // sandwich
1393 tv100->AddNode(tv2, 2, new TGeoTranslation(0., 0., 177.925));
1394 tv100->AddNode(tvep1, 1, new TGeoTranslation(0., 0., -177.925)); // epoxy
1395 tv100->AddNode(tvep1, 2, new TGeoTranslation(0., 0., 177.925));
1396 tv100->AddNode(tvpr1, 1, new TGeoTranslation(0., 0., -177.925)); // prepreg strip
1397 tv100->AddNode(tvpr1, 2, new TGeoTranslation(0., 0., 177.925));
1398 //
1399 // second segment - rotation 120 deg.
1400 //
1401 segrot = new TGeoRotation();
1402 segrot->RotateZ(120.);
1403 //
1404 // central
1405 tv100->AddNode(tv10, 2, segrot); // sandwich
1406 tv100->AddNode(tvep3, 2, segrot); // epoxy
1407 tv100->AddNode(tvpr3, 2, segrot); // prepreg strip
1408 // middle
1409 tv100->AddNode(tv6, 3, new TGeoCombiTrans(0., 0., -98.75, segrot)); // sandwich1
1410 tv100->AddNode(tv6, 4, new TGeoCombiTrans(0., 0., 98.75, segrot)); // sandwich2
1411 tv100->AddNode(tvep2, 3, new TGeoCombiTrans(0., 0., -98.75, segrot)); // epoxy
1412 tv100->AddNode(tvep2, 4, new TGeoCombiTrans(0., 0., 98.75, segrot)); // epoxy
1413 tv100->AddNode(tvpr2, 3, new TGeoCombiTrans(0., 0., -98.75, segrot)); // prepreg strip
1414 tv100->AddNode(tvpr2, 4, new TGeoCombiTrans(0., 0., 98.75, segrot));
1415 // outer
1416 tv100->AddNode(tv2, 3, new TGeoCombiTrans(0., 0., -177.925, segrot)); // sandwich
1417 tv100->AddNode(tv2, 4, new TGeoCombiTrans(0., 0., 177.925, segrot));
1418 tv100->AddNode(tvep1, 3, new TGeoCombiTrans(0., 0., -177.925, segrot)); // epoxy
1419 tv100->AddNode(tvep1, 4, new TGeoCombiTrans(0., 0., 177.925, segrot));
1420 tv100->AddNode(tvpr1, 3, new TGeoCombiTrans(0., 0., -177.925, segrot)); // prepreg strip
1421 tv100->AddNode(tvpr1, 4, new TGeoCombiTrans(0., 0., 177.925, segrot));
1422 //
1423 // third segment - rotation 240 deg.
1424 //
1425 segrot = new TGeoRotation();
1426 segrot->RotateZ(240.);
1427 //
1428 // central
1429 tv100->AddNode(tv10, 3, segrot); // sandwich
1430 tv100->AddNode(tvep3, 3, segrot); // epoxy
1431 tv100->AddNode(tvpr3, 3, segrot); // prepreg strip
1432 // middle
1433 tv100->AddNode(tv6, 5, new TGeoCombiTrans(0., 0., -98.75, segrot)); // sandwich1
1434 tv100->AddNode(tv6, 6, new TGeoCombiTrans(0., 0., 98.75, segrot)); // sandwich2
1435 tv100->AddNode(tvep2, 5, new TGeoCombiTrans(0., 0., -98.75, segrot)); // epoxy
1436 tv100->AddNode(tvep2, 6, new TGeoCombiTrans(0., 0., 98.75, segrot)); // epoxy
1437 tv100->AddNode(tvpr2, 5, new TGeoCombiTrans(0., 0., -98.75, segrot)); // prepreg strip
1438 tv100->AddNode(tvpr2, 6, new TGeoCombiTrans(0., 0., 98.75, segrot));
1439 // outer
1440 tv100->AddNode(tv2, 5, new TGeoCombiTrans(0., 0., -177.925, segrot)); // sandwich
1441 tv100->AddNode(tv2, 6, new TGeoCombiTrans(0., 0., 177.925, segrot));
1442 tv100->AddNode(tvep1, 5, new TGeoCombiTrans(0., 0., -177.925, segrot)); // epoxy
1443 tv100->AddNode(tvep1, 6, new TGeoCombiTrans(0., 0., 177.925, segrot));
1444 tv100->AddNode(tvpr1, 5, new TGeoCombiTrans(0., 0., -177.925, segrot)); // prepreg strip
1445 tv100->AddNode(tvpr1, 6, new TGeoCombiTrans(0., 0., 177.925, segrot));
1446 // Al parts - rings
1447 tv100->AddNode(tv1, 1, new TGeoTranslation(0., 0., -252.85));
1448 tv100->AddNode(tv1, 2, new TGeoTranslation(0., 0., 252.85));
1449 //
1450 v5->AddNode(v6, 1, new TGeoTranslation(0., 0., -252.1));
1451 v5->AddNode(v6, 2, new TGeoTranslation(0., 0., 252.1));
1452 v1->AddNode(v5, 1);
1453 v1->AddNode(v7, 1);
1454 v1->AddNode(v8, 1);
1455 v1->AddNode(hvsm, 1, new TGeoTranslation(0., 0., -163.8));
1456 v1->AddNode(hvss, 1, new TGeoTranslation(0., 0., 163.8));
1457 v9->AddNode(tv100, 1);
1458 //
1459 // guard rings for IFC - outer placed in inner insulator, inner placed in the drift gas (3 different radii)
1460 // AL, 1.2 cm wide, 0.015 cm thick, volumes TPC_IGR1 - outer, TPC_IGR2-4 - inner
1461 //
1462 auto* igro = new TGeoTube(76.6624, 76.6774, 0.6); // inner part, ends at inner radius of the IFC
1463 auto* igrio = new TGeoTube(78.845, 78.86, 0.6); // outer part
1464 auto* igrim = new TGeoTube(78.795, 78.81, 0.6);
1465 auto* igric = new TGeoTube(78.785, 78.8, 0.6);
1466 //
1467 // volumes
1468 //
1469 auto* igrov = new TGeoVolume("TPC_IGR1", igro, m3);
1470 auto* igriov = new TGeoVolume("TPC_IGR2", igrio, m3);
1471 auto* igrimv = new TGeoVolume("TPC_IGR3", igrim, m3);
1472 auto* igricv = new TGeoVolume("TPC_IGR4", igric, m3);
1473 //
1474 // outer guard rings for IFC placement - every 10 cm
1475 //
1476 for (Int_t i = 0; i < 24; i++) {
1477 v5->AddNode(igrov, (i + 1), new TGeoTranslation(0., 0., (i + 1) * 10));
1478 v5->AddNode(igrov, (i + 25), new TGeoTranslation(0., 0., -(i + 1) * 10));
1479 }
1480 //
1481 // inner guard rings for IFC placement
1482 //
1483 for (Int_t i = 0; i < 9; i++) {
1484 v9->AddNode(igricv, (i + 1), new TGeoTranslation(0., 0., (i + 1) * 10));
1485 v9->AddNode(igricv, (i + 10), new TGeoTranslation(0., 0., -(i + 1) * 10));
1486 }
1487 v9->AddNode(igrimv, 1, new TGeoTranslation(0., 0., 100.));
1488 v9->AddNode(igrimv, 2, new TGeoTranslation(0., 0., -100.));
1489 //
1490 for (Int_t i = 0; i < 13; i++) {
1491 v9->AddNode(igriov, i + 1, new TGeoTranslation(0., 0., 100 + (i + 1) * 10));
1492 v9->AddNode(igriov, i + 14, new TGeoTranslation(0., 0., -(100 + (i + 1) * 10)));
1493 }
1494 //
1495 // central drum
1496 //
1497 // flange + sandwich
1498 //
1499 auto* cfl = new TGeoPcon(0., 360., 6);
1500 cfl->DefineSection(0, -71.1, 59.7, 61.2);
1501 cfl->DefineSection(1, -68.6, 59.7, 61.2);
1502 //
1503 cfl->DefineSection(2, -68.6, 60.6124, 61.2);
1504 cfl->DefineSection(3, 68.6, 60.6124, 61.2);
1505 //
1506 cfl->DefineSection(4, 68.6, 59.7, 61.2);
1507 cfl->DefineSection(5, 71.1, 59.7, 61.2);
1508 //
1509 auto* cflv = new TGeoVolume("TPC_CDR", cfl, m3);
1510 // sandwich
1511 auto* cd1 = new TGeoTubeSeg(60.6224, 61.19, 69.8, 0.05, 119.95);
1512 auto* cd2 = new TGeoTubeSeg(60.6262, 61.1862, 69.8, 0.05, 119.95);
1513 auto* cd3 = new TGeoTubeSeg(60.6462, 61.1662, 69.8, 0.05, 119.95);
1514 auto* cd4 = new TGeoTubeSeg(60.6562, 61.1562, 69.8, 0.05, 119.95);
1515 auto* tepox4 = new TGeoTubeSeg(60.6224, 61.19, 69.8, 359.95, 0.05); // epoxy glue 0.01 deg
1516 //
1517 TGeoMedium* sm6 = gGeoManager->GetMedium("TPC_Prepreg1");
1518 TGeoMedium* sm8 = gGeoManager->GetMedium("TPC_Epoxyfm");
1519 auto* cd1v = new TGeoVolume("TPC_CDR1", cd1, sm2); // tedlar
1520 auto* cd2v = new TGeoVolume("TPC_CDR2", cd2, sm6); // prepreg1
1521 auto* cd3v = new TGeoVolume("TPC_CDR3", cd3, sm8); // epoxy film
1522 auto* cd4v = new TGeoVolume("TPC_CDR4", cd4, sm4); // nomex
1523 auto* tvep4 = new TGeoVolume("TPC_IFEPOX4", tepox4, smep); // epoxy glue
1524 //
1525 // joints between sections 1 deg prepreg1 placed in nomex at lower and upper radius + 0.1 deg of glue (epoxy)
1526 //
1527 auto* cdjl = new TGeoTubeSeg(60.6562, 60.6762, 69.8, 0., 1.0); // lower, to be rotated when positioned
1528 auto* cdju = new TGeoTubeSeg(61.1362, 61.1562, 69.8, 0., 1.0); // upper, to be rotated when positioned
1529 //
1530 auto* cdjlv = new TGeoVolume("TPC_CDJL", cdjl, sm6);
1531 auto* cdjuv = new TGeoVolume("TPC_CDJU", cdju, sm6);
1532 //
1533 // seals for central drum 2 copies
1534 //
1535 auto* cs = new TGeoTube(56.9, 61.2, 0.1);
1536 TGeoMedium* sm7 = gGeoManager->GetMedium("TPC_Mylar");
1537 auto* csv = new TGeoVolume("TPC_CDRS", cs, sm7);
1538 v1->AddNode(csv, 1, new TGeoTranslation(0., 0., -71.2));
1539 v1->AddNode(csv, 2, new TGeoTranslation(0., 0., 71.2));
1540 //
1541 // seal collars
1542 auto* se = new TGeoPcon(0., 360., 6);
1543 se->DefineSection(0, -72.8, 59.7, 61.2);
1544 se->DefineSection(1, -72.3, 59.7, 61.2);
1545 //
1546 se->DefineSection(2, -72.3, 58.85, 61.2);
1547 se->DefineSection(3, -71.6, 58.85, 61.2);
1548 //
1549 se->DefineSection(4, -71.6, 59.7, 61.2);
1550 se->DefineSection(5, -71.3, 59.7, 61.2);
1551 //
1552 auto* sev = new TGeoVolume("TPC_CDCE", se, m3);
1553 //
1554 auto* si = new TGeoTube(56.9, 58.8, 1.);
1555 auto* siv = new TGeoVolume("TPC_CDCI", si, m3);
1556 //
1557 // define reflection matrix
1558 //
1559 auto* ref = new TGeoRotation("ref", 90., 0., 90., 90., 180., 0.);
1560 //
1561 cd1v->AddNode(cd2v, 1);
1562 cd2v->AddNode(cd3v, 1);
1563 cd3v->AddNode(cd4v, 1); // sandwich
1564 //
1565 // joints, lower part and upper parts, placed in nomex
1566 //
1567 segrot = new TGeoRotation();
1568 segrot->RotateZ(0.05);
1569 cd4v->AddNode(cdjlv, 1, segrot);
1570 cd4v->AddNode(cdjuv, 1, segrot);
1571 segrot = new TGeoRotation();
1572 segrot->RotateZ(118.95);
1573 cd4v->AddNode(cdjlv, 2, segrot);
1574 cd4v->AddNode(cdjuv, 2, segrot);
1575 //
1576 // according to the conversion data, segments have an additionaly rotated by 4.6 deg
1577 //
1578 // first segment
1579 segrot = new TGeoRotation();
1580 segrot->RotateZ(4.6);
1581 cflv->AddNode(cd1v, 1, segrot);
1582 cflv->AddNode(tvep4, 1, segrot);
1583 // second segment
1584 segrot = new TGeoRotation();
1585 segrot->RotateZ(124.6);
1586 cflv->AddNode(cd1v, 2, segrot);
1587 cflv->AddNode(tvep4, 2, segrot);
1588 // third segment
1589 segrot = new TGeoRotation();
1590 segrot->RotateZ(244.6);
1591 cflv->AddNode(cd1v, 3, segrot);
1592 cflv->AddNode(tvep4, 3, segrot);
1593 //
1594 // heating strips
1595 //
1596 auto* hstr = new TGeoTubeSeg(60.6124, 60.6224, 68.5, 0., 1.25);
1597 auto* hstrv = new TGeoVolume("TPC_HSTR", hstr, m1); // air, caved out from cflv, first strip starts at 0 deg
1598 for (Int_t i = 0; i < 144; i++) {
1599 Double_t alpha = 1.25 + i * 2.5;
1600 segrot = new TGeoRotation();
1601 segrot->RotateZ(alpha);
1602 cflv->AddNode(hstrv, i + 1, segrot);
1603 }
1604 //
1605 v1->AddNode(siv, 1, new TGeoTranslation(0., 0., -69.9));
1606 v1->AddNode(siv, 2, new TGeoTranslation(0., 0., 69.9));
1607 v1->AddNode(sev, 1);
1608 v1->AddNode(sev, 2, ref);
1609 v1->AddNode(cflv, 1);
1610 //
1611 // central membrane - 2 rings and a mylar membrane - assembly
1612 //
1613 auto* ih = new TGeoTube(81.05, 84.05, 0.3);
1614 auto* oh = new TGeoTube(250., 256., 0.5);
1615 auto* mem = new TGeoTube(84.05, 250., 0.00115);
1616
1617 //
1618 TGeoMedium* m4 = gGeoManager->GetMedium("TPC_G10");
1619 //
1620 auto* ihv = new TGeoVolume("TPC_IHVH", ih, m3);
1621 auto* ohv = new TGeoVolume("TPC_OHVH", oh, m3);
1622
1623 auto* memv = new TGeoVolume("TPC_HV", mem, sm7);
1624 //
1625 auto* cm = new TGeoVolumeAssembly("TPC_HVMEM");
1626 cm->AddNode(ihv, 1);
1627 cm->AddNode(ohv, 1);
1628 cm->AddNode(memv, 1);
1629
1630 v9->AddNode(cm, 1);
1631 //
1632 // end caps - they are make as an assembly of single segments
1633 // containing both readout chambers
1634 //
1635 Double_t openingAngle = 10. * TMath::DegToRad();
1636 Double_t thick = 1.5; // rib
1637 Double_t shift = thick / TMath::Sin(openingAngle);
1638 //
1639 Double_t lowEdge = 86.3; // hole in the wheel
1640 Double_t upEdge = 240.4; // hole in the wheel
1641 //
1642 new TGeoTubeSeg("tpc_ssec", 74.5, 264.4, 3., 0., 20.);
1643 //
1644 auto* tpc_hole = new TGeoPgon("tpc_hole", 0., 20., 1, 4);
1645 //
1646 tpc_hole->DefineSection(0, -3.5, lowEdge - shift, upEdge - shift);
1647 tpc_hole->DefineSection(1, -1.5, lowEdge - shift, upEdge - shift);
1648 //
1649 tpc_hole->DefineSection(2, -1.5, lowEdge - shift, upEdge + 3. - shift);
1650 tpc_hole->DefineSection(3, 3.5, lowEdge - shift, upEdge + 3. - shift);
1651 //
1652 Double_t ys = shift * TMath::Sin(openingAngle);
1653 Double_t xs = shift * TMath::Cos(openingAngle);
1654 auto* tr = new TGeoTranslation("tr", xs, ys, 0.);
1655 tr->RegisterYourself();
1656 auto* chamber = new TGeoCompositeShape("tpc_ssec-tpc_hole:tr");
1657 auto* sv = new TGeoVolume("TPC_WSEG", chamber, m3);
1658 auto* bar = new TGeoPgon("bar", 0., 20., 1, 2);
1659 bar->DefineSection(0, -3., 131.5 - shift, 136.5 - shift);
1660 bar->DefineSection(1, 1.5, 131.5 - shift, 136.5 - shift);
1661 auto* barv = new TGeoVolume("TPC_WBAR", bar, m3);
1662 auto* ch = new TGeoVolumeAssembly("TPC_WCH"); // empty segment
1663 //
1664 ch->AddNode(sv, 1);
1665 ch->AddNode(barv, 1, tr);
1666 //
1667 // readout chambers
1668 //
1669 // IROC first
1670 //
1671 TGeoMedium* m6 = gGeoManager->GetMedium("TPC_Makrolon");
1672 //
1673 auto* ibody = new TGeoTrd1(13.8742, 21.3328, 4.29, 21.15);
1674 auto* ibdv = new TGeoVolume("TPC_IROCB", ibody, m3);
1675 // empty space
1676 auto* emp = new TGeoTrd1(12.3742, 19.8328, 4.05, 19.65);
1677 auto* empv = new TGeoVolume("TPC_IROCE", emp, m1);
1678 ibdv->AddNode(empv, 1, new TGeoTranslation(0., -0.24, 0.));
1679 // bars
1680 Double_t tga = (19.8328 - 12.3742) / 39.3;
1681 Double_t xmin, xmax;
1682 // 1
1683 xmin = 9.65 * tga + 12.3742;
1684 xmax = 10.05 * tga + 12.3742;
1685 //
1686 auto* ib1 = new TGeoTrd1(xmin, xmax, 2.06, 0.2);
1687 auto* ib1v = new TGeoVolume("TPC_IRB1", ib1, m3);
1688 empv->AddNode(ib1v, 1, new TGeoTranslation("tt1", 0., 1.99, -9.8));
1689 // 2
1690 xmin = 19.5 * tga + 12.3742;
1691 xmax = 19.9 * tga + 12.3742;
1692 //
1693 auto* ib2 = new TGeoTrd1(xmin, xmax, 2.06, 0.2);
1694 auto* ib2v = new TGeoVolume("TPC_TRB2", ib2, m3);
1695 empv->AddNode(ib2v, 1, new TGeoTranslation(0., 1.99, 0.05));
1696 // 3
1697 xmin = 29.35 * tga + 12.3742;
1698 xmax = 29.75 * tga + 12.3742;
1699 //
1700 auto* ib3 = new TGeoTrd1(xmin, xmax, 2.06, 0.2);
1701 auto* ib3v = new TGeoVolume("TPC_IRB3", ib3, m3);
1702 empv->AddNode(ib3v, 1, new TGeoTranslation(0., 1.99, 9.9));
1703 //
1704 // connectors alu body & strong back
1705 //
1706 auto* conn = new TGeoBBox(0.4, 0.24, 1.937); // connectors alu body
1707 auto* connv = new TGeoVolume("TPC_RCCON", conn, m6); // makrolon
1708 //
1709 auto* connb = new TGeoBBox(0.5, 0.25, 2.375); // connectors strong back
1710 auto* connbv = new TGeoVolume("TPC_RCCONB", connb, m6);
1711 //
1712 // strong back
1713 //
1714 auto* icsb = new TGeoTrd1(14.5974, 23.3521, 0.25, 24.825);
1715 auto* icsbv = new TGeoVolume("TPC_ISB", icsb, m4);
1716 //
1717 // file with positions of connectors
1718 //
1719 TString fileName(gSystem->Getenv("VMCWORKDIR"));
1720 fileName += "/Detectors/Geometry/TPC/conn_iroc.dat";
1721 ifstream in;
1722 in.open(fileName.Data(), ios_base::in); // asci file
1723 if (!in.is_open()) {
1724 LOG(fatal) << "Cannot open input file : " << fileName.Data();
1725 }
1726 for (Int_t i = 0; i < 132; i++) {
1727 Double_t x, z, ang;
1728 in >> ang >> x >> z;
1729 //
1730 ang = -ang;
1731 z -= 1102.; // changing the reference frame from the beam to the volume
1732 z *= 0.1;
1733 x *= 0.1;
1734 //
1735 auto* rrr = new TGeoRotation();
1736 rrr->RotateY(ang);
1737 //
1738 ibdv->AddNode(connv, i + 1, new TGeoCombiTrans(x, 4.05, z, rrr)); // connectors alu body
1739 icsbv->AddNode(connbv, i + 1, new TGeoCombiTrans(x, 0., z + 1.725, rrr)); // connectors strong back
1740 }
1741 in.close();
1742 //
1743 // "cap"
1744 new TGeoTrd1("icap", 14.5974, 23.3521, 1.19, 24.825);
1745 // "hole"
1746 new TGeoTrd1("ihole", 13.8742, 21.3328, 1.2, 21.15);
1747 auto* tr1 = new TGeoTranslation("tr1", 0., 0., 1.725);
1748 tr1->RegisterYourself();
1749 auto* ic = new TGeoCompositeShape("icap-ihole:tr1");
1750 auto* icv = new TGeoVolume("TPC_IRCAP", ic, m3);
1751 //
1752 // pad plane G10 3.2 mm thick
1753 //
1754 auto* icpp = new TGeoTrd1(14.5974, 23.3521, 0.16, 24.825);
1755 auto* icppv = new TGeoVolume("TPC_IPP", icpp, m4); // pad plane
1756 //
1757 // gem
1758 //
1759 new TGeoTrd1("igem", 14.5974, 23.3521, 0.1, 24.825);
1760 new TGeoTrd1("igemh", 14.5974 - .5, 23.3521 - .5, 0.11, 24.825 - .5);
1761 auto* icgem = new TGeoCompositeShape("igem-igemh");
1762 auto* icgemv = new TGeoVolume("TPC_ICGEM", icgem, m4);
1763 //
1764 // assembly of the iroc
1765 //
1766 auto* iroc = new TGeoVolumeAssembly("TPC_IROC");
1767 //
1768 iroc->AddNode(ibdv, 1); // main body
1769 iroc->AddNode(icv, 1, new TGeoTranslation(0., 3.1, -1.725)); // cap
1770 iroc->AddNode(icsbv, 1, new TGeoTranslation(0., 4.54, -1.725)); // strong back
1771 iroc->AddNode(icppv, 1, new TGeoTranslation(0., 4.95, -1.725)); // pad plane
1772 iroc->AddNode(icgemv, 1, new TGeoTranslation(0., 5.21, -1.725)); // gem
1773 //
1774 // OROC
1775 //
1776 auto* obody = new TGeoTrd1(22.2938, 40.5084, 4.29, 51.65);
1777 auto* obdv = new TGeoVolume("TPC_OROCB", obody, m3);
1778 auto* oemp = new TGeoTrd1(20.7938, 39.0084, 3.89, 50.15);
1779 auto* oempv = new TGeoVolume("TPC_OROCE", oemp, m1);
1780 obdv->AddNode(oempv, 1, new TGeoTranslation(0., -0.4, 0.));
1781 //
1782 // horizontal bars
1783 //
1784 tga = (39.0084 - 20.7938) / 100.3;
1785 xmin = tga * 14.2 + 20.7938;
1786 xmax = tga * 14.6 + 20.7938;
1787 auto* ob1 = new TGeoTrd1(xmin, xmax, 2.94, 0.2);
1788 auto* ob1v = new TGeoVolume("TPC_ORB1", ob1, m3);
1789 //
1790 xmin = 30.4 * tga + 20.7938;
1791 xmax = 32.1 * tga + 20.7938;
1792 auto* ob2 = new TGeoTrd1(xmin, xmax, 2.94, 1.05);
1793 auto* ob2v = new TGeoVolume("TPC_ORB2", ob2, m3);
1794 //
1795 xmin = 51.5 * tga + 20.7938;
1796 xmax = 51.9 * tga + 20.7938;
1797 auto* ob3 = new TGeoTrd1(xmin, xmax, 2.94, 0.2);
1798 auto* ob3v = new TGeoVolume("TPC_ORB3", ob3, m3);
1799 //
1800 xmin = 68.5 * tga + 20.7938;
1801 xmax = 70.6 * tga + 20.7938;
1802 auto* ob4 = new TGeoTrd1(xmin, xmax, 2.94, 1.05);
1803 auto* ob4v = new TGeoVolume("TPC_ORB4", ob4, m3);
1804 //
1805 xmin = 89.9 * tga + 20.7938;
1806 xmax = 90.3 * tga + 20.7938;
1807 auto* ob5 = new TGeoTrd1(xmin, xmax, 2.94, 0.2);
1808 auto* ob5v = new TGeoVolume("TPC_ORB5", ob5, m3);
1809 //
1810 oempv->AddNode(ob1v, 1, new TGeoTranslation(0., 0.59, -35.75));
1811 oempv->AddNode(ob2v, 1, new TGeoTranslation(0., 0.59, -18.7));
1812 oempv->AddNode(ob3v, 1, new TGeoTranslation(0., 0.59, 1.55));
1813 oempv->AddNode(ob4v, 1, new TGeoTranslation(0., 0.59, 19.4));
1814 oempv->AddNode(ob5v, 1, new TGeoTranslation(0., 0.59, 39.95));
1815 //
1816 // connectors, identical as for iroc, but I prefer to have separate volumes for better control
1817 //
1818 auto* conno = new TGeoBBox(0.4, 0.4, 1.937); // alu body
1819 auto* connov = new TGeoVolume("TPC_RCCONO", conno, m6); // makrolon
1820 //
1821 auto* connob = new TGeoBBox(0.5, 0.25, 2.375);
1822 auto* connobv = new TGeoVolume("TPC_RCCONOB", connob, m6); // strong back
1823 //
1824 // cap
1825 //
1826 new TGeoTrd1("ocap", 23.3875, 43.524, 1.19, 57.1);
1827 new TGeoTrd1("ohole", 22.2938, 40.5084, 1.19, 51.65);
1828 auto* tr5 = new TGeoTranslation("tr5", 0., 0., -2.15);
1829 tr5->RegisterYourself();
1830 auto* oc = new TGeoCompositeShape("ocap-ohole:tr5");
1831 auto* ocv = new TGeoVolume("TPC_ORCAP", oc, m3);
1832 //
1833 // stron back 5 mm
1834 //
1835 auto* osb = new TGeoTrd1(23.3874, 43.524, 0.25, 57.1);
1836 auto* osbv = new TGeoVolume("TPC_OSB", osb, m4);
1837 //
1838 // pad plane 3.2 mm
1839 //
1840 auto* opp = new TGeoTrd1(23.3874, 43.524, 0.16, 57.1);
1841 auto* oppv = new TGeoVolume("TPC_OPP", opp, m4);
1842 //
1843 // gem
1844 //
1845 new TGeoTrd1("ogem", 23.3874, 43.524, 0.1, 57.1);
1846 //
1847 // ogemh1 - first "hole" ends at z = 36.25, ogemh2 - second "hole" starts at z = 74.15
1848 //
1849 new TGeoTrd1("ogemh1", 22.548, 28.579, 0.1, 17.625); // ogemh1 - lower hole
1850 new TGeoTrd1("ogemh2", 28.949, 35.297, 0.1, 18.45); // ogemh2 - middle hole
1851 new TGeoTrd1("ogemh3", 35.667, 42.332, 0.1, 19.425); // ogemh3 - upper hole
1852 //
1853 auto* tr2 = new TGeoTranslation("tr2", 0., 0., 18.125 - 57.1);
1854 auto* tr3 = new TGeoTranslation("tr3", 0., 0., 55.2 - 57.1);
1855 auto* tr4 = new TGeoTranslation("tr4", 0., 0., 94.175 - 57.1);
1856 tr2->RegisterYourself();
1857 tr3->RegisterYourself();
1858 tr4->RegisterYourself();
1859 auto* ocgem = new TGeoCompositeShape("ogem-ogemh1:tr2-ogemh2:tr3-ogemh3:tr4");
1860 auto* ocgemv = new TGeoVolume("TPC_OCGEM", ocgem, m4);
1861 //
1862 // holes for connectors
1863 //
1864 fileName = gSystem->Getenv("VMCWORKDIR");
1865 fileName += "/Detectors/Geometry/TPC/conn_oroc.dat";
1866 in.open(fileName.Data(), ios_base::in); // asci file
1867 if (!in.is_open()) {
1868 LOG(fatal) << "Cannot open input file : " << fileName.Data();
1869 }
1870 for (Int_t i = 0; i < 232; i++) {
1871 Double_t x, z, ang;
1872 in >> ang >> x >> z;
1873 ang = -ang;
1874 z -= 1884.5;
1875 z *= 0.1;
1876 x *= 0.1;
1877 //
1878 auto* rrr = new TGeoRotation();
1879 rrr->RotateY(ang);
1880 obdv->AddNode(connov, i + 1, new TGeoCombiTrans(x, 3.89, z, rrr));
1881 osbv->AddNode(connobv, i + 1, new TGeoCombiTrans(x, 0., z - 2.15, rrr));
1882 }
1883 in.close();
1884 //
1885 auto* oroc = new TGeoVolumeAssembly("TPC_OROC");
1886 //
1887 oroc->AddNode(obdv, 1);
1888 oroc->AddNode(ocv, 1, new TGeoTranslation(0., 3.1, 2.15));
1889 oroc->AddNode(osbv, 1, new TGeoTranslation(0., 4.54, 2.15));
1890 oroc->AddNode(oppv, 1, new TGeoTranslation(0., 4.95, 2.15));
1891 oroc->AddNode(ocgemv, 1, new TGeoTranslation(0., 5.21, 2.15));
1892 //
1893 // now iroc and oroc are placed into a sector...
1894 //
1895 auto* secta = new TGeoVolumeAssembly("TPC_SECT"); // a-side
1896 auto* sectc = new TGeoVolumeAssembly("TPC_SECT"); // c-side
1897 TGeoRotation rot1("rot1", 90., 90., 0.);
1898 TGeoRotation rot2("rot2");
1899 rot2.RotateY(10.);
1900 auto* rot = new TGeoRotation("rot");
1901 *rot = rot1 * rot2;
1902 //
1903 Double_t x0, y0;
1904 //
1905 // a and c sides separately because of possible different z-coordinate of first gem
1906 //
1907 x0 = 110.2 * TMath::Cos(openingAngle);
1908 y0 = 110.2 * TMath::Sin(openingAngle);
1909 auto* combi1a = new TGeoCombiTrans("combi1", x0, y0, 1.09, rot); // a-side
1910 auto* combi1c = new TGeoCombiTrans("combi1", x0, y0, 1.09, rot); // c-side
1911 x0 = 188.45 * TMath::Cos(openingAngle);
1912 y0 = 188.45 * TMath::Sin(openingAngle);
1913 auto* combi2a = new TGeoCombiTrans("combi2", x0, y0, 1.09, rot); // a-side
1914 auto* combi2c = new TGeoCombiTrans("combi2", x0, y0, 1.09, rot); // c-side
1915 //
1916 //
1917 // A-side
1918 //
1919 secta->AddNode(ch, 1);
1920 secta->AddNode(iroc, 1, combi1a);
1921 secta->AddNode(oroc, 1, combi2a);
1922 //
1923 // C-side
1924 //
1925 sectc->AddNode(ch, 1);
1926 sectc->AddNode(iroc, 1, combi1c);
1927 sectc->AddNode(oroc, 1, combi2c);
1928 //
1929 // now I try to make wheels...
1930 //
1931 auto* wheela = new TGeoVolumeAssembly("TPC_ENDCAP");
1932 auto* wheelc = new TGeoVolumeAssembly("TPC_ENDCAP");
1933 //
1934 for (Int_t i = 0; i < 18; i++) {
1935 Double_t phi = (20. * i);
1936 auto* rwh = new TGeoRotation();
1937 rwh->RotateZ(phi);
1938 wheela->AddNode(secta, i + 1, rwh);
1939 wheelc->AddNode(sectc, i + 1, rwh);
1940 }
1941 // wheels in the drift volume!
1942
1943 auto* combi3 = new TGeoCombiTrans("combi3", 0., 0., 256.6, ref);
1944 v9->AddNode(wheela, 1, combi3);
1945 v9->AddNode(wheelc, 2, new TGeoTranslation(0., 0., -256.6));
1946 //_____________________________________________________________
1947 // service support wheel
1948 //_____________________________________________________________
1949 auto* sw = new TGeoPgon(0., 20., 1, 2);
1950 sw->DefineSection(0, -4., 80.5, 251.75);
1951 sw->DefineSection(1, 4., 80.5, 251.75);
1952 auto* swv = new TGeoVolume("TPC_SWSEG", sw, m3); // Al
1953 //
1954 thick = 1.;
1955 shift = thick / TMath::Sin(openingAngle);
1956 auto* sh = new TGeoPgon(0., 20., 1, 2);
1957 sh->DefineSection(0, -4., 81.5 - shift, 250.75 - shift);
1958 sh->DefineSection(1, 4., 81.5 - shift, 250.75 - shift);
1959 auto* shv = new TGeoVolume("TPC_SWS1", sh, m1); // Air
1960 //
1961 TGeoMedium* m9 = gGeoManager->GetMedium("TPC_Si");
1962 auto* el = new TGeoPgon(0., 20., 1, 2);
1963 el->DefineSection(0, -1.872, 81.5 - shift, 250.75 - shift);
1964 el->DefineSection(1, 1.872, 81.5 - shift, 250.75 - shift);
1965 auto* elv = new TGeoVolume("TPC_ELEC", el, m9); // Si
1966 //
1967 shv->AddNode(elv, 1);
1968 //
1969 //
1970 ys = shift * TMath::Sin(openingAngle);
1971 xs = shift * TMath::Cos(openingAngle);
1972 swv->AddNode(shv, 1, new TGeoTranslation(xs, ys, 0.));
1973 // cover
1974 auto* co = new TGeoPgon(0., 20., 1, 2);
1975 co->DefineSection(0, -0.5, 77., 255.25);
1976 co->DefineSection(1, 0.5, 77., 255.25);
1977 auto* cov = new TGeoVolume("TPC_SWC1", co, m3); // Al
1978 // hole in a cover
1979 auto* coh = new TGeoPgon(0., 20., 1, 2);
1980 shift = 4. / TMath::Sin(openingAngle);
1981 coh->DefineSection(0, -0.5, 85. - shift, 247.25 - shift);
1982 coh->DefineSection(1, 0.5, 85. - shift, 247.25 - shift);
1983 //
1984 auto* cohv = new TGeoVolume("TPC_SWC2", coh, m1);
1985 //
1986 ys = shift * TMath::Sin(openingAngle);
1987 xs = shift * TMath::Cos(openingAngle);
1988 cov->AddNode(cohv, 1, new TGeoTranslation(xs, ys, 0.));
1989 //
1990 // Sector as an Assembly
1991 //
1992 auto* swhs = new TGeoVolumeAssembly("TPC_SSWSEC");
1993 swhs->AddNode(swv, 1);
1994 swhs->AddNode(cov, 1, new TGeoTranslation(0., 0., -4.5));
1995 swhs->AddNode(cov, 2, new TGeoTranslation(0., 0., 4.5));
1996 //
1997 // SSW as an Assembly of sectors
1998 //
1999 TGeoRotation* rsw[18];
2000 auto* swheel = new TGeoVolumeAssembly("TPC_SSWHEEL");
2001 for (Int_t i = 0; i < 18; i++) {
2002 Double_t phi = (20. * i);
2003 rsw[i] = new TGeoRotation();
2004 rsw[i]->RotateZ(phi);
2005 swheel->AddNode(swhs, i + 1, rsw[i]);
2006 }
2007 v1->AddNode(swheel, 1, new TGeoTranslation(0., 0., -284.6));
2008 v1->AddNode(swheel, 2, new TGeoTranslation(0., 0., 284.6));
2009
2010 // sensitive strips - strip "0" is always set
2011 // conditional
2013 Int_t totrows = 159;
2014 // totrows = mParam->GetNRowLow() + mParam->GetNRowUp();
2015 Double_t* upar;
2016 upar = nullptr;
2017 gGeoManager->Volume("TPC_Strip", "PGON", m5->GetId(), upar);
2018 upar = new Double_t[10];
2019 upar[0] = 0.;
2020 upar[1] = 360.;
2021 upar[2] = 18.;
2022 upar[3] = 2.;
2023 //
2024 upar[4] = -124.8;
2025 upar[7] = 124.8;
2026
2028 // Double_t rlow=mParam->GetPadRowRadiiLow(0);
2029 Double_t rlow = 85.225; // cm
2030
2031 upar[5] = rlow;
2032 upar[6] = rlow + .01;
2033 upar[8] = upar[5];
2034 upar[9] = upar[6];
2035 //
2036 gGeoManager->Node("TPC_Strip", 1, "TPC_Drift", 0., 0., 124.82, 0, kTRUE, upar, 10);
2037 gGeoManager->Node("TPC_Strip", totrows + 1, "TPC_Drift", 0., 0., -124.82, 0, kTRUE, upar, 10);
2038 //
2039 // now, strips optionally
2040 //
2041 // if(mSens){
2042 // //lower sectors
2043 // for(Int_t i=2;i<mParam->GetNRowLow()+1;i++){
2044 // rlow=mParam->GetPadRowRadiiLow(i-1);
2045 // upar[5]=rlow;
2046 // upar[6]=rlow+.01;
2047 // upar[8]=upar[5];
2048 // upar[9]=upar[6];
2049 // gGeoManager->Node("TPC_Strip",i,
2050 // "TPC_Drift",0.,0.,124.82,0,kTRUE,upar,10);
2051 // gGeoManager->Node("TPC_Strip",totrows+i,
2052 // "TPC_Drift",0.,0.,-124.82,0,kTRUE,upar,10);
2053 // }
2054 // //upper sectors
2055 // for(Int_t i=1;i<mParam->GetNRowUp()+1;i++){
2056 // rlow=mParam->GetPadRowRadiiUp(i-1);
2057 // upar[5]=rlow;
2058 // upar[6]=rlow+.01;
2059 // upar[8]=upar[5];
2060 // upar[9]=upar[6];
2061 // gGeoManager->Node("TPC_Strip",i+mParam->GetNRowLow(),
2062 // "TPC_Drift",0.,0.,124.82,0,kTRUE,upar,10);
2063 // gGeoManager->Node("TPC_Strip",totrows+i+mParam->GetNRowLow(),
2064 // "TPC_Drift",0.,0.,-124.82,0,kTRUE,upar,10);
2065 // }
2066 // }//strips
2067 //----------------------------------------------------------
2068 // TPC Support Rods - MAKROLON
2069 //----------------------------------------------------------
2070 //
2071 TGeoMedium* m7 = gGeoManager->GetMedium("TPC_Cu");
2072 TGeoMedium* m10 = gGeoManager->GetMedium("TPC_Alumina");
2073 TGeoMedium* m11 = gGeoManager->GetMedium("TPC_Peek");
2074 TGeoMedium* m13 = gGeoManager->GetMedium("TPC_Brass");
2075 TGeoMedium* m14 = gGeoManager->GetMedium("TPC_Alumina1");
2076 //
2077 // tpc rod is an assembly of 10 long parts and 2 short parts
2078 // connected with alu rings and plagged on both sides.
2079 //
2080 //
2081 // tpc rod long
2082 //
2083 auto* rod = new TGeoPcon("rod", 0., 360., 6);
2084 rod->DefineSection(0, -10.43, 1.92, 2.08);
2085 rod->DefineSection(1, -9.75, 1.92, 2.08);
2086
2087 rod->DefineSection(2, -9.75, 1.8, 2.2);
2088 rod->DefineSection(3, 9.75, 1.8, 2.2);
2089
2090 rod->DefineSection(4, 9.75, 1.92, 2.08);
2091 rod->DefineSection(5, 10.43, 1.92, 2.08);
2092 //
2093 auto* mrodl = new TGeoVolume("TPC_mrodl", rod, m6);
2094 //
2095 // tpc rod short
2096 //
2097 auto* rod1 = new TGeoPcon("rod1", 0., 360., 6);
2098 rod1->DefineSection(0, -8.93, 1.92, 2.08);
2099 rod1->DefineSection(1, -8.25, 1.92, 2.08);
2100
2101 rod1->DefineSection(2, -8.25, 1.8, 2.2);
2102 rod1->DefineSection(3, 8.25, 1.8, 2.2);
2103
2104 rod1->DefineSection(4, 8.25, 1.92, 2.08);
2105 rod1->DefineSection(5, 8.93, 1.92, 2.08);
2106 //
2107 auto* mrods = new TGeoVolume("TPC_mrods", rod1, m6);
2108 //
2109 // below is for the resistor rod
2110 //
2111 // hole for the brass connectors
2112 //
2113
2114 new TGeoTube("hhole", 0., 0.3, 0.3);
2115 //
2116 // transformations for holes - initialy they
2117 // are placed at x=0 and negative y
2118 //
2119 auto* rhole = new TGeoRotation();
2120 rhole->RotateX(90.);
2121 TGeoCombiTrans* transf[13];
2122 Char_t name[30];
2123 for (Int_t i = 0; i < 13; i++) {
2124 snprintf(name, 30, "transf%d", i);
2125 transf[i] = new TGeoCombiTrans(name, 0., -2., -9. + i * 1.5, rhole);
2126 transf[i]->RegisterYourself();
2127 }
2128 // union expression for holes
2129 TString operl("hhole:transf0");
2130 for (Int_t i = 1; i < 13; i++) {
2131 snprintf(name, 30, "+hhole:transf%d", i);
2132 operl.Append(name);
2133 }
2134 //
2135 TString opers("hhole:transf1");
2136 for (Int_t i = 2; i < 12; i++) {
2137 snprintf(name, 30, "+hhole:transf%d", i);
2138 opers.Append(name);
2139 }
2140 // union of holes
2141 new TGeoCompositeShape("hlv", operl.Data());
2142 new TGeoCompositeShape("hsv", opers.Data());
2143 //
2144 auto* rodl = new TGeoCompositeShape("rodl", "rod-hlv");
2145 auto* rods = new TGeoCompositeShape("rods", "rod1-hsv");
2146 // rods - volumes - makrolon rods with holes
2147 auto* rodlv = new TGeoVolume("TPC_rodl", rodl, m6);
2148 auto* rodsv = new TGeoVolume("TPC_rods", rods, m6);
2149 // brass connectors
2150 // connectors
2151 auto* bcon = new TGeoTube(0., 0.3, 0.3); // connectors
2152 auto* bconv = new TGeoVolume("TPC_bcon", bcon, m13);
2153 //
2154 // hooks holding strips
2155 //
2156 new TGeoBBox("hk1", 0.625, 0.015, 0.75);
2157 new TGeoBBox("hk2", 0.625, 0.015, 0.15);
2158 auto* tr21 = new TGeoTranslation("tr21", 0., -0.03, -0.6);
2159 auto* tr12 = new TGeoTranslation("tr12", 0., -0.03, 0.6);
2160 tr21->RegisterYourself();
2161 tr12->RegisterYourself();
2162
2163 auto* hook = new TGeoCompositeShape("hook", "hk1+hk2:tr21+hk2:tr12");
2164 auto* hookv = new TGeoVolume("TPC_hook", hook, m13);
2165 //
2166 // assembly of the short rod with connectors and hooks
2167 //
2168 //
2169 // short rod
2170 //
2171 auto* spart = new TGeoVolumeAssembly("TPC_spart");
2172 //
2173 spart->AddNode(rodsv, 1);
2174 for (Int_t i = 1; i < 12; i++) {
2175 spart->AddNode(bconv, i, transf[i]);
2176 }
2177 for (Int_t i = 0; i < 11; i++) {
2178 spart->AddNode(hookv, i + 1, new TGeoTranslation(0., -2.315, -7.5 + i * 1.5));
2179 }
2180 //
2181 // long rod
2182 //
2183 auto* lpart = new TGeoVolumeAssembly("TPC_lpart");
2184 //
2185 lpart->AddNode(rodlv, 1);
2186 for (Int_t i = 0; i < 13; i++) {
2187 lpart->AddNode(bconv, i + 12, transf[i]);
2188 }
2189 for (Int_t i = 0; i < 13; i++) {
2190 lpart->AddNode(hookv, i + 12, new TGeoTranslation(0., -2.315, -9. + i * 1.5));
2191 }
2192 //
2193 // alu ring
2194 //
2195 new TGeoTube("ring1", 2.1075, 2.235, 0.53);
2196 new TGeoTube("ring2", 1.7925, 1.89, 0.43);
2197 new TGeoTube("ring3", 1.89, 2.1075, 0.05);
2198 auto* ring = new TGeoCompositeShape("ring", "ring1+ring2+ring3");
2199 auto* ringv = new TGeoVolume("TPC_ring", ring, m3);
2200 //
2201 // rod assembly
2202 //
2203 auto* tpcrrod = new TGeoVolumeAssembly("TPC_rrod"); // rrod
2204 auto* tpcmrod = new TGeoVolumeAssembly("TPC_mrod"); // makrolon rod
2205 // long pieces
2206 for (Int_t i = 0; i < 11; i++) {
2207 tpcrrod->AddNode(ringv, i + 1, new TGeoTranslation(0., 0., -105. + i * 21));
2208 tpcmrod->AddNode(ringv, i + 12, new TGeoTranslation(0., 0., -105. + i * 21));
2209 }
2210 for (Int_t i = 0; i < 10; i++) {
2211 tpcrrod->AddNode(lpart, i + 1, new TGeoTranslation(0., 0., -94.5 + i * 21)); // resistor rod
2212 tpcmrod->AddNode(mrodl, i + 1, new TGeoTranslation(0., 0., -94.5 + i * 21)); // makrolon rod
2213 }
2214 //
2215 // right plug - identical for all rods
2216 //
2217 auto* tpcrp = new TGeoPcon(0., 360., 6);
2218 //
2219 tpcrp->DefineSection(0, 123.05, 1.89, 2.1075);
2220 tpcrp->DefineSection(1, 123.59, 1.89, 2.1075);
2221 //
2222 tpcrp->DefineSection(2, 123.59, 1.8, 2.2);
2223 tpcrp->DefineSection(3, 127., 1.8, 2.2);
2224 //
2225 tpcrp->DefineSection(4, 127., 0., 2.2);
2226 tpcrp->DefineSection(5, 127.5, 0., 2.2);
2227 //
2228 auto* tpcrpv = new TGeoVolume("TPC_RP", tpcrp, m6);
2229 //
2230 // adding short pieces and right plug
2231 //
2232 tpcrrod->AddNode(spart, 1, new TGeoTranslation(0., 0., -114.));
2233 tpcrrod->AddNode(spart, 2, new TGeoTranslation(0., 0., 114.));
2234 tpcrrod->AddNode(ringv, 23, new TGeoTranslation(0., 0., -123.));
2235 tpcrrod->AddNode(ringv, 24, new TGeoTranslation(0., 0., 123.));
2236 tpcrrod->AddNode(tpcrpv, 1);
2237 //
2238 tpcmrod->AddNode(mrods, 1, new TGeoTranslation(0., 0., -114.));
2239 tpcmrod->AddNode(mrods, 2, new TGeoTranslation(0., 0., 114.));
2240 tpcmrod->AddNode(ringv, 25, new TGeoTranslation(0., 0., -123.));
2241 tpcmrod->AddNode(ringv, 26, new TGeoTranslation(0., 0., 123.));
2242 tpcmrod->AddNode(tpcrpv, 2);
2243 //
2244 // from the ringv position to the CM is 3.0 cm!
2245 //----------------------------------------
2246 //
2247 //
2248 // HV rods - makrolon + 0.58cm (diameter) Cu ->check the length
2249 auto* hvr = new TGeoTube(0., 1.465, 123.);
2250 auto* hvc = new TGeoTube(0., 0.29, 123.);
2251 //
2252 auto* hvrv = new TGeoVolume("TPC_HV_Rod", hvr, m6);
2253 auto* hvcv = new TGeoVolume("TPC_HV_Cable", hvc, m7);
2254 hvrv->AddNode(hvcv, 1);
2255 //
2256 // resistor rod
2257 //
2258 auto* cr = new TGeoTube(0., 0.45, 123.);
2259 auto* cw = new TGeoTube(0., 0.15, 123.);
2260 auto* crv = new TGeoVolume("TPC_CR", cr, m10);
2261 auto* cwv = new TGeoVolume("TPC_W", cw, m12);
2262 //
2263 // ceramic rod with water
2264 //
2265 crv->AddNode(cwv, 1);
2266 //
2267 // peek rod
2268 //
2269 auto* pr = new TGeoTube(0.2, 0.35, 123.);
2270 auto* prv = new TGeoVolume("TPC_PR", pr, m11);
2271 //
2272 // copper plates with connectors
2273 //
2274 new TGeoTube("tub", 0., 1.7, 0.025);
2275 //
2276 // half space - points on the plane and a normal vector
2277 //
2278 Double_t n[3], p[3];
2279 Double_t slope = TMath::Tan(22. * TMath::DegToRad());
2280 Double_t intp = 1.245;
2281 //
2282 Double_t b = slope * slope + 1.;
2283 p[0] = intp * slope / b;
2284 p[1] = -intp / b;
2285 p[2] = 0.;
2286 //
2287 n[0] = -p[0];
2288 n[1] = -p[1];
2289 n[2] = 0.;
2290 Double_t norm;
2291 norm = TMath::Sqrt(n[0] * n[0] + n[1] * n[1]);
2292 n[0] /= norm;
2293 n[1] /= norm;
2294 //
2295 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("sp1", p, n, kHalfSpaceReach);
2296 //
2297 slope = -slope;
2298 //
2299 p[0] = intp * slope / b;
2300 p[1] = -intp / b;
2301 //
2302 n[0] = -p[0];
2303 n[1] = -p[1];
2304 norm = TMath::Sqrt(n[0] * n[0] + n[1] * n[1]);
2305 n[0] /= norm;
2306 n[1] /= norm;
2307 //
2308 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("sp2", p, n, kHalfSpaceReach);
2309 // holes for rods
2310 // holes
2311 new TGeoTube("h1", 0., 0.5, 0.025);
2312 new TGeoTube("h2", 0., 0.35, 0.025);
2313 // translations:
2314 auto* ttr11 = new TGeoTranslation("ttr11", -0.866, 0.5, 0.);
2315 auto* ttr22 = new TGeoTranslation("ttr22", 0.866, 0.5, 0.);
2316 ttr11->RegisterYourself();
2317 ttr22->RegisterYourself();
2318 // elastic connector
2319 new TGeoBBox("elcon", 0.72, 0.005, 0.3);
2320 auto* crr1 = new TGeoRotation();
2321 crr1->RotateZ(-22.);
2322 auto* ctr1 = new TGeoCombiTrans("ctr1", -0.36011, -1.09951, -0.325, crr1);
2323 ctr1->RegisterYourself();
2324 auto* cs1 = new TGeoCompositeShape("cs1", "(((((tub-h1:ttr11)-h1:ttr22)-(sp1:sp1_tr))-(sp2:sp2_tr))-h2)+elcon:ctr1");
2325 //
2326 auto* csvv = new TGeoVolume("TPC_RR_CU", cs1, m7);
2327 //
2328 // resistor rod assembly 2 ceramic rods, peak rod, Cu plates
2329 // and resistors
2330 //
2331 auto* rrod = new TGeoVolumeAssembly("TPC_RRIN");
2332 // rods
2333 rrod->AddNode(crv, 1, ttr11);
2334 rrod->AddNode(crv, 2, ttr22);
2335 rrod->AddNode(prv, 1);
2336 // Cu plates
2337 for (Int_t i = 0; i < 165; i++) {
2338 rrod->AddNode(csvv, i + 1, new TGeoTranslation(0., 0., -122.675 + i * 1.5));
2339 }
2340 // resistors
2341 auto* res = new TGeoTube(0., 0.15, 0.5);
2342 auto* resv = new TGeoVolume("TPC_RES", res, m14);
2343 auto* ress = new TGeoVolumeAssembly("TPC_RES_CH");
2344 ress->AddNode(resv, 1, new TGeoTranslation(0.2, 0., 0.));
2345 ress->AddNode(resv, 2, new TGeoTranslation(-0.2, 0., 0.));
2346 //
2347 auto* crr2 = new TGeoRotation();
2348 crr2->RotateY(30.);
2349 auto* crr3 = new TGeoRotation();
2350 crr3->RotateY(-30.);
2351 //
2352 for (Int_t i = 0; i < 164; i += 2) {
2353 rrod->AddNode(ress, i + 1, new TGeoCombiTrans(0., 1.2, -121.925 + i * 1.5, crr2));
2354 rrod->AddNode(ress, i + 2, new TGeoCombiTrans(0., 1.2, -121.925 + (i + 1) * 1.5, crr3));
2355 }
2356
2357 tpcrrod->AddNode(rrod, 1, new TGeoCombiTrans(0., 0., 0.5, crr1));
2358 //
2359 // rod left head with holders - inner
2360 //
2361 // first element - support for inner holder TPC_IHS
2362 Double_t shift1[3] = {0.0, -0.175, 0.0};
2363
2364 new TGeoBBox("tpcihs1", 4.7, 0.66, 2.35);
2365 new TGeoBBox("tpcihs2", 4.7, 0.485, 1.0, shift1);
2366 new TGeoBBox("tpcihs3", 1.5, 0.485, 2.35, shift1);
2367 new TGeoTube("tpcihs4", 0.0, 2.38, 0.1);
2368 //
2369 Double_t pointstrap[16];
2370 pointstrap[0] = 0.0;
2371 pointstrap[1] = 0.0;
2372 pointstrap[2] = 0.0;
2373 pointstrap[3] = 1.08;
2374 pointstrap[4] = 2.3;
2375 pointstrap[5] = 1.08;
2376 pointstrap[6] = 3.38;
2377 pointstrap[7] = 0.0;
2378 pointstrap[8] = 0.0;
2379 pointstrap[9] = 0.0;
2380 pointstrap[10] = 0.0;
2381 pointstrap[11] = 1.08;
2382 pointstrap[12] = 2.3;
2383 pointstrap[13] = 1.08;
2384 pointstrap[14] = 3.38;
2385 pointstrap[15] = 0.0;
2386 //
2387 auto* tpcihs5 = new TGeoArb8("tpcihs5", 0.6, pointstrap);
2388 //
2389 // half space - cutting "legs"
2390 //
2391 p[0] = 0.0;
2392 p[1] = 0.105;
2393 p[2] = 0.0;
2394 //
2395 n[0] = 0.0;
2396 n[1] = 1.0;
2397 n[2] = 0.0;
2398
2399 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutil1", p, n, kHalfSpaceReach);
2400
2401 //
2402 // transformations
2403 //
2404 auto* trans2 = new TGeoTranslation("trans2", 0.0, 2.84, 2.25);
2405 trans2->RegisterYourself();
2406 auto* trans3 = new TGeoTranslation("trans3", 0.0, 2.84, -2.25);
2407 trans3->RegisterYourself();
2408 // support - composite volume
2409 //
2410 auto* tpcihs6 =
2411 new TGeoCompositeShape("tpcihs6", "tpcihs1-(tpcihs2+tpcihs3)-(tpcihs4:trans2)-(tpcihs4:trans3)-(cutil1:cutil1_tr)");
2412 //
2413 // volumes - all makrolon
2414 //
2415 auto* tpcihss = new TGeoVolume("TPC_IHSS", tpcihs6, m6); // support
2416 auto* tpcihst = new TGeoVolume("TPC_IHSTR", tpcihs5, m6); // trapesoid
2417 // now assembly
2418 auto* rot111 = new TGeoRotation();
2419 rot111->RotateY(180.0);
2420 //
2421 auto* tpcihs = new TGeoVolumeAssembly("TPC_IHS"); // assembly of the support
2422 tpcihs->AddNode(tpcihss, 1);
2423 tpcihs->AddNode(tpcihst, 1, new TGeoTranslation(-4.7, 0.66, 0.0));
2424 tpcihs->AddNode(tpcihst, 2, new TGeoCombiTrans(4.7, 0.66, 0.0, rot111));
2425 //
2426 // two rod holders (TPC_IRH) assembled with the support
2427 //
2428 new TGeoBBox("tpcirh1", 4.7, 1.33, 0.5);
2429 shift1[0] = -3.65;
2430 shift1[1] = 0.53;
2431 shift1[2] = 0.;
2432 new TGeoBBox("tpcirh2", 1.05, 0.8, 0.5, shift1);
2433 shift1[0] = 3.65;
2434 shift1[1] = 0.53;
2435 shift1[2] = 0.;
2436 new TGeoBBox("tpcirh3", 1.05, 0.8, 0.5, shift1);
2437 shift1[0] = 0.0;
2438 shift1[1] = 1.08;
2439 shift1[2] = 0.;
2440 new TGeoBBox("tpcirh4", 1.9, 0.25, 0.5, shift1);
2441 new TGeoTube("tpcirh5", 0, 1.9, 5);
2442 //
2443 auto* trans4 = new TGeoTranslation("trans4", 0, 0.83, 0.0);
2444 trans4->RegisterYourself();
2445 //
2446 auto* tpcirh6 = new TGeoCompositeShape("tpcirh6", "tpcirh1-tpcirh2-tpcirh3-(tpcirh5:trans4)-tpcirh4");
2447 //
2448 // now volume
2449 //
2450 auto* tpcirh = new TGeoVolume("TPC_IRH", tpcirh6, m6);
2451 //
2452 // and all together...
2453 //
2454 TGeoVolume* tpciclamp = new TGeoVolumeAssembly("TPC_ICLP");
2455 tpciclamp->AddNode(tpcihs, 1);
2456 tpciclamp->AddNode(tpcirh, 1, new TGeoTranslation(0, 1.99, 1.1));
2457 tpciclamp->AddNode(tpcirh, 2, new TGeoTranslation(0, 1.99, -1.1));
2458 //
2459 // and now left inner "head"
2460 //
2461 auto* inplug = new TGeoPcon("inplug", 0.0, 360.0, 13);
2462
2463 inplug->DefineSection(0, 0.3, 0.0, 2.2);
2464 inplug->DefineSection(1, 0.6, 0.0, 2.2);
2465
2466 inplug->DefineSection(2, 0.6, 0.0, 1.75);
2467 inplug->DefineSection(3, 0.7, 0.0, 1.75);
2468
2469 inplug->DefineSection(4, 0.7, 1.55, 1.75);
2470 inplug->DefineSection(5, 1.6, 1.55, 1.75);
2471
2472 inplug->DefineSection(6, 1.6, 1.55, 2.2);
2473 inplug->DefineSection(7, 1.875, 1.55, 2.2);
2474
2475 inplug->DefineSection(8, 2.47, 1.75, 2.2);
2476
2477 inplug->DefineSection(9, 2.47, 1.75, 2.08);
2478 inplug->DefineSection(10, 2.57, 1.8, 2.08);
2479
2480 inplug->DefineSection(11, 2.57, 1.92, 2.08);
2481 inplug->DefineSection(12, 2.95, 1.92, 2.08);
2482 //
2483 shift1[0] = 0.0;
2484 shift1[1] = -2.09;
2485 shift1[2] = 1.075;
2486 //
2487 new TGeoBBox("pcuti", 1.5, 0.11, 1.075, shift1);
2488 //
2489 auto* inplleft = new TGeoCompositeShape("inplleft", "inplug-pcuti");
2490 auto* tpcinlplug = new TGeoVolume("TPC_INPLL", inplleft, m6);
2491 //
2492 // holder + plugs
2493 //
2494 TGeoVolume* tpcihpl = new TGeoVolumeAssembly("TPC_IHPL"); // holder+2 plugs (reflected)
2495 tpcihpl->AddNode(tpcinlplug, 1);
2496 tpcihpl->AddNode(tpcinlplug, 2, ref);
2497 tpcihpl->AddNode(tpciclamp, 1, new TGeoTranslation(0.0, -2.765, 0.0));
2498 //
2499 // outer holders and clamps
2500 //
2501
2502 // outer membrane holder (between rods)
2503 pointstrap[0] = 0.0;
2504 pointstrap[1] = 0.0;
2505 pointstrap[2] = 0.0;
2506 pointstrap[3] = 2.8;
2507 pointstrap[4] = 3.1;
2508 pointstrap[5] = 2.8 - 3.1 * TMath::Tan(15. * TMath::DegToRad());
2509 pointstrap[6] = 3.1;
2510 pointstrap[7] = 0.0;
2511 pointstrap[8] = 0.0;
2512 pointstrap[9] = 0.0;
2513 pointstrap[10] = 0.0;
2514 pointstrap[11] = 2.8;
2515 pointstrap[12] = 3.1;
2516 pointstrap[13] = 2.8 - 3.1 * TMath::Tan(15. * TMath::DegToRad());
2517 pointstrap[14] = 3.1;
2518 pointstrap[15] = 0.0;
2519 //
2520 auto* tpcomh1 = new TGeoArb8("tpcomh1", 1.05, pointstrap);
2521 auto* tpcomh2 = new TGeoBBox("tpcomh2", 0.8, 1.4, 6);
2522 //
2523 auto* tpcomh1v = new TGeoVolume("TPC_OMH1", tpcomh1, m7);
2524 auto* tpcomh2v = new TGeoVolume("TPC_OMH2", tpcomh2, m7);
2525 //
2526 TGeoVolume* tpcomh3v = new TGeoVolumeAssembly("TPC_OMH3"); // assembly1
2527 tpcomh3v->AddNode(tpcomh1v, 1, new TGeoTranslation(0.8, -1.4, 4.95));
2528 tpcomh3v->AddNode(tpcomh1v, 2, new TGeoTranslation(0.8, -1.4, -4.95));
2529 tpcomh3v->AddNode(tpcomh2v, 1);
2530 //
2531 shift1[0] = 0.9;
2532 shift1[1] = -1.85;
2533 shift1[2] = 0.0;
2534 //
2535 new TGeoBBox("tpcomh3", 1.65, 1.15, 3.4);
2536 auto* tpcomh4 = new TGeoBBox("tpcomh4", 0.75, 0.7, 3.4, shift1);
2537 //
2538 // halfspace 1
2539 //
2540 p[0] = 0.0;
2541 p[1] = -1.05;
2542 p[2] = -3.4;
2543 //
2544 n[0] = 0.0;
2545 n[1] = -1.0 * TMath::Tan(30. * TMath::DegToRad());
2546 n[2] = 1.0;
2547 //
2548 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutomh1", p, n, kHalfSpaceReach);
2549 //
2550 // halfspace 2
2551 //
2552 p[0] = 0.0;
2553 p[1] = -1.05;
2554 p[2] = 3.4;
2555 //
2556 n[0] = 0.0;
2557 n[1] = -1.0 * TMath::Tan(30. * TMath::DegToRad());
2558 n[2] = -1.0;
2559 //
2560 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutomh2", p, n, kHalfSpaceReach);
2561 //
2562 // halfspace 3
2563 //
2564 p[0] = -1.65;
2565 p[1] = 0.0;
2566 p[2] = -0.9;
2567 //
2568 n[0] = 1.0 * TMath::Tan(75. * TMath::DegToRad());
2569 n[1] = 0.0;
2570 n[2] = 1.0;
2571 //
2572 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutomh3", p, n, kHalfSpaceReach);
2573 //
2574 // halfspace 4
2575 //
2576 p[0] = -1.65;
2577 p[1] = 0.0;
2578 p[2] = 0.9;
2579 //
2580 n[0] = 1.0 * TMath::Tan(75 * TMath::DegToRad());
2581 n[1] = 0.0;
2582 n[2] = -1.0;
2583 //
2584 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutomh4", p, n, kHalfSpaceReach);
2585 //
2586 // halsfspace 5
2587 //
2588 p[0] = 1.65;
2589 p[1] = -1.05;
2590 p[2] = 0.0;
2591 //
2592 n[0] = -1.0;
2593 n[1] = -1.0 * TMath::Tan(20. * TMath::DegToRad());
2594 n[2] = 0.0;
2595 //
2596 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutomh5", p, n, kHalfSpaceReach);
2597 //
2598 auto* tpcomh5 = new TGeoCompositeShape("tpcomh5", "tpcomh3-(cutomh1:cutomh1_tr)-(cutomh2:cutomh2_tr)-(cutomh3:cutomh3_tr)-(cutomh4:cutomh4_tr)-(cutomh5:cutomh5_tr)");
2599 //
2600 auto* tpcomh5v = new TGeoVolume("TPC_OMH5", tpcomh5, m6);
2601 auto* tpcomh4v = new TGeoVolume("TPC_OMH6", tpcomh4, m6);
2602 //
2603 auto* tpcomh7v = new TGeoVolumeAssembly("TPC_OMH7");
2604 tpcomh7v->AddNode(tpcomh5v, 1);
2605 tpcomh7v->AddNode(tpcomh4v, 1);
2606 //
2607 // full membrane holder - tpcomh3v + tpcomh7v
2608 //
2609 auto* tpcomh = new TGeoVolumeAssembly("TPC_OMH");
2610 tpcomh->AddNode(tpcomh3v, 1, new TGeoTranslation(1.5, 0., 0.));
2611 tpcomh->AddNode(tpcomh3v, 2, new TGeoCombiTrans(-1.5, 0., 0., rot111));
2612 tpcomh->AddNode(tpcomh7v, 1, new TGeoTranslation(0.65 + 1.5, 2.55, 0.0));
2613 tpcomh->AddNode(tpcomh7v, 2, new TGeoCombiTrans(-0.65 - 1.5, 2.55, 0.0, rot111));
2614 //
2615 // outer rod holder support
2616 //
2617 new TGeoBBox("tpcohs1", 3.8, 0.675, 2.35);
2618 //
2619 shift1[0] = 0.0;
2620 shift1[1] = 0.175;
2621 shift1[2] = 0.0;
2622 //
2623 new TGeoBBox("tpcohs2", 1.5, 0.5, 2.35, shift1);
2624 new TGeoBBox("tpcohs3", 3.8, 0.5, 0.85, shift1);
2625 //
2626 shift1[0] = 0.0;
2627 shift1[1] = -1.175;
2628 shift1[2] = 0.0;
2629 //
2630 auto* tpcohs4 = new TGeoBBox("tpsohs4", 3.1, 0.5, 0.7, shift1);
2631 //
2632 auto* tpcohs4v = new TGeoVolume("TPC_OHS4", tpcohs4, m6);
2633 //
2634 p[0] = 0.0;
2635 p[1] = -0.186;
2636 p[2] = 0.0;
2637 //
2638 n[0] = 0.0;
2639 n[1] = -1.0;
2640 n[2] = 0.0;
2641 //
2642 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutohs1", p, n, kHalfSpaceReach);
2643 //
2644 auto* tpcohs5 = new TGeoCompositeShape("tpcohs5", "tpcohs1-tpcohs2-tpcohs3-(cutohs1:cutohs1_tr)");
2645 auto* tpcohs5v = new TGeoVolume("TPC_OHS5", tpcohs5, m6);
2646 //
2647 auto* tpcohs = new TGeoVolumeAssembly("TPC_OHS");
2648 tpcohs->AddNode(tpcohs5v, 1);
2649 tpcohs->AddNode(tpcohs4v, 1);
2650 //
2651 // outer rod holder itself
2652 //
2653 shift1[0] = 0.0;
2654 shift1[1] = 1.325;
2655 shift1[2] = 0.0;
2656 new TGeoBBox("tpcorh1", 3.1, 1.825, 0.55); // from this box we cut pieces...
2657 //
2658 shift1[0] = -3.1;
2659 shift1[1] = -0.5;
2660 shift1[2] = 0.0;
2661 //
2662 new TGeoBBox("tpcorh2", 0.5, 2.75, 1.1, shift1);
2663 //
2664 shift1[0] = 3.1;
2665 shift1[1] = -0.5;
2666 shift1[2] = 0.0;
2667 //
2668 new TGeoBBox("tpcorh3", 0.5, 2.75, 1.1, shift1);
2669 //
2670 shift1[0] = 0.0;
2671 shift1[1] = -0.5;
2672 shift1[2] = -0.95;
2673 //
2674 new TGeoBBox("tpcorh4", 3.9, 2.75, 0.5, shift1);
2675 //
2676 shift1[0] = 0.0;
2677 shift1[1] = -0.5;
2678 shift1[2] = 0.0;
2679 //
2680 new TGeoBBox("tpcorh5", 1.95, 0.5, 1.1, shift1);
2681 //
2682 shift1[0] = 0.0;
2683 shift1[1] = -0.5;
2684 shift1[2] = 0.55;
2685 //
2686 new TGeoBBox("tpcorh6", 2.4, 0.5, 0.6, shift1);
2687 //
2688 new TGeoTube("tpcorh7", 0, 1.95, 0.85);
2689 new TGeoTube("tpcorh8", 0, 2.4, 0.6);
2690 //
2691 auto* trans33 = new TGeoTranslation("trans33", 0.0, 0.0, 0.55);
2692 trans33->RegisterYourself();
2693 //
2694 auto* tpcorh9 =
2695 new TGeoCompositeShape("tpcorh9", "tpcorh1-tpcorh2-tpcorh3-tpcorh4-tpcorh5-tpcorh6-(tpcorh8:trans33)-tpcorh7");
2696 //
2697 auto* tpcorh9v = new TGeoVolume("TPC_ORH", tpcorh9, m6); // outer rod holder
2698 //
2699 // now 2 holders together
2700 //
2701 auto* tpcorh = new TGeoVolumeAssembly("TPC_ORH2");
2702 //
2703 tpcorh->AddNode(tpcorh9v, 1, new TGeoTranslation(0.0, 0.0, 1.25));
2704 tpcorh->AddNode(tpcorh9v, 2, new TGeoCombiTrans(0.0, 0.0, -1.25, rot111));
2705 //
2706 // outer rod plug left
2707 //
2708 auto* outplug = new TGeoPcon("outplug", 0.0, 360.0, 13);
2709
2710 outplug->DefineSection(0, 0.5, 0.0, 2.2);
2711 outplug->DefineSection(1, 0.7, 0.0, 2.2);
2712 outplug->DefineSection(2, 0.7, 1.55, 2.2);
2713 outplug->DefineSection(3, 0.8, 1.55, 2.2);
2714 outplug->DefineSection(4, 0.8, 1.55, 1.75);
2715 outplug->DefineSection(5, 1.2, 1.55, 1.75);
2716 outplug->DefineSection(6, 1.2, 1.55, 2.2);
2717 outplug->DefineSection(7, 1.875, 1.55, 2.2);
2718 outplug->DefineSection(8, 2.47, 1.75, 2.2);
2719 outplug->DefineSection(9, 2.47, 1.75, 2.08);
2720 outplug->DefineSection(10, 2.57, 1.8, 2.08);
2721 outplug->DefineSection(11, 2.57, 1.92, 2.08);
2722 outplug->DefineSection(12, 2.95, 1.92, 2.08);
2723 //
2724 shift1[0] = 0.0;
2725 shift1[1] = 2.09;
2726 shift1[2] = 1.01;
2727
2728 new TGeoBBox("cutout", 2.5, 0.11, 1.01, shift1);
2729 //
2730
2731 auto* outplleft = new TGeoCompositeShape("outplleft", "outplug-cutout");
2732 auto* outplleftv = new TGeoVolume("TPC_OPLL", outplleft, m6);
2733 //
2734 // support + holder + plug
2735 //
2736
2737 auto* tpcohpl = new TGeoVolumeAssembly("TPC_OHPL");
2738 //
2739 tpcohpl->AddNode(outplleftv, 1); // plug
2740 tpcohpl->AddNode(outplleftv, 2, ref); // plug reflected
2741 tpcohpl->AddNode(tpcorh, 1); // rod holder
2742 tpcohpl->AddNode(tpcohs, 1, new TGeoTranslation(0.0, 3.925, 0)); // support
2743 //
2744
2745 //
2746 // main membrane holder
2747 //
2748 pointstrap[0] = 0.0;
2749 pointstrap[1] = 0.0;
2750 pointstrap[2] = 0.0;
2751 pointstrap[3] = 2.8;
2752 pointstrap[4] = 3.1;
2753 pointstrap[5] = 1.96;
2754 pointstrap[6] = 3.1;
2755 pointstrap[7] = 0.0;
2756 pointstrap[8] = 0.0;
2757 pointstrap[9] = 0.0;
2758 pointstrap[10] = 0.0;
2759 pointstrap[11] = 2.8;
2760 pointstrap[12] = 3.1;
2761 pointstrap[13] = 1.96;
2762 pointstrap[14] = 3.1;
2763 pointstrap[15] = 0.0;
2764 //
2765 auto* tpcmmh1 = new TGeoArb8("tpcmmh1", 1.75, pointstrap);
2766 auto* tpcmmh2 = new TGeoBBox("tpcmmh2", 0.8, 1.4, 12.5);
2767 //
2768 auto* tpcmmh1v = new TGeoVolume("TPC_MMH1", tpcmmh1, m6);
2769 auto* tpcmmh2v = new TGeoVolume("TPC_MMH2", tpcmmh2, m6);
2770 //
2771 auto* tpcmmhs = new TGeoVolumeAssembly("TPC_MMHS");
2772 tpcmmhs->AddNode(tpcmmh1v, 1, new TGeoTranslation(0.8, -1.4, 10.75));
2773 tpcmmhs->AddNode(tpcmmh1v, 2, new TGeoTranslation(0.8, -1.4, -10.75));
2774 tpcmmhs->AddNode(tpcmmh2v, 1);
2775 //
2776 // main membrahe holder clamp
2777 //
2778 shift1[0] = -0.75;
2779 shift1[1] = -1.15;
2780 shift1[2] = 0.0;
2781 //
2782 new TGeoBBox("tpcmmhc1", 1.65, 1.85, 8.9);
2783 new TGeoBBox("tpcmmhc2", 0.9, 0.7, 8.9, shift1);
2784 //
2785 // half spaces - cuts
2786 //
2787 p[0] = -1.65;
2788 p[1] = 0.0;
2789 p[2] = -0.9;
2790 //
2791 n[0] = 8.0;
2792 n[1] = 0.0;
2793 n[2] = 8.0 * TMath::Tan(13. * TMath::DegToRad());
2794 //
2795 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutmmh1", p, n, kHalfSpaceReach);
2796 //
2797 p[0] = -1.65;
2798 p[1] = 0.0;
2799 p[2] = 0.9;
2800 //
2801 n[0] = 8.0;
2802 n[1] = 0.0;
2803 n[2] = -8.0 * TMath::Tan(13. * TMath::DegToRad());
2804 //
2805 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutmmh2", p, n, kHalfSpaceReach);
2806 //
2807 p[0] = 0.0;
2808 p[1] = 1.85;
2809 p[2] = -2.8;
2810 //
2811 n[0] = 0.0;
2812 n[1] = -6.1;
2813 n[2] = 6.1 * TMath::Tan(20. * TMath::DegToRad());
2814 //
2815 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutmmh3", p, n, kHalfSpaceReach);
2816 //
2817 p[0] = 0.0;
2818 p[1] = 1.85;
2819 p[2] = 2.8;
2820 //
2821 n[0] = 0.0;
2822 n[1] = -6.1;
2823 n[2] = -6.1 * TMath::Tan(20 * TMath::DegToRad());
2824 //
2825 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutmmh4", p, n, kHalfSpaceReach);
2826 //
2827 p[0] = 0.75;
2828 p[1] = 0.0;
2829 p[2] = -8.9;
2830 //
2831 n[0] = 2.4 * TMath::Tan(30 * TMath::DegToRad());
2832 n[1] = 0.0;
2833 n[2] = 2.4;
2834 //
2835 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutmmh5", p, n, kHalfSpaceReach);
2836 //
2837 p[0] = 0.75;
2838 p[1] = 0.0;
2839 p[2] = 8.9;
2840 //
2841 n[0] = 2.4 * TMath::Tan(30 * TMath::DegToRad());
2842 n[1] = 0.0;
2843 n[2] = -2.4;
2844 //
2845 o2::base::TGeoGeometryUtils::makeHalfSpaceBox("cutmmh6", p, n, kHalfSpaceReach);
2846
2847 auto* tpcmmhc =
2848 new TGeoCompositeShape("TPC_MMHC", "tpcmmhc1-tpcmmhc2-(cutmmh1:cutmmh1_tr)-(cutmmh2:cutmmh2_tr)-(cutmmh3:cutmmh3_tr)-(cutmmh4:cutmmh4_tr)-(cutmmh5:cutmmh5_tr)-(cutmmh6:cutmmh6_tr)");
2849
2850 auto* tpcmmhcv = new TGeoVolume("TPC_MMHC", tpcmmhc, m6);
2851 //
2852 TGeoVolume* tpcmmh = new TGeoVolumeAssembly("TPC_MMH");
2853 //
2854 tpcmmh->AddNode(tpcmmhcv, 1, new TGeoTranslation(0.65 + 1.5, 1.85, 0.0));
2855 tpcmmh->AddNode(tpcmmhcv, 2, new TGeoCombiTrans(-0.65 - 1.5, 1.85, 0.0, rot111));
2856 tpcmmh->AddNode(tpcmmhs, 1, new TGeoTranslation(1.5, 0.0, 0.0));
2857 tpcmmh->AddNode(tpcmmhs, 2, new TGeoCombiTrans(-1.5, 0.0, 0.0, rot111));
2858 //
2859
2860 //
2861
2862 //--------------------------------------------
2863 //
2864 // guard ring resistor chain
2865 //
2866
2867 auto* gres1 = new TGeoTube(0., 0.375, 125.); // inside ifc
2868 //
2869 auto* vgres1 = new TGeoVolume("TPC_GRES1", gres1, m14);
2870
2871 //
2872 Double_t xrc, yrc;
2873 //
2874 xrc = 79.3 * TMath::Cos(350. * TMath::DegToRad());
2875 yrc = 79.3 * TMath::Sin(350. * TMath::DegToRad());
2876 //
2877 v9->AddNode(vgres1, 1, new TGeoTranslation(xrc, yrc, 126.9));
2878 v9->AddNode(vgres1, 2, new TGeoTranslation(xrc, yrc, -126.9));
2879 //
2880 xrc = 79.3 * TMath::Cos(190. * TMath::DegToRad());
2881 yrc = 79.3 * TMath::Sin(190. * TMath::DegToRad());
2882 //
2883 v9->AddNode(vgres1, 3, new TGeoTranslation(xrc, yrc, 126.9));
2884 v9->AddNode(vgres1, 4, new TGeoTranslation(xrc, yrc, -126.9));
2885 //------------------------------------------------------------------
2886 TGeoRotation refl("refl", 90., 0., 90., 90., 180., 0.);
2887 TGeoRotation rotrod("rotrod");
2888 //
2889 TGeoRotation* rotpos[2];
2890 //
2891 TGeoRotation* rotrod1[2];
2892 //
2893 // clamps holding rods
2894 //
2895 auto* clampi1 = new TGeoBBox("clampi1", 0.2, 3.1, 0.8);
2896 auto* clampi1v = new TGeoVolume("TPC_clampi1v", clampi1, m6);
2897 //
2898 pointstrap[0] = 0.49;
2899 pointstrap[1] = 0.375;
2900 //
2901 pointstrap[2] = 0.49;
2902 pointstrap[3] = -0.375;
2903 //
2904 pointstrap[4] = -0.49;
2905 pointstrap[5] = -0.375;
2906 //
2907 pointstrap[6] = -0.49;
2908 pointstrap[7] = 1.225;
2909 //
2910 pointstrap[8] = 0.49;
2911 pointstrap[9] = 0.375;
2912 //
2913 pointstrap[10] = 0.49;
2914 pointstrap[11] = -0.375;
2915 //
2916 pointstrap[12] = -0.49;
2917 pointstrap[13] = -0.375;
2918 //
2919 pointstrap[14] = -0.49;
2920 pointstrap[15] = 1.225;
2921 //
2922 auto* clitrap = new TGeoArb8("clitrap", 0.25, pointstrap);
2923 auto* clitrapv = new TGeoVolume("TPC_clitrapv", clitrap, m6);
2924 //
2925 auto* clamprot = new TGeoRotation();
2926 clamprot->RotateX(180.);
2927 //
2928 new TGeoBBox("clibox", 1.125, 3.1, .1);
2929 new TGeoTube("clitub", 0., 2.2, 0.1);
2930 //
2931 // copmisite shape for the clamp holder
2932 //
2933 auto* clitr1 = new TGeoTranslation("clitr1", 1.125, 0., 0.);
2934 clitr1->RegisterYourself();
2935 auto* clihold = new TGeoCompositeShape("clihold", "clibox-clitub:clitr1");
2936 auto* cliholdv = new TGeoVolume("TPC_cliholdv", clihold, m6);
2937 //
2938 // now assembly the whole inner clamp
2939 //
2940 TGeoVolume* iclamp = new TGeoVolumeAssembly("TPC_iclamp");
2941 //
2942 iclamp->AddNode(clampi1v, 1); // main box
2943 iclamp->AddNode(clitrapv, 1, new TGeoTranslation(0.69, -2.725, 0.35)); // trapezoids
2944 iclamp->AddNode(clitrapv, 2, new TGeoTranslation(0.69, -2.725, -0.35));
2945 iclamp->AddNode(clitrapv, 3, new TGeoCombiTrans(0.69, 2.725, 0.35, clamprot));
2946 iclamp->AddNode(clitrapv, 4, new TGeoCombiTrans(0.69, 2.725, -0.35, clamprot));
2947 iclamp->AddNode(cliholdv, 1, new TGeoTranslation(1.325, 0., 0.)); // holder
2948 //
2949 // outer clamps
2950 //
2951 auto* clampo1 = new TGeoBBox("clampo1", 0.25, 3.1, 1.);
2952 auto* clampo2 = new TGeoBBox("clampo2", 0.4, 0.85, 1.);
2953 //
2954 auto* clampo1v = new TGeoVolume("TPC_clampo1v", clampo1, m6);
2955 auto* clampo2v = new TGeoVolume("TPC_clampo2v", clampo2, m6);
2956 //
2957 auto* oclamp = new TGeoVolumeAssembly("TPC_oclamp");
2958 //
2959 oclamp->AddNode(clampo1v, 1);
2960 //
2961 oclamp->AddNode(clampo2v, 1, new TGeoTranslation(0.65, -2.25, 0));
2962 oclamp->AddNode(clampo2v, 2, new TGeoTranslation(0.65, 2.25, 0));
2963
2964 //
2965 pointstrap[0] = 0.375;
2966 pointstrap[1] = 0.75;
2967 pointstrap[2] = 0.375;
2968 pointstrap[3] = -0.35;
2969 pointstrap[4] = -0.375;
2970 pointstrap[5] = -0.35;
2971 pointstrap[6] = -0.375;
2972 pointstrap[7] = 0.35;
2973 //
2974 pointstrap[8] = 0.375;
2975 pointstrap[9] = 0.75;
2976 pointstrap[10] = 0.375;
2977 pointstrap[11] = -0.35;
2978 pointstrap[12] = -0.375;
2979 pointstrap[13] = -0.35;
2980 pointstrap[14] = -0.375;
2981 pointstrap[15] = 0.35;
2982 //
2983 auto* clotrap = new TGeoArb8("clotrap", 0.25, pointstrap);
2984 auto* clotrapv = new TGeoVolume("TPC_clotrapv", clotrap, m6);
2985 //
2986 oclamp->AddNode(clotrapv, 1, new TGeoTranslation(-0.625, -2.75, 0.35));
2987 oclamp->AddNode(clotrapv, 2, new TGeoTranslation(-0.625, -2.75, -0.35));
2988 oclamp->AddNode(clotrapv, 3, new TGeoCombiTrans(-0.625, 2.75, 0.35, clamprot));
2989 oclamp->AddNode(clotrapv, 4, new TGeoCombiTrans(-0.625, 2.75, -0.35, clamprot));
2990 //
2991 auto* clampo3 = new TGeoBBox("clampo3", 1.6, 0.45, .1);
2992 auto* clampo3v = new TGeoVolume("TPC_clampo3v", clampo3, m6);
2993 //
2994 oclamp->AddNode(clampo3v, 1, new TGeoTranslation(-1.85, 2.625, 0.));
2995 oclamp->AddNode(clampo3v, 2, new TGeoTranslation(-1.85, -2.625, 0));
2996 //
2997 auto* clampo4 = new TGeoTubeSeg("clampo4", 2.2, 3.1, 0.1, 90., 270.);
2998 auto* clampo4v = new TGeoVolume("TPC_clampo4v", clampo4, m6);
2999 //
3000 oclamp->AddNode(clampo4v, 1, new TGeoTranslation(-3.45, 0., 0.));
3001
3002 // v9 - drift gas
3003
3004 TGeoRotation rot102("rot102");
3005 rot102.RotateY(-90.);
3006
3007 for (Int_t i = 0; i < 18; i++) {
3008 Double_t angle, x, y;
3009 Double_t z, r;
3010 angle = TMath::DegToRad() * 20. * (Double_t)i;
3011 // inner rods
3012 r = 81.5;
3013 x = r * TMath::Cos(angle);
3014 y = r * TMath::Sin(angle);
3015 z = 126.;
3016 auto* rot12 = new TGeoRotation();
3017 rot12->RotateZ(-90.0 + i * 20.);
3018 v9->AddNode(tpcihpl, i + 1, new TGeoCombiTrans(x, y, 0., rot12));
3019 //
3020 if (i == 11) { // resistor rod inner
3021 rotrod.RotateZ(-90. + i * 20.);
3022 rotrod1[0] = new TGeoRotation();
3023 rotpos[0] = new TGeoRotation();
3024 //
3025 rotrod1[0]->RotateZ(90. + i * 20.);
3026 *rotpos[0] = refl * rotrod; // rotation+reflection
3027 v9->AddNode(tpcrrod, 1, new TGeoCombiTrans(x, y, z, rotrod1[0])); // A
3028 v9->AddNode(tpcrrod, 2, new TGeoCombiTrans(x, y, -z, rotpos[0])); // C
3029 } else {
3030 v9->AddNode(tpcmrod, i + 1, new TGeoTranslation(x, y, z)); // shaft
3031 v9->AddNode(tpcmrod, i + 19, new TGeoCombiTrans(x, y, -z, ref)); // muon
3032 }
3033 //
3034 // inner clamps positioning
3035 //
3036 r = 79.05;
3037 x = r * TMath::Cos(angle);
3038 y = r * TMath::Sin(angle);
3039 rot12 = new TGeoRotation();
3040 rot12->RotateZ(i * 20.);
3041 //
3042 // A-side
3043 v9->AddNode(iclamp, 7 * i + 1, new TGeoCombiTrans(x, y, 5.25, rot12));
3044 v9->AddNode(iclamp, 7 * i + 2, new TGeoCombiTrans(x, y, 38.25, rot12));
3045 v9->AddNode(iclamp, 7 * i + 3, new TGeoCombiTrans(x, y, 80.25, rot12));
3046 v9->AddNode(iclamp, 7 * i + 4, new TGeoCombiTrans(x, y, 122.25, rot12));
3047 v9->AddNode(iclamp, 7 * i + 5, new TGeoCombiTrans(x, y, 164.25, rot12));
3048 v9->AddNode(iclamp, 7 * i + 6, new TGeoCombiTrans(x, y, 206.25, rot12));
3049 v9->AddNode(iclamp, 7 * i + 7, new TGeoCombiTrans(x, y, 246.75, rot12));
3050 // C-side
3051 v9->AddNode(iclamp, 7 * i + 127, new TGeoCombiTrans(x, y, -5.25, rot12));
3052 v9->AddNode(iclamp, 7 * i + 128, new TGeoCombiTrans(x, y, -38.25, rot12));
3053 v9->AddNode(iclamp, 7 * i + 129, new TGeoCombiTrans(x, y, -80.25, rot12));
3054 v9->AddNode(iclamp, 7 * i + 130, new TGeoCombiTrans(x, y, -122.25, rot12));
3055 v9->AddNode(iclamp, 7 * i + 131, new TGeoCombiTrans(x, y, -164.25, rot12));
3056 v9->AddNode(iclamp, 7 * i + 132, new TGeoCombiTrans(x, y, -206.25, rot12));
3057 v9->AddNode(iclamp, 7 * i + 133, new TGeoCombiTrans(x, y, -246.75, rot12));
3058 //
3059 //--------------------------
3060 // outer rods
3061 r = 254.25;
3062 x = r * TMath::Cos(angle);
3063 y = r * TMath::Sin(angle);
3064 z = 126.;
3065 //
3066 // outer rod holder + outer left plug
3067 //
3068
3069 auto* rot33 = new TGeoRotation();
3070 rot33->RotateZ(-90 + i * 20.);
3071 //
3072 v9->AddNode(tpcohpl, i + 1, new TGeoCombiTrans(x, y, 0., rot33));
3073 //
3074 Double_t xxx = 256.297 * TMath::Cos((i * 20. + 10.) * TMath::DegToRad());
3075 Double_t yyy = 256.297 * TMath::Sin((i * 20. + 10.) * TMath::DegToRad());
3076 //
3077 TGeoRotation rot101("rot101");
3078 rot101.RotateZ(90. + i * 20. + 10.);
3079 auto* rot103 = new TGeoRotation("rot103");
3080 *rot103 = rot101 * rot102;
3081 //
3082 auto* trh100 = new TGeoCombiTrans(xxx, yyy, 0., rot103);
3083 //
3084 if (i == 2) {
3085 // main membrane holder
3086 v9->AddNode(tpcmmh, 1, trh100);
3087 } else {
3088 // "normal" membrane holder
3089 v9->AddNode(tpcomh, i + 1, trh100);
3090 }
3091
3092 //
3093 if (i == 3) { // resistor rod outer
3094 rotrod.RotateZ(90. + i * 20.);
3095 rotrod1[1] = new TGeoRotation();
3096 rotpos[1] = new TGeoRotation();
3097 rotrod1[1]->RotateZ(90. + i * 20.);
3098 *rotpos[1] = refl * rotrod; // rotation+reflection
3099 v9->AddNode(tpcrrod, 3, new TGeoCombiTrans(x, y, z, rotrod1[1])); // A
3100 v9->AddNode(tpcrrod, 4, new TGeoCombiTrans(x, y, -z, rotpos[1])); // C
3101 } else {
3102 v9->AddNode(tpcmrod, i + 37, new TGeoTranslation(x, y, z)); // shaft
3103 v9->AddNode(tpcmrod, i + 55, new TGeoCombiTrans(x, y, -z, ref)); // muon
3104 }
3105 if (i == 15) {
3106 v9->AddNode(hvrv, 1, new TGeoTranslation(x, y, z + 0.7)); // hv->A-side only
3107 }
3108 //
3109 // outer clamps
3110 //
3111 r = 256.9;
3112 x = r * TMath::Cos(angle);
3113 y = r * TMath::Sin(angle);
3114 rot12 = new TGeoRotation();
3115 rot12->RotateZ(i * 20.);
3116 //
3117 // A-side
3118 v9->AddNode(oclamp, 7 * i + 1, new TGeoCombiTrans(x, y, 5.25, rot12));
3119 v9->AddNode(oclamp, 7 * i + 2, new TGeoCombiTrans(x, y, 38.25, rot12));
3120 v9->AddNode(oclamp, 7 * i + 3, new TGeoCombiTrans(x, y, 80.25, rot12));
3121 v9->AddNode(oclamp, 7 * i + 4, new TGeoCombiTrans(x, y, 122.25, rot12));
3122 v9->AddNode(oclamp, 7 * i + 5, new TGeoCombiTrans(x, y, 164.25, rot12));
3123 v9->AddNode(oclamp, 7 * i + 6, new TGeoCombiTrans(x, y, 206.25, rot12));
3124 v9->AddNode(oclamp, 7 * i + 7, new TGeoCombiTrans(x, y, 246.75, rot12));
3125 // C-side
3126 v9->AddNode(oclamp, 7 * i + 127, new TGeoCombiTrans(x, y, -5.25, rot12));
3127 v9->AddNode(oclamp, 7 * i + 128, new TGeoCombiTrans(x, y, -38.25, rot12));
3128 v9->AddNode(oclamp, 7 * i + 129, new TGeoCombiTrans(x, y, -80.25, rot12));
3129 v9->AddNode(oclamp, 7 * i + 130, new TGeoCombiTrans(x, y, -122.25, rot12));
3130 v9->AddNode(oclamp, 7 * i + 131, new TGeoCombiTrans(x, y, -164.25, rot12));
3131 v9->AddNode(oclamp, 7 * i + 132, new TGeoCombiTrans(x, y, -206.25, rot12));
3132 v9->AddNode(oclamp, 7 * i + 133, new TGeoCombiTrans(x, y, -246.75, rot12));
3133
3134 } // end of rods positioning
3135
3136 TGeoVolume* alice = gGeoManager->GetVolume("barrel");
3137 alice->AddNode(v1, 1, new TGeoTranslation(0., 30., 0.));
3138
3139} // end of function
3140
3141void Detector::LoadGeometryFromFile()
3142{
3143 // ===| Read the TPC geometry from file |=====================================
3144 if (mGeoFileName.IsNull()) {
3145 LOG(fatal) << "TPC geometry file name not set";
3146 return;
3147 }
3148
3149 TFile* fGeoFile = TFile::Open(mGeoFileName);
3150 if (!fGeoFile || !fGeoFile->IsOpen() || fGeoFile->IsZombie()) {
3151 LOG(fatal) << "Could not open TPC geometry file '" << mGeoFileName << "'";
3152 return;
3153 }
3154
3155 TGeoVolume* tpcVolume = dynamic_cast<TGeoVolume*>(fGeoFile->Get("TPC_M"));
3156 if (!tpcVolume) {
3157 LOG(fatal) << "Could not retrieve TPC geometry from file '" << mGeoFileName << "'";
3158 return;
3159 }
3160
3161 LOG(info) << "Loaded TPC geometry from file '" << mGeoFileName << "'";
3162 TGeoVolume* alice = gGeoManager->GetVolume("barrel");
3163 alice->AddNode(tpcVolume, 1, new TGeoTranslation(0., 30., 0.));
3164}
3165
3166void Detector::defineSensitiveVolumes()
3167{
3168 TGeoManager* geoManager = gGeoManager;
3169 TGeoVolume* v = nullptr;
3170
3171 // const Int_t nSensitive=2;
3172 // const char* volumeNames[nSensitive]={"TPC_Drift","TPC_Strip"};
3173 const Int_t nSensitive = 1;
3174 const char* volumeNames[nSensitive] = {"TPC_Drift"};
3175
3176 // The names of the ITS sensitive volumes have the format: ITSUSensor(0...mNumberLayers-1)
3177 for (Int_t ivol = 0; ivol < nSensitive; ++ivol) {
3178 TString volumeName = volumeNames[ivol];
3179 v = geoManager->GetVolume(volumeName.Data());
3180 if (!v) {
3181 LOG(error) << "Could not find volume '" << volumeName << "'";
3182 continue;
3183 }
3184
3185 // set volume sentive
3186 AddSensitiveVolume(v);
3187 }
3188
3189 // Special sensitive volume parameters in case FLUKA is used as transport engine
3190 auto vmc = TVirtualMC::GetMC();
3191 if (strcmp(vmc->GetName(), "TFluka") == 0) {
3192 LOG(info) << "Setting special FLUKA parameters for TPC Driftgas";
3194 Int_t index = mgr.getMediumID("TPC", kDriftGas2);
3195 vmc->Gstpar(index, "PRIMIO_E", 20.77);
3196 vmc->Gstpar(index, "PRIMIO_N", 14.35);
3197 vmc->Gstpar(index, "LOSS", 14);
3198 vmc->Gstpar(index, "STRA", 4);
3199 }
3200}
3201
3202Double_t Detector::Gamma(Double_t k)
3203{
3204 static thread_local Double_t n = 0;
3205 static thread_local Double_t c1 = 0;
3206 static thread_local Double_t c2 = 0;
3207 static thread_local Double_t b1 = 0;
3208 static thread_local Double_t b2 = 0;
3209 if (k > 0) {
3210 if (k < 0.4) {
3211 n = 1. / k;
3212 } else if (k >= 0.4 && k < 4) {
3213 n = 1. / k + (k - 0.4) / k / 3.6;
3214 } else if (k >= 4.) {
3215 n = 1. / TMath::Sqrt(k);
3216 }
3217 b1 = k - 1. / n;
3218 b2 = k + 1. / n;
3219 c1 = (k < 0.4) ? 0 : b1 * (TMath::Log(b1) - 1.) / 2.;
3220 c2 = b2 * (TMath::Log(b2) - 1.) / 2.;
3221 }
3222 Double_t x;
3223 Double_t y = -1.;
3224 while (1) {
3225 Double_t nu1 = gRandom->Rndm();
3226 Double_t nu2 = gRandom->Rndm();
3227 Double_t w1 = c1 + TMath::Log(nu1);
3228 Double_t w2 = c2 + TMath::Log(nu2);
3229 y = n * (b1 * w2 - b2 * w1);
3230 if (y < 0) {
3231 continue;
3232 }
3233 x = n * (w2 - w1);
3234 if (TMath::Log(y) >= x) {
3235 break;
3236 }
3237 }
3238 return TMath::Exp(x);
3239}
3240
3241std::string Detector::getHitBranchNames(int probe) const
3242{
3243 if (probe >= 0 && probe < Sector::MAXSECTOR) {
3244 TString name;
3245 name.Form("%sHitsShiftedSector%d", GetName(), probe);
3246 return std::string(name.Data());
3247 }
3248 return std::string();
3249}
3250
3252
3253// Define Factory method for calling from the outside
3254extern "C" {
3259}
Definition of the Stack class.
int16_t time
Definition RawEventData.h:4
int32_t i
constexpr int p1()
constexpr to accelerate the coordinates changing
ClassImp(IdPath)
Definition of the parameter class for the detector.
Definition of the parameter class for the detector gas.
Class for TPC Point.
uint16_t slope
Definition RawData.h:1
uint32_t res
Definition RawData.h:0
uint32_t stack
Definition RawData.h:1
Collection of utility functions for TGeo.
o2::base::Detector * create_detector_tpc(bool active)
virtual std::string getHitBranchNames(int probe) const =0
~Detector() override
Default Destructor.
Definition Detector.cxx:95
Detector()
Default Constructor.
Definition Detector.cxx:36
void Mixture(Int_t imat, const char *name, Float_t *a, Float_t *z, Float_t dens, Int_t nlmat, Float_t *wmat)
Definition Detector.cxx:66
void Medium(Int_t numed, const char *name, Int_t nmat, Int_t isvol, Int_t ifield, Float_t fieldm, Float_t tmaxfd, Float_t stemax, Float_t deemax, Float_t epsil, Float_t stmin, Float_t *ubuf=nullptr, Int_t nbuf=0)
Definition Detector.cxx:72
static void initFieldTrackingParams(int &mode, float &maxfield)
Definition Detector.cxx:143
void Material(Int_t imat, const char *name, Float_t a, Float_t z, Float_t dens, Float_t radl, Float_t absl, Float_t *buf=nullptr, Int_t nwbuf=0)
Definition Detector.cxx:59
virtual void InitializeO2Detector()=0
Definition Detector.cxx:106
static MaterialManager & Instance()
static void makeHalfSpaceBox(const char *name, const double p[3], const double n[3], double reach)
void addTrackReference(const o2::TrackReference &p)
Definition Stack.h:335
void Reset() override
void ConstructGeometry() override
Double_t Gamma(Double_t k)
Bool_t ProcessHits(FairVolume *v=nullptr) override
void Register() override
void EndOfEvent() override
static o2::base::Detector * create(bool active)
Definition Detector.h:72
void addHit(float x, float y, float z, float time, float e)
Definition Point.h:120
static int ToShiftedSector(T x, T y, T z)
Definition Sector.h:126
static int ToSector(T x, T y, T z)
Definition Sector.h:107
static constexpr int MAXSECTOR
Definition Sector.h:44
static ShmManager & Instance()
Definition ShmManager.h:61
GLdouble n
Definition glcorearb.h:1982
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
const GLdouble * v
Definition glcorearb.h:832
GLuint index
Definition glcorearb.h:781
GLuint const GLchar * name
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint y
Definition glcorearb.h:270
GLuint GLfloat x0
Definition glcorearb.h:5034
GLfloat angle
Definition glcorearb.h:4071
GLfloat GLfloat v1
Definition glcorearb.h:812
GLboolean r
Definition glcorearb.h:1233
GLfloat GLfloat GLfloat GLfloat v3
Definition glcorearb.h:814
GLfloat GLfloat GLfloat v2
Definition glcorearb.h:813
GLuint GLfloat GLfloat y0
Definition glcorearb.h:5034
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition glcorearb.h:5034
double norm(const Vec3 &vector)
std::optional< Chamber > chamber(int chamberId)
Definition Chamber.cxx:17
std::array< uint64_t, 23 > m2
std::array< uint64_t, 17 > m5
std::array< uint64_t, 17 > m4
std::array< uint64_t, 23 > m3
std::array< uint64_t, 23 > m1
Global TPC definitions and constants.
Definition SimTraits.h:172
constexpr double cm
Definition Specs.h:31
void freeSimVector(std::vector< T > *ptr)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
TStopwatch sw