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
23namespace o2
24{
25namespace iotof
26{
27
29 : o2::base::DetImpl<Detector>("TF3", true),
30 mTrackData(),
31 mHits(o2::utils::createSimVector<o2::itsmft::Hit>())
32{
33}
34
36 : o2::base::DetImpl<Detector>("TF3", true),
37 mTrackData(),
38 mHits(o2::utils::createSimVector<o2::itsmft::Hit>())
39{
40 auto& iotofPars = IOTOFBaseParam::Instance();
41 configLayers(iotofPars.enableInnerTOF, iotofPars.enableOuterTOF,
42 iotofPars.enableForwardTOF, iotofPars.enableBackwardTOF,
43 iotofPars.detectorPattern,
44 iotofPars.segmentedInnerTOF, iotofPars.segmentedOuterTOF, iotofPars.x2x0);
45}
46
48{
49 if (mHits) {
51 }
52}
53
59
60void Detector::configLayers(bool itof, bool otof, bool ftof, bool btof, std::string pattern, bool itofSegmented, bool otofSegmented,
61 const float x2x0)
62{
63
64 const float radiusInnerTof = 19.f;
65 const float radiusOuterTof = 85.f;
66 const float lengthInnerTof = 124.f;
67 float lengthOuterTof = 680.f;
68 std::pair<float, float> radiusRangeDiskTof = {15.f, 100.f};
69 float zForwardTof = 370.f;
70 LOG(info) << "Configuring IOTOF layers with '" << pattern << "' pattern";
71 if (pattern == "") {
72 LOG(info) << "Default pattern";
73 } else if (pattern == "v3b") {
74 ftof = false;
75 btof = false;
76 } else if (pattern == "v3b1a") {
77 lengthOuterTof = 500.f;
78 zForwardTof = 270.f;
79 radiusRangeDiskTof = {30.f, 100.f};
80 } else if (pattern == "v3b1b") {
81 lengthOuterTof = 500.f;
82 zForwardTof = 200.f;
83 radiusRangeDiskTof = {20.f, 68.f};
84 } else if (pattern == "v3b2a") {
85 lengthOuterTof = 440.f;
86 zForwardTof = 270.f;
87 radiusRangeDiskTof = {30.f, 120.f};
88 } else if (pattern == "v3b2b") {
89 lengthOuterTof = 440.f;
90 zForwardTof = 200.f;
91 radiusRangeDiskTof = {20.f, 68.f};
92 } else if (pattern == "v3b3") {
93 lengthOuterTof = 580.f;
94 zForwardTof = 200.f;
95 radiusRangeDiskTof = {20.f, 68.f};
96 } else {
97 LOG(fatal) << "IOTOF layer pattern " << pattern << " not recognized, exiting";
98 }
99 if (itof) { // iTOF
100 mITOFLayer = itofSegmented ? ITOFLayer(std::string{GeometryTGeo::getITOFLayerPattern()},
101 radiusInnerTof, 0.f, lengthInnerTof, 0.f, x2x0, ITOFLayer::kBarrelSegmented,
102 24, 5.42, 10.0, 10)
104 radiusInnerTof, 0.f, lengthInnerTof, 0.f, x2x0, ITOFLayer::kBarrel);
105 }
106 if (otof) { // oTOF
107 mOTOFLayer = otofSegmented ? OTOFLayer(std::string{GeometryTGeo::getOTOFLayerPattern()},
108 radiusOuterTof, 0.f, lengthOuterTof, 0.f, x2x0, OTOFLayer::kBarrelSegmented,
109 62, 9.74, 5.0, 54)
111 radiusOuterTof, 0.f, lengthOuterTof, 0.f, x2x0, OTOFLayer::kBarrel);
112 }
113 if (ftof) {
114 mFTOFLayer = FTOFLayer(std::string{GeometryTGeo::getFTOFLayerPattern()},
115 radiusRangeDiskTof.first, radiusRangeDiskTof.second, 0.f, zForwardTof, x2x0, FTOFLayer::kDisk); // fTOF
116 }
117 if (btof) {
118 mBTOFLayer = BTOFLayer(std::string{GeometryTGeo::getBTOFLayerPattern()},
119 radiusRangeDiskTof.first, radiusRangeDiskTof.second, 0.f, -zForwardTof, x2x0, BTOFLayer::kDisk); // bTOF
120 }
121}
122
126
128{
129 int ifield = 2; // ?
130 float fieldm = 10.0; // ?
132
133 float tmaxfdSi = 0.1; // .10000E+01; // Degree
134 float stemaxSi = 0.0075; // .10000E+01; // cm
135 float deemaxSi = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
136 float epsilSi = 1.0E-4; // .10000E+01;
137 float stminSi = 0.0; // cm "Default value used"
138
139 float tmaxfdAir = 0.1; // .10000E+01; // Degree
140 float stemaxAir = .10000E+01; // cm
141 float deemaxAir = 0.1; // 0.30000E-02; // Fraction of particle's energy 0<deemax<=1
142 float epsilAir = 1.0E-4; // .10000E+01;
143 float stminAir = 0.0; // cm "Default value used"
144
145 // AIR
146 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
147 float zAir[4] = {6., 7., 8., 18.};
148 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
149 float dAir = 1.20479E-3;
150
151 o2::base::Detector::Mixture(1, "AIR$", aAir, zAir, dAir, 4, wAir);
152 o2::base::Detector::Medium(1, "AIR$", 1, 0, ifield, fieldm, tmaxfdAir, stemaxAir, deemaxAir, epsilAir, stminAir);
153
154 o2::base::Detector::Material(3, "SILICON$", 0.28086E+02, 0.14000E+02, 0.23300E+01, 0.93600E+01, 0.99900E+03);
155 o2::base::Detector::Medium(3, "SILICON$", 3, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
156}
157
159{
160 TGeoManager* geoManager = gGeoManager;
161 TGeoVolume* vALIC = geoManager->GetVolume("barrel");
162 if (!vALIC) {
163 LOGP(fatal, "Could not find barrel volume while constructing IOTOF geometry");
164 }
165 new TGeoVolumeAssembly(GeometryTGeo::getIOTOFVolPattern());
166 TGeoVolume* vIOTOF = geoManager->GetVolume(GeometryTGeo::getIOTOFVolPattern());
167 vALIC->AddNode(vIOTOF, 2, new TGeoTranslation(0, 30., 0));
168
169 char vstrng[100] = "IOTOFVol";
170 vIOTOF->SetTitle(vstrng);
171
172 auto& iotofPars = IOTOFBaseParam::Instance();
173 if (iotofPars.enableInnerTOF) {
174 mITOFLayer.createLayer(vIOTOF);
175 }
176 if (iotofPars.enableOuterTOF) {
177 mOTOFLayer.createLayer(vIOTOF);
178 }
179 if (iotofPars.enableForwardTOF) {
180 mFTOFLayer.createLayer(vIOTOF);
181 }
182 if (iotofPars.enableBackwardTOF) {
183 mBTOFLayer.createLayer(vIOTOF);
184 }
185}
186
188{
189 LOG(info) << "Initialize IOTOF O2Detector";
190 mGeometryTGeo = GeometryTGeo::Instance();
191 defineSensitiveVolumes();
192}
193
194void Detector::defineSensitiveVolumes()
195{
196 TGeoManager* geoManager = gGeoManager;
197 TGeoVolume* v;
198
199 // The names of the IOTOF sensitive volumes have the format: IOTOFLayer(0...mLayers.size()-1)
200 auto& iotofPars = IOTOFBaseParam::Instance();
201 if (iotofPars.enableInnerTOF) {
202 for (const std::string& itofSensor : ITOFLayer::mRegister) {
203 v = geoManager->GetVolume(itofSensor.c_str());
204 LOGP(info, "Adding IOTOF Sensitive Volume {}", v->GetName());
205 AddSensitiveVolume(v);
206 }
207 }
208 if (iotofPars.enableOuterTOF) {
209 for (const std::string& otofSensor : OTOFLayer::mRegister) {
210 v = geoManager->GetVolume(otofSensor.c_str());
211 LOGP(info, "Adding IOTOF Sensitive Volume {}", v->GetName());
212 AddSensitiveVolume(v);
213 }
214 }
215 if (iotofPars.enableForwardTOF) {
216 v = geoManager->GetVolume(GeometryTGeo::getFTOFSensorPattern());
217 LOGP(info, "Adding IOTOF Sensitive Volume {}", v->GetName());
218 AddSensitiveVolume(v);
219 }
220 if (iotofPars.enableBackwardTOF) {
221 v = geoManager->GetVolume(GeometryTGeo::getBTOFSensorPattern());
222 LOGP(info, "Adding IOTOF Sensitive Volume {}", v->GetName());
223 AddSensitiveVolume(v);
224 }
225}
226
228
230{
231 // This will create a branch in the output tree called Hit, setting the last
232 // parameter to false means that this collection will not be written to the file,
233 // it will exist only during the simulation
234
235 if (FairRootManager::Instance()) {
236 FairRootManager::Instance()->RegisterAny(addNameTo("Hit").data(), mHits, true);
237 }
238}
239
241{
242 if (!o2::utils::ShmManager::Instance().isOperational()) {
243 mHits->clear();
244 }
245}
246
247bool Detector::ProcessHits(FairVolume* vol)
248{
249 // This method is called from the MC stepping
250 if (!(fMC->TrackCharge())) {
251 return false;
252 }
253
254 int lay = vol->getVolumeId();
255 int volID = vol->getMCid();
256
257 // Is it needed to keep a track reference when the outer volume is encountered?
258 auto stack = (o2::data::Stack*)fMC->GetStack();
259 if (fMC->IsTrackExiting() /*&& (lay == 0 || lay == mLayers.size() - 1)*/) {
260 // Keep the track refs for the innermost and outermost layers only
261 o2::TrackReference tr(*fMC, GetDetId());
262 tr.setTrackID(stack->GetCurrentTrackNumber());
263 tr.setUserId(lay);
264 stack->addTrackReference(tr);
265 }
266 bool startHit = false, stopHit = false;
267 unsigned char status = 0;
268 if (fMC->IsTrackEntering()) {
270 }
271 if (fMC->IsTrackInside()) {
273 }
274 if (fMC->IsTrackExiting()) {
276 }
277 if (fMC->IsTrackOut()) {
279 }
280 if (fMC->IsTrackStop()) {
282 }
283 if (fMC->IsTrackAlive()) {
285 }
286
287 // track is entering or created in the volume
288 if ((status & o2::itsmft::Hit::kTrackEntering) || (status & o2::itsmft::Hit::kTrackInside && !mTrackData.mHitStarted)) {
289 startHit = true;
291 stopHit = true;
292 }
293
294 // increment energy loss at all steps except entrance
295 if (!startHit) {
296 mTrackData.mEnergyLoss += fMC->Edep();
297 }
298 if (!(startHit | stopHit)) {
299 return false; // do noting
300 }
301
302 if (startHit) {
303 mTrackData.mEnergyLoss = 0.;
304 fMC->TrackMomentum(mTrackData.mMomentumStart);
305 fMC->TrackPosition(mTrackData.mPositionStart);
306 mTrackData.mTrkStatusStart = status;
307 mTrackData.mHitStarted = true;
308 }
309 if (stopHit) {
310 TLorentzVector positionStop;
311 fMC->TrackPosition(positionStop);
312 // Retrieve the indices with the volume path
313 int stave(0), halfstave(0), chipinmodule(0), module;
314 fMC->CurrentVolOffID(1, chipinmodule);
315 fMC->CurrentVolOffID(2, module);
316 fMC->CurrentVolOffID(3, halfstave);
317 fMC->CurrentVolOffID(4, stave);
318
319 o2::itsmft::Hit* p = addHit(stack->GetCurrentTrackNumber(), lay, mTrackData.mPositionStart.Vect(), positionStop.Vect(),
320 mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(),
321 mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status);
322
323 // RS: not sure this is needed
324 // Increment number of Detector det points in TParticle
325 stack->addHit(GetDetId());
326 }
327
328 return true;
329}
330
331o2::itsmft::Hit* Detector::addHit(int trackID, int detID, const TVector3& startPos, const TVector3& endPos,
332 const TVector3& startMom, double startE, double endTime, double eLoss, unsigned char startStatus,
333 unsigned char endStatus)
334{
335 mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus);
336 return &(mHits->back());
337}
338} // namespace iotof
339} // namespace o2
340
Definition of the Stack class.
Definition of the ITSMFT Hit class.
ClassImp(o2::hmpid::Detector)
uint32_t stack
Definition RawData.h:1
void setUserId(Int_t userId)
void setTrackID(Int_t track)
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
virtual void createLayer(TGeoVolume *motherVolume) override
Definition Layer.cxx:414
void Reset() override
Definition Detector.cxx:240
bool ProcessHits(FairVolume *v=nullptr) override
Definition Detector.cxx:247
o2::itsmft::Hit * addHit(int trackID, int detID, const TVector3 &startPos, const TVector3 &endPos, const TVector3 &startMom, double startE, double endTime, double eLoss, unsigned char startStatus, unsigned char endStatus)
Definition Detector.cxx:331
void Register() override
Definition Detector.cxx:229
void ConstructGeometry() override
Definition Detector.cxx:54
void configLayers(bool itof=true, bool otof=true, bool ftof=true, bool btof=true, std::string pattern="", bool itofSegmented=false, bool otofSegmented=false, const float x2x0=0.02f)
Definition Detector.cxx:60
void InitializeO2Detector() override
Definition Detector.cxx:187
void EndOfEvent() override
Definition Detector.cxx:227
virtual void createLayer(TGeoVolume *motherVolume) override
Definition Layer.cxx:382
static const char * getFTOFLayerPattern()
static const char * getIOTOFVolPattern()
static const char * getOTOFLayerPattern()
static const char * getFTOFSensorPattern()
static const char * getBTOFLayerPattern()
static GeometryTGeo * Instance()
static const char * getITOFLayerPattern()
static const char * getBTOFSensorPattern()
virtual void createLayer(TGeoVolume *motherVolume) override
Definition Layer.cxx:120
static constexpr int kBarrelSegmented
Definition Layer.h:43
static constexpr int kDisk
Definition Layer.h:42
static constexpr int kBarrel
Definition Layer.h:41
virtual void createLayer(TGeoVolume *motherVolume) override
Definition Layer.cxx:252
@ kTrackStopped
Definition Hit.h:38
@ kTrackInside
Definition Hit.h:35
@ kTrackAlive
Definition Hit.h:39
@ kTrackEntering
Definition Hit.h:34
@ kTrackExiting
Definition Hit.h:36
static ShmManager & Instance()
Definition ShmManager.h:61
const GLdouble * v
Definition glcorearb.h:832
GLboolean * data
Definition glcorearb.h:298
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"
std::array< uint16_t, 5 > pattern