12#include <FairVolume.h>
14#include <TVirtualMC.h>
15#include <TVirtualMCStack.h>
16#include <TGeoVolume.h>
31 return 2. * (10. + radius * std::cos(2 * std::atan(std::exp(-eta))));
35 :
o2::base::DetImpl<Detector>(
"TRK", true),
41Detector::Detector(
bool active)
42 :
o2::base::DetImpl<Detector>(
"TRK", true),
48 if (trkPars.configFile !=
"") {
49 configFromFile(trkPars.configFile);
51 buildTRKNewVacuumVessel();
56 LOGP(info,
"Summary of TRK configuration:");
57 for (
auto&
layer : mLayers) {
58 LOGP(info,
"Layer: {} name: {} r: {} cm | z: {} cm | thickness: {} cm",
layer.getNumber(),
layer.getName(),
layer.getInnerRadius(),
layer.getZ(),
layer.getChipThickness());
69void Detector::ConstructGeometry()
75void Detector::configDefault()
82 LOGP(warning,
"Loading Scoping Document configuration for ALICE3 TRK");
86 mLayers.emplace_back(0, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(0)}, 3.78f, 124.f, 100.e-3);
87 mLayers.emplace_back(1, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(1)}, 7.f, 124.f, 100.e-3);
88 mLayers.emplace_back(2, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(2)}, 12.f, 124.f, 100.e-3);
89 mLayers.emplace_back(3, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(3)}, 20.f, 124.f, 100.e-3);
90 mLayers.emplace_back(4, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(4)}, 30.f, 124.f, 100.e-3);
91 mLayers.emplace_back(5, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(5)}, 45.f, 258.f, 100.e-3);
92 mLayers.emplace_back(6, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(6)}, 60.f, 258.f, 100.e-3);
93 mLayers.emplace_back(7, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(7)}, 80.f, 258.f, 100.e-3);
96void Detector::buildTRKNewVacuumVessel()
105 LOGP(warning,
"Loading \"After Upgrade Days March 2024\" configuration for ALICE3 TRK");
109 mLayers.emplace_back(0, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(0)}, 7.f, 124.f, 100.e-3);
110 LOGP(info,
"TRKLayer created. Name: {}", std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(0)});
111 mLayers.emplace_back(1, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(1)}, 9.f, 124.f, 100.e-3);
112 mLayers.emplace_back(2, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(2)}, 12.f, 124.f, 100.e-3);
113 mLayers.emplace_back(3, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(3)}, 20.f, 124.f, 100.e-3);
114 mLayers.emplace_back(4, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(4)}, 30.f, 124.f, 100.e-3);
115 mLayers.emplace_back(5, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(5)}, 45.f, 258.f, 100.e-3);
116 mLayers.emplace_back(6, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(6)}, 60.f, 258.f, 100.e-3);
117 mLayers.emplace_back(7, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(7)}, 80.f, 258.f, 100.e-3);
119 auto& trkPars = TRKBaseParam::Instance();
122 mLayers[0].setLayout(trkPars.layoutML);
123 mLayers[1].setLayout(trkPars.layoutML);
124 mLayers[2].setLayout(trkPars.layoutML);
125 mLayers[3].setLayout(trkPars.layoutML);
128 mLayers[4].setLayout(trkPars.layoutOL);
129 mLayers[5].setLayout(trkPars.layoutOL);
130 mLayers[6].setLayout(trkPars.layoutOL);
131 mLayers[7].setLayout(trkPars.layoutOL);
134void Detector::configFromFile(std::string fileName)
137 std::ifstream confFile(fileName);
138 if (!confFile.good()) {
139 LOGP(fatal,
"File {} not found, aborting.", fileName);
144 LOGP(info,
"Overriding geometry of ALICE3 TRK using {} file.", fileName);
147 std::vector<float> tmpBuff;
149 while (std::getline(confFile, line)) {
150 if (line[0] ==
'/') {
154 std::stringstream ss(line);
157 while (getline(ss, substr,
'\t')) {
158 tmpBuff.push_back(std::stof(substr));
160 mLayers.emplace_back(layerCount, std::string{GeometryTGeo::getTRKLayerPattern() +
std::to_string(layerCount)}, tmpBuff[0], tmpBuff[1], tmpBuff[2]);
165void Detector::configToFile(std::string fileName)
167 LOGP(info,
"Exporting TRK Detector layout to {}", fileName);
168 std::ofstream conFile(fileName.c_str(), std::ios::out);
169 conFile <<
"/// TRK configuration file: inn_radius z_length lay_thickness" << std::endl;
170 for (
auto layer : mLayers) {
171 conFile <<
layer.getInnerRadius() <<
"\t" <<
layer.getZ() <<
"\t" <<
layer.getChipThickness() << std::endl;
175void Detector::configServices()
180void Detector::createMaterials()
186 float tmaxfdSi = 0.1;
187 float stemaxSi = 0.0075;
188 float deemaxSi = 0.1;
189 float epsilSi = 1.0E-4;
192 float tmaxfdAir = 0.1;
193 float stemaxAir = .10000E+01;
194 float deemaxAir = 0.1;
195 float epsilAir = 1.0E-4;
196 float stminAir = 0.0;
198 float tmaxfdCer = 0.1;
199 float stemaxCer = .10000E+01;
200 float deemaxCer = 0.1;
201 float epsilCer = 1.0E-4;
202 float stminCer = 0.0;
205 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
206 float zAir[4] = {6., 7., 8., 18.};
207 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
208 float dAir = 1.20479E-3;
211 float aCf[2] = {12.0107, 1.00794};
212 float zCf[2] = {6., 1.};
215 o2::base::Detector::Medium(1,
"AIR$", 1, 0, ifield, fieldm, tmaxfdAir, stemaxAir, deemaxAir, epsilAir, stminAir);
218 o2::base::Detector::Medium(3,
"SILICON$", 3, 0, ifield, fieldm, tmaxfdSi, stemaxSi, deemaxSi, epsilSi, stminSi);
221void Detector::createGeometry()
223 TGeoManager* geoManager = gGeoManager;
224 TGeoVolume* vALIC = geoManager->GetVolume(
"barrel");
226 LOGP(fatal,
"Could not find barrel volume while constructing TRK geometry");
228 new TGeoVolumeAssembly(GeometryTGeo::getTRKVolPattern());
229 TGeoVolume* vTRK = geoManager->GetVolume(GeometryTGeo::getTRKVolPattern());
230 vALIC->AddNode(vTRK, 2,
new TGeoTranslation(0, 30., 0));
232 char vstrng[100] =
"TRKVol";
233 vTRK->SetTitle(vstrng);
235 for (
auto&
layer : mLayers) {
236 layer.createLayer(vTRK);
240 mServices.createServices(vTRK);
243 auto& trkPars = TRKBaseParam::Instance();
244 for (Int_t petalCaseNumber = 0; petalCaseNumber < 4; ++petalCaseNumber) {
245 mPetalCases.emplace_back(petalCaseNumber, vTRK, trkPars.irisOpen);
246 mServices.excavateFromVacuum(mPetalCases[petalCaseNumber].getFullName());
248 mServices.registerVacuum(vTRK);
251void Detector::InitializeO2Detector()
253 LOG(info) <<
"Initialize TRK O2Detector";
254 mGeometryTGeo = GeometryTGeo::Instance();
255 defineSensitiveVolumes();
258void Detector::defineSensitiveVolumes()
260 TGeoManager* geoManager = gGeoManager;
264 LOGP(info,
"Adding TRK Sensitive Volumes");
267 for (
int petalCase = 0; petalCase < 4; ++petalCase) {
269 for (
int petalLayer = 0; petalLayer < mPetalCases[petalCase].mPetalLayers.size(); ++petalLayer) {
270 volumeName = mPetalCases[petalCase].mPetalLayers[petalLayer].getSensorName();
271 if (petalLayer == 0) {
272 mFirstOrLastLayers.push_back(volumeName.Data());
274 LOGP(info,
"Trying {}", volumeName.Data());
275 v = geoManager->GetVolume(volumeName.Data());
276 LOGP(info,
"Adding TRK Sensitive Volume {}",
v->GetName());
277 AddSensitiveVolume(
v);
280 for (
int petalDisk = 0; petalDisk < mPetalCases[petalCase].mPetalDisks.size(); ++petalDisk) {
281 volumeName = mPetalCases[petalCase].mPetalDisks[petalDisk].getSensorName();
282 LOGP(info,
"Trying {}", volumeName.Data());
283 v = geoManager->GetVolume(volumeName.Data());
284 LOGP(info,
"Adding TRK Sensitive Volume {}",
v->GetName());
285 AddSensitiveVolume(
v);
290 for (
int j{0};
j < mLayers.size();
j++) {
291 volumeName = GeometryTGeo::getTRKSensorPattern() + TString::Itoa(
j, 10);
292 if (
j == mLayers.size() - 1) {
293 mFirstOrLastLayers.push_back(volumeName.Data());
295 LOGP(info,
"Trying {}", volumeName.Data());
296 v = geoManager->GetVolume(volumeName.Data());
297 LOGP(info,
"Adding TRK Sensitive Volume {}",
v->GetName());
298 AddSensitiveVolume(
v);
302void Detector::EndOfEvent() { Reset(); }
304void Detector::Register()
310 if (FairRootManager::Instance()) {
311 FairRootManager::Instance()->RegisterAny(addNameTo(
"Hit").
data(), mHits,
true);
315void Detector::Reset()
322bool Detector::InsideFirstOrLastLayer(std::string layerName)
325 for (
auto& firstOrLastLayer : mFirstOrLastLayers) {
326 if (firstOrLastLayer == layerName) {
334bool Detector::ProcessHits(FairVolume* vol)
337 if (!(fMC->TrackCharge())) {
341 int lay = vol->getVolumeId();
342 int volID = vol->getMCid();
347 if (fMC->IsTrackExiting() && InsideFirstOrLastLayer(vol->GetName())) {
350 tr.setTrackID(
stack->GetCurrentTrackNumber());
352 stack->addTrackReference(tr);
354 bool startHit =
false, stopHit =
false;
355 unsigned char status = 0;
356 if (fMC->IsTrackEntering()) {
357 status |= Hit::kTrackEntering;
359 if (fMC->IsTrackInside()) {
360 status |= Hit::kTrackInside;
362 if (fMC->IsTrackExiting()) {
363 status |= Hit::kTrackExiting;
365 if (fMC->IsTrackOut()) {
366 status |= Hit::kTrackOut;
368 if (fMC->IsTrackStop()) {
369 status |= Hit::kTrackStopped;
371 if (fMC->IsTrackAlive()) {
372 status |= Hit::kTrackAlive;
376 if ((status & Hit::kTrackEntering) || (status & Hit::kTrackInside && !mTrackData.mHitStarted)) {
378 }
else if ((status & (Hit::kTrackExiting | Hit::kTrackOut | Hit::kTrackStopped))) {
384 mTrackData.mEnergyLoss += fMC->Edep();
386 if (!(startHit | stopHit)) {
391 mTrackData.mEnergyLoss = 0.;
392 fMC->TrackMomentum(mTrackData.mMomentumStart);
393 fMC->TrackPosition(mTrackData.mPositionStart);
394 mTrackData.mTrkStatusStart = status;
395 mTrackData.mHitStarted =
true;
398 TLorentzVector positionStop;
399 fMC->TrackPosition(positionStop);
401 int stave(0), halfstave(0), chipinmodule(0),
module;
402 fMC->CurrentVolOffID(1, chipinmodule);
403 fMC->CurrentVolOffID(2, module);
404 fMC->CurrentVolOffID(3, halfstave);
405 fMC->CurrentVolOffID(4, stave);
407 Hit* p = addHit(
stack->GetCurrentTrackNumber(), lay, mTrackData.mPositionStart.Vect(), positionStop.Vect(),
408 mTrackData.mMomentumStart.Vect(), mTrackData.mMomentumStart.E(), positionStop.T(),
409 mTrackData.mEnergyLoss, mTrackData.mTrkStatusStart, status);
414 stack->addHit(GetDetId());
420o2::itsmft::Hit* Detector::addHit(
int trackID,
int detID,
const TVector3& startPos,
const TVector3& endPos,
421 const TVector3& startMom,
double startE,
double endTime,
double eLoss,
unsigned char startStatus,
422 unsigned char endStatus)
424 mHits->emplace_back(trackID, detID, startPos, endPos, startMom, startE, endTime, eLoss, startStatus, endStatus);
425 return &(mHits->back());
Definition of the Stack class.
Definition of the ITSMFT Hit class.
ClassImp(o2::trk::Detector)
o2::base::Detector * create_detector_trk(bool active)
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)
static const TRKBaseParam & Instance()
static o2::base::Detector * create(bool active)
static ShmManager & Instance()
GLenum GLuint GLint GLint layer
void createGeometry(TGeoManager &geom, TGeoVolume &topVolume)
float getDetLengthFromEta(const float eta, const float radius)
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"