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
16
17#include "DataFormatsFDD/Hit.h"
18
19#include "FDDBase/Geometry.h"
20
22
23#include "DetectorsBase/Stack.h"
24#include "Field/MagneticField.h"
25
26#include "TVirtualMC.h"
27#include "TLorentzVector.h"
28#include "TVector3.h"
29#include "TGeoManager.h"
30#include "TRandom.h"
31
32#include <fairlogger/Logger.h>
33#include "FairRootManager.h"
34#include "FairVolume.h"
35#include "FairRootManager.h"
37
38using namespace o2::fdd;
40using o2::fdd::Hit;
41
43
44//_____________________________________________________________________________
45Detector::Detector(Bool_t Active)
46 : o2::base::DetImpl<Detector>("FDD", Active),
47 mHits(o2::utils::createSimVector<o2::fdd::Hit>()),
48 mGeometry(nullptr)
49{
50}
51
52//_____________________________________________________________________________
54 : o2::base::DetImpl<Detector>(src),
55 mHits(o2::utils::createSimVector<o2::fdd::Hit>())
56{
57}
58
59//_____________________________________________________________________________
60Detector& Detector::operator=(const Detector& src)
61{
62
63 if (this == &src) {
64 return *this;
65 }
66 // base class assignment
68
69 mHits = nullptr;
70 return *this;
71}
72
73//_____________________________________________________________________________
75{
76
77 if (mHits) {
79 }
80}
81
82//_____________________________________________________________________________
84{
85
86 TGeoVolume* vol;
87
88 vol = gGeoManager->GetVolume("FDApad");
89 if (!vol) {
90 LOG(fatal) << "can't find volume FDApad";
91 } else {
93 }
94
95 vol = gGeoManager->GetVolume("FDCpad");
96 if (!vol) {
97 LOG(fatal) << "can't find volume FDCpad";
98 } else {
100 }
101}
102
103//_____________________________________________________________________________
105{
106 // This is step manager
107 if (fMC->IsTrackEntering() && !fMC->IsNewTrack() && fMC->TrackCharge() != 0) { // one reference per charged particle, first entry from outside
108 auto o2stack = static_cast<o2::data::Stack*>(fMC->GetStack());
109 if (o2stack->GetCurrentTrackNumber() != mTrackRefLastTrackID) {
110 mTrackRefLastTrackID = o2stack->GetCurrentTrackNumber();
111 o2stack->addTrackReference(o2::TrackReference(*fMC, GetDetId()));
112 }
113 }
114 // do not track neutral particles
115 if (!(fMC->TrackCharge())) {
116 return kFALSE;
117 }
118
119 Int_t copy;
120 Int_t current_volid = fMC->CurrentVolID(copy);
121
122 // Get sensitive volumes id (scintillator pads)
123 static Int_t idFDA = fMC->VolId("FDApad");
124 static Int_t idFDC = fMC->VolId("FDCpad");
125
126 // Get sector copy (1,2,3,4) ( 1 level up from pad )
127 Int_t sect;
128 fMC->CurrentVolOffID(1, sect);
129
130 // Get Detector copy (1,2) ( 2 levels up from pad )
131 Int_t detc;
132 fMC->CurrentVolOffID(2, detc);
133
134 // Set detector type: FDA or FDC
135 Int_t ADlayer = (current_volid == idFDC) ? 0 : 2;
136
137 sect--; // sector within layer [0-3]
138 detc--; // detector copy [0-1]
139 ADlayer += detc; // global layer number [0-3]
140
141 Int_t ADsector = ADlayer * 4 + sect; // Global AD sector number [0-15]
142 // Layer Sector Number
143 // FDC 0 = 0- 3
144 // FDC 1 = 4- 7
145 // FDA 2 = 8-11
146 // FDA 3 = 12-15
147
148 Float_t fFDDLightYield(12.8e6);
149 //BC420 yield is 0.64 of antracene which is 20k photons/MeV = 12800/MeV = 12.8e6/GeV
150
151 Float_t destep_ad = fMC->Edep();
152 Int_t nPhotonsInStep_ad = Int_t(fFDDLightYield * destep_ad);
153 nPhotonsInStep_ad = o2::base::simRandom()->Poisson(nPhotonsInStep_ad);
154
155 mElossAD += destep_ad;
156
157 if (fMC->IsTrackEntering()) {
158 mNPhotonsAD = nPhotonsInStep_ad;
159 fMC->TrackPosition(mHitPosAD(0), mHitPosAD(1), mHitPosAD(2));
160
161 mElossAD = 0.0;
162 return kFALSE;
163 }
164 mNPhotonsAD += nPhotonsInStep_ad;
165
166 if (fMC->IsTrackExiting() || fMC->IsTrackStop() || fMC->IsTrackDisappeared()) {
167 Int_t trackID = fMC->GetStack()->GetCurrentTrackNumber();
168
169 Float_t time = fMC->TrackTime() * 1.0e9; //time from seconds to ns
170
171 addHit(trackID, ADsector, mHitPosAD, time, mElossAD, mNPhotonsAD);
172 return kTRUE;
173 }
174
175 return kFALSE;
176}
177
178//_____________________________________________________________________________
179Hit* Detector::addHit(int trackID, unsigned short detID, const TVector3& Pos, double Time, double eLoss, int nPhot)
180{
181 //LOG(info) << "FDD hit "<<trackID<<" "<<detID<<" "<<Time<<" "<<eLoss<<" "<<nPhot;
182 mHits->emplace_back(trackID, detID, Pos, Time, eLoss, nPhot);
183 auto stack = (o2::data::Stack*)fMC->GetStack();
184 stack->addHit(GetDetId());
185
186 return &(mHits->back());
187}
188
189//_____________________________________________________________________________
191{
192
193 Float_t density, as[11], zs[11], ws[11];
194 Double_t radLength, absLength, a_ad, z_ad;
195 Int_t id;
196
197 // PVC (C2H3Cl)n
198 Float_t aPVC[3] = {12.0107, 1.00794, 35.4527};
199 Float_t zPVC[3] = {6., 1., 35.};
200 Float_t wPVC[3] = {2., 3., 1.};
201 Float_t dPVC = 1.3;
202 o2::base::Detector::Mixture(47, "PVC", aPVC, zPVC, dPVC, -3, wPVC);
203
204 // Air
205 Float_t aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
206 Float_t zAir[4] = {6., 7., 8., 18.};
207 Float_t wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
208 Float_t dAir1 = 1.20479E-11;
209 // Steel
210 Float_t asteel[4] = {55.847, 51.9961, 58.6934, 28.0855};
211 Float_t zsteel[4] = {26., 24., 28., 14.};
212 Float_t wsteel[4] = {.715, .18, .1, .005};
213 // Cast iron
214 Float_t acasti[4] = {55.847, 12.011, 28.085, 54.938};
215 Float_t zcasti[4] = {26., 6., 14., 25.};
216 Float_t wcasti[4] = {0.929, 0.035, 0.031, 0.005};
217
218 o2::base::Detector::Material(9, "ALU", 26.98, 13., 2.7, 8.9, 37.2);
219 o2::base::Detector::Material(10, "IRON", 55.85, 26., 7.87, 1.76, 17.1);
220 o2::base::Detector::Material(11, "COPPER", 63.55, 29., 8.96, 1.43, 15.1);
221 o2::base::Detector::Mixture(16, "VACUUM", aAir, zAir, dAir1, 4, wAir);
222 o2::base::Detector::Mixture(19, "STAINLESS_STEEL", asteel, zsteel, 7.88, 4, wsteel);
223 o2::base::Detector::Material(13, "LEAD", 207.19, 82., 11.35, .56, 18.5);
224 o2::base::Detector::Mixture(18, "CAST_IRON", acasti, zcasti, 7.2, 4, wcasti);
225
226 // ****************
227 // Tracking media parameters.
228 Int_t fieldType = 3; // Field type
229 Double_t maxField = 5.0; // Field max.
230 Float_t epsil, stmin, tmaxfd, deemax, stemax;
231 epsil = 0.001; // Tracking precision,
232 stemax = -1.; // Maximum displacement for multiple scat
233 tmaxfd = -20.; // Maximum angle due to field deflection
234 deemax = -.3; // Maximum fractional energy loss, DLS
235 stmin = -.8;
236 // ***************
237
238 o2::base::Detector::Medium(47, "PVC", 47, 0, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
239 o2::base::Detector::Medium(9, "ALU", 9, 0, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
240 o2::base::Detector::Medium(10, "FE", 10, 0, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
241 o2::base::Detector::Medium(11, "Cu", 11, 0, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
242 o2::base::Detector::Medium(16, "VA", 16, 0, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
243 o2::base::Detector::Medium(13, "PB", 13, 0, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
244 o2::base::Detector::Medium(19, "ST", 19, 0, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
245
246 // Parameters for AD scintillator: BC420
247 // NE-102, has the following properties :
248 // Density : ca. 1.032 g/cm3
249 // Electrons/cm3: 3.37 x 10^23
250 // H atoms/cm3: 5.21 x 10^22
251 // C atoms/cm3: 4.74 x 10^22
252 // Ratio of H to C : 1.100
253 // wavelength of emission : 408 nm.
254 // Decay time : 1.8 ns.
255 // Photons/MeV: 0.64 of antracene which is 20k photons/MeV
256 // H // C
257 as[0] = 1.00794;
258 as[1] = 12.011;
259 zs[0] = 1.;
260 zs[1] = 6.;
261 ws[0] = 5.21;
262 ws[1] = 4.74;
263 density = 1.032;
264 id = 1;
265 o2::base::Detector::Mixture(id, "BC420", as, zs, density, -2, ws);
266 o2::base::Detector::Medium(id, "BC420", id, 1, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
267
268 // Parameters for lightGuide:
269 // Should be Poly(methyl methacrylate) (PMMA) acrylic
270 // (C5O2H8)n
271 // Density 1.18 g/cm3
272 // Mixture PMMA Aeff=12.3994 Zeff=6.23653 rho=1.18 radlen=34.0677 intlen=63.3073
273 // Element #0 : C Z= 6.00 A= 12.01 w= 0.600 natoms=5
274 // Element #1 : H Z= 1.00 A= 1.01 w= 0.081 natoms=8
275 // Element #2 : O Z= 8.00 A= 16.00 w= 0.320 natoms=2
276
277 // Carbon Hydrogen Oxygen
278 as[0] = 12.0107;
279 as[1] = 1.00794;
280 as[2] = 15.9994;
281 zs[0] = 6.;
282 zs[1] = 1.;
283 zs[2] = 8.;
284 ws[0] = 0.60;
285 ws[1] = 0.081;
286 ws[2] = 0.32;
287 density = 1.18;
288 id = 2;
289 o2::base::Detector::Mixture(id, "PMMA", as, zs, density, 3, ws);
290 o2::base::Detector::Medium(id, "PMMA", id, 1, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
291
292 // mu-metal
293 // Niquel Iron Molybdenum Manganese
294 as[0] = 58.6934;
295 as[1] = 55.845;
296 as[2] = 95.94;
297 as[3] = 54.9380;
298 zs[0] = 28.;
299 zs[1] = 26.;
300 zs[2] = 42.;
301 zs[3] = 25.;
302 ws[0] = 0.802;
303 ws[1] = 0.14079;
304 ws[2] = 0.0485;
305 ws[3] = 0.005;
306 // Silicon Chromium Cobalt Aluminium
307 as[4] = 28.0855;
308 as[5] = 51.9961;
309 as[6] = 58.9332;
310 as[7] = 26.981539;
311 zs[4] = 14.;
312 zs[5] = 24.;
313 zs[6] = 27.;
314 zs[7] = 13.;
315 ws[4] = 0.003;
316 ws[5] = 0.0002;
317 ws[6] = 0.0002;
318 ws[7] = 0.0001;
319 // Carbon Phosphorus Sulfur
320 as[8] = 12.0107;
321 as[9] = 30.97376;
322 as[10] = 32.066;
323 zs[8] = 6.;
324 zs[9] = 15.;
325 zs[10] = 16.;
326 ws[8] = 0.00015;
327 ws[9] = 0.00005;
328 ws[10] = 0.00001;
329 density = 8.25;
330 id = 3;
331 o2::base::Detector::Mixture(id, "MuMetal", as, zs, density, 11, ws);
332 o2::base::Detector::Medium(id, "MuMetal", id, 1, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
333
334 // Parameters for FDCPMA: Aluminium
335 a_ad = 26.98;
336 z_ad = 13.00;
337 density = 2.7;
338 radLength = 8.9;
339 absLength = 37.2;
340 id = 4;
341 o2::base::Detector::Material(id, "Alum", a_ad, z_ad, density, radLength, absLength);
342 o2::base::Detector::Medium(id, "Alum", id, 1, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
343
344 // Parameters for FDCPMG: Glass for the simulation Aluminium
345 a_ad = 26.98;
346 z_ad = 13.00;
347 density = 2.7;
348 radLength = 8.9;
349 absLength = 37.2;
350 id = 5;
351 o2::base::Detector::Material(id, "Glass", a_ad, z_ad, density, radLength, absLength);
352 o2::base::Detector::Medium(id, "Glass", id, 1, fieldType, maxField, tmaxfd, stemax, deemax, epsil, stmin);
353}
354//_____________________________________________________________________________
360//_____________________________________________________________________________
362{
363 // This will create a branch in the output tree called Hit, setting the last
364 // parameter to kFALSE means that this collection will not be written to the file,
365 // it will exist only during the simulation
366
368 FairRootManager::Instance()->RegisterAny(addNameTo("Hit").data(), mHits, kTRUE);
369 }
370}
371
372//_____________________________________________________________________________
374{
375 if (!o2::utils::ShmManager::Instance().isOperational()) {
376 mHits->clear();
377 }
378 mTrackRefLastTrackID = -1;
379}
Definition of the Stack class.
Base definition of FIT-FDD geometry.
Definition of the Detector class.
ClassImp(o2::fdd::Detector)
int16_t time
Definition RawEventData.h:4
Definition of the MagF class.
uint32_t stack
Definition RawData.h:1
Int_t GetDetId()
void AddSensitiveVolume(TGeoVolume *v)
TVirtualMC * fMC
flag for initialisation
Definition FairModule.h:160
void RegisterAny(const char *name, T *&obj, Bool_t toFile)
static FairRootManager * Instance()
Detector & operator=(const Detector &)
Definition Detector.cxx:46
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 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:151
~Detector() override
Default destructor.
Definition Detector.cxx:74
void InitializeO2Detector() override
Definition Detector.cxx:83
void Register() override
Registers the produced collections in FAIRRootManager.
Definition Detector.cxx:361
Bool_t ProcessHits(FairVolume *v=nullptr) override
Definition Detector.cxx:104
void ConstructGeometry() override
Definition Detector.cxx:355
Detector()=default
Default constructor.
void Reset() override
Definition Detector.cxx:373
o2::fdd::Hit * addHit(int trackID, unsigned short detID, const TVector3 &Pos, double Time, double eLoss, int nPhot)
Definition Detector.cxx:179
FIT-FDD Geometry.
Definition Geometry.h:30
static ShmManager & Instance()
Definition ShmManager.h:62
GLuint id
Definition glcorearb.h:650
TRandom * simRandom()
Definition SimRandom.cxx:22
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.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"