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