Project
Loading...
Searching...
No Matches
FT3Layer.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
16
19
20#include <fairlogger/Logger.h> // for LOG
21
22#include <TGeoManager.h> // for TGeoManager, gGeoManager
23#include <TGeoMatrix.h> // for TGeoCombiTrans, TGeoRotation, etc
24#include <TGeoTube.h> // for TGeoTube, TGeoTubeSeg
25#include <TGeoVolume.h> // for TGeoVolume, TGeoVolumeAssembly
26#include <TGeoCompositeShape.h> // for TGeoCompositeShape
27#include "TMathBase.h" // for Abs
28#include <TMath.h> // for Sin, RadToDeg, DegToRad, Cos, Tan, etc
29
30#include <TGeoBBox.h>
31#include <string>
32#include <cstdio> // for snprintf
33#include <cmath>
34
35class TGeoMedium;
36
37using namespace TMath;
38using namespace o2::ft3;
39using namespace o2::itsmft;
40
42
43FT3Layer::~FT3Layer() = default;
44
45TGeoMaterial* FT3Layer::carbonFiberMat = nullptr;
46TGeoMedium* FT3Layer::medCarbonFiber = nullptr;
47
48TGeoMaterial* FT3Layer::kaptonMat = nullptr;
49TGeoMedium* FT3Layer::kaptonMed = nullptr;
50
51TGeoMaterial* FT3Layer::waterMat = nullptr;
52TGeoMedium* FT3Layer::waterMed = nullptr;
53
54TGeoMaterial* FT3Layer::foamMat = nullptr;
55TGeoMedium* FT3Layer::medFoam = nullptr;
56
57FT3Layer::FT3Layer(Int_t layerDirection, Int_t layerNumber, std::string layerName, Float_t z, Float_t rIn, Float_t rOut, Float_t Layerx2X0, bool partOfMiddleLayers)
58{
59 // Creates a simple parametrized EndCap layer covering the given
60 // pseudorapidity range at the z layer position
61 mDirection = layerDirection;
62 mLayerNumber = layerNumber;
63 mIsMiddleLayer = partOfMiddleLayers;
64 mLayerName = layerName;
65 mZ = layerDirection ? std::abs(z) : -std::abs(z);
66 mx2X0 = Layerx2X0;
67 mInnerRadius = rIn;
68 mOuterRadius = rOut;
69 const double Si_X0 = 9.5;
70 mChipThickness = Layerx2X0 * Si_X0;
71
72 // Sanity checks
73 if (std::isnan(mZ)) {
74 LOG(fatal) << "FT3 Layer " << mLayerNumber << " has z = NaN, which is not a valid number.";
75 }
76 if (mZ < 0.001 && mZ > -0.001) {
77 LOG(fatal) << "FT3 Layer " << mLayerNumber << " has z = " << mZ << " cm, which is very close to 0.";
78 }
79
80 LOG(info) << "Creating FT3 Layer " << mLayerNumber << " ; direction " << mDirection;
81 LOG(info) << " Using silicon X0 = " << Si_X0 << " to emulate layer radiation length.";
82 LOG(info) << " Layer z = " << mZ << " ; R_in = " << mInnerRadius << " ; R_out = " << mOuterRadius << " ; x2X0 = " << mx2X0 << " ; ChipThickness = " << mChipThickness;
83}
84
86{
87
88 if (carbonFiberMat) {
89 return;
90 }
91
92 carbonFiberMat = new TGeoMaterial("CarbonFiber", 12.0, 6.0, 1.6);
93 medCarbonFiber = new TGeoMedium("CarbonFiber", 1, carbonFiberMat);
94
95 auto* itsC = new TGeoElement("FT3_C", "Carbon", 6, 12.0107);
96
97 auto* itsFoam = new TGeoMixture("FT3_Foam", 1);
98 itsFoam->AddElement(itsC, 1);
99 itsFoam->SetDensity(0.17);
100
101 medFoam = new TGeoMedium("FT3_Foam", 1, itsFoam);
102 foamMat = medFoam->GetMaterial();
103
104 kaptonMat = new TGeoMaterial("Kapton (cooling pipe)", 13.84, 6.88, 1.346);
105 kaptonMed = new TGeoMedium("Kapton (cooling pipe)", 1, kaptonMat);
106
107 waterMat = new TGeoMaterial("Water", 18.01528, 8.0, 1.064);
108 waterMed = new TGeoMedium("Water", 2, waterMat);
109}
110
111static double y_circle(double x, double radius)
112{
113 return (x * x < radius * radius) ? std::sqrt(radius * radius - x * x) : 0;
114}
115
116void FT3Layer::createSeparationLayer_waterCooling(TGeoVolume* motherVolume, const std::string& separationLayerName)
117{
118
120
121 const double carbonFiberThickness = 0.01; // cm
122 const double foamSpacingThickness = 0.5; // cm
123
124 TGeoTube* carbonFiberLayer = new TGeoTube(mInnerRadius, mOuterRadius, carbonFiberThickness / 2);
125
126 // volumes
127 TGeoVolume* carbonFiberLayerVol1 = new TGeoVolume((separationLayerName + "_CarbonFiber1").c_str(), carbonFiberLayer, medCarbonFiber);
128 TGeoVolume* carbonFiberLayerVol2 = new TGeoVolume((separationLayerName + "_CarbonFiber2").c_str(), carbonFiberLayer, medCarbonFiber);
129
130 carbonFiberLayerVol1->SetLineColor(kGray + 2);
131 carbonFiberLayerVol2->SetLineColor(kGray + 2);
132
133 const double zSeparation = foamSpacingThickness / 2.0 + carbonFiberThickness / 2.0;
134
135 motherVolume->AddNode(carbonFiberLayerVol1, 1, new TGeoTranslation(0, 0, mZ - zSeparation));
136 motherVolume->AddNode(carbonFiberLayerVol2, 1, new TGeoTranslation(0, 0, mZ + zSeparation));
137
138 const double pipeOuterRadius = 0.20;
139 const double kaptonThickness = 0.0025;
140 const double pipeInnerRadius = pipeOuterRadius - kaptonThickness;
141 const double pipeMaxLength = mOuterRadius * 2.0;
142
143 int name_it = 0;
144
145 // positions of the pipes depending on the overlap of the sensors inactive regions: (ALICE 3 dimensions)
146 // partial:
147 // 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};
148 // complete:
149 // 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};
150 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};
151
152 for (double xPos : X_pos) {
153
154 double pipeLength = pipeMaxLength;
155 double yMax = 0.0;
156
157 TGeoRotation* rotation = new TGeoRotation();
158 rotation->RotateX(90);
159
160 if (std::abs(xPos) < mInnerRadius) {
161 double yInner = std::abs(y_circle(xPos, mInnerRadius));
162 double yOuter = std::abs(y_circle(xPos, mOuterRadius));
163
164 yMax = 2 * yOuter;
165 pipeLength = yMax;
166
167 double positiveYLength = yOuter - yInner;
168
169 TGeoVolume* kaptonPipePos = new TGeoVolume((separationLayerName + "_KaptonPipePos_" + std::to_string(name_it)).c_str(), new TGeoTube(pipeInnerRadius, pipeOuterRadius, positiveYLength / 2), kaptonMed);
170 kaptonPipePos->SetLineColor(kGray);
171 TGeoVolume* waterVolumePos = new TGeoVolume((separationLayerName + "_WaterVolumePos_" + std::to_string(name_it)).c_str(), new TGeoTube(0.0, pipeInnerRadius, positiveYLength / 2), waterMed);
172 waterVolumePos->SetLineColor(kBlue);
173
174 motherVolume->AddNode(waterVolumePos, 1, new TGeoCombiTrans(xPos, (yInner + yOuter) / 2.0, mZ, rotation));
175
176 TGeoVolume* kaptonPipeNeg = new TGeoVolume((separationLayerName + "_KaptonPipeNeg_" + std::to_string(name_it)).c_str(), new TGeoTube(pipeInnerRadius, pipeOuterRadius, positiveYLength / 2), kaptonMed);
177 kaptonPipeNeg->SetLineColor(kGray);
178 TGeoVolume* waterVolumeNeg = new TGeoVolume((separationLayerName + "_WaterVolumeNeg_" + std::to_string(name_it)).c_str(), new TGeoTube(0.0, pipeInnerRadius, positiveYLength / 2), waterMed);
179 waterVolumeNeg->SetLineColor(kBlue);
180
181 motherVolume->AddNode(waterVolumeNeg, 1, new TGeoCombiTrans(xPos, -(yInner + yOuter) / 2.0, mZ, rotation));
182
183 motherVolume->AddNode(kaptonPipePos, 1, new TGeoCombiTrans(xPos, (yInner + yOuter) / 2.0, mZ, rotation));
184 motherVolume->AddNode(kaptonPipeNeg, 1, new TGeoCombiTrans(xPos, -(yInner + yOuter) / 2.0, mZ, rotation));
185
186 } else {
187
188 double yOuter = std::abs(y_circle(xPos, mOuterRadius));
189 yMax = 2 * yOuter;
190 pipeLength = yMax;
191
192 TGeoVolume* kaptonPipe = new TGeoVolume((separationLayerName + "_KaptonPipe_" + std::to_string(name_it)).c_str(), new TGeoTube(pipeInnerRadius, pipeOuterRadius, pipeLength / 2), kaptonMed);
193 kaptonPipe->SetLineColor(kGray);
194 TGeoVolume* waterVolume = new TGeoVolume((separationLayerName + "_WaterVolume_" + std::to_string(name_it)).c_str(), new TGeoTube(0.0, pipeInnerRadius, pipeLength / 2), waterMed);
195 waterVolume->SetLineColor(kBlue);
196
197 motherVolume->AddNode(waterVolume, 1, new TGeoCombiTrans(xPos, 0, mZ, rotation));
198 motherVolume->AddNode(kaptonPipe, 1, new TGeoCombiTrans(xPos, 0, mZ, rotation));
199 }
200
201 name_it++;
202 }
203}
204
205void FT3Layer::createSeparationLayer(TGeoVolume* motherVolume, const std::string& separationLayerName)
206{
207
209
210 constexpr double carbonFiberThickness = 0.01; // cm
211 constexpr double foamSpacingThickness = 1.0; // cm
212
213 TGeoTube* carbonFiberLayer = new TGeoTube(mInnerRadius, mOuterRadius, carbonFiberThickness / 2);
214 TGeoTube* foamLayer = new TGeoTube(mInnerRadius, mOuterRadius, foamSpacingThickness / 2);
215
216 // volumes
217 TGeoVolume* carbonFiberLayerVol1 = new TGeoVolume((separationLayerName + "_CarbonFiber1").c_str(), carbonFiberLayer, medCarbonFiber);
218 TGeoVolume* foamLayerVol = new TGeoVolume((separationLayerName + "_Foam").c_str(), foamLayer, medFoam);
219 TGeoVolume* carbonFiberLayerVol2 = new TGeoVolume((separationLayerName + "_CarbonFiber2").c_str(), carbonFiberLayer, medCarbonFiber);
220
221 carbonFiberLayerVol1->SetLineColor(kGray + 2);
222 foamLayerVol->SetLineColor(kBlack);
223 foamLayerVol->SetFillColorAlpha(kBlack, 1.0);
224 carbonFiberLayerVol2->SetLineColor(kGray + 2);
225
226 const double zSeparation = foamSpacingThickness / 2.0 + carbonFiberThickness / 2.0;
227
228 motherVolume->AddNode(carbonFiberLayerVol1, 1, new TGeoTranslation(0, 0, 0 - zSeparation));
229 motherVolume->AddNode(foamLayerVol, 1, new TGeoTranslation(0, 0, 0));
230 motherVolume->AddNode(carbonFiberLayerVol2, 1, new TGeoTranslation(0, 0, 0 + zSeparation));
231}
232
233void FT3Layer::createLayer(TGeoVolume* motherVolume)
234{
235 if (mLayerNumber < 0) {
236 LOG(fatal) << "Invalid layer number " << mLayerNumber << " for FT3 layer.";
237 }
238 if (mIsMiddleLayer) { // ML disks
239
240 std::string chipName = o2::ft3::GeometryTGeo::getFT3ChipPattern() + std::to_string(mLayerNumber),
241 sensName = Form("%s_%d_%d", GeometryTGeo::getFT3SensorPattern(), mDirection, mLayerNumber);
242 TGeoTube* sensor = new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2);
243 TGeoTube* chip = new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2);
244 TGeoTube* layer = new TGeoTube(mInnerRadius, mOuterRadius, mChipThickness / 2);
245
246 TGeoMedium* medSi = gGeoManager->GetMedium("FT3_SILICON$");
247 TGeoMedium* medAir = gGeoManager->GetMedium("FT3_AIR$");
248
249 TGeoVolume* sensVol = new TGeoVolume(sensName.c_str(), sensor, medSi);
250 sensVol->SetLineColor(kYellow);
251 TGeoVolume* chipVol = new TGeoVolume(chipName.c_str(), chip, medSi);
252 chipVol->SetLineColor(kYellow);
253 TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir);
254 layerVol->SetLineColor(kYellow);
255
256 LOG(info) << "Inserting " << sensVol->GetName() << " inside " << chipVol->GetName();
257 chipVol->AddNode(sensVol, 1, nullptr);
258
259 LOG(info) << "Inserting " << chipVol->GetName() << " inside " << layerVol->GetName();
260 layerVol->AddNode(chipVol, 1, nullptr);
261
262 // Finally put everything in the mother volume
263 auto* FwdDiskRotation = new TGeoRotation("FwdDiskRotation", 0, 0, 180);
264 auto* FwdDiskCombiTrans = new TGeoCombiTrans(0, 0, mZ, FwdDiskRotation);
265
266 LOG(info) << "Inserting " << layerVol->GetName() << " inside " << motherVolume->GetName();
267 motherVolume->AddNode(layerVol, 1, FwdDiskCombiTrans);
268
269 } else { // OT disks
270
271 FT3Module module;
272
273 // layer structure
274 std::string frontLayerName = o2::ft3::GeometryTGeo::getFT3LayerPattern() + std::to_string(mDirection) + std::to_string(mLayerNumber) + "_Front";
275 std::string backLayerName = o2::ft3::GeometryTGeo::getFT3LayerPattern() + std::to_string(mDirection) + std::to_string(mLayerNumber) + "_Back";
276 std::string separationLayerName = "FT3SeparationLayer" + std::to_string(mDirection) + std::to_string(mLayerNumber);
277
278 TGeoMedium* medAir = gGeoManager->GetMedium("FT3_AIR$");
279 TGeoTube* layer = new TGeoTube(mInnerRadius, mOuterRadius, 10 * mChipThickness / 2);
280 TGeoVolume* layerVol = new TGeoVolume(mLayerName.c_str(), layer, medAir);
281 layerVol->SetLineColor(kYellow + 2);
282
283 // createSeparationLayer_waterCooling(motherVolume, separationLayerName);
284 createSeparationLayer(layerVol, separationLayerName);
285
286 // create disk faces
287 module.createModule(0, mLayerNumber, mDirection, mInnerRadius, mOuterRadius, 0., "front", "rectangular", layerVol);
288 module.createModule(0, mLayerNumber, mDirection, mInnerRadius, mOuterRadius, 0., "back", "rectangular", layerVol);
289
290 // Finally put everything in the mother volume
291 auto* FwdDiskRotation = new TGeoRotation("FwdDiskRotation", 0, 0, 180);
292 auto* FwdDiskCombiTrans = new TGeoCombiTrans(0, 0, mZ, FwdDiskRotation);
293
294 LOG(info) << "Inserting " << layerVol->GetName() << " inside " << motherVolume->GetName();
295 motherVolume->AddNode(layerVol, 1, FwdDiskCombiTrans);
296 }
297}
ClassImp(FT3Layer)
Definition of the FT3Layer class.
float & yMax
Definition of the GeometryTGeo class.
static TGeoMaterial * waterMat
Definition FT3Layer.h:74
virtual void createLayer(TGeoVolume *motherVolume)
Definition FT3Layer.cxx:233
static TGeoMedium * medFoam
Definition FT3Layer.h:78
static TGeoMedium * medCarbonFiber
Definition FT3Layer.h:69
void createSeparationLayer_waterCooling(TGeoVolume *motherVolume, const std::string &separationLayerName)
Definition FT3Layer.cxx:116
static void initialize_mat()
Definition FT3Layer.cxx:85
static TGeoMedium * waterMed
Definition FT3Layer.h:75
~FT3Layer() override
Default destructor.
FT3Layer()=default
static TGeoMaterial * carbonFiberMat
Definition FT3Layer.h:68
static TGeoMedium * kaptonMed
Definition FT3Layer.h:72
static TGeoMaterial * kaptonMat
Definition FT3Layer.h:71
void createSeparationLayer(TGeoVolume *motherVolume, const std::string &separationLayerName)
Definition FT3Layer.cxx:205
static TGeoMaterial * foamMat
Definition FT3Layer.h:77
static const char * getFT3SensorPattern()
static const char * getFT3ChipPattern()
static const char * getFT3LayerPattern()
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum GLuint GLint GLint layer
Definition glcorearb.h:1310
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"