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);
61 const float x2x0,
const float sensorThickness)
64 std::pair<float, float> dInnerTof = {21.f, 129.f};
65 std::pair<float, float> dOuterTof = {92.f, 680.f};
66 std::pair<float, float> radiusRangeDiskTof = {15.f, 100.f};
67 float zForwardTof = 370.f;
68 LOG(info) <<
"Configuring IOTOF layers with '" <<
pattern <<
"' pattern";
70 LOG(info) <<
"Default pattern";
74 }
else if (
pattern ==
"v3b1a") {
75 dOuterTof.second = 500.f;
77 radiusRangeDiskTof = {30.f, 100.f};
78 }
else if (
pattern ==
"v3b1b") {
79 dOuterTof.second = 500.f;
81 radiusRangeDiskTof = {20.f, 68.f};
82 }
else if (
pattern ==
"v3b2a") {
83 dOuterTof.second = 440.f;
85 radiusRangeDiskTof = {30.f, 120.f};
86 }
else if (
pattern ==
"v3b2b") {
87 dOuterTof.second = 440.f;
89 radiusRangeDiskTof = {20.f, 68.f};
91 dOuterTof.second = 580.f;
93 radiusRangeDiskTof = {20.f, 68.f};
94 }
else if (
pattern.rfind(
"custom/") == 0) {
96 LOG(fatal) <<
"Custom IOTOF pattern does not support segmented configuration, exiting";
99 TString patternStr(
pattern.c_str());
100 patternStr.ReplaceAll(
"custom/",
"");
101 TObjArray* tokens = patternStr.Tokenize(
"/");
102 for (
int i = 0;
i < tokens->GetEntries(); ++
i) {
103 TString token(tokens->At(
i)->GetName());
104 patternStr.ReplaceAll(token,
"");
105 if (token.BeginsWith(
"itof_radius:")) {
106 token.ReplaceAll(
"itof_radius:",
"");
107 dInnerTof.first = token.Atof();
108 LOG(info) <<
"Custom iTOF radius: " << dInnerTof.first <<
" cm";
109 }
else if (token.BeginsWith(
"otof_radius:")) {
110 token.ReplaceAll(
"otof_radius:",
"");
111 dOuterTof.first = token.Atof();
112 LOG(info) <<
"Custom oTOF radius: " << dOuterTof.first <<
" cm";
114 LOG(fatal) <<
"Unrecognized token in custom IOTOF pattern: " << token.Data() <<
", exiting";
117 patternStr.ReplaceAll(
"/",
"");
118 if (!patternStr.IsWhitespace()) {
119 LOG(fatal) <<
"Unrecognized part in custom IOTOF pattern: " << patternStr.Data() <<
", exiting";
122 LOG(fatal) <<
"IOTOF layer pattern " <<
pattern <<
" not recognized, exiting";
126 const int nStaves = itofSegmented ? 24 : 0;
127 const double staveWidth = itofSegmented ? 5.42 : 0.0;
128 const double staveTiltAngle = itofSegmented ? 3.0 : 0.0;
129 const int modulesPerStave = itofSegmented ? 10 : 0;
132 nStaves, staveWidth, staveTiltAngle, modulesPerStave, itofSegmented ? sensorThickness : 0.0f);
136 const int nStaves = otofSegmented ? 62 : 0;
137 const double staveWidth = otofSegmented ? 9.74 : 0.0;
138 const double staveTiltAngle = otofSegmented ? 5.0 : 0.0;
139 const int modulesPerStave = otofSegmented ? 54 : 0;
142 nStaves, staveWidth, staveTiltAngle, modulesPerStave, otofSegmented ? sensorThickness : 0.0f);
164 float tmaxfdSi = 0.1;
165 float stemaxSi = 0.0075;
166 float deemaxSi = 0.1;
167 float epsilSi = 1.0E-4;
170 float tmaxfdAir = 0.1;
171 float stemaxAir = .10000E+01;
172 float deemaxAir = 0.1;
173 float epsilAir = 1.0E-4;
174 float stminAir = 0.0;
177 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
178 float zAir[4] = {6., 7., 8., 18.};
179 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
180 float dAir = 1.20479E-3;
183 o2::base::Detector::Medium(1,
"AIR$", 1, 0, ifield, fieldm, tmaxfdAir, stemaxAir, deemaxAir, epsilAir, stminAir);
186 o2::base::Detector::Medium(3,
"SILICON$", 3, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
191 TGeoManager* geoManager = gGeoManager;
192 TGeoVolume* vALIC = geoManager->GetVolume(
"barrel");
194 LOGP(fatal,
"Could not find barrel volume while constructing IOTOF geometry");
198 vALIC->AddNode(vIOTOF, 2,
new TGeoTranslation(0, 30., 0));
200 char vstrng[100] =
"IOTOFVol";
201 vIOTOF->SetTitle(vstrng);
204 if (iotofPars.enableInnerTOF) {
207 if (iotofPars.enableOuterTOF) {
210 if (iotofPars.enableForwardTOF) {
213 if (iotofPars.enableBackwardTOF) {
220 LOG(info) <<
"Initialize IOTOF O2Detector";
222 defineSensitiveVolumes();
225void Detector::defineSensitiveVolumes()
227 TGeoManager* geoManager = gGeoManager;
231 const bool itof = iotofPars.enableInnerTOF;
232 const bool otof = iotofPars.enableOuterTOF;
233 bool ftof = iotofPars.enableForwardTOF;
234 bool btof = iotofPars.enableBackwardTOF;
235 const std::string
pattern = iotofPars.detectorPattern;
237 LOG(info) <<
"Default pattern";
241 }
else if (
pattern ==
"v3b1a") {
242 }
else if (
pattern ==
"v3b1b") {
243 }
else if (
pattern ==
"v3b2a") {
244 }
else if (
pattern ==
"v3b2b") {
245 }
else if (
pattern ==
"v3b3") {
246 }
else if (
pattern.rfind(
"custom/") == 0) {
248 LOG(fatal) <<
"IOTOF layer pattern " <<
pattern <<
" not recognized, exiting";
253 for (
const std::string& itofSensor : ITOFLayer::mRegister) {
254 v = geoManager->GetVolume(itofSensor.c_str());
255 LOGP(info,
"Adding IOTOF Sensitive Volume {}",
v->GetName());
256 AddSensitiveVolume(
v);
260 for (
const std::string& otofSensor : OTOFLayer::mRegister) {
261 v = geoManager->GetVolume(otofSensor.c_str());
262 LOGP(info,
"Adding IOTOF Sensitive Volume {}",
v->GetName());
263 AddSensitiveVolume(
v);
268 LOGP(info,
"Adding IOTOF Sensitive Volume {}",
v->GetName());
269 AddSensitiveVolume(
v);
273 LOGP(info,
"Adding IOTOF Sensitive Volume {}",
v->GetName());
274 AddSensitiveVolume(
v);
286 if (FairRootManager::Instance()) {
287 FairRootManager::Instance()->RegisterAny(
addNameTo(
"Hit").
data(), mHits,
true);
301 if (!(fMC->TrackCharge())) {
305 int lay = vol->getVolumeId();
306 int volID = vol->getMCid();
310 if (fMC->IsTrackExiting() ) {
315 stack->addTrackReference(tr);
317 bool startHit =
false, stopHit =
false;
318 unsigned char status = 0;
319 if (fMC->IsTrackEntering()) {
322 if (fMC->IsTrackInside()) {
325 if (fMC->IsTrackExiting()) {
328 if (fMC->IsTrackOut()) {
331 if (fMC->IsTrackStop()) {
334 if (fMC->IsTrackAlive()) {
347 mTrackData.mEnergyLoss += fMC->Edep();
349 if (!(startHit | stopHit)) {
354 mTrackData.mEnergyLoss = 0.;
355 fMC->TrackMomentum(mTrackData.mMomentumStart);
356 fMC->TrackPosition(mTrackData.mPositionStart);
357 mTrackData.mTrkStatusStart = status;
358 mTrackData.mHitStarted =
true;
361 TLorentzVector positionStop;
362 fMC->TrackPosition(positionStop);
364 int stave(0), chipinmodule(0), module(0);
365 fMC->CurrentVolOffID(1, chipinmodule);
366 fMC->CurrentVolOffID(2, module);
367 fMC->CurrentVolOffID(3, stave);
378 if (iotofPars.segmentedInnerTOF && iotofPars.segmentedOuterTOF) {
382 sensorID += (mGeometryTGeo->
getSize() - 1);
387 mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(),
388 mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status);
392 stack->addHit(GetDetId());
399 const TVector3& startMom,
double startE,
double endTime,
double eLoss,
unsigned char startStatus,
400 unsigned char endStatus)
402 mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus);
403 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
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()
int getIOTOFChipIndex(int lay, int sta, int mod, int chip) const
static const char * getBTOFSensorPattern()
virtual void createLayer(TGeoVolume *motherVolume) override
static constexpr int kBarrelSegmented
static constexpr int kDisk
static constexpr int kBarrel
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