Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum eLayout {
enum eVDLayout {
kIRIS4 = 0,
kIRISFullCyl,
kIRISFullCyl3InclinedWalls,
kIRIS5,
kIRIS4a,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace o2::trk
// and then places/rotates the petal once into the mother volume.

void createIRISGeometryFullCyl(TGeoVolume* motherVolume); // Full-cylinder IRIS geometry (no petals, no gaps, no side walls)
void createIRISGeometry3InclinedWalls(TGeoVolume* motherVolume); // Full-cylinder IRIS geometry with 3 inclined walls
void createIRISGeometryFullCylwithDisks(TGeoVolume* motherVolume); // Full-cylinder IRIS geometry (no petals, no gaps, no side walls) incl. disks
void createIRIS4Geometry(TGeoVolume* motherVolume); // 4 petals, cylindrical L0
void createIRIS4aGeometry(TGeoVolume* motherVolume); // 3 petals, cylindrical L0
Expand Down
4 changes: 4 additions & 0 deletions Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ void Detector::createGeometry()
LOG(info) << "Building VD with IRIS fully cylindrical layout";
o2::trk::createIRISGeometryFullCyl(vTRK);
break;
case kIRISFullCyl3InclinedWalls:
LOG(info) << "Building VD with IRIS fully cylindrical layout with 3 inclined walls";
o2::trk::createIRISGeometry3InclinedWalls(vTRK);
break;
case kIRIS5:
LOG(info) << "Building VD with IRIS5 layout";
o2::trk::createIRIS5Geometry(vTRK);
Expand Down
197 changes: 193 additions & 4 deletions Detectors/Upgrades/ALICE3/TRK/simulation/src/VDGeometryBuilder.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
// or submit itself to any jurisdiction.

#include "TRKSimulation/VDGeometryBuilder.h"

#include <TGeoVolume.h>
#include <TGeoMatrix.h>
#include <TGeoTube.h>
Expand All @@ -19,13 +18,13 @@
#include <TGeoCompositeShape.h>
#include <TString.h>
#include <DetectorsBase/MaterialManager.h>

#include "TGeoManager.h"

#include "Framework/Logger.h"
#include "TRKBase/GeometryTGeo.h"
#include "TRKSimulation/VDLayer.h"
#include "TRKSimulation/VDSensorRegistry.h"
#include <algorithm>
#include <cmath>

namespace o2::trk
{
Expand Down Expand Up @@ -82,6 +81,9 @@ inline bool isSolidToCut(const TGeoVolume* v)
if (TString(nm).BeginsWith("IRIS_Service_Pos_InVac")) {
return true;
}
if (TString(nm).BeginsWith("VD_InclinedWall")) {
return true;
}
return false;
}

Expand Down Expand Up @@ -253,7 +255,17 @@ static constexpr double kPetalZ_cm = 70.0f; // full wall height
static constexpr double kWallThick_cm = 0.015f; // 0.15 mm
static constexpr double kInnerWallRadius_cm = 0.48f; // 4.8 mm (ALWAYS cylindrical)
static constexpr double kOuterWallRadius_cm = 3.0f; // 30 mm (can be changed)
static constexpr double kEps_cm = 1.e-4f;
static constexpr double kEps_cm = 2.5e-4f;

// 3 inclined walls ("walls") specs for the full-cylinder option
// Thickness in-plane (cm). This is the short half-dimension of the TGeoBBox in XY.
static constexpr double kInclinedWallThick_cm = 0.04f; // 0.4 mm
// Layer-shell thickness used for the gap boundaries in the inclined-wall construction (cm)
static constexpr double kSiLayerThick_cm = 0.01f; // 0.1 mm
// Base tangency angle (deg) for the first wall; the other 2 are +120/+240.
// This matches the angle used in the ROOT sketch from our chat.
static constexpr double kInclinedWallPhi0_deg = 27.799f;
static constexpr double kInclinedWallRmax_cm = 4.75f; // 47.5 mm outer extension

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

// Add 3 inclined walls (straight walls) into a full-cylinder petal assembly.
// The walls are implemented as TWO TGeoBBox segments per wall, living in the gaps:
// - segment 01: from tangency at Rtan to inner surface of L1
// - segment 12: from outer surface of L1 to inner surface of L2
// The construction accounts for the finite wall thickness (kInclinedWallThick_cm).
static void addInclinedWalls3FullCyl(TGeoVolume* petalAsm, double phi0_deg = kInclinedWallPhi0_deg)
{
if (!petalAsm) {
LOGP(error, "addInclinedWalls3FullCyl: petalAsm is null");
return;
}

auto& matmgr = o2::base::MaterialManager::Instance();
const TGeoMedium* med = matmgr.getTGeoMedium("ALICE3_TRKSERVICES_ALUMINIUM5083");
if (!med) {
LOGP(warning, "addInclinedWalls3FullCyl: ALICE3_TRKSERVICES_ALUMINIUM5083 not found, walls not created.");
return;
}

// Clearance margin from layer/coldplate surfaces (cm)
constexpr double clearanceMargin = 0.010; // 100 microns

// Geometry inputs (cm)
constexpr double R0 = rL0_cm;
constexpr double R1 = rL1_cm;
constexpr double R2 = rL2_cm;
constexpr double Rmax = kInclinedWallRmax_cm;

const double wallDy = 0.5 * kInclinedWallThick_cm;
const double shellTh = kSiLayerThick_cm; // 0.1 mm shell thickness for bounds
const double h = 0.5 * shellTh;
const double dz = 0.5 * kLenZ_cm; // match barrel/coldplate length in full-cyl option

constexpr int nWalls = 3;
constexpr double dPhi = 360.0 / double(nWalls);

// Gap boundaries (shell surfaces)
const double R0_out = R0 + h;
const double R1_in = R1 - h;
const double R1_out = R1 + h;
const double R2_in = R2 - h;
const double R2_out = R2 + h;

// Coldplate outer radius (tube segment is [kColdplateRadius_cm, kColdplateRadius_cm + kColdplateThickness_cm])
const double Rcold_out = kColdplateRadius_cm + kColdplateThickness_cm;

// Tangency radius choice (thickness-safe at s=0): need Rtan - wallDy >= R0_out
const double Rtan = R0_out + wallDy + clearanceMargin;

// For finite-thickness box:
// outermost edge uses Reff_plus, innermost edge uses Reff_minus
const double Reff_plus = Rtan + wallDy + clearanceMargin;
const double Reff_minus = std::max(0.0, Rtan - wallDy - clearanceMargin);

auto sAt = [](double R, double Reff) -> double {
const double v = R * R - Reff * Reff;
return (v > 0.0) ? std::sqrt(v) : 0.0;
};

// Segment bounds in 's' (thickness-safe):
// 01: from tangency to L1 inner surface (outer edge <= R1_in)
const double sa01 = 0.0;
const double sb01 = sAt(R1_in, Reff_plus);

// 12: from outside L1 to inside L2
const double sa12 = sAt(R1_out, Reff_minus); // inner edge >= R1_out
const double sb12 = sAt(R2_in, Reff_plus); // outer edge <= R2_in

// 23: from outside coldplate (and outside L2) to Rmax
const double R23_start = std::max(R2_out, Rcold_out) + clearanceMargin;
const double sa23 = sAt(R23_start, Reff_minus); // inner edge >= start radius
const double sb23 = sAt(Rmax, Reff_plus); // outer edge <= Rmax

if (!((sb01 > sa01) && (sb12 > sa12) && (sb23 > sa23))) {
LOGP(error,
"addInclinedWalls3FullCyl: invalid bounds. 01:[{},{}] 12:[{},{}] 23:[{},{}] "
"Rtan={} Reff-={} Reff+={} R23_start={}",
sa01, sb01, sa12, sb12, sa23, sb23,
Rtan, Reff_minus, Reff_plus, R23_start);
return;
}

// Half-lengths and center parameters (s-centers)
const double dx01 = 0.5 * (sb01 - sa01);
const double dx12 = 0.5 * (sb12 - sa12);
const double dx23 = 0.5 * (sb23 - sa23);

const double sc01 = 0.5 * (sa01 + sb01);
const double sc12 = 0.5 * (sa12 + sb12);
const double sc23 = 0.5 * (sa23 + sb23);

// Create shapes once, reuse for all walls
auto* sh01 = new TGeoBBox(dx01, wallDy, dz);
auto* sh12 = new TGeoBBox(dx12, wallDy, dz);
auto* sh23 = new TGeoBBox(dx23, wallDy, dz);
sh01->SetName("VD_InclinedWall01_sh");
sh12->SetName("VD_InclinedWall12_sh");
sh23->SetName("VD_InclinedWall23_sh");

const double phi0_rad = phi0_deg * TMath::DegToRad();

for (int i = 0; i < nWalls; ++i) {
const double phi = phi0_rad + i * (dPhi * TMath::DegToRad());
const double cosPhi = std::cos(phi);
const double sinPhi = std::sin(phi);

// Tangency point on Rtan
const double xT = Rtan * cosPhi;
const double yT = Rtan * sinPhi;

// Tangent direction u = (-sin, cos)
const double ux = -sinPhi;
const double uy = cosPhi;

// Centers (in XY)
const double cx01 = xT + sc01 * ux;
const double cy01 = yT + sc01 * uy;
const double cx12 = xT + sc12 * ux;
const double cy12 = yT + sc12 * uy;
const double cx23 = xT + sc23 * ux;
const double cy23 = yT + sc23 * uy;

// Rotation: local X along tangent => angle = phi + 90°
const double alpha_deg = phi0_deg + i * dPhi + 90.0;
auto* rot = new TGeoRotation();
rot->RotateZ(alpha_deg);

// Create volumes per wall (unique names)
auto* v01 = new TGeoVolume(Form("VD_InclinedWall01_%d", i), sh01, med);
auto* v12 = new TGeoVolume(Form("VD_InclinedWall12_%d", i), sh12, med);
auto* v23 = new TGeoVolume(Form("VD_InclinedWall23_%d", i), sh23, med);
v01->SetLineColor(kOrange + 7);
v12->SetLineColor(kOrange + 7);
v23->SetLineColor(kOrange + 7);
v01->SetTransparency(70);
v12->SetTransparency(70);
v23->SetTransparency(70);

auto* T01 = new TGeoCombiTrans(cx01, cy01, 0.0, rot);
auto* T12 = new TGeoCombiTrans(cx12, cy12, 0.0, new TGeoRotation(*rot));
auto* T23 = new TGeoCombiTrans(cx23, cy23, 0.0, new TGeoRotation(*rot));

petalAsm->AddNode(v01, 1, T01);
petalAsm->AddNode(v12, 1, T12);
petalAsm->AddNode(v23, 1, T23);

LOGP(debug,
"InclinedWall {}: 01({:.3f},{:.3f}) 12({:.3f},{:.3f}) 23({:.3f},{:.3f}) angle={:.2f}°",
i, cx01, cy01, cx12, cy12, cx23, cy23, alpha_deg);
}
}

// =================== Public entry points ===================

void createIRIS4Geometry(TGeoVolume* motherVolume)
Expand Down Expand Up @@ -908,6 +1072,31 @@ void createIRISGeometryFullCyl(TGeoVolume* motherVolume)
buildIrisCutoutFromPetalSolid(nPetals);
}

void createIRISGeometry3InclinedWalls(TGeoVolume* motherVolume)
{
if (!motherVolume) {
LOGP(error, "createIRISGeometry3InclinedWalls: motherVolume is null");
return;
}

clearVDSensorRegistry();

constexpr int nPetals = 1;
constexpr int petalID = 0;

// Start from the same content as createIRISGeometryFullCyl
auto* petal = buildFullCylAssembly(petalID, /*withDisks=*/false);

// Add the 3 inclined walls into the same assembly
addInclinedWalls3FullCyl(petal, kInclinedWallPhi0_deg);

motherVolume->AddNode(petal, 1, nullptr);

// Same cutout pipeline as full-cyl
buildPetalSolidsComposite(petal);
buildIrisCutoutFromPetalSolid(nPetals);
}

void createIRISGeometryFullCylwithDisks(TGeoVolume* motherVolume)
{
if (!motherVolume) {
Expand Down