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