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
13
14#include "DetectorsBase/Stack.h"
15
16#include "TRKBase/Specs.h"
18#include "TRKSimulation/Hit.h"
21#include <TGeoVolume.h>
22#include <TVirtualMC.h>
23#include <TVirtualMCStack.h>
24
25#include <FairVolume.h>
26
27#include <string>
28#include <type_traits>
29
30using o2::trk::Hit;
31
32namespace o2
33{
34namespace trk
35{
36
37float getDetLengthFromEta(const float eta, const float radius)
38{
39 return 2. * (10. + radius * std::cos(2 * std::atan(std::exp(-eta))));
40}
41
43 : o2::base::DetImpl<Detector>("TRK", true),
44 mTrackData(),
45 mHits(o2::utils::createSimVector<o2::trk::Hit>())
46{
47}
48
49Detector::Detector(bool active)
50 : o2::base::DetImpl<Detector>("TRK", true),
51 mTrackData(),
52 mHits(o2::utils::createSimVector<o2::trk::Hit>())
53{
54 auto& trkPars = TRKBaseParam::Instance();
55
56 if (trkPars.configFile != "") {
57 configFromFile(trkPars.configFile);
58 } else {
59 configMLOT();
60 configToFile();
61 configServices();
62 }
63
64 LOGP(info, "Summary of TRK configuration:");
65 for (auto& layer : mLayers) {
66 LOGP(info, "Layer: {} name: {} r: {} cm | z: {} cm | thickness: {} cm", layer->getNumber(), layer->getName(), layer->getInnerRadius(), layer->getZ(), layer->getChipThickness());
67 }
68}
69
70Detector::Detector(const Detector& other)
71 : o2::base::DetImpl<Detector>(other),
72 mTrackData(),
73 mHits(o2::utils::createSimVector<o2::trk::Hit>())
74{
75}
76
77Detector::~Detector()
78{
79 if (mHits) {
81 }
82}
83
84void Detector::ConstructGeometry()
85{
88}
89
90void Detector::configMLOT()
91{
92 auto& trkPars = TRKBaseParam::Instance();
93
94 mLayers.clear();
95
96 const std::vector<float> rInn{7.f, 9.f, 12.f, 20.f, 30.f, 45.f, 60.f, 80.f};
97 const float thick = 100.e-3;
98
99 switch (trkPars.layoutMLOT) {
100 case kCylindrical: {
101 const std::vector<float> length{127.985f, 127.985f, 127.985f, 127.985f, 127.985f, 255.9f, 255.9f, 255.9f};
102 LOGP(warning, "Loading cylindrical configuration for ALICE3 TRK");
103 for (int i{0}; i < constants::ML::nLayers + constants::OT::nLayers; ++i) {
104 std::string name = GeometryTGeo::getTRKLayerPattern() + std::to_string(i);
105 mLayers.push_back(std::make_unique<TRKCylindricalLayer>(i, name, rInn[i], length[i], thick, MatBudgetParamMode::Thickness));
106 }
107 break;
108 }
109 case kSegmented: {
110 const std::vector<float> tiltAngles{11.2f, 11.9f, 11.4f, 0.f, 0.f, 0.f, 0.f, 0.f};
111 // const std::vector<float> tiltAngles{10.f, 16.1f, 19.2f, 0.f, 0.f, 0.f, 0.f, 0.f};
112 const std::vector<int> nStaves{10, 14, 18, 26, 38, 32, 42, 56};
113 // const std::vector<int> nStaves{10, 16, 22, 26, 38, 32, 42, 56};
114 const std::vector<int> nMods{11, 11, 11, 11, 11, 22, 22, 22};
115
116 const std::vector<float> stagOffsets{0.f, 0.f, 0.f, 1.17f, 0.89f};
117
118 LOGP(warning, "Loading segmented configuration for ALICE3 TRK");
119 for (int i{0}; i < constants::ML::nLayers + constants::OT::nLayers; ++i) {
120 std::string name = GeometryTGeo::getTRKLayerPattern() + std::to_string(i);
121 if (i < constants::ML::nLayers) {
122 mLayers.push_back(std::make_unique<TRKMLLayer>(i, name, rInn[i], stagOffsets[i], tiltAngles[i], nStaves[i], nMods[i], thick, MatBudgetParamMode::Thickness));
123 } else {
124 mLayers.push_back(std::make_unique<TRKOTLayer>(i, name, rInn[i], tiltAngles[i], nStaves[i], nMods[i], thick, MatBudgetParamMode::Thickness));
125 }
126 }
127 break;
128 }
129 default:
130 LOGP(fatal, "Unknown option {} for configMLOT", static_cast<int>(trkPars.layoutMLOT));
131 break;
132 }
133}
134
135void Detector::configFromFile(std::string fileName)
136{
137 // Override the default geometry if config file provided
138 std::ifstream confFile(fileName);
139 if (!confFile.good()) {
140 LOGP(fatal, "File {} not found, aborting.", fileName);
141 }
142
143 auto& trkPars = TRKBaseParam::Instance();
144
145 mLayers.clear();
146
147 LOGP(info, "Overriding geometry of ALICE3 TRK using {} file.", fileName);
148
149 std::string line;
150 std::vector<float> tmpBuff;
151 int layerCount{0};
152 while (std::getline(confFile, line)) {
153 if (line[0] == '/') {
154 continue;
155 }
156 tmpBuff.clear();
157 std::stringstream ss(line);
158 float val;
159 std::string substr;
160 while (getline(ss, substr, '\t')) {
161 tmpBuff.push_back(std::stof(substr));
162 }
163
164 std::string name = GeometryTGeo::getTRKLayerPattern() + std::to_string(layerCount);
165
166 switch (trkPars.layoutMLOT) {
167 case kCylindrical: {
168 // Expected column mapping in the text file (separated by \t):
169 // tmpBuff[0] = rInn
170 // tmpBuff[1] = length
171 // tmpBuff[2] = thick
172 // tmpBuff[3] = matBudgetMode (optional, default = Thickness)
173
174 // Cylindrical requires at least 3 parameters
175 if (tmpBuff.size() < 3) {
176 LOGP(fatal, "Invalid configuration for cylindrical layer {}: insufficient parameters.", layerCount);
177 }
178
179 float rInn = tmpBuff[0];
180 float length = tmpBuff[1];
181 float thick = tmpBuff[2];
182
183 // Default mode is Thickness
184 MatBudgetParamMode matBudgetMode = MatBudgetParamMode::Thickness;
185 if (tmpBuff.size() >= 4) {
186 matBudgetMode = static_cast<MatBudgetParamMode>(static_cast<int>(tmpBuff[3]));
187 }
188
189 mLayers.push_back(std::make_unique<TRKCylindricalLayer>(layerCount, name, rInn, length, thick, matBudgetMode));
190 break;
191 }
192 case kSegmented: {
193 // Expected column mapping in the text file (separated by \t):
194 // tmpBuff[0] = rInn
195 // tmpBuff[1] = thick
196 // tmpBuff[2] = tiltAngle
197 // tmpBuff[3] = nStaves
198 // tmpBuff[4] = nMods
199 // tmpBuff[5] = stagOffset (required ONLY for ML)
200 // tmpBuff[6] = matBudgetMode (optional, default = Thickness)
201
202 // Base parameters for all segmented layers (at least 5 needed)
203 if (tmpBuff.size() < 5) {
204 LOGP(fatal, "Invalid configuration for segmented layer {}: missing base parameters.", layerCount);
205 }
206
207 float rInn = tmpBuff[0];
208 float thick = tmpBuff[1];
209 float tiltAngle = tmpBuff[2];
210 int nStaves = static_cast<int>(tmpBuff[3]);
211 int nMods = static_cast<int>(tmpBuff[4]);
212
213 // Default mode is Thickness
214 MatBudgetParamMode matBudgetMode = MatBudgetParamMode::Thickness;
215
216 if (layerCount < constants::ML::nLayers) {
217 // ML layers require stagOffset (index 5)
218 if (tmpBuff.size() < 6) {
219 LOGP(fatal, "Invalid configuration for ML layer {}: stagOffset is missing.", layerCount);
220 }
221 float stagOffset = tmpBuff[5];
222
223 if (tmpBuff.size() >= 7) {
224 matBudgetMode = static_cast<MatBudgetParamMode>(static_cast<int>(tmpBuff[6]));
225 }
226
227 mLayers.push_back(std::make_unique<TRKMLLayer>(layerCount, name, rInn, stagOffset, tiltAngle, nStaves, nMods, thick, matBudgetMode));
228 } else {
229 // OT layers do NOT have stagOffset. The optional mode is at index 5.
230 if (tmpBuff.size() >= 6) {
231 matBudgetMode = static_cast<MatBudgetParamMode>(static_cast<int>(tmpBuff[5]));
232 }
233
234 mLayers.push_back(std::make_unique<TRKOTLayer>(layerCount, name, rInn, tiltAngle, nStaves, nMods, thick, matBudgetMode));
235 }
236 break;
237 }
238 default:
239 LOGP(fatal, "Unknown option {} for configMLOT", static_cast<int>(trkPars.layoutMLOT));
240 break;
241 }
242
243 ++layerCount;
244 }
245}
246
247void Detector::configToFile(std::string fileName)
248{
249 LOGP(info, "Exporting TRK Detector layout to {}", fileName);
250 std::ofstream conFile(fileName.c_str(), std::ios::out);
251 conFile << "/// TRK configuration file: inn_radius z_length lay_thickness" << std::endl;
252 for (const auto& layer : mLayers) {
253 conFile << layer->getInnerRadius() << "\t" << layer->getZ() << "\t" << layer->getChipThickness() << std::endl;
254 }
255}
256
257void Detector::configServices()
258{
259 mServices = TRKServices();
260}
261
262void Detector::createMaterials()
263{
264 int ifield = 2; // ?
265 float fieldm = 10.0; // ?
267
268 float tmaxfdSi = 0.1; // .10000E+01; // Degree
269 float stemaxSi = 0.0075; // .10000E+01; // cm
270 float deemaxSi = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
271 float epsilSi = 1.0E-4; // .10000E+01;
272 float stminSi = 0.0; // cm "Default value used"
273
274 float tmaxfdAir = 0.1; // .10000E+01; // Degree
275 float stemaxAir = .10000E+01; // cm
276 float deemaxAir = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
277 float epsilAir = 1.0E-4; // .10000E+01;
278 float stminAir = 0.0; // cm "Default value used"
279
280 float tmaxfdCer = 0.1; // .10000E+01; // Degree
281 float stemaxCer = .10000E+01; // cm
282 float deemaxCer = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
283 float epsilCer = 1.0E-4; // .10000E+01;
284 float stminCer = 0.0; // cm "Default value used"
285
286 // AIR
287 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
288 float zAir[4] = {6., 7., 8., 18.};
289 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
290 float dAir = 1.20479E-3;
291
292 // Carbon fiber
293 float aCf[2] = {12.0107, 1.00794};
294 float zCf[2] = {6., 1.};
295
296 o2::base::Detector::Mixture(1, "AIR$", aAir, zAir, dAir, 4, wAir);
297 o2::base::Detector::Medium(1, "AIR$", 1, 0, ifield, fieldm, tmaxfdAir, stemaxAir, deemaxAir, epsilAir, stminAir);
298
299 o2::base::Detector::Material(3, "SILICON$", 0.28086E+02, 0.14000E+02, 0.23300E+01, 0.93600E+01, 0.99900E+03);
300 o2::base::Detector::Medium(3, "SILICON$", 3, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
301}
302
303void Detector::createGeometry()
304{
305 TGeoManager* geoManager = gGeoManager;
306 TGeoVolume* vALIC = geoManager->GetVolume("barrel");
307 if (!vALIC) {
308 LOGP(fatal, "Could not find barrel volume while constructing TRK geometry");
309 }
310 new TGeoVolumeAssembly(GeometryTGeo::getTRKVolPattern());
311 TGeoVolume* vTRK = geoManager->GetVolume(GeometryTGeo::getTRKVolPattern());
312 vALIC->AddNode(vTRK, 2, new TGeoTranslation(0, 30., 0));
313
314 char vstrng[100] = "TRKVol";
315 vTRK->SetTitle(vstrng);
316
317 for (auto& layer : mLayers) {
318 layer->createLayer(vTRK);
319 }
320
321 // Add service for inner tracker
322 mServices.createServices(vTRK);
323
324 // Build the VD using the petal builder
325 // Choose the VD design based on TRKBaseParam.layoutVD
326 auto& trkPars = TRKBaseParam::Instance();
327
329
330 switch (trkPars.layoutVD) {
331 case kIRIS4:
332 LOG(info) << "Building VD with IRIS4 layout";
334 break;
335 case kIRISFullCyl:
336 LOG(info) << "Building VD with IRIS fully cylindrical layout";
338 break;
340 LOG(info) << "Building VD with IRIS fully cylindrical layout with 3 inclined walls";
342 break;
343 case kIRIS5:
344 LOG(info) << "Building VD with IRIS5 layout";
346 break;
347 case kIRIS4a:
348 LOG(info) << "Building VD with IRIS4a layout";
350 break;
351 default:
352 LOG(fatal) << "Unknown VD layout option: " << static_cast<int>(trkPars.layoutVD);
353 break;
354 }
355
356 // Fill sensor names from registry right after geometry creation
357 const auto& regs = o2::trk::vdSensorRegistry();
358 mNumberOfVolumesVD = static_cast<int>(regs.size());
359 mNumberOfVolumes = mNumberOfVolumesVD + mLayers.size();
360 mSensorName.resize(mNumberOfVolumes);
361
362 // Fill VD sensor names from registry
363 int VDvolume = 0;
364 for (const auto& sensor : regs) {
365 mSensorName[VDvolume] = sensor.name;
366 VDvolume++;
367 }
368
369 // Add MLOT sensor names
370 for (int i = 0; i < mLayers.size(); i++) {
371 mSensorName[VDvolume++].Form("%s%d", GeometryTGeo::getTRKSensorPattern(), i);
372 }
373
374 for (auto vd : mSensorName) {
375 std::cout << "Volume name: " << vd << std::endl;
376 }
377
378 mServices.excavateFromVacuum("IRIS_CUTOUTsh");
379 mServices.registerVacuum(vTRK);
380}
381
382void Detector::InitializeO2Detector()
383{
384 LOG(info) << "Initialize TRK O2Detector";
385 mGeometryTGeo = GeometryTGeo::Instance();
386 defineSensitiveVolumes();
387
388 mSensorID.resize(mNumberOfVolumes); // hardcoded. TODO: change size when a different namingh scheme for VD is in place. Ideally could be 4 petals + 8 layers = 12
389 for (int i = 0; i < mNumberOfVolumes; i++) {
390 mSensorID[i] = gMC ? TVirtualMC::GetMC()->VolId(mSensorName[i]) : 0; // Volume ID from the Geant geometry
391 LOGP(info, "{}: mSensorID={}, mSensorName={}", i, mSensorID[i], mSensorName[i].Data());
392 }
393}
394
395void Detector::defineSensitiveVolumes()
396{
397 TGeoManager* geoManager = gGeoManager;
398 TGeoVolume* v;
399
400 TString volumeName;
401 LOGP(info, "Adding TRK Sensitive Volumes");
402
403 // Register VD sensors created by VDGeometryBuilder
404 for (const auto& s : o2::trk::vdSensorRegistry()) {
405 TGeoVolume* v = gGeoManager->GetVolume(s.name.c_str());
406 if (!v) {
407 LOGP(warning, "VD sensor volume '{}' not found", s.name);
408 continue;
409 }
410 LOGP(info, "Adding VD Sensitive Volume {}", v->GetName());
411 AddSensitiveVolume(v);
412 // Optionally track first/last layers for TR references:
413 if (s.region == o2::trk::VDSensorDesc::Region::Barrel && (s.idx == 0 /*innermost*/)) {
414 mFirstOrLastLayers.push_back(s.name);
415 }
416 }
417
418 // The names of the TRK sensitive volumes have the format: TRKLayer(0...mLayers.size()-1)
419 for (int j{0}; j < mLayers.size(); j++) {
420 volumeName = GeometryTGeo::getTRKSensorPattern() + TString::Itoa(j, 10);
421 if (j == mLayers.size() - 1) {
422 mFirstOrLastLayers.push_back(volumeName.Data());
423 }
424 LOGP(info, "Trying {}", volumeName.Data());
425 v = geoManager->GetVolume(volumeName.Data());
426 LOGP(info, "Adding TRK Sensitive Volume {}", v->GetName());
427 AddSensitiveVolume(v);
428 }
429}
430
431void Detector::EndOfEvent() { Reset(); }
432
433void Detector::Register()
434{
435 // This will create a branch in the output tree called Hit, setting the last
436 // parameter to kFALSE means that this collection will not be written to the file,
437 // it will exist only during the simulation
438
439 if (FairRootManager::Instance()) {
440 FairRootManager::Instance()->RegisterAny(addNameTo("Hit").data(), mHits, true);
441 }
442}
443
444void Detector::Reset()
445{
446 if (!o2::utils::ShmManager::Instance().isOperational()) {
447 mHits->clear();
448 }
449}
450
451bool Detector::InsideFirstOrLastLayer(std::string layerName)
452{
453 bool inside = false;
454 for (auto& firstOrLastLayer : mFirstOrLastLayers) {
455 if (firstOrLastLayer == layerName) {
456 inside = true;
457 break;
458 }
459 }
460 return inside;
461}
462
463bool Detector::ProcessHits(FairVolume* vol)
464{
465 // This method is called from the MC stepping
466 if (!(fMC->TrackCharge())) {
467 return false;
468 }
469
470 int subDetID = -1;
471 int layer = -1;
472 int volume = 0;
473 int volID = vol->getMCid();
474
475 bool notSens = false;
476 while ((volume < mNumberOfVolumes) && (notSens = (volID != mSensorID[volume]))) {
477 ++volume;
478 }
479
480 if (notSens) {
481 return kFALSE; // RS: can this happen? This method must be called for sensors only?
482 }
483
484 if (volume < mNumberOfVolumesVD) {
485 subDetID = 0; // VD. For the moment each "chip" is a volume./// TODO: change this logic once the naming scheme is changed
486 } else {
487 subDetID = 1; // MLOT
488 layer = volume - mNumberOfVolumesVD;
489 }
490
491 // Is it needed to keep a track reference when the outer ITS volume is encountered?
492 auto stack = (o2::data::Stack*)fMC->GetStack();
493 // if (fMC->IsTrackExiting() && (lay == 0 || lay == mLayers.size() - 1)) {
494 if (fMC->IsTrackExiting() && InsideFirstOrLastLayer(vol->GetName())) {
495 // Keep the track refs for the innermost and outermost layers only
496 o2::TrackReference tr(*fMC, GetDetId());
497 tr.setTrackID(stack->GetCurrentTrackNumber());
498 tr.setUserId(volume);
499 stack->addTrackReference(tr);
500 }
501 bool startHit = false, stopHit = false;
502 unsigned char status = 0;
503 if (fMC->IsTrackEntering()) {
504 status |= Hit::kTrackEntering;
505 }
506 if (fMC->IsTrackInside()) {
507 status |= Hit::kTrackInside;
508 }
509 if (fMC->IsTrackExiting()) {
510 status |= Hit::kTrackExiting;
511 }
512 if (fMC->IsTrackOut()) {
513 status |= Hit::kTrackOut;
514 }
515 if (fMC->IsTrackStop()) {
516 status |= Hit::kTrackStopped;
517 }
518 if (fMC->IsTrackAlive()) {
519 status |= Hit::kTrackAlive;
520 }
521
522 // track is entering or created in the volume
523 if ((status & Hit::kTrackEntering) || (status & Hit::kTrackInside && !mTrackData.mHitStarted)) {
524 startHit = true;
525 } else if ((status & (Hit::kTrackExiting | Hit::kTrackOut | Hit::kTrackStopped))) {
526 stopHit = true;
527 }
528
529 // increment energy loss at all steps except entrance
530 if (!startHit) {
531 mTrackData.mEnergyLoss += fMC->Edep();
532 }
533 if (!(startHit | stopHit)) {
534 return false; // do noting
535 }
536
537 if (startHit) {
538 mTrackData.mEnergyLoss = 0.;
539 fMC->TrackMomentum(mTrackData.mMomentumStart);
540 fMC->TrackPosition(mTrackData.mPositionStart);
541 mTrackData.mTrkStatusStart = status;
542 mTrackData.mHitStarted = true;
543 }
544 if (stopHit) {
545 TLorentzVector positionStop;
546 fMC->TrackPosition(positionStop);
547
548 // Retrieve the indices with the volume path
549 int stave(0), halfstave(0), mod(0), chip(0);
550
551 auto& trkPars = TRKBaseParam::Instance();
552
553 if (subDetID == 1) {
554 if (trkPars.layoutMLOT == o2::trk::eMLOTLayout::kSegmented) {
555 fMC->CurrentVolOffID(1, chip);
556 fMC->CurrentVolOffID(2, mod);
557 if (mGeometryTGeo->getNumberOfHalfStaves(layer) == 2) {
558 fMC->CurrentVolOffID(3, halfstave);
559 fMC->CurrentVolOffID(4, stave);
560 } else if (mGeometryTGeo->getNumberOfHalfStaves(layer) == 1) {
561 fMC->CurrentVolOffID(3, stave);
562 } else {
563 LOGP(fatal, "Wrong number of halfstaves for layer {}", layer);
564 }
565 }
566 }
567
568 unsigned short chipID = mGeometryTGeo->getChipIndex(subDetID, volume, layer, stave, halfstave, mod, chip);
569
570 // Print(vol, volume, subDetID, layer, stave, halfstave, mod, chip, chipID);
571
572 // mGeometryTGeo->Print();
573
574 Hit* p = addHit(stack->GetCurrentTrackNumber(), chipID, mTrackData.mPositionStart.Vect(), positionStop.Vect(),
575 mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(),
576 mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status);
577 // p->SetTotalEnergy(vmc->Etot());
578
579 // RS: not sure this is needed
580 // Increment number of Detector det points in TParticle
581 stack->addHit(GetDetId());
582 }
583
584 return true;
585}
586
587o2::trk::Hit* Detector::addHit(int trackID, unsigned short detID, const TVector3& startPos, const TVector3& endPos,
588 const TVector3& startMom, double startE, double endTime, double eLoss, unsigned char startStatus,
589 unsigned char endStatus)
590{
591 mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus);
592 return &(mHits->back());
593}
594
595void Detector::Print(FairVolume* vol, int volume, int subDetID, int layer, int stave, int halfstave, int mod, int chip, int chipID) const
596{
597 int currentVol(0);
598 LOG(info) << "Current volume name: " << fMC->CurrentVolName() << " and ID " << fMC->CurrentVolID(currentVol);
599 LOG(info) << "volume: " << volume << "/" << mNumberOfVolumes - 1;
600
601 auto& trkPars = TRKBaseParam::Instance();
602
603 if (subDetID == 1) { // MLOT
604 if (trkPars.layoutMLOT == o2::trk::eMLOTLayout::kCylindrical) {
605 LOG(info) << "off volume name 1 " << fMC->CurrentVolOffName(1) << " chip: " << chip;
606 LOG(info) << "SubDetector ID: " << subDetID << " Layer: " << layer << " Chip ID: " << chipID;
607 } else {
608 LOG(info) << "off volume name 1 " << fMC->CurrentVolOffName(1) << " chip: " << chip;
609 LOG(info) << "off volume name 2 " << fMC->CurrentVolOffName(2) << " module: " << mod;
610 if (mGeometryTGeo->getNumberOfHalfStaves(layer) == 2) { // staggered geometry
611 LOG(info) << "off volume name 3 " << fMC->CurrentVolOffName(3) << " halfstave: " << halfstave;
612 LOG(info) << "off volume name 4 " << fMC->CurrentVolOffName(4) << " stave: " << stave;
613 LOG(info) << "SubDetector ID: " << subDetID << " Layer: " << layer << " staveinLayer: " << stave << " Chip ID: " << chipID;
614 } else if (mGeometryTGeo->getNumberOfHalfStaves(layer) == 1) { // turbo geometry
615 LOG(info) << "off volume name 3 " << fMC->CurrentVolOffName(3) << " stave: " << stave;
616 LOG(info) << "SubDetector ID: " << subDetID << " Layer: " << layer << " staveinLayer: " << stave << " Chip ID: " << chipID;
617 }
618 }
619 } else {
620 // VD
621 LOG(info) << "SubDetector ID: " << subDetID << " Chip ID: " << chipID;
622 }
623
624 LOG(info);
625}
626
627} // namespace trk
628} // namespace o2
629
631
632// Define Factory method for calling from the outside
633extern "C" {
638}
Definition of the Stack class.
Definition of the TRK Hit class.
int32_t i
uint32_t j
Definition RawData.h:0
uint32_t stack
Definition RawData.h:1
specs of the ALICE3 TRK
ClassImp(o2::trk::Detector)
o2::base::Detector * create_detector_trk(bool active)
Definition Detector.cxx:634
void Mixture(Int_t imat, const char *name, Float_t *a, Float_t *z, Float_t dens, Int_t nlmat, Float_t *wmat)
Definition Detector.cxx:66
void Medium(Int_t numed, const char *name, Int_t nmat, Int_t isvol, Int_t ifield, Float_t fieldm, Float_t tmaxfd, Float_t stemax, Float_t deemax, Float_t epsil, Float_t stmin, Float_t *ubuf=nullptr, Int_t nbuf=0)
Definition Detector.cxx:72
static void initFieldTrackingParams(int &mode, float &maxfield)
Definition Detector.cxx:143
void Material(Int_t imat, const char *name, Float_t a, Float_t z, Float_t dens, Float_t radl, Float_t absl, Float_t *buf=nullptr, Int_t nwbuf=0)
Definition Detector.cxx:59
static o2::base::Detector * create(bool active)
Definition Detector.h:39
static ShmManager & Instance()
Definition ShmManager.h:61
const GLdouble * v
Definition glcorearb.h:832
GLuint const GLchar * name
Definition glcorearb.h:781
GLboolean * data
Definition glcorearb.h:298
GLuint GLsizei GLsizei * length
Definition glcorearb.h:790
GLuint GLfloat * val
Definition glcorearb.h:1582
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
void createGeometry(TGeoManager &geom, TGeoVolume &topVolume)
Definition Geometry.cxx:74
void createMaterials()
Definition Materials.cxx:91
std::vector< VDSensorDesc > & vdSensorRegistry()
float getDetLengthFromEta(const float eta, const float radius)
Definition Detector.cxx:37
void createIRISGeometry3InclinedWalls(TGeoVolume *motherVolume)
void createIRISGeometryFullCyl(TGeoVolume *motherVolume)
void createIRIS4aGeometry(TGeoVolume *motherVolume)
MatBudgetParamMode
Definition TRKLayer.h:28
void createIRIS4Geometry(TGeoVolume *motherVolume)
void createIRIS5Geometry(TGeoVolume *motherVolume)
@ kIRISFullCyl3InclinedWalls
void clearVDSensorRegistry()
void freeSimVector(std::vector< T > *ptr)
std::vector< T > * createSimVector()
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
Common utility functions.
VectorOfTObjectPtrs other
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"