16#include "TGeoManager.h"
17#include "TGeoVolume.h"
19#include "TGeoMatrix.h"
22#include "TGeoCompositeShape.h"
23#include "TGeoBoolNode.h"
26#include <fairlogger/Logger.h>
77 return dynamic_cast<TGeoVolumeAssembly*
>(gGeoManager->GetVolume(
composeFlexName(nbsensors).c_str()));
90 static TGeoManager* cacheOwner =
nullptr;
91 static std::map<Int_t, TGeoVolumeAssembly*> flexPerClass;
92 static std::map<Int_t, Double_t> lengthPerClass;
93 if (cacheOwner != gGeoManager) {
95 cacheOwner = gGeoManager;
97 lengthPerClass.clear();
99 auto cached = flexPerClass.find(nbsensors);
100 if (cached != flexPerClass.end()) {
101 if (
length != lengthPerClass[nbsensors]) {
102 LOG(fatal) <<
"Flex::makeFlex: the flex for " << nbsensors <<
" sensors was built with length "
103 << lengthPerClass[nbsensors] <<
" but this call asks for " <<
length
104 <<
" - the per-class flex cache assumes the length follows the sensor count";
106 return cached->second;
110 LOG(
debug) <<
"Flex::makeFlex: building the flex for " << nbsensors <<
" sensors, first asked for by ladder "
111 << mftGeom->
getHalfID(mLadderSeg->GetUniqueID()) <<
"/"
112 << mftGeom->
getDiskID(mLadderSeg->GetUniqueID()) <<
"/"
113 << mftGeom->
getLadderID(mLadderSeg->GetUniqueID());
115 auto* flex =
new TGeoVolumeAssembly(
composeFlexName(nbsensors).c_str());
143 flex->AddNode(varnishlayerIn, 1,
new TGeoTranslation(0., 0., zvarnishIn));
144 flex->AddNode(agnd_dgnd, 1,
new TGeoTranslation(0., 0., zgnd));
145 flex->AddNode(kaptonlayer, 1,
new TGeoTranslation(0., 0., zkaptonlayer));
146 flex->AddNode(lines, 1,
new TGeoTranslation(0., 0., zlines));
147 flex->AddNode(varnishlayerOut, 1,
new TGeoTranslation(0., 0., zvarnishOut));
151 flexPerClass[nbsensors] = flex;
152 lengthPerClass[nbsensors] =
length;
162 TGeoVolumeAssembly* electric[200];
167 auto* rotation =
new TGeoRotation(
"rotation", 90., 0., 0.);
168 auto* rotationpi =
new TGeoRotation(
"rotationpi", 180., 0., 0.);
169 auto* transformation0 =
172 auto* transformation1 =
176 for (Int_t
id = 0;
id < 2;
id++) {
179 flex->AddNode(electric[0], 1, transformation0);
180 flex->AddNode(electric[1], 2, transformation1);
184 for (Int_t
id = 0;
id < 4 * nbsensors;
id++) {
185 electric[
id + total] =
188 for (Int_t
id = 0;
id < 2 * nbsensors;
id++) {
189 flex->AddNode(electric[
id + total],
id + 1000,
193 flex->AddNode(electric[
id + total + 2 * nbsensors],
id + 2000,
197 total = total + 4 * nbsensors;
200 for (Int_t
id = 0;
id < 3;
id++) {
201 electric[
id + total] =
204 for (Int_t
id = 0;
id < 3;
id++) {
205 flex->AddNode(electric[
id + total],
id + 3000,
230 Double_t interspace = 0.1;
231 Double_t step = 0.04;
232 Double_t boxthickness = 0.05;
237 static TGeoManager* connectorCacheOwner =
nullptr;
238 static TGeoVolume* connectord =
nullptr;
239 static TGeoVolume* boxconnectord =
nullptr;
240 if (connectorCacheOwner != gGeoManager) {
242 connectorCacheOwner = gGeoManager;
243 connectord =
nullptr;
244 boxconnectord =
nullptr;
248 TGeoMedium* kMedAlu = gGeoManager->GetMedium(
"MFT_Alu$");
249 TGeoMedium* kMedPeek = gGeoManager->GetMedium(
"MFT_PEEK$");
258 auto* connecto =
new TGeoSubtraction(connect, remov,
nullptr,
t1);
259 auto* connector =
new TGeoCompositeShape(
"connector", connecto);
260 connectord =
new TGeoVolume(
"connectord", connector, kMedAlu);
261 connectord->SetVisibility(kTRUE);
262 connectord->SetLineColor(kRed);
263 connectord->SetLineWidth(1);
264 connectord->SetFillColor(connectord->GetLineColor());
265 connectord->SetFillStyle(4000);
271 auto* boxconnecto =
new TGeoSubtraction(boxconnect, boxremov,
nullptr,
nullptr);
272 auto* boxconnector =
new TGeoCompositeShape(
"boxconnector", boxconnecto);
273 boxconnectord =
new TGeoVolume(
"boxconnectord", boxconnector, kMedPeek);
276 for (Int_t
id = 0;
id < 37;
id++) {
278 connectord,
id + total,
282 auto* transformationpi =
286 flex->AddNode(connectord,
id + total + 37, transformationpi);
289 flex->AddNode(boxconnectord, 1,
296TGeoVolumeAssembly* Flex::makeElectricComponent(Double_t dx, Double_t dy, Double_t dz, Int_t
id)
303 static TGeoManager* cacheOwner =
nullptr;
304 static TGeoVolumeAssembly* X7R0402 =
nullptr;
305 static Double_t sCachedDx = 0., sCachedDy = 0., sCachedDz = 0.;
306 if (cacheOwner != gGeoManager) {
308 cacheOwner = gGeoManager;
312 if (dx != sCachedDx || dy != sCachedDy || dz != sCachedDz) {
313 LOG(fatal) <<
"Flex::makeElectricComponent: cached X7R0402 assembly was built with "
314 "different dx,dy,dz than this call - the single-assembly cache assumes "
315 "identical dimensions at every call site";
323 TGeoMedium* kmedX7R = gGeoManager->GetMedium(
"MFT_X7Rcapacitors$");
324 TGeoMedium* kmedX7Rw = gGeoManager->GetMedium(
"MFT_X7Rweld$");
326 auto* capacit =
new TGeoBBox(
"capacitor", dx / 2, dy / 2, dz / 2);
327 auto* weld =
new TGeoBBox(
"weld", (dx / 4) / 2, dy / 2, (dz / 2) / 2);
329 auto* capacitor =
new TGeoVolume(
"capacitor", capacit, kmedX7R);
330 auto* welding0 =
new TGeoVolume(
"welding0", weld, kmedX7Rw);
331 auto* welding1 =
new TGeoVolume(
"welding1", weld, kmedX7Rw);
333 capacitor->SetVisibility(kTRUE);
334 capacitor->SetLineColor(kRed);
335 capacitor->SetLineWidth(1);
336 capacitor->SetFillColor(capacitor->GetLineColor());
337 capacitor->SetFillStyle(4000);
339 welding0->SetVisibility(kTRUE);
340 welding0->SetLineColor(kGray);
341 welding0->SetLineWidth(1);
342 welding0->SetFillColor(welding0->GetLineColor());
343 welding0->SetFillStyle(4000);
345 welding1->SetVisibility(kTRUE);
346 welding1->SetLineColor(kGray);
347 welding1->SetLineWidth(1);
348 welding1->SetFillColor(welding1->GetLineColor());
349 welding1->SetFillStyle(4000);
351 X7R0402 =
new TGeoVolumeAssembly(
"X7R0402");
352 X7R0402->AddNode(capacitor, 1,
new TGeoTranslation(0., 0., 0.));
353 X7R0402->AddNode(welding0, 1,
new TGeoTranslation(dx / 2 + (dx / 4) / 2, 0., (dz / 2) / 2));
354 X7R0402->AddNode(welding1, 1,
new TGeoTranslation(-dx / 2 - (dx / 4) / 2, 0., (dz / 2) / 2));
355 X7R0402->SetVisibility(kTRUE);
379TGeoVolume* Flex::makeLines(Int_t nbsensors, Double_t
length, Double_t widthflex, Double_t thickness)
386 auto* layer_def =
new TGeoBBox(
"layer_def",
length / 2, widthflex / 2, thickness / 2);
393 auto* layerholesub1 =
new TGeoSubtraction(layer_def, hole1,
nullptr,
t1);
394 auto* layerhole1 =
new TGeoCompositeShape(
"layerhole1", layerholesub1);
397 auto* layerholesub2 =
new TGeoSubtraction(layerhole1, hole2,
nullptr, t2);
398 auto*
layer =
new TGeoCompositeShape(
"layerhole2", layerholesub2);
401 TGeoTranslation *t[6], *ts[15], *tvdd, *tl[2];
402 TGeoSubtraction* layerl[25];
403 TGeoCompositeShape* layern[25];
405 Int_t kTotalLinesNb = 0;
406 Int_t kTotalLinesNb1, kTotalLinesNb2;
407 Double_t length_line;
414 layerl[0] =
new TGeoSubtraction(
layer, line[0],
nullptr, t[0]);
415 layern[0] =
new TGeoCompositeShape(Form(
"layer%d", 0), layerl[0]);
419 for (
int iline = istart; iline < istop; iline++) {
426 layerl[iline] =
new TGeoSubtraction(layern[iline - 1], line[iline],
nullptr, t[iline]);
427 layern[iline] =
new TGeoCompositeShape(Form(
"layer%d", iline), layerl[iline]);
432 istart = kTotalLinesNb + 1;
433 istop = 6 + 3 * nbsensors;
434 for (
int iline = istart; iline < istop; iline++) {
442 layerl[iline] =
new TGeoSubtraction(layern[iline - 1], line[iline],
nullptr, ts[iline - 6]);
443 layern[iline] =
new TGeoCompositeShape(Form(
"layer%d", iline), layerl[iline]);
452 layerl[kTotalLinesNb] =
new TGeoSubtraction(layern[kTotalLinesNb - 1], line[kTotalLinesNb],
nullptr, tvdd);
453 layern[kTotalLinesNb] =
new TGeoCompositeShape(Form(
"layer%d", kTotalLinesNb), layerl[kTotalLinesNb]);
457 istart = kTotalLinesNb;
458 istop = kTotalLinesNb + 2;
459 for (
int iline = istart; iline < istop; iline++) {
466 layerl[iline] =
new TGeoSubtraction(layern[iline - 1], line[iline],
nullptr, tl[iline - istart]);
467 layern[iline] =
new TGeoCompositeShape(Form(
"layer%d", iline), layerl[iline]);
471 TGeoMedium* kMedAlu = gGeoManager->GetMedium(
"MFT_Alu$");
474 layern[kTotalLinesNb - 1], kMedAlu);
475 lineslayer->SetVisibility(
true);
476 lineslayer->SetLineColor(kBlue);
482TGeoVolume* Flex::makeAGNDandDGND(Int_t nbsensors, Double_t
length, Double_t widthflex, Double_t thickness)
491 auto* layerholesub1 =
new TGeoSubtraction(
layer, hole1,
nullptr,
t1);
492 auto* layerhole1 =
new TGeoCompositeShape(
"layerhole1", layerholesub1);
495 auto* layerholesub2 =
new TGeoSubtraction(layerhole1, hole2,
nullptr, t2);
496 auto* layerhole2 =
new TGeoCompositeShape(
"layerhole2", layerholesub2);
500 TGeoTranslation* t[3];
501 TGeoCompositeShape* layern[3];
502 TGeoSubtraction* layerl[3];
503 Double_t length_line;
511 layerl[0] =
new TGeoSubtraction(layerhole2, line[0],
nullptr, t[0]);
512 layern[0] =
new TGeoCompositeShape(Form(
"layer%d", 0), layerl[0]);
518 layerl[1] =
new TGeoSubtraction(layern[0], line[1],
nullptr, t[1]);
519 layern[1] =
new TGeoCompositeShape(Form(
"layer%d", 1), layerl[1]);
525 layerl[2] =
new TGeoSubtraction(layern[1], line[2],
nullptr, t[2]);
526 layern[2] =
new TGeoCompositeShape(Form(
"layer%d", 2), layerl[2]);
530 TGeoMedium* kMedAlu = gGeoManager->GetMedium(
"MFT_Alu$");
531 auto* alulayer =
new TGeoVolume(
composeFlexLayerName(
"alulayer", nbsensors).c_str(), layern[2], kMedAlu);
532 alulayer->SetVisibility(
true);
533 alulayer->SetLineColor(kBlue);
539TGeoVolume* Flex::makeKapton(Int_t nbsensors, Double_t
length, Double_t widthflex, Double_t thickness)
548 auto* layerholesub1 =
new TGeoSubtraction(
layer, hole1,
nullptr,
t1);
549 auto* layerhole1 =
new TGeoCompositeShape(
"layerhole1", layerholesub1);
552 auto* layerholesub2 =
new TGeoSubtraction(layerhole1, hole2,
nullptr, t2);
553 auto* layerhole2 =
new TGeoCompositeShape(
"layerhole2", layerholesub2);
555 TGeoMedium* kMedKapton = gGeoManager->GetMedium(
"MFT_Kapton$");
558 kaptonlayer->SetVisibility(
true);
559 kaptonlayer->SetLineColor(kYellow);
565TGeoVolume* Flex::makeVarnish(Int_t nbsensors, Double_t
length, Double_t widthflex, Double_t thickness, Int_t iflag)
574 auto* layerholesub1 =
new TGeoSubtraction(
layer, hole1,
nullptr,
t1);
575 auto* layerhole1 =
new TGeoCompositeShape(
"layerhole1", layerholesub1);
578 auto* layerholesub2 =
new TGeoSubtraction(layerhole1, hole2,
nullptr, t2);
579 auto* layerhole2 =
new TGeoCompositeShape(
"layerhole2", layerholesub2);
581 TGeoMedium* kMedVarnish = gGeoManager->GetMedium(
"MFT_Epoxy$");
582 TGeoMaterial* kMatVarnish = kMedVarnish->GetMaterial();
585 new TGeoVolume(
composeFlexLayerName(
"varnishlayer", nbsensors, iflag).c_str(), layerhole2, kMedVarnish);
586 varnishlayer->SetVisibility(
true);
587 varnishlayer->SetLineColor(kGreen - 1);
Chip (sensor) segmentation description.
Flex (Printed Cabled Board) class for ALICE MFT upgrade.
Class handling both virtual segmentation and real volumes.
Description of the virtual segmentation of a ladder.
Class building the Ladder geometry.
Definition of the SegmentationAlpide class.
static constexpr float SensorSizeCols
static std::string composeFlexName(Int_t nbsensors)
void makeElectricComponents(TGeoVolumeAssembly *flex, Int_t nbsensors, Double_t length, Double_t zvarnish)
static TGeoVolumeAssembly * getFlexVolume(Int_t nbsensors)
static std::string composeFlexLayerName(const char *layer, Int_t nbsensors, Int_t iflag=-1)
TGeoVolumeAssembly * makeFlex(Int_t nbsensors, Double_t length)
static const Double_t sCapacitorDy
static const Double_t sHoleShift1
static const Double_t sEpsilon
static const Double_t sVarnishThickness
static const Double_t sShiftDDGNDline
Int_t getDiskID(UInt_t uniqueID) const
Returns Half-Disk ID based on Unique ID provided.
static const Double_t sLineWidth
static const Double_t sConnectorLength
Int_t getLadderID(UInt_t uniqueID) const
Returns Ladder ID based on Unique ID provided.
static const Double_t sConnectorOffset
Int_t getHalfID(UInt_t uniqueID) const
Returns Half-MFT ID based on Unique ID provided.
static const Double_t sGlueThickness
static const Double_t sKaptonThickness
static Geometry * instance()
Singleton access.
static const Double_t sCapacitorDz
static const Double_t sConnectorWidth
static const Double_t sClearance
static const Double_t sConnectorHeight
static const Double_t sFlexHeight
Flex Height.
static const Double_t sConnectorThickness
static const Double_t sRadiusHole1
static const Double_t sShiftline
static const Double_t sRadiusHole2
static const Double_t sHoleShift2
static const Double_t sCapacitorDx
static const Double_t sAluThickness
GLuint const GLchar * name
GLuint GLsizei GLsizei * length
GLenum GLuint GLint GLint layer
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
int32_t const char int32_t line
std::string to_string(gsl::span< T, Size > span)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"