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