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