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