Skip to content

Commit a2e7b8e

Browse files
Add option to use a segmented OT (#13325)
* [WIP] Add staves in the naming [WIP] Add staves to the tracker * [WIP] Add segmentation of the layers into staves Add possibility to switch on/off the layer segmentation * Minor format changes * Update Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h --------- Co-authored-by: Matteo Concas <mconcas@cern.ch>
1 parent 4b29cae commit a2e7b8e

File tree

6 files changed

+102
-18
lines changed

6 files changed

+102
-18
lines changed

Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/GeometryTGeo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache
2929

3030
static const char* getTRKVolPattern() { return sVolumeName.c_str(); }
3131
static const char* getTRKLayerPattern() { return sLayerName.c_str(); }
32+
static const char* getTRKStavePattern() { return sStaveName.c_str(); }
3233
static const char* getTRKChipPattern() { return sChipName.c_str(); }
3334
static const char* getTRKSensorPattern() { return sSensorName.c_str(); }
3435

@@ -37,12 +38,14 @@ class GeometryTGeo : public o2::detectors::DetMatrixCache
3738
return Form("%s_%d", o2::detectors::DetID(o2::detectors::DetID::TRK).getName(), d);
3839
}
3940
static const char* composeSymNameLayer(int d, int layer);
41+
static const char* composeSymNameStave(int d, int layer);
4042
static const char* composeSymNameChip(int d, int lr);
4143
static const char* composeSymNameSensor(int d, int layer);
4244

4345
protected:
4446
static std::string sVolumeName;
4547
static std::string sLayerName;
48+
static std::string sStaveName;
4649
static std::string sChipName;
4750
static std::string sSensorName;
4851

Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@ namespace o2
2020
namespace trk
2121
{
2222

23+
enum eLayout {
24+
kCylinder = 0,
25+
kTurboStaves,
26+
};
27+
2328
struct TRKBaseParam : public o2::conf::ConfigurableParamHelper<TRKBaseParam> {
2429
std::string configFile = "";
2530
float serviceTubeX0 = 0.02f; // X0 Al2O3
31+
eLayout layout = kCylinder; // Type of segmentation of the layers into staves
2632

2733
O2ParamDef(TRKBaseParam, "TRKBase");
2834
};

Detectors/Upgrades/ALICE3/TRK/base/src/GeometryTGeo.cxx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ std::unique_ptr<o2::trk::GeometryTGeo> GeometryTGeo::sInstance;
2020

2121
// Names
2222
std::string GeometryTGeo::sVolumeName = "TRKV";
23+
std::string GeometryTGeo::sStaveName = "TRKStave";
2324
std::string GeometryTGeo::sLayerName = "TRKLayer";
2425
std::string GeometryTGeo::sChipName = "TRKChip";
2526
std::string GeometryTGeo::sSensorName = "TRKSensor";
@@ -65,9 +66,14 @@ const char* GeometryTGeo::composeSymNameLayer(int d, int lr)
6566
return Form("%s/%s%d", composeSymNameTRK(d), getTRKLayerPattern(), lr);
6667
}
6768

69+
const char* GeometryTGeo::composeSymNameStave(int d, int lr)
70+
{
71+
return Form("%s/%s%d", composeSymNameLayer(d, lr), getTRKStavePattern(), lr);
72+
}
73+
6874
const char* GeometryTGeo::composeSymNameChip(int d, int lr)
6975
{
70-
return Form("%s/%s%d", composeSymNameLayer(d, lr), getTRKChipPattern(), lr);
76+
return Form("%s/%s%d", composeSymNameStave(d, lr), getTRKChipPattern(), lr);
7177
}
7278

7379
const char* GeometryTGeo::composeSymNameSensor(int d, int lr)

Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/TRKLayer.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include <TGeoManager.h>
1616
#include <Rtypes.h>
1717

18+
#include "TRKBase/TRKBaseParam.h"
19+
1820
namespace o2
1921
{
2022
namespace trk
@@ -27,6 +29,8 @@ class TRKLayer
2729
TRKLayer(int layerNumber, std::string layerName, float rInn, float zLength, float thick);
2830
~TRKLayer() = default;
2931

32+
void setLayout(eLayout layout) { mLayout = layout; };
33+
3034
auto getInnerRadius() const { return mInnerRadius; }
3135
auto getOuterRadius() const { return mOuterRadius; }
3236
auto getZ() const { return mZ; }
@@ -45,8 +49,10 @@ class TRKLayer
4549
float mZ;
4650
float mX2X0;
4751
float mChipThickness;
52+
float mModuleWidth; // u.m. = cm
53+
eLayout mLayout;
4854

49-
ClassDef(TRKLayer, 0);
55+
ClassDef(TRKLayer, 1);
5056
};
5157

5258
} // namespace trk

Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ void Detector::buildTRKNewVacuumVessel()
114114
mLayers.emplace_back(8, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(8)}, 45.f, 258.f, 100.e-3);
115115
mLayers.emplace_back(9, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(9)}, 60.f, 258.f, 100.e-3);
116116
mLayers.emplace_back(10, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(10)}, 80.f, 258.f, 100.e-3);
117+
118+
auto& trkPars = TRKBaseParam::Instance();
119+
mLayers[8].setLayout(trkPars.layout);
120+
mLayers[9].setLayout(trkPars.layout);
121+
mLayers[10].setLayout(trkPars.layout);
117122
}
118123

119124
void Detector::configFromFile(std::string fileName)

Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,25 @@
1515
#include "Framework/Logger.h"
1616

1717
#include <TGeoTube.h>
18+
#include <TGeoBBox.h>
1819
#include <TGeoVolume.h>
1920

21+
#include <TMath.h>
22+
2023
namespace o2
2124
{
2225
namespace trk
2326
{
2427
TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float rOut, float zLength, float layerX2X0)
25-
: mLayerNumber(layerNumber), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mZ(zLength), mX2X0(layerX2X0)
28+
: mLayerNumber(layerNumber), mLayerName(layerName), mInnerRadius(rInn), mOuterRadius(rOut), mZ(zLength), mX2X0(layerX2X0), mModuleWidth(4.54), mLayout(kCylinder)
2629
{
2730
float Si_X0 = 9.5f;
2831
mChipThickness = mX2X0 * Si_X0;
2932
LOGP(info, "Creating layer: id: {} rInner: {} rOuter: {} zLength: {} x2X0: {}", mLayerNumber, mInnerRadius, mOuterRadius, mZ, mX2X0);
3033
}
3134

3235
TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float zLength, float thick)
33-
: mLayerNumber(layerNumber), mLayerName(layerName), mInnerRadius(rInn), mZ(zLength), mChipThickness(thick)
36+
: mLayerNumber(layerNumber), mLayerName(layerName), mInnerRadius(rInn), mZ(zLength), mChipThickness(thick), mModuleWidth(4.54), mLayout(kCylinder)
3437
{
3538
float Si_X0 = 9.5f;
3639
mOuterRadius = rInn + thick;
@@ -40,29 +43,84 @@ TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float zLe
4043

4144
void TRKLayer::createLayer(TGeoVolume* motherVolume)
4245
{
43-
std::string chipName = o2::trk::GeometryTGeo::getTRKChipPattern() + std::to_string(mLayerNumber),
46+
TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
47+
TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$");
48+
49+
std::string staveName = o2::trk::GeometryTGeo::getTRKStavePattern() + std::to_string(mLayerNumber),
50+
chipName = o2::trk::GeometryTGeo::getTRKChipPattern() + std::to_string(mLayerNumber),
4451
sensName = Form("%s%d", GeometryTGeo::getTRKSensorPattern(), mLayerNumber);
4552

46-
TGeoTube* sensor = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2);
47-
TGeoTube* chip = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2);
4853
TGeoTube* layer = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2);
4954

50-
TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
51-
TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$");
52-
53-
TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi);
54-
sensVol->SetLineColor(kYellow);
55-
TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi);
56-
chipVol->SetLineColor(kYellow);
5755
TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir);
5856
layerVol->SetLineColor(kYellow);
5957

60-
LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName());
61-
chipVol->AddNode(sensVol, 1, nullptr);
58+
if (mLayout == eLayout::kCylinder) {
59+
TGeoTube* stave = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2);
60+
TGeoTube* chip = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2);
61+
TGeoTube* sensor = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2);
62+
63+
TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi);
64+
sensVol->SetLineColor(kYellow);
65+
TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi);
66+
chipVol->SetLineColor(kYellow);
67+
TGeoVolume* staveVol = new TGeoVolume(staveName.c_str(), stave, medSi);
68+
staveVol->SetLineColor(kYellow);
69+
70+
LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName());
71+
chipVol->AddNode(sensVol, 1, nullptr);
72+
73+
LOGP(info, "Inserting {} in {} ", chipVol->GetName(), staveVol->GetName());
74+
staveVol->AddNode(chipVol, 1, nullptr);
75+
76+
LOGP(info, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName());
77+
layerVol->AddNode(staveVol, 1, nullptr);
78+
} else if (mLayout == eLayout::kTurboStaves) {
79+
// Compute the number of staves
80+
double width = mModuleWidth * 2; // Each stave has two modules (based on the LOI design)
81+
int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / width);
82+
nStaves += nStaves % 2; // Require an even number of staves
83+
84+
// Compute the size of the overlap region
85+
double theta = 2 * TMath::Pi() / nStaves;
86+
double theta1 = std::atan(width / 2 / mInnerRadius);
87+
double st = std::sin(theta);
88+
double ct = std::cos(theta);
89+
double theta2 = std::atan((mInnerRadius * st - width / 2 * ct) / (mInnerRadius * ct + width / 2 * st));
90+
double overlap = (theta1 - theta2) * mInnerRadius;
91+
LOGP(info, "Creating a layer with {} staves and {} mm overlap", nStaves, overlap * 10);
92+
93+
for (int iStave = 0; iStave < nStaves; iStave++) {
94+
TGeoBBox* sensor = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2);
95+
TGeoBBox* chip = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2);
96+
TGeoBBox* stave = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2);
97+
98+
TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi);
99+
sensVol->SetLineColor(kYellow);
100+
TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi);
101+
chipVol->SetLineColor(kYellow);
102+
TGeoVolume* staveVol = new TGeoVolume(staveName.c_str(), stave, medSi);
103+
staveVol->SetLineColor(kYellow);
104+
105+
// Put the staves in the correct position and orientation
106+
TGeoCombiTrans* trans = new TGeoCombiTrans();
107+
double theta = 360. * iStave / nStaves;
108+
TGeoRotation* rot = new TGeoRotation("rot", theta + 90 + 2, 0, 0);
109+
trans->SetRotation(rot);
110+
trans->SetTranslation(mInnerRadius * std::cos(2. * TMath::Pi() * iStave / nStaves), mInnerRadius * std::sin(2 * TMath::Pi() * iStave / nStaves), 0);
111+
112+
LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName());
113+
chipVol->AddNode(sensVol, 1, nullptr);
62114

63-
LOGP(info, "Inserting {} in {} ", chipVol->GetName(), layerVol->GetName());
64-
layerVol->AddNode(chipVol, 1, nullptr);
115+
LOGP(info, "Inserting {} in {} ", chipVol->GetName(), staveVol->GetName());
116+
staveVol->AddNode(chipVol, 1, nullptr);
65117

118+
LOGP(info, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName());
119+
layerVol->AddNode(staveVol, iStave, trans);
120+
}
121+
} else {
122+
LOGP(fatal, "Layout not implemented");
123+
}
66124
LOGP(info, "Inserting {} in {} ", layerVol->GetName(), motherVolume->GetName());
67125
motherVolume->AddNode(layerVol, 1, nullptr);
68126
}

0 commit comments

Comments
 (0)