26#include "FairDetector.h"
27#include "FairRootManager.h"
28#include "FairRootManager.h"
30#include "FairRuntimeDb.h"
31#include "FairVolume.h"
33#include "TGeoManager.h"
36#include "TGeoVolume.h"
38#include "TVirtualMC.h"
39#include "TVirtualMCStack.h"
41#include <fairlogger/Logger.h>
46#define MAX_SENSORS 2000
71 LOG(info) <<
"Building FT3 Detector: Conical Telescope";
73 const int numberOfLayers =
param.nLayers;
74 const auto z_first =
param.z0;
75 const auto z_length =
param.zLength;
76 const auto etaIn =
param.etaIn;
77 const auto etaOut =
param.etaOut;
78 const auto Layerx2X0 =
param.Layerx2X0;
83 for (
int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
85 mLayerName[direction][layerNumber] = layerName;
88 const float layerZ = z_first + (layerNumber * z_length / numberOfLayers) * std::copysign(1, z_first);
89 const float rIn = std::abs(layerZ * std::tan(2.f * std::atan(std::exp(-etaIn))));
90 const float rOut = std::abs(layerZ * std::tan(2.f * std::atan(std::exp(-etaOut))));
91 const bool isMiddleLayer = layerNumber < 3;
92 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName, layerZ, rIn, rOut, Layerx2X0, isMiddleLayer);
103 LOG(info) <<
"Building FT3 Detector: V1";
105 const int numberOfLayers = 10;
106 const float sensorThickness = 30.e-4;
107 const float layersx2X0 = 1.e-2;
108 const std::vector<std::array<float, 4>> layersConfig{
109 {26., .5, 3., 0.1f * layersx2X0},
110 {30., .5, 3., 0.1f * layersx2X0},
111 {34., .5, 3., 0.1f * layersx2X0},
112 {77., 3.5, 35., layersx2X0},
113 {100., 3.5, 35., layersx2X0},
114 {122., 3.5, 35., layersx2X0},
115 {150., 3.5, 80.f, layersx2X0},
116 {180., 3.5, 80.f, layersx2X0},
117 {220., 3.5, 80.f, layersx2X0},
118 {279., 3.5, 80.f, layersx2X0}};
124 for (
int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
127 mLayerName[direction][layerNumber] = layerName;
128 auto&
z = layersConfig[layerNumber][0];
130 auto& rIn = layersConfig[layerNumber][1];
131 auto& rOut = layersConfig[layerNumber][2];
132 auto&
x0 = layersConfig[layerNumber][3];
134 LOG(info) <<
"Adding Layer " << layerName <<
" at z = " <<
z;
136 const bool isMiddleLayer = layerNumber < 3;
137 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName,
z, rIn, rOut,
x0, isMiddleLayer);
148 LOG(info) <<
"Building FT3 Detector: V3b";
150 const int numberOfLayers = 12;
151 float sensorThickness = 30.e-4;
152 float layersx2X0 = 1.e-2;
153 std::vector<std::array<float, 4>> layersConfig{
154 {26., .5, 3., 0.1f * layersx2X0},
155 {30., .5, 3., 0.1f * layersx2X0},
156 {34., .5, 3., 0.1f * layersx2X0},
157 {77., 5.0, 35., layersx2X0},
158 {100., 5.0, 35., layersx2X0},
159 {122., 5.0, 35., layersx2X0},
160 {150., 5.5, 80.f, layersx2X0},
161 {180., 6.6, 80.f, layersx2X0},
162 {220., 8.1, 80.f, layersx2X0},
163 {279., 10.2, 80.f, layersx2X0},
164 {340., 12.5, 80.f, layersx2X0},
165 {400., 14.7, 80.f, layersx2X0}};
171 for (
int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
174 mLayerName[direction][layerNumber] = layerName;
175 auto&
z = layersConfig[layerNumber][0];
177 auto& rIn = layersConfig[layerNumber][1];
178 auto& rOut = layersConfig[layerNumber][2];
179 auto&
x0 = layersConfig[layerNumber][3];
181 LOG(info) <<
"Adding Layer " << layerName <<
" at z = " <<
z;
183 const bool isMiddleLayer = layerNumber < 3;
184 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName,
z, rIn, rOut,
x0, isMiddleLayer);
198 LOG(info) <<
"Building FT3 Detector: After Upgrade Days March 2024 version";
200 const int numberOfLayers = 9;
201 const float sensorThickness = 30.e-4;
202 const float layersx2X0 = 1.e-2;
203 const std::vector<std::array<float, 4>> layersConfigCSide{
204 {77., 7.0, 35., layersx2X0},
205 {100., 7.0, 35., layersx2X0},
206 {122., 7.0, 35., layersx2X0},
207 {150., 7.0, 68.f, layersx2X0},
208 {180., 7.0, 68.f, layersx2X0},
209 {220., 7.0, 68.f, layersx2X0},
210 {260., 7.0, 68.f, layersx2X0},
211 {300., 7.0, 68.f, layersx2X0},
212 {350., 7.0, 68.f, layersx2X0}};
214 const std::vector<std::array<float, 4>> layersConfigASide{
215 {77., 5.0, 35., layersx2X0},
216 {100., 5.0, 35., layersx2X0},
217 {122., 5.0, 35., layersx2X0},
218 {150., 5.0, 68.f, layersx2X0},
219 {180., 5.0, 68.f, layersx2X0},
220 {220., 5.0, 68.f, layersx2X0},
221 {260., 5.0, 68.f, layersx2X0},
222 {300., 5.0, 68.f, layersx2X0},
223 {350., 5.0, 68.f, layersx2X0}};
229 for (
int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
232 mLayerName[direction][layerNumber] = layerName;
233 float z, rIn, rOut,
x0;
234 if (direction == 0) {
235 z = layersConfigCSide[layerNumber][0];
236 rIn = layersConfigCSide[layerNumber][1];
237 rOut = layersConfigCSide[layerNumber][2];
238 x0 = layersConfigCSide[layerNumber][3];
239 }
else if (direction == 1) {
240 z = layersConfigASide[layerNumber][0];
241 rIn = layersConfigASide[layerNumber][1];
242 rOut = layersConfigASide[layerNumber][2];
243 x0 = layersConfigASide[layerNumber][3];
246 LOG(info) <<
"Adding Layer " << layerName <<
" at z = " <<
z;
248 const bool isMiddleLayer = layerNumber < 3;
249 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName,
z, rIn, rOut,
x0, isMiddleLayer);
261 LOG(info) <<
"Building FT3 Detector: v3 scoping version";
263 const int numberOfLayers = 6;
264 const float sensorThickness = 30.e-4;
265 const float layersx2X0 = 1.e-2;
266 using LayerConfig = std::array<float, 4>;
267 const std::array<LayerConfig, numberOfLayers> layersConfigCSide{LayerConfig{77., 10.0, 35., layersx2X0},
268 LayerConfig{100., 10.0, 35., layersx2X0},
269 LayerConfig{122., 10.0, 35., layersx2X0},
270 LayerConfig{150., 20.0, 68.f, layersx2X0},
271 LayerConfig{180., 20.0, 68.f, layersx2X0},
272 LayerConfig{220., 20.0, 68.f, layersx2X0}};
274 const std::array<LayerConfig, numberOfLayers> layersConfigASide{LayerConfig{77., 10.0, 35., layersx2X0},
275 LayerConfig{100., 10.0, 35., layersx2X0},
276 LayerConfig{122., 10.0, 35., layersx2X0},
277 LayerConfig{150., 20.0, 68.f, layersx2X0},
278 LayerConfig{180., 20.0, 68.f, layersx2X0},
279 LayerConfig{220., 20.0, 68.f, layersx2X0}};
280 const std::array<bool, numberOfLayers>
enabled{
true,
true,
true,
true,
true,
true};
284 const std::array<LayerConfig, numberOfLayers>& layerConfig = (direction ==
IdxBackwardDisks) ? layersConfigCSide : layersConfigASide;
285 for (
int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
291 mLayerName[direction].push_back(layerName.c_str());
292 const float z = layerConfig[layerNumber][0];
293 const float rIn = layerConfig[layerNumber][1];
294 const float rOut = layerConfig[layerNumber][2];
295 const float x0 = layerConfig[layerNumber][3];
296 LOG(info) <<
"buildFT3ScopingV3 -> Adding Layer " << layerNumber <<
"/" << numberOfLayers <<
" " << layerName <<
" at z = " <<
z;
298 const bool isMiddleLayer = layerNumber < 3;
299 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName,
z, rIn, rOut,
x0, isMiddleLayer);
309 LOG(info) <<
"Building FT3 Detector: Scoping document version";
311 const int numberOfLayers = 12;
312 const float sensorThickness = 30.e-4;
313 const float layersx2X0 = 1.e-2;
314 const std::vector<std::array<float, 4>> layersConfig{
315 {26., .5, 2.5, 0.1f * layersx2X0},
316 {30., .5, 2.5, 0.1f * layersx2X0},
317 {34., .5, 2.5, 0.1f * layersx2X0},
318 {77., 5.0, 35., layersx2X0},
319 {100., 5.0, 35., layersx2X0},
320 {122., 5.0, 35., layersx2X0},
321 {150., 5.0, 68.f, layersx2X0},
322 {180., 5.0, 68.f, layersx2X0},
323 {220., 5.0, 68.f, layersx2X0},
324 {260., 5.0, 68.f, layersx2X0},
325 {300., 5.0, 68.f, layersx2X0},
326 {350., 5.0, 68.f, layersx2X0}};
332 for (
int layerNumber = 0; layerNumber < numberOfLayers; layerNumber++) {
335 mLayerName[direction][layerNumber] = layerName;
336 auto&
z = layersConfig[layerNumber][0];
337 auto& rIn = layersConfig[layerNumber][1];
338 auto& rOut = layersConfig[layerNumber][2];
339 auto&
x0 = layersConfig[layerNumber][3];
341 LOG(info) <<
"Adding Layer " << layerName <<
" at z = " <<
z;
343 const bool isMiddleLayer = layerNumber < 3;
344 auto& thisLayer = mLayers[direction].emplace_back(direction, layerNumber, layerName,
z, rIn, rOut,
x0, isMiddleLayer);
365 mLayerName = rhs.mLayerName;
396 mLayerName = rhs.mLayerName;
397 mLayers = rhs.mLayers;
398 mTrackData = rhs.mTrackData;
410 LOG(info) <<
"Initialize FT3 O2Detector";
412 defineSensitiveVolumes();
419 if (!(fMC->TrackCharge())) {
423 int volID = vol->getMCid();
427 bool startHit =
false, stopHit =
false;
428 unsigned char status = 0;
429 if (fMC->IsTrackEntering()) {
430 status |= Hit::kTrackEntering;
432 if (fMC->IsTrackInside()) {
433 status |= Hit::kTrackInside;
435 if (fMC->IsTrackExiting()) {
436 status |= Hit::kTrackExiting;
438 if (fMC->IsTrackOut()) {
439 status |= Hit::kTrackOut;
441 if (fMC->IsTrackStop()) {
442 status |= Hit::kTrackStopped;
444 if (fMC->IsTrackAlive()) {
445 status |= Hit::kTrackAlive;
449 if ((status & Hit::kTrackEntering) || (status & Hit::kTrackInside && !mTrackData.mHitStarted)) {
451 }
else if ((status & (Hit::kTrackExiting | Hit::kTrackOut | Hit::kTrackStopped))) {
457 mTrackData.mEnergyLoss += fMC->Edep();
459 if (!(startHit | stopHit)) {
463 mTrackData.mEnergyLoss = 0.;
464 fMC->TrackMomentum(mTrackData.mMomentumStart);
465 fMC->TrackPosition(mTrackData.mPositionStart);
466 mTrackData.mTrkStatusStart = status;
467 mTrackData.mHitStarted =
true;
471 TLorentzVector positionStop;
472 fMC->TrackPosition(positionStop);
475 std::string volName = fMC->CurrentVolName();
476 int direction = -1,
layer = -1, stave = -1, chip = -1;
477 geom->extractChipIds(volName, direction,
layer, stave, chip);
478 chipindex = geom->getChipIndex(direction,
layer, stave, chip);
480 Hit* p =
addHit(
stack->GetCurrentTrackNumber(), chipindex, mTrackData.mPositionStart.Vect(), positionStop.Vect(),
481 mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(),
482 mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status);
487 stack->addHit(GetDetId());
504 for (
const auto& [materialID, material] :
Materials::materials) {
505 const int id =
static_cast<int>(materialID);
506 if (material.nComponents == 0) {
508 material.radl, material.absl);
516 const auto& tracking = material.tracking;
518 tracking.deemax, tracking.epsil, tracking.stmin);
532 if (FairRootManager::Instance()) {
533 FairRootManager::Instance()->RegisterAny(
addNameTo(
"Hit").
data(), mHits, kTRUE);
564 TGeoVolume* vALIC = gGeoManager->GetVolume(
"barrel");
566 LOG(fatal) <<
"Could not find the top volume";
569 TGeoVolume* A3IPvac = gGeoManager->GetVolume(
"OUT_PIPEVACUUM");
571 LOG(info) <<
"Running simulation with no beam pipe.";
576 for (
int direction : {IdxBackwardDisks, IdxForwardDisks}) {
577 const std::string directionString = direction ?
"Forward" :
"Backward";
578 LOG(info) <<
" Creating FT3 without beampipe " << directionString <<
" layers:";
579 for (
int iLayer = 0; iLayer < mLayers[direction].size(); iLayer++) {
580 mLayers[direction][iLayer].createLayer(volFT3);
583 vALIC->AddNode(volFT3, 2,
new TGeoTranslation(0., 30., 0.));
585 for (
int direction : {IdxBackwardDisks, IdxForwardDisks}) {
586 const std::string directionString = direction ?
"Forward" :
"Backward";
587 LOG(info) <<
" Creating FT3 " << directionString <<
" layers:";
588 for (
int iLayer = 0; iLayer < mLayers[direction].size(); iLayer++) {
589 LOG(info) <<
" Creating " << directionString <<
" layer " << iLayer;
590 if (mLayers[direction][iLayer].getIsInMiddleLayer()) {
591 mLayers[direction][iLayer].createLayer(volIFT3);
593 mLayers[direction][iLayer].createLayer(volFT3);
597 A3IPvac->AddNode(volIFT3, 2,
new TGeoTranslation(0., 0., 0.));
598 vALIC->AddNode(volFT3, 2,
new TGeoTranslation(0., 30., 0.));
603void Detector::defineSensitiveVolumes()
605 TGeoManager* geoManager = gGeoManager;
608 TObjArray* allVolumes = geoManager->GetListOfVolumes();
609 int nVolumes = allVolumes->GetEntriesFast();
611 LOG(info) <<
"Adding FT3 Sensitive Volumes by iterating over all geometry volumes...";
614 for (
int direction : {IdxBackwardDisks, IdxForwardDisks}) {
632 for (
int i = 0;
i < nVolumes; ++
i) {
633 TGeoVolume*
v = (TGeoVolume*)allVolumes->At(
i);
634 std::string vName =
v->GetName();
637 if (vName.find(
"Inactive") != std::string::npos || vName.find(
"inactive") != std::string::npos) {
642 bool isMatch =
false;
645 }
else if (vName.find(sig2) == 0 || vName.find(sig3) == 0 || vName.find(sig4) == 0) {
650 AddSensitiveVolume(
v);
656 LOG(error) <<
"NO sensitive volume found for direction " << direction <<
", layer " << iLayer;
658 LOG(info) << iSens <<
" sensitive volume(s) added for direction " << direction <<
" layer " << iLayer;
666 const TVector3& startMom,
double startE,
double endTime,
double eLoss,
unsigned char startStatus,
667 unsigned char endStatus)
669 mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus);
670 return &(mHits->back());
Definition of the Stack class.
Definition of the FT3Layer class.
Materials of the FT3 detector, and access to the media made from them.
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
GLboolean GLboolean GLboolean GLboolean a
GLubyte GLubyte GLubyte GLubyte w
GLdouble GLdouble GLdouble z
std::array< float, maxMaterialComponents > ComponentArray
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"