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