@@ -247,10 +247,9 @@ TRKMLLayer::TRKMLLayer(int layerNumber, std::string layerName, float rInn, float
247247
248248TGeoVolume* TRKMLLayer::createStave ()
249249{
250- TGeoMedium* medAir = gGeoManager -> GetMedium ( " TRK_AIR$ " );
250+ // Assembly (not a solid box) so the end-of-stave card can extend past the module envelope.
251251 std::string staveName = GeometryTGeo::getTRKStavePattern () + std::to_string (mLayerNumber );
252- TGeoShape* stave = new TGeoBBox (sStaveWidth / 2 , mChipThickness / 2 , mLength / 2 );
253- TGeoVolume* staveVol = new TGeoVolume (staveName.c_str (), stave, medAir);
252+ TGeoVolume* staveVol = new TGeoVolumeAssembly (staveName.c_str ());
254253 staveVol->SetLineColor (kYellow );
255254
256255 for (int iModule = 0 ; iModule < mNumberOfModules ; iModule++) {
@@ -262,17 +261,58 @@ TGeoVolume* TRKMLLayer::createStave()
262261 staveVol->AddNode (moduleVol, iModule, trans);
263262 }
264263
264+ // End-of-stave card on the A-side (+z) only, just past the stave end and in front of the
265+ // TRK_MIDBARCONN_DISK. Local frame: x = phi (width), y = radial (thickness), z = length.
266+ TGeoCombiTrans* tCard = new TGeoCombiTrans ();
267+ tCard->SetTranslation (0 , 0 , mLength / 2 + constants::ML ::eosCard::zGap + constants::ML ::eosCard::length / 2 );
268+ staveVol->AddNode (createEndOfStaveCard (), 0 , tCard);
269+
265270 return staveVol;
266271}
267272
273+ TGeoVolume* TRKMLLayer::createEndOfStaveCard ()
274+ {
275+ // FR4 board carrying evenly spaced copper planes; same construction as the OT card, with its
276+ // own constants::ML::eosCard dimensions and a configurable copper thickness (TRKBase.mlEosCardCuThickness),
277+ // which displaces FR4 inside the fixed envelope and sets the card x/X0.
278+ TGeoMedium* medFR4 = gGeoManager ->GetMedium (" TRK_FR4$" );
279+ TGeoMedium* medCu = gGeoManager ->GetMedium (" TRK_COPPER$" );
280+ const std::string name = GeometryTGeo::getTRKStavePattern () + std::to_string (mLayerNumber ) + " _EOSCard" ;
281+
282+ TGeoShape* board = new TGeoBBox (constants::ML ::eosCard::width / 2 , constants::ML ::eosCard::thickness / 2 , constants::ML ::eosCard::length / 2 );
283+ TGeoVolume* cardVol = new TGeoVolume (name.c_str (), board, medFR4);
284+ cardVol->SetLineColor (kGreen + 3 );
285+
286+ const double cuThickness = TRKBaseParam::Instance ().mlEosCardCuThickness ;
287+ const int nPlanes = constants::ML ::eosCard::nCopperLayers;
288+ if (cuThickness * nPlanes >= constants::ML ::eosCard::thickness) {
289+ LOGP (fatal, " TRKBase.mlEosCardCuThickness = {} cm x {} planes does not fit in the {} cm ML end-of-stave card" ,
290+ cuThickness, nPlanes, constants::ML ::eosCard::thickness);
291+ }
292+ TGeoShape* plane = new TGeoBBox (constants::ML ::eosCard::width / 2 , cuThickness / 2 , constants::ML ::eosCard::length / 2 );
293+ TGeoVolume* planeVol = new TGeoVolume ((name + " _Cu" ).c_str (), plane, medCu);
294+ planeVol->SetLineColor (kOrange + 7 );
295+
296+ // Evenly spaced, the outermost two flush with the board surfaces.
297+ const double span = constants::ML ::eosCard::thickness - cuThickness;
298+ for (int iPlane = 0 ; iPlane < nPlanes; iPlane++) {
299+ const double y = (nPlanes > 1 ) ? -span / 2 + iPlane * span / (nPlanes - 1 ) : 0 .;
300+ cardVol->AddNode (planeVol, iPlane, new TGeoTranslation (0 , y, 0 ));
301+ }
302+
303+ return cardVol;
304+ }
305+
268306void TRKMLLayer::createLayer (TGeoVolume* motherVolume)
269307{
270308 // Retrieve exact bounding boundaries and create the logical container volume
271309 auto [rMin, rMax] = getBoundingRadii (sStaveWidth );
272310
273311 TGeoMedium* medAir = gGeoManager ->GetMedium (" TRK_AIR$" );
274312 // TGeoTube* layer = new TGeoTube(mInnerRadius - 0.333 * sLogicalVolumeThickness, mInnerRadius + 0.667 * sLogicalVolumeThickness, mLength / 2);
275- TGeoTube* layer = new TGeoTube (rMin, rMax, mLength / 2 );
313+ // Extend the z half-length so the A-side end-of-stave card (past mLength/2) stays inside the layer.
314+ const double halfLengthZ = mLength / 2 + constants::ML ::eosCard::zGap + constants::ML ::eosCard::length;
315+ TGeoTube* layer = new TGeoTube (rMin, rMax, halfLengthZ);
276316 TGeoVolume* layerVol = new TGeoVolume (mLayerName .c_str (), layer, medAir);
277317 layerVol->SetLineColor (kYellow );
278318
0 commit comments