Skip to content
Merged
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 @@ -23,12 +23,14 @@ namespace trk
enum eLayout {
kCylinder = 0,
kTurboStaves,
kStaggered,
};

struct TRKBaseParam : public o2::conf::ConfigurableParamHelper<TRKBaseParam> {
std::string configFile = "";
float serviceTubeX0 = 0.02f; // X0 Al2O3
eLayout layout = kCylinder; // Type of segmentation of the layers into staves
eLayout layoutML = kCylinder; // Type of segmentation for the middle layers
eLayout layoutOL = kCylinder; // Type of segmentation for the outer layers

O2ParamDef(TRKBaseParam, "TRKBase");
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class TRKLayer
auto getNumber() const { return mLayerNumber; }
auto getName() const { return mLayerName; }

TGeoVolume* createSensor(std::string type, double width = -1);
TGeoVolume* createChip(std::string type, double width = -1);
TGeoVolume* createStave(std::string type, double width = -1);
void createLayer(TGeoVolume* motherVolume);

private:
Expand Down
15 changes: 12 additions & 3 deletions Detectors/Upgrades/ALICE3/TRK/simulation/src/Detector.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,18 @@ void Detector::buildTRKNewVacuumVessel()
mLayers.emplace_back(10, std::string{GeometryTGeo::getTRKLayerPattern() + std::to_string(10)}, 80.f, 258.f, 100.e-3);

auto& trkPars = TRKBaseParam::Instance();
mLayers[8].setLayout(trkPars.layout);
mLayers[9].setLayout(trkPars.layout);
mLayers[10].setLayout(trkPars.layout);

// Middle layers
mLayers[3].setLayout(trkPars.layoutML);
mLayers[4].setLayout(trkPars.layoutML);
mLayers[5].setLayout(trkPars.layoutML);
mLayers[6].setLayout(trkPars.layoutML);

// Outer tracker
mLayers[7].setLayout(trkPars.layoutOL);
mLayers[8].setLayout(trkPars.layoutOL);
mLayers[9].setLayout(trkPars.layoutOL);
mLayers[10].setLayout(trkPars.layoutOL);
}

void Detector::configFromFile(std::string fileName)
Expand Down
169 changes: 136 additions & 33 deletions Detectors/Upgrades/ALICE3/TRK/simulation/src/TRKLayer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,108 @@ TRKLayer::TRKLayer(int layerNumber, std::string layerName, float rInn, float zLe
LOGP(info, "Creating layer: id: {} rInner: {} rOuter: {} zLength: {} x2X0: {}", mLayerNumber, mInnerRadius, mOuterRadius, mZ, mX2X0);
}

TGeoVolume* TRKLayer::createSensor(std::string type, double width)
{
TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
std::string sensName = Form("%s%d", GeometryTGeo::getTRKSensorPattern(), this->mLayerNumber);

TGeoShape* sensor;

if (type == "cylinder") {
sensor = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2);
} else if (type == "flat") {
if (width < 0) {
LOGP(fatal, "Attempting to create sensor with invalid width");
}
sensor = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2);
} else {
LOGP(fatal, "Sensor of type '{}' is not implemented", type);
}

TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi);
sensVol->SetLineColor(kYellow);

return sensVol;
};

TGeoVolume* TRKLayer::createChip(std::string type, double width)
{
TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
std::string chipName = o2::trk::GeometryTGeo::getTRKChipPattern() + std::to_string(mLayerNumber);

TGeoShape* chip;
TGeoVolume* sensVol;

if (type == "cylinder") {
chip = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2);
sensVol = createSensor("cylinder");
} else if (type == "flat") {
if (width < 0) {
LOGP(fatal, "Attempting to create chip with invalid width");
}
chip = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2);
sensVol = createSensor("flat", width);
} else {
LOGP(fatal, "Sensor of type '{}' is not implemented", type);
}

TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi);
LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName());
chipVol->AddNode(sensVol, 1, nullptr);
chipVol->SetLineColor(kYellow);

return chipVol;
}

TGeoVolume* TRKLayer::createStave(std::string type, double width)
{
TGeoMedium* medAir = gGeoManager->GetMedium("TRK_AIR$");
std::string staveName = o2::trk::GeometryTGeo::getTRKStavePattern() + std::to_string(mLayerNumber);

TGeoShape* stave;
TGeoVolume* staveVol;
TGeoVolume* chipVol;

if (type == "cylinder") {
stave = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2);
chipVol = createChip("cylinder");
staveVol = new TGeoVolume(staveName.c_str(), stave, medAir);
LOGP(info, "Inserting {} in {} ", chipVol->GetName(), staveVol->GetName());
staveVol->AddNode(chipVol, 1, nullptr);
} else if (type == "flat") {
if (width < 0) {
LOGP(fatal, "Attempting to create stave with invalid width");
}
stave = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2);
chipVol = createChip("flat", width);
staveVol = new TGeoVolume(staveName.c_str(), stave, medAir);
LOGP(info, "Inserting {} in {} ", chipVol->GetName(), staveVol->GetName());
staveVol->AddNode(chipVol, 1, nullptr);
} else if (type == "staggered") {
double width = mModuleWidth * 2; // Each stave has two modules (based on the LOI design)
stave = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2);
TGeoVolume* chipVolLeft = createChip("flat", mModuleWidth);
TGeoVolume* chipVolRight = createChip("flat", mModuleWidth);
staveVol = new TGeoVolume(staveName.c_str(), stave, medAir);

TGeoCombiTrans* transLeft = new TGeoCombiTrans();
transLeft->SetTranslation(-mModuleWidth / 2 + 0.05, 0, 0); // 1mm overlap between the modules
LOGP(info, "Inserting {} in {} ", chipVolLeft->GetName(), staveVol->GetName());
staveVol->AddNode(chipVolLeft, 0, transLeft);

TGeoCombiTrans* transRight = new TGeoCombiTrans();
transRight->SetTranslation(mModuleWidth / 2 - 0.05, 0.2, 0);
LOGP(info, "Inserting {} in {} ", chipVolRight->GetName(), staveVol->GetName());
staveVol->AddNode(chipVolRight, 1, transRight);
} else {
LOGP(fatal, "Chip of type '{}' is not implemented", type);
}

staveVol->SetLineColor(kYellow);

return staveVol;
}

void TRKLayer::createLayer(TGeoVolume* motherVolume)
{
TGeoMedium* medSi = gGeoManager->GetMedium("TRK_SILICON$");
Expand All @@ -56,28 +158,16 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume)
layerVol->SetLineColor(kYellow);

if (mLayout == eLayout::kCylinder) {
TGeoTube* stave = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2);
TGeoTube* chip = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2);
TGeoTube* sensor = new TGeoTube(mInnerRadius, mInnerRadius + mChipThickness, mZ / 2);

TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi);
sensVol->SetLineColor(kYellow);
TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi);
chipVol->SetLineColor(kYellow);
TGeoVolume* staveVol = new TGeoVolume(staveName.c_str(), stave, medSi);
staveVol->SetLineColor(kYellow);

LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName());
chipVol->AddNode(sensVol, 1, nullptr);

LOGP(info, "Inserting {} in {} ", chipVol->GetName(), staveVol->GetName());
staveVol->AddNode(chipVol, 1, nullptr);

auto staveVol = createStave("cylinder");
LOGP(info, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName());
layerVol->AddNode(staveVol, 1, nullptr);
} else if (mLayout == eLayout::kTurboStaves) {
// Compute the number of staves
double width = mModuleWidth * 2; // Each stave has two modules (based on the LOI design)
double width = mModuleWidth; // Each stave has two modules (based on the LOI design)
if (mInnerRadius > 25) {
width *= 2; // Outer layers have two modules per stave
}

int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / width);
nStaves += nStaves % 2; // Require an even number of staves

Expand All @@ -91,29 +181,42 @@ void TRKLayer::createLayer(TGeoVolume* motherVolume)
LOGP(info, "Creating a layer with {} staves and {} mm overlap", nStaves, overlap * 10);

for (int iStave = 0; iStave < nStaves; iStave++) {
TGeoBBox* sensor = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2);
TGeoBBox* chip = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2);
TGeoBBox* stave = new TGeoBBox(width / 2, mChipThickness / 2, mZ / 2);

TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi);
sensVol->SetLineColor(kYellow);
TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi);
chipVol->SetLineColor(kYellow);
TGeoVolume* staveVol = new TGeoVolume(staveName.c_str(), stave, medSi);
staveVol->SetLineColor(kYellow);
TGeoVolume* staveVol = createStave("flat", width);

// Put the staves in the correct position and orientation
TGeoCombiTrans* trans = new TGeoCombiTrans();
double theta = 360. * iStave / nStaves;
TGeoRotation* rot = new TGeoRotation("rot", theta + 90 + 2, 0, 0);
TGeoRotation* rot = new TGeoRotation("rot", theta + 90 + 3, 0, 0);
trans->SetRotation(rot);
trans->SetTranslation(mInnerRadius * std::cos(2. * TMath::Pi() * iStave / nStaves), mInnerRadius * std::sin(2 * TMath::Pi() * iStave / nStaves), 0);

LOGP(info, "Inserting {} in {} ", sensVol->GetName(), chipVol->GetName());
chipVol->AddNode(sensVol, 1, nullptr);
LOGP(info, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName());
layerVol->AddNode(staveVol, iStave, trans);
}
} else if (mLayout == kStaggered) {
// Compute the number of staves
double width = mModuleWidth * 2; // Each stave has two modules (based on the LOI design)
int nStaves = (int)std::ceil(mInnerRadius * 2 * TMath::Pi() / width);
nStaves += nStaves % 2; // Require an even number of staves

LOGP(info, "Inserting {} in {} ", chipVol->GetName(), staveVol->GetName());
staveVol->AddNode(chipVol, 1, nullptr);
// Compute the size of the overlap region
double theta = 2 * TMath::Pi() / nStaves;
double theta1 = std::atan(width / 2 / mInnerRadius);
double st = std::sin(theta);
double ct = std::cos(theta);
double theta2 = std::atan((mInnerRadius * st - width / 2 * ct) / (mInnerRadius * ct + width / 2 * st));
double overlap = (theta1 - theta2) * mInnerRadius;
LOGP(info, "Creating a layer with {} staves and {} mm overlap", nStaves, overlap * 10);

for (int iStave = 0; iStave < nStaves; iStave++) {
TGeoVolume* staveVol = createStave("staggered");

// Put the staves in the correct position and orientation
TGeoCombiTrans* trans = new TGeoCombiTrans();
double theta = 360. * iStave / nStaves;
TGeoRotation* rot = new TGeoRotation("rot", theta + 90, 0, 0);
trans->SetRotation(rot);
trans->SetTranslation(mInnerRadius * std::cos(2. * TMath::Pi() * iStave / nStaves), mInnerRadius * std::sin(2 * TMath::Pi() * iStave / nStaves), 0);

LOGP(info, "Inserting {} in {} ", staveVol->GetName(), layerVol->GetName());
layerVol->AddNode(staveVol, iStave, trans);
Expand Down