25#include "FairDetector.h"
26#include "FairRootManager.h"
27#include "FairRootManager.h"
29#include "FairRuntimeDb.h"
30#include "FairVolume.h"
32#include "TGeoManager.h"
35#include "TGeoVolume.h"
37#include "TVirtualMC.h"
38#include "TVirtualMCStack.h"
40#include <fairlogger/Logger.h>
44#define MAX_SENSORS 2000
69 LOG(info) <<
"Building FT3 Detector: Conical Telescope";
71 const int numberOfLayers =
param.nLayers;
72 const auto z_first =
param.z0;
73 const auto z_length =
param.zLength;
74 const auto etaIn =
param.etaIn;
75 const auto etaOut =
param.etaOut;
76 const auto Layerx2X0 =
param.Layerx2X0;
81 for (
int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
83 mLayerName[direction][layerNumber] = layerName;
86 const float layerZ = z_first + (layerNumber * z_length / numberOfLayers) * std::copysign(1, z_first);
87 const float rIn = std::abs(layerZ * std::tan(2.f * std::atan(std::exp(-etaIn))));
88 const float rOut = std::abs(layerZ * std::tan(2.f * std::atan(std::exp(-etaOut))));
89 const bool isMiddleLayer = layerNumber < 3;
90 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, layerZ, rIn, rOut, Layerx2X0, isMiddleLayer);
101 LOG(info) <<
"Building FT3 Detector: V1";
103 const int numberOfLayers = 10;
104 const float sensorThickness = 30.e-4;
105 const float layersx2X0 = 1.e-2;
106 const std::vector<std::array<float, 4>> layersConfig{
107 {26., .5, 3., 0.1f * layersx2X0},
108 {30., .5, 3., 0.1f * layersx2X0},
109 {34., .5, 3., 0.1f * layersx2X0},
110 {77., 3.5, 35., layersx2X0},
111 {100., 3.5, 35., layersx2X0},
112 {122., 3.5, 35., layersx2X0},
113 {150., 3.5, 80.f, layersx2X0},
114 {180., 3.5, 80.f, layersx2X0},
115 {220., 3.5, 80.f, layersx2X0},
116 {279., 3.5, 80.f, layersx2X0}};
122 for (
int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
125 mLayerName[direction][layerNumber] = layerName;
126 auto&
z = layersConfig[layerNumber][0];
128 auto& rIn = layersConfig[layerNumber][1];
129 auto& rOut = layersConfig[layerNumber][2];
130 auto&
x0 = layersConfig[layerNumber][3];
132 LOG(info) <<
"Adding Layer " << layerName <<
" at z = " <<
z;
134 const bool isMiddleLayer = layerNumber < 3;
135 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName,
z, rIn, rOut,
x0, isMiddleLayer);
146 LOG(info) <<
"Building FT3 Detector: V3b";
148 const int numberOfLayers = 12;
149 float sensorThickness = 30.e-4;
150 float layersx2X0 = 1.e-2;
151 std::vector<std::array<float, 4>> layersConfig{
152 {26., .5, 3., 0.1f * layersx2X0},
153 {30., .5, 3., 0.1f * layersx2X0},
154 {34., .5, 3., 0.1f * layersx2X0},
155 {77., 5.0, 35., layersx2X0},
156 {100., 5.0, 35., layersx2X0},
157 {122., 5.0, 35., layersx2X0},
158 {150., 5.5, 80.f, layersx2X0},
159 {180., 6.6, 80.f, layersx2X0},
160 {220., 8.1, 80.f, layersx2X0},
161 {279., 10.2, 80.f, layersx2X0},
162 {340., 12.5, 80.f, layersx2X0},
163 {400., 14.7, 80.f, layersx2X0}};
169 for (
int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
172 mLayerName[direction][layerNumber] = layerName;
173 auto&
z = layersConfig[layerNumber][0];
175 auto& rIn = layersConfig[layerNumber][1];
176 auto& rOut = layersConfig[layerNumber][2];
177 auto&
x0 = layersConfig[layerNumber][3];
179 LOG(info) <<
"Adding Layer " << layerName <<
" at z = " <<
z;
181 const bool isMiddleLayer = layerNumber < 3;
182 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName,
z, rIn, rOut,
x0, isMiddleLayer);
196 LOG(info) <<
"Building FT3 Detector: After Upgrade Days March 2024 version";
198 const int numberOfLayers = 9;
199 const float sensorThickness = 30.e-4;
200 const float layersx2X0 = 1.e-2;
201 const std::vector<std::array<float, 4>> layersConfigCSide{
202 {77., 7.0, 35., layersx2X0},
203 {100., 7.0, 35., layersx2X0},
204 {122., 7.0, 35., layersx2X0},
205 {150., 7.0, 68.f, layersx2X0},
206 {180., 7.0, 68.f, layersx2X0},
207 {220., 7.0, 68.f, layersx2X0},
208 {260., 7.0, 68.f, layersx2X0},
209 {300., 7.0, 68.f, layersx2X0},
210 {350., 7.0, 68.f, layersx2X0}};
212 const std::vector<std::array<float, 4>> layersConfigASide{
213 {77., 5.0, 35., layersx2X0},
214 {100., 5.0, 35., layersx2X0},
215 {122., 5.0, 35., layersx2X0},
216 {150., 5.0, 68.f, layersx2X0},
217 {180., 5.0, 68.f, layersx2X0},
218 {220., 5.0, 68.f, layersx2X0},
219 {260., 5.0, 68.f, layersx2X0},
220 {300., 5.0, 68.f, layersx2X0},
221 {350., 5.0, 68.f, layersx2X0}};
227 for (
int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
230 mLayerName[direction][layerNumber] = layerName;
231 float z, rIn, rOut,
x0;
232 if (direction == 0) {
233 z = layersConfigCSide[layerNumber][0];
234 rIn = layersConfigCSide[layerNumber][1];
235 rOut = layersConfigCSide[layerNumber][2];
236 x0 = layersConfigCSide[layerNumber][3];
237 }
else if (direction == 1) {
238 z = layersConfigASide[layerNumber][0];
239 rIn = layersConfigASide[layerNumber][1];
240 rOut = layersConfigASide[layerNumber][2];
241 x0 = layersConfigASide[layerNumber][3];
244 LOG(info) <<
"Adding Layer " << layerName <<
" at z = " <<
z;
246 const bool isMiddleLayer = layerNumber < 3;
247 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName,
z, rIn, rOut,
x0, isMiddleLayer);
259 LOG(info) <<
"Building FT3 Detector: v3 scoping version";
261 const int numberOfLayers = 6;
262 const float sensorThickness = 30.e-4;
263 const float layersx2X0 = 1.e-2;
264 using LayerConfig = std::array<float, 4>;
265 const std::array<LayerConfig, numberOfLayers> layersConfigCSide{LayerConfig{77., 10.0, 35., layersx2X0},
266 LayerConfig{100., 10.0, 35., layersx2X0},
267 LayerConfig{122., 10.0, 35., layersx2X0},
268 LayerConfig{150., 20.0, 68.f, layersx2X0},
269 LayerConfig{180., 20.0, 68.f, layersx2X0},
270 LayerConfig{220., 20.0, 68.f, layersx2X0}};
272 const std::array<LayerConfig, numberOfLayers> layersConfigASide{LayerConfig{77., 10.0, 35., layersx2X0},
273 LayerConfig{100., 10.0, 35., layersx2X0},
274 LayerConfig{122., 10.0, 35., layersx2X0},
275 LayerConfig{150., 20.0, 68.f, layersx2X0},
276 LayerConfig{180., 20.0, 68.f, layersx2X0},
277 LayerConfig{220., 20.0, 68.f, layersx2X0}};
278 const std::array<bool, numberOfLayers>
enabled{
true,
true,
true,
true,
true,
true};
282 const std::array<LayerConfig, numberOfLayers>& layerConfig = (direction ==
IdxBackwardDisks) ? layersConfigCSide : layersConfigASide;
283 for (
int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
289 mLayerName[direction].push_back(layerName.c_str());
290 const float z = layerConfig[layerNumber][0];
291 const float rIn = layerConfig[layerNumber][1];
292 const float rOut = layerConfig[layerNumber][2];
293 const float x0 = layerConfig[layerNumber][3];
294 LOG(info) <<
"buildFT3ScopingV3 -> Adding Layer " << layerNumber <<
"/" << numberOfLayers <<
" " << layerName <<
" at z = " <<
z;
296 const bool isMiddleLayer = layerNumber < 3;
297 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName,
z, rIn, rOut,
x0, isMiddleLayer);
307 LOG(info) <<
"Building FT3 Detector: Scoping document version";
309 const int numberOfLayers = 12;
310 const float sensorThickness = 30.e-4;
311 const float layersx2X0 = 1.e-2;
312 const std::vector<std::array<float, 4>> layersConfig{
313 {26., .5, 2.5, 0.1f * layersx2X0},
314 {30., .5, 2.5, 0.1f * layersx2X0},
315 {34., .5, 2.5, 0.1f * layersx2X0},
316 {77., 5.0, 35., layersx2X0},
317 {100., 5.0, 35., layersx2X0},
318 {122., 5.0, 35., layersx2X0},
319 {150., 5.0, 68.f, layersx2X0},
320 {180., 5.0, 68.f, layersx2X0},
321 {220., 5.0, 68.f, layersx2X0},
322 {260., 5.0, 68.f, layersx2X0},
323 {300., 5.0, 68.f, layersx2X0},
324 {350., 5.0, 68.f, layersx2X0}};
330 for (
int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
333 mLayerName[direction][layerNumber] = layerName;
334 auto&
z = layersConfig[layerNumber][0];
335 auto& rIn = layersConfig[layerNumber][1];
336 auto& rOut = layersConfig[layerNumber][2];
337 auto&
x0 = layersConfig[layerNumber][3];
339 LOG(info) <<
"Adding Layer " << layerName <<
" at z = " <<
z;
341 const bool isMiddleLayer = layerNumber < 3;
342 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName,
z, rIn, rOut,
x0, isMiddleLayer);
363 mLayerName = rhs.mLayerName;
394 mLayerName = rhs.mLayerName;
395 mLayers = rhs.mLayers;
396 mTrackData = rhs.mTrackData;
408 LOG(info) <<
"Initialize FT3 O2Detector";
410 defineSensitiveVolumes();
417 if (!(fMC->TrackCharge())) {
421 int volID = vol->getMCid();
425 bool startHit =
false, stopHit =
false;
426 unsigned char status = 0;
427 if (fMC->IsTrackEntering()) {
428 status |= Hit::kTrackEntering;
430 if (fMC->IsTrackInside()) {
431 status |= Hit::kTrackInside;
433 if (fMC->IsTrackExiting()) {
434 status |= Hit::kTrackExiting;
436 if (fMC->IsTrackOut()) {
437 status |= Hit::kTrackOut;
439 if (fMC->IsTrackStop()) {
440 status |= Hit::kTrackStopped;
442 if (fMC->IsTrackAlive()) {
443 status |= Hit::kTrackAlive;
447 if ((status & Hit::kTrackEntering) || (status & Hit::kTrackInside && !mTrackData.mHitStarted)) {
449 }
else if ((status & (Hit::kTrackExiting | Hit::kTrackOut | Hit::kTrackStopped))) {
455 mTrackData.mEnergyLoss += fMC->Edep();
457 if (!(startHit | stopHit)) {
461 mTrackData.mEnergyLoss = 0.;
462 fMC->TrackMomentum(mTrackData.mMomentumStart);
463 fMC->TrackPosition(mTrackData.mPositionStart);
464 mTrackData.mTrkStatusStart = status;
465 mTrackData.mHitStarted =
true;
469 TLorentzVector positionStop;
470 fMC->TrackPosition(positionStop);
473 std::string volName = fMC->CurrentVolName();
474 int direction = -1,
layer = -1, stave = -1, chip = -1;
475 geom->extractChipIds(volName, direction,
layer, stave, chip);
476 chipindex = geom->getChipIndex(direction,
layer, stave, chip);
478 Hit* p =
addHit(
stack->GetCurrentTrackNumber(), chipindex, mTrackData.mPositionStart.Vect(), positionStop.Vect(),
479 mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(),
480 mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status);
485 stack->addHit(GetDetId());
498 float tmaxfdSi = 0.1;
499 float stemaxSi = 0.0075;
500 float deemaxSi = 0.1;
501 float epsilSi = 1.0E-4;
504 float tmaxfdAir = 0.1;
505 float stemaxAir = .10000E+01;
506 float deemaxAir = 0.1;
507 float epsilAir = 1.0E-4;
508 float stminAir = 0.0;
511 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
512 float zAir[4] = {6., 7., 8., 18.};
513 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
514 float dAir = 1.20479E-3;
517 o2::base::Detector::Medium(1,
"AIR$", 1, 0, ifield, fieldm, tmaxfdAir, stemaxAir, deemaxAir, epsilAir, stminAir);
520 o2::base::Detector::Medium(3,
"SILICON$", 3, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
533 if (FairRootManager::Instance()) {
534 FairRootManager::Instance()->RegisterAny(
addNameTo(
"Hit").
data(), mHits, kTRUE);
565 TGeoVolume* vALIC = gGeoManager->GetVolume(
"barrel");
567 LOG(fatal) <<
"Could not find the top volume";
570 TGeoVolume* A3IPvac = gGeoManager->GetVolume(
"OUT_PIPEVACUUM");
572 LOG(info) <<
"Running simulation with no beam pipe.";
577 for (
int direction : {IdxBackwardDisks, IdxForwardDisks}) {
578 const std::string directionString = direction ?
"Forward" :
"Backward";
579 LOG(info) <<
" Creating FT3 without beampipe " << directionString <<
" layers:";
580 for (
int iLayer = 0; iLayer < mLayers[direction].size(); iLayer++) {
581 mLayers[direction][iLayer].createLayer(volFT3);
584 vALIC->AddNode(volFT3, 2,
new TGeoTranslation(0., 30., 0.));
586 for (
int direction : {IdxBackwardDisks, IdxForwardDisks}) {
587 const std::string directionString = direction ?
"Forward" :
"Backward";
588 LOG(info) <<
" Creating FT3 " << directionString <<
" layers:";
589 for (
int iLayer = 0; iLayer < mLayers[direction].size(); iLayer++) {
590 LOG(info) <<
" Creating " << directionString <<
" layer " << iLayer;
591 if (mLayers[direction][iLayer].getIsInMiddleLayer()) {
592 mLayers[direction][iLayer].createLayer(volIFT3);
594 mLayers[direction][iLayer].createLayer(volFT3);
598 A3IPvac->AddNode(volIFT3, 2,
new TGeoTranslation(0., 0., 0.));
599 vALIC->AddNode(volFT3, 2,
new TGeoTranslation(0., 30., 0.));
604void Detector::defineSensitiveVolumes()
606 TGeoManager* geoManager = gGeoManager;
609 TObjArray* allVolumes = geoManager->GetListOfVolumes();
610 int nVolumes = allVolumes->GetEntriesFast();
612 LOG(info) <<
"Adding FT3 Sensitive Volumes by iterating over all geometry volumes...";
615 for (
int direction : {IdxBackwardDisks, IdxForwardDisks}) {
633 for (
int i = 0;
i < nVolumes; ++
i) {
634 TGeoVolume*
v = (TGeoVolume*)allVolumes->At(
i);
635 std::string vName =
v->GetName();
638 if (vName.find(
"Inactive") != std::string::npos || vName.find(
"inactive") != std::string::npos) {
643 bool isMatch =
false;
646 }
else if (vName.find(sig2) == 0 || vName.find(sig3) == 0 || vName.find(sig4) == 0) {
651 AddSensitiveVolume(
v);
657 LOG(error) <<
"NO sensitive volume found for direction " << direction <<
", layer " << iLayer;
659 LOG(info) << iSens <<
" sensitive volume(s) added for direction " << direction <<
" layer " << iLayer;
667 const TVector3& startMom,
double startE,
double endTime,
double eLoss,
unsigned char startStatus,
668 unsigned char endStatus)
670 mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus);
671 return &(mHits->back());
Definition of the Stack class.
Definition of the FT3Layer class.
Definition of the GeometryTGeo class.
Definition of the Detector class.
Detector & operator=(const Detector &)
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
std::array< std::vector< TString >, 2 > mLayerName
static constexpr int IdxBackwardDisks
static constexpr int IdxForwardDisks
Detector()
Default constructor.
void buildBasicFT3(const FT3BaseParam ¶m)
void buildFT3NewVacuumVessel()
static const char * getFT3SensorPattern()
static const char * getFT3LayerPattern()
static const char * getFT3VolPattern()
static const char * getFT3InnerVolPattern()
void ConstructGeometry() override
void InitializeO2Detector() override
o2::trkft3::Hit * addHit(int trackID, unsigned short detID, const TVector3 &startPos, const TVector3 &endPos, const TVector3 &startMom, double startE, double endTime, double eLoss, unsigned char startStatus, unsigned char endStatus)
void EndOfEvent() override
int getNumberOfLayers() const
Number of VD petals.
bool ProcessHits(FairVolume *v=nullptr) override
static GeometryTGeo * Instance()
static ShmManager & Instance()
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLenum GLuint GLint GLint layer
GLdouble GLdouble GLdouble z
void freeSimVector(std::vector< T > *ptr)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
Common utility functions.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"