Project
Loading...
Searching...
No Matches
Pipe.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
15#include <TGeoTube.h>
16#include <TVirtualMC.h>
17#include "TGeoManager.h" // for TGeoManager, gGeoManager
18#include "TGeoMaterial.h" // for TGeoMaterial
19#include "TGeoMedium.h" // for TGeoMedium
20#include "TGeoVolume.h" // for TGeoVolume
21#include "TGeoCompositeShape.h" // for TGeoCompositeShape
22#include "TCanvas.h"
23// force availability of assert
24#ifdef NDEBUG
25#undef NDEBUG
26#endif
27#include <cassert>
28
29using namespace o2::passive;
30
33 const char* title,
34 bool isTRKActivated,
35 bool isFT3Activated,
36 float pipeRIn,
37 float pipeThickness,
38 float a3ipLength,
39 float vacuumVesselRIn,
40 float vacuumVesselThickness,
41 float vacuumVesselASideLength)
42 : Alice3PassiveBase{name, title},
43 mIsTRKActivated{isTRKActivated},
44 mIsFT3Activated{isFT3Activated},
45 mPipeRIn{pipeRIn},
46 mPipeThick{pipeThickness},
47 mA3IPLength{a3ipLength},
48 mVacuumVesselRIn{vacuumVesselRIn},
49 mVacuumVesselThick{vacuumVesselThickness},
50 mVacuumVesselASideLength{vacuumVesselASideLength}
51{
52}
53
54Alice3Pipe::~Alice3Pipe() = default;
55Alice3Pipe& Alice3Pipe::operator=(const Alice3Pipe& rhs)
56{
57 // self assignment
58 if (this == &rhs) {
59 return *this;
60 }
61
62 // base class assignment
63 Alice3PassiveBase::operator=(rhs);
64
65 return *this;
66}
67
69{
70 createMaterials();
71 //
72 // Class describing the beam Alice3Pipe geometry
73 //
74 // Rotation Matrices
75 //
76 const float kDegRad = TMath::Pi() / 180.;
77 // Rotation by 180 deg
78 TGeoRotation* rot180 = new TGeoRotation("rot180", 90., 180., 90., 90., 180., 0.);
79 TGeoRotation* rotyz = new TGeoRotation("rotyz", 90., 180., 0., 180., 90., 90.);
80 TGeoRotation* rotxz = new TGeoRotation("rotxz", 0., 0., 90., 90., 90., 180.);
81 //
82
83 //
84 // Media
86
87 const TGeoMedium* kMedBe = matmgr.getTGeoMedium("ALICE3_PIPE_BE");
88 const TGeoMedium* kMedVac = matmgr.getTGeoMedium("ALICE3_PIPE_VACUUM");
89
90 // Top volume
91 TGeoVolume* top = gGeoManager->GetVolume("cave");
92 TGeoVolume* barrel = gGeoManager->GetVolume("barrel");
93 if (!barrel) {
94 LOG(fatal) << "Could not find the top volume";
95 }
96
97 // We split the naming of the parts if the beam pipe for ALICE 3 into parts
98 // - pipe A Side
99 // - vacuum vessel (which hosts the primary vacuum and covers all C Side as well)
100 // - iris vacuum vessel (which hosts the secondary vacuum)
101
102 // A3IP update
103 // Vacuum
104 Double_t pipeASideLength = mA3IPLength / 2. - mVacuumVesselThick - mVacuumVesselASideLength;
105 Double_t pipeCSideLength = mA3IPLength / 2. + mVacuumVesselASideLength;
106 TGeoTube* vacuumBasePipe = new TGeoTube("PIPEVACUUM_BASEsh", 0., mPipeRIn, mA3IPLength / 2.);
107 TGeoTube* vacuumBaseVacuumVessel = new TGeoTube("VACUUM_VESSELVACUUM_BASEsh", mPipeRIn, mVacuumVesselRIn, pipeCSideLength / 2.);
108
109 TGeoTranslation* posPipeCSide = new TGeoTranslation("PIPE_CSIDE_POSITION", 0, 0, mVacuumVesselASideLength - pipeCSideLength / 2.);
110 posPipeCSide->RegisterYourself();
111 // Excavate volumes from the vacuum such that there is place for the TRK barrel layers and FT3 disc layers of the IRIS tracker
112 // And the other passive shapes: coldplate, iris tracker vacuum vessel
113 TGeoCompositeShape* vacuumComposite;
114 TGeoVolume* vacuumVolume;
115 TString compositeFormula{"PIPEVACUUM_BASEsh+VACUUM_VESSELVACUUM_BASEsh:PIPE_CSIDE_POSITION"};
116 TString subtractorsFormula;
117
118 if (!mIsTRKActivated) {
119 std::vector<TGeoTube*> trkLayerShapes;
120
121 std::vector<std::array<float, 3>> layersQuotas = {std::array<float, 3>{0.5f, 50.f, 100.e-4}, // TODO: Set layers dynamically. {radius, zLen, thickness}
122 std::array<float, 3>{1.2f, 50.f, 100.e-4},
123 std::array<float, 3>{2.5f, 50.f, 100.e-4}};
124
125 for (auto iLayer{0}; iLayer < layersQuotas.size(); ++iLayer) { // Create TRK layers shapes
126 auto& layerData = layersQuotas[iLayer];
127 trkLayerShapes.emplace_back(new TGeoTube(Form("TRKLAYER_%dsh", iLayer), layerData[0], layerData[0] + layerData[2], layerData[1] / 2.));
128 if (iLayer != 0) {
129 subtractorsFormula += "+";
130 }
131 subtractorsFormula += Form("TRKLAYER_%dsh", iLayer);
132 }
133
134 // IRIS vacuum vessel and coldplate dimensions
135 float coldplateRIn = 2.6f; // cm
136 float coldplateThick = 150.e-3; // cm
137 float coldplateLength = 50.f; // cm
138 float irisVacuumVesselInnerRIn = 0.48f; // cm
139 float irisVacuumVesselOuterRIn = coldplateRIn + coldplateThick;
140 float irisVacuumVesselLength = 70.f; // cm
141 float irisVacuumVesselThick = 150.e-4; // cm
142
143 // Excavate vacuum for hosting cold plate and IRIS tracker
144 TGeoTube* coldPlate = new TGeoTube("TRK_COLDPLATEsh", coldplateRIn, coldplateRIn + coldplateThick, coldplateLength / 2.);
145 subtractorsFormula += "+TRK_COLDPLATEsh";
146
147 TGeoTube* irisVacuumVesselInner = new TGeoTube("TRK_IRISVACUUMVESSELINNERsh", irisVacuumVesselInnerRIn, irisVacuumVesselInnerRIn + irisVacuumVesselThick, irisVacuumVesselLength / 2.);
148 subtractorsFormula += "+TRK_IRISVACUUMVESSELINNERsh";
149
150 TGeoTube* irisVacuumVesselOuter = new TGeoTube("TRK_IRISVACUUMVESSELOUTERsh", irisVacuumVesselOuterRIn, irisVacuumVesselOuterRIn + irisVacuumVesselThick, irisVacuumVesselLength / 2.);
151 subtractorsFormula += "+TRK_IRISVACUUMVESSELOUTERsh";
152
153 TGeoTube* irisVacuumVesselWall = new TGeoTube("TRK_IRISVACUUMVESSELWALLsh", irisVacuumVesselInnerRIn, irisVacuumVesselOuterRIn + irisVacuumVesselThick, irisVacuumVesselThick / 2.);
154 TGeoTranslation* posIrisVacVWallNegZSide = new TGeoTranslation("IRISWALLNEGZ", 0., 0., -irisVacuumVesselLength / 2. - irisVacuumVesselThick / 2.);
155 posIrisVacVWallNegZSide->RegisterYourself();
156 subtractorsFormula += "+TRK_IRISVACUUMVESSELWALLsh:IRISWALLNEGZ";
157
158 TGeoTranslation* posIrisVacVWallPosZSide = new TGeoTranslation("IRISWALLPOSZ", 0., 0., irisVacuumVesselLength / 2. + irisVacuumVesselThick / 2.);
159 posIrisVacVWallPosZSide->RegisterYourself();
160 subtractorsFormula += "+TRK_IRISVACUUMVESSELWALLsh:IRISWALLPOSZ";
161 }
162
163 if (!mIsFT3Activated) {
164 std::vector<TGeoTube*> ft3DiscShapes;
165 std::vector<TGeoTranslation*> ft3DiscPositions;
166
167 std::vector<std::array<float, 4>> discsQuotas = {std::array<float, 4>{0.5f, 2.5f, 100.e-4, 26.}, // TODO: Set discs dynamically. {rIn, rOut, thickness, zpos}
168 std::array<float, 4>{0.5f, 2.5f, 100.e-4, 30.},
169 std::array<float, 4>{0.5f, 2.5f, 100.e-4, 34.},
170 std::array<float, 4>{0.5f, 2.5f, 100.e-4, -26.},
171 std::array<float, 4>{0.5f, 2.5f, 100.e-4, -30.},
172 std::array<float, 4>{0.5f, 2.5f, 100.e-4, -34.}};
173 TString tempSubtractorsFormula = "";
174 if (!mIsTRKActivated) {
175 tempSubtractorsFormula = "+";
176 }
177 for (auto iDisc{0}; iDisc < discsQuotas.size(); ++iDisc) {
178 auto& discData = discsQuotas[iDisc];
179 ft3DiscShapes.emplace_back(new TGeoTube(Form("FT3DISC_%dsh", iDisc), discData[0], discData[1], discData[2] / 2.));
180 ft3DiscPositions.emplace_back(new TGeoTranslation(Form("t%d", iDisc), 0., 0., discData[3]));
181 ft3DiscPositions[iDisc]->RegisterYourself();
182 if (iDisc != 0) {
183 tempSubtractorsFormula += "+";
184 }
185 tempSubtractorsFormula += Form("FT3DISC_%dsh:t%d", iDisc, iDisc);
186 }
187 subtractorsFormula += tempSubtractorsFormula;
188 }
189
190 // Pipe tubes
191 TGeoTube* pipeASide = new TGeoTube("PIPE_Ash", mPipeRIn, mPipeRIn + mPipeThick, pipeASideLength / 2.);
192 TGeoTube* pipeCSide = new TGeoTube("PIPE_Csh", mVacuumVesselRIn, mVacuumVesselRIn + mVacuumVesselThick, pipeCSideLength / 2.);
193 TGeoTube* vacuumVesselWall = new TGeoTube("VACUUM_VESSEL_WALLsh", mPipeRIn, mVacuumVesselRIn + mVacuumVesselThick, mVacuumVesselThick / 2.);
194
195 // Pipe and vacuum vessel positions
196 TGeoTranslation* posVacuumVesselWall = new TGeoTranslation("WALL_POSITION", 0, 0, mVacuumVesselASideLength + mVacuumVesselThick / 2.);
197 posVacuumVesselWall->RegisterYourself();
198 TGeoTranslation* posPipeASide = new TGeoTranslation("PIPE_ASIDE_POSITION", 0, 0, mVacuumVesselASideLength + mVacuumVesselThick + pipeASideLength / 2.);
199 posPipeASide->RegisterYourself();
200
201 // Pipe composite shape and volume
202 TString pipeCompositeFormula =
203 "VACUUM_VESSEL_WALLsh:WALL_POSITION"
204 "+PIPE_Ash:PIPE_ASIDE_POSITION"
205 "+PIPE_Csh:PIPE_CSIDE_POSITION";
206
207 if (subtractorsFormula.Length()) {
208 LOG(info) << "Subtractors formula before : " << subtractorsFormula;
209 subtractorsFormula = Form("-(%s)", subtractorsFormula.Data());
210 LOG(info) << "Subtractors formula after: " << subtractorsFormula;
211
212 vacuumComposite = new TGeoCompositeShape("VACUUM_BASEsh", (compositeFormula + subtractorsFormula).Data());
213 vacuumVolume = new TGeoVolume("VACUUM_BASE", vacuumComposite, kMedVac);
214 } else {
215 vacuumComposite = new TGeoCompositeShape("VACUUM_BASEsh", compositeFormula.Data());
216 vacuumVolume = new TGeoVolume("VACUUM_BASE", vacuumComposite, kMedVac);
217 }
218
219 TGeoCompositeShape* pipeComposite = new TGeoCompositeShape("A3IPsh", pipeCompositeFormula);
220 TGeoVolume* pipeVolume = new TGeoVolume("A3IP", pipeComposite, kMedBe);
221
222 // Add everything to the barrel
223 barrel->AddNode(vacuumVolume, 1, new TGeoTranslation(0, 30.f, 0));
224 barrel->AddNode(pipeVolume, 1, new TGeoTranslation(0, 30.f, 0));
225
226 vacuumVolume->SetLineColor(kGreen + 3);
227 pipeVolume->SetLineColor(kGreen + 3);
228}
229
230void Alice3Pipe::createMaterials()
231{
232 //
233 // Define materials for beam Alice3Pipe
234 //
235 int isxfld = 2;
236 float sxmgmx = 10.;
238
239 //
240 // Air
241 //
242 float aAir[4] = {12.0107, 14.0067, 15.9994, 39.948};
243 float zAir[4] = {6., 7., 8., 18.};
244 float wAir[4] = {0.000124, 0.755267, 0.231781, 0.012827};
245 float dAir = 1.20479E-3;
246 float dAir1 = 1.20479E-11;
247
248 // ****************
249 // Defines tracking media parameters.
250 //
251 float epsil = .1; // Tracking precision,
252 float stemax = -0.01; // Maximum displacement for multiple scat
253 float tmaxfd = -20.; // Maximum angle due to field deflection
254 float deemax = -.3; // Maximum fractional energy loss, DLS
255 float stmin = -.8;
256 // ***************
257
259
260 // Beryllium
261 matmgr.Material("ALICE3_PIPE", 5, "BERILLIUM$", 9.01, 4., 1.848, 35.3, 36.7);
262 matmgr.Medium("ALICE3_PIPE", 5, "BE", 5, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
263
264 // Vacuum
265 matmgr.Mixture("ALICE3_PIPE", 16, "VACUUM$ ", aAir, zAir, dAir1, 4, wAir);
266
267 matmgr.Medium("ALICE3_PIPE", 16, "VACUUM", 16, 0, isxfld, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
268}
269
270// ----------------------------------------------------------------------------
271FairModule* Alice3Pipe::CloneModule() const { return new Alice3Pipe(*this); }
Definition of the Detector class.
ClassImp(IdPath)
static void initFieldTrackingParams(int &mode, float &maxfield)
Definition Detector.cxx:143
static MaterialManager & Instance()
a common base class for passive modules - implementing generic functions
Definition PassiveBase.h:24
FairModule * CloneModule() const override
Clone this object (used in MT mode only)
Definition Pipe.cxx:271
void ConstructGeometry() override
Definition Pipe.cxx:68
GLdouble GLdouble GLdouble GLdouble top
Definition glcorearb.h:4077
GLuint const GLchar * name
Definition glcorearb.h:781
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"