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
12#include <FairVolume.h>
13
14#include <TVirtualMC.h>
15#include <TVirtualMCStack.h>
16#include <TGeoVolume.h>
17
18#include "DetectorsBase/Stack.h"
22
23using o2::itsmft::Hit;
24
25namespace o2
26{
27namespace trk
28{
29float getDetLengthFromEta(const float eta, const float radius)
30{
31 return 2. * (10. + radius * std::cos(2 * std::atan(std::exp(-eta))));
32}
33
35 : o2::base::DetImpl<Detector>("TRK", true),
36 mTrackData(),
37 mHits(o2::utils::createSimVector<o2::itsmft::Hit>())
38{
39}
40
41Detector::Detector(bool active)
42 : o2::base::DetImpl<Detector>("TRK", true),
43 mTrackData(),
44 mHits(o2::utils::createSimVector<o2::itsmft::Hit>())
45{
46 auto& trkPars = TRKBaseParam::Instance();
47
48 if (trkPars.configFile != "") {
49 configFromFile(trkPars.configFile);
50 } else {
51 buildTRKNewVacuumVessel();
52 configToFile();
53 configServices();
54 }
55
56 mSensorName.resize(mNumberOfVolumes); // hardcoded. TODO: change size when a different naming scheme for VD is in place. Ideally could be 4 petals + 8 layers = 12
57 int VDvolume = 0;
58 for (int i = 0; i < 4; i++) {
59 for (int j = 0; j < 3; j++) {
61 VDvolume++;
62 }
63 for (int j = 0; j < 6; j++) {
65 VDvolume++;
66 }
67 }
68
69 for (int i = 0; i < 8; i++) {
70 mSensorName[VDvolume].Form("%s%d", GeometryTGeo::getTRKSensorPattern(), i);
71 VDvolume++;
72 }
73
74 for (auto vd : mSensorName) {
75 std::cout << "Volume name: " << vd << std::endl;
76 }
77
78 LOGP(info, "Summary of TRK configuration:");
79 for (auto& layer : mLayers) {
80 LOGP(info, "Layer: {} name: {} r: {} cm | z: {} cm | thickness: {} cm", layer.getNumber(), layer.getName(), layer.getInnerRadius(), layer.getZ(), layer.getChipThickness());
81 }
82}
83
84Detector::~Detector()
85{
86 if (mHits) {
88 }
89}
90
91void Detector::ConstructGeometry()
92{
95}
96
97void Detector::configDefault()
98{
99
100 // Build TRK detector according to the scoping document
101
102 mLayers.clear();
103
104 LOGP(warning, "Loading Scoping Document configuration for ALICE3 TRK");
105 // mLayers.emplace_back(0, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}, 0.5f, 50.f, 100.e-4);
106 // mLayers.emplace_back(1, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(1)}, 1.2f, 50.f, 100.e-4);
107 // mLayers.emplace_back(2, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(2)}, 2.5f, 50.f, 100.e-4);
108 mLayers.emplace_back(0, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}, 3.78f, 124.f, 100.e-3);
109 mLayers.emplace_back(1, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(1)}, 7.f, 124.f, 100.e-3);
110 mLayers.emplace_back(2, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(2)}, 12.f, 124.f, 100.e-3);
111 mLayers.emplace_back(3, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(3)}, 20.f, 124.f, 100.e-3);
112 mLayers.emplace_back(4, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(4)}, 30.f, 124.f, 100.e-3);
113 mLayers.emplace_back(5, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(5)}, 45.f, 258.f, 100.e-3);
114 mLayers.emplace_back(6, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(6)}, 60.f, 258.f, 100.e-3);
115 mLayers.emplace_back(7, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(7)}, 80.f, 258.f, 100.e-3);
116}
117
118void Detector::buildTRKNewVacuumVessel()
119{
120 // Build the TRK detector according to changes proposed during
121 // https://indico.cern.ch/event/1407704/
122 // to adhere to the changes that were presented at the ALICE 3 Upgrade days in March 2024
123 // L3 -> 7 cm, L4 -> 9 cm
124
125 mLayers.clear();
126
127 LOGP(warning, "Loading \"After Upgrade Days March 2024\" configuration for ALICE3 TRK");
128 // mLayers.emplace_back(0, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}, 0.5f, 50.f, 100.e-4);
129 // mLayers.emplace_back(1, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(1)}, 1.2f, 50.f, 100.e-4);
130 // mLayers.emplace_back(2, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(2)}, 2.5f, 50.f, 100.e-4);
131 mLayers.emplace_back(0, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(0)}, 7.f, 124.f, 100.e-3);
132 LOGP(info, "TRKLayer created. Name: {}", std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(0)});
133 mLayers.emplace_back(1, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(1)}, 9.f, 124.f, 100.e-3);
134 mLayers.emplace_back(2, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(2)}, 12.f, 124.f, 100.e-3);
135 mLayers.emplace_back(3, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(3)}, 20.f, 124.f, 100.e-3);
136 mLayers.emplace_back(4, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(4)}, 30.f, 124.f, 100.e-3);
137 mLayers.emplace_back(5, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(5)}, 45.f, 258.f, 100.e-3);
138 mLayers.emplace_back(6, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(6)}, 60.f, 258.f, 100.e-3);
139 mLayers.emplace_back(7, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(7)}, 80.f, 258.f, 100.e-3);
140
141 auto& trkPars = TRKBaseParam::Instance();
142
143 // Middle layers
144 mLayers[0].setLayout(trkPars.layoutML);
145 mLayers[1].setLayout(trkPars.layoutML);
146 mLayers[2].setLayout(trkPars.layoutML);
147 mLayers[3].setLayout(trkPars.layoutML);
148
149 // Outer tracker
150 mLayers[4].setLayout(trkPars.layoutOL);
151 mLayers[5].setLayout(trkPars.layoutOL);
152 mLayers[6].setLayout(trkPars.layoutOL);
153 mLayers[7].setLayout(trkPars.layoutOL);
154}
155
156void Detector::configFromFile(std::string fileName)
157{
158 // Override the default geometry if config file provided
159 std::ifstream confFile(fileName);
160 if (!confFile.good()) {
161 LOGP(fatal, "File {} not found, aborting.", fileName);
162 }
163
164 mLayers.clear();
165
166 LOGP(info, "Overriding geometry of ALICE3 TRK using {} file.", fileName);
167
168 std::string line;
169 std::vector<float> tmpBuff;
170 int layerCount{0};
171 while (std::getline(confFile, line)) {
172 if (line[0] == '/') {
173 continue;
174 }
175 tmpBuff.clear();
176 std::stringstream ss(line);
177 float val;
178 std::string substr;
179 while (getline(ss, substr, '\t')) {
180 tmpBuff.push_back(std::stof(substr));
181 }
182 mLayers.emplace_back(layerCount, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(layerCount)}, tmpBuff[0], tmpBuff[1], tmpBuff[2]);
183 ++layerCount;
184 }
185}
186
187void Detector::configToFile(std::string fileName)
188{
189 LOGP(info, "Exporting TRK Detector layout to {}", fileName);
190 std::ofstream conFile(fileName.c_str(), std::ios::out);
191 conFile << "/// TRK configuration file: inn_radius z_length lay_thickness" << std::endl;
192 for (auto layer : mLayers) {
193 conFile << layer.getInnerRadius() << "\t" << layer.getZ() << "\t" << layer.getChipThickness() << std::endl;
194 }
195}
196
197void Detector::configServices()
198{
199 mServices = TRKServices();
200}
201
202void Detector::createMaterials()
203{
204 int ifield = 2; // ?
205 float fieldm = 10.0; // ?
207
208 float tmaxfdSi = 0.1; // .10000E+01; // Degree
209 float stemaxSi = 0.0075; // .10000E+01; // cm
210 float deemaxSi = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
211 float epsilSi = 1.0E-4; // .10000E+01;
212 float stminSi = 0.0; // cm "Default value used"
213
214 float tmaxfdAir = 0.1; // .10000E+01; // Degree
215 float stemaxAir = .10000E+01; // cm
216 float deemaxAir = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
217 float epsilAir = 1.0E-4; // .10000E+01;
218 float stminAir = 0.0; // cm "Default value used"
219
220 float tmaxfdCer = 0.1; // .10000E+01; // Degree
221 float stemaxCer = .10000E+01; // cm
222 float deemaxCer = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
223 float epsilCer = 1.0E-4; // .10000E+01;
224 float stminCer = 0.0; // cm "Default value used"
225
226 // AIR
227 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
228 float zAir[4] = {6., 7., 8., 18.};
229 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
230 float dAir = 1.20479E-3;
231
232 // Carbon fiber
233 float aCf[2] = {12.0107, 1.00794};
234 float zCf[2] = {6., 1.};
235
236 o2::base::Detector::Mixture(1, "AIR$", aAir, zAir, dAir, 4, wAir);
237 o2::base::Detector::Medium(1, "AIR$", 1, 0, ifield, fieldm, tmaxfdAir, stemaxAir, deemaxAir, epsilAir, stminAir);
238
239 o2::base::Detector::Material(3, "SILICON$", 0.28086E+02, 0.14000E+02, 0.23300E+01, 0.93600E+01, 0.99900E+03);
240 o2::base::Detector::Medium(3, "SILICON$", 3, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
241}
242
243void Detector::createGeometry()
244{
245 TGeoManager* geoManager = gGeoManager;
246 TGeoVolume* vALIC = geoManager->GetVolume("barrel");
247 if (!vALIC) {
248 LOGP(fatal, "Could not find barrel volume while constructing TRK geometry");
249 }
250 new TGeoVolumeAssembly(GeometryTGeo::getTRKVolPattern());
251 TGeoVolume* vTRK = geoManager->GetVolume(GeometryTGeo::getTRKVolPattern());
252 vALIC->AddNode(vTRK, 2, new TGeoTranslation(0, 30., 0));
253
254 char vstrng[100] = "TRKVol";
255 vTRK->SetTitle(vstrng);
256
257 for (auto& layer : mLayers) {
258 layer.createLayer(vTRK);
259 }
260
261 // Add service for inner tracker
262 mServices.createServices(vTRK);
263 mPetalCases.clear();
264 // Add petal cases (the sensitive layers inside the petal cases get constructed here too)
265 auto& trkPars = TRKBaseParam::Instance();
266 for (Int_t petalCaseNumber = 0; petalCaseNumber < sNumberVDPetalCases; ++petalCaseNumber) {
267 mPetalCases.emplace_back(petalCaseNumber, vTRK, trkPars.irisOpen);
268 mServices.excavateFromVacuum(mPetalCases[petalCaseNumber].getFullName());
269 }
270 mServices.registerVacuum(vTRK);
271}
272
273void Detector::InitializeO2Detector()
274{
275 LOG(info) << "Initialize TRK O2Detector";
276 mGeometryTGeo = GeometryTGeo::Instance();
277 defineSensitiveVolumes();
278
279 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
280 for (int i = 0; i < mNumberOfVolumes; i++) {
281 mSensorID[i] = gMC ? TVirtualMC::GetMC()->VolId(mSensorName[i]) : 0; // Volume ID from the Geant geometry
282 LOGP(info, "{}: mSensorID={}", i, mSensorID[i]);
283 }
284}
285
286void Detector::defineSensitiveVolumes()
287{
288 TGeoManager* geoManager = gGeoManager;
289 TGeoVolume* v;
290
291 TString volumeName;
292 LOGP(info, "Adding TRK Sensitive Volumes");
293
294 // Add petal case sensitive volumes
295 for (int petalCase = 0; petalCase < sNumberVDPetalCases; ++petalCase) {
296 // Petal layers
297 for (int petalLayer = 0; petalLayer < mPetalCases[petalCase].mPetalLayers.size(); ++petalLayer) {
298 volumeName = mPetalCases[petalCase].mPetalLayers[petalLayer].getSensorName();
299 if (petalLayer == 0) {
300 mFirstOrLastLayers.push_back(volumeName.Data());
301 }
302 LOGP(info, "Trying {}", volumeName.Data());
303 v = geoManager->GetVolume(volumeName.Data());
304 LOGP(info, "Adding TRK Sensitive Volume {}", v->GetName());
305 AddSensitiveVolume(v);
306 }
307 // Petal disks
308 for (int petalDisk = 0; petalDisk < mPetalCases[petalCase].mPetalDisks.size(); ++petalDisk) {
309 volumeName = mPetalCases[petalCase].mPetalDisks[petalDisk].getSensorName();
310 LOGP(info, "Trying {}", volumeName.Data());
311 v = geoManager->GetVolume(volumeName.Data());
312 LOGP(info, "Adding TRK Sensitive Volume {}", v->GetName());
313 AddSensitiveVolume(v);
314 }
315 }
316
317 // The names of the TRK sensitive volumes have the format: TRKLayer(0...mLayers.size()-1)
318 for (int j{0}; j < mLayers.size(); j++) {
319 volumeName = GeometryTGeo::getTRKSensorPattern() + TString::Itoa(j, 10);
320 if (j == mLayers.size() - 1) {
321 mFirstOrLastLayers.push_back(volumeName.Data());
322 }
323 LOGP(info, "Trying {}", volumeName.Data());
324 v = geoManager->GetVolume(volumeName.Data());
325 LOGP(info, "Adding TRK Sensitive Volume {}", v->GetName());
326 AddSensitiveVolume(v);
327 }
328}
329
330void Detector::EndOfEvent() { Reset(); }
331
332void Detector::Register()
333{
334 // This will create a branch in the output tree called Hit, setting the last
335 // parameter to kFALSE means that this collection will not be written to the file,
336 // it will exist only during the simulation
337
338 if (FairRootManager::Instance()) {
339 FairRootManager::Instance()->RegisterAny(addNameTo("Hit").data(), mHits, true);
340 }
341}
342
343void Detector::Reset()
344{
345 if (!o2::utils::ShmManager::Instance().isOperational()) {
346 mHits->clear();
347 }
348}
349
350bool Detector::InsideFirstOrLastLayer(std::string layerName)
351{
352 bool inside = false;
353 for (auto& firstOrLastLayer : mFirstOrLastLayers) {
354 if (firstOrLastLayer == layerName) {
355 inside = true;
356 break;
357 }
358 }
359 return inside;
360}
361
362bool Detector::ProcessHits(FairVolume* vol)
363{
364 // This method is called from the MC stepping
365 if (!(fMC->TrackCharge())) {
366 return false;
367 }
368
369 int subDetID = -1;
370 int layer = -1;
371 int volume = 0;
372 int stave = -1;
373 int volID = vol->getMCid();
374
375 bool notSens = false;
376 while ((volume < mNumberOfVolumes) && (notSens = (volID != mSensorID[volume]))) {
377 ++volume;
378 }
379
380 if (notSens) {
381 return kFALSE; // RS: can this happen? This method must be called for sensors only?
382 }
383
384 if (volume < mNumberOfVolumesVD) {
385 subDetID = 0; // VD. For the moment each "chip" is a volume./// TODO: change this logic once the naming scheme is changed
386 } else {
387 subDetID = 1; // MLOT
388 layer = volume - mNumberOfVolumesVD;
389 }
390
391 // Is it needed to keep a track reference when the outer ITS volume is encountered?
392 auto stack = (o2::data::Stack*)fMC->GetStack();
393 // if (fMC->IsTrackExiting() && (lay == 0 || lay == mLayers.size() - 1)) {
394 if (fMC->IsTrackExiting() && InsideFirstOrLastLayer(vol->GetName())) {
395 // Keep the track refs for the innermost and outermost layers only
396 o2::TrackReference tr(*fMC, GetDetId());
397 tr.setTrackID(stack->GetCurrentTrackNumber());
398 tr.setUserId(volume);
399 stack->addTrackReference(tr);
400 }
401 bool startHit = false, stopHit = false;
402 unsigned char status = 0;
403 if (fMC->IsTrackEntering()) {
404 status |= Hit::kTrackEntering;
405 }
406 if (fMC->IsTrackInside()) {
407 status |= Hit::kTrackInside;
408 }
409 if (fMC->IsTrackExiting()) {
410 status |= Hit::kTrackExiting;
411 }
412 if (fMC->IsTrackOut()) {
413 status |= Hit::kTrackOut;
414 }
415 if (fMC->IsTrackStop()) {
416 status |= Hit::kTrackStopped;
417 }
418 if (fMC->IsTrackAlive()) {
419 status |= Hit::kTrackAlive;
420 }
421
422 // track is entering or created in the volume
423 if ((status & Hit::kTrackEntering) || (status & Hit::kTrackInside && !mTrackData.mHitStarted)) {
424 startHit = true;
425 } else if ((status & (Hit::kTrackExiting | Hit::kTrackOut | Hit::kTrackStopped))) {
426 stopHit = true;
427 }
428
429 // increment energy loss at all steps except entrance
430 if (!startHit) {
431 mTrackData.mEnergyLoss += fMC->Edep();
432 }
433 if (!(startHit | stopHit)) {
434 return false; // do noting
435 }
436
437 if (startHit) {
438 mTrackData.mEnergyLoss = 0.;
439 fMC->TrackMomentum(mTrackData.mMomentumStart);
440 fMC->TrackPosition(mTrackData.mPositionStart);
441 mTrackData.mTrkStatusStart = status;
442 mTrackData.mHitStarted = true;
443 }
444 if (stopHit) {
445 TLorentzVector positionStop;
446 fMC->TrackPosition(positionStop);
447 // Retrieve the indices with the volume path
448 int stave(0), halfstave(0);
449 if (subDetID == 1) {
450 fMC->CurrentVolOffID(1, halfstave);
451 fMC->CurrentVolOffID(2, stave);
452 }
453
454 int chipID = mGeometryTGeo->getChipIndex(subDetID, volume, layer, stave, halfstave);
455
456 Print(vol, volume, subDetID, layer, stave, halfstave, chipID);
457
458 Hit* p = addHit(stack->GetCurrentTrackNumber(), chipID, mTrackData.mPositionStart.Vect(), positionStop.Vect(),
459 mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(),
460 mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status);
461 // p->SetTotalEnergy(vmc->Etot());
462
463 // RS: not sure this is needed
464 // Increment number of Detector det points in TParticle
465 stack->addHit(GetDetId());
466 }
467
468 return true;
469}
470
471o2::itsmft::Hit* Detector::addHit(int trackID, int detID, const TVector3& startPos, const TVector3& endPos,
472 const TVector3& startMom, double startE, double endTime, double eLoss, unsigned char startStatus,
473 unsigned char endStatus)
474{
475 mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus);
476 return &(mHits->back());
477}
478
479void Detector::Print(FairVolume* vol, int volume, int subDetID, int layer, int stave, int halfstave, int chipID) const
480{
481 int currentVol(0);
482 LOG(info) << "Current volume name: " << fMC->CurrentVolName() << " and ID " << fMC->CurrentVolID(currentVol);
483 LOG(info) << "volume: " << volume << "/" << mNumberOfVolumes - 1;
484 if (subDetID == 1 && mGeometryTGeo->getNumberOfHalfStaves(layer) == 2) { // staggered geometry
485 LOG(info) << "off volume name 1 " << fMC->CurrentVolOffName(1) << " halfstave: " << halfstave;
486 LOG(info) << "off volume name 2 " << fMC->CurrentVolOffName(2) << " stave: " << stave;
487 LOG(info) << "SubDetector ID: " << subDetID << " Layer: " << layer << " staveinLayer: " << stave << " Chip ID: " << chipID;
488 } else if (subDetID == 1 && mGeometryTGeo->getNumberOfHalfStaves(layer) == 1) { // turbo geometry
489 LOG(info) << "off volume name 2 " << fMC->CurrentVolOffName(2) << " stave: " << stave;
490 LOG(info) << "SubDetector ID: " << subDetID << " Layer: " << layer << " staveinLayer: " << stave << " Chip ID: " << chipID;
491 } else {
492 LOG(info) << "SubDetector ID: " << subDetID << " Chip ID: " << chipID;
493 }
494 LOG(info);
495}
496
497} // namespace trk
498} // namespace o2
499
501
502// Define Factory method for calling from the outside
503extern "C" {
508}
Definition of the Stack class.
Definition of the ITSMFT Hit class.
int32_t i
uint32_t j
Definition RawData.h:0
uint32_t stack
Definition RawData.h:1
ClassImp(o2::trk::Detector)
o2::base::Detector * create_detector_trk(bool active)
Definition Detector.cxx:504
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:42
static const char * getTRKPetalDiskPattern()
static const char * getTRKSensorPattern()
static const char * getTRKPetalLayerPattern()
static const char * getTRKPetalPattern()
static ShmManager & Instance()
Definition ShmManager.h:61
const GLdouble * v
Definition glcorearb.h:832
GLboolean * data
Definition glcorearb.h:298
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
float getDetLengthFromEta(const float eta, const float radius)
Definition Detector.cxx:29
void freeSimVector(std::vector< T > *ptr)
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.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"