12#include <FairVolume.h>
14#include <TVirtualMC.h>
15#include <TVirtualMCStack.h>
16#include <TGeoVolume.h>
31 mHits(
o2::
utils::createSimVector<
o2::itsmft::Hit>())
38 mHits(
o2::
utils::createSimVector<
o2::itsmft::Hit>())
41 configLayers(iotofPars.enableInnerTOF, iotofPars.enableOuterTOF,
42 iotofPars.enableForwardTOF, iotofPars.enableBackwardTOF,
43 iotofPars.detectorPattern,
44 iotofPars.segmentedInnerTOF, iotofPars.segmentedOuterTOF, iotofPars.x2x0, iotofPars.sensorThickness);
61 const float x2x0,
const float sensorThickness)
65 std::pair<float, float> dInnerTof = {iotofPars.itofRadius, iotofPars.itofLength};
66 std::pair<float, float> dOuterTof = {iotofPars.otofRadius, iotofPars.otofLength};
67 std::pair<float, float> radiusRangeDiskTof = {15.f, 100.f};
68 float zForwardTof = 370.f;
69 LOG(info) <<
"Configuring IOTOF layers with '" <<
pattern <<
"' pattern";
71 LOG(info) <<
"Default pattern";
75 }
else if (
pattern ==
"v3b1a") {
76 dOuterTof.second = 500.f;
78 radiusRangeDiskTof = {30.f, 100.f};
79 }
else if (
pattern ==
"v3b1b") {
80 dOuterTof.second = 500.f;
82 radiusRangeDiskTof = {20.f, 68.f};
83 }
else if (
pattern ==
"v3b2a") {
84 dOuterTof.second = 440.f;
86 radiusRangeDiskTof = {30.f, 120.f};
87 }
else if (
pattern ==
"v3b2b") {
88 dOuterTof.second = 440.f;
90 radiusRangeDiskTof = {20.f, 68.f};
92 dOuterTof.second = 580.f;
94 radiusRangeDiskTof = {20.f, 68.f};
95 }
else if (
pattern.rfind(
"custom/") == 0) {
97 LOG(fatal) <<
"Custom IOTOF pattern does not support segmented configuration, exiting";
100 TString patternStr(
pattern.c_str());
101 patternStr.ReplaceAll(
"custom/",
"");
102 TObjArray* tokens = patternStr.Tokenize(
"/");
103 for (
int i = 0;
i < tokens->GetEntries(); ++
i) {
104 TString token(tokens->At(
i)->GetName());
105 patternStr.ReplaceAll(token,
"");
106 if (token.BeginsWith(
"itof_radius:")) {
107 token.ReplaceAll(
"itof_radius:",
"");
108 dInnerTof.first = token.Atof();
109 LOG(info) <<
"Custom iTOF radius: " << dInnerTof.first <<
" cm";
110 }
else if (token.BeginsWith(
"otof_radius:")) {
111 token.ReplaceAll(
"otof_radius:",
"");
112 dOuterTof.first = token.Atof();
113 LOG(info) <<
"Custom oTOF radius: " << dOuterTof.first <<
" cm";
115 LOG(fatal) <<
"Unrecognized token in custom IOTOF pattern: " << token.Data() <<
", exiting";
118 patternStr.ReplaceAll(
"/",
"");
119 if (!patternStr.IsWhitespace()) {
120 LOG(fatal) <<
"Unrecognized part in custom IOTOF pattern: " << patternStr.Data() <<
", exiting";
123 LOG(fatal) <<
"IOTOF layer pattern " <<
pattern <<
" not recognized, exiting";
128 const int nStaves = itofSegmented ? iotofPars.itofNStaves : 0;
129 const double staveWidth = itofSegmented ? 5.42 : 0.0;
130 const double staveTiltAngle = itofSegmented ? iotofPars.itofStaveTilt : 0.0;
131 const int modulesPerStave = itofSegmented ? 7 : 0;
134 nStaves, staveWidth, staveTiltAngle, modulesPerStave, itofSegmented ? sensorThickness : 0.0f);
138 const int nStaves = otofSegmented ? iotofPars.otofNStaves : 0;
139 const double staveWidth = otofSegmented ? 9.74 : 0.0;
140 const double staveTiltAngle = otofSegmented ? iotofPars.otofStaveTilt : 0.0;
141 const int modulesPerStave = otofSegmented ? 38 : 0;
144 nStaves, staveWidth, staveTiltAngle, modulesPerStave, otofSegmented ? sensorThickness : 0.0f);
166 float tmaxfdSi = 0.1;
167 float stemaxSi = 0.0075;
168 float deemaxSi = 0.1;
169 float epsilSi = 1.0E-4;
172 float tmaxfdAir = 0.1;
173 float stemaxAir = .10000E+01;
174 float deemaxAir = 0.1;
175 float epsilAir = 1.0E-4;
176 float stminAir = 0.0;
179 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
180 float zAir[4] = {6., 7., 8., 18.};
181 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
182 float dAir = 1.20479E-3;
185 o2::base::Detector::Medium(1,
"AIR$", 1, 0, ifield, fieldm, tmaxfdAir, stemaxAir, deemaxAir, epsilAir, stminAir);
188 o2::base::Detector::Medium(3,
"SILICON$", 3, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
193 TGeoManager* geoManager = gGeoManager;
194 TGeoVolume* vALIC = geoManager->GetVolume(
"barrel");
196 LOGP(fatal,
"Could not find barrel volume while constructing IOTOF geometry");
200 vALIC->AddNode(vIOTOF, 2,
new TGeoTranslation(0, 30., 0));
202 char vstrng[100] =
"IOTOFVol";
203 vIOTOF->SetTitle(vstrng);
206 if (iotofPars.enableInnerTOF) {
209 if (iotofPars.enableOuterTOF) {
212 if (iotofPars.enableForwardTOF) {
215 if (iotofPars.enableBackwardTOF) {
222 LOG(info) <<
"Initialize IOTOF O2Detector";
224 defineSensitiveVolumes();
227void Detector::defineSensitiveVolumes()
229 TGeoManager* geoManager = gGeoManager;
233 const bool itof = iotofPars.enableInnerTOF;
234 const bool otof = iotofPars.enableOuterTOF;
235 bool ftof = iotofPars.enableForwardTOF;
236 bool btof = iotofPars.enableBackwardTOF;
237 const std::string
pattern = iotofPars.detectorPattern;
239 LOG(info) <<
"Default pattern";
243 }
else if (
pattern ==
"v3b1a") {
244 }
else if (
pattern ==
"v3b1b") {
245 }
else if (
pattern ==
"v3b2a") {
246 }
else if (
pattern ==
"v3b2b") {
247 }
else if (
pattern ==
"v3b3") {
248 }
else if (
pattern.rfind(
"custom/") == 0) {
250 LOG(fatal) <<
"IOTOF layer pattern " <<
pattern <<
" not recognized, exiting";
255 for (
const std::string& itofSensor : ITOFLayer::mRegister) {
256 v = geoManager->GetVolume(itofSensor.c_str());
257 LOGP(info,
"Adding IOTOF Sensitive Volume {}",
v->GetName());
258 AddSensitiveVolume(
v);
262 for (
const std::string& otofSensor : OTOFLayer::mRegister) {
263 v = geoManager->GetVolume(otofSensor.c_str());
264 LOGP(info,
"Adding IOTOF Sensitive Volume {}",
v->GetName());
265 AddSensitiveVolume(
v);
270 LOGP(info,
"Adding IOTOF Sensitive Volume {}",
v->GetName());
271 AddSensitiveVolume(
v);
275 LOGP(info,
"Adding IOTOF Sensitive Volume {}",
v->GetName());
276 AddSensitiveVolume(
v);
288 if (FairRootManager::Instance()) {
289 FairRootManager::Instance()->RegisterAny(
addNameTo(
"Hit").
data(), mHits,
true);
303 if (!(fMC->TrackCharge())) {
307 int lay = vol->getVolumeId();
308 int volID = vol->getMCid();
312 if (fMC->IsTrackExiting() ) {
317 stack->addTrackReference(tr);
319 bool startHit =
false, stopHit =
false;
320 unsigned char status = 0;
321 if (fMC->IsTrackEntering()) {
324 if (fMC->IsTrackInside()) {
327 if (fMC->IsTrackExiting()) {
330 if (fMC->IsTrackOut()) {
333 if (fMC->IsTrackStop()) {
336 if (fMC->IsTrackAlive()) {
349 mTrackData.mEnergyLoss += fMC->Edep();
351 if (!(startHit | stopHit)) {
356 mTrackData.mEnergyLoss = 0.;
357 fMC->TrackMomentum(mTrackData.mMomentumStart);
358 fMC->TrackPosition(mTrackData.mPositionStart);
359 mTrackData.mTrkStatusStart = status;
360 mTrackData.mHitStarted =
true;
363 TLorentzVector positionStop;
364 fMC->TrackPosition(positionStop);
372 int stave(0), chipinmodule(0), substave(1), module(0);
373 fMC->CurrentVolOffID(1, chipinmodule);
374 fMC->CurrentVolOffID(2, module);
376 fMC->CurrentVolOffID(3, stave);
377 }
else if (layN == 1) {
378 fMC->CurrentVolOffID(3, substave);
379 fMC->CurrentVolOffID(4, stave);
385 if (iotofPars.segmentedInnerTOF && iotofPars.segmentedOuterTOF) {
387 sensorID = mGeometryTGeo->
getIOTOFChipIndex(layN, stave, substave, module, chipinmodule);
389 sensorID += (mGeometryTGeo->
getSize() - 1);
394 mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(),
395 mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status);
399 stack->addHit(GetDetId());
406 const TVector3& startMom,
double startE,
double endTime,
double eLoss,
unsigned char startStatus,
407 unsigned char endStatus)
409 mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus);
410 return &(mHits->back());
Definition of the Stack class.
Definition of the ITSMFT Hit class.
ClassImp(o2::hmpid::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)
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)
static void initFieldTrackingParams(int &mode, float &maxfield)
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)
std::string addNameTo(const char *ext) const
static const IOTOFBaseParam & Instance()
virtual void createLayer(TGeoVolume *motherVolume) override
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)
bool ProcessHits(FairVolume *v=nullptr) override
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)
void ConstructGeometry() override
void InitializeO2Detector() override
void EndOfEvent() override
virtual void createLayer(TGeoVolume *motherVolume) override
int getIOTOFChipIndex(int lay, int sta, int substa, int mod, int chip) const
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
static constexpr int kBarrelSegmented
static constexpr int kDisk
static constexpr int kBarrel
static constexpr int kBarrelStaggered
virtual void createLayer(TGeoVolume *motherVolume) override
static ShmManager & Instance()
GLuint const GLchar * name
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