Project
Loading...
Searching...
No Matches
Compensator.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#include <TGeoCompositeShape.h>
17#include <TGeoManager.h>
18#include <TGeoMaterial.h>
19#include <TGeoMatrix.h>
20#include <TGeoMedium.h>
21#include <TGeoTube.h>
22#include <TGeoVolume.h>
23#include <TGeoXtru.h>
24#ifdef NDEBUG
25#undef NDEBUG
26#endif
27#include <cassert>
28
29using namespace o2::passive;
30
32
34Compensator::Compensator(const char* name, const char* Title) : PassiveBase(name, Title) {}
35Compensator::Compensator(const Compensator& rhs) = default;
36
37Compensator& Compensator::operator=(const Compensator& rhs)
38{
39 // self assignment
40 if (this == &rhs) {
41 return *this;
42 }
43
44 // base class assignment
45 PassiveBase::operator=(rhs);
46
47 return *this;
48}
49
50void Compensator::createMaterials()
51{
53
54 //
55 // Create Materials for Magnetic Compensator
56 //
57 Int_t isxfld1 = 2.;
58 Float_t sxmgmx = 10.;
60
61 // we don not have a field map for the Yoke and Coil
62 Int_t isxfld2 = 0; // TODO: set this properly ((AliMagF*)TGeoGlobalMagField::Instance()->GetField())->PrecInteg();
63
64 // ****************
65 // Defines tracking media parameters.
66 // Les valeurs sont commentees pour laisser le defaut
67 // a GEANT (version 3-21, page CONS200), f.m.
68 Float_t epsil, stmin, deemax, tmaxfd, stemax;
69 epsil = .001; // Tracking precision,
70 stemax = -1.; // Maximum displacement for multiple scat
71 tmaxfd = -20.; // Maximum angle due to field deflection
72 deemax = -.3; // Maximum fractional energy loss, DLS
73 stmin = -.8;
74 // ***************
75
76 // --- Define the various materials + tracking media for GEANT ---
77 // Aluminum
78 matmgr.Material("COMP", 9, "ALUMINIUM0", 26.98, 13., 2.7, 8.9, 37.2);
79 matmgr.Medium("COMP", 9, "ALU_C0", 9, 0, isxfld1, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
80 matmgr.Material("COMP", 29, "ALUMINIUM1", 26.98, 13., 2.7, 8.9, 37.2);
81 matmgr.Medium("COMP", 29, "ALU_C1", 29, 0, isxfld1, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
82 matmgr.Material("COMP", 49, "ALUMINIUM2", 26.98, 13., 2.7, 8.9, 37.2);
83 matmgr.Medium("COMP", 49, "ALU_C2", 49, 0, isxfld1, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
84
85 // Iron
86 matmgr.Material("COMP", 10, "IRON0", 55.85, 26., 7.87, 1.76, 17.1);
87 matmgr.Medium("COMP", 10, "FE_C0", 10, 0, isxfld1, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
88 matmgr.Material("COMP", 30, "IRON1", 55.85, 26., 7.87, 1.76, 17.1);
89 matmgr.Medium("COMP", 30, "FE_C1", 30, 0, 1, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
90 matmgr.Material("COMP", 50, "IRON2", 55.85, 26., 7.87, 1.76, 17.1);
91 matmgr.Medium("COMP", 50, "FE_C2", 50, 0, isxfld1, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
92
93 // Copper
94 matmgr.Material("COMP", 17, "COPPER0", 63.55, 29., 8.96, 1.43, 15.1);
95 matmgr.Material("COMP", 37, "COPPER1", 63.55, 29., 8.96, 1.43, 15.1);
96 matmgr.Material("COMP", 57, "COPPER2", 63.55, 29., 8.96, 1.43, 15.1);
97 matmgr.Medium("COMP", 17, "Cu_C0", 17, 0, isxfld1, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
98 matmgr.Medium("COMP", 37, "Cu_C1", 37, 0, isxfld1, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
99 matmgr.Medium("COMP", 57, "Cu_C2", 57, 0, isxfld1, sxmgmx, tmaxfd, stemax, deemax, epsil, stmin);
100}
101
103{
104 createMaterials();
105 createCompensator();
106}
107
108#define kDegrad TMath::DegToRad()
109
110void Compensator::createCompensator()
111{
112 auto top = gGeoManager->GetVolume("caveRB24");
113 top->AddNode(createMagnetYoke(), 1, new TGeoTranslation(0., 0., 1075. - 1313.347));
114}
115
116TGeoVolume* Compensator::createMagnetYoke()
117{
118 TGeoVolumeAssembly* voMagnet = new TGeoVolumeAssembly("DCM0");
119 voMagnet->SetName("DCM0");
120 TGeoRotation* Ry180 = new TGeoRotation("Ry180", 180., 180., 0.);
122 auto kMedAlu = matmgr.getTGeoMedium("COMP_ALU_C0");
123 auto kMedCooper = matmgr.getTGeoMedium("COMP_Cu_C0");
124 auto kMedIron = matmgr.getTGeoMedium("COMP_FE_C0");
125
126 // we use a special optimized tracking medium for the inner part
127 // of the YOKE (FE_C1 instead of FE_C2)
128 auto kMedIronInner = matmgr.getTGeoMedium("COMP_FE_C1");
129
130 const double innerUpLx = 8.;
131 const double innerUpLy = 32.2;
132 const double innerDwLx = 46.;
133 const double innerDwLy = 23.;
134 const double outerLx = 116.4;
135 const double outerLy = 90.2;
136 const double Lz = 250.;
137
138 new TGeoBBox("shMagnetYokeOuter", outerLx / 2.0, outerLy / 2.0, Lz / 2.0);
139 new TGeoBBox("shMagnetYokeInnerUp", innerUpLx / 2.0, innerUpLy / 2.0, Lz / 1.0);
140 new TGeoBBox("shMagnetYokeInnerDw", innerDwLx / 2.0, innerDwLy / 2.0, Lz / 1.0);
141 (new TGeoTranslation("trMagnetYokeOuter", 0.0, -29.1, 0.0))->RegisterYourself();
142 (new TGeoTranslation("trMagnetYokeInnerUp", 0.0, 0.0, 0.0))->RegisterYourself();
143 (new TGeoTranslation("trMagnetYokeInnerDw", 0.0, -27.5, 0.0))->RegisterYourself();
144
145 TGeoCompositeShape* shMagnetYoke =
146 new TGeoCompositeShape("shMagnetBulk",
147 "shMagnetYokeOuter:trMagnetYokeOuter-(shMagnetYokeInnerUp:trMagnetYokeInnerUp+"
148 "shMagnetYokeInnerDw:trMagnetYokeInnerDw)");
149 TGeoVolume* voMagnetYoke = new TGeoVolume("voMagnetYoke", shMagnetYoke, kMedIron);
150
151 // make a second version of volume which is smaller than the first and which can be embedded
152 // into the first for the purpose of defining a "fast physics" region
153 // introduce a thin layer dimension "delta" in which we treat physics correctly
154 // and which we can tune
156 const double delta = param.yokeDelta;
157
158 new TGeoBBox("shMagnetYokeOuterFast", (outerLx - delta) / 2.0, (outerLy - delta) / 2.0, (Lz - delta) / 2.0);
159 new TGeoBBox("shMagnetYokeInnerUpFast", (innerUpLx + delta) / 2.0, (innerUpLy + delta) / 2.0, Lz / 1.0);
160 new TGeoBBox("shMagnetYokeInnerDwFast", (innerDwLx + delta) / 2.0, (innerDwLy + delta) / 2.0, Lz / 1.0);
161
162 TGeoCompositeShape* shMagnetYokeFast =
163 new TGeoCompositeShape("shMagnetInner",
164 "shMagnetYokeOuterFast:trMagnetYokeOuter-(shMagnetYokeInnerUpFast:trMagnetYokeInnerUp+"
165 "shMagnetYokeInnerDwFast:trMagnetYokeInnerDw)");
166
167 TGeoVolume* voMagnetYokeInner = new TGeoVolume("voMagnetYokeInner", shMagnetYokeFast, kMedIronInner);
168 if (delta >= 0.) {
169 voMagnetYoke->AddNode(voMagnetYokeInner, 1, new TGeoTranslation(0., 0., 0.0));
170 }
171
172 // Make the coils:
173 TGeoVolume* voCoilH = gGeoManager->MakeBox("voCoilH", kMedCooper, 12.64 / 2.0, 21.46 / 2.0, 310.5 / 2.0);
174 TGeoVolume* voCoilV = gGeoManager->MakeBox("voCoilV", kMedCooper, 12.64 / 2.0, 35.80 / 2.0, 26.9 / 2.0);
175
176 // Make the top coil supports:
177 // Polygone Coordinates (x,y)
178 Double_t x, y;
179 const Double_t kDegToRad = TMath::Pi() / 180.;
180 const Double_t AngleInner = 4.5 * kDegToRad;
181 const Double_t AngleOuter = 56.0 * kDegToRad;
182 const Double_t ArcStart = 90. - AngleOuter / kDegToRad;
183 const Double_t ArcEnd = 90. + AngleInner / kDegToRad;
184 const Double_t b = 13.6;
185 const Double_t Lx = 37.2;
186 const Double_t Ly = 25.7;
187 const Double_t LxV = 14.9;
188 const Double_t R = 9.50;
189 const Double_t dz = 2.00 / 2.0;
190 const Int_t npoints = 8;
191 Double_t CenterX;
192 Double_t CenterY;
193 Double_t PointsX[npoints] = {0.};
194 Double_t PointsY[npoints] = {0.};
195 Int_t ip = 0;
196 // Start point:
197 x = 0.0;
198 y = 0.0;
199 PointsX[ip] = x;
200 PointsY[ip] = y;
201 ip++;
202 // 1st step:
203 x = 0.00;
204 y = 1.95;
205 PointsX[ip] = x;
206 PointsY[ip] = y;
207 ip++;
208 // 2nd step:
209 x += b;
210 y += b * TMath::Tan(AngleInner);
211 PointsX[ip] = x;
212 PointsY[ip] = y;
213 ip++;
214 // Center of Arc:
215 x += R * TMath::Sin(AngleInner);
216 y -= R * TMath::Cos(AngleInner);
217 CenterX = x;
218 CenterY = y;
219 TGeoTubeSeg* shPolygonArc = new TGeoTubeSeg("shPolygonArc", R - 2.0, R, dz, ArcStart, ArcEnd);
220 (new TGeoTranslation("trPolygonArc", x, y, 0.))->RegisterYourself();
221 // 3rd Step:
222 x += R * TMath::Sin(AngleOuter);
223 y += R * TMath::Cos(AngleOuter);
224 PointsX[ip] = x;
225 PointsY[ip] = y;
226 ip++;
227 // 4th Step:
228 Double_t a = Lx - b - R * TMath::Sin(AngleInner) - R * TMath::Sin(AngleOuter);
229 x = Lx;
230 y -= a * TMath::Tan(AngleOuter);
231 PointsX[ip] = x;
232 PointsY[ip] = y;
233 ip++;
234 // 5th Step:
235 x = Lx;
236 y = -Ly;
237 PointsX[ip] = x;
238 PointsY[ip] = y;
239 ip++;
240 // 6th Step:
241 x = LxV;
242 y = -Ly;
243 PointsX[ip] = x;
244 PointsY[ip] = y;
245 ip++;
246 // 7th Step:
247 x = LxV;
248 y = 0.0;
249 PointsX[ip] = x;
250 PointsY[ip] = y;
251 ip++;
252 //
253 //
254 //
255 TGeoXtru* shPolygon = new TGeoXtru(2);
256 shPolygon->SetNameTitle("shPolygon", "shPolygon");
257 shPolygon->DefinePolygon(npoints, PointsX, PointsY);
258 shPolygon->DefineSection(0, -dz, 0., 0., 1.0); // index, Z position, offset (x,y) and scale for first section
259 shPolygon->DefineSection(1, +dz, 0., 0., 1.0); // idem, second section
260
261 TGeoCompositeShape* shCoilSupportV = new TGeoCompositeShape("shCoilSupportV", "shPolygon+shPolygonArc:trPolygonArc");
262 TGeoVolume* voCoilSupportV = new TGeoVolume("voCoilSupportV", shCoilSupportV, kMedAlu);
263
264 const Double_t MagCoilDx = 12.64 / 2.;
265 const Double_t MagCoilDy = 21.46 / 2.;
266 const Double_t SqOuterDx = MagCoilDx + 2.8;
267 const Double_t SqInnerDx = MagCoilDx + 0.6;
268 const Double_t SqOuterDy = 29.2 / 2.;
269 const Double_t SqInnerDy = 24.8 / 2.;
270 const Double_t SqOuterDz = 15.5 / 2.;
271 const Double_t SqInnerDz = SqOuterDz * 2.;
272 TGeoBBox* shCoilSupportSqOuter = new TGeoBBox("shCoilSupportSqOuter", SqOuterDx, SqOuterDy, SqOuterDz);
273 TGeoBBox* shCoilSupportSqInner = new TGeoBBox("shCoilSupportSqInner", SqInnerDx, SqInnerDy, SqInnerDz);
274 TGeoCompositeShape* shCoilSupportSq =
275 new TGeoCompositeShape("shCoilSupportSq", "shCoilSupportSqOuter - shCoilSupportSqInner");
276 TGeoVolume* voCoilSupportSq = new TGeoVolume("voCoilSupportSq", shCoilSupportSq, kMedAlu);
277
278 const Double_t HSuppDx = (Lx - LxV + 0.6) / 2.0;
279 const Double_t HSuppDy = 2.2 / 2.0;
280 const Double_t HSuppDz = SqOuterDz;
281
282 TGeoVolume* voCoilSupportH = gGeoManager->MakeBox("voCoilSupportH", kMedAlu, HSuppDx, HSuppDy, HSuppDz);
283
284 TGeoVolumeAssembly* voCoilSupport = new TGeoVolumeAssembly("voCoilSupport");
285 voCoilSupportV->SetLineColor(kViolet + 9);
286 voCoilSupportSq->SetLineColor(kBlue - 5);
287 voCoilSupportH->SetLineColor(kPink);
288 // voCoilSupportH -> SetTransparency(16);
289 voCoilSupport->AddNode(voCoilSupportV, 1, new TGeoTranslation(SqOuterDx - LxV, SqOuterDy, 0.));
290 voCoilSupport->AddNode(voCoilSupportSq, 1, new TGeoTranslation(0., 0., 0.));
291 voCoilSupport->AddNode(voCoilSupportH, 1, new TGeoTranslation(SqOuterDx + HSuppDx, SqOuterDy - Ly - HSuppDy, 0.));
292
293 // Make the Top Support for Geodesic reference points:
294 TGeoVolume* voSupportHTop = gGeoManager->MakeBox("voSupportHTop", kMedAlu, 66.0 / 2.0, 2.0 / 2.0, 17.0 / 2.0);
295 TGeoVolume* voSupportHBot = gGeoManager->MakeBox("voSupportHBot", kMedAlu, 14.0 / 2.0, 2.0 / 2.0, 17.0 / 2.0);
296 TGeoVolume* voSupportVert = gGeoManager->MakeBox("voSupportVert", kMedAlu, 3.0 / 2.0, 25.0 / 2.0, 17.0 / 2.0);
297
298 TGeoVolumeAssembly* voSupportGeoRefPoint = new TGeoVolumeAssembly("voSupportGeoRefPoint");
299 voSupportHTop->SetLineColor(kGreen);
300 voSupportHBot->SetLineColor(kGreen);
301 voSupportVert->SetLineColor(kGreen);
302 voSupportGeoRefPoint->AddNode(voSupportHTop, 1, new TGeoTranslation(0.0, 28.0, 0.));
303 voSupportGeoRefPoint->AddNode(voSupportHBot, 1, new TGeoTranslation(+33.0, 1.0, 0.));
304 voSupportGeoRefPoint->AddNode(voSupportHBot, 2, new TGeoTranslation(-33.0, 1.0, 0.));
305 voSupportGeoRefPoint->AddNode(voSupportVert, 1, new TGeoTranslation(+31.5, 14.5, 0.));
306 voSupportGeoRefPoint->AddNode(voSupportVert, 2, new TGeoTranslation(-31.5, 14.5, 0.));
307
308 // Add some color:
309 voMagnetYoke->SetLineColor(kAzure - 7);
310 voCoilH->SetLineColor(kOrange - 3);
311 voCoilV->SetLineColor(kOrange - 3);
312 // Assembling:
313
314 voMagnet->AddNode(voMagnetYoke, 1, new TGeoTranslation(0., 0., 0.0));
315 voMagnet->AddNode(voCoilH, 1, new TGeoTranslation(+16.14, +29.83, 0.0));
316 voMagnet->AddNode(voCoilH, 2, new TGeoTranslation(-16.14, +29.83, 0.0));
317 voMagnet->AddNode(voCoilH, 3, new TGeoTranslation(+16.14, -27.43, 0.0));
318 voMagnet->AddNode(voCoilH, 4, new TGeoTranslation(-16.14, -27.43, 0.0));
319 voMagnet->AddNode(voCoilV, 1, new TGeoTranslation(+16.14, 1.20, +141.8));
320 voMagnet->AddNode(voCoilV, 2, new TGeoTranslation(-16.14, 1.20, +141.8));
321 voMagnet->AddNode(voCoilV, 3, new TGeoTranslation(+16.14, 1.20, -141.8));
322 voMagnet->AddNode(voCoilV, 4, new TGeoTranslation(-16.14, 1.20, -141.8));
323 Double_t zGeoRef = 74.0 / 2. + SqOuterDz + 9.0 + 17.0 / 2.0;
324 voMagnet->AddNode(voSupportGeoRefPoint, 1, new TGeoTranslation(0., 16.0, +zGeoRef));
325 voMagnet->AddNode(voSupportGeoRefPoint, 2, new TGeoTranslation(0., 16.0, -zGeoRef));
326 Double_t zCoilSupp = 29.83 - MagCoilDy - 0.6 + SqInnerDy;
327 voMagnet->AddNode(voCoilSupport, 1, new TGeoTranslation(+16.14, zCoilSupp, 74.0 * 0.5));
328 voMagnet->AddNode(voCoilSupport, 2, new TGeoTranslation(+16.14, zCoilSupp, -74.0 * 0.5));
329 voMagnet->AddNode(voCoilSupport, 3, new TGeoTranslation(+16.14, zCoilSupp, 74.0 * 1.5));
330 voMagnet->AddNode(voCoilSupport, 4, new TGeoTranslation(+16.14, zCoilSupp, -74.0 * 1.5));
331 //
332 voMagnet->AddNode(voCoilSupport, 5, new TGeoCombiTrans(-16.14, zCoilSupp, 74.0 * 0.5, Ry180));
333 voMagnet->AddNode(voCoilSupport, 6, new TGeoCombiTrans(-16.14, zCoilSupp, -74.0 * 0.5, Ry180));
334 voMagnet->AddNode(voCoilSupport, 7, new TGeoCombiTrans(-16.14, zCoilSupp, 74.0 * 1.5, Ry180));
335 voMagnet->AddNode(voCoilSupport, 8, new TGeoCombiTrans(-16.14, zCoilSupp, -74.0 * 1.5, Ry180));
336
337 return (TGeoVolume*)voMagnet;
338}
339
340FairModule* Compensator::CloneModule() const { return new Compensator(*this); }
Definition of the Detector class.
ClassImp(IdPath)
static void initFieldTrackingParams(int &mode, float &maxfield)
Definition Detector.cxx:143
static MaterialManager & Instance()
void ConstructGeometry() override
FairModule * CloneModule() const override
Clone this object (used in MT mode only)
a common base class for passive modules - implementing generic functions
Definition PassiveBase.h:24
GLint GLenum GLint x
Definition glcorearb.h:403
GLdouble GLdouble GLdouble GLdouble top
Definition glcorearb.h:4077
GLuint const GLchar * name
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint y
Definition glcorearb.h:270
GLenum GLfloat param
Definition glcorearb.h:271
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233