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{128.35f, 128.35f, 128.35f, 128.35f, 128.35f, 256.7f, 256.7f, 256.7f};
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{10, 10, 10, 10, 10, 20, 20, 20};
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 // Cylindrical requires at least 3 parameters
169 if (tmpBuff.size() < 3) {
170 LOGP(fatal, "Invalid configuration for cylindrical layer {}: insufficient parameters.", layerCount);
171 }
172
173 // Default mode is Thickness
174 MatBudgetParamMode mode = MatBudgetParamMode::Thickness;
175 if (tmpBuff.size() >= 4) {
176 mode = static_cast<MatBudgetParamMode>(static_cast<int>(tmpBuff[3]));
177 }
178
179 mLayers.push_back(std::make_unique<TRKCylindricalLayer>(layerCount, name, tmpBuff[0], tmpBuff[1], tmpBuff[2], mode));
180 break;
181 }
182 case kSegmented: {
183 // Expected column mapping in the text file (separated by \t):
184 // tmpBuff[0] = rInn
185 // tmpBuff[1] = thick
186 // tmpBuff[2] = tiltAngle
187 // tmpBuff[3] = nStaves
188 // tmpBuff[4] = nMods
189 // tmpBuff[5] = stagOffset (required ONLY for ML)
190 // tmpBuff[6] = matBudgetMode (optional, default = Thickness)
191
192 // Base parameters for all segmented layers (at least 5 needed)
193 if (tmpBuff.size() < 5) {
194 LOGP(fatal, "Invalid configuration for segmented layer {}: missing base parameters.", layerCount);
195 }
196
197 float rInn = tmpBuff[0];
198 float thick = tmpBuff[1];
199 float tiltAngle = tmpBuff[2];
200 int nStaves = static_cast<int>(tmpBuff[3]);
201 int nMods = static_cast<int>(tmpBuff[4]);
202
203 // Default mode is Thickness
204 MatBudgetParamMode mode = MatBudgetParamMode::Thickness;
205
206 if (layerCount < constants::ML::nLayers) {
207 // ML layers require stagOffset (index 5)
208 if (tmpBuff.size() < 6) {
209 LOGP(fatal, "Invalid configuration for ML layer {}: stagOffset is missing.", layerCount);
210 }
211 float stagOffset = tmpBuff[5];
212
213 if (tmpBuff.size() >= 7) {
214 mode = static_cast<MatBudgetParamMode>(static_cast<int>(tmpBuff[6]));
215 }
216
217 mLayers.push_back(std::make_unique<TRKMLLayer>(layerCount, name, rInn, stagOffset, tiltAngle, nStaves, nMods, thick, mode));
218 } else {
219 // OT layers do NOT have stagOffset. The optional mode is at index 5.
220 if (tmpBuff.size() >= 6) {
221 mode = static_cast<MatBudgetParamMode>(static_cast<int>(tmpBuff[5]));
222 }
223
224 mLayers.push_back(std::make_unique<TRKOTLayer>(layerCount, name, rInn, tiltAngle, nStaves, nMods, thick, mode));
225 }
226 break;
227 }
228 default:
229 LOGP(fatal, "Unknown option {} for configMLOT", static_cast<int>(trkPars.layoutMLOT));
230 break;
231 }
232
233 ++layerCount;
234 }
235}
236
237void Detector::configToFile(std::string fileName)
238{
239 LOGP(info, "Exporting TRK Detector layout to {}", fileName);
240 std::ofstream conFile(fileName.c_str(), std::ios::out);
241 conFile << "/// TRK configuration file: inn_radius z_length lay_thickness" << std::endl;
242 for (const auto& layer : mLayers) {
243 conFile << layer->getInnerRadius() << "\t" << layer->getZ() << "\t" << layer->getChipThickness() << std::endl;
244 }
245}
246
247void Detector::configServices()
248{
249 mServices = TRKServices();
250}
251
252void Detector::createMaterials()
253{
254 int ifield = 2; // ?
255 float fieldm = 10.0; // ?
257
258 float tmaxfdSi = 0.1; // .10000E+01; // Degree
259 float stemaxSi = 0.0075; // .10000E+01; // cm
260 float deemaxSi = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
261 float epsilSi = 1.0E-4; // .10000E+01;
262 float stminSi = 0.0; // cm "Default value used"
263
264 float tmaxfdAir = 0.1; // .10000E+01; // Degree
265 float stemaxAir = .10000E+01; // cm
266 float deemaxAir = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
267 float epsilAir = 1.0E-4; // .10000E+01;
268 float stminAir = 0.0; // cm "Default value used"
269
270 float tmaxfdCer = 0.1; // .10000E+01; // Degree
271 float stemaxCer = .10000E+01; // cm
272 float deemaxCer = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
273 float epsilCer = 1.0E-4; // .10000E+01;
274 float stminCer = 0.0; // cm "Default value used"
275
276 // AIR
277 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
278 float zAir[4] = {6., 7., 8., 18.};
279 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
280 float dAir = 1.20479E-3;
281
282 // Carbon fiber
283 float aCf[2] = {12.0107, 1.00794};
284 float zCf[2] = {6., 1.};
285
286 o2::base::Detector::Mixture(1, "AIR$", aAir, zAir, dAir, 4, wAir);
287 o2::base::Detector::Medium(1, "AIR$", 1, 0, ifield, fieldm, tmaxfdAir, stemaxAir, deemaxAir, epsilAir, stminAir);
288
289 o2::base::Detector::Material(3, "SILICON$", 0.28086E+02, 0.14000E+02, 0.23300E+01, 0.93600E+01, 0.99900E+03);
290 o2::base::Detector::Medium(3, "SILICON$", 3, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
291}
292
293void Detector::createGeometry()
294{
295 TGeoManager* geoManager = gGeoManager;
296 TGeoVolume* vALIC = geoManager->GetVolume("barrel");
297 if (!vALIC) {
298 LOGP(fatal, "Could not find barrel volume while constructing TRK geometry");
299 }
300 new TGeoVolumeAssembly(GeometryTGeo::getTRKVolPattern());
301 TGeoVolume* vTRK = geoManager->GetVolume(GeometryTGeo::getTRKVolPattern());
302 vALIC->AddNode(vTRK, 2, new TGeoTranslation(0, 30., 0));
303
304 char vstrng[100] = "TRKVol";
305 vTRK->SetTitle(vstrng);
306
307 for (auto& layer : mLayers) {
308 layer->createLayer(vTRK);
309 }
310
311 // Add service for inner tracker
312 mServices.createServices(vTRK);
313
314 // Build the VD using the petal builder
315 // Choose the VD design based on TRKBaseParam.layoutVD
316 auto& trkPars = TRKBaseParam::Instance();
317
319
320 switch (trkPars.layoutVD) {
321 case kIRIS4:
322 LOG(info) << "Building VD with IRIS4 layout";
324 break;
325 case kIRISFullCyl:
326 LOG(info) << "Building VD with IRIS fully cylindrical layout";
328 break;
330 LOG(info) << "Building VD with IRIS fully cylindrical layout with 3 inclined walls";
332 break;
333 case kIRIS5:
334 LOG(info) << "Building VD with IRIS5 layout";
336 break;
337 case kIRIS4a:
338 LOG(info) << "Building VD with IRIS4a layout";
340 break;
341 default:
342 LOG(fatal) << "Unknown VD layout option: " << static_cast<int>(trkPars.layoutVD);
343 break;
344 }
345
346 // Fill sensor names from registry right after geometry creation
347 const auto& regs = o2::trk::vdSensorRegistry();
348 mNumberOfVolumesVD = static_cast<int>(regs.size());
349 mNumberOfVolumes = mNumberOfVolumesVD + mLayers.size();
350 mSensorName.resize(mNumberOfVolumes);
351
352 // Fill VD sensor names from registry
353 int VDvolume = 0;
354 for (const auto& sensor : regs) {
355 mSensorName[VDvolume] = sensor.name;
356 VDvolume++;
357 }
358
359 // Add MLOT sensor names
360 for (int i = 0; i < mLayers.size(); i++) {
361 mSensorName[VDvolume++].Form("%s%d", GeometryTGeo::getTRKSensorPattern(), i);
362 }
363
364 for (auto vd : mSensorName) {
365 std::cout << "Volume name: " << vd << std::endl;
366 }
367
368 mServices.excavateFromVacuum("IRIS_CUTOUTsh");
369 mServices.registerVacuum(vTRK);
370}
371
372void Detector::InitializeO2Detector()
373{
374 LOG(info) << "Initialize TRK O2Detector";
375 mGeometryTGeo = GeometryTGeo::Instance();
376 defineSensitiveVolumes();
377
378 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
379 for (int i = 0; i < mNumberOfVolumes; i++) {
380 mSensorID[i] = gMC ? TVirtualMC::GetMC()->VolId(mSensorName[i]) : 0; // Volume ID from the Geant geometry
381 LOGP(info, "{}: mSensorID={}, mSensorName={}", i, mSensorID[i], mSensorName[i].Data());
382 }
383}
384
385void Detector::defineSensitiveVolumes()
386{
387 TGeoManager* geoManager = gGeoManager;
388 TGeoVolume* v;
389
390 TString volumeName;
391 LOGP(info, "Adding TRK Sensitive Volumes");
392
393 // Register VD sensors created by VDGeometryBuilder
394 for (const auto& s : o2::trk::vdSensorRegistry()) {
395 TGeoVolume* v = gGeoManager->GetVolume(s.name.c_str());
396 if (!v) {
397 LOGP(warning, "VD sensor volume '{}' not found", s.name);
398 continue;
399 }
400 LOGP(info, "Adding VD Sensitive Volume {}", v->GetName());
401 AddSensitiveVolume(v);
402 // Optionally track first/last layers for TR references:
403 if (s.region == o2::trk::VDSensorDesc::Region::Barrel && (s.idx == 0 /*innermost*/)) {
404 mFirstOrLastLayers.push_back(s.name);
405 }
406 }
407
408 // The names of the TRK sensitive volumes have the format: TRKLayer(0...mLayers.size()-1)
409 for (int j{0}; j < mLayers.size(); j++) {
410 volumeName = GeometryTGeo::getTRKSensorPattern() + TString::Itoa(j, 10);
411 if (j == mLayers.size() - 1) {
412 mFirstOrLastLayers.push_back(volumeName.Data());
413 }
414 LOGP(info, "Trying {}", volumeName.Data());
415 v = geoManager->GetVolume(volumeName.Data());
416 LOGP(info, "Adding TRK Sensitive Volume {}", v->GetName());
417 AddSensitiveVolume(v);
418 }
419}
420
421void Detector::EndOfEvent() { Reset(); }
422
423void Detector::Register()
424{
425 // This will create a branch in the output tree called Hit, setting the last
426 // parameter to kFALSE means that this collection will not be written to the file,
427 // it will exist only during the simulation
428
429 if (FairRootManager::Instance()) {
430 FairRootManager::Instance()->RegisterAny(addNameTo("Hit").data(), mHits, true);
431 }
432}
433
434void Detector::Reset()
435{
436 if (!o2::utils::ShmManager::Instance().isOperational()) {
437 mHits->clear();
438 }
439}
440
441bool Detector::InsideFirstOrLastLayer(std::string layerName)
442{
443 bool inside = false;
444 for (auto& firstOrLastLayer : mFirstOrLastLayers) {
445 if (firstOrLastLayer == layerName) {
446 inside = true;
447 break;
448 }
449 }
450 return inside;
451}
452
453bool Detector::ProcessHits(FairVolume* vol)
454{
455 // This method is called from the MC stepping
456 if (!(fMC->TrackCharge())) {
457 return false;
458 }
459
460 int subDetID = -1;
461 int layer = -1;
462 int volume = 0;
463 int volID = vol->getMCid();
464
465 bool notSens = false;
466 while ((volume < mNumberOfVolumes) && (notSens = (volID != mSensorID[volume]))) {
467 ++volume;
468 }
469
470 if (notSens) {
471 return kFALSE; // RS: can this happen? This method must be called for sensors only?
472 }
473
474 if (volume < mNumberOfVolumesVD) {
475 subDetID = 0; // VD. For the moment each "chip" is a volume./// TODO: change this logic once the naming scheme is changed
476 } else {
477 subDetID = 1; // MLOT
478 layer = volume - mNumberOfVolumesVD;
479 }
480
481 // Is it needed to keep a track reference when the outer ITS volume is encountered?
482 auto stack = (o2::data::Stack*)fMC->GetStack();
483 // if (fMC->IsTrackExiting() && (lay == 0 || lay == mLayers.size() - 1)) {
484 if (fMC->IsTrackExiting() && InsideFirstOrLastLayer(vol->GetName())) {
485 // Keep the track refs for the innermost and outermost layers only
486 o2::TrackReference tr(*fMC, GetDetId());
487 tr.setTrackID(stack->GetCurrentTrackNumber());
488 tr.setUserId(volume);
489 stack->addTrackReference(tr);
490 }
491 bool startHit = false, stopHit = false;
492 unsigned char status = 0;
493 if (fMC->IsTrackEntering()) {
494 status |= Hit::kTrackEntering;
495 }
496 if (fMC->IsTrackInside()) {
497 status |= Hit::kTrackInside;
498 }
499 if (fMC->IsTrackExiting()) {
500 status |= Hit::kTrackExiting;
501 }
502 if (fMC->IsTrackOut()) {
503 status |= Hit::kTrackOut;
504 }
505 if (fMC->IsTrackStop()) {
506 status |= Hit::kTrackStopped;
507 }
508 if (fMC->IsTrackAlive()) {
509 status |= Hit::kTrackAlive;
510 }
511
512 // track is entering or created in the volume
513 if ((status & Hit::kTrackEntering) || (status & Hit::kTrackInside && !mTrackData.mHitStarted)) {
514 startHit = true;
515 } else if ((status & (Hit::kTrackExiting | Hit::kTrackOut | Hit::kTrackStopped))) {
516 stopHit = true;
517 }
518
519 // increment energy loss at all steps except entrance
520 if (!startHit) {
521 mTrackData.mEnergyLoss += fMC->Edep();
522 }
523 if (!(startHit | stopHit)) {
524 return false; // do noting
525 }
526
527 if (startHit) {
528 mTrackData.mEnergyLoss = 0.;
529 fMC->TrackMomentum(mTrackData.mMomentumStart);
530 fMC->TrackPosition(mTrackData.mPositionStart);
531 mTrackData.mTrkStatusStart = status;
532 mTrackData.mHitStarted = true;
533 }
534 if (stopHit) {
535 TLorentzVector positionStop;
536 fMC->TrackPosition(positionStop);
537
538 // Retrieve the indices with the volume path
539 int stave(0), halfstave(0), mod(0), chip(0);
540
541 auto& trkPars = TRKBaseParam::Instance();
542
543 if (subDetID == 1) {
544 if (trkPars.layoutMLOT == o2::trk::eMLOTLayout::kSegmented) {
545 fMC->CurrentVolOffID(1, chip);
546 fMC->CurrentVolOffID(2, mod);
547 if (mGeometryTGeo->getNumberOfHalfStaves(layer) == 2) {
548 fMC->CurrentVolOffID(3, halfstave);
549 fMC->CurrentVolOffID(4, stave);
550 } else if (mGeometryTGeo->getNumberOfHalfStaves(layer) == 1) {
551 fMC->CurrentVolOffID(3, stave);
552 } else {
553 LOGP(fatal, "Wrong number of halfstaves for layer {}", layer);
554 }
555 }
556 }
557
558 unsigned short chipID = mGeometryTGeo->getChipIndex(subDetID, volume, layer, stave, halfstave, mod, chip);
559
560 // Print(vol, volume, subDetID, layer, stave, halfstave, mod, chip, chipID);
561
562 // mGeometryTGeo->Print();
563
564 Hit* p = addHit(stack->GetCurrentTrackNumber(), chipID, mTrackData.mPositionStart.Vect(), positionStop.Vect(),
565 mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(),
566 mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status);
567 // p->SetTotalEnergy(vmc->Etot());
568
569 // RS: not sure this is needed
570 // Increment number of Detector det points in TParticle
571 stack->addHit(GetDetId());
572 }
573
574 return true;
575}
576
577o2::trk::Hit* Detector::addHit(int trackID, unsigned short detID, const TVector3& startPos, const TVector3& endPos,
578 const TVector3& startMom, double startE, double endTime, double eLoss, unsigned char startStatus,
579 unsigned char endStatus)
580{
581 mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus);
582 return &(mHits->back());
583}
584
585void Detector::Print(FairVolume* vol, int volume, int subDetID, int layer, int stave, int halfstave, int mod, int chip, int chipID) const
586{
587 int currentVol(0);
588 LOG(info) << "Current volume name: " << fMC->CurrentVolName() << " and ID " << fMC->CurrentVolID(currentVol);
589 LOG(info) << "volume: " << volume << "/" << mNumberOfVolumes - 1;
590
591 auto& trkPars = TRKBaseParam::Instance();
592
593 if (subDetID == 1) { // MLOT
594 if (trkPars.layoutMLOT == o2::trk::eMLOTLayout::kCylindrical) {
595 LOG(info) << "off volume name 1 " << fMC->CurrentVolOffName(1) << " chip: " << chip;
596 LOG(info) << "SubDetector ID: " << subDetID << " Layer: " << layer << " Chip ID: " << chipID;
597 } else {
598 LOG(info) << "off volume name 1 " << fMC->CurrentVolOffName(1) << " chip: " << chip;
599 LOG(info) << "off volume name 2 " << fMC->CurrentVolOffName(2) << " module: " << mod;
600 if (mGeometryTGeo->getNumberOfHalfStaves(layer) == 2) { // staggered geometry
601 LOG(info) << "off volume name 3 " << fMC->CurrentVolOffName(3) << " halfstave: " << halfstave;
602 LOG(info) << "off volume name 4 " << fMC->CurrentVolOffName(4) << " stave: " << stave;
603 LOG(info) << "SubDetector ID: " << subDetID << " Layer: " << layer << " staveinLayer: " << stave << " Chip ID: " << chipID;
604 } else if (mGeometryTGeo->getNumberOfHalfStaves(layer) == 1) { // turbo geometry
605 LOG(info) << "off volume name 3 " << fMC->CurrentVolOffName(3) << " stave: " << stave;
606 LOG(info) << "SubDetector ID: " << subDetID << " Layer: " << layer << " staveinLayer: " << stave << " Chip ID: " << chipID;
607 }
608 }
609 } else {
610 // VD
611 LOG(info) << "SubDetector ID: " << subDetID << " Chip ID: " << chipID;
612 }
613
614 LOG(info);
615}
616
617} // namespace trk
618} // namespace o2
619
621
622// Define Factory method for calling from the outside
623extern "C" {
628}
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:624
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
GLenum mode
Definition glcorearb.h:266
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"