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