17#include <TGeoManager.h>
18#include <TGeoMedium.h>
21#include <TGeoMatrix.h>
22#include <TGeoCompositeShape.h>
37 return (
x *
x < radius * radius) ? std::sqrt(radius * radius -
x *
x) : 0;
41 double x_left,
double x_right,
double Rin,
double Rout)
61 }
else if (x_left < 0) {
66 }
else if (x_left < Rin) {
75 return {min_y_abs, max_y_abs};
94 std::pair<double, double>& absAllowedYRange)
102 double max_sensor_y_abs = std::min(absAllowedYRange.second, y_ranges.first.second);
106 if (!y_positions.first.empty()) {
109 }
else if (absAllowedYRange.first > 0) {
111 y_top = std::max(absAllowedYRange.first, y_ranges.first.first);
114 y_top = y_ranges.first.first;
117 while ((y_top + sensorStackHeight) <= max_sensor_y_abs) {
118 y_positions.first.emplace_back(y_top, kSensorStack);
119 y_top += sensorAbsStackYShift;
125 if (!y_positions.second.empty()) {
129 }
else if (absAllowedYRange.first > 0) {
131 y_bottom = std::min(-absAllowedYRange.first, y_ranges.second.first);
134 y_bottom = y_ranges.second.first;
137 while ((y_bottom - sensorStackHeight) >= -max_sensor_y_abs) {
138 y_positions.second.emplace_back(y_bottom, kSensorStack);
139 y_bottom -= sensorAbsStackYShift;
157PositionTypes FT3Module::fill_stave_exact(
const std::vector<Constants::StaveFill>& fills)
160 for (
const auto& fill : fills) {
161 double y_bottom = fill.yStart;
162 for (
unsigned kSensorStack : fill.stackHeights) {
163 y_positions.emplace_back(y_bottom, kSensorStack);
196 std::array<double, 3> xv_inner, xv_outer, zv_inner, zv_outer;
200 zv_outer[0] = (direction == 1) ? -H
207 xv_outer[2] = -xv_outer[1];
211 xv_inner[0] = xv_outer[0];
213 zv_inner[0] = (direction == 1) ? zv_outer[0] + z_shift_inner
214 : zv_outer[0] - z_shift_inner;
216 zv_inner[1] = (direction == 1) ? zv_outer[1] - d
219 xv_inner[1] = xv_outer[1] - x_shift_abs;
221 zv_inner[2] = zv_inner[1];
222 xv_inner[2] = -xv_inner[1];
224 return {xv_outer, zv_outer, xv_inner, zv_inner};
231void FT3Module::addStaveVolume(
232 TGeoVolume* motherVolume, std::string volumeName,
int direction,
233 unsigned* volume_count,
double staveLength,
234 std::array<std::array<double, 3>, 4> staveTriangles,
235 std::pair<double, double>& absAllowedYRange,
236 double x_mid,
double y_mid,
double z_stave_shift_forward)
239 if (absAllowedYRange.first < 0 || absAllowedYRange.second < 0 ||
240 absAllowedYRange.first >= absAllowedYRange.second) {
241 LOG(error) <<
"Invalid allowed y range in addStaveVolume(): ("
242 << absAllowedYRange.first <<
", " << absAllowedYRange.second
243 <<
"). Both values must be non-negative and the first "
244 <<
"value must be less than the second value.";
248 double y_lower = y_mid - staveLength / 2;
249 double y_upper = y_mid + staveLength / 2;
250 bool splitStave =
false;
252 y_lower = std::max(y_lower, absAllowedYRange.first);
253 y_upper = std::min(y_upper, absAllowedYRange.second);
254 }
else if (y_upper < 0) {
255 y_lower = std::max(y_lower, -absAllowedYRange.second);
256 y_upper = std::min(y_upper, -absAllowedYRange.first);
259 if (absAllowedYRange.first > 0) {
262 y_lower = absAllowedYRange.first;
265 y_lower = std::max(y_lower, -absAllowedYRange.second);
267 y_upper = std::min(y_upper, absAllowedYRange.second);
269 double staveLengthToUse = y_upper - y_lower;
277 TGeoXtru* staveFull =
new TGeoXtru(2);
278 staveFull->SetName((volumeName +
"_Xtru_outer").c_str());
279 staveFull->DefinePolygon(3, staveTriangles[0].
data(), staveTriangles[1].
data());
280 staveFull->DefineSection(0, 0);
281 staveFull->DefineSection(1, staveLengthToUse);
283 TGeoXtru* staveInner =
new TGeoXtru(2);
284 staveInner->SetName((volumeName +
"_Xtru_inner").c_str());
285 staveInner->DefinePolygon(3, staveTriangles[2].
data(), staveTriangles[3].
data());
286 staveInner->DefineSection(0, 0);
287 staveInner->DefineSection(1, staveLengthToUse);
289 TGeoCompositeShape* staveShape =
new TGeoCompositeShape(
290 (volumeName +
"_shape").c_str(),
291 Form(
"%s - %s", staveFull->GetName(), staveInner->GetName()));
292 TGeoVolume* staveVolume =
new TGeoVolume(
293 (volumeName).c_str(),
295 getMedium(Materials::MaterialID::CarbonFiber));
296 const int carbonFiberColor =
Materials::materials.at(Materials::MaterialID::CarbonFiber).colour;
297 staveVolume->SetLineColor(carbonFiberColor);
298 staveVolume->SetFillColorAlpha(carbonFiberColor, 0.4);
300 TGeoRotation* rot =
new TGeoRotation();
314 double z_shift = (direction == 1) ? z_stave_shift_forward : -z_stave_shift_forward;
315 TGeoCombiTrans* combiTrans =
316 new TGeoCombiTrans(x_mid, y_lower, z_shift, rot);
317 motherVolume->AddNode(staveVolume,
324 TGeoCombiTrans* combiTransSplit =
325 new TGeoCombiTrans(x_mid, -y_upper, z_shift, rot);
326 motherVolume->AddNode(staveVolume,
338void FT3Module::addDetectorVolume(
339 TGeoVolume* motherVolume, std::string volumeName,
int color, TGeoMedium* med,
340 unsigned volume_count,
double x_mid,
double y_mid,
double z_mid,
341 double x_half_length,
double y_half_length,
double z_half_length,
double rotX)
343 TGeoManager* geoManager = gGeoManager;
344 TGeoVolume* volume = geoManager->MakeBox(volumeName.c_str(), med, x_half_length,
345 y_half_length, z_half_length);
346 volume->SetLineColor(
color);
347 volume->SetFillColorAlpha(
color, 0.4);
349 motherVolume->AddNode(
358 motherVolume->AddNode(
361 new TGeoCombiTrans(
"",
365 new TGeoRotation(
"", 0., rotX, 0.))
374void FT3Module::add2x1GlueVolume(
375 TGeoVolume* motherVolume,
int layerNumber,
int direction,
unsigned stave_idx,
376 unsigned volume_count,
double x_mid,
double y_mid,
double z_mid,
377 std::string element_glued_to)
382 getMedium(Materials::MaterialID::Epoxy), volume_count,
391void FT3Module::add2x1CopperVolume(
392 TGeoVolume* motherVolume,
int layerNumber,
int direction,
unsigned stave_idx,
393 unsigned volume_count,
double x_mid,
double y_mid,
double z_mid)
398 getMedium(Materials::MaterialID::Copper), volume_count,
407void FT3Module::add2x1KaptonVolume(
408 TGeoVolume* motherVolume,
int layerNumber,
int direction,
unsigned stave_idx,
409 unsigned volume_count,
double x_mid,
double y_mid,
double z_mid)
414 getMedium(Materials::MaterialID::Kapton), volume_count,
437void FT3Module::addSingleSensorVolume(
438 TGeoVolume* motherVolume,
int layerNumber,
int direction,
unsigned stave_idx,
439 unsigned volume_count,
double active_x_mid,
double y_mid,
double z_mid,
443 TGeoManager* geoManager = gGeoManager;
444 TGeoMedium* siliconMed =
getMedium(Materials::MaterialID::Silicon);
449 motherVolume, sensor_name,
Materials::materials.at(Materials::MaterialID::Silicon).colour, siliconMed,
450 volume_count, active_x_mid, y_mid, z_mid,
461 volume_count, inactive_x_mid, y_mid, z_mid,
471 double& y_midpoint,
bool& mirrorStaveAroundX)
477 y_midpoint = y_midpoint_it->second.first;
478 mirrorStaveAroundX = y_midpoint_it->second.second;
489void FT3Module::addEndOfStaveCard(
490 TGeoVolume* motherVolume,
const std::string&
name,
int direction,
491 unsigned volume_count,
double x_mid,
double y_tip,
double z_sensor,
492 bool isML,
double cuThickness)
495 if (cuThickness *
c.nCopperLayers >=
c.thickness) {
496 LOG(fatal) <<
"FT3 disk EoS card: Cu " << cuThickness <<
" cm x " <<
c.nCopperLayers
497 <<
" planes does not fit in the " <<
c.thickness <<
" cm card";
501 TGeoVolume* cardVol = gGeoManager->MakeBox(
name.c_str(),
getMedium(Materials::MaterialID::FR4),
502 c.width / 2,
c.thickness / 2,
c.length / 2);
503 cardVol->SetLineColor(kGreen + 3);
506 TGeoVolume* planeVol = gGeoManager->MakeBox((
name +
"_Cu").c_str(),
getMedium(Materials::MaterialID::Copper),
507 c.width / 2, cuThickness / 2,
c.length / 2);
508 planeVol->SetLineColor(kOrange + 7);
509 const double span =
c.thickness - cuThickness;
510 for (
int i = 0;
i <
c.nCopperLayers; ++
i) {
511 const double y = (
c.nCopperLayers > 1) ? -span / 2 +
i * span / (
c.nCopperLayers - 1) : 0.;
512 cardVol->AddNode(planeVol,
i,
new TGeoTranslation(0,
y, 0));
519 const double s = (direction == 1) ? 1.0 : -1.0;
520 const double zCard = z_sensor +
s * (
c.zGap +
c.length / 2);
521 const double yClear = 0.05;
522 const double yCard = y_tip + (y_tip >= 0 ? 1.0 : -1.0) * (
c.thickness / 2 + yClear);
523 motherVolume->AddNode(cardVol, volume_count,
new TGeoTranslation(x_mid, yCard, zCard));
530void FT3Module::add_stave_volumes(
531 TGeoVolume* motherVolume,
int layerNumber,
int direction,
533 const std::array<std::array<double, 3>, 4>& staveTriangles,
534 double z_offset_to_carbon_face, std::pair<double, double>& absAllowedYRange,
535 double y_midpoint,
bool mirrorStaveAroundX,
unsigned* staveVolumeCount)
539 double z_stave_shift_forward =
540 -z_offset_to_carbon_face + z_stave_shift_abs;
541 std::string stave_volume_name =
546 motherVolume, stave_volume_name, direction, staveVolumeCount,
547 staveConfig.
y_lengths[i_stave], staveTriangles, absAllowedYRange,
548 staveConfig.
x_midpoints[i_stave], y_midpoint, z_stave_shift_forward);
550 if (mirrorStaveAroundX) {
552 motherVolume, stave_volume_name +
"_mirrored", direction, staveVolumeCount,
553 staveConfig.
y_lengths[i_stave], staveTriangles, absAllowedYRange,
554 staveConfig.
x_midpoints[i_stave], -y_midpoint, z_stave_shift_forward);
565 if (ft3Params.addDiskEosCards) {
566 const bool isML = staveConfig.
isML;
567 const double cuT = isML ? ft3Params.ft3EosCardCuThicknessML : ft3Params.ft3EosCardCuThicknessOT;
571 const double yTip = std::min(y_midpoint + staveConfig.
y_lengths[i_stave] / 2,
572 absAllowedYRange.second);
576 const double z_offset_to_silicon = z_offset_to_carbon_face +
580 const double zOffMult = (direction == 1) ? -1.0 : 1.0;
581 double zStaveShiftSensors = 0.0;
586 const double zSensor = z_offset_to_silicon * zOffMult + zStaveShiftSensors;
587 const std::string cardBase =
"FT3_EOSdiskCard_" +
std::to_string(direction) +
"_" +
589 addEndOfStaveCard(motherVolume, cardBase +
"_pos", direction, (*staveVolumeCount)++,
590 staveConfig.
x_midpoints[i_stave], +yTip, zSensor, isML, cuT);
592 if (mirrorStaveAroundX) {
593 addEndOfStaveCard(motherVolume, cardBase +
"_neg", direction, (*staveVolumeCount)++,
594 staveConfig.
x_midpoints[i_stave], -yTip, zSensor, isML, cuT);
609void FT3Module::build_staves_exact(
610 TGeoVolume* motherVolume,
int layerNumber,
int direction,
612 const std::array<std::array<double, 3>, 4>& staveTriangles,
613 double z_offset_to_carbon_face,
614 std::vector<PosNegPositionTypes>& y_positionsPosNeg,
615 unsigned& staveVolumeCount)
620 std::map<unsigned, unsigned> nSensorStackTotal;
621 for (
unsigned i_stave = 0; i_stave < staveConfig.
x_midpoints.size(); i_stave++) {
625 double y_midpoint = 0.;
626 bool mirrorStaveAroundX =
false;
630 std::pair<double, double> absAllowedYRange = {0., std::numeric_limits<double>::max()};
632 add_stave_volumes(motherVolume, layerNumber, direction, staveConfig, i_stave,
633 staveTriangles, z_offset_to_carbon_face, absAllowedYRange,
634 y_midpoint, mirrorStaveAroundX, &staveVolumeCount);
642 y_positionsPosNeg.emplace_back(fill_stave_exact(staveConfig.
exactStaveFills[i_stave]),
645 std::map<unsigned, unsigned> nSensorStackCount;
646 for (
const auto& [y_bottom, kSensorStack] : y_positionsPosNeg.back().
first) {
647 nSensorStackCount[kSensorStack]++;
648 nSensorStackTotal[kSensorStack]++;
650 std::string moduleDebugStr =
"Module size counts for layer " +
std::to_string(layerNumber) +
" in direction " +
std::to_string(direction) +
":\n";
651 for (
const auto& [kSensorStack, nModules] : nSensorStackCount) {
656 std::string totalModuleInfoStr =
657 "Total module size counts for layer " +
std::to_string(layerNumber) +
659 for (
const auto& [kSensorStack, nModules] : nSensorStackTotal) {
662 LOG(info) << totalModuleInfoStr;
673void FT3Module::build_staves_greedy(
674 TGeoVolume* motherVolume,
int layerNumber,
int direction,
double Rin,
double Rout,
676 const std::array<std::array<double, 3>, 4>& staveTriangles,
677 double z_offset_to_carbon_face,
678 std::vector<PosNegPositionTypes>& y_positionsPosNeg,
unsigned& staveVolumeCount)
683 std::vector<std::vector<unsigned>> nSensorStackCountPerStave(
687 for (
unsigned i_stave = 0; i_stave < staveConfig.
x_midpoints.size(); i_stave++) {
691 double y_midpoint = 0.;
692 bool mirrorStaveAroundX =
false;
694 double stave_half_length = staveConfig.
y_lengths[i_stave] / 2;
703 y_ranges.first = {y_midpoint - stave_half_length, y_midpoint + stave_half_length};
704 y_ranges.second = {-y_midpoint + stave_half_length, -y_midpoint - stave_half_length};
708 double tolerance_inner, tolerance_outer;
709 if (staveConfig.
isML) {
710 tolerance_inner = ft3Params.staveTolMLInner;
711 tolerance_outer = ft3Params.staveTolMLOuter;
713 tolerance_inner = ft3Params.staveTolOTInner;
714 tolerance_outer = ft3Params.staveTolOTOuter;
735 std::pair<double, double> absAllowedYRange =
744 absAllowedYRange.first -= tolerance_inner;
745 absAllowedYRange.second += tolerance_outer;
747 if (absAllowedYRange.first < 0) {
748 absAllowedYRange.first = 0;
750 if (absAllowedYRange.second <= 0) {
751 LOG(warning) <<
"For stave " << i_stave <<
" in layer " << layerNumber
752 <<
" with direction " << direction <<
": no space to place sensors after applying tolerances, skipping stave.";
757 add_stave_volumes(motherVolume, layerNumber, direction, staveConfig, i_stave,
758 staveTriangles, z_offset_to_carbon_face, absAllowedYRange,
759 y_midpoint, mirrorStaveAroundX, &staveVolumeCount);
763 unsigned nModulesCurr = y_positionsPosNeg.back().first.size() + y_positionsPosNeg.back().second.size();
765 y_ranges, absAllowedYRange);
766 unsigned nModulesAdded = y_positionsPosNeg.back().first.size() + y_positionsPosNeg.back().second.size() - nModulesCurr;
767 nSensorStackCountPerStave[i_stave][i_kSens] = nModulesAdded;
768 nSensorStackTotal[i_kSens] += nModulesAdded;
770 std::string moduleDebugStr =
"Module size counts for layer " +
std::to_string(layerNumber) +
" in direction " +
std::to_string(direction) +
":\n";
776 std::string totalModuleInfoStr =
777 "Total module size counts for layer " +
std::to_string(layerNumber) +
782 LOG(info) << totalModuleInfoStr;
785void FT3Module::create_layout_staveGeo(
double mZ,
int layerNumber,
int direction,
786 double Rin,
double Rout,
double z_offset_local,
788 TGeoVolume* motherVolume)
790 LOG(
debug) <<
"FT3Module: create_layout_staveGeo - Direction "
791 << direction <<
", Layer " << layerNumber;
815 double totalSensorMaterialThickness =
818 double z_offset_to_carbon_face = z_offset_local - totalSensorMaterialThickness - 0.1;
819 double z_offset_to_glue_Ka =
821 double z_offset_to_kapton =
824 double z_offset_to_copper =
827 double z_offset_to_glue_Si =
830 double z_offset_to_silicon =
836 std::vector<PosNegPositionTypes> y_positionsPosNeg;
839 unsigned staveVolumeCount = 0;
849 if (ft3Params.useExactStavePlacement && !staveConfig.
exactStaveFills.empty()) {
850 build_staves_exact(motherVolume, layerNumber, direction, staveConfig, staveTriangles,
851 z_offset_to_carbon_face, y_positionsPosNeg, staveVolumeCount);
853 build_staves_greedy(motherVolume, layerNumber, direction, Rin, Rout, staveConfig,
854 staveTriangles, z_offset_to_carbon_face, y_positionsPosNeg,
859 for (
unsigned i_stave = 0; i_stave < staveConfig.
x_midpoints.size(); i_stave++) {
872 if (direction == 1) {
877 int z_offset_multiplier = (direction == 1) ? -1 : 1;
880 double z_stave_shift = 0;
887 unsigned sensor_count = 0;
888 for (
int y_sign = -1; y_sign < 2; y_sign += 2) {
892 const auto& positions = (y_sign == 1) ? y_positionsPosNeg[i_stave].
first
893 : y_positionsPosNeg[i_stave].second;
895 for (
unsigned i_y_pos = 0; i_y_pos < positions.size(); i_y_pos++) {
897 for (
unsigned i_sens = 0; i_sens < positions[i_y_pos].second; i_sens++) {
901 double z_mid = z_offset_to_silicon * z_offset_multiplier + z_stave_shift;
902 addSingleSensorVolume(
903 motherVolume, layerNumber, direction, i_stave, sensor_count,
907 addSingleSensorVolume(
908 motherVolume, layerNumber, direction, i_stave, sensor_count + 1,
910 y_mid, z_mid,
false);
912 z_mid = z_offset_to_glue_Si * z_offset_multiplier + z_stave_shift;
914 motherVolume, layerNumber, direction, i_stave, sensor_count,
915 x_mid, y_mid, z_mid,
"SiCu");
917 z_mid = z_offset_to_copper * z_offset_multiplier + z_stave_shift;
919 motherVolume, layerNumber, direction, i_stave, sensor_count,
920 x_mid, y_mid, z_mid);
922 z_mid = z_offset_to_kapton * z_offset_multiplier + z_stave_shift;
924 motherVolume, layerNumber, direction, i_stave, sensor_count,
925 x_mid, y_mid, z_mid);
927 z_mid = z_offset_to_glue_Ka * z_offset_multiplier + z_stave_shift;
929 motherVolume, layerNumber, direction, i_stave, sensor_count,
930 x_mid, y_mid, z_mid,
"CarbonKapton");
940void FT3Module::create_layout(
double mZ,
int layerNumber,
int direction,
double Rin,
double Rout,
double overlap,
const std::string&
face,
const std::string& layout_type, TGeoVolume* motherVolume)
943 LOG(
debug) <<
"FT3Module: create_layout - Layer " << layerNumber <<
", Direction " << direction <<
", Face " <<
face;
944 TGeoManager* geoManager = gGeoManager;
946 TGeoMedium* siliconMed =
getMedium(Materials::MaterialID::Silicon);
947 TGeoMedium* copperMed =
getMedium(Materials::MaterialID::Copper);
948 TGeoMedium* kaptonMed =
getMedium(Materials::MaterialID::Kapton);
949 TGeoMedium* epoxyMed =
getMedium(Materials::MaterialID::Epoxy);
950 TGeoMedium* AluminumMed =
getMedium(Materials::MaterialID::Aluminum);
957 double sensor_width = 5.0;
958 double sensor_height = 9.6;
963 double silicon_thickness = 0.01;
964 double copper_thickness = 0.006;
965 double kapton_thickness = 0.03;
966 double epoxy_thickness = 0.0012;
968 double carbonFiberThickness = 0.01;
970 double foamSpacingThickness = 1.0;
977 double z_offset = (
face ==
"front") ? -foamSpacingThickness / 2.0 - carbonFiberThickness : foamSpacingThickness / 2.0 + carbonFiberThickness;
980 if (sensor_height == 3.2 && sensor_width == 2.5) {
983 }
else if (sensor_height == 19.2 && sensor_width == 5) {
987 x_offset = sensor_width / 2;
988 y_offset = sensor_height / 2;
991 double x_condition_min = 0;
992 double x_condition_max = 0;
993 double offset_Rin_lower = 0;
994 double offset_Rin_upper = 0;
995 bool adjust_bottom_y_pos =
false;
996 bool adjust_bottom_y_neg =
false;
997 double x_adjust_bottom_y_pos = 0;
998 double bottom_y_pos_value = 0;
999 double bottom_y_neg_value = 0;
1001 double Rin_offset = (sensor_height == 19.2) ? 1 : 0;
1002 double Rout_offset = (sensor_height == 19.2) ? 1 : 0;
1004 if (Rin == 7 && sensor_height == 9.6 && sensor_width == 5) {
1005 x_condition_min = -Rin - 2;
1006 x_condition_max = Rin;
1008 adjust_bottom_y_pos =
true;
1009 adjust_bottom_y_neg =
true;
1010 x_adjust_bottom_y_pos = 3.5;
1011 bottom_y_pos_value = 3.5;
1012 bottom_y_neg_value = -3.5;
1013 }
else if (Rin == 5 && sensor_height == 9.6 && sensor_width == 5) {
1014 x_condition_min = -Rin - 6;
1015 x_condition_max = Rin;
1016 adjust_bottom_y_pos =
true;
1017 adjust_bottom_y_neg =
true;
1018 x_adjust_bottom_y_pos = 3.5;
1019 bottom_y_pos_value = 3.5;
1020 bottom_y_neg_value = -3.5;
1021 }
else if ((Rin == 5 || Rin == 7) && sensor_height == 19.2) {
1022 x_condition_min = -Rin - 3;
1023 x_condition_max = Rin - 0.2;
1025 adjust_bottom_y_pos =
false;
1026 adjust_bottom_y_neg =
false;
1027 }
else if (Rin == 5 && sensor_height == 3.2) {
1028 x_condition_min = -(Rin + 2.6);
1029 x_condition_max = Rin + 1.5;
1030 adjust_bottom_y_pos =
true;
1031 adjust_bottom_y_neg =
true;
1032 x_adjust_bottom_y_pos = 3.5;
1033 bottom_y_pos_value = 3.5;
1034 bottom_y_neg_value = -3.5;
1035 }
else if (Rin == 7 && sensor_height == 3.2) {
1036 x_condition_min = -Rin - 1;
1037 x_condition_max = Rin - 0.2;
1038 adjust_bottom_y_pos =
true;
1039 adjust_bottom_y_neg =
true;
1040 x_adjust_bottom_y_pos = 3.5;
1041 bottom_y_pos_value = 3.5;
1042 bottom_y_neg_value = -3.5;
1043 }
else if (Rin == 5 && sensor_height == 9.6 && sensor_width == 2.5) {
1044 x_condition_min = -(Rin + 2.6);
1045 x_condition_max = Rin;
1046 adjust_bottom_y_pos =
true;
1047 adjust_bottom_y_neg =
true;
1048 x_adjust_bottom_y_pos = 3.5;
1049 bottom_y_pos_value = 3.5;
1050 bottom_y_neg_value = -3.5;
1051 }
else if (Rin == 7 && sensor_height == 9.6 && sensor_width == 2.5) {
1052 x_condition_min = -Rin - 2.6;
1053 x_condition_max = Rin + 1;
1055 adjust_bottom_y_pos =
true;
1056 adjust_bottom_y_neg =
true;
1057 x_adjust_bottom_y_pos = 5.5;
1058 bottom_y_pos_value = 3.5;
1059 bottom_y_neg_value = -3.5;
1060 }
else if (Rin == 10 && sensor_height == 9.6 && sensor_width == 5.0) {
1061 x_condition_min = -Rin - 4;
1062 x_condition_max = Rin;
1064 adjust_bottom_y_pos =
false;
1065 adjust_bottom_y_neg =
false;
1066 x_adjust_bottom_y_pos = 3.5;
1067 bottom_y_pos_value = 3.5;
1068 bottom_y_neg_value = -3.5;
1069 }
else if (Rin == 20 && sensor_height == 9.6 && sensor_width == 5.0) {
1070 x_condition_min = -Rin - 4;
1071 x_condition_max = Rin;
1073 adjust_bottom_y_pos =
false;
1074 adjust_bottom_y_neg =
false;
1075 x_adjust_bottom_y_pos = 3.5;
1076 bottom_y_pos_value = 3.5;
1077 bottom_y_neg_value = -3.5;
1079 LOG(warning) <<
"Different config - to determine offsets needed for " <<
"Rin = " << Rin <<
" ; sensor_height = " << sensor_height <<
" ; sensor_width = " << sensor_width <<
" layer " << layerNumber;
1080 x_condition_min = -Rin - sensor_width;
1081 x_condition_max = Rin;
1082 adjust_bottom_y_pos =
false;
1083 adjust_bottom_y_neg =
false;
1086 offset_Rin_lower = Rin - Rin_offset;
1087 offset_Rin_upper = Rout + Rout_offset;
1089 std::set<std::pair<double, double>> placed_sensors;
1090 int sensor_count = 0;
1092 int placementCounter = 0;
1093 bool justSkipped =
false;
1095 std::vector<double> X_positions;
1096 std::vector<int> justSkipped1;
1098 if (sensor_width == 2.5) {
1100 if (
face ==
"front") {
1101 X_positions = {-63.4, -60.9, -54.2, -51.7, -45.0, -42.5, -35.8, -33.3, -26.6, -24.1, -17.4, -14.9,
1102 -8.2, -5.7, 1.0, 3.5, 10.2, 12.7, 19.4, 21.9, 28.6, 31.1, 37.8, 40.3, 47.0, 49.5,
1104 justSkipped1 = {1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1};
1105 }
else if (
face ==
"back") {
1106 X_positions = {-65.5, -58.8, -56.3, -49.6, -47.1, -40.4, -37.9, -31.2, -28.7, -22.0, -19.5, -12.8,
1107 -10.3, -3.6, -1.1, 5.6, 8.1, 14.8, 17.3, 24.0, 26.5, 33.2, 35.7, 42.4, 44.9,
1108 51.6, 54.1, 60.8, 63.3};
1109 justSkipped1 = {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0};
1112 if (Rin == 10 || Rin == 20) {
1113 float overlap = 0.3;
1115 float X_start = -2.0 - 13.5 * (sensor_width - overlap);
1116 float X_start_pos = 2.0 - 0.5 * (sensor_width - overlap);
1117 if (
face ==
"back") {
1118 X_start += (sensor_width - overlap);
1119 X_start_pos += (sensor_width - overlap);
1121 while (X_start < -2) {
1122 X_positions.push_back(X_start);
1123 justSkipped1.push_back(1);
1124 X_start += 2 * (sensor_width - overlap);
1126 while (X_start_pos < Rout + x_offset - sensor_width) {
1127 X_positions.push_back(X_start_pos);
1128 justSkipped1.push_back(1);
1129 X_start_pos += 2 * (sensor_width - overlap);
1133 if (
face ==
"front") {
1134 X_positions = {-63.4, -54.2, -45, -35.8, -26.6, -17.4, -8.2, 1., 10.2, 19.4, 28.6, 37.8, 47., 56.2, 65.4};
1135 justSkipped1 = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
1136 }
else if (
face ==
"back") {
1137 X_positions = {-58.8, -49.6, -40.4, -31.2, -22, -12.8, -3.6, 5.6, 14.8, 24, 33.2, 42.4, 51.6, 60.8};
1138 justSkipped1 = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
1143 if (layout_type ==
"rectangular") {
1145 double x_start = -Rout;
1146 double x_end = Rout;
1148 std::vector<double> x_positions;
1149 for (
double x = x_start;
x <= x_end;
x += sensor_width) {
1150 x_positions.push_back(
x);
1154 const int rowsToAlternate = 2;
1156 for (
size_t i = 0;
i < X_positions.size(); ++
i) {
1158 double x = X_positions[
i];
1159 bool justSkippedValue = justSkipped1[
i];
1161 std::vector<double> y_positions_positive;
1162 std::vector<double> y_positions_negative;
1164 for (
double y = -Rout - Rin_offset;
y <= Rout + Rin_offset;
y += sensor_height) {
1165 std::vector<std::pair<double, double>> corners = {
1167 {
x + sensor_width,
y},
1168 {
x,
y + sensor_height},
1169 {
x + sensor_width,
y + sensor_height}};
1171 bool within_bounds = std::all_of(corners.begin(), corners.end(), [&](
const std::pair<double, double>& corner) {
1172 double cx = corner.first;
1173 double cy = corner.second;
1174 return (offset_Rin_lower <= std::sqrt(cx * cx + cy * cy) && std::sqrt(cx * cx + cy * cy) <= offset_Rin_upper);
1177 if (within_bounds) {
1179 y_positions_positive.push_back(
y);
1181 y_positions_negative.push_back(
y);
1187 if (x_condition_min <=
x &&
x <= x_condition_max && !y_positions_positive.empty()) {
1188 double first_y_pos = y_positions_positive.front();
1189 double last_y_pos = y_positions_positive.back() - sensor_height;
1192 double top_distance_pos = top_y_pos - last_y_pos;
1194 if (adjust_bottom_y_pos &&
x > x_adjust_bottom_y_pos) {
1195 bottom_y_pos = bottom_y_pos_value;
1198 double bottom_distance_pos = first_y_pos - bottom_y_pos;
1200 if (std::abs(top_distance_pos + bottom_distance_pos) >= sensor_height) {
1201 for (
auto&
y : y_positions_positive) {
1202 y -= bottom_distance_pos - 0.2;
1204 y_positions_positive.push_back(y_positions_positive.back() + sensor_height);
1209 if (x_condition_min <=
x &&
x <= x_condition_max && !y_positions_negative.empty()) {
1210 double first_y_neg = y_positions_negative.front();
1211 double last_y_neg = y_positions_negative.back() + sensor_height;
1214 double top_distance_neg = -(top_y_neg - first_y_neg);
1216 if (adjust_bottom_y_neg &&
x > x_adjust_bottom_y_pos) {
1217 bottom_y_neg = bottom_y_neg_value;
1220 double bottom_distance_neg = -(last_y_neg - bottom_y_neg);
1222 top_distance_neg = std::abs(top_distance_neg);
1223 bottom_distance_neg = std::abs(bottom_distance_neg);
1224 std::sort(y_positions_negative.begin(), y_positions_negative.end());
1226 if (std::abs(top_distance_neg + bottom_distance_neg) >= sensor_height) {
1227 if (sensor_height == 19.2) {
1228 for (
auto&
y : y_positions_negative) {
1229 y -= bottom_distance_neg;
1232 for (
auto&
y : y_positions_negative) {
1233 y += bottom_distance_neg - 0.2;
1236 y_positions_negative.push_back(y_positions_negative.front() - sensor_height);
1241 if ((x < x_condition_min || x > x_condition_max) && !y_positions_negative.empty() && !y_positions_positive.empty()) {
1242 double first_y_neg = y_positions_negative.front();
1243 double last_y_pos = y_positions_positive.back() + sensor_height;
1245 double bottom_y_pos = -top_y_pos;
1247 double top_distance_pos = std::abs(top_y_pos - last_y_pos);
1248 double bottom_distance_pos = std::abs(first_y_neg - bottom_y_pos);
1250 if (top_distance_pos + bottom_distance_pos >= sensor_height) {
1251 for (
auto&
y : y_positions_positive) {
1252 y += top_distance_pos - 0.2;
1254 for (
auto&
y : y_positions_negative) {
1255 y += top_distance_pos - 0.2;
1257 double new_y = y_positions_negative.front() - sensor_height;
1259 if (
static_cast<int>(new_y) >
static_cast<int>(bottom_y_pos)) {
1260 y_positions_negative.push_back(new_y);
1265 std::sort(y_positions_negative.begin(), y_positions_negative.end());
1266 std::sort(y_positions_positive.begin(), y_positions_positive.end());
1268 double first_y_pos = y_positions_negative.front();
1270 last_y_pos = y_positions_positive.back() + sensor_height;
1273 bottom_y_pos = -top_y_pos;
1274 top_distance_pos = std::abs(top_y_pos - last_y_pos);
1275 bottom_distance_pos = std::abs(first_y_pos - bottom_y_pos);
1277 double Lb = (bottom_distance_pos + top_distance_pos) / 2;
1279 if (top_distance_pos < Lb) {
1280 double shift = Lb - top_distance_pos;
1281 for (
auto&
y : y_positions_negative) {
1284 for (
auto&
y : y_positions_positive) {
1287 }
else if (top_distance_pos > Lb) {
1288 double shift = top_distance_pos - Lb;
1289 for (
auto&
y : y_positions_negative) {
1292 for (
auto&
y : y_positions_positive) {
1298 std::vector<double> y_positions = y_positions_positive;
1299 y_positions.insert(y_positions.end(), y_positions_negative.begin(), y_positions_negative.end());
1301 for (
double y : y_positions) {
1304 double R_material_threshold = 0;
1306 if (placed_sensors.find({x, y}) == placed_sensors.end()) {
1307 placed_sensors.insert({
x,
y});
1311 double left_inactive_x_shift;
1312 double right_inactive_x_shift;
1313 double active_x_shift_sensor;
1315 if (
face ==
"front") {
1317 double active_x_shift, inactive_x_shift;
1319 if (justSkippedValue) {
1331 double inactive_x_shift_left, inactive_x_shift_right;
1333 if (sensor_width == 5.0) {
1336 inactive_x_shift_right =
x + sensor_width / 2;
1339 std::vector<std::pair<double, double>> corners_shifted = {
1341 {
x + sensor_width,
y},
1342 {
x,
y + sensor_height},
1343 {
x + sensor_width,
y + sensor_height}};
1345 bool within_bounds =
true;
1346 for (
const auto& corner : corners_shifted) {
1347 double cx = corner.first;
1348 double cy = corner.second;
1349 double dist = std::sqrt(cx * cx + cy * cy);
1351 if (Rin > dist || dist >= Rout) {
1352 within_bounds =
false;
1357 if (within_bounds) {
1359 double r_squared = (
x + x_offset) * (
x + x_offset) + (
y + y_offset) * (
y + y_offset);
1361 if (r_squared < R_material_threshold * R_material_threshold) {
1362 silicon_thickness = 0.005;
1363 copper_thickness = 0.00475;
1364 kapton_thickness = 0.03;
1365 epoxy_thickness = 0.0012;
1369 silicon_thickness = 0.01;
1370 copper_thickness = 0.006;
1371 kapton_thickness = 0.03;
1372 epoxy_thickness = 0.0012;
1377 if (sensor_width == 2.5) {
1380 sensor = geoManager->MakeBox(sensor_name.c_str(), siliconMed, active_width / 2, active_height / 2, silicon_thickness / 2);
1381 sensor->SetLineColor(SiColor);
1382 sensor->SetFillColorAlpha(SiColor, 0.4);
1383 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(active_x_shift_sensor + x_offset,
y + y_offset, mZ + z_offset - epoxy_thickness - kapton_thickness - copper_thickness - epoxy_thickness - silicon_thickness / 2));
1386 sensor = geoManager->MakeBox(inactive_name.c_str(), siliconMed, (sensor_width - active_width) / 2, sensor_height / 2, silicon_thickness / 2);
1387 sensor->SetLineColor(kRed);
1388 sensor->SetFillColorAlpha(kRed, 1.0);
1389 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(x_offset + inactive_x_shift,
y + y_offset, mZ + z_offset - epoxy_thickness - kapton_thickness - copper_thickness - epoxy_thickness - silicon_thickness / 2));
1394 sensor = geoManager->MakeBox(sensor_name.c_str(), siliconMed, active_width / 2, sensor_height / 2, silicon_thickness / 2);
1395 sensor->SetLineColor(SiColor);
1396 sensor->SetFillColorAlpha(SiColor, 0.4);
1397 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(x_offset +
x + inactive_width / 2,
y + y_offset, mZ + z_offset - epoxy_thickness - kapton_thickness - copper_thickness - epoxy_thickness - silicon_thickness / 2));
1400 sensor = geoManager->MakeBox(inactive_name_left.c_str(), siliconMed, inactive_width / 2, sensor_height / 2, silicon_thickness / 2);
1401 sensor->SetLineColor(kRed);
1402 sensor->SetFillColorAlpha(kRed, 1.0);
1403 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(x_offset + inactive_x_shift_left,
y + y_offset, mZ + z_offset - epoxy_thickness - kapton_thickness - copper_thickness - epoxy_thickness - silicon_thickness / 2));
1406 sensor = geoManager->MakeBox(inactive_name_right.c_str(), siliconMed, inactive_width / 2, sensor_height / 2, silicon_thickness / 2);
1407 sensor->SetLineColor(kRed);
1408 sensor->SetFillColorAlpha(kRed, 1.0);
1409 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(x_offset + inactive_x_shift_right,
y + y_offset, mZ + z_offset - epoxy_thickness - kapton_thickness - copper_thickness - epoxy_thickness - silicon_thickness / 2));
1414 sensor = geoManager->MakeBox(glue_up_name.c_str(), epoxyMed, sensor_width / 2, sensor_height / 2, epoxy_thickness / 2);
1415 sensor->SetLineColor(kBlue);
1416 sensor->SetFillColorAlpha(kBlue, 1.0);
1417 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(x_offset + active_x_shift,
y + y_offset, mZ + z_offset - epoxy_thickness - kapton_thickness - copper_thickness - epoxy_thickness / 2));
1419 if (r_squared < R_material_threshold * R_material_threshold) {
1421 sensor = geoManager->MakeBox(alu_name.c_str(), AluminumMed, sensor_width / 2, sensor_height / 2, copper_thickness / 2);
1422 sensor->SetLineColor(kBlack);
1423 sensor->SetFillColorAlpha(kBlack, 0.4);
1424 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(active_x_shift + x_offset,
y + y_offset, mZ + z_offset - epoxy_thickness - kapton_thickness - copper_thickness / 2));
1428 sensor = geoManager->MakeBox(copper_name.c_str(), copperMed, sensor_width / 2, sensor_height / 2, copper_thickness / 2);
1429 sensor->SetLineColor(kBlack);
1430 sensor->SetFillColorAlpha(kBlack, 0.4);
1431 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(active_x_shift + x_offset,
y + y_offset, mZ + z_offset - epoxy_thickness - kapton_thickness - copper_thickness / 2));
1436 sensor = geoManager->MakeBox(fpc_name.c_str(), kaptonMed, sensor_width / 2, sensor_height / 2, kapton_thickness / 2);
1437 sensor->SetLineColor(kGreen);
1438 sensor->SetFillColorAlpha(kGreen, 0.4);
1439 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(active_x_shift + x_offset,
y + y_offset, mZ + z_offset - epoxy_thickness - kapton_thickness / 2));
1443 sensor = geoManager->MakeBox(glue_down_name.c_str(), epoxyMed, sensor_width / 2, sensor_height / 2, epoxy_thickness / 2);
1444 sensor->SetLineColor(kBlue);
1445 sensor->SetFillColorAlpha(kBlue, 1.0);
1446 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(x_offset + active_x_shift,
y + y_offset, mZ + z_offset - epoxy_thickness / 2));
1449 double x_shifted =
x;
1450 double inactive_x_shift, active_x_shift;
1451 double active_x_shift_sensor;
1453 if (justSkippedValue) {
1465 double inactive_x_shift_left, inactive_x_shift_right;
1467 if (sensor_width == 5.0) {
1470 inactive_x_shift_right =
x + sensor_width / 2;
1473 std::vector<std::pair<double, double>> corners_shifted = {
1475 {x_shifted + sensor_width,
y},
1476 {x_shifted,
y + sensor_height},
1477 {x_shifted + sensor_width,
y + sensor_height}};
1479 bool within_bounds =
true;
1480 for (
const auto& corner : corners_shifted) {
1481 double cx = corner.first;
1482 double cy = corner.second;
1483 double dist = std::sqrt(cx * cx + cy * cy);
1485 if (Rin > dist + dist_offset || dist >= Rout) {
1486 within_bounds =
false;
1491 if (within_bounds) {
1493 double r_squared = (
x + x_offset) * (
x + x_offset) + (
y + y_offset) * (
y + y_offset);
1495 if (r_squared < R_material_threshold * R_material_threshold) {
1496 silicon_thickness = 0.005;
1497 copper_thickness = 0.00475;
1498 kapton_thickness = 0.03;
1499 epoxy_thickness = 0.0006;
1503 silicon_thickness = 0.01;
1504 copper_thickness = 0.006;
1505 kapton_thickness = 0.03;
1506 epoxy_thickness = 0.0012;
1513 sensor = geoManager->MakeBox(glue_down_name.c_str(), epoxyMed, sensor_width / 2, sensor_height / 2, epoxy_thickness / 2);
1514 sensor->SetLineColor(kBlue);
1515 sensor->SetFillColorAlpha(kBlue, 1.0);
1516 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(x_offset + active_x_shift,
y + y_offset, mZ + z_offset + epoxy_thickness / 2));
1520 sensor = geoManager->MakeBox(fpc_name.c_str(), kaptonMed, sensor_width / 2, sensor_height / 2, kapton_thickness / 2);
1521 sensor->SetLineColor(kGreen);
1522 sensor->SetFillColorAlpha(kGreen, 0.4);
1523 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(active_x_shift + x_offset,
y + y_offset, mZ + z_offset + epoxy_thickness + kapton_thickness / 2));
1525 if (r_squared < R_material_threshold * R_material_threshold) {
1528 sensor = geoManager->MakeBox(alu_name.c_str(), AluminumMed, sensor_width / 2, sensor_height / 2, copper_thickness / 2);
1529 sensor->SetLineColor(kBlack);
1530 sensor->SetFillColorAlpha(kBlack, 0.4);
1531 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(active_x_shift + x_offset,
y + y_offset, mZ + z_offset + epoxy_thickness + kapton_thickness + copper_thickness / 2));
1535 sensor = geoManager->MakeBox(copper_name.c_str(), copperMed, sensor_width / 2, sensor_height / 2, copper_thickness / 2);
1536 sensor->SetLineColor(kBlack);
1537 sensor->SetFillColorAlpha(kBlack, 0.4);
1538 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(active_x_shift + x_offset,
y + y_offset, mZ + z_offset + epoxy_thickness + kapton_thickness + copper_thickness / 2));
1543 sensor = geoManager->MakeBox(glue_up_name.c_str(), epoxyMed, sensor_width / 2, sensor_height / 2, epoxy_thickness / 2);
1544 sensor->SetLineColor(kBlue);
1545 sensor->SetFillColorAlpha(kBlue, 1.0);
1546 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(x_offset + active_x_shift,
y + y_offset, mZ + z_offset + epoxy_thickness + kapton_thickness + copper_thickness + epoxy_thickness / 2));
1548 if (sensor_width == 2.5) {
1551 sensor = geoManager->MakeBox(sensor_name.c_str(), siliconMed, active_width / 2, active_height / 2, silicon_thickness / 2);
1552 sensor->SetLineColor(SiColor);
1553 sensor->SetFillColorAlpha(SiColor, 0.4);
1554 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(active_x_shift_sensor + x_offset,
y + y_offset, mZ + z_offset + epoxy_thickness + kapton_thickness + copper_thickness + epoxy_thickness + silicon_thickness / 2));
1557 sensor = geoManager->MakeBox(inactive_name.c_str(), siliconMed, (sensor_width - active_width) / 2, sensor_height / 2, silicon_thickness / 2);
1558 sensor->SetLineColor(kRed);
1559 sensor->SetFillColorAlpha(kRed, 1.0);
1560 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(x_offset + inactive_x_shift,
y + y_offset, mZ + z_offset + epoxy_thickness + kapton_thickness + copper_thickness + epoxy_thickness + silicon_thickness / 2));
1565 sensor = geoManager->MakeBox(sensor_name.c_str(), siliconMed, active_width / 2, sensor_height / 2, silicon_thickness / 2);
1566 sensor->SetLineColor(SiColor);
1567 sensor->SetFillColorAlpha(SiColor, 0.4);
1568 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(x_offset + x_shifted + inactive_width / 2,
y + y_offset, mZ + z_offset + epoxy_thickness + kapton_thickness + copper_thickness + epoxy_thickness + silicon_thickness / 2));
1572 sensor = geoManager->MakeBox(inactive_name_left.c_str(), siliconMed, inactive_width / 2, sensor_height / 2, silicon_thickness / 2);
1573 sensor->SetLineColor(kRed);
1574 sensor->SetFillColorAlpha(kRed, 1.0);
1575 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(x_offset + inactive_x_shift_left,
y + y_offset, mZ + z_offset + epoxy_thickness + kapton_thickness + copper_thickness + epoxy_thickness + silicon_thickness / 2));
1579 sensor = geoManager->MakeBox(inactive_name_right.c_str(), siliconMed, inactive_width / 2, sensor_height / 2, silicon_thickness / 2);
1580 sensor->SetLineColor(kRed);
1581 sensor->SetFillColorAlpha(kRed, 1.0);
1582 motherVolume->AddNode(sensor, sensor_count++,
new TGeoTranslation(x_offset + inactive_x_shift_right,
y + y_offset, mZ + z_offset + epoxy_thickness + kapton_thickness + copper_thickness + epoxy_thickness + silicon_thickness / 2));
1592 LOG(
debug) <<
"FT3Module: done create_layout";
1595void FT3Module::createModule(
double mZ,
int layerNumber,
int direction,
double Rin,
double Rout,
double overlap,
const std::string&
face,
const std::string& layout_type, TGeoVolume* motherVolume)
1598 LOG(
debug) <<
"FT3Module: createModule - Layer " << layerNumber <<
", Direction " << direction <<
", Face " <<
face;
1599 create_layout(mZ, layerNumber, direction, Rin, Rout, overlap,
face, layout_type, motherVolume);
1600 LOG(
debug) <<
"FT3Module: done createModule";
1604 double Rin,
double Rout,
double z_offset_local,
1606 TGeoVolume* motherVolume)
1608 LOG(
debug) <<
"FT3Module: createModule_staveGeo - Layer " << layerNumber
1609 <<
" at z=" << mZ <<
", Direction " << direction;
1610 create_layout_staveGeo(mZ, layerNumber, direction, Rin, Rout,
1611 z_offset_local, staveConfig, motherVolume);
1612 LOG(
debug) <<
"FT3Module: done createModule_staveGeo";
std::pair< double, double > calculate_y_range(double x_left, double x_right, double Rin, double Rout)
double calculate_y_circle(double x, double radius)
std::array< std::array< double, 3 >, 4 > buildStaveTriangle(int direction)
bool staveMidpointAndMirror(const Constants::StaveConfig &staveConfig, int staveID, double &y_midpoint, bool &mirrorStaveAroundX)
Definition of the FT3Module class.
std::pair< std::pair< double, double >, std::pair< double, double > > PositionRangeType
std::vector< PositionType > PositionTypes
std::pair< PositionTypes, PositionTypes > PosNegPositionTypes
void createModule_staveGeo(double mZ, int layerNumber, int direction, double Rin, double Rout, double z_offset_local, const Constants::StaveConfig &staveConfig, TGeoVolume *motherVolume)
static void createModule(double mZ, int layerNumber, int direction, double Rin, double Rout, double overlap, const std::string &face, const std::string &layout_type, TGeoVolume *motherVolume)
static const FT3BaseParam & Instance()
GLuint const GLchar * name
GLenum GLuint GLint GLenum face
const std::unordered_map< MaterialID, MaterialProperties > materials
const int SiInactiveColor
const double staveSensorGap
const double single_sensor_height
const double epoxyThickness
const double effectiveCarbonThickness_Stave
const double sensor2x1_height
const double z_offsetStave(double x_midpoint_spacing)
const double inactive_width
const EosCardParams & getEosCardParams(bool isML)
const double active_width
const int staveIdxToID(int staveIdx, unsigned nStavesPerDisc)
const double active_height
const double sensor2x1_gap
const double sensor2x1_width
const double siliconThickness
const double getStackHeight(unsigned nSensorsPerStack)
const double kaptonThickness
const double copperThickness
const double staveTriangleHeight
const std::vector< unsigned > kSensorsPerStack
TGeoMedium * getMedium(Materials::MaterialID id)
std::string to_string(gsl::span< T, Size > span)
const std::vector< double > & x_midpoints
const double x_midpoint_spacing
const std::vector< double > & y_lengths
const double maxToleranceInner
const std::vector< std::vector< StaveFill > > & exactStaveFills
const std::map< int, std::pair< double, bool > > & staveID_to_y_midpoint
const std::vector< bool > & staveOnFront
const double maxToleranceOuter
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"