1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 #include <TVirtualMC.h>
19 #include <TGeoManager.h>
20 #include <TGeoVolume.h>
21 #include <TGeoMedium.h>
22 #include <TGeoMatrix.h>
27 #include <TGeoCompositeShape.h>
30 #include "AliDIPOv3.h"
36 //_____________________________________________________________________________
37 AliDIPOv3::AliDIPOv3()
40 // Last design of magnetic dipole version 3
44 //_____________________________________________________________________________
45 AliDIPOv3::AliDIPOv3(const char *name, const char *title)
46 : AliDIPOv2(name,title)
49 // Standard constructor for the magnetic dipole version 3
53 //_____________________________________________________________________________
54 void AliDIPOv3::CreateSpectrometerDipole()
56 // Detailed dipole geometry as built
58 // Drawing: ALIP2A__0026
59 // Geometer measurements: EDMS 596079
65 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
69 TGeoMedium* kMedSteel = gGeoManager->GetMedium("DIPO_ST_C3");
70 TGeoMedium* kMedCoil = gGeoManager->GetMedium("DIPO_Coil_C1");
71 TGeoMedium* kMedCoilSh = gGeoManager->GetMedium("DIPO_Coil_C3");
72 TGeoMedium* kMedCable = gGeoManager->GetMedium("DIPO_ALU_C2");
73 TGeoMedium* kMedAlu = gGeoManager->GetMedium("DIPO_ALU_C2");
74 TGeoMedium* kMedAir = gGeoManager->GetMedium("DIPO_AIR_MUON");
80 TGeoRotation* rotxz = new TGeoRotation("rotxz", 90., 0., 90., 90., 180., 0.);
81 TGeoRotation* rotxzlhc = new TGeoRotation("rotxzlhc", 180., 180. + alhc, 0.);
82 TGeoRotation* rotlhc = new TGeoRotation("rotlhc", 0., alhc, 0.);
84 TGeoRotation* rotxz108 = new TGeoRotation("rotxz108", 90., 108., 90., 198., 180., 0.);
85 TGeoRotation* rotxz180 = new TGeoRotation("rotxz180", 90., 180., 90., 270., 180., 0.);
86 TGeoRotation* rotxz288 = new TGeoRotation("rotxz288", 90., 288., 90., 18., 180., 0.);
88 TGeoRotation* rotxy180 = new TGeoRotation("rotxy180", 90., 180., 90., 270., 0., 0.);
89 TGeoRotation* rotxy108 = new TGeoRotation("rotxy108", 90., 108., 90., 198., 0., 0.);
90 TGeoRotation* rotxy288 = new TGeoRotation("rotxy288", 90., 288., 90., 18., 0., 0.);
92 TGeoRotation* rot00 = new TGeoRotation("rot00", 180., 0., 90., 151., 90., 61.);
93 TGeoRotation* rot01 = new TGeoRotation("rot01", 180., 0., 90., 29.,- 90., -61.);
94 TGeoRotation* rot02 = new TGeoRotation("rot02", 0., 0., 90., 151., 90., 61.);
95 TGeoRotation* rot03 = new TGeoRotation("rot03", 0., 0., 90., 29.,- 90., -61.);
96 TGeoRotation* rot04 = new TGeoRotation("rot04", 90., 61., 90., 151., 0., 0.);
97 TGeoRotation* rot05 = new TGeoRotation("rot05", 90., -61., 90.,-151., 0., 0.);
98 TGeoRotation* rot06 = new TGeoRotation("rot06", 90., 119., 90., 209., 0., 0.);
99 TGeoRotation* rot07 = new TGeoRotation("rot07", 90.,-119., 90.,-209., 0., 0.);
101 const Float_t dipoleL = 498.;
102 const Float_t kZDipoleR = 1244.;
103 const Float_t kZDipole = kZDipoleR - dipoleL/2.;
104 const Float_t kZDipoleF = kZDipoleR - dipoleL;
105 const Float_t yokeLength = 309.4;
106 const Float_t blockLength = yokeLength / 7.;
107 const Float_t gapWidthFront = 297.6;
108 const Float_t gapWidthRear = 395.4;
109 const Float_t dGap = (gapWidthRear - gapWidthFront) / 12.;
110 const Float_t gapHeight = 609.1;
111 const Float_t blockHeight = 145.45;
112 const Float_t dzCoil = 4.45;
119 Float_t rcD1 = kZDipole * TMath::Tan(9. * kDegrad);
120 TGeoPcon* shDDIP1 = new TGeoPcon("shDDIP1", 0., 360., 4);
121 shDDIP1->DefineSection(0, -dipoleL/2. - 5., 0., (kZDipoleF -5.) * TMath::Tan(9. * kDegrad));
122 shDDIP1->DefineSection(1, 0., 0., rcD1);
123 Float_t rcD2 = rcD1 + dipoleL/2. * TMath::Tan(10.1 * kDegrad);
124 shDDIP1->DefineSection(2, +dipoleL/2., 0., rcD2);
125 shDDIP1->DefineSection(3, +dipoleL/2. + 5., 0., rcD2);
127 TGeoCombiTrans* trDDIP = new TGeoCombiTrans("trDDIP", 0., dipoleL/2. * TMath::Tan(alhc * kDegrad), 0., rotlhc);
128 trDDIP->RegisterYourself();
130 TGeoBBox* shDDIP2 = new TGeoBBox("shDDIP2", 164, 182., 25.);
132 TGeoPcon* shDDIP3 = new TGeoPcon("shDDIP3", 0., 360., 5);
133 Float_t z30 = 825. - kZDipole;
134 Float_t zst = 1052. - kZDipole;
137 shDDIP3->DefineSection(0, -dipoleL/2. - 10., 0., (kZDipoleF - 10.) * TMath::Tan(2. * kDegrad) + 0.2);
138 shDDIP3->DefineSection(1, z30, 0., 28.8 + 0.2);
139 shDDIP3->DefineSection(2, zst, 0., 28.8 + 0.2);
140 shDDIP3->DefineSection(3, zst, 0., 35.8);
141 shDDIP3->DefineSection(4, +dipoleL/2. + 10., 0., 35.8 + (dipoleL/2. + 10. - zst) * TMath::Tan(2. * kDegrad));
143 TGeoCompositeShape* shDDIP = new TGeoCompositeShape("shDDIP", "(shDDIP2 + shDDIP1:trDDIP) - shDDIP3:trDDIP");
145 TGeoVolume* voDDIP = new TGeoVolume("DDIP", shDDIP, kMedAir);
150 TGeoVolumeAssembly* asYoke = new TGeoVolumeAssembly("DYoke");
153 Float_t lx0 = gapWidthFront + 2. * blockHeight;
156 TGeoVolumeAssembly* asYokeBase = new TGeoVolumeAssembly("DYokeBase");
157 for (Int_t i = 0; i < 7; i++) {
158 sprintf(name, "DYokeBaseBlock%1d", i);
159 TGeoVolume* voBaseBlock = new TGeoVolume(name,
160 new TGeoBBox(lx/2., blockHeight/2., blockLength/2.),
162 asYokeBase->AddNode(voBaseBlock, 1, new TGeoTranslation(0., 0., Float_t(i - 3) * blockLength));
166 asYoke->AddNode(asYokeBase, 1, new TGeoTranslation(0., -(gapHeight + blockHeight)/2. , 0.));
167 asYoke->AddNode(asYokeBase, 2, new TGeoTranslation(0., +(gapHeight + blockHeight)/2. , 0.));
171 TGeoVolumeAssembly* asYokeSide = new TGeoVolumeAssembly("DYokeSide");
172 TGeoVolume* voSideBlock = new TGeoVolume("DSideBlock",
173 new TGeoBBox(blockHeight/2., gapHeight/2., blockLength/2.),
176 for (Int_t i = 0; i < 7; i++) {
177 asYokeSide->AddNode(voSideBlock, i, new TGeoTranslation(Float_t(i - 3) * dGap, 0., Float_t(i - 3) * blockLength));
181 asYoke->AddNode(asYokeSide, 1, new TGeoTranslation(+lx0/2. + 3. * dGap - blockHeight/2., 0., 0.));
182 asYoke->AddNode(asYokeSide, 2, new TGeoCombiTrans( -lx0/2. - 3. * dGap + blockHeight/2., 0., 0., rotxz));
187 Float_t coilRi = 206.;
189 Float_t coilRo = coilRi + coilD;
191 Float_t phiMin = -61.;
192 Float_t phiMax = 61.;
193 Float_t lengthSt = 240. + 33.9;
194 Float_t phiKnee = phiMax * kDegrad;
195 Float_t rKnee = 31.5;
198 TGeoVolumeAssembly* asCoil = new TGeoVolumeAssembly("DCoil");
200 TGeoVolume* voDC1 = new TGeoVolume("DC1",
201 new TGeoTubeSeg(coilRi, coilRo, coilH / 2., phiMin, phiMax),
203 TGeoVolume* voDC2 = new TGeoVolume("DC2",
204 new TGeoTubeSeg(coilRi + 5., coilRo - 5., coilH / 2., phiMin, phiMax),
207 voDC1->AddNode(voDC2, 1, gGeoIdentity);
208 voDC2->SetVisibility(0);
210 dz = lengthSt / 2. + coilH / 2. + rKnee;
213 asCoil->AddNode(voDC1, 1, new TGeoTranslation(-dx, 0., -dz));
214 asCoil->AddNode(voDC1, 2, new TGeoCombiTrans( dx, 0., -dz, rotxy180));
215 asCoil->AddNode(voDC1, 3, new TGeoTranslation(-dx, 0., dz));
216 asCoil->AddNode(voDC1, 4, new TGeoCombiTrans( dx, 0., dz, rotxz180));
222 TGeoVolume* voDC11 = new TGeoVolume("DC11",
223 new TGeoTubeSeg(rKnee, rKnee + coilH, coilD/2., 270., 360.),
227 dx = - TMath::Cos(phiKnee) * (coilRi + coilD/2.);
228 dy = - TMath::Sin(phiKnee) * (coilRi + coilD/2.);
231 asCoil->AddNode(voDC11, 1, new TGeoCombiTrans( dx, dy, -dz, rot00));
232 asCoil->AddNode(voDC11, 2, new TGeoCombiTrans( dx, dy, dz, rot02));
233 asCoil->AddNode(voDC11, 3, new TGeoCombiTrans(-dx, dy, -dz, rot01));
234 asCoil->AddNode(voDC11, 4, new TGeoCombiTrans(-dx, dy, dz, rot03));
236 TGeoVolume* voDC12 = new TGeoVolume("DC12",
237 new TGeoTubeSeg(rKnee, rKnee + coilH, coilD/2., 0., 90.),
241 asCoil->AddNode(voDC12, 1, new TGeoCombiTrans( dx, -dy, -dz, rot01));
242 asCoil->AddNode(voDC12, 2, new TGeoCombiTrans( dx, -dy, dz, rot03));
243 asCoil->AddNode(voDC12, 3, new TGeoCombiTrans(-dx, -dy, -dz, rot00));
244 asCoil->AddNode(voDC12, 4, new TGeoCombiTrans(-dx, -dy, dz, rot02));
249 TGeoVolume* voDL0 = new TGeoVolume("DL0",
250 new TGeoBBox(coilD / 2. + 2., coilH / 2. + 2., lengthSt / 2.),
253 TGeoVolume* voDL1 = new TGeoVolume("DL1",
254 new TGeoBBox(coilD / 2., coilH / 2., lengthSt / 2.),
258 TGeoVolume* voDL2 = new TGeoVolume("DL2",
259 new TGeoBBox(coilD / 2. - 5., coilH / 2. - 5., lengthSt / 2. - 5.),
262 TGeoVolume* voDL3 = new TGeoVolume("DL3",
263 new TGeoBBox(1., coilH / 2., 120.),
266 TGeoVolume* voDL4 = new TGeoVolume("DL4",
267 new TGeoBBox(coilD/2., 1., 120.),
270 voDL0->SetVisibility(0);
271 voDL1->AddNode(voDL2, 1, gGeoIdentity);
272 voDL0->AddNode(voDL1, 1, gGeoIdentity);
273 voDL0->AddNode(voDL3, 1, new TGeoTranslation(-coilD/2. - 1., 0., 0.));
274 voDL0->AddNode(voDL3, 2, new TGeoTranslation(+coilD/2. + 1., 0., 0.));
275 voDL0->AddNode(voDL4, 1, new TGeoTranslation(0., -coilH/2. - 1., 0.));
276 voDL0->AddNode(voDL4, 2, new TGeoTranslation(0., +coilH/2. + 1., 0.));
279 dx += (rKnee + coilH/2.) * TMath::Sin(phiKnee);
280 dy -= (rKnee + coilH/2.) * TMath::Cos(phiKnee);
283 asCoil->AddNode(voDL0, 1, new TGeoCombiTrans( dx, dy, dz, rot04));
284 asCoil->AddNode(voDL0, 2, new TGeoCombiTrans( dx, -dy, dz, rot05));
285 asCoil->AddNode(voDL0, 3, new TGeoCombiTrans(-dx, dy, dz, rot06));
286 asCoil->AddNode(voDL0, 4, new TGeoCombiTrans(-dx, -dy, dz, rot07));
291 TGeoVolumeAssembly* asContactor = new TGeoVolumeAssembly("DContactor");
293 TGeoVolume* voDC10 = new TGeoVolume("DC10",
294 new TGeoTubeSeg(coilRo + 5.1, coilRo + 73.5, 1., -20., 20.),
296 asContactor->AddNode(voDC10, 1, new TGeoTranslation(dx, 0, -32.325));
297 asContactor->AddNode(voDC10, 2, new TGeoTranslation(dx, 0, +32.325));
304 TGeoVolumeAssembly* asDCoilSupport = new TGeoVolumeAssembly("DCoilSupport");
306 // Steel fixed to the yoke
307 TGeoVolume* voDCS01 = new TGeoVolume("DCS01",
308 new TGeoTubeSeg(coilRo, 325., 1., 21., 51.),
312 TGeoVolume* voDCS02 = new TGeoVolume("DCS02",
313 new TGeoTubeSeg(coilRo, coilRo + 3.125, sW/2., 21., 51.),
315 TGeoVolume* voDCS021 = new TGeoVolume("DCS021",
316 new TGeoConeSeg(sW/2., coilRo, 320., coilRo, coilRo + 2., 21., 21.4),
321 TGeoVolume* voDCS03 = new TGeoVolume("DCS03",
322 new TGeoTubeSeg(coilRi - 3.125, coilRo + 3.125, 3.125/2., 21., 51.),
325 TGeoVolume* voDCS04 = new TGeoVolume("DCS04",
326 new TGeoTubeSeg(coilRi - 3.125, coilRi, coilH/2., 21., 51.),
330 TGeoVolume* voDCS05 = new TGeoVolume("DCS05",
331 new TGeoTubeSeg(coilRi - 3.125, coilRo, 3.125/2., 21., 51.),
334 asDCoilSupport->AddNode(voDCS02, 1, new TGeoTranslation(0., 0., -(sW - coilH)/2.));
335 asDCoilSupport->AddNode(voDCS04, 1, gGeoIdentity);
336 for (Int_t i = 0; i < 9; i++)
339 sprintf(name, "rotdcs%1d", i);
340 Float_t phi = Float_t(i) * 3.75;
341 TGeoRotation* rot = new TGeoRotation(name, 90., phi, 90., 90. + phi, 0., 0.);
342 asDCoilSupport->AddNode(voDCS021, i, new TGeoCombiTrans(0., 0., -(sW - coilH)/2., rot));
347 asDCoilSupport->AddNode(voDCS01, 1, new TGeoTranslation(0., 0., -sW/2. - (sW - coilH)/2. - 3.125/2.));
348 asDCoilSupport->AddNode(voDCS03, 1, new TGeoTranslation(0., 0., +coilH/2. + 3.125/2.));
349 asDCoilSupport->AddNode(voDCS05, 1, new TGeoTranslation(0., 0., -coilH/2. - 3.125/2.));
353 // SAA1 Support: Hanger 1
355 TGeoTranslation* trHanger = new TGeoTranslation("trHanger", 0., 250., 0.);
356 trHanger->RegisterYourself();
358 Float_t rmin1, rmin2, rmax1, rmax2;
360 Float_t zHanger1 = 811.9;
361 TGeoBBox* shHanger11 = new TGeoBBox("shHanger11", 2.5/2., 250., 25./2.);
363 rmin1 = (zHanger1 - 13.) * TMath::Tan(2. * kDegrad);
364 rmin2 = rmin1 + 26. * TMath::Tan( 2.0 * kDegrad);
365 rmax1 = (zHanger1 - 13.) * TMath::Tan(9. * kDegrad);
366 rmax2 = rmax1 + 26. * TMath::Tan(9. * kDegrad);
368 TGeoCone* shHanger12 = new TGeoCone("shHanger12", 13., rmin1, rmax1, rmin2, rmax2);
369 TGeoCompositeShape* shHanger1 = new TGeoCompositeShape("shHanger1", "shHanger12*shHanger11:trHanger");
370 TGeoVolume* voHanger1 = new TGeoVolume("DHanger1", shHanger1, kMedSteel);
372 // SAA1 Support: Hanger 2
374 Float_t zHanger2 = 1171.9;
375 TGeoBBox* shHanger21 = new TGeoBBox("shHanger21", 3.5/2., 250., 25./2.);
378 rmin1 = 35.8 + (zHanger2 - 13. - zst - kZDipole) * TMath::Tan(2. * kDegrad);
379 rmin2 = rmin1 + 26. * TMath::Tan( 2.0 * kDegrad);
380 rmax1 = rcD1 + (zHanger2 - 13. - kZDipole) * TMath::Tan(10.1 * kDegrad);
381 rmax2 = rmax1 + 26. * TMath::Tan(10.1 * kDegrad);
382 TGeoCone* shHanger22 = new TGeoCone("shHanger22", 13., rmin1, rmax1, rmin2, rmax2);
383 TGeoCompositeShape* shHanger2 = new TGeoCompositeShape("shHanger2", "shHanger22*shHanger21:trHanger");
385 TGeoVolume* voHanger2 = new TGeoVolume("DHanger2", shHanger2, kMedSteel);
388 Float_t hsLength = yokeLength + (zHanger2 - kZDipole - yokeLength/2.) + 25./2.;
390 TGeoVolume* voHS1 = new TGeoVolume("DHS1", new TGeoBBox( 1.5, 12.5, hsLength/2.), kMedSteel);
391 TGeoVolume* voHS2 = new TGeoVolume("DHS2", new TGeoBBox(12.5, 1.5, hsLength/2.), kMedSteel);
392 Float_t hsH = gapHeight/2. + blockHeight - (rmax1+rmax2)/2.;
394 TGeoVolume* voHS3 = new TGeoVolume("DHS3", new TGeoBBox(3.5/2., hsH/2., 25./2.), kMedSteel);
396 TGeoVolumeAssembly* asHS = new TGeoVolumeAssembly("asHS");
397 asHS->AddNode(voHS1, 1, gGeoIdentity);
398 asHS->AddNode(voHS2, 1, new TGeoTranslation(0., +14., 0.));
399 asHS->AddNode(voHS2, 2, new TGeoTranslation(0., -14., 0.));
400 asHS->AddNode(voHS3, 1, new TGeoTranslation(0., -hsH/2. - 14., hsLength/2. - 25./2.));
404 dz = zHanger1 - kZDipole;
405 dy = -(kZDipoleR - zHanger1) * TMath::Tan(alhc * kDegrad);
406 voDDIP->AddNode(voHanger1, 1, new TGeoCombiTrans(0., dy, dz, rotlhc));
408 dz = zHanger2 - kZDipole;
409 dy = -(kZDipoleR - zHanger2) * TMath::Tan(alhc * kDegrad);
410 voDDIP->AddNode(voHanger2, 1, new TGeoCombiTrans(0., dy, dz, rotlhc));
415 // Assembly everything
417 TGeoVolumeAssembly* asDipole = new TGeoVolumeAssembly("Dipole");
419 asDipole->AddNode(asYoke, 1, new TGeoTranslation(0., 0., -dzCoil));
420 asDipole->AddNode(asCoil, 1, gGeoIdentity);
422 dz = lengthSt / 2. + coilH / 2. + rKnee;
423 asDipole->AddNode(asContactor, 1, new TGeoTranslation(0., 0., dz + dzCoil));
424 asDipole->AddNode(asContactor, 2, new TGeoCombiTrans( 0., 0., dz - dzCoil, rotxy180));
426 asDipole->AddNode(asDCoilSupport, 1, new TGeoTranslation(0., 0., dz));
427 asDipole->AddNode(asDCoilSupport, 2, new TGeoCombiTrans( 0., 0., dz, rotxy180));
428 asDipole->AddNode(asDCoilSupport, 3, new TGeoCombiTrans( 0., 0., dz, rotxy108));
429 asDipole->AddNode(asDCoilSupport, 4, new TGeoCombiTrans( 0., 0., dz, rotxy288));
431 asDipole->AddNode(asDCoilSupport, 5, new TGeoCombiTrans( 0., 0., -dz, rotxz));
432 asDipole->AddNode(asDCoilSupport, 6, new TGeoCombiTrans( 0., 0., -dz, rotxz108));
433 asDipole->AddNode(asDCoilSupport, 7, new TGeoCombiTrans( 0., 0., -dz, rotxz180));
434 asDipole->AddNode(asDCoilSupport, 8, new TGeoCombiTrans( 0., 0., -dz, rotxz288));
437 dy = gapHeight/2. + blockHeight + 14.;
439 asDipole->AddNode(asHS, 1, new TGeoTranslation(0., dy, ((zHanger2 - kZDipole - yokeLength/2.) + 25./2.)/2.));
442 asDipole->SetVisContainers(1);
443 voDDIP->SetVisibility(0);
444 asDipole->AddNode(voDDIP, 1, gGeoIdentity);
445 top->AddNode(asDipole, 1, new TGeoCombiTrans(0., dipoleL / 2. * TMath::Tan(alhc * kDegrad), -kZDipole, rotxzlhc));