Skip to content

Commit ff93406

Browse files
lorber98claude
andauthored
[ALICE3] TRK: rInnRow column for staggered ML layers in the config file (#15992)
* [ALICE3] TRK: rInnRow column for staggered ML layers in the config file The TRK configuration file (TRKBase.configFile) accepts an optional 8th column, rInnRow, which chooses the staves of a staggered layer (layers 3 and 4) that sit at rInn: 0 = even staves (default, previous behaviour), 1 = odd staves, i.e. stave 0 in the shifted row. Existing files and the default layouts give the same geometry as before. A value other than 0 or 1 is fatal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * [ALICE3] TRK: phiOffset column for the ML layers in the config file The TRK configuration file (TRKBase.configFile) accepts an optional 9th column, phiOffset (degrees, counterclockwise as phi), which rotates all the staves of a ML layer about the beam axis, keeping their tilt. Existing files and the default layouts give the same geometry as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Fix formatting * Update readme --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent c06edc8 commit ff93406

4 files changed

Lines changed: 34 additions & 8 deletions

File tree

‎Detectors/Upgrades/ALICE3/TRKFT3/TRK/README.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ Both layouts use the same configuration-file syntax (only the OT geometry implem
6868

6969
**Middle Layers (ML) - Indices 0 to 4**
7070
The first 5 valid lines are parsed as `TRKMLLayer` objects. These layers **require** a 6th parameter for the staggering offset (`stagOffset`).
71-
* **Format:** `rInn` \t `thick` \t `tiltAngle` \t `nStaves` \t `nMods` \t `stagOffset` \t `[optional_mode]`
71+
* **Format:** `rInn` \t `thick` \t `tiltAngle` \t `nStaves` \t `nMods` \t `stagOffset` \t `[optional_mode]` \t `[optional_rInnRow]` \t `[optional_phiOffset]`
72+
* Layers 3 and 4 are staggered: one stave out of two sits at `rInn`, the others are shifted by `stagOffset`. By default the even staves are at `rInn`; `rInnRow` = 1 puts the odd staves there instead, i.e. stave 0 in the shifted row. In the flipped layer 3 the `rInn` row is the outer one and the shift points inwards, so there `rInnRow` = 1 puts stave 0 in the inner row; in layer 4 in the outer row. To give `rInnRow`, the mode column must be written too.
73+
* `phiOffset` (degrees, counterclockwise, default 0) rotates the whole layer about the beam axis; each stave keeps its tilt. It requires the mode and `rInnRow` columns.
7274

7375
**Outer Layers (OT) - Indices 5 and above**
7476
From the 6th valid line onwards, lines are parsed as OT layer objects (`TRKOTLayer` for `kSegmented`, `TRKOTLayerRealistic` for `kSimplifiedRealistic`). These layers do **not** have a staggering offset. The optional mode parameter shifts to the 6th column.

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class TRKMLLayer : public TRKSegmentedLayer
111111
{
112112
public:
113113
TRKMLLayer() = default;
114-
TRKMLLayer(int layerNumber, std::string layerName, float rInn, float staggerOffset, float tiltAngle, int numberOfStaves, int numberOfModules, float thickOrX2X0, MatBudgetParamMode mode);
114+
TRKMLLayer(int layerNumber, std::string layerName, float rInn, float staggerOffset, float tiltAngle, int numberOfStaves, int numberOfModules, float thickOrX2X0, MatBudgetParamMode mode, int rInnRow = 0, float phiOffset = 0.f);
115115
~TRKMLLayer() override = default;
116116

117117
TGeoVolume* createStave() override;
@@ -121,6 +121,8 @@ class TRKMLLayer : public TRKSegmentedLayer
121121
TGeoVolume* createEndOfStaveCard(); // A-side (+z) end-of-stave card, in front of the conn disk
122122

123123
float mStaggerOffset;
124+
int mRInnRow = 0; // staggered layers: staves with iStave % 2 == mRInnRow sit at rInn, the others are shifted by the stagger offset
125+
float mPhiOffset = 0.f; // deg, rotation of all the staves of the layer about the beam axis (counterclockwise, as phi)
124126

125127
static constexpr double sStaveWidth = constants::ML::width;
126128
static constexpr int sFlippedLayerNumber = 3;

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ void Detector::configFromFile(std::string fileName)
225225
// tmpBuff[4] = nMods
226226
// tmpBuff[5] = stagOffset (required ONLY for ML)
227227
// tmpBuff[6] = matBudgetMode (optional, default = Thickness)
228+
// tmpBuff[7] = rInnRow (optional, ML only, default = 0): which staves of a staggered layer sit at
229+
// rInn, 0 = even, 1 = odd (needs tmpBuff[6]); in the flipped layer the rInn row is the outer one
230+
// tmpBuff[8] = phiOffset (optional, ML only, default = 0): rotation of all the staves of the layer about
231+
// the beam axis, in degrees, counterclockwise as phi (needs tmpBuff[6] and tmpBuff[7])
228232

229233
// Base parameters for all segmented layers (at least 5 needed)
230234
if (tmpBuff.size() < 5) {
@@ -250,8 +254,10 @@ void Detector::configFromFile(std::string fileName)
250254
if (tmpBuff.size() >= 7) {
251255
matBudgetMode = static_cast<MatBudgetParamMode>(static_cast<int>(tmpBuff[6]));
252256
}
257+
const int rInnRow = (tmpBuff.size() >= 8) ? static_cast<int>(tmpBuff[7]) : 0;
258+
const float phiOffset = (tmpBuff.size() >= 9) ? tmpBuff[8] : 0.f;
253259

254-
mLayers.push_back(std::make_unique<TRKMLLayer>(layerCount, name, rInn, stagOffset, tiltAngle, nStaves, nMods, thick, matBudgetMode));
260+
mLayers.push_back(std::make_unique<TRKMLLayer>(layerCount, name, rInn, stagOffset, tiltAngle, nStaves, nMods, thick, matBudgetMode, rInnRow, phiOffset));
255261
} else {
256262
// OT layers do NOT have stagOffset. The optional mode is at index 5.
257263
if (tmpBuff.size() >= 6) {

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

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,16 +233,31 @@ std::pair<float, float> TRKSegmentedLayer::getBoundingRadii(double staveWidth) c
233233

234234
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
235235

236-
TRKMLLayer::TRKMLLayer(int layerNumber, std::string layerName, float rInn, float staggerOffset, float tiltAngle, int numberOfStaves, int numberOfModules, float thickOrX2X0, MatBudgetParamMode mode)
237-
: TRKSegmentedLayer(layerNumber, layerName, rInn, tiltAngle, numberOfStaves, numberOfModules, thickOrX2X0, mode), mStaggerOffset(staggerOffset)
236+
TRKMLLayer::TRKMLLayer(int layerNumber, std::string layerName, float rInn, float staggerOffset, float tiltAngle, int numberOfStaves, int numberOfModules, float thickOrX2X0, MatBudgetParamMode mode, int rInnRow, float phiOffset)
237+
: TRKSegmentedLayer(layerNumber, layerName, rInn, tiltAngle, numberOfStaves, numberOfModules, thickOrX2X0, mode), mStaggerOffset(staggerOffset), mRInnRow(rInnRow), mPhiOffset(phiOffset)
238238
{
239+
if (mPhiOffset != 0.f) {
240+
LOGP(info, "Layer {}: staves rotated by {} deg about the beam axis (phiOffset)", mLayerNumber, mPhiOffset);
241+
}
239242
if (mLayerNumber == sFlippedLayerNumber) {
240243
mOuterRadius = rInn;
241244
mInnerRadius = rInn - mChipThickness;
242245
mIsFlipped = true;
243246
mStaggerOffset = -staggerOffset;
244247
LOGP(info, "Layer {} is flipped: sensor and metal stack positions are switched", mLayerNumber);
245248
}
249+
if (mRInnRow != 0 && mRInnRow != 1) {
250+
LOGP(fatal, "Layer {}: rInnRow = {}, use 0 (even staves at rInn) or 1 (odd staves at rInn)", mLayerNumber, mRInnRow);
251+
}
252+
if (mRInnRow != 0) {
253+
if (mLayerNumber == 3 || mLayerNumber == 4) {
254+
// even staves (stave 0) go to the shifted row: inside the rInn row in the flipped layer, outside
255+
// otherwise (stagOffset >= 0; a negative stagOffset is not handled by getBoundingRadii)
256+
LOGP(info, "Layer {} (staggered): even staves in the {} row (rInnRow = {})", mLayerNumber, mIsFlipped ? "inner" : "outer", mRInnRow);
257+
} else {
258+
LOGP(info, "Layer {} is not staggered: rInnRow = {} has no effect", mLayerNumber, mRInnRow);
259+
}
260+
}
246261
}
247262

248263
TGeoVolume* TRKMLLayer::createStave()
@@ -336,13 +351,14 @@ void TRKMLLayer::createLayer(TGeoVolume* motherVolume)
336351
for (int iStave = 0; iStave < mNumberOfStaves; iStave++) {
337352
TGeoVolume* staveVol = createStave();
338353
TGeoCombiTrans* trans = new TGeoCombiTrans();
339-
// If the number of staves is a multiple of 4, rotate by half a stave to avoid having the first one exactly on the x
340-
double phi = (mNumberOfStaves % 4 == 0) ? theta * (iStave + 0.5) : theta * iStave;
354+
// If the number of staves is a multiple of 4, rotate by half a stave to avoid having the first one exactly on the x;
355+
// mPhiOffset rotates the whole layer (position and orientation of every stave) about the beam axis
356+
double phi = ((mNumberOfStaves % 4 == 0) ? theta * (iStave + 0.5) : theta * iStave) + mPhiOffset * TMath::DegToRad();
341357
double phiDeg = phi * TMath::RadToDeg();
342358
TGeoRotation* rot = new TGeoRotation("rot", phiDeg + 90 + mTiltAngle, 0, 0);
343359
trans->SetRotation(rot);
344360
// float trueRadius = (mLayerNumber == 3 || mLayerNumber == 4) ? (iStave % 2 == 0 ? mInnerRadius : mInnerRadius + mStaggerOffset) : mInnerRadius;
345-
float trueRadius = (mLayerNumber == 3 || mLayerNumber == 4) ? (iStave % 2 == 0 ? avgRadiusInner : avgRadiusOuter) : avgRadiusInner;
361+
float trueRadius = (mLayerNumber == 3 || mLayerNumber == 4) ? (iStave % 2 == mRInnRow ? avgRadiusInner : avgRadiusOuter) : avgRadiusInner;
346362
trans->SetTranslation(trueRadius * std::cos(phi), trueRadius * std::sin(phi), 0);
347363
LOGP(debug, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName());
348364
layerVol->AddNode(staveVol, iStave, trans);

0 commit comments

Comments
 (0)