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 "TRDBase/Geometry.h"
15#include "TRDSimulation/TRsim.h"
18#include "DataFormatsTRD/Hit.h"
19
21#include "DetectorsBase/Stack.h"
22#include "FairVolume.h"
23#include "FairRootManager.h"
24
25#include <TGeoManager.h>
26#include <TVirtualMC.h>
27
28#include <vector>
29#include <stdexcept>
30#include <string>
31
32using namespace o2::trd;
33using namespace o2::trd::constants;
34
36 : o2::base::DetImpl<Detector>("TRD", active)
37{
38 mHits = o2::utils::createSimVector<Hit>();
39 InitializeParams();
40}
41
43 : o2::base::DetImpl<Detector>(rhs),
44 mHits(o2::utils::createSimVector<Hit>()),
45 mFoilDensity(rhs.mFoilDensity),
46 mGasNobleFraction(rhs.mGasNobleFraction),
47 mGasDensity(rhs.mGasDensity),
48 mGeom(rhs.mGeom)
49{
50 InitializeParams();
51}
52
57
59{
60 // register the sensitive volumes with FairRoot
61 defineSensitiveVolumes();
62 buildVolumeIdTables();
63}
64
65void Detector::buildVolumeIdTables()
66{
67 auto* vmc = TVirtualMC::GetMC();
68 const int nVols = vmc->NofVolumes() + 1;
69 mRegionByVolId.assign(nVols, kNotSensitive);
70 mChamberByVolId.assign(nVols, -1);
71 mSectorByVolId.assign(nVols, -1);
72
73 auto record = [nVols](std::vector<int8_t>& table, int vid, int8_t value, const char* what) {
74 if (vid <= 0 || vid >= nVols) {
75 LOG(fatal) << "TRD volume " << what << " has no usable volume id (" << vid << ")";
76 }
77 table[vid] = value;
78 };
79
80 // The drift and amplification gas volumes, distinguished by the second character of
81 // their name exactly as Geometry::createVolume selects them as sensitive.
82 for (const auto& name : mGeom->getSensitiveTRDVolumes()) {
83 record(mRegionByVolId, vmc->VolId(name.c_str()), name[1] == 'J' ? kDrift : kAmplification, name.c_str());
84 }
85
86 // The readout-chamber assemblies and the supermodule mother volumes
87 char volName[16];
88 for (int idet = 0; idet < NLAYER * NSTACK; ++idet) {
89 snprintf(volName, sizeof(volName), "UT%02d", idet);
90 record(mChamberByVolId, vmc->VolId(volName), idet, volName);
91 }
92 for (int sector = 0; sector < NSECTOR; ++sector) {
93 snprintf(volName, sizeof(volName), "BTRD%d", sector);
94 record(mSectorByVolId, vmc->VolId(volName), sector, volName);
95 }
96}
97
98void Detector::InitializeParams()
99{
101 mWion = 23.53; // Ionization energy XeCO2 (85/15)
103 mWion = 27.21; // Ionization energy ArCO2 (82/18)
104 } else {
105 LOG(fatal) << "Wrong gas mixture";
106 // add hard exit here!
107 }
108 // Switch on TR simulation as default
110 if (!mTRon) {
111 LOG(info) << "TR simulation off";
112 }
113 mTR = new TRsim();
114 mMaxMCStepDef = TRDSimParams::Instance().maxMCStepSize;
115}
116
117bool Detector::ProcessHits(FairVolume* v)
118{
119 // If not charged track or already stopped or disappeared, just return.
120 if ((!fMC->TrackCharge()) || fMC->IsTrackDisappeared()) {
121 return false;
122 }
123 fMC->SetMaxStep(mMaxMCStepDef); // Should we optimize this value?
124
125 // Inside sensitive volume ?
126 int copy = 0;
127 const int vid = fMC->CurrentVolID(copy);
128 const int8_t region = (vid > 0 && vid < (int)mRegionByVolId.size()) ? mRegionByVolId[vid] : kNotSensitive;
129 if (region == kNotSensitive) {
130 return false;
131 }
132 const bool drRegion = (region == kDrift);
133 const bool amRegion = (region == kAmplification);
134
135 // Find how far up the chamber and the supermodule sit, once, by walking up until the
136 // ancestor's volume id is one we know. Hard-coding the depth breaks silently whenever a
137 // level is added, removed, or flattened away by the transport engine's own conversion.
138 if (mSectorOffset < 0) {
139 for (int off = 0; off < 16; ++off) {
140 const int oid = fMC->CurrentVolOffID(off, copy);
141 if (oid <= 0 || oid >= (int)mChamberByVolId.size()) {
142 continue;
143 }
144 if (mChamberOffset < 0 && mChamberByVolId[oid] >= 0) {
145 mChamberOffset = off;
146 }
147 if (mSectorByVolId[oid] >= 0) {
148 mSectorOffset = off;
149 break;
150 }
151 }
152 if (mChamberOffset < 0 || mSectorOffset < 0) {
153 LOG(fatal) << "No TRD chamber/supermodule ancestor above sensitive volume " << fMC->CurrentVolName();
154 }
155 LOG(info) << "TRD: chamber at mother offset " << mChamberOffset << ", supermodule at " << mSectorOffset;
156 }
157
158 const int chamberVol = fMC->CurrentVolOffID(mChamberOffset, copy);
159 const int sectorVol = fMC->CurrentVolOffID(mSectorOffset, copy);
160 const int idChamber = (chamberVol > 0 && chamberVol < (int)mChamberByVolId.size()) ? mChamberByVolId[chamberVol] : -1;
161 const int sector = (sectorVol > 0 && sectorVol < (int)mSectorByVolId.size()) ? mSectorByVolId[sectorVol] : -1;
162 if (idChamber < 0 || sector < 0) {
163 LOG(fatal) << "Cannot resolve TRD chamber/supermodule from volume " << fMC->CurrentVolName();
164 }
165
166 // The detector number (0 - 539)
167 int det = mGeom->getDetector(mGeom->getLayer(idChamber), mGeom->getStack(idChamber), sector);
168 if (det < 0 || det >= MAXCHAMBER) {
169 LOG(fatal) << "Detector number out of bounds";
170 }
171
172 // 0: InFlight 1: Entering 2: Exiting
173 int trkStat = 0;
174
175 o2::data::Stack* stack = (o2::data::Stack*)fMC->GetStack();
176 float xp, yp, zp;
177 float px, py, pz, etot;
178 float trackLength = fMC->TrackLength(); // Return the length of the current track from its origin (in cm)
179 float tof = fMC->TrackTime(); // Return the current time of flight of the track being transported (in s).
180
181 // Special hits if track is entering
182 if (drRegion && fMC->IsTrackEntering()) {
183 // Create a track reference at the entrance of each
184 // chamber that contains the momentum components of the particle
185 fMC->TrackMomentum(px, py, pz, etot);
186 fMC->TrackPosition(xp, yp, zp);
187 stack->addTrackReference(o2::TrackReference(*fMC, GetDetId()));
188 // Update track status
189 trkStat = 1;
190 // Create the hits from TR photons if electron/positron is entering the drift volume
191 const bool ele = (std::fabs(fMC->TrackPid()) == 11); // electron PDG code.
192 if (mTRon && ele) {
193 createTRhit(det);
194 }
195 } else if (amRegion && fMC->IsTrackExiting()) {
196 // Create a track reference at the exit of each
197 // chamber that contains the momentum components of the particle
198 fMC->TrackMomentum(px, py, pz, etot);
199 fMC->TrackPosition(xp, yp, zp);
200 stack->addTrackReference(o2::TrackReference(*fMC, GetDetId()));
201 // Update track status
202 trkStat = 2;
203 }
204
205 // Calculate the charge according to GEANT Edep
206 // Create a new dEdx hit
207 const float enDep = std::max(fMC->Edep(), 0.0) * 1e9; // Energy in eV
208 const int totalChargeDep = (int)(enDep / mWion); // Total charge
209
210 // Store those hits with enDep bigger than the ionization potential of the gas mixture for in-flight tracks
211 // or store hits of tracks that are entering or exiting
212 if (totalChargeDep || trkStat) {
213 fMC->TrackPosition(xp, yp, zp);
214 tof = tof * 1e6; // The time of flight in micro-seconds
215 const int trackID = stack->GetCurrentTrackNumber();
216 double pos[3] = {xp, yp, zp};
217 double loc[3] = {-99, -99, -99};
218 gGeoManager->MasterToLocal(pos, loc); // Go to the local coordinate system (locR, locC, locT)
219 float locC = loc[0], locR = loc[1], locT = loc[2];
220 if (drRegion) {
221 locT = locT - 0.5 * (Geometry::drThick() + Geometry::amThick()); // Relative to middle of amplification region
222 }
223 addHit(xp, yp, zp, locC, locR, locT, tof, totalChargeDep, trackID, det, drRegion);
224 stack->addHit(GetDetId());
225 return true;
226 }
227 return false;
228}
229
230void Detector::createTRhit(int det)
231{
232 //
233 // Creates an electron cluster from a TR photon.
234 // The photon is assumed to be created a the end of the radiator. The
235 // distance after which it deposits its energy takes into account the
236 // absorbtion of the entrance window and of the gas mixture in drift
237 // volume.
238 //
239
240 // Maximum number of TR photons per track
241 constexpr int mMaxNumberOfTRPhotons = 50; // Make this a class member?
242
243 float px, py, pz, etot;
244 fMC->TrackMomentum(px, py, pz, etot);
245 float pTot = std::sqrt(px * px + py * py + pz * pz);
246 std::vector<float> photonEnergyContainer; // energy in keV
247 mTR->createPhotons(11, pTot, photonEnergyContainer); // Create TR photons
248 if (photonEnergyContainer.size() > mMaxNumberOfTRPhotons) {
249 LOG(error) << "Boundary error: nTR = " << photonEnergyContainer.size() << ", mMaxNumberOfTRPhotons = " << mMaxNumberOfTRPhotons;
250 }
251
252 // Loop through the TR photons
253 for (const float& photonEnergy : photonEnergyContainer) {
254 const double energyMeV = photonEnergy * 1e-3;
255 const double energyeV = photonEnergy * 1e3;
256 double absLength = 0.0;
257 double sigma = 0.0;
258 // Take the absorbtion in the entrance window into account
259 double muMy = mTR->getMuMy(energyMeV);
260 sigma = muMy * mFoilDensity;
261 if (sigma > 0.0) {
262 absLength = gRandom->Exp(1.0 / sigma);
263 if (absLength < Geometry::myThick()) {
264 continue;
265 }
266 } else {
267 continue;
268 }
269 // The absorbtion cross sections in the drift gas
270 // Gas-mixture (Xe/CO2)
271 double muNo = 0.0;
273 muNo = mTR->getMuXe(energyMeV);
275 muNo = mTR->getMuAr(energyMeV);
276 }
277 double muCO = mTR->getMuCO(energyMeV);
278 // double fGasNobleFraction = 1;
279 // double fGasDensity = 1;
280 sigma = (mGasNobleFraction * muNo + (1.0 - mGasNobleFraction) * muCO) * mGasDensity * mTR->getTemp();
281
282 // The distance after which the energy of the TR photon
283 // is deposited.
284 if (sigma > 0.0) {
285 absLength = gRandom->Exp(1.0 / sigma);
286 if (absLength > (Geometry::drThick() + Geometry::amThick())) {
287 continue;
288 }
289 } else {
290 continue;
291 }
292
293 // The position of the absorbtion
294 float xp, yp, zp;
295 fMC->TrackPosition(xp, yp, zp);
296 float invpTot = 1. / pTot;
297 float x = xp + px * invpTot * absLength;
298 float y = yp + py * invpTot * absLength;
299 float z = zp + pz * invpTot * absLength;
300
301 // Add the hit to the array. TR photon hits are marked by negative energy (and not by charge)
302 float tof = fMC->TrackTime() * 1e6; // The time of flight in micro-seconds
303 o2::data::Stack* stack = (o2::data::Stack*)fMC->GetStack();
304 const int trackID = stack->GetCurrentTrackNumber();
305 const int totalChargeDep = -1 * (int)(energyeV / mWion); // Negative charge for tagging TR photon hits
306 // prepare local coordinates
307 double pos[3] = {x, y, z};
308 double loc[3] = {-99, -99, -99};
309 gGeoManager->MasterToLocal(pos, loc); // Go to the local coordinate system (locR, locC, locT)
310 float locC = loc[0], locR = loc[1], locT = loc[2];
311 locT = locT - 0.5 * (Geometry::drThick() + Geometry::amThick()); // Relative to middle of amplification region
312 addHit(x, y, z, locC, locR, locT, tof, totalChargeDep, trackID, det, true); // All TR hits are in drift region
313 stack->addHit(GetDetId());
314 }
315}
316
318{
319 FairRootManager::Instance()->RegisterAny(addNameTo("Hit").data(), mHits, true);
320}
321
323{
324 // Sort hit vector by detector number before the End of the Event
325 std::sort(mHits->begin(), mHits->end(),
326 [](const Hit& a, const Hit& b) {
327 return a.GetDetectorID() < b.GetDetectorID();
328 });
329}
330
331// this is very problematic; we should do round robin or the clear needs
332// to be done by the HitMerger
334{
335 if (!o2::utils::ShmManager::Instance().isOperational()) {
336 mHits->clear();
337 }
338}
339
341
342//_____________________________________________________________________________
344{
345 //
346 // Create the materials for the TRD
347 //
348 int isxfld = 2;
349 float sxmgmx = 10.;
351
353 // Define Materials
355
356 // Aluminum
357 Material(1, "Al", 26.98, 13.0, 2.7, 8.9, 37.2);
358 // Copper
359 Material(2, "Cu", 63.54, 29.0, 8.96, 1.43, 14.8);
360 // Carbon
361 Material(3, "C", 12.01, 6.0, 2.265, 18.8, 74.4);
362 // Carbon for fiber mats
363 Material(4, "C2", 12.01, 6.0, 1.75, 18.8, 74.4);
364 // Zinc
365 Material(5, "Sn", 118.71, 50.0, 7.31, 1.21, 14.8);
366 // Silicon
367 Material(6, "Si", 28.09, 14.0, 2.33, 9.36, 37.2);
368 // Iron
369 Material(7, "Fe", 55.85, 26.0, 7.87, 1.76, 14.8);
370
371 // Air
372 float aAir[4] = {12.011, 14.0, 15.9994, 36.0};
373 float zAir[4] = {6.0, 7.0, 8.0, 18.0};
374 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
375 float dAir = 1.20479e-03;
376 Mixture(51, "Air", aAir, zAir, dAir, 4, wAir);
377 // Polyethilene (CH2)
378 float ape[2] = {12.011, 1.0079};
379 float zpe[2] = {6.0, 1.0};
380 float wpe[2] = {1.0, 2.0};
381 float dpe = 0.95;
382 Mixture(52, "Polyethilene", ape, zpe, dpe, -2, wpe);
383 // Gas mixtures
384 // Xe/CO2-gas-mixture (85% / 15%)
385 float aXeCO2[3] = {131.29, 12.0107, 15.9994};
386 float zXeCO2[3] = {54.0, 6.0, 8.0};
387 float wXeCO2[3] = {8.5, 1.5, 3.0};
388 float fxc = 0.85;
389 float dxe = 0.00549; // at 20C
390 float dco = 0.00186; // at 20C
391 float dgmXe = fxc * dxe + (1.0 - fxc) * dco;
392 // Ar/CO2-gas-mixture
393 float aArCO2[3] = {39.948, 12.0107, 15.9994};
394 float zArCO2[3] = {18.0, 6.0, 8.0};
395 float wArCO2[3] = {8.2, 1.8, 3.6};
396 float fac = 0.82;
397 float dar = 0.00166; // at 20C
398 float dgmAr = fac * dar + (1.0 - fac) * dco;
400 Mixture(53, "XeCO2", aXeCO2, zXeCO2, dgmXe, -3, wXeCO2);
402 LOG(info) << "Gas mixture: Ar C02 (80/20)";
403 Mixture(53, "ArCO2", aArCO2, zArCO2, dgmAr, -3, wArCO2);
404 } else {
405 LOG(fatal) << "Wrong gas mixture";
406 exit(1);
407 }
408 // G10
409 float aG10[4] = {1.0079, 12.011, 15.9994, 28.086};
410 float zG10[4] = {1.0, 6.0, 8.0, 14.0};
411 float wG10[4] = {0.023, 0.194, 0.443, 0.340};
412 float dG10 = 2.0;
413 Mixture(54, "G10", aG10, zG10, dG10, 4, wG10);
414 // Water
415 float awa[2] = {1.0079, 15.9994};
416 float zwa[2] = {1.0, 8.0};
417 float wwa[2] = {2.0, 1.0};
418 float dwa = 1.0;
419 Mixture(55, "Water", awa, zwa, dwa, -2, wwa);
420 // Rohacell (C5H8O2), X0 = 535.005cm
421 float arh[3] = {12.011, 1.0079, 15.9994};
422 float zrh[3] = {6.0, 1.0, 8.0};
423 float wrh[3] = {5.0, 8.0, 2.0};
424 float drh = 0.075;
425 Mixture(56, "Rohacell", arh, zrh, drh, -3, wrh);
426 // Epoxy (C18H19O3)
427 float aEpoxy[3] = {15.9994, 1.0079, 12.011};
428 float zEpoxy[3] = {8.0, 1.0, 6.0};
429 float wEpoxy[3] = {3.0, 19.0, 18.0};
430 float dEpoxy = 1.8;
431 Mixture(57, "Epoxy", aEpoxy, zEpoxy, dEpoxy, -3, wEpoxy);
432 // Araldite, low density epoxy (C18H19O3)
433 float aAral[3] = {15.9994, 1.0079, 12.011};
434 float zAral[3] = {8.0, 1.0, 6.0};
435 float wAral[3] = {3.0, 19.0, 18.0};
436 float dAral = 1.12; // Hardener: 1.15, epoxy: 1.1, mixture: 1/2
437 Mixture(58, "Araldite", aAral, zAral, dAral, -3, wAral);
438 // Mylar
439 float aMy[3] = {12.011, 1.0, 15.9994};
440 float zMy[3] = {6.0, 1.0, 8.0};
441 float wMy[3] = {5.0, 4.0, 2.0};
442 float dMy = 1.39;
443 Mixture(59, "Mylar", aMy, zMy, dMy, -3, wMy);
444 // Polypropylene (C3H6) for radiator fibers
445 float app[2] = {12.011, 1.0079};
446 float zpp[2] = {6.0, 1.0};
447 float wpp[2] = {3.0, 6.0};
448 float dpp = 0.068;
449 Mixture(60, "Polypropylene", app, zpp, dpp, -2, wpp);
450 // Aramide for honeycomb
451 float aAra[4] = {1.0079, 12.011, 15.9994, 14.0067};
452 float zAra[4] = {1.0, 6.0, 8.0, 7.0};
453 float wAra[4] = {3.0, 1.0, 1.0, 1.0};
454 float dAra = 0.032;
455 Mixture(61, "Aramide", aAra, zAra, dAra, -4, wAra);
456 // GFK for Wacosit (Epoxy + Si)
457 float aGFK[4] = {1.0079, 12.011, 15.9994, 28.086};
458 float zGFK[4] = {1.0, 6.0, 8.0, 14.0};
459 float wGFK[4] = {0.0445, 0.5031, 0.1118, 0.340};
460 float dGFK = 2.0;
461 Mixture(62, "GFK", aGFK, zGFK, dGFK, 4, wGFK);
462
464 // Tracking Media Parameters
466
467 // General tracking parameter
468 float tmaxfd = -10.0;
469 float stemax = -1.0e10;
470 float deemax = -0.1;
471 float epsil = 1.0e-4;
472 float stmin = -0.001;
473
474 // Al Frame
475 Medium(1, "Al Frame", 1, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
476 // Air
477 Medium(2, "Air", 51, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
478 // Wires
479 Medium(3, "Wires", 2, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
480 // All other ROB materials (caps, etc.)
481 Medium(4, "ROB Other", 2, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
482 // Cu pads
483 Medium(5, "Padplane", 2, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
484 // Fee + cables
485 Medium(6, "Readout", 2, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
486 // C frame (Wacosit)
487 Medium(7, "Wacosit", 62, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
488 // INOX of cooling bus bars
489 Medium(8, "Cooling bus", 7, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
490 // Gas-mixture (Xe/CO2)
491 Medium(9, "Gas-mix", 53, 1, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
492 // Honeycomb
493 Medium(10, "Honeycomb", 61, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
494 // Araldite glue
495 Medium(11, "Glue", 58, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
496 // G10-plates
497 Medium(13, "G10-plates", 54, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
498 // Cooling water
499 Medium(14, "Water", 55, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
500 // Rohacell for the radiator
501 Medium(15, "Rohacell", 56, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
502 // Al layer in MCMs
503 Medium(16, "MCM-Al", 1, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
504 // Sn layer in MCMs
505 Medium(17, "MCM-Sn", 5, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
506 // Cu layer in MCMs
507 Medium(18, "MCM-Cu", 2, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
508 // G10 layer in MCMs
509 Medium(19, "MCM-G10", 54, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
510 // Si in readout chips
511 Medium(20, "Chip-Si", 6, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
512 // Epoxy in readout chips
513 Medium(21, "Chip-Ep", 57, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
514 // PE in connectors
515 Medium(22, "Conn-PE", 52, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
516 // Cu in connectors
517 Medium(23, "Chip-Cu", 2, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
518 // Al of cooling pipes
519 Medium(24, "Cooling", 1, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
520 // Cu in services
521 Medium(25, "Serv-Cu", 2, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
522 // Carbon fiber mat
523 Medium(26, "Carbon", 4, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
524 // Mylar foil
525 Medium(27, "Mylar", 59, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
526 // Polypropylene fibers
527 Medium(28, "Fiber", 60, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
528
529 // Save the density values for the TRD absorbtion
530 float dmy = 1.39;
531 mFoilDensity = dmy;
533 mGasDensity = dgmXe;
534 mGasNobleFraction = fxc;
536 mGasDensity = dgmAr;
537 mGasNobleFraction = fac;
538 }
539}
540
541// setting up the geometry
543{
545
546 std::vector<int> medmapping;
547 // now query the medium mapping and fill a vector to be passed along
548 // to the geometry creation
549 getMediumIDMappingAsVector(medmapping);
550
551 mGeom = Geometry::instance();
552 mGeom->createGeometry(medmapping);
553}
554
555void Detector::defineSensitiveVolumes()
556{
557 auto vols = mGeom->getSensitiveTRDVolumes();
558 for (auto& name : vols) {
559 auto tgeovol = gGeoManager->GetVolume(name.c_str());
560 if (tgeovol != nullptr) {
561 AddSensitiveVolume(tgeovol);
562 } else {
563 LOG(error) << "No TGeo volume for TRD vol name " << name << " found\n";
564 }
565 }
566}
567
569{
570 mGeom->addAlignableVolumes();
571}
572
Global TRD definitions and constants.
Definition of the Stack class.
ClassImp(IdPath)
uint16_t pos
Definition RawData.h:3
uint32_t stack
Definition RawData.h:1
void getMediumIDMappingAsVector(std::vector< int > &mapping)
Definition Detector.h:143
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
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
std::string addNameTo(const char *ext) const
Definition Detector.h:150
Int_t GetCurrentTrackNumber() const override
Definition Stack.h:133
void addTrackReference(const o2::TrackReference &p)
Definition Stack.h:335
~Detector() override
Definition Detector.cxx:53
void InitializeO2Detector() override
Definition Detector.cxx:58
void EndOfEvent() override
Definition Detector.cxx:340
void Register() override
Definition Detector.cxx:317
Detector(Bool_t active=true)
Definition Detector.cxx:35
void ConstructGeometry() override
Definition Detector.cxx:542
void addAlignableVolumes() const override
Add alignable top volumes.
Definition Detector.cxx:568
bool ProcessHits(FairVolume *v=nullptr) override
Definition Detector.cxx:117
void Reset() override
Definition Detector.cxx:333
void FinishEvent() override
Definition Detector.cxx:322
void addAlignableVolumes() const
static Geometry * instance()
Definition Geometry.h:33
void createGeometry(std::vector< int > const &idtmed)
Definition Geometry.cxx:258
std::vector< std::string > const & getSensitiveTRDVolumes() const
Definition Geometry.h:46
int createPhotons(int pdg, float p, std::vector< float > &ePhoton)
Definition TRsim.cxx:122
double getMuAr(double energyMeV)
Definition TRsim.cxx:418
double getMuXe(double energyMeV)
Definition TRsim.cxx:375
float getTemp() const
Definition TRsim.h:114
double getMuCO(double energyMeV)
Definition TRsim.cxx:340
double getMuMy(double energyMeV)
Definition TRsim.cxx:455
static ShmManager & Instance()
Definition ShmManager.h:61
GLint GLenum GLint x
Definition glcorearb.h:403
const GLdouble * v
Definition glcorearb.h:832
GLuint const GLchar * name
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint y
Definition glcorearb.h:270
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLboolean * data
Definition glcorearb.h:298
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
constexpr int NLAYER
the number of layers
Definition Constants.h:27
constexpr int NSECTOR
the number of sectors
Definition Constants.h:25
constexpr int NSTACK
the number of stacks per sector
Definition Constants.h:26
constexpr int MAXCHAMBER
the maximum number of installed chambers
Definition Constants.h:30
void freeSimVector(std::vector< T > *ptr)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Common utility functions.
bool doTR
switch for transition radiation
SimParam::GasMixture gas
the gas mixture in the TRD
float maxMCStepSize
maximum size of MC steps
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"