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
8 changes: 6 additions & 2 deletions Detectors/Upgrades/ALICE3/FT3/simulation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@
# or submit itself to any jurisdiction.

o2_add_library(FT3Simulation
SOURCES src/FT3Layer.cxx
SOURCES
src/FT3Module.cxx
src/FT3Layer.cxx
src/Detector.cxx
PUBLIC_LINK_LIBRARIES O2::FT3Base
O2::ITSMFTSimulation
ROOT::Physics)

o2_target_root_dictionary(FT3Simulation
HEADERS include/FT3Simulation/Detector.h
HEADERS
include/FT3Simulation/FT3Module.h
include/FT3Simulation/Detector.h
include/FT3Simulation/FT3Layer.h)

o2_data_file(COPY data DESTINATION Detectors/FT3/simulation)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <TGeoManager.h> // for gGeoManager
#include "Rtypes.h" // for Double_t, Int_t, Bool_t, etc
#include "FT3Simulation/Detector.h" // for Detector, Detector::Model
#include "FT3Simulation/FT3Module.h"

class TGeoVolume;

Expand Down Expand Up @@ -57,6 +58,24 @@ class FT3Layer : public TObject
/// \param motherVolume the TGeoVolume owing the volume structure
virtual void createLayer(TGeoVolume* motherVolume);

static void initialize_mat();

// create layer for disk support
void createSeparationLayer(TGeoVolume* motherVolume, const std::string& separationLayerName);
void createSeparationLayer_waterCooling(TGeoVolume* motherVolume, const std::string& separationLayerName);

static TGeoMaterial* carbonFiberMat;
static TGeoMedium* medCarbonFiber;

static TGeoMaterial* kaptonMat;
static TGeoMedium* kaptonMed;

static TGeoMaterial* waterMat;
static TGeoMedium* waterMed;

static TGeoMaterial* foamMat;
static TGeoMedium* medFoam;

private:
Int_t mLayerNumber = -1; ///< Current layer number
Int_t mDirection; ///< Layer direction 0=Forward 1 = Backward
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
// All rights not expressly granted are reserved.
//
// This software is distributed under the terms of the GNU General Public
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

/// \file FT3Module.h
/// \brief Definition of the FT3Module class

#ifndef FT3MODULE_H
#define FT3MODULE_H

#include <TGeoVolume.h>
#include <string>

class FT3Module
{

public:
static void initialize_materials();
static TGeoMaterial* siliconMat;
static TGeoMedium* siliconMed;
static TGeoMaterial* copperMat;
static TGeoMedium* copperMed;
static TGeoMaterial* kaptonMat;
static TGeoMedium* kaptonMed;
static TGeoMaterial* epoxyMat;
static TGeoMedium* epoxyMed;
static TGeoMaterial* AluminumMat;
static TGeoMedium* AluminumMed;

const char* mDetName;

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);

private:
static void 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);
};

#endif // FT3MODULE_H
22 changes: 19 additions & 3 deletions Detectors/Upgrades/ALICE3/FT3/simulation/src/Detector.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@

#include <cstdio> // for NULL, snprintf

#define MAX_SENSORS 2000

class FairModule;

class TGeoMedium;
Expand Down Expand Up @@ -729,9 +731,23 @@ void Detector::defineSensitiveVolumes()
for (int direction : {0, 1}) {
for (int iLayer = 0; iLayer < mNumberOfLayers; iLayer++) {
volumeName = o2::ft3::GeometryTGeo::getFT3SensorPattern() + std::to_string(iLayer);
v = geoManager->GetVolume(Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), direction, iLayer));
LOG(info) << "Adding FT3 Sensitive Volume => " << v->GetName();
AddSensitiveVolume(v);
if (iLayer < 3) { // ML disks
v = geoManager->GetVolume(Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), direction, iLayer));
AddSensitiveVolume(v);
} else { // OT disks
for (int sensor_count = 0; sensor_count < MAX_SENSORS; ++sensor_count) {
std::string sensor_name_front = "FT3sensor_front_" + std::to_string(iLayer) + "_" + std::to_string(direction) + "_" + std::to_string(sensor_count);
std::string sensor_name_back = "FT3sensor_back_" + std::to_string(iLayer) + "_" + std::to_string(direction) + "_" + std::to_string(sensor_count);
v = geoManager->GetVolume(sensor_name_front.c_str());
if (v) {
AddSensitiveVolume(v);
}
v = geoManager->GetVolume(sensor_name_back.c_str());
if (v) {
AddSensitiveVolume(v);
}
}
}
}
}
}
Expand Down
182 changes: 179 additions & 3 deletions Detectors/Upgrades/ALICE3/FT3/simulation/src/FT3Layer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
#include "TMathBase.h" // for Abs
#include <TMath.h> // for Sin, RadToDeg, DegToRad, Cos, Tan, etc

#include <TGeoBBox.h>
#include <string>
#include <cstdio> // for snprintf
#include <cmath>

class TGeoMedium;

Expand All @@ -40,6 +43,18 @@ ClassImp(FT3Layer);

FT3Layer::~FT3Layer() = default;

TGeoMaterial* FT3Layer::carbonFiberMat = nullptr;
TGeoMedium* FT3Layer::medCarbonFiber = nullptr;

TGeoMaterial* FT3Layer::kaptonMat = nullptr;
TGeoMedium* FT3Layer::kaptonMed = nullptr;

TGeoMaterial* FT3Layer::waterMat = nullptr;
TGeoMedium* FT3Layer::waterMed = nullptr;

TGeoMaterial* FT3Layer::foamMat = nullptr;
TGeoMedium* FT3Layer::medFoam = nullptr;

FT3Layer::FT3Layer(Int_t layerDirection, Int_t layerNumber, std::string layerName, Float_t z, Float_t rIn, Float_t rOut, Float_t Layerx2X0)
{
// Creates a simple parametrized EndCap layer covering the given
Expand All @@ -59,10 +74,157 @@ FT3Layer::FT3Layer(Int_t layerDirection, Int_t layerNumber, std::string layerNam
LOG(info) << " Layer z = " << mZ << " ; R_in = " << mInnerRadius << " ; R_out = " << mOuterRadius << " ; x2X0 = " << mx2X0 << " ; ChipThickness = " << mChipThickness;
}

void FT3Layer::initialize_mat()
{

if (carbonFiberMat) {
return;
}

carbonFiberMat = new TGeoMaterial("CarbonFiber", 12.0, 6.0, 1.6);
medCarbonFiber = new TGeoMedium("CarbonFiber", 1, carbonFiberMat);

auto* itsC = new TGeoElement("FT3_C", "Carbon", 6, 12.0107);

auto* itsFoam = new TGeoMixture("FT3_Foam", 1);
itsFoam->AddElement(itsC, 1);
itsFoam->SetDensity(0.17);

medFoam = new TGeoMedium("FT3_Foam", 1, itsFoam);
foamMat = medFoam->GetMaterial();

kaptonMat = new TGeoMaterial("Kapton (cooling pipe)", 13.84, 6.88, 1.346);
kaptonMed = new TGeoMedium("Kapton (cooling pipe)", 1, kaptonMat);

waterMat = new TGeoMaterial("Water", 18.01528, 8.0, 1.064);
waterMed = new TGeoMedium("Water", 2, waterMat);
}

static double y_circle(double x, double radius)
{
return (x * x < radius * radius) ? std::sqrt(radius * radius - x * x) : 0;
}

void FT3Layer::createSeparationLayer_waterCooling(TGeoVolume* motherVolume, const std::string& separationLayerName)
{

FT3Layer::initialize_mat();

double carbonFiberThickness = 0.01;
double foamSpacingThickness = 0.5;

TGeoTube* carbonFiberLayer = new TGeoTube(mInnerRadius, mOuterRadius, carbonFiberThickness / 2);

// volumes
TGeoVolume* carbonFiberLayerVol1 = new TGeoVolume((separationLayerName + "_CarbonFiber1").c_str(), carbonFiberLayer, medCarbonFiber);
TGeoVolume* carbonFiberLayerVol2 = new TGeoVolume((separationLayerName + "_CarbonFiber2").c_str(), carbonFiberLayer, medCarbonFiber);

carbonFiberLayerVol1->SetLineColor(kGray + 2);
carbonFiberLayerVol2->SetLineColor(kGray + 2);

double zSeparation = foamSpacingThickness / 2.0 + carbonFiberThickness / 2.0;

motherVolume->AddNode(carbonFiberLayerVol1, 1, new TGeoTranslation(0, 0, mZ - zSeparation));
motherVolume->AddNode(carbonFiberLayerVol2, 1, new TGeoTranslation(0, 0, mZ + zSeparation));

double pipeOuterRadius = 0.20;
double kaptonThickness = 0.0025;
double pipeInnerRadius = pipeOuterRadius - kaptonThickness;
double pipeMaxLength = mOuterRadius * 2.0;

int name_it = 0;

// positions of the pipes depending on the overlap of the sensors inactive regions: (ALICE 3 dimensions)
// partial:
// std::vector<double> X_pos = {-63.2, -58.4, -53.6, -48.8, -44.0, -39.199999999999996, -34.4, -29.599999999999994, -24.799999999999997, -19.999999999999993, -15.199999999999998, -10.399999999999993, -5.599999999999998, -0.7999999999999936, 4.000000000000002, 8.800000000000006, 13.600000000000001, 18.400000000000006, 23.200000000000003, 28.000000000000007, 32.800000000000004, 37.60000000000001, 42.400000000000006, 47.20000000000001, 52.00000000000001, 56.80000000000001, 61.60000000000001, 66.4};
// complete:
// std::vector<double> X_pos = {-63.4, -58.8, -54.199999999999996, -49.599999999999994, -44.99999999999999, -40.39999999999999, -35.79999999999999, -31.199999999999992, -26.59999999999999, -21.999999999999993, -17.39999999999999, -12.799999999999994, -8.199999999999992, -3.5999999999999934, 1.000000000000008, 5.600000000000007, 10.200000000000008, 14.800000000000008, 19.40000000000001, 24.000000000000007, 28.60000000000001, 33.20000000000001, 37.80000000000001, 42.40000000000001, 47.000000000000014, 51.600000000000016, 56.20000000000002, 60.80000000000002, 65.40000000000002};
std::vector<double> X_pos = {-62.3168, -57.9836, -53.650400000000005, -49.317200000000014, -44.984000000000016, -40.65080000000002, -36.31760000000002, -31.984400000000026, -27.65120000000003, -23.318000000000037, -18.98480000000004, -14.651600000000043, -10.318400000000047, -5.98520000000005, -1.6520000000000519, 2.6811999999999445, 7.014399999999941, 11.347599999999936, 15.680799999999934, 20.01399999999993, 24.347199999999926, 28.68039999999992, 33.013599999999926, 37.34679999999992, 41.980000000000004, 46.613200000000006, 51.246399999999994, 55.87960000000001, 60.5128};

for (double xPos : X_pos) {

double pipeLength = pipeMaxLength;
double yMax = 0.0;

TGeoRotation* rotation = new TGeoRotation();
rotation->RotateX(90);

if (std::abs(xPos) < mInnerRadius) {
double yInner = std::abs(y_circle(xPos, mInnerRadius));
double yOuter = std::abs(y_circle(xPos, mOuterRadius));

yMax = 2 * yOuter;
pipeLength = yMax;

double positiveYLength = yOuter - yInner;

TGeoVolume* kaptonPipePos = new TGeoVolume((separationLayerName + "_KaptonPipePos_" + std::to_string(name_it)).c_str(), new TGeoTube(pipeInnerRadius, pipeOuterRadius, positiveYLength / 2), kaptonMed);
kaptonPipePos->SetLineColor(kGray);
TGeoVolume* waterVolumePos = new TGeoVolume((separationLayerName + "_WaterVolumePos_" + std::to_string(name_it)).c_str(), new TGeoTube(0.0, pipeInnerRadius, positiveYLength / 2), waterMed);
waterVolumePos->SetLineColor(kBlue);

motherVolume->AddNode(waterVolumePos, 1, new TGeoCombiTrans(xPos, (yInner + yOuter) / 2.0, mZ, rotation));

TGeoVolume* kaptonPipeNeg = new TGeoVolume((separationLayerName + "_KaptonPipeNeg_" + std::to_string(name_it)).c_str(), new TGeoTube(pipeInnerRadius, pipeOuterRadius, positiveYLength / 2), kaptonMed);
kaptonPipeNeg->SetLineColor(kGray);
TGeoVolume* waterVolumeNeg = new TGeoVolume((separationLayerName + "_WaterVolumeNeg_" + std::to_string(name_it)).c_str(), new TGeoTube(0.0, pipeInnerRadius, positiveYLength / 2), waterMed);
waterVolumeNeg->SetLineColor(kBlue);

motherVolume->AddNode(waterVolumeNeg, 1, new TGeoCombiTrans(xPos, -(yInner + yOuter) / 2.0, mZ, rotation));

motherVolume->AddNode(kaptonPipePos, 1, new TGeoCombiTrans(xPos, (yInner + yOuter) / 2.0, mZ, rotation));
motherVolume->AddNode(kaptonPipeNeg, 1, new TGeoCombiTrans(xPos, -(yInner + yOuter) / 2.0, mZ, rotation));

} else {

double yOuter = std::abs(y_circle(xPos, mOuterRadius));
yMax = 2 * yOuter;
pipeLength = yMax;

TGeoVolume* kaptonPipe = new TGeoVolume((separationLayerName + "_KaptonPipe_" + std::to_string(name_it)).c_str(), new TGeoTube(pipeInnerRadius, pipeOuterRadius, pipeLength / 2), kaptonMed);
kaptonPipe->SetLineColor(kGray);
TGeoVolume* waterVolume = new TGeoVolume((separationLayerName + "_WaterVolume_" + std::to_string(name_it)).c_str(), new TGeoTube(0.0, pipeInnerRadius, pipeLength / 2), waterMed);
waterVolume->SetLineColor(kBlue);

motherVolume->AddNode(waterVolume, 1, new TGeoCombiTrans(xPos, 0, mZ, rotation));
motherVolume->AddNode(kaptonPipe, 1, new TGeoCombiTrans(xPos, 0, mZ, rotation));
}

name_it++;
}
}

void FT3Layer::createSeparationLayer(TGeoVolume* motherVolume, const std::string& separationLayerName)
{

FT3Layer::initialize_mat();

double carbonFiberThickness = 0.01;
double foamSpacingThickness = 1.0;

TGeoTube* carbonFiberLayer = new TGeoTube(mInnerRadius, mOuterRadius, carbonFiberThickness / 2);
TGeoTube* foamLayer = new TGeoTube(mInnerRadius, mOuterRadius, foamSpacingThickness / 2);

// volumes
TGeoVolume* carbonFiberLayerVol1 = new TGeoVolume((separationLayerName + "_CarbonFiber1").c_str(), carbonFiberLayer, medCarbonFiber);
TGeoVolume* foamLayerVol = new TGeoVolume((separationLayerName + "_Foam").c_str(), foamLayer, medFoam);
TGeoVolume* carbonFiberLayerVol2 = new TGeoVolume((separationLayerName + "_CarbonFiber2").c_str(), carbonFiberLayer, medCarbonFiber);

carbonFiberLayerVol1->SetLineColor(kGray + 2);
foamLayerVol->SetLineColor(kBlack);
foamLayerVol->SetFillColorAlpha(kBlack, 1.0);
carbonFiberLayerVol2->SetLineColor(kGray + 2);

double zSeparation = foamSpacingThickness / 2.0 + carbonFiberThickness / 2.0;

motherVolume->AddNode(carbonFiberLayerVol1, 1, new TGeoTranslation(0, 0, mZ - zSeparation));
motherVolume->AddNode(foamLayerVol, 1, new TGeoTranslation(0, 0, mZ));
motherVolume->AddNode(carbonFiberLayerVol2, 1, new TGeoTranslation(0, 0, mZ + zSeparation));
}

void FT3Layer::createLayer(TGeoVolume* motherVolume)
{
if (mLayerNumber >= 0) {
// Create tube, set sensitive volume, add to mother volume
if (mLayerNumber >= 0 && mLayerNumber < 3) {

std::string chipName = o2::ft3::GeometryTGeo::getFT3ChipPattern() + std::to_string(mLayerNumber),
sensName = Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), mDirection, mLayerNumber);
Expand Down Expand Up @@ -93,6 +255,20 @@ void FT3Layer::createLayer(TGeoVolume* motherVolume)
LOG(info) << "Inserting " << layerVol->GetName() << " inside " << motherVolume->GetName();
motherVolume->AddNode(layerVol, 1, FwdDiskCombiTrans);

return;
} else if (mLayerNumber >= 3) {

FT3Module module;

// layer structure
std::string frontLayerName = o2::ft3::GeometryTGeo::getFT3LayerPattern() + std::to_string(mDirection) + std::to_string(mLayerNumber) + "_Front";
std::string backLayerName = o2::ft3::GeometryTGeo::getFT3LayerPattern() + std::to_string(mDirection) + std::to_string(mLayerNumber) + "_Back";
std::string separationLayerName = "FT3SeparationLayer" + std::to_string(mDirection) + std::to_string(mLayerNumber);

// createSeparationLayer_waterCooling(motherVolume, separationLayerName);
createSeparationLayer(motherVolume, separationLayerName);

// create disk faces
module.createModule(mZ, mLayerNumber, mDirection, mInnerRadius, mOuterRadius, 0., "front", "rectangular", motherVolume);
module.createModule(mZ, mLayerNumber, mDirection, mInnerRadius, mOuterRadius, 0., "back", "rectangular", motherVolume);
}
}
Loading