78 const double carbonFiberThickness = 0.01;
79 const double foamSpacingThickness = 0.5;
81 TGeoTube* carbonFiberLayer =
new TGeoTube(mInnerRadius, mOuterRadius, carbonFiberThickness / 2);
87 carbonFiberLayerVol1->SetLineColor(kGray + 2);
88 carbonFiberLayerVol2->SetLineColor(kGray + 2);
90 const double zSeparation = foamSpacingThickness / 2.0 + carbonFiberThickness / 2.0;
92 motherVolume->AddNode(carbonFiberLayerVol1, 1,
new TGeoTranslation(0, 0, mZ - zSeparation));
93 motherVolume->AddNode(carbonFiberLayerVol2, 1,
new TGeoTranslation(0, 0, mZ + zSeparation));
95 const double pipeOuterRadius = 0.20;
96 const double kaptonThickness = 0.0025;
97 const double pipeInnerRadius = pipeOuterRadius - kaptonThickness;
98 const double pipeMaxLength = mOuterRadius * 2.0;
107 std::vector<double> X_pos = {-62.3168, -57.9836, -53.650400000000005, -49.317200000000014, -44.984000000000016, -40.65080000000002, -36.31760000000002, -31.984400000000026, -27.65120000000003, -23.318000000000037, -18.98480000000004, -14.651600000000043, -10.318400000000047, -5.98520000000005, -1.6520000000000519, 2.6811999999999445, 7.014399999999941, 11.347599999999936, 15.680799999999934, 20.01399999999993, 24.347199999999926, 28.68039999999992, 33.013599999999926, 37.34679999999992, 41.980000000000004, 46.613200000000006, 51.246399999999994, 55.87960000000001, 60.5128};
109 for (
double xPos : X_pos) {
111 double pipeLength = pipeMaxLength;
114 TGeoRotation* rotation =
new TGeoRotation();
115 rotation->RotateX(90);
117 if (std::abs(xPos) < mInnerRadius) {
118 double yInner = std::abs(y_circle(xPos, mInnerRadius));
119 double yOuter = std::abs(y_circle(xPos, mOuterRadius));
124 double positiveYLength = yOuter - yInner;
127 kaptonPipePos->SetLineColor(kGray);
129 waterVolumePos->SetLineColor(kBlue);
131 motherVolume->AddNode(waterVolumePos, 1,
new TGeoCombiTrans(xPos, (yInner + yOuter) / 2.0, mZ, rotation));
134 kaptonPipeNeg->SetLineColor(kGray);
136 waterVolumeNeg->SetLineColor(kBlue);
138 motherVolume->AddNode(waterVolumeNeg, 1,
new TGeoCombiTrans(xPos, -(yInner + yOuter) / 2.0, mZ, rotation));
140 motherVolume->AddNode(kaptonPipePos, 1,
new TGeoCombiTrans(xPos, (yInner + yOuter) / 2.0, mZ, rotation));
141 motherVolume->AddNode(kaptonPipeNeg, 1,
new TGeoCombiTrans(xPos, -(yInner + yOuter) / 2.0, mZ, rotation));
145 double yOuter = std::abs(y_circle(xPos, mOuterRadius));
150 kaptonPipe->SetLineColor(kGray);
152 waterVolume->SetLineColor(kBlue);
154 motherVolume->AddNode(waterVolume, 1,
new TGeoCombiTrans(xPos, 0, mZ, rotation));
155 motherVolume->AddNode(kaptonPipe, 1,
new TGeoCombiTrans(xPos, 0, mZ, rotation));
165 constexpr double carbonFiberThickness = 0.01;
166 constexpr double foamSpacingThickness = 1.0;
168 TGeoTube* carbonFiberLayer =
new TGeoTube(mInnerRadius, mOuterRadius, carbonFiberThickness / 2);
169 TGeoTube* foamLayer =
new TGeoTube(mInnerRadius, mOuterRadius, foamSpacingThickness / 2);
176 carbonFiberLayerVol1->SetLineColor(kGray + 2);
177 foamLayerVol->SetLineColor(kBlack);
178 foamLayerVol->SetFillColorAlpha(kBlack, 1.0);
179 carbonFiberLayerVol2->SetLineColor(kGray + 2);
181 const double zSeparation = foamSpacingThickness / 2.0 + carbonFiberThickness / 2.0;
183 motherVolume->AddNode(carbonFiberLayerVol1, 1,
new TGeoTranslation(0, 0, 0 - zSeparation));
184 motherVolume->AddNode(foamLayerVol, 1,
new TGeoTranslation(0, 0, 0));
185 motherVolume->AddNode(carbonFiberLayerVol2, 1,
new TGeoTranslation(0, 0, 0 + zSeparation));
192 TGeoTube* innerCircle =
new TGeoTube(mInnerRadius - 0.1, mInnerRadius + 0.1, 0.01);
193 TGeoTube* outerCircle =
new TGeoTube(mOuterRadius - 0.1, mOuterRadius + 0.1, 0.01);
194 TGeoTube* outerCircleEdge =
new TGeoTube(mOuterRadius + 3.3, mOuterRadius + 3.5, 0.01);
200 innerCircleVol->SetLineColor(kRed);
201 outerCircleVol->SetLineColor(kBlue);
202 outerCircleEdgeVol->SetLineColor(kBlack);
204 double z_position = mDirection ? 0.5 : -0.5;
206 motherVolume->AddNode(innerCircleVol, 1,
new TGeoTranslation(0, 0, z_position));
207 motherVolume->AddNode(outerCircleVol, 1,
new TGeoTranslation(0, 0, z_position));
208 motherVolume->AddNode(outerCircleEdgeVol, 1,
new TGeoTranslation(0, 0, z_position));
215 if (mLayerNumber < 0) {
216 LOG(fatal) <<
"Invalid layer number " << mLayerNumber <<
" for FT3 layer.";
219 LOG(info) <<
"FT3: ft3Params.layoutFT3 = " << ft3Params.layoutFT3
220 <<
" Creating Layer " << mLayerNumber <<
" at z=" << mZ
221 <<
" with direction " << mDirection;
238 TGeoTube*
layer =
new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2);
239 TGeoVolume* layerVol =
new TGeoVolume(mLayerName.c_str(),
layer, medAir);
240 layerVol->SetLineColor(kGray);
242 const int NtrapezoidalSegments = ft3Params.nTrapezoidalSegments;
244 const double dz = mChipThickness / 2;
245 const double dzSensor = mSensorThickness / 2;
247 const double dphi = 2.0 * TMath::Pi() / NtrapezoidalSegments;
248 double innerRadiusTrapezoidCorner = mInnerRadius / sin((TMath::Pi() - dphi) / 2);
250 const double rc = 0.5 * (innerRadiusTrapezoidCorner + mOuterRadius) * TMath::Cos(0.5 * dphi);
251 const double h = 0.5 * (mOuterRadius - innerRadiusTrapezoidCorner) * TMath::Cos(0.5 * dphi);
254 const double bl = innerRadiusTrapezoidCorner * TMath::Sin(0.5 * dphi);
255 const double tl = mOuterRadius * TMath::Sin(0.5 * dphi);
258 for (
int iTr = 0; iTr < NtrapezoidalSegments; ++iTr) {
260 auto trdShapeChip =
new TGeoTrap(dz,
270 TGeoVolume* trapezoidChipVolume =
new TGeoVolume(chipName.c_str(), trdShapeChip, medSi);
271 trapezoidChipVolume->SetLineColor(kCyan);
272 trapezoidChipVolume->SetTransparency(50);
275 auto trdShapeSensor =
new TGeoTrap(dzSensor,
285 TGeoVolume* trapezoidSensorVolume =
new TGeoVolume(sensName.c_str(), trdShapeSensor, medSi);
286 trapezoidSensorVolume->SetLineColor(kYellow);
289 const double zSensorInChip = (dz - dzSensor) * (mZ < 0 ? 1 : -1);
290 TGeoCombiTrans* transSens =
new TGeoCombiTrans();
291 transSens->SetTranslation(0, 0, zSensorInChip);
292 trapezoidChipVolume->AddNode(trapezoidSensorVolume, iTr, transSens);
295 auto trdShapePassive =
new TGeoTrap(dz - dzSensor,
305 TGeoVolume* trapezoidPassiveVolume =
new TGeoVolume(passiveName.c_str(), trdShapePassive, medSi);
306 trapezoidPassiveVolume->SetLineColor(kGray);
309 const double zPassiveInChip = (-dzSensor) * (mZ < 0 ? 1 : -1);
310 TGeoCombiTrans* transPassive =
new TGeoCombiTrans();
311 transPassive->SetTranslation(0, 0, zPassiveInChip);
312 trapezoidChipVolume->AddNode(trapezoidPassiveVolume, iTr, transPassive);
315 const double phi_c = (iTr + 0.5) * dphi;
316 const double phi_deg = phi_c * 180.0 / TMath::Pi();
319 const double x = rc * TMath::Cos(phi_c);
320 const double y = rc * TMath::Sin(phi_c);
321 const double z = 0.0;
324 auto rot =
new TGeoRotation();
325 rot->RotateZ(phi_deg - 90.0);
326 auto transf =
new TGeoCombiTrans(
x,
y,
z, rot);
328 layerVol->AddNode(trapezoidChipVolume, iTr, transf);
331 LOG(info) <<
"Inserting " << NtrapezoidalSegments <<
" trapezoidal segments (Rmin="
332 << mInnerRadius <<
", Rmax=" << mOuterRadius <<
", z = " << mZ <<
"cm) inside " << layerVol->GetName();
334 auto* diskRotation =
new TGeoRotation(
"TrapezoidalDiskRotation", 0, 0, 0);
335 auto* diskCombiTrans =
new TGeoCombiTrans(0, 0, mZ, diskRotation);
336 motherVolume->AddNode(layerVol, 1, diskCombiTrans);
342 TGeoTube* sensor =
new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2);
343 TGeoTube* chip =
new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2);
344 TGeoTube*
layer =
new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2);
349 TGeoVolume* sensVol =
new TGeoVolume(sensName.c_str(), sensor, medSi);
350 sensVol->SetLineColor(kYellow);
351 TGeoVolume* chipVol =
new TGeoVolume(chipName.c_str(), chip, medSi);
352 chipVol->SetLineColor(kYellow);
353 TGeoVolume* layerVol =
new TGeoVolume(mLayerName.c_str(),
layer, medAir);
354 layerVol->SetLineColor(kYellow);
356 LOG(info) <<
"Inserting " << sensVol->GetName() <<
" inside " << chipVol->GetName();
357 chipVol->AddNode(sensVol, 1,
nullptr);
359 LOG(info) <<
"Inserting " << chipVol->GetName() <<
" inside " << layerVol->GetName();
360 layerVol->AddNode(chipVol, 1,
nullptr);
363 auto* FwdDiskRotation =
new TGeoRotation(
"FwdDiskRotation", 0, 0, 180);
364 auto* FwdDiskCombiTrans =
new TGeoCombiTrans(0, 0, mZ, FwdDiskRotation);
366 LOG(info) <<
"Inserting " << layerVol->GetName() <<
" inside " << motherVolume->GetName();
367 motherVolume->AddNode(layerVol, 1, FwdDiskCombiTrans);
368 }
else if (ft3Params.layoutFT3 ==
kSegmented ||
378 TGeoVolume* layerVol =
nullptr;
380 TGeoTube*
layer =
new TGeoTube(mInnerRadius - 0.1, mOuterRadius + 0.1, 1.5);
381 layerVol =
new TGeoVolume(mLayerName.c_str(),
layer, medAir);
382 layerVol->SetLineColor(kYellow + 2);
385 module.createModule(0, mLayerNumber, mDirection, mInnerRadius, mOuterRadius, 0., "front", "rectangular", layerVol);
386 module.createModule(0, mLayerNumber, mDirection, mInnerRadius, mOuterRadius, 0., "back", "rectangular", layerVol);
389 auto* FwdDiskRotation =
new TGeoRotation(
"FwdDiskRotation", 0, 0, 180);
391 auto* FwdDiskCombiTrans =
new TGeoCombiTrans(0, 0, mZ + 0, FwdDiskRotation);
393 LOG(info) <<
"Inserting " << layerVol->GetName() <<
" (Rmin=" << mInnerRadius <<
", Rmax=" << mOuterRadius <<
", z=" << mZ <<
"cm) inside " << motherVolume->GetName();
394 motherVolume->AddNode(layerVol, 1, FwdDiskCombiTrans);
405 TGeoVolume* layerVol =
nullptr;
413 double z_layer_thickness =
423 double z_local_offset = z_layer_thickness / 2.0;
427 double innerRadiusForAirTube = mIsMiddleLayer ? mInnerRadius : mInnerRadius - 9.0;
428 double outerRadiusForAirTube = mIsMiddleLayer ? mOuterRadius + 2.5 : mOuterRadius + 3.0;
430 const double rInEnv = innerRadiusForAirTube - 0.2;
431 const double rOutEnv = outerRadiusForAirTube;
432 const double H0 = z_layer_thickness / 2;
433 if (ft3Params.addDiskEosCards) {
437 const double s = (mDirection == 1) ? 1.0 : -1.0;
438 TGeoTube* baseTube =
new TGeoTube((mLayerName +
"_base").c_str(), rInEnv, rOutEnv, H0);
439 TGeoTube* extTube =
new TGeoTube((mLayerName +
"_eosext").c_str(), rInEnv, rOutEnv, ext / 2);
440 TGeoTranslation* extTr =
new TGeoTranslation((mLayerName +
"_eosext_tr").c_str(), 0, 0, s * (H0 + ext / 2));
441 extTr->RegisterYourself();
442 TGeoCompositeShape* layerShape =
new TGeoCompositeShape(
443 (mLayerName +
"_env").c_str(),
444 Form(
"%s + %s:%s", baseTube->GetName(), extTube->GetName(), extTr->GetName()));
445 layerVol =
new TGeoVolume(mLayerName.c_str(), layerShape, medAir);
447 TGeoTube*
layer =
new TGeoTube(rInEnv, rOutEnv, H0);
448 layerVol =
new TGeoVolume(mLayerName.c_str(),
layer, medAir);
451 if (ft3Params.drawReferenceCircles) {
457 module.createModule_staveGeo(0., mLayerNumber, mDirection, mInnerRadius,
458 mOuterRadius, z_local_offset, staveConfig, layerVol);
460 auto* FwdDiskRotation =
new TGeoRotation(
"FwdDiskRotation", 0, 0, 180);
462 double z_offset_directional = mDirection ? z_local_offset : -z_local_offset;
463 auto* FwdDiskCombiTrans =
new TGeoCombiTrans(0, 0, mZ + z_offset_directional, FwdDiskRotation);
465 LOG(info) <<
"Inserting " << layerVol->GetName() <<
" (Rmin=" << mInnerRadius <<
", Rmax=" << mOuterRadius <<
", z=" << mZ <<
"cm, segmented disk with staves) inside " << motherVolume->GetName();
467 motherVolume->AddNode(layerVol, 1, FwdDiskCombiTrans);
469 LOG(fatal) <<
"Unknown FT3 layout option: " <<
static_cast<int>(ft3Params.layoutFT3);