Skip to content

Commit c616f61

Browse files
committed
Add basic functionality for placing exact staves and sensors: achieve by bundling existing functionalities into functions more
1 parent 40ae21c commit c616f61

4 files changed

Lines changed: 363 additions & 134 deletions

File tree

‎Detectors/Upgrades/ALICE3/TRKFT3/FT3/base/include/FT3Base/FT3BaseParam.h‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,13 @@ struct FT3BaseParam : public o2::conf::ConfigurableParamHelper<FT3BaseParam> {
4646
double staveTolOTInner = 0.;
4747
double staveTolOTOuter = 0.;
4848

49-
// What to place over x=0 line in case of full outer-outer stave: Gap or Module
50-
bool placeSensorStackInMiddleOfStave = false;
49+
/*
50+
* Place the sensor stacks from the tabulated layout in FT3ModuleConstants.h
51+
* (StaveConfig::exactStaveFills) instead of filling every stave greedily
52+
* with the stack sizes in kSensorsPerStack. The tabulated layout is taken as
53+
* given: none of the radial tolerances above are applied to it.
54+
*/
55+
bool useExactStavePlacement = false;
5156

5257
// Draw reference circles at inner and outer radius of stave layer, for visualisation
5358
bool drawReferenceCircles = false;

‎Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/FT3Module.h‎

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,39 @@ class FT3Module
5959
double Rout, double z_offset_local, const Constants::StaveConfig& staveConfig,
6060
TGeoVolume* motherVolume);
6161

62+
// Walk every stave of a layer, create its volumes and work out where its
63+
// modules go, leaving the positions in y_positionsPosNeg
64+
void build_staves_exact(
65+
TGeoVolume* motherVolume, int layerNumber, int direction,
66+
const Constants::StaveConfig& staveConfig,
67+
const std::array<std::array<double, 3>, 4>& staveTriangles,
68+
double z_offset_to_carbon_face,
69+
std::vector<PosNegPositionTypes>& y_positionsPosNeg,
70+
unsigned& staveVolumeCount);
71+
72+
void build_staves_greedy(
73+
TGeoVolume* motherVolume, int layerNumber, int direction, double Rin, double Rout,
74+
const Constants::StaveConfig& staveConfig,
75+
const std::array<std::array<double, 3>, 4>& staveTriangles,
76+
double z_offset_to_carbon_face,
77+
std::vector<PosNegPositionTypes>& y_positionsPosNeg, unsigned& staveVolumeCount);
78+
79+
// Shared by both: one stave's carbon shell, plus its mirror where needed
80+
void add_stave_volumes(
81+
TGeoVolume* motherVolume, int layerNumber, int direction,
82+
const Constants::StaveConfig& staveConfig, unsigned i_stave,
83+
const std::array<std::array<double, 3>, 4>& staveTriangles,
84+
double z_offset_to_carbon_face, std::pair<double, double>& absAllowedYRange,
85+
double y_midpoint, bool mirrorStaveAroundX, unsigned* staveVolumeCount);
86+
6287
// Helper functions
63-
void fill_stave(PosNegPositionTypes& y_positions, double Rin, double Rout,
64-
double x_left, unsigned kSensorStack, PositionRangeType y_range,
65-
std::pair<double, double>& absAllowedYRange);
88+
void fill_stave_greedy(
89+
PosNegPositionTypes& y_positions, double Rin, double Rout,
90+
double x_left, unsigned kSensorStack, PositionRangeType y_range,
91+
std::pair<double, double>& absAllowedYRange);
92+
93+
PositionTypes fill_stave_exact(const std::vector<Constants::StaveFill>& fills);
94+
6695
void addStaveVolume(
6796
TGeoVolume* motherVolume, std::string volumeName, int direction,
6897
unsigned* volume_count, double staveLength,

‎Detectors/Upgrades/ALICE3/TRKFT3/FT3/simulation/include/FT3Simulation/FT3ModuleConstants.h‎

Lines changed: 75 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,35 @@ inline const int staveIdxToID(int staveIdx, unsigned nStavesPerDisc)
7373
return staveIdx - nStavesOneSide + isRight;
7474
}
7575

76+
/*
77+
* Stave x midpoints follow from their number and spacing: they are spread
78+
* symmetrically about x=0, so an even count leaves a gap on the axis rather
79+
* than putting a stave on it. Deriving them keeps the spacing and the
80+
* positions from drifting apart.
81+
*/
82+
inline std::vector<double> makeStaveXMidpoints(unsigned nStaves, double spacing)
83+
{
84+
std::vector<double> midpoints(nStaves);
85+
for (unsigned i = 0; i < nStaves; i++) {
86+
midpoints[i] = (i - (nStaves - 1) / 2.0) * spacing;
87+
}
88+
return midpoints;
89+
}
90+
91+
/*
92+
* Staves alternate between the front and the back of the disc so that
93+
* neighbours can overlap in x without touching, staggered in z by
94+
* z_offsetStave. Starting at 0 puts the leftmost stave at the back.
95+
*/
96+
inline std::vector<bool> makeStaveOnFront(unsigned nStaves)
97+
{
98+
std::vector<bool> staveOnFront(nStaves);
99+
for (unsigned i = 0; i < nStaves; i++) {
100+
staveOnFront[i] = i % 2;
101+
}
102+
return staveOnFront;
103+
}
104+
76105
// material properties
77106
const double siliconThickness = 0.01;
78107
const double copperThickness = 0.006;
@@ -101,6 +130,22 @@ inline const double z_offsetStave(double x_midpoint_spacing)
101130
(2 - x_midpoint_spacing / (sensor2x1_width / 2 + staveSensorGap));
102131
}
103132

133+
/*
134+
* One uninterrupted fill of 2xN modules along a stave.
135+
*
136+
* yStart is the y of the BOTTOM edge of the first module; modules follow
137+
* upwards, each separated from the previous one by stackGap. Nothing is
138+
* mirrored: the layout is symmetric about the y-axis (stave +-ID) but NOT
139+
* about the x-axis, so every fill states its own y explicitly.
140+
*
141+
* A stave that the beam pipe cuts in two therefore carries two fills, one
142+
* below the hole and one above it, each with its own yStart.
143+
*/
144+
struct StaveFill {
145+
const double yStart;
146+
const std::vector<unsigned> stackHeights;
147+
};
148+
104149
// Struct for stave position configuration (varies between ML/OT)
105150
struct StaveConfig {
106151
const unsigned isML; // whether this config is for ML or OT
@@ -128,6 +173,13 @@ struct StaveConfig {
128173
// kSegmentedStave: staggering staves in z (see z_offsetStave)
129174
// accessed via stave index, NOT stave ID
130175
const std::vector<bool>& staveOnFront;
176+
/*
177+
* Tabulated module layout, used when FT3Base.useExactStavePlacement is set.
178+
* One entry per stave, indexed like x_midpoints (NOT by stave ID), holding
179+
* that stave's fills: one for a stave reaching across y=0, two for a stave
180+
* split by the beam pipe.
181+
*/
182+
const std::vector<std::vector<StaveFill>>& exactStaveFills;
131183
};
132184

133185
namespace OT_StavePositions
@@ -142,20 +194,21 @@ const std::vector<double> y_lengths = {
142194
128.7, 132.0, 132.0, 138.6, 138.6, 56.1, 52.8,
143195
52.8, 56.1, 138.6, 138.6, 132.0, 132.0, 128.7,
144196
118.8, 118.8, 105.6, 99.0, 92.4, 79.2, 66.0, 52.8};
145-
const std::vector<double> x_midpoints = {
146-
-65.25, -60.75, -56.25, -51.75, -47.25, -42.75, -38.25, // L
147-
-33.75, -29.25, -24.75, -20.25, -15.75, -11.25, -6.75, -2.25, // L
148-
2.25, 6.75, 11.25, 15.75, 20.25, 24.75, 29.25, 33.75, // R
149-
38.25, 42.75, 47.25, 51.75, 56.25, 60.75, 65.25 // R
150-
};
151-
const double x_midpoint_spacing = 4.5; // assume constant for now
152-
const double maxToleranceInner = 0.; // default not allowed inwards
197+
const unsigned nStaves = 30; // y_lengths, staveOnFront and exactStaveFills follow this
198+
const double x_midpoint_spacing = 4.5;
199+
const std::vector<double> x_midpoints = makeStaveXMidpoints(nStaves, x_midpoint_spacing);
200+
const double maxToleranceInner = 9.; // close but not directly at 10cm yet
153201
const double maxToleranceOuter = 3.4; // leave 1mm for layer air encapsulation
154-
const std::vector<bool> staveOnFront =
155-
{
156-
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, // L
157-
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 // R
158-
};
202+
const std::vector<bool> staveOnFront = makeStaveOnFront(nStaves);
203+
/*
204+
* TODO: fill from the disk optimiser output. One entry per stave, in the same
205+
* order as x_midpoints, and nStaves entries in total before
206+
* useExactStavePlacement works. Each entry lists that stave's fills:
207+
*
208+
* {{{-52.80, {4, 4, 4, 3}}}}, // reaches across y=0
209+
* {{-63.84, {4, 4, 3}}, {8.34, {4, 4, 3}}}, // split by the beam pipe
210+
*/
211+
const std::vector<std::vector<StaveFill>> exactStaveFills = {};
159212
} // namespace OT_StavePositions
160213

161214
namespace ML_StavePositions
@@ -171,18 +224,14 @@ const std::map<int, std::pair<double, bool>> staveID_to_y_midpoint = {
171224
const std::vector<double> y_lengths = {
172225
30.5, 44.5, 53.6, 60.0, 64.6, 29.5, 25.8, 25.0,
173226
25.0, 25.8, 29.5, 64.6, 60.0, 53.6, 44.5, 30.5};
174-
const std::vector<double> x_midpoints = {
175-
-33.75, -29.25, -24.75, -20.25, -15.75, -11.25, -6.75, -2.25, // L
176-
2.25, 6.75, 11.25, 15.75, 20.25, 24.75, 29.25, 33.75 // R
177-
};
227+
const unsigned nStaves = 16; // y_lengths, staveOnFront and exactStaveFills follow this
178228
const double x_midpoint_spacing = 4.5;
229+
const std::vector<double> x_midpoints = makeStaveXMidpoints(nStaves, x_midpoint_spacing);
179230
const double maxToleranceInner = 0.; // default not allowed inwards
180231
const double maxToleranceOuter = 3.4; // leave 1mm for layer air encapsulation
181-
const std::vector<bool> staveOnFront =
182-
{
183-
1, 0, 1, 0, 1, 0, 1, 0, // L
184-
1, 0, 1, 0, 1, 0, 1, 0 // R
185-
};
232+
const std::vector<bool> staveOnFront = makeStaveOnFront(nStaves);
233+
// TODO: fill from the disk optimiser output, see OT_StavePositions above.
234+
const std::vector<std::vector<StaveFill>> exactStaveFills = {};
186235
} // namespace ML_StavePositions
187236

188237
// Get stave configuration based on tracker type
@@ -197,7 +246,8 @@ inline StaveConfig getStaveConfig(bool isInnerDisk)
197246
ML_StavePositions::x_midpoint_spacing,
198247
ML_StavePositions::maxToleranceInner,
199248
ML_StavePositions::maxToleranceOuter,
200-
ML_StavePositions::staveOnFront};
249+
ML_StavePositions::staveOnFront,
250+
ML_StavePositions::exactStaveFills};
201251
} else {
202252
return StaveConfig{
203253
false, // isML
@@ -207,7 +257,8 @@ inline StaveConfig getStaveConfig(bool isInnerDisk)
207257
OT_StavePositions::x_midpoint_spacing,
208258
OT_StavePositions::maxToleranceInner,
209259
OT_StavePositions::maxToleranceOuter,
210-
OT_StavePositions::staveOnFront};
260+
OT_StavePositions::staveOnFront,
261+
OT_StavePositions::exactStaveFills};
211262
}
212263
}
213264

0 commit comments

Comments
 (0)