Skip to content

Commit a1d999e

Browse files
plarionoalibuild
andauthored
[ALICE 3] Add IRIS option with inclined walls material (#15098)
* Fully cyl IRIS with inclined walls material * Remove white space * Please consider the following formatting changes * Added 3rd segment up to R = 47.5 mm * Petal outer radius 48 mm * Set incl. material length to petal length --------- Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent 1ffca72 commit a1d999e

File tree

4 files changed

+200
-5
lines changed

4 files changed

+200
-5
lines changed

Detectors/Upgrades/ALICE3/TRK/base/include/TRKBase/TRKBaseParam.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ enum eLayout {
3434
enum eVDLayout {
3535
kIRIS4 = 0,
3636
kIRISFullCyl,
37+
kIRISFullCyl3InclinedWalls,
3738
kIRIS5,
3839
kIRIS4a,
3940
};

Detectors/Upgrades/ALICE3/TRK/simulation/include/TRKSimulation/VDGeometryBuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ namespace o2::trk
2525
// and then places/rotates the petal once into the mother volume.
2626

2727
void createIRISGeometryFullCyl(TGeoVolume* motherVolume); // Full-cylinder IRIS geometry (no petals, no gaps, no side walls)
28+
void createIRISGeometry3InclinedWalls(TGeoVolume* motherVolume); // Full-cylinder IRIS geometry with 3 inclined walls
2829
void createIRISGeometryFullCylwithDisks(TGeoVolume* motherVolume); // Full-cylinder IRIS geometry (no petals, no gaps, no side walls) incl. disks
2930
void createIRIS4Geometry(TGeoVolume* motherVolume); // 4 petals, cylindrical L0
3031
void createIRIS4aGeometry(TGeoVolume* motherVolume); // 3 petals, cylindrical L0

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,10 @@ void Detector::createGeometry()
275275
LOG(info) << "Building VD with IRIS fully cylindrical layout";
276276
o2::trk::createIRISGeometryFullCyl(vTRK);
277277
break;
278+
case kIRISFullCyl3InclinedWalls:
279+
LOG(info) << "Building VD with IRIS fully cylindrical layout with 3 inclined walls";
280+
o2::trk::createIRISGeometry3InclinedWalls(vTRK);
281+
break;
278282
case kIRIS5:
279283
LOG(info) << "Building VD with IRIS5 layout";
280284
o2::trk::createIRIS5Geometry(vTRK);

Detectors/Upgrades/ALICE3/TRK/simulation/src/VDGeometryBuilder.cxx

Lines changed: 194 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
// or submit itself to any jurisdiction.
1111

1212
#include "TRKSimulation/VDGeometryBuilder.h"
13-
1413
#include <TGeoVolume.h>
1514
#include <TGeoMatrix.h>
1615
#include <TGeoTube.h>
@@ -19,13 +18,13 @@
1918
#include <TGeoCompositeShape.h>
2019
#include <TString.h>
2120
#include <DetectorsBase/MaterialManager.h>
22-
2321
#include "TGeoManager.h"
24-
2522
#include "Framework/Logger.h"
2623
#include "TRKBase/GeometryTGeo.h"
2724
#include "TRKSimulation/VDLayer.h"
2825
#include "TRKSimulation/VDSensorRegistry.h"
26+
#include <algorithm>
27+
#include <cmath>
2928

3029
namespace o2::trk
3130
{
@@ -82,6 +81,9 @@ inline bool isSolidToCut(const TGeoVolume* v)
8281
if (TString(nm).BeginsWith("IRIS_Service_Pos_InVac")) {
8382
return true;
8483
}
84+
if (TString(nm).BeginsWith("VD_InclinedWall")) {
85+
return true;
86+
}
8587
return false;
8688
}
8789

@@ -252,8 +254,18 @@ static const double diskZ_cm[6] = {-34.0f, -30.0f, -26.0f, 26.0f, 30.0f, 34.0f};
252254
static constexpr double kPetalZ_cm = 70.0f; // full wall height
253255
static constexpr double kWallThick_cm = 0.015f; // 0.15 mm
254256
static constexpr double kInnerWallRadius_cm = 0.48f; // 4.8 mm (ALWAYS cylindrical)
255-
static constexpr double kOuterWallRadius_cm = 3.0f; // 30 mm (can be changed)
256-
static constexpr double kEps_cm = 1.e-4f;
257+
static constexpr double kOuterWallRadius_cm = 4.8f; // 48 mm (can be changed)
258+
static constexpr double kEps_cm = 2.5e-4f;
259+
260+
// 3 inclined walls ("walls") specs for the full-cylinder option
261+
// Thickness in-plane (cm). This is the short half-dimension of the TGeoBBox in XY.
262+
static constexpr double kInclinedWallThick_cm = 0.04f; // 0.4 mm
263+
// Layer-shell thickness used for the gap boundaries in the inclined-wall construction (cm)
264+
static constexpr double kSiLayerThick_cm = 0.01f; // 0.1 mm
265+
// Base tangency angle (deg) for the first wall; the other 2 are +120/+240.
266+
// This matches the angle used in the ROOT sketch from our chat.
267+
static constexpr double kInclinedWallPhi0_deg = 27.799f;
268+
static constexpr double kInclinedWallRmax_cm = 4.75f; // 47.5 mm outer extension
257269

258270
// Coldplate specs (cm)
259271
static constexpr double kColdplateRadius_cm = 2.6f; // 26 mm (outer radius)
@@ -806,6 +818,158 @@ static TGeoVolume* buildFullCylAssembly(int petalID, bool withDisks)
806818
return petalAsm;
807819
}
808820

821+
// Add 3 inclined walls (straight walls) into a full-cylinder petal assembly.
822+
// The walls are implemented as TWO TGeoBBox segments per wall, living in the gaps:
823+
// - segment 01: from tangency at Rtan to inner surface of L1
824+
// - segment 12: from outer surface of L1 to inner surface of L2
825+
// The construction accounts for the finite wall thickness (kInclinedWallThick_cm).
826+
static void addInclinedWalls3FullCyl(TGeoVolume* petalAsm, double phi0_deg = kInclinedWallPhi0_deg)
827+
{
828+
if (!petalAsm) {
829+
LOGP(error, "addInclinedWalls3FullCyl: petalAsm is null");
830+
return;
831+
}
832+
833+
auto& matmgr = o2::base::MaterialManager::Instance();
834+
const TGeoMedium* med = matmgr.getTGeoMedium("ALICE3_TRKSERVICES_ALUMINIUM5083");
835+
if (!med) {
836+
LOGP(warning, "addInclinedWalls3FullCyl: ALICE3_TRKSERVICES_ALUMINIUM5083 not found, walls not created.");
837+
return;
838+
}
839+
840+
// Clearance margin from layer/coldplate surfaces (cm)
841+
constexpr double clearanceMargin = 0.010; // 100 microns
842+
843+
// Geometry inputs (cm)
844+
constexpr double R0 = rL0_cm;
845+
constexpr double R1 = rL1_cm;
846+
constexpr double R2 = rL2_cm;
847+
constexpr double Rmax = kInclinedWallRmax_cm;
848+
849+
const double wallDy = 0.5 * kInclinedWallThick_cm;
850+
const double shellTh = kSiLayerThick_cm; // 0.1 mm shell thickness for bounds
851+
const double h = 0.5 * shellTh;
852+
const double dz = 0.5 * kPetalZ_cm; // match barrel/coldplate length in full-cyl option
853+
854+
constexpr int nWalls = 3;
855+
constexpr double dPhi = 360.0 / double(nWalls);
856+
857+
// Gap boundaries (shell surfaces)
858+
const double R0_out = R0 + h;
859+
const double R1_in = R1 - h;
860+
const double R1_out = R1 + h;
861+
const double R2_in = R2 - h;
862+
const double R2_out = R2 + h;
863+
864+
// Coldplate outer radius (tube segment is [kColdplateRadius_cm, kColdplateRadius_cm + kColdplateThickness_cm])
865+
const double Rcold_out = kColdplateRadius_cm + kColdplateThickness_cm;
866+
867+
// Tangency radius choice (thickness-safe at s=0): need Rtan - wallDy >= R0_out
868+
const double Rtan = R0_out + wallDy + clearanceMargin;
869+
870+
// For finite-thickness box:
871+
// outermost edge uses Reff_plus, innermost edge uses Reff_minus
872+
const double Reff_plus = Rtan + wallDy + clearanceMargin;
873+
const double Reff_minus = std::max(0.0, Rtan - wallDy - clearanceMargin);
874+
875+
auto sAt = [](double R, double Reff) -> double {
876+
const double v = R * R - Reff * Reff;
877+
return (v > 0.0) ? std::sqrt(v) : 0.0;
878+
};
879+
880+
// Segment bounds in 's' (thickness-safe):
881+
// 01: from tangency to L1 inner surface (outer edge <= R1_in)
882+
const double sa01 = 0.0;
883+
const double sb01 = sAt(R1_in, Reff_plus);
884+
885+
// 12: from outside L1 to inside L2
886+
const double sa12 = sAt(R1_out, Reff_minus); // inner edge >= R1_out
887+
const double sb12 = sAt(R2_in, Reff_plus); // outer edge <= R2_in
888+
889+
// 23: from outside coldplate (and outside L2) to Rmax
890+
const double R23_start = std::max(R2_out, Rcold_out) + clearanceMargin;
891+
const double sa23 = sAt(R23_start, Reff_minus); // inner edge >= start radius
892+
const double sb23 = sAt(Rmax, Reff_plus); // outer edge <= Rmax
893+
894+
if (!((sb01 > sa01) && (sb12 > sa12) && (sb23 > sa23))) {
895+
LOGP(error,
896+
"addInclinedWalls3FullCyl: invalid bounds. 01:[{},{}] 12:[{},{}] 23:[{},{}] "
897+
"Rtan={} Reff-={} Reff+={} R23_start={}",
898+
sa01, sb01, sa12, sb12, sa23, sb23,
899+
Rtan, Reff_minus, Reff_plus, R23_start);
900+
return;
901+
}
902+
903+
// Half-lengths and center parameters (s-centers)
904+
const double dx01 = 0.5 * (sb01 - sa01);
905+
const double dx12 = 0.5 * (sb12 - sa12);
906+
const double dx23 = 0.5 * (sb23 - sa23);
907+
908+
const double sc01 = 0.5 * (sa01 + sb01);
909+
const double sc12 = 0.5 * (sa12 + sb12);
910+
const double sc23 = 0.5 * (sa23 + sb23);
911+
912+
// Create shapes once, reuse for all walls
913+
auto* sh01 = new TGeoBBox(dx01, wallDy, dz);
914+
auto* sh12 = new TGeoBBox(dx12, wallDy, dz);
915+
auto* sh23 = new TGeoBBox(dx23, wallDy, dz);
916+
sh01->SetName("VD_InclinedWall01_sh");
917+
sh12->SetName("VD_InclinedWall12_sh");
918+
sh23->SetName("VD_InclinedWall23_sh");
919+
920+
const double phi0_rad = phi0_deg * TMath::DegToRad();
921+
922+
for (int i = 0; i < nWalls; ++i) {
923+
const double phi = phi0_rad + i * (dPhi * TMath::DegToRad());
924+
const double cosPhi = std::cos(phi);
925+
const double sinPhi = std::sin(phi);
926+
927+
// Tangency point on Rtan
928+
const double xT = Rtan * cosPhi;
929+
const double yT = Rtan * sinPhi;
930+
931+
// Tangent direction u = (-sin, cos)
932+
const double ux = -sinPhi;
933+
const double uy = cosPhi;
934+
935+
// Centers (in XY)
936+
const double cx01 = xT + sc01 * ux;
937+
const double cy01 = yT + sc01 * uy;
938+
const double cx12 = xT + sc12 * ux;
939+
const double cy12 = yT + sc12 * uy;
940+
const double cx23 = xT + sc23 * ux;
941+
const double cy23 = yT + sc23 * uy;
942+
943+
// Rotation: local X along tangent => angle = phi + 90°
944+
const double alpha_deg = phi0_deg + i * dPhi + 90.0;
945+
auto* rot = new TGeoRotation();
946+
rot->RotateZ(alpha_deg);
947+
948+
// Create volumes per wall (unique names)
949+
auto* v01 = new TGeoVolume(Form("VD_InclinedWall01_%d", i), sh01, med);
950+
auto* v12 = new TGeoVolume(Form("VD_InclinedWall12_%d", i), sh12, med);
951+
auto* v23 = new TGeoVolume(Form("VD_InclinedWall23_%d", i), sh23, med);
952+
v01->SetLineColor(kOrange + 7);
953+
v12->SetLineColor(kOrange + 7);
954+
v23->SetLineColor(kOrange + 7);
955+
v01->SetTransparency(70);
956+
v12->SetTransparency(70);
957+
v23->SetTransparency(70);
958+
959+
auto* T01 = new TGeoCombiTrans(cx01, cy01, 0.0, rot);
960+
auto* T12 = new TGeoCombiTrans(cx12, cy12, 0.0, new TGeoRotation(*rot));
961+
auto* T23 = new TGeoCombiTrans(cx23, cy23, 0.0, new TGeoRotation(*rot));
962+
963+
petalAsm->AddNode(v01, 1, T01);
964+
petalAsm->AddNode(v12, 1, T12);
965+
petalAsm->AddNode(v23, 1, T23);
966+
967+
LOGP(debug,
968+
"InclinedWall {}: 01({:.3f},{:.3f}) 12({:.3f},{:.3f}) 23({:.3f},{:.3f}) angle={:.2f}°",
969+
i, cx01, cy01, cx12, cy12, cx23, cy23, alpha_deg);
970+
}
971+
}
972+
809973
// =================== Public entry points ===================
810974

811975
void createIRIS4Geometry(TGeoVolume* motherVolume)
@@ -908,6 +1072,31 @@ void createIRISGeometryFullCyl(TGeoVolume* motherVolume)
9081072
buildIrisCutoutFromPetalSolid(nPetals);
9091073
}
9101074

1075+
void createIRISGeometry3InclinedWalls(TGeoVolume* motherVolume)
1076+
{
1077+
if (!motherVolume) {
1078+
LOGP(error, "createIRISGeometry3InclinedWalls: motherVolume is null");
1079+
return;
1080+
}
1081+
1082+
clearVDSensorRegistry();
1083+
1084+
constexpr int nPetals = 1;
1085+
constexpr int petalID = 0;
1086+
1087+
// Start from the same content as createIRISGeometryFullCyl
1088+
auto* petal = buildFullCylAssembly(petalID, /*withDisks=*/false);
1089+
1090+
// Add the 3 inclined walls into the same assembly
1091+
addInclinedWalls3FullCyl(petal, kInclinedWallPhi0_deg);
1092+
1093+
motherVolume->AddNode(petal, 1, nullptr);
1094+
1095+
// Same cutout pipeline as full-cyl
1096+
buildPetalSolidsComposite(petal);
1097+
buildIrisCutoutFromPetalSolid(nPetals);
1098+
}
1099+
9111100
void createIRISGeometryFullCylwithDisks(TGeoVolume* motherVolume)
9121101
{
9131102
if (!motherVolume) {

0 commit comments

Comments
 (0)