Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
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 : **************************************************************************/
15 : //
16 : // This class Defines the Geometry for the ITS services and support cones
17 : // outside of the central volume (except for the Central support
18 : // cylinders). Other classes define the rest of the ITS, specifically the
19 : // SSD support cone, the SSD Support central cylinder, the SDD support cone,
20 : // the SDD support central cylinder, the SPD Thermal Shield, The supports
21 : // and cable trays on both the RB26 (muon dump) and RB24 sides, and all of
22 : // the cabling from the ladders/stave ends out past the TPC.
23 : //
24 : // Here is the calling sequence associated with this file
25 : // SPDSector(TGeoVolume *moth,TGeoManager *mgr)
26 : // -----CarbonFiberSector(TGeoVolume *moth,Double_t &xAAtubeCenter0,
27 : // Double_t &yAAtubeCenter0,TGeoManager *mgr)
28 : // -----2* SPDsectorShape(Int_t n,const Double_t *xc,const Double_t *yc,
29 : // | const Double_t *r,const Double_t *ths,
30 : // | const Double_t *the,Int_t npr,Int_t &m,
31 : // | Double_t **xp,Double_t **yp)
32 : // -----StavesInSector(TGeoVolume *moth,TGeoManager *mgr)
33 : // -----3* CreaeStave(Int_t layer,TArrayD &sizes,Bool_t addClips,
34 : // | TGeoManager *mgr)
35 : // | -----2* CreateHalfStave(Boot_t isRight,Int_t layer,
36 : // | Int_t idxCentral,Int_t idxSide,
37 : // | TArrayD &sizes,Bool_t addClips,
38 : // | TGeoManager *mgr)
39 : // | -----CreateGrondingFoil(Bool_t isRight,TArrayD &sizes,
40 : // | | TGeoManager *mgr)
41 : // | | -----4* CreateGroundingFoilSingle(Int_t type,
42 : // | | TArrayD &sizes,
43 : // | | TGeoManger *mgr)
44 : // | |----CreateLadder(Int_t layer, TArrayD &sizes,
45 : // | | TGeoManager *mgr)
46 : // | |----CreateMCM(Bool_t isRight,TArrayD &sizes,
47 : // | | TGeoManger *mgr)
48 : // | |----CreatePixelBus(Bool_t isRight,TArrayD &sizes,
49 : // | | TGeoManager *mgr)
50 : // | -----CreateClip(TArrayD &sizes,TGeoManager *mgr)
51 : // |----GetSectorMountingPoints(Int_t index,Double_t &x0,
52 : // | Double_t &y0,Double_t &x1,
53 : // | Double_t y1)
54 : // -----3* ParallelPosition(Double_t dist1,Double_t dist2,
55 : // Double_t phi,Double_t &x,Double_t &y)
56 : //
57 : // Obsoleate or presently unused routines are: setAddStave(Bool_t *mask),
58 : // CreatePixelBusAndExtensions(...) which calles CreateExtender(...).
59 :
60 : /* $Id$ */
61 :
62 :
63 : // General Root includes
64 : #include <Riostream.h>
65 : #include <TMath.h>
66 : #include <TLatex.h>
67 : #include <TCanvas.h>
68 : #include <TPolyLine.h>
69 : #include <TPolyMarker.h>
70 :
71 : // Root Geometry includes
72 : #include <TGeoCompositeShape.h>
73 : #include <TGeoEltu.h>
74 : #include <TGeoGlobalMagField.h>
75 : #include <TGeoMaterial.h>
76 : #include <TGeoMatrix.h>
77 : #include <TGeoMedium.h>
78 : #include <TGeoTube.h> // contains TGeoTubeSeg
79 : #include <TGeoVolume.h>
80 : #include <TGeoXtru.h>
81 : #include <TGeoPcon.h>
82 : #include <TGeoPgon.h>
83 : #include <TGeoArb8.h>
84 :
85 : // AliRoot includes
86 : #include "AliLog.h"
87 : #include "AliMagF.h"
88 : #include "AliRun.h"
89 :
90 : // Declaration file
91 : #include "AliITSv11GeometrySPD.h"
92 : #include "AliITSv11GeomCableRound.h"
93 :
94 : // Constant definistions
95 : const Double_t AliITSv11GeometrySPD::fgkGapLadder =
96 116 : AliITSv11Geometry::fgkmicron*75.; // 75 microns
97 : const Double_t AliITSv11GeometrySPD::fgkGapHalfStave =
98 116 : AliITSv11Geometry::fgkmicron*120.; // 120 microns
99 :
100 : using std::endl;
101 : using std::cout;
102 : using std::ios;
103 116 : ClassImp(AliITSv11GeometrySPD)
104 : //______________________________________________________________________
105 : AliITSv11GeometrySPD::AliITSv11GeometrySPD(/*Double_t gap*/):
106 1 : AliITSv11Geometry(),// Default constructor of base class
107 1 : fAddStave(), // [DEBUG] must be TRUE for all staves which will be
108 : // mounted in the sector (used to check overlaps)
109 1 : fSPDsectorX0(0), // X of first edge of sector plane for stave
110 1 : fSPDsectorY0(0), // Y of first edge of sector plane for stave
111 1 : fSPDsectorX1(0), // X of second edge of sector plane for stave
112 1 : fSPDsectorY1(0), // Y of second edge of sector plane for stave
113 1 : fTubeEndSector() // coordinate of cooling tube ends
114 5 : {
115 : //
116 : // Default constructor.
117 : // This does not initialize anything and is provided just for
118 : // completeness. It is recommended to use the other one.
119 : // The alignment gap is specified as argument (default = 0.0075 cm).
120 : // Inputs:
121 : // none.
122 : // Outputs:
123 : // none.
124 : // Return:
125 : // A default constructed AliITSv11GeometrySPD class.
126 : //
127 : Int_t i = 0,j=0,k=0;
128 :
129 14 : for (i = 0; i < 6; i++) fAddStave[i] = kTRUE;
130 642 : for(k=0;k<10;k++)for(i=0;i<6;i++)for(j=0;j<3;j++){
131 180 : this->fTubeEndSector[k][0][i][j] = 0.0;
132 180 : this->fTubeEndSector[k][1][i][j] = 0.0;
133 : } // end for i,j
134 2 : }
135 : //______________________________________________________________________
136 : AliITSv11GeometrySPD::AliITSv11GeometrySPD(Int_t debug/*, Double_t gap*/):
137 0 : AliITSv11Geometry(debug),// Default constructor of base class
138 0 : fAddStave(), // [DEBUG] must be TRUE for all staves which will be
139 : // mounted in the sector (used to check overlaps)
140 0 : fSPDsectorX0(0), // X of first edge of sector plane for stave
141 0 : fSPDsectorY0(0), // Y of first edge of sector plane for stave
142 0 : fSPDsectorX1(0), // X of second edge of sector plane for stave
143 0 : fSPDsectorY1(0), // Y of second edge of sector plane for stave
144 0 : fTubeEndSector() // coordinate of cooling tube ends
145 0 : {
146 : //
147 : // Constructor with debug setting argument
148 : // This is the constructor which is recommended to be used.
149 : // It sets a debug level, and initializes the name of the object.
150 : // The alignment gap is specified as argument (default = 0.0075 cm).
151 : // Inputs:
152 : // Int_t debug Debug level, 0= no debug output.
153 : // Outputs:
154 : // none.
155 : // Return:
156 : // A default constructed AliITSv11GeometrySPD class.
157 : //
158 : Int_t i = 0,j=0,k=0;
159 :
160 0 : for (i = 0; i < 6; i++) fAddStave[i] = kTRUE;
161 0 : for(k=0;k<10;k++)for(i=0;i<6;i++)for(j=0;j<3;j++){
162 0 : this->fTubeEndSector[k][0][i][j] = 0.0;
163 0 : this->fTubeEndSector[k][1][i][j] = 0.0;
164 : } // end for i,j
165 0 : }
166 : //______________________________________________________________________
167 : AliITSv11GeometrySPD::AliITSv11GeometrySPD(const AliITSv11GeometrySPD &s):
168 0 : AliITSv11Geometry(s),// Base Class Copy constructor
169 0 : fAddStave(), // [DEBUG] must be TRUE for all staves which will be
170 : // mounted in the sector (used to check overlaps)
171 0 : fSPDsectorX0(s.fSPDsectorX0), // X of first edge of sector plane for stave
172 0 : fSPDsectorY0(s.fSPDsectorY0), // Y of first edge of sector plane for stave
173 0 : fSPDsectorX1(s.fSPDsectorX1), // X of second edge of sector plane for stave
174 0 : fSPDsectorY1(s.fSPDsectorY1) // Y of second edge of sector plane for stave
175 0 : {
176 : //
177 : // Copy Constructor
178 : // Inputs:
179 : // AliITSv11GeometrySPD &s source class
180 : // Outputs:
181 : // none.
182 : // Return:
183 : // A copy of a AliITSv11GeometrySPD class.
184 : //
185 : Int_t i=0,j=0,k=0;
186 :
187 0 : for (i = 0; i < 6; i++) this->fAddStave[i] = s.fAddStave[i];
188 0 : for(k=0;k<10;k++)for(i=0;i<6;i++)for(j=0;j<3;j++){
189 0 : this->fTubeEndSector[k][0][i][j] = s.fTubeEndSector[k][0][i][j];
190 0 : this->fTubeEndSector[k][1][i][j] = s.fTubeEndSector[k][1][i][j];
191 : } // end for i,j
192 0 : }
193 : //______________________________________________________________________
194 : AliITSv11GeometrySPD& AliITSv11GeometrySPD::operator=(const
195 : AliITSv11GeometrySPD &s)
196 : {
197 : //
198 : // = operator
199 : // Inputs:
200 : // AliITSv11GeometrySPD &s source class
201 : // Outputs:
202 : // none.
203 : // Return:
204 : // A copy of a AliITSv11GeometrySPD class.
205 : //
206 : Int_t i=0,j=0,k=0;
207 :
208 0 : if(this==&s) return *this;
209 0 : for (i = 0; i < 6; i++) this->fAddStave[i] = s.fAddStave[i];
210 0 : this->fSPDsectorX0=s.fSPDsectorX0;
211 0 : this->fSPDsectorY0=s.fSPDsectorY0;
212 0 : this->fSPDsectorX1=s.fSPDsectorX1;
213 0 : this->fSPDsectorY1=s.fSPDsectorY1;
214 0 : for(k=0;k<10;k++)for(i=0;i<6;i++)for(j=0;j<3;j++){
215 0 : this->fTubeEndSector[k][0][i][j] = s.fTubeEndSector[k][0][i][j];
216 0 : this->fTubeEndSector[k][1][i][j] = s.fTubeEndSector[k][1][i][j];
217 : } // end for i,j
218 0 : return *this;
219 0 : }
220 : //______________________________________________________________________
221 : TGeoMedium* AliITSv11GeometrySPD::GetMedium(const char* mediumName,
222 : const TGeoManager *mgr) const
223 : {
224 : //
225 : // This function is used to recovery any medium
226 : // used to build the geometry volumes.
227 : // If the required medium does not exists,
228 : // a NULL pointer is returned, and an error message is written.
229 : //
230 1500 : Char_t itsMediumName[30];
231 :
232 750 : snprintf(itsMediumName, 30, "ITS_%s", mediumName);
233 750 : TGeoMedium* medium = mgr->GetMedium(itsMediumName);
234 750 : if (!medium) AliError(Form("Medium <%s> not found", mediumName));
235 :
236 750 : return medium;
237 750 : }
238 :
239 : //______________________________________________________________________
240 : void AliITSv11GeometrySPD::SPDSector(TGeoVolume *moth, TGeoManager *mgr)
241 : {
242 : //
243 : // Creates a single SPD carbon fiber sector and places it
244 : // in a container volume passed as first argument ('moth').
245 : // Second argument points to the TGeoManager which coordinates
246 : // the overall volume creation.
247 : // The position of the sector is based on distance of
248 : // closest point of SPD stave to beam pipe
249 : // (figures all-sections-modules.ps) of 7.22mm at section A-A.
250 : //
251 :
252 : // Begin_Html
253 : /*
254 : <img src="http://alice.pd.infn.it/latestdr/Geometric-Revision/assembly.ps"
255 : title="SPD Sector drawing with all cross sections defined">
256 : <p>The SPD Sector definition. In
257 : <a href="http://alice.pd.infn.it/latestdr/Geometric-Revision/assembly.hpgl">HPGL</a> format.
258 : <img src="http://alice.pd.infn.it/latestdr/Geometric-Revision/assembly-10-modules.ps"
259 : titile="SPD All Sectors end view with thermal sheald">
260 : <p>The SPD all sector end view with thermal sheald.
261 : <img src="http://alice.pd.infn.it/latestdr/Geometric-Revision/assembly.ps"
262 : title="SPD side view cross section">
263 : <p>SPD side view cross section with condes and thermal shealds.
264 : <img src="http://alice.pd.infn.it/latestdr/Geometric-Revision/SECTION-A_A.jpg"
265 : title="Cross section A-A"><p>Cross section A-A.
266 : <img src="http://alice.pd.infn.it/latestdr/Geometric-Revision/SECTION-B_B.jpg"
267 : title="Cross updated section A-A"><p>Cross updated section A-A.
268 : <img src="http://physics.mps.ohio-state.edu/~nilsen/ITSfigures/Sezione_layerAA.pdf"
269 : title="Cross section B-B"><p>Cross section B-B.
270 : <img src="http://alice.pd.infn.it/latestdr/Geometric-Revision/SECTION-C_C.jpg"
271 : title-"Cross section C-C"><p>Cross section C-C.
272 : <img src="http://alice.pd.infn.it/latestdr/Geometric-Revision/SECTION-D_D.jpg"
273 : title="Cross section D-D"><p>Cross section D-D.
274 : <img src="http://alice.pd.infn.it/latestdr/Geometric-Revision/SECTION-E_E.jpg"
275 : title="Cross section E-E"><p>Cross section E-E.
276 : <img src="http://alice.pd.infn.it/latestdr/Geometric-Revision/SECTION-F_F.jpg"
277 : title="Cross section F-F"><p>Cross section F-F.
278 : <img src="http://alice.pd.infn.it/latestdr/Geometric-Revision/SECTION-G_G.jpg"
279 : title="Cross section G-G"><p>Cross section G-G.
280 : */
281 : // End_Html
282 :
283 : // Inputs:
284 : // TGeoVolume *moth Pointer to mother volume where this object
285 : // is to be placed in
286 : // TGeoManager *mgr Pointer to the TGeoManager used, defaule is
287 : // gGeoManager.
288 : // Outputs:
289 : // none.
290 : // Return:
291 : // none.
292 : // Updated values for kSPDclossesStaveAA, kBeamPipeRadius, and
293 : // staveThicknessAA are taken from
294 : // http://physics.mps.ohio-state.edu/~nilsen/ITSfigures/Sezione_layerAA.pdf
295 : //
296 2 : const Double_t kSPDclossesStaveAA = 7.25* fgkmm;
297 1 : const Double_t kSectorStartingAngle = -72.0 * fgkDegree;
298 : const Int_t kNSectorsTotal = 10;
299 1 : const Double_t kSectorRelativeAngle = 36.0 * fgkDegree; // = 360.0 / 10
300 1 : const Double_t kBeamPipeRadius = 0.5 * 59.6 * fgkmm; // diam. = 59.6 mm
301 : //const Double_t staveThicknessAA = 0.9 *fgkmm; // nominal thickness
302 1 : const Double_t staveThicknessAA = 1.02 * fgkmm; // get from stave geometry.
303 :
304 : Int_t i, j, k;
305 1 : Double_t angle, radiusSector, xAAtubeCenter0, yAAtubeCenter0;
306 1 : TGeoCombiTrans *secRot = new TGeoCombiTrans(), *comrot;
307 1 : TGeoVolume *vCarbonFiberSector[10];
308 : TGeoMedium *medSPDcf;
309 :
310 : // Define an assembly and fill it with the support of
311 : // a single carbon fiber sector and staves in it
312 1 : medSPDcf = GetMedium("SPD C (M55J)$", mgr);
313 22 : for(Int_t is=0; is<10; is++)
314 : {
315 20 : vCarbonFiberSector[is] = new TGeoVolumeAssembly("ITSSPDCarbonFiberSectorV");
316 10 : vCarbonFiberSector[is]->SetMedium(medSPDcf);
317 10 : CarbonFiberSector(vCarbonFiberSector[is], is, xAAtubeCenter0, yAAtubeCenter0, mgr);
318 10 : vCarbonFiberSector[is]->GetShape()->ComputeBBox(); //RS: enforce recompting of BBox
319 : }
320 :
321 : // Compute the radial shift out of the sectors
322 1 : radiusSector = kBeamPipeRadius + kSPDclossesStaveAA + staveThicknessAA;
323 2 : radiusSector = GetSPDSectorTranslation(fSPDsectorX0.At(1), fSPDsectorY0.At(1),
324 1 : fSPDsectorX1.At(1), fSPDsectorY1.At(1), radiusSector);
325 : //radiusSector *= radiusSector; // squaring;
326 : //radiusSector -= xAAtubeCenter0 * xAAtubeCenter0;
327 : //radiusSector = -yAAtubeCenter0 + TMath::Sqrt(radiusSector);
328 :
329 3 : AliDebug(1, Form("SPDSector : radiusSector=%f\n",radiusSector));
330 : i = 1;
331 3 : AliDebug(1, Form("i= %d x0=%f y0=%f x1=%f y1=%f\n", i,
332 : fSPDsectorX0.At(i), fSPDsectorY0.At(i),
333 : fSPDsectorX1.At(i),fSPDsectorY1.At(i)));
334 :
335 : // add 10 single sectors, by replicating the virtual sector defined above
336 : // and placing at different angles
337 1 : Double_t shiftX, shiftY, tub[2][6][3];
338 130 : for(i=0;i<2;i++)for(j=0;j<6;j++)for(k=0;k<3;k++) tub[i][j][k] = fTubeEndSector[0][i][j][k];
339 : angle = kSectorStartingAngle;
340 1 : secRot->RotateZ(angle);
341 1 : TGeoVolumeAssembly *vcenteral = new TGeoVolumeAssembly("ITSSPD");
342 1 : moth->AddNode(vcenteral, 1, 0);
343 22 : for(i = 0; i < kNSectorsTotal; i++) {
344 10 : shiftX = -radiusSector * TMath::Sin(angle/fgkRadian);
345 10 : shiftY = radiusSector * TMath::Cos(angle/fgkRadian);
346 : //cout << "ANGLE = " << angle << endl;
347 10 : shiftX += 0.1094 * TMath::Cos((angle + 196.)/fgkRadian);
348 10 : shiftY += 0.1094 * TMath::Sin((angle + 196.)/fgkRadian);
349 : //shiftX -= 0.105;
350 : //shiftY -= 0.031;
351 : //shiftX -= 0.11 * TMath::Cos(angle/fgkRadian); // add by Alberto
352 : //shiftY -= 0.11 * TMath::Sin(angle/fgkRadian); // don't ask me where that 0.11 comes from!
353 10 : secRot->SetDx(shiftX);
354 10 : secRot->SetDy(shiftY);
355 10 : comrot = new TGeoCombiTrans(*secRot);
356 10 : vcenteral->AddNode(vCarbonFiberSector[i],i+1,comrot);
357 340 : for(j=0;j<2;j++)for(k=0;k<6;k++) // Transform Tube ends for each sector
358 120 : comrot->LocalToMaster(tub[j][k],fTubeEndSector[i][j][k]);
359 10 : if(GetDebug(5)) {
360 0 : AliInfo(Form("i=%d angle=%g angle[rad]=%g radiusSector=%g "
361 : "x=%g y=%g \n",i, angle, angle/fgkRadian,
362 : radiusSector, shiftX, shiftY));
363 0 : } // end if GetDebug(5)
364 10 : angle += kSectorRelativeAngle;
365 10 : secRot->RotateZ(kSectorRelativeAngle);
366 : } // end for i
367 :
368 1 : vcenteral->GetShape()->ComputeBBox(); //RS: enforce recompting of BBox
369 :
370 1 : if(GetDebug(3)) moth->PrintNodes();
371 2 : delete secRot;
372 :
373 1 : CreateCones(moth);
374 1 : CreateServices(moth);
375 1 : }
376 : //______________________________________________________________________
377 : void AliITSv11GeometrySPD::CarbonFiberSector(TGeoVolume *moth, Int_t sect,
378 : Double_t &xAAtubeCenter0, Double_t &yAAtubeCenter0, TGeoManager *mgr)
379 : {
380 : // The method has been modified in order to build a support sector
381 : // whose shape is dependent on the sector number; the aim is to get
382 : // as close as possible to the shape inferred from alignment
383 : // and avoid as much as possible overlaps generated by alignment.
384 : //
385 : // Define the detail SPD Carbon fiber support Sector geometry.
386 : // Based on the drawings:
387 : /*
388 : http:///QA-construzione-profilo-modulo.ps
389 : */
390 : // - ALICE-Pixel "Costruzione Profilo Modulo" (march 25 2004)
391 : // - ALICE-SUPPORTO "Costruzione Profilo Modulo"
392 : // ---
393 : // Define outside radii as negative, where "outside" means that the
394 : // center of the arc is outside of the object (feb 16 2004).
395 : // ---
396 : // Arguments [the one passed by ref contain output values]:
397 : // Inputs:
398 : // TGeoVolume *moth the voulme which will contain this object
399 : // TGeoManager *mgr TGeo builder defauls is gGeoManager
400 : // Outputs:
401 : // Double_t &xAAtubeCenter0 (by ref) x location of the outer surface
402 : // of the cooling tube center for tube 0.
403 : // Double_t &yAAtubeCenter0 (by ref) y location of the outer surface
404 : // of the cooling tube center for tube 0.
405 : // Return:
406 : // none.
407 : // ---
408 : // Int the two variables passed by reference values will be stored
409 : // which will then be used to correctly locate this sector.
410 : // The information used for this is the distance between the
411 : // center of the #0 detector and the beam pipe.
412 : // Measurements are taken at cross section A-A.
413 : //
414 :
415 : //TGeoMedium *medSPDfs = 0;//SPD support cone inserto stesalite 4411w
416 : //TGeoMedium *medSPDfo = 0;//SPD support cone foam, Rohacell 50A.
417 : //TGeoMedium *medSPDal = 0;//SPD support cone SDD mounting bracket Al
418 20 : TGeoMedium *medSPDcf = GetMedium("SPD C (M55J)$", mgr);
419 10 : TGeoMedium *medSPDss = GetMedium("INOX$", mgr);
420 10 : TGeoMedium *medSPDcoolfl = GetMedium("Freon$", mgr); //ITSspdCoolingFluid
421 : //
422 10 : const Double_t ksecDz = 0.5 * 500.0 * fgkmm;
423 : //const Double_t ksecLen = 30.0 * fgkmm;
424 10 : const Double_t ksecCthick = 0.2 * fgkmm;
425 10 : const Double_t ksecDipLength = 3.2 * fgkmm;
426 10 : const Double_t ksecDipRadii = 0.4 * fgkmm;
427 : //const Double_t ksecCoolingTubeExtraDepth = 0.86 * fgkmm;
428 : //
429 : // The following positions ('ksecX#' and 'ksecY#') and radii ('ksecR#')
430 : // are the centers and radii of curvature of all the rounded corners
431 : // between the straight borders of the SPD sector shape.
432 : // To draw this SPD sector, the following steps are followed:
433 : // 1) the (ksecX, ksecY) points are plotted
434 : // and circles of the specified radii are drawn around them.
435 : // 2) each pair of consecutive circles is connected by a line
436 : // tangent to them, in accordance with the radii being "internal"
437 : // or "external" with respect to the closed shape which describes
438 : // the sector itself.
439 : // The resulting connected shape is the section
440 : // of the SPD sector surface in the transverse plane (XY).
441 : //
442 10 : const Double_t ksecX0 = -10.725 * fgkmm;
443 10 : const Double_t ksecY0 = -14.853 * fgkmm;
444 10 : const Double_t ksecR0 = -0.8 * fgkmm; // external
445 :
446 10 : const Double_t ksecR1 = +0.6 * fgkmm;
447 : const Double_t ksecR2 = +0.6 * fgkmm;
448 10 : const Double_t ksecR3 = -0.6 * fgkmm;
449 10 : const Double_t ksecR4 = +0.8 * fgkmm;
450 : const Double_t ksecR5 = +0.8 * fgkmm;
451 : const Double_t ksecR6 = +0.6 * fgkmm;
452 : const Double_t ksecR7 = -0.6 * fgkmm;
453 : const Double_t ksecR8 = +0.6 * fgkmm;
454 : const Double_t ksecR9 = -0.6 * fgkmm;
455 : const Double_t ksecR10 = +0.6 * fgkmm;
456 : const Double_t ksecR11 = -0.6 * fgkmm;
457 10 : const Double_t ksecR12 = +0.85 * fgkmm;
458 :
459 : // // IDEAL GEOMETRY
460 : // const Double_t ksecX1[10] ={-1.3187,-1.3187,-1.3187,-1.3187,-1.3187,-1.3187,-1.3187,-1.3187,-1.3187,-1.3187};
461 : // const Double_t ksecY1[10] ={-1.9964,-1.9964,-1.9964,-1.9964,-1.9964,-1.9964,-1.9964,-1.9964,-1.9964,-1.9964};
462 : // const Double_t ksecX2[10] ={-0.3833,-0.3833,-0.3833,-0.3833,-0.3833,-0.3833,-0.3833,-0.3833,-0.3833,-0.3833};
463 : // const Double_t ksecY2[10] ={-1.7805,-1.7805,-1.7805,-1.7805,-1.7805,-1.7805,-1.7805,-1.7805,-1.7805,-1.7805};
464 : // const Double_t ksecX3[10] ={-0.3123,-0.3123,-0.3123,-0.3123,-0.3123,-0.3123,-0.3123,-0.3123,-0.3123,-0.3123};
465 : // const Double_t ksecY3[10] ={-1.4618,-1.4618,-1.4618,-1.4618,-1.4618,-1.4618,-1.4618,-1.4618,-1.4618,-1.4618};
466 : // const Double_t ksecX4[10] ={+1.1280,+1.1280,+1.1280,+1.1280,+1.1280,+1.1280,+1.1280,+1.1280,+1.1280,+1.1280};
467 : // const Double_t ksecY4[10] ={-1.4473,-1.4473,-1.4473,-1.4473,-1.4473,-1.4473,-1.4473,-1.4473,-1.4473,-1.4473};
468 : // const Double_t ksecX5[10] ={+1.9544,+1.9544,+1.9544,+1.9544,+1.9544,+1.9544,+1.9544,+1.9544,+1.9544,+1.9544};
469 : // const Double_t ksecY5[10] ={+1.0961,+1.0961,+1.0961,+1.0961,+1.0961,+1.0961,+1.0961,+1.0961,+1.0961,+1.0961};
470 : // const Double_t ksecX6[10] ={+1.0830,+1.0830,+1.0830,+1.0830,+1.0830,+1.0830,+1.0830,+1.0830,+1.0830,+1.0830};
471 : // const Double_t ksecY6[10] ={+1.6868,+1.6868,+1.6868,+1.6868,+1.6868,+1.6868,+1.6868,+1.6868,+1.6868,+1.6868};
472 : // const Double_t ksecX7[10] ={+1.1581,+1.1581,+1.1581,+1.1581,+1.1581,+1.1581,+1.1581,+1.1581,+1.1581,+1.1581};
473 : // const Double_t ksecY7[10] ={+1.3317,+1.3317,+1.3317,+1.3317,+1.3317,+1.3317,+1.3317,+1.3317,+1.3317,+1.3317};
474 : // const Double_t ksecX8[10] ={-0.0733,-0.0733,-0.0733,-0.0733,-0.0733,-0.0733,-0.0733,-0.0733,-0.0733,-0.0733};
475 : // const Double_t ksecY8[10] ={+1.7486,+1.7486,+1.7486,+1.7486,+1.7486,+1.7486,+1.7486,+1.7486,+1.7486,+1.7486};
476 : // const Double_t ksecX9[10] ={+0.0562,+0.0562,+0.0562,+0.0562,+0.0562,+0.0562,+0.0562,+0.0562,+0.0562,+0.0562};
477 : // const Double_t ksecY9[10] ={+1.4107,+1.4107,+1.4107,+1.4107,+1.4107,+1.4107,+1.4107,+1.4107,+1.4107,+1.4107};
478 : // const Double_t ksecX10[10]={-1.2252,-1.2252,-1.2252,-1.2252,-1.2252,-1.2252,-1.2252,-1.2252,-1.2252,-1.2252};
479 : // const Double_t ksecY10[10]={+1.6298,+1.6298,+1.6298,+1.6298,+1.6298,+1.6298,+1.6298,+1.6298,+1.6298,+1.6298};
480 : // const Double_t ksecX11[10]={-1.0445,-1.0445,-1.0445,-1.0445,-1.0445,-1.0445,-1.0445,-1.0445,-1.0445,-1.0445};
481 : // const Double_t ksecY11[10]={+1.3162,+1.3162,+1.3162,+1.3162,+1.3162,+1.3162,+1.3162,+1.3162,+1.3162,+1.3162};
482 : // const Double_t ksecX12[10]={-2.2276,-2.2276,-2.2276,-2.2276,-2.2276,-2.2276,-2.2276,-2.2276,-2.2276,-2.2276};
483 : // const Double_t ksecY12[10]={+1.2948,+1.2948,+1.2948,+1.2948,+1.2948,+1.2948,+1.2948,+1.2948,+1.2948,+1.2948};
484 :
485 :
486 : // MODIFIED GEOMETRY according with partial alignment of Staves relative to Sectors
487 : // last numbers: 2010/06/11 (ML)
488 :
489 : const Double_t ksecX1[10]={-1.305917, -1.322242, -1.300649, -1.298700, -1.290830, -1.274307, -1.276433, -1.286468, -1.274381, -1.314864};
490 : const Double_t ksecY1[10]={-1.997857, -2.018611, -2.005854, -2.004897, -1.995517, -2.002552, -1.995860, -2.021062, -2.012931, -2.043967};
491 : const Double_t ksecX2[10]={-0.366115, -0.385562, -0.372689, -0.365682, -0.348432, -0.348442, -0.342468, -0.354071, -0.346900, -0.381275};
492 : const Double_t ksecY2[10]={-1.801679, -1.808306, -1.759315, -1.778851, -1.811655, -1.747888, -1.773811, -1.792427, -1.764514, -1.820324};
493 : // const Double_t ksecX1[10]={-1.305917, -1.322242, -1.300649, -1.298700, -1.290830, -1.274307, -1.276433, -1.286468, -1.274381, -1.325864};
494 : // const Double_t ksecY1[10]={-1.997857, -2.018611, -2.005854, -2.004897, -1.995517, -2.002552, -1.995860, -2.021062, -2.012931, -2.032967};
495 : // const Double_t ksecX2[10]={-0.366115, -0.385562, -0.372689, -0.365682, -0.348432, -0.348442, -0.342468, -0.354071, -0.346900, -0.392275};
496 : // const Double_t ksecY2[10]={-1.801679, -1.808306, -1.759315, -1.778851, -1.811655, -1.747888, -1.773811, -1.792427, -1.764514, -1.809324};
497 : const Double_t ksecX3[10]={-0.314030, -0.315531, -0.347521, -0.337675, -0.300420, -0.378487, -0.330729, -0.330850, -0.362360, -0.321097};
498 : const Double_t ksecY3[10]={-1.452488, -1.460418, -1.447060, -1.443146, -1.472410, -1.430019, -1.469073, -1.472048, -1.462010, -1.444355};
499 : const Double_t ksecX4[10]={1.124299, 1.124162, 1.089523, 1.095520, 1.136171, 1.058616, 1.105626, 1.106433, 1.077455, 1.117946};
500 : const Double_t ksecY4[10]={-1.458714, -1.452649, -1.465297, -1.492717, -1.494665, -1.447732, -1.493369, -1.488126, -1.452925, -1.443447};
501 : const Double_t ksecX5[10]={1.951621, 1.939284, 1.931830, 1.935235, 1.952206, 1.939082, 1.924822, 1.940114, 1.918160, 1.960017};
502 : const Double_t ksecY5[10]={1.092731, 1.118870, 1.129765, 1.129422, 1.081511, 1.127387, 1.103960, 1.101784, 1.121428, 1.150110};
503 : const Double_t ksecX6[10]={1.070070, 1.048297, 1.035920, 1.049049, 1.083621, 1.045882, 1.050399, 1.067823, 1.037967, 1.070850};
504 : const Double_t ksecY6[10]={1.667590, 1.678571, 1.681383, 1.696892, 1.676520, 1.683470, 1.689988, 1.691111, 1.698432, 1.712770};
505 : const Double_t ksecX7[10]={1.139398, 1.150471, 1.150074, 1.132807, 1.150192, 1.124064, 1.124335, 1.137723, 1.143056, 1.130568};
506 : const Double_t ksecY7[10]={1.345588, 1.356062, 1.342468, 1.320467, 1.335807, 1.334477, 1.328622, 1.347184, 1.319861, 1.308420};
507 : const Double_t ksecX8[10]={-0.096963, -0.098603, -0.095286, -0.099990, -0.075132, -0.121593, -0.108673, -0.104237, -0.092082, -0.104044};
508 : const Double_t ksecY8[10]={1.751207, 1.731467, 1.726908, 1.734219, 1.766159, 1.718203, 1.741891, 1.739743, 1.728288, 1.718046};
509 : const Double_t ksecX9[10]={0.047615, 0.087875, 0.034917, 0.071603, 0.026468, 0.091619, 0.051994, 0.059947, 0.079785, 0.043443};
510 : const Double_t ksecY9[10]={1.414699, 1.403187, 1.399061, 1.403430, 1.435056, 1.384557, 1.397692, 1.420269, 1.391372, 1.398954};
511 : const Double_t ksecX10[10]={-1.233255, -1.186874, -1.246702, -1.213368, -1.259425, -1.190067, -1.225655, -1.224171, -1.197833, -1.237182};
512 : const Double_t ksecY10[10]={1.635767, 1.646249, 1.617336, 1.608928, 1.636944, 1.602583, 1.630504, 1.629065, 1.624295, 1.620934};
513 : const Double_t ksecX11[10]={-1.018270, -1.031317, -0.960524, -1.001155, -1.045437, -0.986867, -1.002685, -1.017369, -1.005614, -0.985385};
514 : const Double_t ksecY11[10]={1.318108, 1.330683, 1.301572, 1.314410, 1.326680, 1.295226, 1.306372, 1.309414, 1.306542, 1.307086};
515 : const Double_t ksecX12[10]={-2.199004, -2.214964, -2.139247, -2.180547, -2.224505, -2.165324, -2.175883, -2.193485, -2.183227, -2.161570};
516 : const Double_t ksecY12[10]={1.317677, 1.303982, 1.317057, 1.324766, 1.339537, 1.312715, 1.359642, 1.343638, 1.330234, 1.340836};
517 :
518 :
519 : const Double_t ksecR13 = -0.8 * fgkmm; // external
520 10 : const Double_t ksecAngleSide13 = 36.0 * fgkDegree;
521 : //
522 : const Int_t ksecNRadii = 20;
523 : const Int_t ksecNPointsPerRadii = 4;
524 : const Int_t ksecNCoolingTubeDips = 6;
525 : //
526 : // Since the rounded parts are approximated by a regular polygon
527 : // and a cooling tube of the propper diameter must fit, a scaling factor
528 : // increases the size of the polygon for the tube to fit.
529 : //const Double_t ksecRCoolScale = 1./TMath::Cos(TMath::Pi()/
530 : // (Double_t)ksecNPointsPerRadii);
531 10 : const Double_t ksecZEndLen = 30.000 * fgkmm;
532 : //const Double_t ksecZFlangLen = 45.000 * fgkmm;
533 10 : const Double_t ksecTl = 0.860 * fgkmm;
534 : const Double_t ksecCthick2 = 0.600 * fgkmm;
535 : //const Double_t ksecCthick3 = 1.80 * fgkmm;
536 : //const Double_t ksecSidelen = 22.0 * fgkmm;
537 : //const Double_t ksecSideD5 = 3.679 * fgkmm;
538 : //const Double_t ksecSideD12 = 7.066 * fgkmm;
539 10 : const Double_t ksecRCoolOut = 2.400 * fgkmm;
540 10 : const Double_t ksecRCoolIn = 2.000 * fgkmm;
541 10 : const Double_t ksecDl1 = 5.900 * fgkmm;
542 10 : const Double_t ksecDl2 = 8.035 * fgkmm;
543 10 : const Double_t ksecDl3 = 4.553 * fgkmm;
544 10 : const Double_t ksecDl4 = 6.978 * fgkmm;
545 : const Double_t ksecDl5 = 6.978 * fgkmm;
546 : const Double_t ksecDl6 = 6.978 * fgkmm;
547 10 : const Double_t ksecCoolTubeThick = 0.04 * fgkmm;
548 10 : const Double_t ksecCoolTubeROuter = 2.6 * fgkmm;
549 10 : const Double_t ksecCoolTubeFlatX = 3.696 * fgkmm;
550 10 : const Double_t ksecCoolTubeFlatY = 0.68 * fgkmm;
551 : //const Double_t ksecBeamX0 = 0.0 * fgkmm; // guess
552 : //const Double_t ksecBeamY0 = (15.223 + 40.) * fgkmm; // guess
553 : //
554 : // redefine some of the points already defined above
555 : // in the format of arrays (???)
556 : const Int_t ksecNPoints = (ksecNPointsPerRadii + 1) * ksecNRadii + 8;
557 130 : Double_t secX[ksecNRadii] = {
558 10 : ksecX0, ksecX1[sect], -1000.0,
559 20 : ksecX2[sect], ksecX3[sect], -1000.0,
560 20 : ksecX4[sect], ksecX5[sect], -1000.0,
561 20 : ksecX6[sect], ksecX7[sect], -1000.0,
562 20 : ksecX8[sect], ksecX9[sect], -1000.0,
563 20 : ksecX10[sect], ksecX11[sect], -1000.0,
564 10 : ksecX12[sect], -1000.0
565 : };
566 130 : Double_t secY[ksecNRadii] = {
567 10 : ksecY0, ksecY1[sect], -1000.0,
568 20 : ksecY2[sect], ksecY3[sect], -1000.0,
569 20 : ksecY4[sect], ksecY5[sect], -1000.0,
570 20 : ksecY6[sect], ksecY7[sect], -1000.0,
571 20 : ksecY8[sect], ksecY9[sect], -1000.0,
572 20 : ksecY10[sect], ksecY11[sect], -1000.0,
573 10 : ksecY12[sect], -1000.0
574 : };
575 20 : Double_t secR[ksecNRadii] = {
576 10 : ksecR0, ksecR1, -.5 * ksecDipLength - ksecDipRadii,
577 : ksecR2, ksecR3, -.5 * ksecDipLength - ksecDipRadii,
578 : ksecR4, ksecR5, -.5 * ksecDipLength - ksecDipRadii,
579 : ksecR6, ksecR7, -.5 * ksecDipLength - ksecDipRadii,
580 : ksecR8, ksecR9, -.5 * ksecDipLength - ksecDipRadii,
581 : ksecR10, ksecR11, -.5 * ksecDipLength - ksecDipRadii,
582 : ksecR12, ksecR13
583 : };
584 :
585 10 : Double_t secX2[ksecNRadii];
586 10 : Double_t secY2[ksecNRadii];
587 10 : Double_t secR2[ksecNRadii] = {
588 : ksecR0, ksecR1, ksecRCoolOut,
589 : ksecR2, ksecR3, ksecRCoolOut,
590 : ksecR4, ksecR5, ksecRCoolOut,
591 : ksecR6, ksecR7, ksecRCoolOut,
592 : ksecR8, ksecR9, ksecRCoolOut,
593 : ksecR10, ksecR11, ksecRCoolOut,
594 : ksecR12, ksecR13
595 : };
596 10 : Double_t secDip2[ksecNCoolingTubeDips] = {
597 : ksecDl1, ksecDl2, ksecDl3,
598 : ksecDl4, ksecDl5, ksecDl6
599 : };
600 10 : Double_t secX3[ksecNRadii];
601 10 : Double_t secY3[ksecNRadii];
602 : const Int_t ksecDipIndex[ksecNCoolingTubeDips] = {2, 5, 8, 11, 14, 17};
603 10 : Double_t secAngleStart[ksecNRadii];
604 10 : Double_t secAngleEnd[ksecNRadii];
605 420 : for(Int_t i = 0; i < ksecNRadii; i++)secAngleEnd[i] = 0.;
606 10 : Double_t secAngleStart2[ksecNRadii];
607 10 : Double_t secAngleEnd2[ksecNRadii];
608 10 : Double_t secAngleTurbo[ksecNCoolingTubeDips] = {0., 0., 0., 0., 0., 0.0};
609 : //Double_t secAngleStart3[ksecNRadii];
610 : //Double_t secAngleEnd3[ksecNRadii];
611 10 : Double_t xpp[ksecNPoints], ypp[ksecNPoints];
612 10 : Double_t xpp2[ksecNPoints], ypp2[ksecNPoints];
613 10 : Double_t *xp[ksecNRadii], *xp2[ksecNRadii];
614 10 : Double_t *yp[ksecNRadii], *yp2[ksecNRadii];
615 : TGeoXtru *sA0, *sA1, *sB0, *sB1;
616 : TGeoCompositeShape *sA2, *sB2;
617 : TGeoBBox *sB3;
618 : TGeoEltu *sTA0, *sTA1;
619 : TGeoTube *sTB0, *sTB1; //,*sM0;
620 : TGeoRotation *rot;
621 : TGeoTranslation *trans;
622 : TGeoCombiTrans *rotrans;
623 10 : Double_t t, t0, t1, a, b, x0, y0,z0, x1, y1;
624 10 : Int_t i, j, k, m;
625 : Bool_t tst;
626 :
627 10 : if(!moth) {
628 0 : AliError("Container volume (argument) is NULL");
629 0 : return;
630 : } // end if(!moth)
631 420 : for(i = 0; i < ksecNRadii; i++) {
632 200 : xp[i] = &(xpp[i*(ksecNPointsPerRadii+1)]);
633 200 : yp[i] = &(ypp[i*(ksecNPointsPerRadii+1)]);
634 200 : xp2[i] = &(xpp2[i*(ksecNPointsPerRadii+1)]);
635 200 : yp2[i] = &(ypp2[i*(ksecNPointsPerRadii+1)]);
636 200 : secX2[i] = secX[i];
637 200 : secY2[i] = secY[i];
638 200 : secX3[i] = secX[i];
639 200 : secY3[i] = secY[i];
640 : } // end for i
641 : //
642 : // find starting and ending angles for all but cooling tube sections
643 10 : secAngleStart[0] = 0.5 * ksecAngleSide13;
644 380 : for(i = 0; i < ksecNRadii - 2; i++) {
645 : tst = kFALSE;
646 4530 : for(j=0;j<ksecNCoolingTubeDips;j++) tst = (tst||i==ksecDipIndex[j]);
647 180 : if (tst) continue;
648 : tst = kFALSE;
649 2970 : for(j=0;j<ksecNCoolingTubeDips;j++) tst =(tst||(i+1)==ksecDipIndex[j]);
650 240 : if (tst) j = i+2; else j = i+1;
651 240 : AnglesForRoundedCorners(secX[i],secY[i],secR[i],secX[j],secY[j],
652 120 : secR[j],t0,t1);
653 120 : secAngleEnd[i] = t0;
654 120 : secAngleStart[j] = t1;
655 190 : if(secR[i] > 0.0 && secR[j] > 0.0) {
656 40 : if(secAngleStart[i] > secAngleEnd[i]) secAngleEnd[i] += 360.0;
657 : } // end if(secR[i]>0.0 && secR[j]>0.0)
658 120 : secAngleStart2[i] = secAngleStart[i];
659 120 : secAngleEnd2[i] = secAngleEnd[i];
660 120 : } // end for i
661 20 : secAngleEnd[ksecNRadii-2] = secAngleStart[ksecNRadii-2] +
662 10 : (secAngleEnd[ksecNRadii-5] - secAngleStart[ksecNRadii-5]);
663 10 : if (secAngleEnd[ksecNRadii-2] < 0.0) secAngleEnd[ksecNRadii-2] += 360.0;
664 10 : secAngleStart[ksecNRadii-1] = secAngleEnd[ksecNRadii-2] - 180.0;
665 10 : secAngleEnd[ksecNRadii-1] = secAngleStart[0];
666 10 : secAngleStart2[ksecNRadii-2] = secAngleStart[ksecNRadii-2];
667 10 : secAngleEnd2[ksecNRadii-2] = secAngleEnd[ksecNRadii-2];
668 10 : secAngleStart2[ksecNRadii-1] = secAngleStart[ksecNRadii-1];
669 10 : secAngleEnd2[ksecNRadii-1] = secAngleEnd[ksecNRadii-1];
670 : //
671 : // find location of circle last rounded corner.
672 : i = 0;
673 : j = ksecNRadii - 2;
674 10 : t0 = TanD(secAngleStart[i]-90.);
675 10 : t1 = TanD(secAngleEnd[j]-90.);
676 10 : t = secY[i] - secY[j];
677 : // NOTE: secR[i=0] < 0; secR[j=18] > 0; and secR[j+1=19] < 0
678 10 : t += (-secR[i]+secR[j+1]) * SinD(secAngleStart[i]);
679 10 : t -= (secR[j]-secR[j+1]) * SinD(secAngleEnd[j]);
680 10 : t += t1 * secX[j] - t0*secX[i];
681 10 : t += t1 * (secR[j] - secR[j+1]) * CosD(secAngleEnd[j]);
682 10 : t -= t0 * (-secR[i]+secR[j+1]) * CosD(secAngleStart[i]);
683 10 : secX[ksecNRadii-1] = t / (t1-t0);
684 30 : secY[ksecNRadii-1] = TanD(90.0+0.5*ksecAngleSide13)*
685 20 : (secX[ksecNRadii-1]-secX[0])+secY[0];
686 10 : secX2[ksecNRadii-1] = secX[ksecNRadii-1];
687 10 : secY2[ksecNRadii-1] = secY[ksecNRadii-1];
688 10 : secX3[ksecNRadii-1] = secX[ksecNRadii-1];
689 10 : secY3[ksecNRadii-1] = secY[ksecNRadii-1];
690 :
691 : // find location of cooling tube centers
692 140 : for(i = 0; i < ksecNCoolingTubeDips; i++) {
693 60 : j = ksecDipIndex[i];
694 60 : x0 = secX[j-1] + TMath::Abs(secR[j-1]) * CosD(secAngleEnd[j-1]);
695 60 : y0 = secY[j-1] + TMath::Abs(secR[j-1]) * SinD(secAngleEnd[j-1]);
696 60 : x1 = secX[j+1] + TMath::Abs(secR[j+1]) * CosD(secAngleStart[j+1]);
697 60 : y1 = secY[j+1] + TMath::Abs(secR[j+1]) * SinD(secAngleStart[j+1]);
698 60 : t0 = TMath::Sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
699 60 : t = secDip2[i] / t0;
700 60 : a = x0+(x1-x0) * t;
701 60 : b = y0+(y1-y0) * t;
702 60 : if(i == 0) {
703 : // get location of tube center->Surface for locating
704 : // this sector around the beam pipe.
705 : // This needs to be double checked, but I need my notes for that.
706 : // (Bjorn Nilsen)
707 10 : xAAtubeCenter0 = x0 + (x1 - x0) * t * 0.5;
708 10 : yAAtubeCenter0 = y0 + (y1 - y0) * t * 0.5;
709 10 : }// end if i==0
710 120 : if(a + b*(a - x0) / (b - y0) > 0.0) {
711 70 : secX[j] = a + TMath::Abs(y1-y0) * 2.0 * ksecDipRadii/t0;
712 10 : secY[j] = b - TMath::Sign(2.0*ksecDipRadii,y1-y0) * (x1-x0)/t0;
713 10 : secX2[j] = a + TMath::Abs(y1-y0) * ksecTl/t0;
714 10 : secY2[j] = b - TMath::Sign(ksecTl,y1-y0) * (x1-x0) / t0;
715 30 : secX3[j] = a + TMath::Abs(y1-y0) *
716 20 : (2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY)/t0;
717 20 : secY3[j] = b - TMath::Sign(2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY,
718 10 : y1-y0)*(x1-x0)/t0;
719 10 : } else {
720 50 : secX[j] = a - TMath::Abs(y1-y0)*2.0*ksecDipRadii/t0;
721 50 : secY[j] = b + TMath::Sign(2.0*ksecDipRadii,y1-y0)*(x1-x0)/t0;
722 50 : secX2[j] = a - TMath::Abs(y1-y0)*ksecTl/t0;
723 50 : secY2[j] = b + TMath::Sign(ksecTl,y1-y0)*(x1-x0)/t0;
724 100 : secX3[j] = a - TMath::Abs(y1-y0)*(2.0*ksecDipRadii-0.5*
725 50 : ksecCoolTubeFlatY)/t0;
726 100 : secY3[j] = b + TMath::Sign(2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY,
727 50 : y1-y0)*(x1-x0)/t0;
728 : } // end if(a+b*(a-x0)/(b-y0)>0.0)
729 :
730 : // Set up Start and End angles to correspond to start/end of dips.
731 60 : t1 = (secDip2[i]-TMath::Abs(secR[j])) / t0;
732 120 : secAngleStart[j] =TMath::RadToDeg()*TMath::ATan2(y0+(y1-y0)*t1-secY[j],
733 60 : x0+(x1-x0)*t1-secX[j]);
734 100 : if (secAngleStart[j]<0.0) secAngleStart[j] += 360.0;
735 60 : secAngleStart2[j] = secAngleStart[j];
736 60 : t1 = (secDip2[i]+TMath::Abs(secR[j]))/t0;
737 120 : secAngleEnd[j] = TMath::RadToDeg()*TMath::ATan2(y0+(y1-y0)*t1-secY[j],
738 60 : x0+(x1-x0)*t1-secX[j]);
739 80 : if (secAngleEnd[j]<0.0) secAngleEnd[j] += 360.0;
740 60 : secAngleEnd2[j] = secAngleEnd[j];
741 100 : if (secAngleEnd[j]>secAngleStart[j]) secAngleEnd[j] -= 360.0;
742 60 : secR[j] = TMath::Sqrt(secR[j]*secR[j]+4.0*ksecDipRadii*ksecDipRadii);
743 : } // end for i
744 :
745 : // Special cases
746 10 : secAngleStart2[8] -= 360.;
747 10 : secAngleStart2[11] -= 360.;
748 :
749 20 : SPDsectorShape(ksecNRadii, secX, secY, secR, secAngleStart, secAngleEnd,
750 10 : ksecNPointsPerRadii, m, xp, yp);
751 :
752 : // Fix up dips to be square.
753 140 : for(i = 0; i < ksecNCoolingTubeDips; i++) {
754 60 : j = ksecDipIndex[i];
755 60 : t = 0.5*ksecDipLength+ksecDipRadii;
756 60 : t0 = TMath::RadToDeg()*TMath::ATan(2.0*ksecDipRadii/t);
757 60 : t1 = secAngleEnd[j] + t0;
758 60 : t0 = secAngleStart[j] - t0;
759 60 : x0 = xp[j][1] = secX[j] + t*CosD(t0);
760 60 : y0 = yp[j][1] = secY[j] + t*SinD(t0);
761 60 : x1 = xp[j][ksecNPointsPerRadii-1] = secX[j] + t*CosD(t1);
762 60 : y1 = yp[j][ksecNPointsPerRadii-1] = secY[j] + t*SinD(t1);
763 60 : t0 = 1./((Double_t)(ksecNPointsPerRadii-2));
764 240 : for(k = 2; k < ksecNPointsPerRadii - 1; k++) {
765 : // extra points spread them out.
766 60 : t = ((Double_t)(k-1)) * t0;
767 60 : xp[j][k] = x0+(x1-x0) * t;
768 60 : yp[j][k] = y0+(y1-y0) * t;
769 : } // end for k
770 60 : secAngleTurbo[i] = -TMath::RadToDeg() * TMath::ATan2(y1-y0, x1-x0);
771 60 : if(GetDebug(3)) {
772 0 : AliInfo(
773 : Form("i=%d -- angle=%f -- x0,y0=(%f, %f) -- x1,y1=(%f, %f)",
774 : i, secAngleTurbo[i], x0, y0, x1, y1));
775 0 : } // end if GetDebug(3)
776 : } // end for i
777 10 : sA0 = new TGeoXtru(2);
778 10 : sA0->SetName("SectorA0");
779 10 : sA0->DefinePolygon(m, xpp, ypp);
780 10 : sA0->DefineSection(0, -ksecDz);
781 10 : sA0->DefineSection(1, ksecDz);
782 :
783 : // store the edges of each XY segment which defines
784 : // one of the plane zones where staves will have to be placed
785 10 : fSPDsectorX0.Set(ksecNCoolingTubeDips);
786 10 : fSPDsectorY0.Set(ksecNCoolingTubeDips);
787 10 : fSPDsectorX1.Set(ksecNCoolingTubeDips);
788 10 : fSPDsectorY1.Set(ksecNCoolingTubeDips);
789 : Int_t ixy0, ixy1;
790 140 : for(i = 0; i < ksecNCoolingTubeDips; i++) {
791 : // Find index in xpp[] and ypp[] corresponding to where the
792 : // SPD ladders are to be attached. Order them according to
793 : // the ALICE numbering schema. Using array of indexes (+-1 for
794 : // cooling tubes. For any "bend/dip/edge, there are
795 : // ksecNPointsPerRadii+1 points involved.
796 70 : if(i == 0) j = 1;
797 60 : else if (i == 1) j = 0;
798 : else j = i;
799 60 : ixy0 = (ksecDipIndex[j]-1)*(ksecNPointsPerRadii+1)+
800 : (ksecNPointsPerRadii);
801 60 : ixy1 = (ksecDipIndex[j]+1) * (ksecNPointsPerRadii+1);
802 60 : fSPDsectorX0[i] = sA0->GetX(ixy0);
803 60 : fSPDsectorY0[i] = sA0->GetY(ixy0);
804 60 : fSPDsectorX1[i] = sA0->GetX(ixy1);
805 60 : fSPDsectorY1[i] = sA0->GetY(ixy1);
806 : } // end for i
807 :
808 : //printf("SectorA#%d ",0);
809 20 : InsidePoint(xpp[m-1],ypp[m-1],xpp[0],ypp[0],xpp[1],ypp[1],ksecCthick,
810 10 : xpp2[0],ypp2[0]);
811 1980 : for(i = 1; i < m - 1; i++) {
812 : j = i / (ksecNPointsPerRadii+1);
813 : //printf("SectorA#%d ",i);
814 1960 : InsidePoint(xpp[i-1],ypp[i-1],xpp[i],ypp[i],xpp[i+1],ypp[i+1],
815 980 : ksecCthick,xpp2[i],ypp2[i]);
816 : } // end for i
817 : //printf("SectorA#%d ",m);
818 20 : InsidePoint(xpp[m-2],ypp[m-2],xpp[m-1],ypp[m-1],xpp[0],ypp[0],
819 10 : ksecCthick,xpp2[m-1],ypp2[m-1]);
820 : // Fix center value of cooling tube dip and
821 : // find location of cooling tube centers
822 140 : for(i = 0; i < ksecNCoolingTubeDips; i++) {
823 60 : j = ksecDipIndex[i];
824 60 : x0 = xp2[j][1];
825 60 : y0 = yp2[j][1];
826 60 : x1 = xp2[j][ksecNPointsPerRadii-1];
827 60 : y1 = yp2[j][ksecNPointsPerRadii-1];
828 60 : t0 = TMath::Sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
829 60 : t = secDip2[i]/t0;
830 240 : for(k = 2; k < ksecNPointsPerRadii - 1; k++) {
831 : // extra points spread them out.
832 60 : t = ((Double_t)(k-1)) * t0;
833 60 : xp2[j][k] = x0+(x1-x0) * t;
834 60 : yp2[j][k] = y0+(y1-y0) * t;
835 : } // end for k
836 : } // end for i
837 10 : sA1 = new TGeoXtru(2);
838 10 : sA1->SetName("SectorA1");
839 10 : sA1->DefinePolygon(m, xpp2, ypp2);
840 10 : sA1->DefineSection(0, -ksecDz-ksecCthick2);
841 10 : sA1->DefineSection(1, ksecDz+ksecCthick2);
842 :
843 10 : sA2 = new TGeoCompositeShape("ITS SPD Carbon fiber support Sector A0",
844 : "SectorA0-SectorA1");
845 : //
846 : // Error in TGeoEltu. Semi-axis X must be < Semi-axis Y (?).
847 20 : sTA0 = new TGeoEltu("ITS SPD Cooling Tube TA0", 0.5 * ksecCoolTubeFlatY,
848 10 : 0.5 * ksecCoolTubeFlatX, ksecDz);
849 20 : sTA1 = new TGeoEltu("ITS SPD Cooling Tube coolant TA1",
850 20 : sTA0->GetA() - ksecCoolTubeThick,
851 20 : sTA0->GetB()-ksecCoolTubeThick,ksecDz);
852 10 : SPDsectorShape(ksecNRadii,secX2,secY2,secR2,secAngleStart2,secAngleEnd2,
853 : ksecNPointsPerRadii, m, xp, yp);
854 10 : sB0 = new TGeoXtru(2);
855 10 : sB0->SetName("EndB0");
856 10 : sB0->DefinePolygon(m, xpp, ypp);
857 10 : sB0->DefineSection(0, ksecDz);
858 10 : sB0->DefineSection(1, ksecDz + ksecZEndLen);
859 :
860 : //printf("SectorB#%d ",0);
861 : // Points around the most sharpened tips have to be avoided - M.S. 24 feb 09
862 : const Int_t nSpecialPoints = 5;
863 : const Int_t kSpecialPoints[nSpecialPoints] = {7, 17, 47, 62, 77};
864 : Int_t i2 = 0;
865 10 : InsidePoint(xpp[m-1],ypp[m-1],xpp[0],ypp[0],xpp[1],ypp[1],
866 : ksecCthick2,xpp2[i2],ypp2[i2]);
867 1980 : for(i = 1; i < m - 1; i++) {
868 : t = ksecCthick2;
869 13720 : for(k = 0; k < ksecNCoolingTubeDips; k++)
870 5880 : if((i/(ksecNPointsPerRadii+1))==ksecDipIndex[k])
871 540 : if(!(ksecDipIndex[k]*(ksecNPointsPerRadii+1) == i ||
872 240 : ksecDipIndex[k]*(ksecNPointsPerRadii+1) +
873 240 : ksecNPointsPerRadii == i))
874 180 : t = ksecRCoolOut-ksecRCoolIn;
875 : //printf("SectorB#%d ",i);
876 : Bool_t useThisPoint = kTRUE;
877 11760 : for(Int_t ii = 0; ii < nSpecialPoints; ii++)
878 9750 : if ( (i == kSpecialPoints[ii] - 1) ||
879 4950 : (i == kSpecialPoints[ii] + 1) ) useThisPoint = kFALSE;
880 980 : if (useThisPoint) {
881 880 : i2++;
882 1760 : InsidePoint(xpp[i-1],ypp[i-1],xpp[i],ypp[i],xpp[i+1],ypp[i+1],t,
883 880 : xpp2[i2],ypp2[i2]);
884 880 : }
885 : }// end for i
886 : //printf("SectorB#%d ",m);
887 10 : i2++;
888 20 : InsidePoint(xpp[m-2],ypp[m-2],xpp[m-1],ypp[m-1],xpp[0],ypp[0],
889 10 : ksecCthick2,xpp2[i2],ypp2[i2]);
890 10 : sB1 = new TGeoXtru(2);
891 10 : sB1->SetName("EndB1");
892 10 : sB1->DefinePolygon(i2+1, xpp2, ypp2);
893 10 : sB1->DefineSection(0,sB0->GetZ(0)-ksecCthick2);
894 10 : sB1->DefineSection(1,sB0->GetZ(1)+ksecCthick2);
895 :
896 10 : sB2 = new TGeoCompositeShape("ITS SPD Carbon fiber support Sector End B0",
897 : "EndB0-EndB1");
898 : // SPD sector mount blocks
899 20 : const Double_t kMountBlock[3] = {0.5*(1.8-0.2)*fgkmm,0.5*22.0*fgkmm,
900 10 : 0.5*45.0*fgkmm};
901 10 : sB3 = new TGeoBBox((Double_t*)kMountBlock);
902 : // SPD sector mount block screws and nuts (M.S. - 27 oct 2012)
903 10 : const Double_t kMountBlockM3ScrewR = 0.5*3.0*fgkmm; // Metric screw
904 10 : const Double_t kMountBlockHead1R = 0.5*8.0*fgkmm;
905 : const Double_t kMountBlockHead1H = 1.0*fgkmm;
906 10 : const Double_t kMountBlockHead2R = 0.5*6.0*fgkmm;
907 10 : const Double_t kMountBlockHead2H = 2.7*fgkmm;
908 10 : const Double_t kMountBlockM3NutR = 1.8*kMountBlockM3ScrewR; // Metric nut
909 : const Double_t kMountBlockM3NutH = kMountBlockM3NutR; // Metric nut
910 20 : TGeoTube *sM3 = new TGeoTube(0, kMountBlockM3ScrewR, sB3->GetDX());
911 10 : TGeoTube *sD1 = new TGeoTube(0, kMountBlockHead1R,kMountBlockHead1H/2);
912 10 : TGeoTube *sD2 = new TGeoTube(0, kMountBlockHead2R,kMountBlockHead2H/2);
913 10 : TGeoPgon *sN3 = new TGeoPgon(0, 360, 6, 2);
914 10 : sN3->DefineSection(0,-kMountBlockM3NutH/2, 0, kMountBlockM3NutR);
915 10 : sN3->DefineSection(1, kMountBlockM3NutH/2, 0, kMountBlockM3NutR);
916 : // SPD sector cooling tubes
917 20 : sTB0 = new TGeoTube("ITS SPD Cooling Tube End TB0", 0.0,
918 30 : 0.5*ksecCoolTubeROuter,0.5*(sB0->GetZ(1)-sB0->GetZ(0)));
919 20 : sTB1 = new TGeoTube("ITS SPD Cooling Tube End coolant TB0", 0.0,
920 20 : sTB0->GetRmax() - ksecCoolTubeThick,sTB0->GetDz());
921 : //
922 10 : if(GetDebug(3)) {
923 0 : if(medSPDcf) medSPDcf->Dump(); else AliInfo("medSPDcf = 0");
924 0 : if(medSPDss) medSPDss->Dump(); else AliInfo("medSPDss = 0");
925 0 : if(medSPDcoolfl) medSPDcoolfl->Dump();else AliInfo("medSPDcoolfl = 0");
926 0 : sA0->InspectShape();
927 0 : sA1->InspectShape();
928 0 : sB0->InspectShape();
929 0 : sB1->InspectShape();
930 0 : sB2->InspectShape();
931 0 : } // end if(GetDebug(3))
932 :
933 : // create the assembly of the support and place staves on it
934 10 : TGeoVolumeAssembly *vM0 = new TGeoVolumeAssembly(
935 : "ITSSPDSensitiveVirtualvolumeM0");
936 10 : StavesInSector(vM0);
937 : // create other volumes with some graphical settings
938 20 : TGeoVolume *vA0 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorA0",
939 10 : sA2, medSPDcf);
940 10 : vA0->SetVisibility(kTRUE);
941 10 : vA0->SetLineColor(4); // Blue
942 10 : vA0->SetLineWidth(1);
943 10 : vA0->SetFillColor(vA0->GetLineColor());
944 10 : vA0->SetFillStyle(4010); // 10% transparent
945 10 : TGeoVolume *vTA0 = new TGeoVolume("ITSSPDCoolingTubeTA0", sTA0, medSPDss);
946 10 : vTA0->SetVisibility(kTRUE);
947 10 : vTA0->SetLineColor(15); // gray
948 10 : vTA0->SetLineWidth(1);
949 10 : vTA0->SetFillColor(vTA0->GetLineColor());
950 10 : vTA0->SetFillStyle(4000); // 0% transparent
951 20 : TGeoVolume *vTA1 = new TGeoVolume("ITSSPDCoolingTubeFluidTA1",
952 10 : sTA1, medSPDcoolfl);
953 10 : vTA1->SetVisibility(kTRUE);
954 10 : vTA1->SetLineColor(6); // Purple
955 10 : vTA1->SetLineWidth(1);
956 10 : vTA1->SetFillColor(vTA1->GetLineColor());
957 10 : vTA1->SetFillStyle(4000); // 0% transparent
958 20 : TGeoVolume *vB0 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorEndB0",
959 10 : sB2, medSPDcf);
960 10 : vB0->SetVisibility(kTRUE);
961 10 : vB0->SetLineColor(1); // Black
962 10 : vB0->SetLineWidth(1);
963 10 : vB0->SetFillColor(vB0->GetLineColor());
964 10 : vB0->SetFillStyle(4000); // 0% transparent
965 20 : TGeoVolume *vB3 = new TGeoVolume(
966 10 : "ITSSPDCarbonFiberSupportSectorMountBlockB3",sB3, medSPDcf);
967 10 : vB3->SetVisibility(kTRUE);
968 10 : vB3->SetLineColor(26); // Brown shade
969 10 : vB3->SetLineWidth(1);
970 10 : vB3->SetFillColor(vB3->GetLineColor());
971 10 : vB3->SetFillStyle(4000); // 0% transparent
972 20 : TGeoVolume *vM3 = new TGeoVolume(
973 10 : "ITSSPDCarbonFiberSupportSectorMountBlockScrewM3",sM3, medSPDss);
974 10 : vM3->SetVisibility(kTRUE);
975 10 : vM3->SetLineColor(kGray); // Gray
976 10 : vM3->SetLineWidth(1);
977 10 : vM3->SetFillColor(vM3->GetLineColor());
978 10 : vM3->SetFillStyle(4000); // 0% transparent
979 20 : TGeoVolume *vD1 = new TGeoVolume(
980 10 : "ITSSPDCarbonFiberSupportSectorMountBlockScrewHead1",sD1, medSPDss);
981 10 : vD1->SetVisibility(kTRUE);
982 10 : vD1->SetLineColor(kGray); // Gray
983 10 : vD1->SetLineWidth(1);
984 10 : vD1->SetFillColor(vD1->GetLineColor());
985 10 : vD1->SetFillStyle(4000); // 0% transparent
986 20 : TGeoVolume *vD2 = new TGeoVolume(
987 10 : "ITSSPDCarbonFiberSupportSectorMountBlockScrewHead2",sD2, medSPDss);
988 10 : vD2->SetVisibility(kTRUE);
989 10 : vD2->SetLineColor(kGray); // Gray
990 10 : vD2->SetLineWidth(1);
991 10 : vD2->SetFillColor(vD2->GetLineColor());
992 10 : vD2->SetFillStyle(4000); // 0% transparent
993 20 : TGeoVolume *vN3 = new TGeoVolume(
994 10 : "ITSSPDCarbonFiberSupportSectorMountBlockScrewNut",sN3, medSPDss);
995 10 : vN3->SetVisibility(kTRUE);
996 10 : vN3->SetLineColor(kGray); // Gray
997 10 : vN3->SetLineWidth(1);
998 10 : vN3->SetFillColor(vN3->GetLineColor());
999 10 : vN3->SetFillStyle(4000); // 0% transparent
1000 10 : TGeoVolume *vTB0 = new TGeoVolume("ITSSPDCoolingTubeEndTB0",sTB0,medSPDss);
1001 10 : vTB0->SetVisibility(kTRUE);
1002 10 : vTB0->SetLineColor(15); // gray
1003 10 : vTB0->SetLineWidth(1);
1004 10 : vTB0->SetFillColor(vTB0->GetLineColor());
1005 10 : vTB0->SetFillStyle(4000); // 0% transparent
1006 10 : TGeoVolume *vTB1 = new TGeoVolume("ITSSPDCoolingTubeEndFluidTB1",sTB1,
1007 : medSPDcoolfl);
1008 10 : vTB1->SetVisibility(kTRUE);
1009 10 : vTB1->SetLineColor(7); // light blue
1010 10 : vTB1->SetLineWidth(1);
1011 10 : vTB1->SetFillColor(vTB1->GetLineColor());
1012 10 : vTB1->SetFillStyle(4050); // 0% transparent
1013 :
1014 : // add volumes to mother container passed as argument of this method
1015 10 : moth->AddNode(vM0,1,0); // Add virtual volume to mother
1016 10 : vTA0->AddNode(vTA1,1,0); // Put cooling liquid indide tube middel.
1017 10 : vTB0->AddNode(vTB1,1,0); // Put cooling liquid inside tube end.
1018 10 : Double_t tubeEndLocal[3]={0.0,0.0,sTA0->GetDz()};
1019 140 : for(i = 0; i < ksecNCoolingTubeDips; i++) {
1020 60 : x0 = secX3[ksecDipIndex[i]];
1021 60 : y0 = secY3[ksecDipIndex[i]];
1022 60 : t = 90.0 - secAngleTurbo[i];
1023 60 : z0 = 0.5*(sB1->GetZ(0)+sB1->GetZ(1));
1024 60 : trans = new TGeoTranslation("",x0,y0,z0);
1025 60 : vM0->AddNode(vTB0, i+1, trans);
1026 : // Find location of tube ends for later use.
1027 60 : trans->LocalToMaster(tubeEndLocal,fTubeEndSector[0][0][i]);
1028 60 : trans = new TGeoTranslation("",x0,y0,-z0);
1029 60 : vM0->AddNode(vTB0, i+1+ksecNCoolingTubeDips, trans);
1030 60 : rot = new TGeoRotation("", 0.0, 0.0, t);
1031 60 : rotrans = new TGeoCombiTrans("", x0, y0, 0.0, rot);
1032 60 : vM0->AddNode(vTA0, i+1, rotrans);
1033 : } // end for i
1034 10 : vM0->AddNode(vA0, 1, 0);
1035 10 : vM0->AddNode(vB0, 1, 0);
1036 : // Reflection.
1037 10 : rot = new TGeoRotation("", 90., 0., 90., 90., 180., 0.);
1038 10 : vM0->AddNode(vB0,2,rot);
1039 : // Find location of tube ends for later use.
1040 200 : for(i=0;i<ksecNCoolingTubeDips;i++) rot->LocalToMaster(
1041 60 : fTubeEndSector[0][0][i],fTubeEndSector[0][1][i]);
1042 : // Put screws inside the mounting block
1043 10 : const Double_t kMountingBlockScrew1ZPos = 0.7 *fgkcm;
1044 10 : const Double_t kMountingBlockScrew2ZPos = 2.01*fgkcm;
1045 10 : const Double_t kMountingBlockScrew34Pos = 0.51*fgkcm;
1046 30 : vB3->AddNode(vM3, 1, new TGeoCombiTrans(0, 0,
1047 20 : (sB3->GetDZ()-kMountingBlockScrew1ZPos),
1048 20 : new TGeoRotation("",90,90,90)));
1049 30 : vB3->AddNode(vM3, 2, new TGeoCombiTrans(0, 0,
1050 20 : (sB3->GetDZ()-kMountingBlockScrew2ZPos),
1051 20 : new TGeoRotation("",90,90,90)));
1052 30 : vB3->AddNode(vM3, 3, new TGeoCombiTrans(0,-kMountingBlockScrew34Pos,
1053 20 : -(sB3->GetDZ()-kMountingBlockScrew34Pos),
1054 20 : new TGeoRotation("",90,90,90)));
1055 30 : vB3->AddNode(vM3, 4, new TGeoCombiTrans(0, kMountingBlockScrew34Pos,
1056 20 : -(sB3->GetDZ()-kMountingBlockScrew34Pos),
1057 20 : new TGeoRotation("",90,90,90)));
1058 : // left side
1059 20 : t = -TMath::RadToDeg()*TMath::ATan2(
1060 10 : sB0->GetX(0)-sB0->GetX(sB0->GetNvert()-1),
1061 10 : sB0->GetY(0)-sB0->GetY(sB0->GetNvert()-1));
1062 10 : rot = new TGeoRotation("",t,0.0,0.0);// z axis rotation
1063 20 : x0 = 0.5*(sB0->GetX(0)+sB0->GetX(sB0->GetNvert()-1))+
1064 10 : sB3->GetDX()*TMath::Cos(t*TMath::DegToRad());
1065 20 : y0 = 0.5*(sB0->GetY(0)+sB0->GetY(sB0->GetNvert()-1))+
1066 10 : sB3->GetDX()*TMath::Sin(t*TMath::DegToRad());
1067 10 : z0 = sB0->GetZ(0)+sB3->GetDZ();
1068 10 : rotrans = new TGeoCombiTrans("",x0,y0,z0,rot);
1069 10 : vM0->AddNode(vB3,1,rotrans); // Put Mounting bracket on sector
1070 : // the screw heads and nuts
1071 10 : Double_t h = sM3->GetDz() + sD1->GetDz();
1072 10 : Double_t zt = sB3->GetDZ()-kMountingBlockScrew1ZPos;
1073 50 : vM0->AddNode(vD1, 1, new TGeoCombiTrans(x0+h*CosD(180+t), y0+h*SinD(180+t),
1074 10 : z0+zt,
1075 20 : new TGeoRotation("",90+t,90,90)));
1076 10 : h = sM3->GetDz() + sD2->GetDz() + ksecCthick2 + 0.06;
1077 10 : zt = sB3->GetDZ()-kMountingBlockScrew2ZPos;
1078 50 : vM0->AddNode(vD2, 1, new TGeoCombiTrans(x0+h*CosD(180+t), y0+h*SinD(180+t),
1079 10 : z0+zt,
1080 20 : new TGeoRotation("",90+t,90,90)));
1081 10 : Double_t loc[3],mas[3];
1082 10 : loc[0]=0;
1083 10 : loc[1]=-kMountingBlockScrew34Pos;
1084 10 : loc[2]=-(sB3->GetDZ()-kMountingBlockScrew34Pos);
1085 10 : rotrans->LocalToMaster(loc,mas);
1086 40 : vM0->AddNode(vD2, 2, new TGeoCombiTrans(mas[0]+h*CosD(180+t),
1087 20 : mas[1]+h*SinD(180+t),
1088 10 : mas[2],
1089 20 : new TGeoRotation("",90+t,90,90)));
1090 10 : loc[1]=kMountingBlockScrew34Pos;
1091 10 : rotrans->LocalToMaster(loc,mas);
1092 40 : vM0->AddNode(vD2, 3, new TGeoCombiTrans(mas[0]+h*CosD(180+t),
1093 20 : mas[1]+h*SinD(180+t),
1094 10 : mas[2],
1095 20 : new TGeoRotation("",90+t,90,90)));
1096 :
1097 10 : rot = new TGeoRotation("",t,180.0,0.0);// z & x axis rotation
1098 10 : rotrans = new TGeoCombiTrans("",x0,y0,-z0,rot);
1099 10 : vM0->AddNode(vB3,2,rotrans); // Put Mounting bracket on sector
1100 10 : h = sM3->GetDz() + sN3->GetZ(1);
1101 10 : zt = sB3->GetDZ()-kMountingBlockScrew1ZPos;
1102 50 : vM0->AddNode(vN3, 1, new TGeoCombiTrans(x0+h*CosD(180+t), y0+h*SinD(180+t),
1103 10 : -z0-zt,
1104 20 : new TGeoRotation("",90+t,90,90)));
1105 10 : h += ksecCthick2 + 0.06;
1106 10 : zt = sB3->GetDZ()-kMountingBlockScrew2ZPos;
1107 50 : vM0->AddNode(vN3, 2, new TGeoCombiTrans(x0+h*CosD(180+t), y0+h*SinD(180+t),
1108 10 : -z0-zt,
1109 20 : new TGeoRotation("",90+t,90,90)));
1110 10 : loc[1]=-kMountingBlockScrew34Pos;
1111 10 : rotrans->LocalToMaster(loc,mas);
1112 40 : vM0->AddNode(vN3, 3, new TGeoCombiTrans(mas[0]+h*CosD(180+t),
1113 20 : mas[1]+h*SinD(180+t),
1114 10 : mas[2],
1115 20 : new TGeoRotation("",90+t,90,90)));
1116 10 : loc[1]=kMountingBlockScrew34Pos;
1117 10 : rotrans->LocalToMaster(loc,mas);
1118 40 : vM0->AddNode(vN3, 4, new TGeoCombiTrans(mas[0]+h*CosD(180+t),
1119 20 : mas[1]+h*SinD(180+t),
1120 10 : mas[2],
1121 20 : new TGeoRotation("",90+t,90,90)));
1122 :
1123 10 : t *= -1.0;
1124 10 : rot = new TGeoRotation("",t,0.0,0.0); // z axis rotation
1125 30 : x0 = -0.5*(sB0->GetX(0)+sB0->GetX(sB0->GetNvert()-1))-3.5*
1126 20 : sB3->GetDX()*TMath::Cos(t*TMath::DegToRad());
1127 30 : y0 = 0.5*(sB0->GetY(0)+sB0->GetY(sB0->GetNvert()-1))-3.5*
1128 20 : sB3->GetDX()*TMath::Sin(t*TMath::DegToRad());
1129 10 : rotrans = new TGeoCombiTrans("",1.02*x0,y0,z0,rot);
1130 10 : vM0->AddNode(vB3,3,rotrans); // Put Mounting bracket on sector
1131 10 : h = sM3->GetDz() + sN3->GetZ(1) + 0.03;
1132 10 : zt = sB3->GetDZ()-kMountingBlockScrew1ZPos;
1133 50 : vM0->AddNode(vN3, 5, new TGeoCombiTrans(x0-h*CosD(180-t), y0+h*SinD(180-t),
1134 10 : z0+zt,
1135 20 : new TGeoRotation("",90+t,90,90)));
1136 10 : h += ksecCthick2 + 0.05;
1137 10 : zt = sB3->GetDZ()-kMountingBlockScrew2ZPos;
1138 50 : vM0->AddNode(vN3, 6, new TGeoCombiTrans(x0-h*CosD(180-t), y0+h*SinD(180-t),
1139 10 : z0+zt,
1140 20 : new TGeoRotation("",90+t,90,90)));
1141 10 : loc[1]=-kMountingBlockScrew34Pos;
1142 10 : rotrans->LocalToMaster(loc,mas);
1143 40 : vM0->AddNode(vN3, 7, new TGeoCombiTrans(mas[0]-h*CosD(180-t),
1144 20 : mas[1]+h*SinD(180-t),
1145 10 : mas[2],
1146 20 : new TGeoRotation("",90+t,90,90)));
1147 10 : loc[1]=kMountingBlockScrew34Pos;
1148 10 : rotrans->LocalToMaster(loc,mas);
1149 40 : vM0->AddNode(vN3, 8, new TGeoCombiTrans(mas[0]-h*CosD(180-t),
1150 20 : mas[1]+h*SinD(180-t),
1151 10 : mas[2],
1152 20 : new TGeoRotation("",90+t,90,90)));
1153 :
1154 10 : rot = new TGeoRotation("",t,180.0,0.0); // z & x axis rotation
1155 10 : rotrans = new TGeoCombiTrans("",1.02*x0,y0,-z0,rot);
1156 10 : vM0->AddNode(vB3,4,rotrans); // Put Mounting bracket on sector
1157 10 : h = sM3->GetDz() + sD1->GetDz();
1158 10 : zt = sB3->GetDZ()-kMountingBlockScrew1ZPos;
1159 50 : vM0->AddNode(vD1, 2, new TGeoCombiTrans(x0-h*CosD(180-t), y0+h*SinD(180-t),
1160 10 : -z0-zt,
1161 20 : new TGeoRotation("",90+t,90,90)));
1162 10 : h = sM3->GetDz() + sD2->GetDz() + ksecCthick2 + 0.08;
1163 10 : zt = sB3->GetDZ()-kMountingBlockScrew2ZPos;
1164 50 : vM0->AddNode(vD2, 4, new TGeoCombiTrans(x0-h*CosD(180-t), y0+h*SinD(180-t),
1165 10 : -z0-zt,
1166 20 : new TGeoRotation("",90+t,90,90)));
1167 10 : loc[1]=-kMountingBlockScrew34Pos;
1168 10 : rotrans->LocalToMaster(loc,mas);
1169 40 : vM0->AddNode(vD2, 5, new TGeoCombiTrans(mas[0]-h*CosD(180-t),
1170 20 : mas[1]+h*SinD(180-t),
1171 10 : mas[2],
1172 20 : new TGeoRotation("",90+t,90,90)));
1173 10 : loc[1]=kMountingBlockScrew34Pos;
1174 10 : rotrans->LocalToMaster(loc,mas);
1175 40 : vM0->AddNode(vD2, 6, new TGeoCombiTrans(mas[0]-h*CosD(180-t),
1176 20 : mas[1]+h*SinD(180-t),
1177 10 : mas[2],
1178 20 : new TGeoRotation("",90+t,90,90)));
1179 :
1180 10 : vM0->GetShape()->ComputeBBox(); //RS: enforce recompting of BBox
1181 :
1182 10 : if(GetDebug(3)){
1183 0 : vM0->PrintNodes();
1184 0 : vA0->PrintNodes();
1185 0 : vB0->PrintNodes();
1186 0 : vB3->PrintNodes();
1187 0 : vTA0->PrintNodes();
1188 0 : vTA1->PrintNodes();
1189 0 : vTB0->PrintNodes();
1190 0 : vTB1->PrintNodes();
1191 0 : } // end if(GetDebug(3))
1192 20 : }
1193 : //______________________________________________________________________
1194 : Bool_t AliITSv11GeometrySPD::CFHolePoints(Double_t s,Double_t r1,
1195 : Double_t r2,Double_t l,Double_t &x,Double_t &y) const
1196 : {
1197 : //
1198 : // Step along arck a distancs ds and compute boundry of
1199 : // two holes (radius r1 and r2) a distance l apart (along
1200 : // x-axis).
1201 : // Inputs:
1202 : // Double_t s fractional Distance along arcs [0-1]
1203 : // where 0-> alpha=beta=0, 1-> alpha=90 degrees.
1204 : // Double_t r1 radius at center circle
1205 : // Double_t r2 radius of displaced circle
1206 : // Double_t l Distance displaced circle is displaces (x-axis)
1207 : // Output:
1208 : // Double_t x x coordinate along double circle.
1209 : // Double_t y y coordinate along double circle.
1210 : // Return:
1211 : // logical, kFALSE if an error
1212 : //
1213 : Double_t alpha,beta;
1214 : Double_t ac,bc,scb,sca,t,alphac,betac; // at intersection of two circles
1215 :
1216 0 : x=y=0.0;
1217 0 : ac = r1*r1-l*l-r2*r2;
1218 0 : bc = 2.*l*r2;
1219 0 : if(bc==0.0) {printf("bc=0 l=%e r2=%e\n",l,r2);return kFALSE;}
1220 0 : betac = TMath::ACos(ac/bc);
1221 0 : alphac = TMath::Sqrt((bc-ac)*(bc+ac))/(2.*l*r1);
1222 0 : scb = r2*betac;
1223 0 : sca = r1*alphac;
1224 0 : t = r1*0.5*TMath::Pi() - sca + scb;
1225 0 : if(s<= scb/t){
1226 0 : beta = s*t/r2;
1227 0 : x = r2*TMath::Cos(beta) + l;
1228 0 : y = r2*TMath::Sin(beta);
1229 : //printf("betac=%e scb=%e t=%e s=%e beta=%e x=%e y=%e\n",
1230 : // betac,scb,t,s,beta,x,y);
1231 0 : return kTRUE;
1232 : }else{
1233 0 : beta = (s*t-scb+sca)/(r1*0.5*TMath::Pi());
1234 0 : alpha = beta*0.5*TMath::Pi();
1235 0 : x = r1*TMath::Cos(alpha);
1236 0 : y = r1*TMath::Sin(alpha);
1237 : //printf("alphac=%e sca=%e t=%e s=%e beta=%e alpha=%e x=%e y=%e\n",
1238 : // alphac,sca,t,s,beta,alpha,x,y);
1239 0 : return kTRUE;
1240 : } // end if
1241 : return kFALSE;
1242 0 : }
1243 : //______________________________________________________________________
1244 : Bool_t AliITSv11GeometrySPD::GetSectorMountingPoints(Int_t index,Double_t &x0,
1245 : Double_t &y0, Double_t &x1, Double_t &y1) const
1246 : {
1247 : //
1248 : // Returns the edges of the straight borders in the SPD sector shape,
1249 : // which are used to mount staves on them.
1250 : // Coordinate system is that of the carbon fiber sector volume.
1251 : // ---
1252 : // Index numbering is as follows:
1253 : // /5
1254 : // /\/4
1255 : // 1\ \/3
1256 : // 0|___\/2
1257 : // ---
1258 : // Arguments [the ones passed by reference contain output values]:
1259 : // Int_t index --> location index according to above scheme [0-5]
1260 : // Double_t &x0 --> (by ref) x0 location or the ladder sector [cm]
1261 : // Double_t &y0 --> (by ref) y0 location of the ladder sector [cm]
1262 : // Double_t &x1 --> (by ref) x1 location or the ladder sector [cm]
1263 : // Double_t &y1 --> (by ref) y1 location of the ladder sector [cm]
1264 : // TGeoManager *mgr --> The TGeo builder
1265 : // ---
1266 : // The location is described by a line going from (x0, y0) to (x1, y1)
1267 : // ---
1268 : // Returns kTRUE if no problems encountered.
1269 : // Returns kFALSE if a problem was encountered (e.g.: shape not found).
1270 : //
1271 120 : Int_t isize = fSPDsectorX0.GetSize();
1272 :
1273 60 : x0 = x1 = y0 = y1 = 0.0;
1274 120 : if(index < 0 || index > isize) {
1275 0 : AliError(Form("index = %d: allowed 0 --> %d", index, isize));
1276 0 : return kFALSE;
1277 : } // end if(index<0||index>isize)
1278 60 : x0 = fSPDsectorX0[index];
1279 60 : x1 = fSPDsectorX1[index];
1280 60 : y0 = fSPDsectorY0[index];
1281 60 : y1 = fSPDsectorY1[index];
1282 60 : return kTRUE;
1283 60 : }
1284 : //______________________________________________________________________
1285 : void AliITSv11GeometrySPD::SPDsectorShape(Int_t n,const Double_t *xc,
1286 : const Double_t *yc, const Double_t *r,
1287 : const Double_t *ths, const Double_t *the,
1288 : Int_t npr, Int_t &m, Double_t **xp, Double_t **yp) const
1289 : {
1290 : //
1291 : // Code to compute the points that make up the shape of the SPD
1292 : // Carbon fiber support sections
1293 : // Inputs:
1294 : // Int_t n size of arrays xc,yc, and r.
1295 : // Double_t *xc array of x values for radii centers.
1296 : // Double_t *yc array of y values for radii centers.
1297 : // Double_t *r array of signed radii values.
1298 : // Double_t *ths array of starting angles [degrees].
1299 : // Double_t *the array of ending angles [degrees].
1300 : // Int_t npr the number of lines segments to aproximate the arc.
1301 : // Outputs (arguments passed by reference):
1302 : // Int_t m the number of enetries in the arrays *xp[npr+1]
1303 : // and *yp[npr+1].
1304 : // Double_t **xp array of x coordinate values of the line segments
1305 : // which make up the SPD support sector shape.
1306 : // Double_t **yp array of y coordinate values of the line segments
1307 : // which make up the SPD support sector shape.
1308 : //
1309 : Int_t i, k;
1310 : Double_t t, t0, t1;
1311 :
1312 40 : m = n*(npr + 1);
1313 20 : if(GetDebug(2)) {
1314 0 : cout <<" X \t Y \t R \t S \t E" << m << endl;
1315 0 : for(i = 0; i < n; i++) {
1316 0 : cout << "{" << xc[i] << ", ";
1317 0 : cout << yc[i] << ", ";
1318 0 : cout << r[i] << ", ";
1319 0 : cout << ths[i] << ", ";
1320 0 : cout << the[i] << "}, " << endl;
1321 : } // end for i
1322 : } // end if(GetDebug(2))
1323 20 : if (GetDebug(3)) cout << "Double_t sA0 = [" << n*(npr+1)+1<<"][";
1324 20 : if (GetDebug(4)) cout << "3] {";
1325 20 : else if(GetDebug(3)) cout <<"2] {";
1326 20 : t0 = (Double_t)npr;
1327 840 : for(i = 0; i < n; i++) {
1328 400 : t1 = (the[i] - ths[i]) / t0;
1329 400 : if(GetDebug(5)) cout << "t1 = " << t1 << endl;
1330 4800 : for(k = 0; k <= npr; k++) {
1331 2000 : t = ths[i] + ((Double_t)k) * t1;
1332 2000 : xp[i][k] = TMath::Abs(r[i]) * CosD(t) + xc[i];
1333 2000 : yp[i][k] = TMath::Abs(r[i]) * SinD(t) + yc[i];
1334 2000 : if(GetDebug(3)) {
1335 0 : cout << "{" << xp[i][k] << "," << yp[i][k];
1336 0 : if (GetDebug(4)) cout << "," << t;
1337 0 : cout << "},";
1338 0 : } // end if GetDebug
1339 : } // end for k
1340 400 : if(GetDebug(3)) cout << endl;
1341 : } // end of i
1342 20 : if(GetDebug(3)) cout << "{" << xp[0][0] << ", " << yp[0][0];
1343 20 : if(GetDebug(4)) cout << "," << ths[0];
1344 20 : if(GetDebug(3)) cout << "}}" << endl;
1345 20 : }
1346 :
1347 : //______________________________________________________________________
1348 : TGeoVolume* AliITSv11GeometrySPD::CreateLadder(Int_t layer,TArrayD &sizes,
1349 : TGeoManager *mgr) const
1350 : {
1351 : //
1352 : // Creates the "ladder" = silicon sensor + 5 chips.
1353 : // Returns a TGeoVolume containing the following components:
1354 : // - the sensor (TGeoBBox), whose name depends on the layer
1355 : // - 5 identical chips (TGeoBBox)
1356 : // - a guard ring around the sensor (subtraction of TGeoBBoxes),
1357 : // which is separated from the rest of sensor because it is not
1358 : // a sensitive part
1359 : // - bump bondings (TGeoBBox stripes for the whole width of the
1360 : // sensor, one per column).
1361 : // ---
1362 : // Arguments:
1363 : // 1 - the owner layer (MUST be 1 or 2 or a fatal error is raised)
1364 : // 2 - a TArrayD passed by reference, which will contain relevant
1365 : // dimensions related to this object:
1366 : // size[0] = 'thickness' (the smallest dimension)
1367 : // size[1] = 'length' (the direction along the ALICE Z axis)
1368 : // size[2] = 'width' (extension in the direction perp. to the
1369 : // above ones)
1370 : // 3 - the used TGeoManager
1371 :
1372 : // ** CRITICAL CHECK **
1373 : // layer number can be ONLY 1 or 2
1374 80 : if (layer != 1 && layer != 2) AliFatal("Layer number MUST be 1 or 2");
1375 :
1376 : // ** MEDIA **
1377 40 : TGeoMedium *medAir = GetMedium("AIR$",mgr);
1378 40 : TGeoMedium *medSPDSiChip = GetMedium("SPD SI CHIP$",mgr); // SPD SI CHIP
1379 40 : TGeoMedium *medSi = GetMedium("SI$",mgr);
1380 40 : TGeoMedium *medBumpBond = GetMedium("COPPER$",mgr); // ??? BumpBond
1381 :
1382 : // ** SIZES **
1383 40 : Double_t chipThickness = fgkmm * 0.150;
1384 40 : Double_t chipWidth = fgkmm * 15.950;
1385 40 : Double_t chipLength = fgkmm * 13.600;
1386 40 : Double_t chipSpacing = fgkmm * 0.400; // separation of chips along Z
1387 40 : Double_t sensThickness = fgkmm * 0.200;
1388 40 : Double_t sensLength = fgkmm * 69.600;
1389 40 : Double_t sensWidth = fgkmm * 12.800;
1390 40 : Double_t guardRingWidth = fgkmm * 0.560; // a border of this thickness
1391 : // all around the sensor
1392 40 : Double_t bbLength = fgkmm * 0.042;
1393 : Double_t bbWidth = sensWidth;
1394 40 : Double_t bbThickness = fgkmm * 0.012;
1395 : Double_t bbPos = 0.080; // Z position w.r. to left pixel edge
1396 : // compute the size of the container volume which
1397 : // will also be returned in the referenced TArrayD;
1398 : // for readability, they are linked by reference to a more meaningful name
1399 40 : sizes.Set(3);
1400 40 : Double_t &thickness = sizes[0];
1401 40 : Double_t &length = sizes[1];
1402 40 : Double_t &width = sizes[2];
1403 : // the container is a box which exactly enclose all the stuff;
1404 40 : width = chipWidth;
1405 40 : length = sensLength + 2.0*guardRingWidth;
1406 40 : thickness = sensThickness + chipThickness + bbThickness;
1407 :
1408 : // ** VOLUMES **
1409 : // While creating this volume, since it is a sensitive volume,
1410 : // we must respect some standard criteria for its local reference frame.
1411 : // Local X must correspond to x coordinate of the sensitive volume:
1412 : // this means that we are going to create the container with a local
1413 : // reference system that is **not** in the middle of the box.
1414 : // This is accomplished by calling the shape constructor with an
1415 : // additional option ('originShift'):
1416 40 : Double_t xSens = 0.5 * (width - sensWidth - 2.0*guardRingWidth);
1417 40 : Double_t originShift[3] = {-xSens, 0., 0.};
1418 80 : TGeoBBox *shapeContainer = new TGeoBBox(0.5*width,0.5*thickness,
1419 40 : 0.5*length,originShift);
1420 : // then the volume is made of air, and using this shape
1421 80 : TGeoVolume *container = new TGeoVolume(Form("ITSSPDlay%d-Ladder",layer),
1422 40 : shapeContainer, medAir);
1423 : // the chip is a common box
1424 40 : TGeoVolume *volChip = mgr->MakeBox("ITSSPDchip",medSPDSiChip,
1425 40 : 0.5*chipWidth,0.5*chipThickness,0.5*chipLength);
1426 : // the sensor as well
1427 80 : TGeoVolume *volSens = mgr->MakeBox(GetSenstiveVolumeName(layer),medSi,
1428 40 : 0.5*sensWidth,0.5*sensThickness,0.5*sensLength);
1429 : // the guard ring shape is the subtraction of two boxes with the
1430 : // same center.
1431 40 : TGeoBBox *shIn = new TGeoBBox(0.5*sensWidth,sensThickness,0.5*sensLength);
1432 80 : TGeoBBox *shOut = new TGeoBBox(0.5*sensWidth+guardRingWidth,
1433 40 : 0.5*sensThickness,0.5*sensLength+guardRingWidth);
1434 40 : shIn->SetName("ITSSPDinnerBox");
1435 40 : shOut->SetName("ITSSPDouterBox");
1436 80 : TGeoCompositeShape *shBorder = new TGeoCompositeShape(
1437 120 : "ITSSPDgaurdRingBorder",Form("%s-%s",shOut->GetName(),shIn->GetName()));
1438 40 : TGeoVolume *volBorder = new TGeoVolume("ITSSPDgaurdRing",shBorder,medSi);
1439 : // bump bonds for one whole column
1440 40 : TGeoVolume *volBB = mgr->MakeBox("ITSSPDbb",medBumpBond,0.5*bbWidth,
1441 40 : 0.5*bbThickness,0.5*bbLength);
1442 : // set colors of all objects for visualization
1443 40 : volSens->SetLineColor(kYellow + 1);
1444 40 : volChip->SetLineColor(kGreen);
1445 40 : volBorder->SetLineColor(kYellow + 3);
1446 40 : volBB->SetLineColor(kGray);
1447 :
1448 : // ** MOVEMENTS **
1449 : // sensor is translated along thickness (X) and width (Y)
1450 40 : Double_t ySens = 0.5 * (thickness - sensThickness);
1451 : Double_t zSens = 0.0;
1452 : // we want that the x of the ladder is the same as the one of
1453 : // its sensitive volume
1454 40 : TGeoTranslation *trSens = new TGeoTranslation(0.0, ySens, zSens);
1455 : // bump bonds are translated along all axes:
1456 : // keep same Y used for sensors, but change the Z
1457 40 : TGeoTranslation *trBB[160];
1458 : Double_t x = 0.0;
1459 40 : Double_t y = 0.5 * (thickness - bbThickness) - sensThickness;
1460 40 : Double_t z = -0.5 * sensLength + guardRingWidth + fgkmm*0.425 - bbPos;
1461 : Int_t i;
1462 12880 : for (i = 0; i < 160; i++) {
1463 12800 : trBB[i] = new TGeoTranslation(x, y, z);
1464 6400 : switch(i) {
1465 : case 31:case 63:case 95:case 127:
1466 160 : z += fgkmm * 0.625 + fgkmm * 0.2;
1467 160 : break;
1468 : default:
1469 6240 : z += fgkmm * 0.425;
1470 6240 : } // end switch
1471 : } // end for i
1472 : // the chips are translated along the length (Z) and thickness (X)
1473 40 : TGeoTranslation *trChip[5] = {0, 0, 0, 0, 0};
1474 : x = -xSens;
1475 40 : y = 0.5 * (chipThickness - thickness);
1476 : z = 0.0;
1477 480 : for (i = 0; i < 5; i++) {
1478 200 : z = -0.5*length + guardRingWidth
1479 200 : + (Double_t)i*chipSpacing + ((Double_t)(i) + 0.5)*chipLength;
1480 400 : trChip[i] = new TGeoTranslation(x, y, z);
1481 : } // end ofr i
1482 :
1483 : // add nodes to container
1484 40 : container->AddNode(volSens, 1, trSens);
1485 40 : container->AddNode(volBorder, 1, trSens);
1486 12880 : for (i = 0; i < 160; i++) container->AddNode(volBB,i+1,trBB[i]);
1487 480 : for (i = 0; i < 5; i++) container->AddNode(volChip,i+3,trChip[i]);
1488 : // return the container
1489 40 : return container;
1490 40 : }
1491 :
1492 : //______________________________________________________________________
1493 : TGeoVolume* AliITSv11GeometrySPD::CreateClip(TArrayD &sizes,Bool_t isDummy,
1494 : TGeoManager *mgr) const
1495 : {
1496 : //
1497 : // Creates the carbon fiber clips which are added to the central ladders.
1498 : // They have a complicated shape which is approximated by a TGeoXtru
1499 : // Implementation of a single clip over an half-stave.
1500 : // It has a complicated shape which is approximated to a section like this:
1501 : //
1502 : // 6
1503 : // /\ .
1504 : // 7 //\\ 5
1505 : // / 1\\___________________4
1506 : // 0 \___________________
1507 : // 2 3
1508 : // with a finite thickness for all the shape
1509 : // Its local reference frame is such that point A corresponds to origin.
1510 : //
1511 :
1512 : // MODIFIED geometry
1513 50 : Double_t sposty = fgkmm * -0.5; // lower internal side to avoid overlaps with modified geometry
1514 :
1515 50 : Double_t fullLength = fgkmm * 12.6; // = x4 - x0
1516 50 : Double_t flatLength = fgkmm * 5.4; // = x4 - x3
1517 50 : Double_t inclLongLength = fgkmm * 5.0; // = 5-6
1518 50 : Double_t inclShortLength = fgkmm * 2.0; // = 6-7
1519 50 : Double_t fullHeight = fgkmm * 2.8; // = y6 - y3
1520 50 : Double_t thickness = fgkmm * 0.18; // thickness
1521 50 : Double_t totalLength = fgkmm * 52.0; // total length in Z
1522 : Double_t holeSize = fgkmm * 5.0; // dimension of cubic
1523 : // hole inserted for pt1000
1524 : Double_t angle1 = 27.0; // supplementary of angle DCB
1525 : Double_t angle2; // angle DCB
1526 : Double_t angle3; // angle of GH with vertical
1527 :
1528 : angle2 = 0.5 * (180.0 - angle1);
1529 150 : angle3 = 90.0 - TMath::ACos(fullLength - flatLength -
1530 100 : inclLongLength*TMath::Cos(angle1)) *
1531 50 : TMath::RadToDeg();
1532 50 : angle1 *= TMath::DegToRad();
1533 50 : angle2 *= TMath::DegToRad();
1534 50 : angle3 *= TMath::DegToRad();
1535 :
1536 50 : Double_t x[8], y[8];
1537 :
1538 50 : x[0] = 0.0;
1539 50 : x[1] = x[0] + fullLength - flatLength - inclLongLength*TMath::Cos(angle1);
1540 50 : x[2] = x[0] + fullLength - flatLength;
1541 50 : x[3] = x[0] + fullLength;
1542 50 : x[4] = x[3];
1543 50 : x[5] = x[4] - flatLength + thickness * TMath::Cos(angle2);
1544 50 : x[6] = x[1];
1545 50 : x[7] = x[0];
1546 :
1547 50 : y[0] = 0.0;
1548 50 : y[1] = y[0] + inclShortLength * TMath::Cos(angle3);
1549 50 : y[2] = y[1] - inclLongLength * TMath::Sin(angle1);
1550 50 : y[3] = y[2];
1551 50 : y[4] = y[3] + thickness;
1552 50 : y[5] = y[4];
1553 50 : y[6] = y[1] + thickness;
1554 50 : y[7] = y[0] + thickness;
1555 :
1556 50 : y[0] += sposty;
1557 50 : y[7] += sposty;
1558 :
1559 50 : sizes.Set(7);
1560 50 : sizes[0] = totalLength;
1561 50 : sizes[1] = fullHeight;
1562 50 : sizes[2] = y[2];
1563 50 : sizes[3] = y[6];
1564 50 : sizes[4] = x[0];
1565 50 : sizes[5] = x[3];
1566 50 : sizes[6] = x[2];
1567 :
1568 50 : if(isDummy){// use this argument when on ewant just the
1569 : // positions without create any volume
1570 40 : return NULL;
1571 : } // end if isDummy
1572 :
1573 10 : TGeoXtru *shClip = new TGeoXtru(2);
1574 10 : shClip->SetName("ITSSPDshclip");
1575 10 : shClip->DefinePolygon(8, x, y);
1576 10 : shClip->DefineSection(0, -0.5*totalLength, 0., 0., 1.0);
1577 10 : shClip->DefineSection(1, 0.5*totalLength, 0., 0., 1.0);
1578 :
1579 10 : TGeoBBox *shHole = new TGeoBBox("ITSSPDSHClipHole",0.5*holeSize,
1580 : 0.5*holeSize,0.5*holeSize);
1581 20 : TGeoTranslation *tr1 = new TGeoTranslation("ITSSPDTRClipHole1",x[2],0.0,
1582 10 : fgkmm*14.);
1583 10 : TGeoTranslation *tr2 = new TGeoTranslation("ITSSPDTRClipHole2",x[2],0.0,
1584 : 0.0);
1585 20 : TGeoTranslation *tr3 = new TGeoTranslation("ITSSPDTRClipHole3",x[2],0.0,
1586 10 : -fgkmm*14.);
1587 10 : tr1->RegisterYourself();
1588 10 : tr2->RegisterYourself();
1589 10 : tr3->RegisterYourself();
1590 :
1591 : //TString strExpr("ITSSPDshclip-(");
1592 10 : TString strExpr(shClip->GetName());
1593 10 : strExpr.Append("-(");
1594 40 : strExpr.Append(Form("%s:%s+", shHole->GetName(), tr1->GetName()));
1595 40 : strExpr.Append(Form("%s:%s+", shHole->GetName(), tr2->GetName()));
1596 40 : strExpr.Append(Form("%s:%s)", shHole->GetName(), tr3->GetName()));
1597 30 : TGeoCompositeShape *shClipHole = new TGeoCompositeShape(
1598 10 : "ITSSPDSHClipHoles",strExpr.Data());
1599 :
1600 10 : TGeoMedium *mat = GetMedium("SPD C (M55J)$", mgr);
1601 20 : TGeoVolume *vClip = new TGeoVolume("ITSSPDclip", shClipHole, mat);
1602 10 : vClip->SetLineColor(kGray + 2);
1603 : return vClip;
1604 60 : }
1605 :
1606 : //______________________________________________________________________
1607 : TGeoVolume* AliITSv11GeometrySPD::CreatePatchPanel(TArrayD &sizes,
1608 : TGeoManager *mgr) const
1609 : {
1610 : //
1611 : // Creates the patch panel approximated with a "L"-shaped TGeoXtru
1612 : // with a finite thickness for all the shape
1613 : // Its local reference frame is such that point A corresponds to origin.
1614 : //
1615 4 : Double_t hLength = fgkmm * 50.0; // horizontal length
1616 : Double_t vLength = fgkmm * 50.0; // vertical length
1617 : Double_t angle = 88.3; // angle between hor and vert
1618 2 : Double_t thickness = fgkmm * 4.0; // thickness
1619 2 : Double_t width = fgkmm * 100.0; // width looking from cone
1620 :
1621 2 : Double_t x[7], y[7];
1622 :
1623 2 : y[0] = 0.0;
1624 2 : y[1] = y[0] + hLength;
1625 2 : y[2] = y[1];
1626 2 : y[3] = y[0] + thickness;
1627 2 : y[4] = y[3] + vLength * TMath::Cos(angle*TMath::DegToRad());
1628 2 : y[5] = y[4] - thickness / TMath::Sin(angle*TMath::DegToRad());
1629 2 : y[6] = y[0];
1630 :
1631 2 : x[0] = 0.0;
1632 2 : x[1] = x[0];
1633 2 : x[2] = x[1] + thickness;
1634 2 : x[3] = x[2];
1635 2 : x[4] = x[3] + vLength * TMath::Sin(angle*TMath::DegToRad());
1636 2 : x[5] = x[4];
1637 2 : x[6] = x[0] + thickness;
1638 :
1639 2 : sizes.Set(3);
1640 2 : sizes[0] = hLength;
1641 2 : sizes[1] = vLength;
1642 2 : sizes[2] = thickness;
1643 :
1644 2 : TGeoXtru *shPatch = new TGeoXtru(2);
1645 2 : shPatch->SetName("ITSSPDpatchShape1");
1646 2 : shPatch->DefinePolygon(7, x, y);
1647 2 : shPatch->DefineSection(0, -0.5*width, 0., 0., 1.0);
1648 2 : shPatch->DefineSection(1, 0.5*width, 0., 0., 1.0);
1649 :
1650 : /*
1651 : Double_t subThickness = 10.0 * fgkmm;
1652 : Double_t subWidth = 55.0 * fgkmm;
1653 : new TGeoBBox("ITSSPDpatchShape2", 0.5*subThickness, 60.0 * fgkmm, 0.5*subWidth);
1654 : TGeoRotation *rotSub = new TGeoRotation(*gGeoIdentity);
1655 : rotSub->SetName("shPatchSubRot");
1656 : rotSub->RotateZ(50.0);
1657 : rotSub->RegisterYourself();
1658 : TGeoCombiTrans *trSub = new TGeoCombiTrans(0.26*hLength, 0.26*vLength, 0.0, rotSub);
1659 : trSub->SetName("shPatchSubTr");
1660 : trSub->RegisterYourself();
1661 :
1662 : TGeoCompositeShape *shPatchFinal = new TGeoCompositeShape("ITSSPDpatchShape1-(ITSSPDpatchShape2:shPatchSubTr)");
1663 : */
1664 :
1665 2 : TGeoMedium *mat = GetMedium("AL$", mgr);
1666 : //TGeoVolume *vPatch = new TGeoVolume("ITSSPDpatchPanel", shPatchFinal, mat);
1667 2 : TGeoVolume *vPatch = new TGeoVolume("ITSSPDpatchPanel", shPatch, mat);
1668 2 : vPatch->SetLineColor(kAzure);
1669 :
1670 2 : return vPatch;
1671 2 : }
1672 :
1673 : //___________________________________________________________________
1674 : TGeoCompositeShape* AliITSv11GeometrySPD::CreateGroundingFoilShape
1675 : (Int_t itype,Double_t &length,Double_t &width,
1676 : Double_t thickness,TArrayD &sizes)
1677 : {
1678 : //
1679 : // Creates the typical composite shape of the grounding foil:
1680 : //
1681 : // +---------------------------------------------------------+
1682 : // | 5 6 9 |
1683 : // | +-----------+ +------------+ 10
1684 : // | O | | |
1685 : // | 3 /-----+ 4 +------+
1686 : // | 1 / 7 8
1687 : // | /----------/
1688 : // +-----/ 2 +
1689 : // 0
1690 : // Z + 11
1691 : //
1692 : // This shape is used 4 times: two layers of glue, one in kapton
1693 : // and one in aluminum, taking into account that the aliminum
1694 : // layer has small differences in the size of some parts.
1695 : // ---
1696 : // In order to overcome problems apparently due to a large number
1697 : // of points, the shape creation is done according the following
1698 : // steps:
1699 : // 1) a TGeoBBox is created with a size right enough to contain
1700 : // the whole shape (0-1-X-13)
1701 : // 2) holes are defined as other TGeoBBox which are subtracted
1702 : // from the main shape
1703 : // 3) a TGeoXtru is defined connecting the points (0-->11-->0)
1704 : // and is also subtracted from the main shape
1705 : // ---
1706 : // The argument ("type") is used to choose between all these
1707 : // possibilities:
1708 : // - type = 0 --> kapton layer
1709 : // - type = 1 --> aluminum layer
1710 : // - type = 2 --> glue layer between support and GF
1711 : // - type = 3 --> glue layer between GF and ladders
1712 : // Returns: a TGeoCompositeShape which will then be used to shape
1713 : // several volumes. Since TGeoXtru is used, the local reference
1714 : // frame of this object has X horizontal and Y vertical w.r to
1715 : // the shape drawn above, and Z axis going perpendicularly to the screen.
1716 : // This is not the correct reference for the half stave, for which
1717 : // the "long" dimension is Z and the "short" is X, while Y goes in
1718 : // the direction of thickness. This will imply some rotations when
1719 : // using the volumes created with this shape.
1720 :
1721 : // suffix to differentiate names
1722 320 : Char_t type[10];
1723 :
1724 : // size of the virtual box containing exactly this volume
1725 160 : length = fgkmm * 243.18;
1726 160 : width = fgkmm * 15.95;
1727 160 : if (itype == 1) {
1728 40 : length -= fgkmm * 0.4;
1729 40 : width -= fgkmm * 0.4;
1730 40 : } // end if itype==1
1731 320 : switch (itype) {
1732 : case 0:
1733 40 : snprintf(type,10,"Kap");
1734 40 : break;
1735 : case 1:
1736 40 : snprintf(type,10, "Alu");
1737 40 : break;
1738 : case 2:
1739 40 : snprintf(type,10,"Glue1");
1740 40 : break;
1741 : case 3:
1742 40 : snprintf(type,10,"Glue2");
1743 40 : break;
1744 : }
1745 : // we divide the shape in several slices along the horizontal
1746 : // direction (local X) here we define define the length of all
1747 : // sectors (from leftmost to rightmost)
1748 : Int_t i;
1749 160 : Double_t sliceLength[] = { 140.71, 2.48, 26.78, 4.00,
1750 : 10.00, 24.40, 10.00, 24.81 };
1751 2880 : for (i = 0; i < 8; i++) sliceLength[i] *= fgkmm;
1752 160 : if (itype == 1) {
1753 40 : sliceLength[0] -= fgkmm * 0.2;
1754 40 : sliceLength[4] -= fgkmm * 0.2;
1755 40 : sliceLength[5] += fgkmm * 0.4;
1756 40 : sliceLength[6] -= fgkmm * 0.4;
1757 40 : } // end if itype ==1
1758 :
1759 : // as shown in the drawing, we have four different widths
1760 : // (along local Y) in this shape:
1761 160 : Double_t widthMax = fgkmm * 15.95;
1762 160 : Double_t widthMed1 = fgkmm * 15.00;
1763 160 : Double_t widthMed2 = fgkmm * 11.00;
1764 160 : Double_t widthMin = fgkmm * 4.40;
1765 160 : if (itype == 1) {
1766 40 : widthMax -= fgkmm * 0.4;
1767 40 : widthMed1 -= fgkmm * 0.4;
1768 40 : widthMed2 -= fgkmm * 0.4;
1769 40 : widthMin -= fgkmm * 0.4;
1770 40 : } // end if itype==1
1771 :
1772 : // create the main shape
1773 : TGeoBBox *shGroundFull = 0;
1774 320 : shGroundFull = new TGeoBBox(Form("ITSSPDSHgFoil%sFull", type),
1775 160 : 0.5*length,0.5*width, 0.5*thickness);
1776 :
1777 160 : if(GetDebug(5)) shGroundFull->Print(); // Avoid Coverity warning
1778 :
1779 : // create the polygonal shape to be subtracted to give the correct
1780 : // shape to the borders its vertices are defined in sugh a way that
1781 : // this polygonal will be placed in the correct place considered
1782 : // that the origin of the local reference frame is in the center
1783 : // of the main box: we fix the starting point at the lower-left
1784 : // edge of the shape (point 12), and add all points in order,
1785 : // following a clockwise rotation
1786 :
1787 160 : Double_t x[13], y[13];
1788 160 : x[ 0] = -0.5 * length + sliceLength[0];
1789 160 : y[ 0] = -0.5 * widthMax;
1790 :
1791 160 : x[ 1] = x[0] + sliceLength[1];
1792 160 : y[ 1] = y[0] + (widthMax - widthMed1);
1793 :
1794 160 : x[ 2] = x[1] + sliceLength[2];
1795 160 : y[ 2] = y[1];
1796 :
1797 160 : x[ 3] = x[2] + sliceLength[3];
1798 160 : y[ 3] = y[2] + (widthMed1 - widthMed2);
1799 :
1800 160 : x[ 4] = x[3] + sliceLength[4];
1801 160 : y[ 4] = y[3];
1802 :
1803 160 : x[ 5] = x[4];
1804 160 : y[ 5] = y[4] + (widthMed2 - widthMin);
1805 :
1806 160 : x[ 6] = x[5] + sliceLength[5];
1807 160 : y[ 6] = y[5];
1808 :
1809 160 : x[ 7] = x[6];
1810 160 : y[ 7] = y[4];
1811 :
1812 160 : x[ 8] = x[7] + sliceLength[6];
1813 160 : y[ 8] = y[7];
1814 :
1815 160 : x[ 9] = x[8];
1816 160 : y[ 9] = y[6];
1817 :
1818 160 : x[10] = x[9] + sliceLength[7] + 0.5;
1819 160 : y[10] = y[9];
1820 :
1821 160 : x[11] = x[10];
1822 160 : y[11] = y[0] - 0.5;
1823 :
1824 160 : x[12] = x[0];
1825 160 : y[12] = y[11];
1826 :
1827 : // create the shape
1828 160 : TGeoXtru *shGroundXtru = new TGeoXtru(2);
1829 160 : shGroundXtru->SetName(Form("ITSSPDSHgFoil%sXtru", type));
1830 160 : shGroundXtru->DefinePolygon(13, x, y);
1831 160 : shGroundXtru->DefineSection(0, -thickness, 0., 0., 1.0);
1832 160 : shGroundXtru->DefineSection(1, thickness, 0., 0., 1.0);
1833 :
1834 : // define a string which will express the algebric operations among volumes
1835 : // and add the subtraction of this shape from the main one
1836 320 : TString strComposite(Form("ITSSPDSHgFoil%sFull-(%s+", type,
1837 160 : shGroundXtru->GetName()));
1838 :
1839 : // define the holes according to size information coming from drawings:
1840 160 : Double_t holeLength = fgkmm * 10.00;
1841 160 : Double_t holeWidth = fgkmm * 7.50;
1842 160 : Double_t holeSepX0 = fgkmm * 7.05; // separation between center
1843 : // of first hole and left border
1844 160 : Double_t holeSepXC = fgkmm * 14.00; // separation between the centers
1845 : // of two consecutive holes
1846 160 : Double_t holeSepX1 = fgkmm * 15.42; // separation between centers of
1847 : // 5th and 6th hole
1848 160 : Double_t holeSepX2 = fgkmm * 22.00; // separation between centers of
1849 : // 10th and 11th hole
1850 160 : if (itype == 1) {
1851 40 : holeSepX0 -= fgkmm * 0.2;
1852 40 : holeLength += fgkmm * 0.4;
1853 40 : holeWidth += fgkmm * 0.4;
1854 40 : } // end if itype==1
1855 160 : sizes.Set(7);
1856 320 : sizes[0] = holeLength;
1857 320 : sizes[1] = holeWidth;
1858 320 : sizes[2] = holeSepX0;
1859 320 : sizes[3] = holeSepXC;
1860 320 : sizes[4] = holeSepX1;
1861 320 : sizes[5] = holeSepX2;
1862 320 : sizes[6] = fgkmm * 4.40;
1863 :
1864 : // X position of hole center (will change for each hole)
1865 160 : Double_t holeX = -0.5*length;
1866 : // Y position of center of all holes (= 4.4 mm from upper border)
1867 160 : Double_t holeY = 0.5*(width - holeWidth) - widthMin;
1868 :
1869 : // create a shape for the holes (common)
1870 640 : new TGeoBBox(Form("ITSSPD%sGfoilHole", type),0.5*holeLength,
1871 160 : 0.5*holeWidth, thickness);
1872 :
1873 : // insert the holes in the XTRU shape:
1874 : // starting from the first value of X, they are simply
1875 : // shifted along this axis
1876 160 : char name[200];
1877 160 : TGeoTranslation *transHole[11];
1878 3840 : for (i = 0; i < 11; i++) {
1879 : // set the position of the hole, depending on index
1880 1760 : if (i == 0) {
1881 160 : holeX += holeSepX0;
1882 1760 : }else if (i < 5) {
1883 640 : holeX += holeSepXC;
1884 1600 : }else if (i == 5) {
1885 160 : holeX += holeSepX1;
1886 960 : }else if (i < 10) {
1887 640 : holeX += holeSepXC;
1888 640 : }else {
1889 160 : holeX += holeSepX2;
1890 : } // end if else if's
1891 : //cout << i << " --> X = " << holeX << endl;
1892 1760 : snprintf(name,200,"ITSSPDTRgFoil%sHole%d", type, i);
1893 5280 : transHole[i] = new TGeoTranslation(name, holeX, holeY, 0.0);
1894 1760 : transHole[i]->RegisterYourself();
1895 3520 : strComposite.Append(Form("ITSSPD%sGfoilHole:%s", type, name));
1896 3520 : if (i < 10) strComposite.Append("+"); else strComposite.Append(")");
1897 : } // end for i
1898 :
1899 : // create composite shape
1900 480 : TGeoCompositeShape *shGround = new TGeoCompositeShape(
1901 320 : Form("ITSSPDSHgFoil%s", type), strComposite.Data());
1902 :
1903 : return shGround;
1904 160 : }
1905 : //______________________________________________________________________
1906 : TGeoVolumeAssembly* AliITSv11GeometrySPD::CreateGroundingFoil(Bool_t isRight,
1907 : TArrayD &sizes, TGeoManager *mgr)
1908 : {
1909 : //
1910 : // Create a volume containing all parts of the grounding foil a
1911 : // for a half-stave.
1912 : // It consists of 4 layers with the same shape but different thickness:
1913 : // 1) a layer of glue
1914 : // 2) the aluminum layer
1915 : // 3) the kapton layer
1916 : // 4) another layer of glue
1917 : // ---
1918 : // Arguments:
1919 : // 1: a boolean value to know if it is the grounding foir for
1920 : // the right or left side
1921 : // 2: a TArrayD which will contain the dimension of the container box:
1922 : // - size[0] = length along Z (the beam line direction)
1923 : // - size[1] = the 'width' of the stave, which defines, together
1924 : // with Z, the plane of the carbon fiber support
1925 : // - size[2] = 'thickness' (= the direction along which all
1926 : // stave components are superimposed)
1927 : // 3: the TGeoManager
1928 : // ---
1929 : // The return value is a TGeoBBox volume containing all grounding
1930 : // foil components.
1931 : // to avoid strange behaviour of the geometry manager,
1932 : // create a suffix to be used in the names of all shapes
1933 : //
1934 40 : char suf[5];
1935 80 : if (isRight) strncpy(suf, "R", 5); else strncpy(suf, "L", 5);
1936 : // this volume will be created in order to ease its placement in
1937 : // the half-stave; then, it is added here the small distance of
1938 : // the "central" edge of each volume from the Z=0 plane in the stave
1939 : // reference (which coincides with ALICE one)
1940 40 : Double_t dist = fgkmm * 0.71;
1941 :
1942 : // define materials
1943 40 : TGeoMedium *medKap = GetMedium("SPD KAPTON(POLYCH2)$", mgr);
1944 40 : TGeoMedium *medAlu = GetMedium("AL$", mgr);
1945 40 : TGeoMedium *medGlue = GetMedium("EPOXY$", mgr); //??? GLUE_GF_SUPPORT
1946 :
1947 : // compute the volume shapes (thicknesses change from one to the other)
1948 40 : Double_t kpLength, kpWidth, alLength, alWidth;
1949 80 : TArrayD kpSize, alSize, glSize;
1950 40 : Double_t kpThickness = fgkmm * 0.04;
1951 40 : Double_t alThickness = fgkmm * 0.01;
1952 : //cout << "AL THICKNESS" << alThickness << endl;
1953 : //Double_t g0Thickness = fgkmm * 0.1175 - fgkGapHalfStave;
1954 : //Double_t g1Thickness = fgkmm * 0.1175 - fgkGapLadder;
1955 40 : Double_t g0Thickness = fgkmm * 0.1275 - fgkGapHalfStave;
1956 40 : Double_t g1Thickness = fgkmm * 0.1275 - fgkGapLadder;
1957 40 : TGeoCompositeShape *kpShape = CreateGroundingFoilShape(0,kpLength,kpWidth,
1958 : kpThickness, kpSize);
1959 40 : TGeoCompositeShape *alShape = CreateGroundingFoilShape(1,alLength,alWidth,
1960 : alThickness, alSize);
1961 40 : TGeoCompositeShape *g0Shape = CreateGroundingFoilShape(2,kpLength,kpWidth,
1962 : g0Thickness, glSize);
1963 40 : TGeoCompositeShape *g1Shape = CreateGroundingFoilShape(3,kpLength,kpWidth,
1964 : g1Thickness, glSize);
1965 : // create the component volumes and register their sizes in the
1966 : // passed arrays for readability reasons, some reference variables
1967 : // explicit the meaning of the array slots
1968 120 : TGeoVolume *kpVol = new TGeoVolume(Form("ITSSPDgFoilKap%s",suf),
1969 40 : kpShape, medKap);
1970 120 : TGeoVolume *alVol = new TGeoVolume(Form("ITSSPDgFoilAlu%s",suf),
1971 40 : alShape, medAlu);
1972 120 : TGeoVolume *g0Vol = new TGeoVolume(Form("ITSSPDgFoilGlue%s",suf),
1973 40 : g0Shape, medGlue);
1974 120 : TGeoVolume *g1Vol = new TGeoVolume(Form("ITSSPDgFoilGlue%s",suf),
1975 40 : g1Shape, medGlue);
1976 : // set colors for the volumes
1977 40 : kpVol->SetLineColor(kRed);
1978 40 : alVol->SetLineColor(kGray);
1979 40 : g0Vol->SetLineColor(kYellow);
1980 40 : g1Vol->SetLineColor(kYellow);
1981 : // create references for the final size object
1982 40 : if (sizes.GetSize() != 3) sizes.Set(3);
1983 40 : Double_t &fullThickness = sizes[0];
1984 40 : Double_t &fullLength = sizes[1];
1985 40 : Double_t &fullWidth = sizes[2];
1986 : // kapton leads the larger dimensions of the foil
1987 : // (including the cited small distance from Z=0 stave reference plane)
1988 : // the thickness is the sum of the ones of all components
1989 40 : fullLength = kpLength + dist;
1990 40 : fullWidth = kpWidth;
1991 40 : fullThickness = kpThickness + alThickness + g0Thickness + g1Thickness;
1992 : // create the container
1993 : // TGeoMedium *air = GetMedium("AIR$", mgr);
1994 120 : TGeoVolumeAssembly *container = new TGeoVolumeAssembly(Form("ITSSPDgFOIL-%s",suf));
1995 : // TGeoVolume *container = mgr->MakeBox(Form("ITSSPDgFOIL-%s",suf),
1996 : // air, 0.5*fullThickness, 0.5*fullWidth, 0.5*fullLength);
1997 : // create the common correction rotation (which depends of what side
1998 : // we are building)
1999 80 : TGeoRotation *rotCorr = new TGeoRotation(*gGeoIdentity);
2000 60 : if (isRight) rotCorr->RotateY(90.0);
2001 20 : else rotCorr->RotateY(-90.0);
2002 : // compute the translations, which are in the length and
2003 : // thickness directions
2004 : Double_t x, y, z, shift = 0.0;
2005 60 : if (isRight) shift = dist;
2006 : // glue (bottom)
2007 40 : x = -0.5*(fullThickness - g0Thickness);
2008 40 : z = 0.5*(fullLength - kpLength) - shift;
2009 80 : TGeoCombiTrans *glTrans0 = new TGeoCombiTrans(x, 0.0, z, rotCorr);
2010 : // kapton
2011 40 : x += 0.5*(g0Thickness + kpThickness);
2012 80 : TGeoCombiTrans *kpTrans = new TGeoCombiTrans(x, 0.0, z, rotCorr);
2013 : // aluminum
2014 40 : x += 0.5*(kpThickness + alThickness);
2015 40 : z = 0.5*(fullLength - alLength) - shift - 0.5*(kpLength - alLength);
2016 80 : TGeoCombiTrans *alTrans = new TGeoCombiTrans(x, 0.0, z, rotCorr);
2017 : // glue (top)
2018 40 : x += 0.5*(alThickness + g1Thickness);
2019 40 : z = 0.5*(fullLength - kpLength) - shift;
2020 80 : TGeoCombiTrans *glTrans1 = new TGeoCombiTrans(x, 0.0, z, rotCorr);
2021 :
2022 : //cout << fgkGapHalfStave << endl;
2023 : //cout << g0Thickness << endl;
2024 : //cout << kpThickness << endl;
2025 : //cout << alThickness << endl;
2026 : //cout << g1Thickness << endl;
2027 :
2028 : // add to container
2029 40 : container->SetLineColor(kMagenta-10);
2030 40 : container->AddNode(kpVol, 1, kpTrans);
2031 40 : container->AddNode(alVol, 1, alTrans);
2032 40 : container->AddNode(g0Vol, 1, glTrans0);
2033 40 : container->AddNode(g1Vol, 2, glTrans1);
2034 : // to add the grease we remember the sizes of the holes, stored as
2035 : // additional parameters in the kapton layer size:
2036 : // - sizes[3] = hole length
2037 : // - sizes[4] = hole width
2038 : // - sizes[5] = position of first hole center
2039 : // - sizes[6] = standard separation between holes
2040 : // - sizes[7] = separation between 5th and 6th hole
2041 : // - sizes[8] = separation between 10th and 11th hole
2042 : // - sizes[9] = separation between the upper hole border and
2043 : // the foil border
2044 80 : Double_t holeLength = kpSize[0];
2045 80 : Double_t holeWidth = kpSize[1];
2046 80 : Double_t holeFirstZ = kpSize[2];
2047 80 : Double_t holeSepZ = kpSize[3];
2048 80 : Double_t holeSep5th6th = kpSize[4];
2049 80 : Double_t holeSep10th11th = kpSize[5];
2050 80 : Double_t holeSepY = kpSize[6];
2051 : // volume (common)
2052 : // Grease has not been defined to date. Need much more information
2053 : // no this material!
2054 40 : TGeoMedium *grease = GetMedium("SPD KAPTON(POLYCH2)$", mgr); // ??? GREASE
2055 40 : TGeoVolume *hVol = mgr->MakeBox("ITSSPDGrease", grease,
2056 40 : 0.5*fullThickness, 0.5*holeWidth, 0.5*holeLength);
2057 40 : hVol->SetLineColor(kBlue);
2058 : // displacement of volumes in the container
2059 : Int_t idx = 1; // copy numbers start from 1.
2060 : x = 0.0;
2061 40 : y = 0.5*(fullWidth - holeWidth) - holeSepY;
2062 60 : if (isRight) z = holeFirstZ - 0.5*fullLength + dist;
2063 20 : else z = 0.5*fullLength - holeFirstZ - dist;
2064 960 : for (Int_t i = 0; i < 11; i++) {
2065 : TGeoTranslation *t = 0;
2066 880 : t = new TGeoTranslation(x, y, -z);
2067 440 : container->AddNode(hVol, idx++, t);
2068 600 : if (i < 4) shift = holeSepZ;
2069 320 : else if (i == 4) shift = holeSep5th6th;
2070 400 : else if (i < 9) shift = holeSepZ;
2071 : else shift = holeSep10th11th;
2072 660 : if (isRight) z += shift;
2073 220 : else z -= shift;
2074 : } // end for i
2075 :
2076 40 : container->GetShape()->ComputeBBox(); //RS: enforce recompting of BBox
2077 :
2078 : return container;
2079 40 : }
2080 : //___________________________________________________________________
2081 : TGeoVolumeAssembly* AliITSv11GeometrySPD::CreateMCM(Bool_t isRight,
2082 : TArrayD &sizes, TGeoManager *mgr) const
2083 : {
2084 : //
2085 : // Create a TGeoAssembly containing all the components of the MCM.
2086 : // The TGeoVolume container is rejected due to the possibility of overlaps
2087 : // when placing this object on the carbon fiber sector.
2088 : // The assembly contains:
2089 : // - the thin part of the MCM (integrated circuit)
2090 : // - the MCM chips (specifications from EDMS)
2091 : // - the cap which covers the zone where chips are bound to MCM
2092 : // ---
2093 : // The local reference frame of this assembly is defined in such a way
2094 : // that all volumes are contained in a virtual box whose center
2095 : // is placed exactly in the middle of the occupied space w.r to all
2096 : // directions. This will ease the positioning of this object in the
2097 : // half-stave. The sizes of this virtual box are stored in
2098 : // the array passed by reference.
2099 : // ---
2100 : // Arguments:
2101 : // - a boolean flag to know if this is the "left" or "right" MCM, when
2102 : // looking at the stave from above (i.e. the direction from which
2103 : // one sees bus over ladders over grounding foil) and keeping the
2104 : // continuous border in the upper part, one sees the thicker part
2105 : // on the left or right.
2106 : // - an array passed by reference which will contain the size of
2107 : // the virtual container.
2108 : // - a pointer to the used TGeoManager.
2109 : //
2110 :
2111 : // to distinguish the "left" and "right" objects, a suffix is created
2112 40 : char suf[5];
2113 80 : if (isRight) strncpy(suf, "R", 5); else strncpy(suf, "L", 5);
2114 :
2115 : // ** MEDIA **
2116 40 : TGeoMedium *medBase = GetMedium("SPD KAPTON(POLYCH2)$",mgr);// ??? MCM BASE
2117 40 : TGeoMedium *medChip = GetMedium("SPD SI CHIP$",mgr);
2118 40 : TGeoMedium *medCap = GetMedium("AL$",mgr);
2119 :
2120 : // The shape of the MCM is divided into 3 sectors with different
2121 : // widths (Y) and lengths (X), like in this sketch:
2122 : //
2123 : // 0 1 2
2124 : // +---------------------+-----------------------------------+
2125 : // | 4 sect 2 |
2126 : // | 6 sect 1 /-------------------+
2127 : // | sect 0 /--------------/ 3
2128 : // +--------------------/ 5
2129 : // 8 7
2130 : //
2131 : // the inclination of all oblique borders (6-7, 4-5) is always 45 degrees.
2132 : // From drawings we can parametrize the dimensions of all these sectors,
2133 : // then the shape of this part of the MCM is implemented as a
2134 : // TGeoXtru centerd in the virtual XY space.
2135 : // The first step is definig the relevant sizes of this shape:
2136 : Int_t i, j;
2137 40 : Double_t mcmThickness = fgkmm * 0.35;
2138 40 : Double_t sizeXtot = fgkmm * 105.6; // total distance (0-2)
2139 : // resp. 7-8, 5-6 and 3-4
2140 40 : Double_t sizeXsector[3] = {fgkmm * 28.4, fgkmm * 41.4, fgkmm * 28.8};
2141 : // resp. 0-8, 1-6 and 2-3
2142 40 : Double_t sizeYsector[3] = {fgkmm * 15.0, fgkmm * 11.0, fgkmm * 8.0};
2143 40 : Double_t sizeSep01 = fgkmm * 4.0; // x(6)-x(7)
2144 40 : Double_t sizeSep12 = fgkmm * 3.0; // x(4)-x(5)
2145 :
2146 : // define sizes of chips (last is the thickest)
2147 40 : Double_t chipLength[5] = { 4.00, 6.15, 3.85, 5.60, 18.00 };
2148 40 : Double_t chipWidth[5] = { 3.00, 4.10, 3.85, 5.60, 5.45 };
2149 40 : Double_t chipThickness[5] = { 0.60, 0.30, 0.30, 1.00, 1.20 };
2150 440 : TString name[5];
2151 40 : name[0] = "ITSSPDanalog";
2152 40 : name[1] = "ITSSPDpilot";
2153 40 : name[2] = "ITSSPDgol";
2154 40 : name[3] = "ITSSPDrx40";
2155 40 : name[4] = "ITSSPDoptical";
2156 40 : Color_t color[5] = { kCyan, kGreen, kYellow, kBlue, kOrange };
2157 :
2158 : // define the sizes of the cover
2159 40 : Double_t capThickness = fgkmm * 0.3;
2160 40 : Double_t capHeight = fgkmm * 1.7;
2161 :
2162 : // compute the total size of the virtual container box
2163 40 : sizes.Set(3);
2164 40 : Double_t &thickness = sizes[0];
2165 40 : Double_t &length = sizes[1];
2166 40 : Double_t &width = sizes[2];
2167 40 : length = sizeXtot;
2168 40 : width = sizeYsector[0];
2169 40 : thickness = mcmThickness + capHeight;
2170 :
2171 : // define all the relevant vertices of the polygon
2172 : // which defines the transverse shape of the MCM.
2173 : // These values are used to several purposes, and
2174 : // for each one, some points must be excluded
2175 40 : Double_t xRef[9], yRef[9];
2176 40 : xRef[0] = -0.5*sizeXtot;
2177 40 : yRef[0] = 0.5*sizeYsector[0];
2178 40 : xRef[1] = xRef[0] + sizeXsector[0] + sizeSep01;
2179 40 : yRef[1] = yRef[0];
2180 40 : xRef[2] = -xRef[0];
2181 40 : yRef[2] = yRef[0];
2182 40 : xRef[3] = xRef[2];
2183 40 : yRef[3] = yRef[2] - sizeYsector[2];
2184 40 : xRef[4] = xRef[3] - sizeXsector[2];
2185 40 : yRef[4] = yRef[3];
2186 40 : xRef[5] = xRef[4] - sizeSep12;
2187 40 : yRef[5] = yRef[4] - sizeSep12;
2188 40 : xRef[6] = xRef[5] - sizeXsector[1];
2189 40 : yRef[6] = yRef[5];
2190 40 : xRef[7] = xRef[6] - sizeSep01;
2191 40 : yRef[7] = yRef[6] - sizeSep01;
2192 40 : xRef[8] = xRef[0];
2193 40 : yRef[8] = -yRef[0];
2194 :
2195 : // the above points are defined for the "right" MCM (if ve view the
2196 : // stave from above) in order to change to the "left" one, we must
2197 : // change the sign to all X values:
2198 440 : if (isRight) for (i = 0; i < 9; i++) xRef[i] = -xRef[i];
2199 :
2200 : // the shape of the MCM and glue layer are done excluding point 1,
2201 : // which is not necessary and cause the geometry builder to get confused
2202 : j = 0;
2203 40 : Double_t xBase[8], yBase[8];
2204 800 : for (i = 0; i < 9; i++) {
2205 360 : if (i == 1) continue;
2206 320 : xBase[j] = xRef[i];
2207 320 : yBase[j] = yRef[i];
2208 320 : j++;
2209 320 : } // end for i
2210 :
2211 : // the MCM cover is superimposed over the zones 1 and 2 only
2212 40 : Double_t xCap[6], yCap[6];
2213 : j = 0;
2214 560 : for (i = 1; i <= 6; i++) {
2215 240 : xCap[j] = xRef[i];
2216 240 : yCap[j] = yRef[i];
2217 240 : j++;
2218 : } // end for i
2219 :
2220 : // define positions of chips,
2221 : // which must be added to the bottom-left corner of MCM
2222 : // and divided by 1E4;
2223 40 : Double_t chipX[5], chipY[5];
2224 40 : if (isRight) {
2225 60 : chipX[0] = 666320.;
2226 20 : chipX[1] = 508320.;
2227 20 : chipX[2] = 381320.;
2228 20 : chipX[3] = 295320.;
2229 20 : chipX[4] = 150320.;
2230 20 : chipY[0] = 23750.;
2231 20 : chipY[1] = 27750.;
2232 20 : chipY[2] = 20750.;
2233 20 : chipY[3] = 42750.;
2234 20 : chipY[4] = 39750.;
2235 20 : } else {
2236 20 : chipX[0] = 389730.;
2237 20 : chipX[1] = 548630.;
2238 20 : chipX[2] = 674930.;
2239 20 : chipX[3] = 761430.;
2240 20 : chipX[4] = 905430.;
2241 20 : chipY[0] = 96250.;
2242 20 : chipY[1] = 91950.;
2243 20 : chipY[2] = 99250.;
2244 20 : chipY[3] = 107250.;
2245 20 : chipY[4] = 109750.;
2246 : } // end if isRight
2247 480 : for (i = 0; i < 5; i++) {
2248 200 : chipX[i] *= 0.00001;
2249 200 : chipY[i] *= 0.00001;
2250 200 : if (isRight) {
2251 100 : chipX[i] += xRef[3];
2252 100 : chipY[i] += yRef[3];
2253 100 : } else {
2254 100 : chipX[i] += xRef[8];
2255 100 : chipY[i] += yRef[8];
2256 : } // end for isRight
2257 200 : chipLength[i] *= fgkmm;
2258 200 : chipWidth[i] *= fgkmm;
2259 200 : chipThickness[i] *= fgkmm;
2260 : } // end for i
2261 :
2262 : // create shapes for MCM
2263 : Double_t z1, z2;
2264 80 : TGeoXtru *shBase = new TGeoXtru(2);
2265 40 : z1 = -0.5*thickness;
2266 40 : z2 = z1 + mcmThickness;
2267 40 : shBase->DefinePolygon(8, xBase, yBase);
2268 40 : shBase->DefineSection(0, z1, 0., 0., 1.0);
2269 40 : shBase->DefineSection(1, z2, 0., 0., 1.0);
2270 :
2271 : // create volumes of MCM
2272 80 : TGeoVolume *volBase = new TGeoVolume("ITSSPDbase", shBase, medBase);
2273 40 : volBase->SetLineColor(kRed);
2274 :
2275 : // to create the border of the MCM cover, it is required the
2276 : // subtraction of two shapes the outer is created using the
2277 : // reference points defined here
2278 80 : TGeoXtru *shCapOut = new TGeoXtru(2);
2279 80 : shCapOut->SetName(Form("ITSSPDshCAPOUT%s", suf));
2280 : z1 = z2;
2281 40 : z2 = z1 + capHeight - capThickness;
2282 40 : shCapOut->DefinePolygon(6, xCap, yCap);
2283 40 : shCapOut->DefineSection(0, z1, 0., 0., 1.0);
2284 40 : shCapOut->DefineSection(1, z2, 0., 0., 1.0);
2285 : // the inner is built similarly but subtracting the thickness
2286 : Double_t angle, cs;
2287 40 : Double_t xin[6], yin[6];
2288 40 : if (!isRight) {
2289 : angle = 45.0;
2290 40 : cs = TMath::Cos( 0.5*(TMath::Pi() - angle*TMath::DegToRad()) );
2291 20 : xin[0] = xCap[0] + capThickness;
2292 20 : yin[0] = yCap[0] - capThickness;
2293 20 : xin[1] = xCap[1] - capThickness;
2294 20 : yin[1] = yin[0];
2295 20 : xin[2] = xin[1];
2296 20 : yin[2] = yCap[2] + capThickness;
2297 20 : xin[3] = xCap[3] - capThickness*cs;
2298 20 : yin[3] = yin[2];
2299 20 : xin[4] = xin[3] - sizeSep12;
2300 20 : yin[4] = yCap[4] + capThickness;
2301 20 : xin[5] = xin[0];
2302 20 : yin[5] = yin[4];
2303 20 : } else {
2304 : angle = 45.0;
2305 80 : cs = TMath::Cos( 0.5*(TMath::Pi() - angle*TMath::DegToRad()) );
2306 20 : xin[0] = xCap[0] - capThickness;
2307 20 : yin[0] = yCap[0] - capThickness;
2308 20 : xin[1] = xCap[1] + capThickness;
2309 20 : yin[1] = yin[0];
2310 20 : xin[2] = xin[1];
2311 20 : yin[2] = yCap[2] + capThickness;
2312 20 : xin[3] = xCap[3] - capThickness*cs;
2313 20 : yin[3] = yin[2];
2314 20 : xin[4] = xin[3] + sizeSep12;
2315 20 : yin[4] = yCap[4] + capThickness;
2316 20 : xin[5] = xin[0];
2317 20 : yin[5] = yin[4];
2318 : } // end if !isRight
2319 80 : TGeoXtru *shCapIn = new TGeoXtru(2);
2320 80 : shCapIn->SetName(Form("ITSSPDshCAPIN%s", suf));
2321 40 : shCapIn->DefinePolygon(6, xin, yin);
2322 40 : shCapIn->DefineSection(0, z1 - 0.01, 0., 0., 1.0);
2323 40 : shCapIn->DefineSection(1, z2 + 0.01, 0., 0., 1.0);
2324 : // compose shapes
2325 120 : TGeoCompositeShape *shCapBorder = new TGeoCompositeShape(
2326 40 : Form("ITSSPDshBORDER%s", suf),
2327 80 : Form("%s-%s", shCapOut->GetName(),
2328 40 : shCapIn->GetName()));
2329 : // create volume
2330 120 : TGeoVolume *volCapBorder = new TGeoVolume("ITSSPDcapBoarder",
2331 40 : shCapBorder,medCap);
2332 40 : volCapBorder->SetLineColor(kGreen);
2333 : // finally, we create the top of the cover, which has the same
2334 : // shape of outer border and a thickness equal of the one othe
2335 : // cover border one
2336 80 : TGeoXtru *shCapTop = new TGeoXtru(2);
2337 : z1 = z2;
2338 40 : z2 = z1 + capThickness;
2339 40 : shCapTop->DefinePolygon(6, xCap, yCap);
2340 40 : shCapTop->DefineSection(0, z1, 0., 0., 1.0);
2341 40 : shCapTop->DefineSection(1, z2, 0., 0., 1.0);
2342 80 : TGeoVolume *volCapTop = new TGeoVolume("ITSSPDcapTop", shCapTop, medCap);
2343 40 : volCapTop->SetLineColor(kBlue);
2344 :
2345 : // create container assembly with right suffix
2346 120 : TGeoVolumeAssembly *mcmAssembly = new TGeoVolumeAssembly(
2347 40 : Form("ITSSPDmcm%s", suf));
2348 :
2349 : // add mcm layer
2350 40 : mcmAssembly->AddNode(volBase, 1, gGeoIdentity);
2351 : // add chips
2352 480 : for (i = 0; i < 5; i++) {
2353 400 : TGeoVolume *box = gGeoManager->MakeBox(name[i],medChip,
2354 200 : 0.5*chipLength[i], 0.5*chipWidth[i], 0.5*chipThickness[i]);
2355 600 : TGeoTranslation *tr = new TGeoTranslation(chipX[i],chipY[i],
2356 200 : 0.5*(-thickness + chipThickness[i]) + mcmThickness);
2357 200 : box->SetLineColor(color[i]);
2358 200 : mcmAssembly->AddNode(box, 1, tr);
2359 : } // end for i
2360 : // add cap border
2361 40 : mcmAssembly->AddNode(volCapBorder, 1, gGeoIdentity);
2362 : // add cap top
2363 40 : mcmAssembly->AddNode(volCapTop, 1, gGeoIdentity);
2364 :
2365 40 : mcmAssembly->GetShape()->ComputeBBox(); //RS: enforce recompting of BBox
2366 :
2367 : return mcmAssembly;
2368 280 : }
2369 :
2370 : //______________________________________________________________________
2371 : TGeoVolumeAssembly* AliITSv11GeometrySPD::CreatePixelBus
2372 : (Bool_t isRight, Int_t ilayer, TArrayD &sizes, TGeoManager *mgr) const
2373 : {
2374 : //
2375 : // The pixel bus is implemented as a TGeoBBox with some objects on it,
2376 : // which could affect the particle energy loss.
2377 : // ---
2378 : // In order to avoid confusion, the bus is directly displaced
2379 : // according to the axis orientations which are used in the final stave:
2380 : // X --> thickness direction
2381 : // Y --> width direction
2382 : // Z --> length direction
2383 : //
2384 :
2385 : // ** CRITICAL CHECK ******************************************************
2386 : // layer number can be ONLY 1 or 2
2387 40 : if (ilayer != 1 && ilayer != 2) AliFatal("Layer number MUST be 1 or 2");
2388 :
2389 : // ** MEDIA **
2390 : //PIXEL BUS
2391 40 : TGeoMedium *medBus = GetMedium("SPDBUS(AL+KPT+EPOX)$",mgr);
2392 40 : TGeoMedium *medPt1000 = GetMedium("CERAMICS$",mgr); // ??? PT1000
2393 : // Capacity
2394 40 : TGeoMedium *medCap = GetMedium("SDD X7R capacitors$",mgr);
2395 : // ??? Resistance
2396 : //TGeoMedium *medRes = GetMedium("SDD X7R capacitors$",mgr);
2397 40 : TGeoMedium *medRes = GetMedium("ALUMINUM$",mgr);
2398 : //TGeoMedium *medExt = GetMedium("SDDKAPTON (POLYCH2)$", mgr);
2399 40 : TGeoMedium *medExt = GetMedium("SPD-MIX CU KAPTON$", mgr);
2400 : // ** SIZES & POSITIONS **
2401 40 : Double_t busLength = 170.501 * fgkmm; // length of plane part
2402 40 : Double_t busWidth = 13.800 * fgkmm; // width
2403 40 : Double_t busThickness = 0.280 * fgkmm; // thickness
2404 40 : Double_t pt1000Length = fgkmm * 1.50;
2405 40 : Double_t pt1000Width = fgkmm * 3.10;
2406 40 : Double_t pt1000Thickness = fgkmm * 0.60;
2407 40 : Double_t pt1000Y, pt1000Z[10];// position of the pt1000's along the bus
2408 40 : Double_t capLength = fgkmm * 2.55;
2409 40 : Double_t capWidth = fgkmm * 1.50;
2410 40 : Double_t capThickness = fgkmm * 1.35;
2411 40 : Double_t capY[2], capZ[2];
2412 :
2413 40 : Double_t resLength = fgkmm * 2.20;
2414 40 : Double_t resWidth = fgkmm * 0.80;
2415 40 : Double_t resThickness = fgkmm * 0.35;
2416 40 : Double_t resY[2], resZ[2];
2417 :
2418 40 : Double_t extThickness = fgkmm * 0.25;
2419 40 : Double_t ext1Length = fgkmm * (26.7 - 10.0);
2420 40 : Double_t ext2Length = fgkmm * 284.0 - ext1Length + extThickness;
2421 40 : Double_t ext2LengthL2 = fgkmm * 130.0;
2422 40 : Double_t ext4Length = fgkmm * 40.0;
2423 : Double_t ext4Twist = 66.54; //deg
2424 40 : Double_t extWidth = fgkmm * 11.0;
2425 40 : Double_t extHeight = fgkmm * 2.5;
2426 :
2427 : // position of pt1000, resistors and capacitors depends on the
2428 : // bus if it's left or right one
2429 40 : if (!isRight) {
2430 : pt1000Y = 64400.;
2431 20 : pt1000Z[0] = 66160.;
2432 20 : pt1000Z[1] = 206200.;
2433 20 : pt1000Z[2] = 346200.;
2434 20 : pt1000Z[3] = 486200.;
2435 20 : pt1000Z[4] = 626200.;
2436 20 : pt1000Z[5] = 776200.;
2437 20 : pt1000Z[6] = 916200.;
2438 20 : pt1000Z[7] = 1056200.;
2439 20 : pt1000Z[8] = 1196200.;
2440 20 : pt1000Z[9] = 1336200.;
2441 20 : resZ[0] = 1397500.;
2442 20 : resY[0] = 26900.;
2443 20 : resZ[1] = 682500.;
2444 20 : resY[1] = 27800.;
2445 20 : capZ[0] = 1395700.;
2446 20 : capY[0] = 45700.;
2447 20 : capZ[1] = 692600.;
2448 20 : capY[1] = 45400.;
2449 20 : } else {
2450 : pt1000Y = 66100.;
2451 20 : pt1000Z[0] = 319700.;
2452 20 : pt1000Z[1] = 459700.;
2453 20 : pt1000Z[2] = 599700.;
2454 20 : pt1000Z[3] = 739700.;
2455 20 : pt1000Z[4] = 879700.;
2456 20 : pt1000Z[5] = 1029700.;
2457 20 : pt1000Z[6] = 1169700.;
2458 20 : pt1000Z[7] = 1309700.;
2459 20 : pt1000Z[8] = 1449700.;
2460 20 : pt1000Z[9] = 1589700.;
2461 20 : capY[0] = 44500.;
2462 20 : capZ[0] = 266700.;
2463 20 : capY[1] = 44300.;
2464 20 : capZ[1] = 974700.;
2465 20 : resZ[0] = 266500.;
2466 20 : resY[0] = 29200.;
2467 20 : resZ[1] = 974600.;
2468 20 : resY[1] = 29900.;
2469 : } // end if isRight
2470 : Int_t i;
2471 40 : pt1000Y *= 1E-4 * fgkmm;
2472 880 : for (i = 0; i < 10; i++) {
2473 400 : pt1000Z[i] *= 1E-4 * fgkmm;
2474 400 : if (i < 2) {
2475 80 : capZ[i] *= 1E-4 * fgkmm;
2476 80 : capY[i] *= 1E-4 * fgkmm;
2477 80 : resZ[i] *= 1E-4 * fgkmm;
2478 80 : resY[i] *= 1E-4 * fgkmm;
2479 80 : } // end if iM2
2480 : } // end for i
2481 :
2482 40 : Double_t &fullLength = sizes[1];
2483 40 : Double_t &fullWidth = sizes[2];
2484 40 : Double_t &fullThickness = sizes[0];
2485 40 : fullLength = busLength;
2486 40 : fullWidth = busWidth;
2487 : // add the thickness of the thickest component on bus (capacity)
2488 40 : fullThickness = busThickness + capThickness;
2489 :
2490 : // ** VOLUMES **
2491 40 : TGeoVolumeAssembly *container = new TGeoVolumeAssembly("ITSSPDpixelBus");
2492 80 : TGeoVolume *bus = mgr->MakeBox("ITSSPDbus", medBus, 0.5*busThickness,
2493 40 : 0.5*busWidth, 0.5*busLength);
2494 40 : TGeoVolume *pt1000 = mgr->MakeBox("ITSSPDpt1000",medPt1000,
2495 40 : 0.5*pt1000Thickness,0.5*pt1000Width, 0.5*pt1000Length);
2496 80 : TGeoVolume *res = mgr->MakeBox("ITSSPDresistor", medRes, 0.5*resThickness,
2497 40 : 0.5*resWidth, 0.5*resLength);
2498 80 : TGeoVolume *cap = mgr->MakeBox("ITSSPDcapacitor", medCap, 0.5*capThickness,
2499 40 : 0.5*capWidth, 0.5*capLength);
2500 :
2501 40 : char extname[12];
2502 40 : snprintf(extname,12,"Extender1l%d",ilayer);
2503 40 : TGeoVolume *ext1 = mgr->MakeBox(extname, medExt, 0.5*extThickness, 0.5*extWidth, 0.5*ext1Length);
2504 40 : snprintf(extname,12,"Extender2l%d",ilayer);
2505 40 : TGeoVolume *ext2 = mgr->MakeBox(extname, medExt, 0.5*extHeight - 2.*extThickness, 0.5*extWidth, 0.5*extThickness);
2506 : TGeoVolume *ext3=0;
2507 40 : snprintf(extname,12,"Extender3l%d",ilayer);
2508 : TGeoVolume *ext4=0;
2509 40 : snprintf(extname,12,"Extender3l%d",ilayer);
2510 40 : if (ilayer==1) {
2511 20 : Double_t halflen=(0.5*ext2Length + extThickness);
2512 20 : Double_t xprof[6],yprof[6];
2513 : Double_t alpha=24;
2514 20 : xprof[0] = -halflen;
2515 20 : yprof[0] = -0.5*extThickness;
2516 20 : xprof[1] = halflen/2;
2517 20 : yprof[1] = yprof[0];
2518 20 : xprof[2] = xprof[1] + 0.5*halflen*CosD(alpha);
2519 20 : yprof[2] = yprof[1] + 0.5*halflen*SinD(alpha);
2520 20 : xprof[3] = xprof[2] - extThickness*SinD(alpha);
2521 20 : yprof[3] = yprof[2] + extThickness*CosD(alpha);
2522 40 : InsidePoint(xprof[0], yprof[0], xprof[1], yprof[1], xprof[2], yprof[2],
2523 20 : extThickness, xprof[4], yprof[4]);
2524 20 : xprof[5] = xprof[0];
2525 20 : yprof[5] = 0.5*extThickness;
2526 20 : TGeoXtru *ext3sh = new TGeoXtru(2);
2527 20 : ext3sh->DefinePolygon(6, xprof, yprof);
2528 20 : ext3sh->DefineSection(0, -0.5*(extWidth-0.8*fgkmm));
2529 20 : ext3sh->DefineSection(1, 0.5*(extWidth-0.8*fgkmm));
2530 20 : ext3 = new TGeoVolume(extname, ext3sh, medExt);
2531 20 : } else {
2532 20 : ext3 = mgr->MakeBox(extname, medExt, 0.5*extThickness, 0.5*(extWidth-0.8*fgkmm), 0.5*ext2LengthL2 + extThickness); // Hardcode fix of a small overlap
2533 20 : ext4= mgr->MakeGtra("Extender4l2", medExt, 0.5*ext4Length, 0, 0, ext4Twist, 0.5*(extWidth-0.8*fgkmm), 0.5*extThickness, 0.5*extThickness, 0, 0.5*(extWidth-0.8*fgkmm), 0.5*extThickness, 0.5*extThickness, 0);
2534 20 : ext4->SetLineColor(kGray);
2535 : }
2536 40 : bus->SetLineColor(kYellow + 2);
2537 40 : pt1000->SetLineColor(kGreen + 3);
2538 40 : res->SetLineColor(kRed + 1);
2539 40 : cap->SetLineColor(kBlue - 7);
2540 40 : ext1->SetLineColor(kGray);
2541 40 : ext2->SetLineColor(kGray);
2542 40 : ext3->SetLineColor(kGray);
2543 :
2544 : // ** MOVEMENTS AND POSITIONEMENT **
2545 : // bus
2546 80 : TGeoTranslation *trBus = new TGeoTranslation(0.5 * (busThickness -
2547 40 : fullThickness), 0.0, 0.0);
2548 40 : container->AddNode(bus, 1, trBus);
2549 : Double_t zRef, yRef, x, y, z;
2550 : if (isRight) {
2551 40 : zRef = -0.5*fullLength;
2552 40 : yRef = -0.5*fullWidth;
2553 : } else {
2554 : zRef = -0.5*fullLength;
2555 : yRef = -0.5*fullWidth;
2556 : } // end if isRight
2557 : // pt1000
2558 40 : x = 0.5*(pt1000Thickness - fullThickness) + busThickness;
2559 880 : for (i = 0; i < 10; i++) {
2560 400 : y = yRef + pt1000Y;
2561 400 : z = zRef + pt1000Z[i];
2562 400 : TGeoTranslation *tr = new TGeoTranslation(x, y, z);
2563 400 : container->AddNode(pt1000, i+1, tr);
2564 : } // end for i
2565 : // capacitors
2566 40 : x = 0.5*(capThickness - fullThickness) + busThickness;
2567 240 : for (i = 0; i < 2; i++) {
2568 80 : y = yRef + capY[i];
2569 80 : z = zRef + capZ[i];
2570 80 : TGeoTranslation *tr = new TGeoTranslation(x, y, z);
2571 80 : container->AddNode(cap, i+1, tr);
2572 : } // end for i
2573 : // resistors
2574 40 : x = 0.5*(resThickness - fullThickness) + busThickness;
2575 240 : for (i = 0; i < 2; i++) {
2576 80 : y = yRef + resY[i];
2577 80 : z = zRef + resZ[i];
2578 80 : TGeoTranslation *tr = new TGeoTranslation(x, y, z);
2579 80 : container->AddNode(res, i+1, tr);
2580 : } // end for i
2581 :
2582 : // extender
2583 80 : if (ilayer == 2) {
2584 20 : if (isRight) {
2585 60 : y = 0.5 * (fullWidth - extWidth) - 0.1;
2586 30 : z = 0.5 * (-fullLength + fgkmm * 10.0);
2587 10 : }
2588 : else {
2589 : y = 0.5 * (fullWidth - extWidth) - 0.1;
2590 10 : z = 0.5 * ( fullLength - fgkmm * 10.0);
2591 : }
2592 : }
2593 : else {
2594 20 : if (isRight) {
2595 20 : y = -0.5 * (fullWidth - extWidth);
2596 30 : z = 0.5 * (-fullLength + fgkmm * 10.0);
2597 10 : }
2598 : else {
2599 : y = -0.5 * (fullWidth - extWidth);
2600 10 : z = 0.5 * ( fullLength - fgkmm * 10.0);
2601 : }
2602 : }
2603 40 : x = 0.5 * (extThickness - fullThickness) + busThickness;
2604 : //y = 0.5 * (fullWidth - extWidth);
2605 40 : TGeoTranslation *trExt1 = new TGeoTranslation(x, y, z);
2606 40 : if (isRight) {
2607 60 : z -= 0.5 * (ext1Length - extThickness);
2608 20 : }
2609 : else {
2610 20 : z += 0.5 * (ext1Length - extThickness);
2611 : }
2612 40 : x += 0.5*(extHeight - 3.*extThickness);
2613 40 : TGeoTranslation *trExt2 = new TGeoTranslation(x, y, z);
2614 40 : if (isRight) {
2615 20 : if (ilayer==1)
2616 10 : z -= 0.5 * (ext2Length - extThickness) + 2.5*extThickness;
2617 : else
2618 10 : z -= 0.5 * (ext2LengthL2 - extThickness) + 2.5*extThickness;
2619 : }
2620 : else {
2621 20 : if (ilayer==1)
2622 10 : z += 0.5 * (ext2Length - extThickness) + 2.5*extThickness;
2623 : else
2624 10 : z += 0.5 * (ext2LengthL2 - extThickness) + 2.5*extThickness;
2625 : }
2626 40 : x += 0.5*(extHeight - extThickness) - 2.*extThickness;
2627 : TGeoCombiTrans *trExt3=0;
2628 40 : if (ilayer==1) {
2629 20 : if (isRight)
2630 60 : trExt3 = new TGeoCombiTrans(x, y, z, new TGeoRotation("",0.,-90.,90.));
2631 : else
2632 30 : trExt3 = new TGeoCombiTrans(x, y, z, new TGeoRotation("",0., 90.,90.));
2633 : } else
2634 20 : trExt3 = new TGeoCombiTrans(x, y, z, 0);
2635 40 : container->AddNode(ext1, 0, trExt1);
2636 40 : container->AddNode(ext2, 0, trExt2);
2637 40 : container->AddNode(ext3, 0, trExt3);
2638 40 : if (ilayer==2) {
2639 : TGeoCombiTrans *trExt4=0;
2640 20 : if (isRight) {
2641 30 : z -= ( ((TGeoBBox*)ext3->GetShape())->GetDZ() + ((TGeoGtra*)ext4->GetShape())->GetDZ() );
2642 30 : trExt4 = new TGeoCombiTrans(x, y, z, new TGeoRotation("", ext4Twist/2,0,0));
2643 10 : } else {
2644 10 : z += ( ((TGeoBBox*)ext3->GetShape())->GetDZ() + ((TGeoGtra*)ext4->GetShape())->GetDZ() );
2645 30 : trExt4 = new TGeoCombiTrans(x, y, z, new TGeoRotation("",-ext4Twist/2,0,0));
2646 : }
2647 20 : container->AddNode(ext4, 0, trExt4);
2648 20 : }
2649 40 : sizes[3] = yRef + pt1000Y;
2650 40 : sizes[4] = zRef + pt1000Z[2];
2651 40 : sizes[5] = zRef + pt1000Z[7];
2652 :
2653 40 : container->GetShape()->ComputeBBox(); //RS: enforce recompting of BBox
2654 :
2655 40 : return container;
2656 40 : }
2657 :
2658 : //______________________________________________________________________
2659 : TList* AliITSv11GeometrySPD::CreateConeModule(Bool_t sideC, const Double_t angrot,
2660 : TGeoManager *mgr) const
2661 : {
2662 : //
2663 : // Creates all services modules and places them in a TList
2664 : // angrot is the rotation angle (passed as an argument to avoid
2665 : // defining the same quantity in two different places)
2666 : //
2667 : // Created: ?? ??? 2008 A. Pulvirenti
2668 : // Updated: 03 May 2010 M. Sitta
2669 : // Updated: 20 Jun 2010 A. Pulvirenti Optical patch panels
2670 : // Updated: 22 Jun 2010 M. Sitta Fiber cables
2671 : // Updated: 04 Jul 2010 M. Sitta Water cooling
2672 : // Updated: 08 Jul 2010 A. Pulvirenti Air cooling on Side C
2673 : //
2674 :
2675 2 : TGeoMedium *medInox = GetMedium("INOX$",mgr);
2676 : //TGeoMedium *medExt = GetMedium("SDDKAPTON (POLYCH2)$", mgr);
2677 2 : TGeoMedium *medExtB = GetMedium("SPD-BUS CU KAPTON$", mgr);
2678 2 : TGeoMedium *medExtM = GetMedium("SPD-MCM CU KAPTON$", mgr);
2679 2 : TGeoMedium *medPlate = GetMedium("SPD C (M55J)$", mgr);
2680 2 : TGeoMedium *medFreon = GetMedium("Freon$", mgr);
2681 2 : TGeoMedium *medGas = GetMedium("GASEOUS FREON$", mgr);
2682 2 : TGeoMedium *medFibs = GetMedium("SDD OPTICFIB$",mgr);
2683 2 : TGeoMedium *medCopper= GetMedium("COPPER$",mgr);
2684 2 : TGeoMedium *medPVC = GetMedium("PVC$",mgr);
2685 :
2686 2 : Double_t extThickness = fgkmm * 0.25;
2687 2 : Double_t ext1Length = fgkmm * (26.7 - 10.0);
2688 : // Double_t ext2Length = fgkmm * (285.0 - ext1Length + extThickness);
2689 2 : Double_t ext2Length = fgkmm * 285.0 - ext1Length + extThickness;
2690 :
2691 2 : const Double_t kCableThickness = 1.5 *fgkmm;
2692 2 : Double_t cableL0 = 10.0 * fgkmm;
2693 2 : Double_t cableL1 = 340.0 * fgkmm - extThickness - ext1Length - ext2Length;
2694 2 : Double_t cableL2 = 300.0 * fgkmm;
2695 : //Double_t cableL3 = 570.0 * fgkmm;
2696 2 : Double_t cableL3 = 57.0 * fgkmm;
2697 2 : Double_t cableW1 = 11.0 * fgkmm;
2698 2 : Double_t cableW2 = 30.0 * fgkmm;
2699 2 : Double_t cableW3 = 50.0 * fgkmm;
2700 :
2701 2 : const Double_t kMCMLength = cableL0 + cableL1 + cableL2 + cableL3;
2702 : const Double_t kMCMWidth = cableW1;
2703 2 : const Double_t kMCMThickness = 1.2 *fgkmm;
2704 :
2705 2 : const Double_t kPlateLength = 200.0 *fgkmm;
2706 : const Double_t kPlateWidth = 50.0 *fgkmm;
2707 2 : const Double_t kPlateThickness = 5.0 *fgkmm;
2708 :
2709 2 : const Double_t kConeTubeRmin = 2.0 *fgkmm;
2710 2 : const Double_t kConeTubeRmax = 3.0 *fgkmm;
2711 :
2712 2 : const Double_t kHorizTubeLen = 150.0 *fgkmm;
2713 2 : const Double_t kYtoHalfStave = 9.5 *fgkmm;
2714 :
2715 2 : const Double_t kWaterCoolRMax = 2.6 *fgkmm;
2716 2 : const Double_t kWaterCoolThick = 0.04 *fgkmm;
2717 2 : const Double_t kWaterCoolLen = 250.0 *fgkmm;
2718 2 : const Double_t kWCPlateThick = 0.5 *fgkmm;
2719 2 : const Double_t kWCPlateWide = 33.0 *fgkmm;
2720 2 : const Double_t kWCPlateLen = 230.0 *fgkmm;
2721 2 : const Double_t kWCFittingRext1 = 2.4 *fgkmm;
2722 2 : const Double_t kWCFittingRext2 = 3.7 *fgkmm;
2723 2 : const Double_t kWCFittingRint1 = 1.9 *fgkmm;
2724 : const Double_t kWCFittingRint2 = kWaterCoolRMax;
2725 2 : const Double_t kWCFittingLen1 = 7.0 *fgkmm;
2726 2 : const Double_t kWCFittingLen2 = 8.0 *fgkmm;
2727 :
2728 2 : const Double_t kCollWidth = 40.0 *fgkmm;
2729 2 : const Double_t kCollLength = 60.0 *fgkmm;
2730 : const Double_t kCollThickness = 10.0 *fgkmm;
2731 : const Double_t kCollTubeThick = 1.0 *fgkmm;
2732 : const Double_t kCollTubeRadius = 7.0 *fgkmm;
2733 2 : const Double_t kCollTubeLength = 205.0 *fgkmm;
2734 :
2735 2 : const Double_t kOptFibDiamet = 4.5 *fgkmm;
2736 :
2737 2 : Double_t x[12], y[12];
2738 : Double_t xloc, yloc, zloc;
2739 :
2740 : Int_t kPurple = 6; // Purple (Root does not define it)
2741 :
2742 : TGeoVolumeAssembly* container[5];
2743 4 : if (sideC)
2744 4 : container[0] = new TGeoVolumeAssembly("ITSSPDConeModuleC");
2745 : else
2746 1 : container[0] = new TGeoVolumeAssembly("ITSSPDConeModuleA");
2747 2 : container[1] = new TGeoVolumeAssembly("ITSSPDCoolingModuleSideA");
2748 2 : container[2] = new TGeoVolumeAssembly("ITSSPDCoolingModuleSideC");
2749 2 : container[3] = new TGeoVolumeAssembly("ITSSPDPatchPanelModule");
2750 2 : container[4] = new TGeoVolumeAssembly("ITSSPDWaterCooling");
2751 :
2752 : // The extender on the cone as a Xtru
2753 2 : x[0] = -cableL0;
2754 2 : y[0] = 0.0 + 0.5 * cableW1;
2755 :
2756 2 : x[1] = x[0] + cableL0 + cableL1 - 0.5*(cableW2 - cableW1);
2757 2 : y[1] = y[0];
2758 :
2759 2 : x[2] = x[0] + cableL0 + cableL1;
2760 2 : y[2] = y[1] + 0.5*(cableW2 - cableW1);
2761 :
2762 2 : x[3] = x[2] + cableL2;
2763 2 : y[3] = y[2];
2764 :
2765 2 : x[4] = x[3] + 0.5*(cableW3 - cableW2);
2766 2 : y[4] = y[3] + 0.5*(cableW3 - cableW2);
2767 :
2768 2 : x[5] = x[4] + cableL3 - 0.5*(cableW3 - cableW2);
2769 2 : y[5] = y[4];
2770 :
2771 28 : for (Int_t i = 6; i < 12; i++) {
2772 12 : x[i] = x[11 - i];
2773 12 : y[i] = -y[11 - i];
2774 : }
2775 :
2776 2 : TGeoXtru *shCable = new TGeoXtru(2);
2777 2 : shCable->DefinePolygon(12, x, y);
2778 2 : shCable->DefineSection(0, 0.0);
2779 2 : shCable->DefineSection(1, kCableThickness);
2780 :
2781 2 : TGeoVolume *volCable = new TGeoVolume("ITSSPDExtender", shCable, medExtB);
2782 2 : volCable->SetLineColor(kGreen);
2783 :
2784 : // The MCM extender on the cone as a Xtru
2785 4 : TGeoBBox *shMCMExt = new TGeoBBox(0.5*kMCMLength,
2786 : 0.5*kMCMWidth,
2787 2 : 0.5*kMCMThickness);
2788 :
2789 4 : TGeoVolume *volMCMExt = new TGeoVolume("ITSSPDExtenderMCM",
2790 2 : shMCMExt, medExtM);
2791 2 : volMCMExt->SetLineColor(kGreen+3);
2792 :
2793 : // The support plate on the cone as a composite shape
2794 2 : Double_t thickness = kCableThickness + kMCMThickness;
2795 4 : TGeoBBox *shOut = new TGeoBBox("ITSSPD_shape_plateout",
2796 2 : 0.5*kPlateLength,
2797 2 : 0.5*kPlateWidth,
2798 2 : 0.5*kPlateThickness);
2799 4 : TGeoBBox *shIn = new TGeoBBox("ITSSPD_shape_platein" ,
2800 : 0.5*kPlateLength,
2801 2 : 0.5*cableW2,
2802 2 : 0.5*thickness);
2803 2 : Char_t string[255];
2804 2 : snprintf(string, 255, "%s-%s", shOut->GetName(), shIn->GetName());
2805 2 : TGeoCompositeShape *shPlate = new TGeoCompositeShape("ITSSPDPlate_shape",
2806 : string);
2807 :
2808 4 : TGeoVolume *volPlate = new TGeoVolume("ITSSPDPlate",
2809 2 : shPlate, medPlate);
2810 2 : volPlate->SetLineColor(kRed);
2811 :
2812 : // The air cooling tubes
2813 2 : TGeoBBox *shCollBox = new TGeoBBox("ITSSPD_shape_collector_box", 0.5*kCollLength, 0.5*kCollWidth, 0.5*kCollThickness);
2814 2 : TGeoTube *shCollTube = new TGeoTube("ITSSPD_shape_collector_tube",kCollTubeRadius - kCollTubeThick, kCollTubeRadius, 0.5*kCollTubeLength);
2815 2 : TGeoVolume *volCollBox = new TGeoVolume("ITSSPDCollectorBox", shCollBox, medPVC);
2816 2 : TGeoVolume *volCollTube = new TGeoVolume("ITSSPDCollectorTube", shCollTube, medPVC);
2817 2 : volCollBox->SetLineColor(kAzure);
2818 2 : volCollTube->SetLineColor(kAzure);
2819 :
2820 : // The cooling tube on the cone as a Ctub
2821 2 : Double_t tubeLength = shCable->GetX(5) - shCable->GetX(0) + kYtoHalfStave -0.85;
2822 4 : TGeoCtub *shTube = new TGeoCtub(0, kConeTubeRmax, 0.5*tubeLength, 0, 360,
2823 6 : 0, SinD(angrot/2), -CosD(angrot/2),
2824 : 0, 0, 1);
2825 :
2826 4 : TGeoVolume *volTubeA = new TGeoVolume("ITSSPDCoolingTubeOnConeA",
2827 2 : shTube, medInox);
2828 2 : volTubeA->SetLineColor(kGray);
2829 :
2830 2 : TGeoVolume *volTubeC = new TGeoVolume("ITSSPDCoolingTubeOnConeC",
2831 : shTube, medInox);
2832 2 : volTubeC->SetLineColor(kGray);
2833 :
2834 : // The freon in the cooling tubes on the cone as a Ctub
2835 4 : TGeoCtub *shFreon = new TGeoCtub(0, kConeTubeRmin, 0.5*tubeLength, 0, 360,
2836 6 : 0, SinD(angrot/2), -CosD(angrot/2),
2837 : 0, 0, 1);
2838 :
2839 4 : TGeoVolume *volFreon = new TGeoVolume("ITSSPDCoolingFreonOnCone",
2840 2 : shFreon, medFreon);
2841 2 : volFreon->SetLineColor(kPurple);
2842 :
2843 2 : TGeoVolume *volGasFr = new TGeoVolume("ITSSPDCoolingFreonGasOnCone",
2844 : shFreon, medGas);
2845 2 : volGasFr->SetLineColor(kPurple);
2846 :
2847 : // The cooling tube inside the cylinder as a Ctub
2848 4 : TGeoCtub *shCylTub = new TGeoCtub(0, kConeTubeRmax,
2849 2 : 0.5*kHorizTubeLen, 0, 360,
2850 : 0, 0, -1,
2851 4 : 0, SinD(angrot/2), CosD(angrot/2));
2852 :
2853 4 : TGeoVolume *volCylTubA = new TGeoVolume("ITSSPDCoolingTubeOnCylA",
2854 2 : shCylTub, medInox);
2855 2 : volCylTubA->SetLineColor(kGray);
2856 :
2857 2 : TGeoVolume *volCylTubC = new TGeoVolume("ITSSPDCoolingTubeOnCylC",
2858 : shCylTub, medInox);
2859 2 : volCylTubC->SetLineColor(kGray);
2860 :
2861 : // The freon in the cooling tubes in the cylinder as a Ctub
2862 4 : TGeoCtub *shCylFr = new TGeoCtub(0, kConeTubeRmin,
2863 : 0.5*kHorizTubeLen, 0, 360,
2864 : 0, 0, -1,
2865 4 : 0, SinD(angrot/2), CosD(angrot/2));
2866 :
2867 4 : TGeoVolume *volCylFr = new TGeoVolume("ITSSPDCoolingFreonOnCyl",
2868 2 : shCylFr, medFreon);
2869 2 : volCylFr->SetLineColor(kPurple);
2870 :
2871 2 : TGeoVolume *volCylGasFr = new TGeoVolume("ITSSPDCoolingFreonGasOnCyl",
2872 : shCylFr, medGas);
2873 2 : volCylGasFr->SetLineColor(kPurple);
2874 :
2875 : // The optical fibers bundle on the cone as a Tube
2876 2 : Double_t optLength = shCable->GetX(5) - shCable->GetX(0) + kYtoHalfStave -0.85;
2877 2 : TGeoTube *shOptFibs = new TGeoTube(0., 0.5*kOptFibDiamet, 0.5*optLength);
2878 :
2879 4 : TGeoVolume *volOptFibs = new TGeoVolume("ITSSPDOpticalFibersOnCone",
2880 2 : shOptFibs, medFibs);
2881 2 : volOptFibs->SetLineColor(kOrange);
2882 :
2883 : // The optical patch panels
2884 2 : TArrayD psizes;
2885 2 : TGeoVolume *volPatch = CreatePatchPanel(psizes, mgr);
2886 :
2887 : // The water cooling tube as a Tube
2888 6 : TGeoTube *shWatCool = new TGeoTube(kWaterCoolRMax-kWaterCoolThick,
2889 2 : kWaterCoolRMax, kWaterCoolLen/2);
2890 :
2891 6 : TGeoVolume *volWatCool = new TGeoVolume("ITSSPDWaterCoolingOnCone",
2892 2 : shWatCool, medInox);
2893 2 : volWatCool->SetLineColor(kGray);
2894 :
2895 : // The support plate for the water tubes: a Tubs and a BBox
2896 6 : TGeoTubeSeg *shWCPltT = new TGeoTubeSeg(kWaterCoolRMax,
2897 2 : kWaterCoolRMax+kWCPlateThick,
2898 2 : kWCPlateLen/2, 180., 360.);
2899 :
2900 2 : Double_t plateBoxWide = (kWCPlateWide - 2*kWaterCoolRMax)/2;
2901 6 : TGeoBBox *shWCPltB = new TGeoBBox(plateBoxWide/2,
2902 2 : kWCPlateThick/2,
2903 : kWCPlateLen/2);
2904 :
2905 6 : TGeoVolume *volWCPltT = new TGeoVolume("ITSSPDWaterCoolingTubsPlate",
2906 2 : shWCPltT, medPlate);
2907 2 : volWCPltT->SetLineColor(kRed);
2908 :
2909 6 : TGeoVolume *volWCPltB = new TGeoVolume("ITSSPDWaterCoolingBoxPlate",
2910 2 : shWCPltB, medPlate);
2911 2 : volWCPltB->SetLineColor(kRed);
2912 :
2913 : // The fitting for the water cooling tube: a Pcon
2914 4 : TGeoPcon *shFitt = new TGeoPcon(0., 360., 4);
2915 2 : shFitt->Z(0) = -kWCFittingLen1;
2916 2 : shFitt->Rmin(0) = kWCFittingRint1;
2917 2 : shFitt->Rmax(0) = kWCFittingRext1;
2918 :
2919 2 : shFitt->Z(1) = 0;
2920 2 : shFitt->Rmin(1) = kWCFittingRint1;
2921 2 : shFitt->Rmax(1) = kWCFittingRext1;
2922 :
2923 2 : shFitt->Z(2) = 0;
2924 2 : shFitt->Rmin(2) = kWCFittingRint2;
2925 2 : shFitt->Rmax(2) = kWCFittingRext2;
2926 :
2927 2 : shFitt->Z(3) = kWCFittingLen2;
2928 2 : shFitt->Rmin(3) = kWCFittingRint2;
2929 2 : shFitt->Rmax(3) = kWCFittingRext2;
2930 :
2931 6 : TGeoVolume *volFitt = new TGeoVolume("ITSSPDWaterCoolingFitting",
2932 2 : shFitt, medCopper);
2933 2 : volFitt->SetLineColor(kOrange);
2934 :
2935 : // Now place everything in the containers
2936 2 : volTubeA->AddNode(volGasFr, 1, 0);
2937 2 : volTubeC->AddNode(volFreon, 1, 0);
2938 :
2939 2 : volCylTubA->AddNode(volCylGasFr, 1, 0);
2940 2 : volCylTubC->AddNode(volCylFr , 1, 0);
2941 :
2942 2 : container[0]->AddNode(volCable, 1, 0);
2943 :
2944 4 : xloc = shMCMExt->GetDX() - cableL0;
2945 2 : zloc = shMCMExt->GetDZ();
2946 4 : container[0]->AddNode(volMCMExt, 1,
2947 6 : new TGeoTranslation( xloc, 0.,-zloc));
2948 :
2949 2 : xloc = shMCMExt->GetDX();
2950 6 : zloc = shCable->GetZ(1)/2 - shMCMExt->GetDZ();
2951 4 : container[0]->AddNode(volPlate, 1,
2952 6 : new TGeoTranslation( xloc, 0., zloc));
2953 :
2954 4 : TGeoRotation *rot2 = new TGeoRotation(*gGeoIdentity);
2955 2 : rot2->SetName("rotPatch");
2956 2 : rot2->RotateX(90.0);
2957 2 : rot2->RotateY(163.0);
2958 : //rot2->RotateZ(132.5);
2959 :
2960 : // add collectors only on side C
2961 2 : if (sideC)
2962 : {
2963 2 : TGeoTranslation *trCollBox = new TGeoTranslation(xloc - 0.5*kPlateLength + 0.5*kCollLength, 0.0, +0.5*(kPlateThickness+1.1*kCollThickness));
2964 2 : TGeoRotation *rotCollTube = new TGeoRotation(*gGeoIdentity);
2965 1 : rotCollTube->RotateY(90.0);
2966 2 : TGeoCombiTrans *trCollTube = new TGeoCombiTrans(xloc + 0.5*kCollTubeLength - (0.5*kPlateLength - kCollLength), 0.0, +0.5*(kPlateThickness+2.0*kCollTubeRadius+kCollTubeThick), rotCollTube);
2967 1 : container[0]->AddNode(volCollBox, 1, trCollBox);
2968 1 : container[0]->AddNode(volCollTube, 1, trCollTube);
2969 1 : }
2970 :
2971 : Double_t dxPatch = 2.75;
2972 : Double_t dzPatch = 2.8;
2973 4 : TGeoCombiTrans *tr2 = new TGeoCombiTrans(1.7*ext2Length - dxPatch, 0.0, dzPatch, rot2);
2974 2 : container[3]->AddNode(volPatch, 0, tr2);
2975 :
2976 2 : xloc = shTube->GetRmax();
2977 2 : yloc = shTube->GetRmax();
2978 6 : zloc = shTube->GetDz() - shTube->GetRmax() - kYtoHalfStave;
2979 4 : container[1]->AddNode(volTubeA, 1,
2980 6 : new TGeoTranslation(-xloc, -yloc, zloc));
2981 4 : container[2]->AddNode(volTubeC, 1,
2982 6 : new TGeoTranslation(-xloc, -yloc, zloc));
2983 :
2984 2 : xloc = shTube->GetRmax();
2985 8 : yloc = (shCylTub->GetDz())*SinD(angrot) - shTube->GetRmax();
2986 8 : zloc = (shCylTub->GetDz())*CosD(angrot) + shTube->GetRmax() +kYtoHalfStave;
2987 4 : container[1]->AddNode(volCylTubA, 1,
2988 8 : new TGeoCombiTrans(-xloc, yloc,-zloc,
2989 4 : new TGeoRotation("",0.,angrot,0.)));
2990 4 : container[2]->AddNode(volCylTubC, 1,
2991 8 : new TGeoCombiTrans(-xloc, yloc,-zloc,
2992 4 : new TGeoRotation("",0.,angrot,0.)));
2993 :
2994 6 : xloc = shOptFibs->GetRmax() + 2*shTube->GetRmax();
2995 4 : yloc = 1.6*shOptFibs->GetRmax();
2996 6 : zloc = shOptFibs->GetDZ() - shTube->GetRmax() - kYtoHalfStave;
2997 4 : container[1]->AddNode(volOptFibs, 1,
2998 6 : new TGeoTranslation(-xloc, -yloc, zloc));
2999 4 : container[2]->AddNode(volOptFibs, 1,
3000 6 : new TGeoTranslation(-xloc, -yloc, zloc));
3001 :
3002 2 : yloc = shWatCool->GetRmax();
3003 6 : zloc = (2*shTube->GetDz() - shTube->GetRmax() - kYtoHalfStave)/2;
3004 4 : container[4]->AddNode(volWatCool, 1,
3005 6 : new TGeoTranslation(0, -yloc, zloc));
3006 :
3007 4 : container[4]->AddNode(volWCPltT, 1,
3008 6 : new TGeoTranslation(0, -yloc, zloc));
3009 :
3010 4 : yloc -= shWCPltB->GetDY();
3011 6 : xloc = shWatCool->GetRmax() + shWCPltB->GetDX();
3012 4 : container[4]->AddNode(volWCPltB, 1,
3013 6 : new TGeoTranslation( xloc, -yloc, zloc));
3014 4 : container[4]->AddNode(volWCPltB, 2,
3015 6 : new TGeoTranslation(-xloc, -yloc, zloc));
3016 :
3017 2 : yloc = shWatCool->GetRmax();
3018 4 : zloc -= shWatCool->GetDz();
3019 4 : container[4]->AddNode(volFitt, 1,
3020 6 : new TGeoTranslation(0, -yloc, zloc));
3021 :
3022 2 : container[0]->GetShape()->ComputeBBox(); //RS: enforce recompting of BBox
3023 2 : container[1]->GetShape()->ComputeBBox();
3024 2 : container[2]->GetShape()->ComputeBBox();
3025 2 : container[3]->GetShape()->ComputeBBox();
3026 2 : container[4]->GetShape()->ComputeBBox();
3027 :
3028 : // Finally create the list of assemblies and return it to the caller
3029 4 : TList* conemodulelist = new TList();
3030 2 : conemodulelist->Add(container[0]);
3031 2 : conemodulelist->Add(container[1]);
3032 2 : conemodulelist->Add(container[2]);
3033 2 : conemodulelist->Add(container[3]);
3034 2 : conemodulelist->Add(container[4]);
3035 :
3036 : return conemodulelist;
3037 2 : }
3038 :
3039 : //______________________________________________________________________
3040 : void AliITSv11GeometrySPD::CreateCones(TGeoVolume *moth) const
3041 : {
3042 : //
3043 : // Places all services modules in the mother reference system
3044 : //
3045 : // Created: ?? ??? 2008 Alberto Pulvirenti
3046 : // Updated: 03 May 2010 Mario Sitta
3047 : // Updated: 04 Jul 2010 Mario Sitta Water cooling
3048 : //
3049 :
3050 : const Int_t kNumberOfModules = 10;
3051 :
3052 2 : const Double_t kInnerRadius = 80.775*fgkmm;
3053 1 : const Double_t kZTrans = 451.800*fgkmm;
3054 1 : const Double_t kAlphaRot = 46.500*fgkDegree;
3055 1 : const Double_t kAlphaSpaceCool = 9.200*fgkDegree;
3056 :
3057 1 : TList* modulelistA = CreateConeModule(kFALSE, 90-kAlphaRot);
3058 1 : TList* modulelistC = CreateConeModule(kTRUE , 90-kAlphaRot);
3059 : TList* &modulelist = modulelistC;
3060 : TGeoVolumeAssembly* module, *moduleA, *moduleC;
3061 :
3062 : Double_t xloc, yloc, zloc;
3063 :
3064 : //Double_t angle[10] = {18., 54., 90., 126., 162., -18., -54., -90., -126., -162.};
3065 : // anglem for cone modules (cables and cooling tubes)
3066 : // anglep for pathc panels
3067 1 : Double_t anglem[10] = {18., 54., 90., 126., 162., 198., 234., 270., 306., 342.};
3068 1 : Double_t anglep[10] = {18., 62., 90., 115., 162., 198., 242., 270., 295., 342.};
3069 : // Double_t angle1m[10] = {23., 53., 90., 127., 157., 203.0, 233.0, 270.0, 307.0, 337.0};
3070 : // Double_t angle2m[10] = {18., 53., 90., 126., 162., 198.0, 233.0, 270.0, 309.0, 342.0};
3071 : // Double_t angle1c[10] = {23., 53., 90., 124., 157., 203.0, 233.0, 270.0, 304.0, 337.0};
3072 : // Double_t angle2c[10] = {18., 44., 90., 126., 162., 198.0, 223.0, 270.0, 309.0, 342.0};
3073 :
3074 : // First add the cables
3075 1 : moduleA = (TGeoVolumeAssembly*)modulelistA->At(0);
3076 1 : moduleC = (TGeoVolumeAssembly*)modulelistC->At(0);
3077 22 : for (Int_t i = 0; i < kNumberOfModules; i++) {
3078 10 : TGeoRotation *rot1 = new TGeoRotation(*gGeoIdentity);
3079 10 : rot1->RotateY(-kAlphaRot);
3080 10 : rot1->RotateZ(anglem[i]);
3081 10 : xloc = kInnerRadius*CosD(anglem[i]);
3082 10 : yloc = kInnerRadius*SinD(anglem[i]);
3083 : zloc = kZTrans;
3084 20 : moth->AddNode(moduleA, 2*i+2,
3085 20 : new TGeoCombiTrans( xloc, yloc, zloc, rot1));
3086 :
3087 10 : TGeoRotation *rot2 = new TGeoRotation(*gGeoIdentity);
3088 10 : rot2->RotateY(180.-kAlphaRot);
3089 10 : rot2->RotateZ(anglem[i]);
3090 10 : xloc = kInnerRadius*CosD(anglem[i]);
3091 10 : yloc = kInnerRadius*SinD(anglem[i]);
3092 : zloc = kZTrans;
3093 20 : moth->AddNode(moduleC, 2*i+1,
3094 20 : new TGeoCombiTrans(-xloc,-yloc,-zloc, rot2));
3095 : }
3096 :
3097 : // Then the cooling tubes on Side A
3098 1 : module = (TGeoVolumeAssembly*)modulelist->At(1);
3099 : Double_t anglec;
3100 22 : for (Int_t i = 0; i < kNumberOfModules; i++) {
3101 10 : anglec = anglem[i] + kAlphaSpaceCool;
3102 10 : TGeoRotation *rot1 = new TGeoRotation(*gGeoIdentity);
3103 10 : rot1->RotateX(-90.0+kAlphaRot-0.04); // 0.04 fixes small overlap
3104 10 : rot1->RotateZ(-90.0+anglec);
3105 10 : xloc = kInnerRadius*CosD(anglec);
3106 10 : yloc = kInnerRadius*SinD(anglec);
3107 10 : zloc = kZTrans+0.162; // 0.162 fixes small overlap
3108 20 : moth->AddNode(module, 2*i+2,
3109 20 : new TGeoCombiTrans( xloc, yloc, zloc, rot1));
3110 : }
3111 :
3112 : // And the cooling tubes on Side C
3113 1 : module = (TGeoVolumeAssembly*)modulelist->At(2);
3114 22 : for (Int_t i = 0; i < kNumberOfModules; i++) {
3115 10 : anglec = anglem[i] - kAlphaSpaceCool;
3116 10 : TGeoRotation *rot2 = new TGeoRotation(*gGeoIdentity);
3117 10 : rot2->RotateX(-90.0+kAlphaRot-0.04); // 0.04 fixes small overlap
3118 10 : rot2->RotateY(180.);
3119 10 : rot2->RotateZ(90.0+anglec);
3120 10 : xloc = kInnerRadius*CosD(anglec);
3121 10 : yloc = kInnerRadius*SinD(anglec);
3122 10 : zloc = kZTrans+0.162; // 0.162 fixes small overlap
3123 20 : moth->AddNode(module, 2*i+1,
3124 20 : new TGeoCombiTrans(-xloc,-yloc,-zloc, rot2));
3125 : }
3126 :
3127 : // Then the water cooling tubes
3128 1 : module = (TGeoVolumeAssembly*)modulelist->At(4);
3129 20 : for (Int_t i = 1; i < kNumberOfModules; i++) { // i = 1,2,...,9
3130 9 : if (i != 5) { // There is no tube in this position
3131 8 : anglec = (anglem[i-1]+anglem[i])/2;
3132 8 : TGeoRotation *rot1 = new TGeoRotation(*gGeoIdentity);
3133 8 : rot1->RotateX(-90.0+kAlphaRot);
3134 8 : rot1->RotateZ(-90.0+anglec);
3135 8 : xloc = kInnerRadius*CosD(anglec);
3136 8 : yloc = kInnerRadius*SinD(anglec);
3137 : zloc = kZTrans;
3138 16 : moth->AddNode(module, 2*i+2,
3139 16 : new TGeoCombiTrans( xloc, yloc, zloc, rot1));
3140 :
3141 8 : TGeoRotation *rot2 = new TGeoRotation(*gGeoIdentity);
3142 8 : rot2->RotateX(-90.0+kAlphaRot);
3143 8 : rot2->RotateY(180.);
3144 8 : rot2->RotateZ(90.0+anglec);
3145 8 : xloc = kInnerRadius*CosD(anglec);
3146 8 : yloc = kInnerRadius*SinD(anglec);
3147 : zloc = kZTrans;
3148 16 : moth->AddNode(module, 2*i+1,
3149 16 : new TGeoCombiTrans(-xloc,-yloc,-zloc, rot2));
3150 8 : }
3151 : }
3152 :
3153 : // Finally the optical patch panels
3154 1 : module = (TGeoVolumeAssembly*)modulelist->At(3);
3155 22 : for (Int_t i = 0; i < kNumberOfModules; i++) {
3156 10 : TGeoRotation *rot1 = new TGeoRotation(*gGeoIdentity);
3157 10 : rot1->RotateY(-kAlphaRot);
3158 10 : rot1->RotateZ(anglep[i]);
3159 10 : xloc = kInnerRadius*CosD(anglep[i]);
3160 10 : yloc = kInnerRadius*SinD(anglep[i]);
3161 : zloc = kZTrans;
3162 20 : moth->AddNode(module, 2*i+2,
3163 20 : new TGeoCombiTrans( xloc, yloc, zloc, rot1));
3164 :
3165 10 : TGeoRotation *rot2 = new TGeoRotation(*gGeoIdentity);
3166 10 : rot2->RotateY(180.-kAlphaRot);
3167 10 : rot2->RotateZ(anglep[i]);
3168 10 : xloc = kInnerRadius*CosD(anglep[i]);
3169 10 : yloc = kInnerRadius*SinD(anglep[i]);
3170 : zloc = kZTrans;
3171 20 : moth->AddNode(module, 2*i+1,
3172 20 : new TGeoCombiTrans(-xloc,-yloc,-zloc, rot2));
3173 : }
3174 :
3175 1 : }
3176 :
3177 :
3178 : //______________________________________________________________________
3179 : void AliITSv11GeometrySPD::CreateServices(TGeoVolume *moth) const
3180 : {
3181 : //
3182 : // New method to implement SPD services
3183 : //
3184 : // Created: 25 Jul 2012 Mario Sitta
3185 : // Updated: 15 Nov 2012 Mario Sitta
3186 : //
3187 : // Data provided by C.Gargiulo from CAD
3188 :
3189 : // Cooling manifolds
3190 2 : const Double_t kCoolManifWidth = fgkmm * 22.0;
3191 1 : const Double_t kCoolManifLength = fgkmm * 50.0;
3192 1 : const Double_t kCoolManifThick = fgkmm * 7.0;
3193 1 : const Double_t kCoolManifFitR1out = fgkmm * 4.0;
3194 1 : const Double_t kCoolManifFitH1 = fgkmm * 2.5;
3195 : const Double_t kCoolManifFitR2out = fgkmm * 4.0;
3196 1 : const Double_t kCoolManifFitR2in = fgkmm * 3.2;
3197 : const Double_t kCoolManifFitH2 = fgkmm * 7.0;
3198 1 : const Double_t kCoolManifFitZPos = fgkmm * 2.0; // TO BE CHECKED!
3199 1 : const Double_t kCoolManifCollR1 = fgkmm * 3.0;
3200 : const Double_t kCoolManifCollH1 = fgkmm * 2.5;
3201 1 : const Double_t kCoolManifCollR2 = fgkmm * 1.5;
3202 1 : const Double_t kCoolManifCollH2 = fgkmm * 5.0;
3203 : const Double_t kCoolManifCollXPos = fgkmm * 5.0;
3204 1 : const Double_t kCoolManifCollDZ = fgkmm * 13.0;
3205 1 : const Double_t kCoolManifCollZ0 = fgkmm * 9.0;
3206 :
3207 1 : const Double_t kCoolManifRPosCAD = fgkmm * 76.2;
3208 1 : const Double_t kCoolManifZPos = fgkcm * 33.97;// 34.0 - 0.03 toll.
3209 : // Manifold supports
3210 1 : const Double_t kManifSuppWidth = fgkmm * 24.0; // TO BE CHECKED!
3211 1 : const Double_t kManifSuppLen1 = fgkmm * 17.9;
3212 1 : const Double_t kManifSuppLen2 = fgkmm * 54.2;
3213 1 : const Double_t kManifSuppLen3 = fgkmm * 7.9;
3214 : const Double_t kManifSuppThick = fgkmm * 1.5;
3215 : const Double_t kSuppScrewXPos = fgkmm * 4.0;
3216 : const Double_t kSuppScrewZPos = fgkmm * 3.0;
3217 1 : const Double_t kRThermalShield = fgkcm * 9.9255; // MUST match with GeometrySupport
3218 : // Sector supports
3219 1 : const Double_t kSectSuppWidth = fgkmm * 15.0;
3220 1 : const Double_t kSectSuppLen1 = fgkmm * 16.9; // TO BE CHECKED!
3221 1 : const Double_t kSectSuppLen2 = fgkmm * 35.1; // TO BE CHECKED!
3222 : const Double_t kSectSuppThick = fgkmm * 1.5;
3223 1 : const Double_t kSectSuppDepth = fgkmm * 17.78; // MUST match with GeometrySupport
3224 1 : const Double_t kSectScrewZPos = fgkmm * 5.1; // TO BE CHECKED!
3225 :
3226 1 : const Double_t kSectSuppZPos = fgkcm * 26.5;
3227 : // Sector clips
3228 1 : const Double_t kSectClipLength = fgkmm * 30.0;
3229 1 : const Double_t kSectClipWidth = fgkmm * 28.53;
3230 : const Double_t kSectClipThick1 = fgkmm * 2.0;
3231 1 : const Double_t kSectClipThick2 = fgkmm * 0.715;
3232 1 : const Double_t kSectClipInStave = fgkmm * 11.0; // Tuned
3233 : const Double_t kSectClipAngle = 29.0; // Degree. Tuned
3234 : // M3 screws
3235 : const Double_t kScrewM3Diam = fgkmm * 3.0;
3236 : const Double_t kScrewM3HeadThick = fgkmm * 2.0;
3237 : const Double_t kScrewM3HeadRmin = fgkmm * 1.5;
3238 : const Double_t kScrewM3HeadRmax = fgkmm * 2.5;
3239 : const Double_t kScrewM3OutManifH = fgkmm * 1.5;
3240 : // Central set pin (in sector support)
3241 1 : const Double_t kSetPinDiam = fgkmm * 6.0;
3242 1 : const Double_t kSetPinHeadDiam = fgkmm * 8.0;
3243 : const Double_t kSetPinHeadRmin = fgkmm * 1.5;
3244 : const Double_t kSetPinHeadThick = fgkmm * 1.5;
3245 : const Double_t kSetPinOutClipH = fgkmm * 1.0;
3246 :
3247 : // Local variables
3248 1 : Double_t xprof[12], yprof[12];
3249 : Double_t radius, theta;
3250 : Double_t xpos, ypos, zpos;
3251 : Double_t tmp;
3252 :
3253 :
3254 : // The cooling manifold: an Assembly
3255 1 : TGeoVolumeAssembly *coolmanifA = new TGeoVolumeAssembly("ITSSPDCoolManifSideA");
3256 1 : TGeoVolumeAssembly *coolmanifC = new TGeoVolumeAssembly("ITSSPDCoolManifSideC");
3257 :
3258 : // The various parts of the manifold
3259 2 : TGeoBBox *manifblksh = new TGeoBBox(kCoolManifWidth/2,
3260 1 : kCoolManifThick/2,
3261 1 : kCoolManifLength/2);
3262 :
3263 1 : TGeoBBox *manifinscubesh = new TGeoBBox(kCoolManifFitR2out,
3264 : kCoolManifFitR2out,
3265 : kCoolManifFitR2out);
3266 :
3267 2 : TGeoTube *manifinscyl1sh = new TGeoTube(0, // TO BE CHECKED!
3268 : kCoolManifFitR1out,
3269 1 : kCoolManifFitH1/2);
3270 :
3271 1 : TGeoTube *manifinscyl2sh = new TGeoTube(kCoolManifFitR2in,
3272 : kCoolManifFitR2out,
3273 : kCoolManifFitH2/2);
3274 :
3275 1 : TGeoTube *manifcollcyl1sh = new TGeoTube(0,
3276 : kCoolManifCollR1,
3277 : kCoolManifCollH1/2);
3278 :
3279 2 : TGeoTube *manifcollcyl2sh = new TGeoTube(0,
3280 : kCoolManifCollR2,
3281 1 : kCoolManifCollH2/2);
3282 :
3283 : // The cooling manifold supports
3284 1 : const Double_t kCoolManifRPos = kCoolManifRPosCAD +
3285 2 : (manifinscubesh->GetDY() +
3286 2 : 2*manifinscyl1sh->GetDz() +
3287 1 : manifblksh->GetDY() );
3288 :
3289 1 : const Double_t kManifSuppDepth = kRThermalShield -
3290 1 : (kCoolManifRPos + manifblksh->GetDY());
3291 :
3292 1 : TGeoXtru *suppmanifsh = new TGeoXtru(2);
3293 :
3294 1 : xprof[ 0] = kManifSuppLen2/2 + kManifSuppThick;
3295 1 : yprof[ 0] = 0;
3296 1 : xprof[ 1] = xprof[0];
3297 1 : yprof[ 1] = kManifSuppDepth;
3298 1 : xprof[ 2] = kManifSuppLen2/2 + kManifSuppLen3;
3299 1 : yprof[ 2] = yprof[1];
3300 1 : xprof[ 3] = xprof[2];
3301 1 : yprof[ 3] = yprof[2] + kManifSuppThick;
3302 1 : xprof[ 4] = kManifSuppLen2/2;
3303 1 : yprof[ 4] = yprof[3];
3304 1 : xprof[ 5] = xprof[4];
3305 1 : yprof[ 5] = kManifSuppThick;
3306 1 : xprof[ 6] = -xprof[5];
3307 1 : yprof[ 6] = yprof[5];
3308 1 : xprof[ 7] = -xprof[4];
3309 1 : yprof[ 7] = yprof[4];
3310 1 : xprof[ 8] = -(kManifSuppLen2/2 + kManifSuppLen1);
3311 1 : yprof[ 8] = yprof[3];
3312 1 : xprof[ 9] = xprof[8];
3313 1 : yprof[ 9] = yprof[2];
3314 1 : xprof[10] = -xprof[1];
3315 1 : yprof[10] = yprof[1];
3316 1 : xprof[11] = -xprof[0];
3317 1 : yprof[11] = yprof[0];
3318 :
3319 1 : suppmanifsh->DefinePolygon(12,xprof,yprof);
3320 1 : suppmanifsh->DefineSection(0,-kManifSuppWidth/2);
3321 1 : suppmanifsh->DefineSection(1, kManifSuppWidth/2);
3322 :
3323 : // The screw head and body
3324 2 : TGeoTube *suppscrewbodysh = new TGeoTube(0, kScrewM3Diam/2,
3325 1 : kManifSuppThick/2);
3326 :
3327 1 : TGeoPcon *suppscrewheadsh = new TGeoPcon(0, 360, 4);
3328 1 : suppscrewheadsh->DefineSection(0,-kScrewM3HeadThick/2,0, kScrewM3HeadRmax);
3329 1 : suppscrewheadsh->DefineSection(1, 0, 0, kScrewM3HeadRmax);
3330 1 : suppscrewheadsh->DefineSection(2, 0, kScrewM3HeadRmin, kScrewM3HeadRmax);
3331 1 : suppscrewheadsh->DefineSection(3, kScrewM3HeadThick/2,
3332 : kScrewM3HeadRmin, kScrewM3HeadRmax);
3333 :
3334 1 : TGeoTube *clipscrewbodysh = new TGeoTube(0, kScrewM3Diam/2,
3335 : kSectClipThick1/2);
3336 :
3337 : // The screw segment below the manifold and the sector clip
3338 1 : TGeoTube *screwoutmanifsh = new TGeoTube(0, kScrewM3Diam/2,
3339 : kScrewM3OutManifH/2);
3340 :
3341 : // The sector supports
3342 1 : TGeoXtru *suppsectsh = new TGeoXtru(2);
3343 :
3344 1 : xprof[ 0] = kSectSuppLen2/2 + kSectSuppThick;
3345 1 : yprof[ 0] = 0;
3346 1 : xprof[ 1] = xprof[0];
3347 1 : yprof[ 1] = kSectSuppDepth;
3348 1 : xprof[ 2] = kSectSuppLen2/2 + kSectSuppLen1;
3349 1 : yprof[ 2] = yprof[1];
3350 1 : xprof[ 3] = xprof[2];
3351 1 : yprof[ 3] = yprof[2] + kSectSuppThick;
3352 1 : xprof[ 4] = kSectSuppLen2/2;
3353 1 : yprof[ 4] = yprof[3];
3354 1 : xprof[ 5] = xprof[4];
3355 1 : yprof[ 5] = kSectSuppThick;
3356 1 : xprof[ 6] = -xprof[5];
3357 1 : yprof[ 6] = yprof[5];
3358 1 : xprof[ 7] = -xprof[4];
3359 1 : yprof[ 7] = yprof[4];
3360 1 : xprof[ 8] = -xprof[3];
3361 1 : yprof[ 8] = yprof[3];
3362 1 : xprof[ 9] = -xprof[2];
3363 1 : yprof[ 9] = yprof[2];
3364 1 : xprof[10] = -xprof[1];
3365 1 : yprof[10] = yprof[1];
3366 1 : xprof[11] = -xprof[0];
3367 1 : yprof[11] = yprof[0];
3368 :
3369 1 : suppsectsh->DefinePolygon(12,xprof,yprof);
3370 1 : suppsectsh->DefineSection(0,-kSectSuppWidth/2);
3371 1 : suppsectsh->DefineSection(1, kSectSuppWidth/2);
3372 :
3373 : // The sector clips
3374 1 : TGeoXtru *sectclipsh = new TGeoXtru(2);
3375 :
3376 1 : xprof[ 0] = kSectClipWidth/2;
3377 1 : yprof[ 0] = 0;
3378 1 : xprof[ 1] = -kSectClipWidth/2;
3379 1 : yprof[ 1] = yprof[0];
3380 1 : xprof[ 2] = xprof[1];
3381 1 : yprof[ 2] = -kSectClipThick1;
3382 1 : xprof[ 3] = kSectClipWidth/2 - kSectClipThick2;
3383 1 : yprof[ 3] = yprof[2];
3384 1 : xprof[ 4] = xprof[3] + kSectClipInStave*SinD(kSectClipAngle);
3385 1 : yprof[ 4] = -kSectClipInStave*CosD(kSectClipAngle);
3386 1 : xprof[ 5] = xprof[4] + kSectClipThick2*CosD(kSectClipAngle);
3387 1 : yprof[ 5] = yprof[4] + kSectClipThick2*SinD(kSectClipAngle);
3388 :
3389 1 : sectclipsh->DefinePolygon(6,xprof,yprof);
3390 1 : sectclipsh->DefineSection(0,-kSectClipLength/2);
3391 1 : sectclipsh->DefineSection(1, kSectClipLength/2);
3392 :
3393 : // The central set pin head and body
3394 1 : TGeoTube *setpinbodysh = new TGeoTube(0, kSetPinDiam/2,
3395 : kSectSuppThick/2);
3396 :
3397 1 : TGeoTube *setpinheadsh = new TGeoTube(kSetPinHeadRmin, kSetPinHeadDiam/2,
3398 : kSetPinHeadThick/2);
3399 :
3400 1 : TGeoTube *pinclipbodysh = new TGeoTube(0, kSetPinDiam/2,
3401 : kSectClipThick1/2);
3402 :
3403 : // The set pin segment below the sector clip
3404 2 : TGeoTube *setpinoutclipsh = new TGeoTube(0, kSetPinDiam/2,
3405 1 : kSetPinOutClipH/2);
3406 :
3407 :
3408 : // We have the shapes: now create the real volumes
3409 1 : TGeoMedium *medInox = GetMedium("INOX$");
3410 1 : TGeoMedium *medCu = GetMedium("COPPER$");
3411 1 : TGeoMedium *medSPDcf = GetMedium("SPD shield$");
3412 :
3413 2 : TGeoVolume *manifblk = new TGeoVolume("ITSSPDBlkManif",
3414 1 : manifblksh,medInox);
3415 1 : manifblk->SetLineColor(kGreen+2);
3416 :
3417 2 : TGeoVolume *manifinscube = new TGeoVolume("ITSSPDInsCubeManif",
3418 1 : manifinscubesh,medCu);
3419 1 : manifinscube->SetLineColor(kYellow);
3420 :
3421 2 : TGeoVolume *manifinscyl1 = new TGeoVolume("ITSSPDInsCyl1Manif",
3422 1 : manifinscyl1sh,medCu);
3423 1 : manifinscyl1->SetLineColor(kYellow);
3424 :
3425 2 : TGeoVolume *manifinscyl2 = new TGeoVolume("ITSSPDInsCyl2Manif",
3426 1 : manifinscyl2sh,medCu);
3427 1 : manifinscyl2->SetLineColor(kYellow);
3428 :
3429 2 : TGeoVolume *manifcollcyl1 = new TGeoVolume("ITSSPDCollCyl1Manif",
3430 1 : manifcollcyl1sh,medCu);
3431 1 : manifcollcyl1->SetLineColor(kYellow);
3432 :
3433 2 : TGeoVolume *manifcollcyl2 = new TGeoVolume("ITSSPDCollCyl2Manif",
3434 1 : manifcollcyl2sh,medCu);
3435 1 : manifcollcyl2->SetLineColor(kYellow);
3436 :
3437 2 : TGeoVolume *suppmanif = new TGeoVolume("ITSSPDCoolManifSupp",
3438 1 : suppmanifsh,medSPDcf);
3439 1 : suppmanif->SetLineColor(7);
3440 :
3441 2 : TGeoVolume *suppscrewbody = new TGeoVolume("ITSSPDSuppScrewBody",
3442 1 : suppscrewbodysh,medInox);
3443 1 : suppscrewbody->SetLineColor(kGray);
3444 :
3445 1 : xpos = kCoolManifLength/2 - kSuppScrewZPos;
3446 1 : ypos = suppscrewbodysh->GetDz();
3447 1 : zpos = kCoolManifWidth/2 - kSuppScrewXPos;
3448 3 : suppmanif->AddNode(suppscrewbody, 1, new TGeoCombiTrans( xpos, ypos, zpos,
3449 2 : new TGeoRotation("",0,90,0)));
3450 3 : suppmanif->AddNode(suppscrewbody, 2, new TGeoCombiTrans( xpos, ypos,-zpos,
3451 2 : new TGeoRotation("",0,90,0)));
3452 3 : suppmanif->AddNode(suppscrewbody, 3, new TGeoCombiTrans(-xpos, ypos, zpos,
3453 2 : new TGeoRotation("",0,90,0)));
3454 3 : suppmanif->AddNode(suppscrewbody, 4, new TGeoCombiTrans(-xpos, ypos,-zpos,
3455 2 : new TGeoRotation("",0,90,0)));
3456 :
3457 2 : TGeoVolume *suppscrewhead = new TGeoVolume("ITSSPDSuppScrewHead",
3458 1 : suppscrewheadsh,medInox);
3459 1 : suppscrewhead->SetLineColor(kGray);
3460 :
3461 2 : TGeoVolume *screwoutmanif = new TGeoVolume("ITSSPDSuppScrewOutManif",
3462 1 : screwoutmanifsh,medInox);
3463 1 : screwoutmanif->SetLineColor(kGray);
3464 :
3465 2 : TGeoVolume *suppsect = new TGeoVolume("ITSSPDCoolSectorSupp",
3466 1 : suppsectsh,medSPDcf);
3467 1 : suppsect->SetLineColor(7);
3468 :
3469 1 : xpos = kSectSuppLen2/2 - kSectScrewZPos;
3470 1 : ypos = suppscrewbodysh->GetDz();
3471 3 : suppsect->AddNode(suppscrewbody, 1, new TGeoCombiTrans( xpos, ypos, 0,
3472 2 : new TGeoRotation("",0,90,0)));
3473 3 : suppsect->AddNode(suppscrewbody, 2, new TGeoCombiTrans(-xpos, ypos, 0,
3474 2 : new TGeoRotation("",0,90,0)));
3475 :
3476 2 : TGeoVolume *setpinbody = new TGeoVolume("ITSSPDSetPinBody",
3477 1 : setpinbodysh,medInox);
3478 1 : setpinbody->SetLineColor(kGray);
3479 :
3480 1 : ypos = setpinbodysh->GetDz();
3481 3 : suppsect->AddNode(setpinbody, 1, new TGeoCombiTrans( 0, ypos, 0,
3482 2 : new TGeoRotation("",0,90,0)));
3483 :
3484 2 : TGeoVolume *setpinhead = new TGeoVolume("ITSSPDSetPinHead",
3485 1 : setpinheadsh,medInox);
3486 1 : setpinhead->SetLineColor(kGray);
3487 :
3488 2 : TGeoVolume *sectclip = new TGeoVolume("ITSSPDCoolSectorClip",
3489 1 : sectclipsh,medSPDcf);
3490 1 : sectclip->SetLineColor(7);
3491 :
3492 2 : TGeoVolume *clipscrewbody = new TGeoVolume("ITSSPDClipScrewBody",
3493 1 : clipscrewbodysh,medInox);
3494 1 : clipscrewbody->SetLineColor(kGray);
3495 :
3496 1 : ypos = -clipscrewbodysh->GetDz();
3497 : zpos = kSectSuppLen2/2 - kSectScrewZPos;
3498 3 : sectclip->AddNode(clipscrewbody, 1, new TGeoCombiTrans( 0, ypos, zpos,
3499 2 : new TGeoRotation("",0,90,0)));
3500 3 : sectclip->AddNode(clipscrewbody, 2, new TGeoCombiTrans( 0, ypos,-zpos,
3501 2 : new TGeoRotation("",0,90,0)));
3502 :
3503 2 : TGeoVolume *pinclipbody = new TGeoVolume("ITSSPDClipPinBody",
3504 1 : pinclipbodysh,medInox);
3505 1 : pinclipbody->SetLineColor(kGray);
3506 :
3507 1 : ypos = -pinclipbodysh->GetDz();
3508 3 : sectclip->AddNode(pinclipbody, 1, new TGeoCombiTrans( 0, ypos, 0,
3509 2 : new TGeoRotation("",0,90,0)));
3510 :
3511 2 : TGeoVolume *setpinoutclip = new TGeoVolume("ITSSPDSetPinOutClip",
3512 1 : setpinoutclipsh,medInox);
3513 1 : setpinoutclip->SetLineColor(kGray);
3514 :
3515 :
3516 : // Add all volumes in the assemblies
3517 1 : coolmanifA->AddNode(manifblk,1,0);
3518 1 : coolmanifC->AddNode(manifblk,1,0);
3519 :
3520 1 : ypos = manifblksh->GetDY() + manifinscyl1sh->GetDz();
3521 1 : zpos = manifblksh->GetDZ() - manifinscyl1sh->GetRmax() - kCoolManifFitZPos;
3522 3 : coolmanifA->AddNode(manifinscyl1, 1, new TGeoCombiTrans(0, -ypos, zpos,
3523 2 : new TGeoRotation("",0,90,0)));
3524 3 : coolmanifC->AddNode(manifinscyl1, 1, new TGeoCombiTrans(0, -ypos, zpos,
3525 2 : new TGeoRotation("",0,90,0)));
3526 :
3527 1 : ypos += (manifinscyl1sh->GetDz() + manifinscubesh->GetDY());
3528 2 : coolmanifA->AddNode(manifinscube, 1, new TGeoTranslation(0, -ypos, zpos));
3529 2 : coolmanifC->AddNode(manifinscube, 1, new TGeoTranslation(0, -ypos, zpos));
3530 :
3531 1 : zpos += (manifinscubesh->GetDZ() + manifinscyl2sh->GetDz());
3532 2 : coolmanifA->AddNode(manifinscyl2, 1, new TGeoTranslation(0, -ypos, zpos));
3533 2 : coolmanifC->AddNode(manifinscyl2, 1, new TGeoTranslation(0, -ypos, zpos));
3534 :
3535 1 : ypos = manifblksh->GetDY();
3536 3 : coolmanifA->AddNode(suppmanif, 1, new TGeoCombiTrans(0, ypos, 0,
3537 2 : new TGeoRotation("",-90,90,90)));
3538 3 : coolmanifC->AddNode(suppmanif, 1, new TGeoCombiTrans(0, ypos, 0,
3539 2 : new TGeoRotation("",-90,90,90)));
3540 :
3541 1 : ypos += (kManifSuppThick + kScrewM3HeadThick/2);
3542 : xpos = kCoolManifWidth/2 - kSuppScrewXPos;
3543 : zpos = kCoolManifLength/2 - kSuppScrewZPos;
3544 3 : coolmanifA->AddNode(suppscrewhead, 1, new TGeoCombiTrans( xpos, ypos, zpos,
3545 2 : new TGeoRotation("",0,-90,0)));
3546 3 : coolmanifC->AddNode(suppscrewhead, 1, new TGeoCombiTrans( xpos, ypos, zpos,
3547 2 : new TGeoRotation("",0,-90,0)));
3548 3 : coolmanifA->AddNode(suppscrewhead, 2, new TGeoCombiTrans( xpos, ypos,-zpos,
3549 2 : new TGeoRotation("",0,-90,0)));
3550 3 : coolmanifC->AddNode(suppscrewhead, 2, new TGeoCombiTrans( xpos, ypos,-zpos,
3551 2 : new TGeoRotation("",0,-90,0)));
3552 3 : coolmanifA->AddNode(suppscrewhead, 3, new TGeoCombiTrans(-xpos, ypos, zpos,
3553 2 : new TGeoRotation("",0,-90,0)));
3554 3 : coolmanifC->AddNode(suppscrewhead, 3, new TGeoCombiTrans(-xpos, ypos, zpos,
3555 2 : new TGeoRotation("",0,-90,0)));
3556 3 : coolmanifA->AddNode(suppscrewhead, 4, new TGeoCombiTrans(-xpos, ypos,-zpos,
3557 2 : new TGeoRotation("",0,-90,0)));
3558 3 : coolmanifC->AddNode(suppscrewhead, 4, new TGeoCombiTrans(-xpos, ypos,-zpos,
3559 2 : new TGeoRotation("",0,-90,0)));
3560 :
3561 1 : ypos = manifblksh->GetDY() + screwoutmanifsh->GetDz();
3562 3 : coolmanifA->AddNode(screwoutmanif, 1, new TGeoCombiTrans( xpos,-ypos, zpos,
3563 2 : new TGeoRotation("",0,-90,0)));
3564 3 : coolmanifC->AddNode(screwoutmanif, 1, new TGeoCombiTrans( xpos,-ypos, zpos,
3565 2 : new TGeoRotation("",0,-90,0)));
3566 3 : coolmanifA->AddNode(screwoutmanif, 2, new TGeoCombiTrans( xpos,-ypos,-zpos,
3567 2 : new TGeoRotation("",0,-90,0)));
3568 3 : coolmanifC->AddNode(screwoutmanif, 2, new TGeoCombiTrans( xpos,-ypos,-zpos,
3569 2 : new TGeoRotation("",0,-90,0)));
3570 3 : coolmanifA->AddNode(screwoutmanif, 3, new TGeoCombiTrans(-xpos,-ypos, zpos,
3571 2 : new TGeoRotation("",0,-90,0)));
3572 3 : coolmanifC->AddNode(screwoutmanif, 3, new TGeoCombiTrans(-xpos,-ypos, zpos,
3573 2 : new TGeoRotation("",0,-90,0)));
3574 3 : coolmanifA->AddNode(screwoutmanif, 4, new TGeoCombiTrans(-xpos,-ypos,-zpos,
3575 2 : new TGeoRotation("",0,-90,0)));
3576 3 : coolmanifC->AddNode(screwoutmanif, 4, new TGeoCombiTrans(-xpos,-ypos,-zpos,
3577 2 : new TGeoRotation("",0,-90,0)));
3578 :
3579 1 : ypos = manifblksh->GetDY() + suppmanifsh->GetY(1) - suppsectsh->GetY(1);
3580 1 : zpos = manifblksh->GetDZ() + (kCoolManifZPos - kSectSuppZPos);
3581 3 : coolmanifA->AddNode(suppsect, 1, new TGeoCombiTrans(0, ypos,-zpos,
3582 2 : new TGeoRotation("",-90,90,90)));
3583 3 : coolmanifC->AddNode(suppsect, 1, new TGeoCombiTrans(0, ypos,-zpos,
3584 2 : new TGeoRotation("",-90,90,90)));
3585 :
3586 : tmp = ypos; // Save it to avoid recomputing
3587 :
3588 1 : ypos += (kSectSuppThick + kScrewM3HeadThick/2);
3589 1 : zpos += (kSectSuppLen2/2 - kSectScrewZPos);
3590 3 : coolmanifA->AddNode(suppscrewhead, 5, new TGeoCombiTrans( 0, ypos,-zpos,
3591 2 : new TGeoRotation("",0,-90,0)));
3592 3 : coolmanifC->AddNode(suppscrewhead, 5, new TGeoCombiTrans( 0, ypos,-zpos,
3593 2 : new TGeoRotation("",0,-90,0)));
3594 1 : zpos -= 2*(kSectSuppLen2/2 - kSectScrewZPos);
3595 3 : coolmanifA->AddNode(suppscrewhead, 6, new TGeoCombiTrans( 0, ypos,-zpos,
3596 2 : new TGeoRotation("",0,-90,0)));
3597 3 : coolmanifC->AddNode(suppscrewhead, 6, new TGeoCombiTrans( 0, ypos,-zpos,
3598 2 : new TGeoRotation("",0,-90,0)));
3599 :
3600 1 : ypos = tmp + kSectSuppThick + kSetPinHeadThick/2;
3601 1 : zpos += (kSectSuppLen2/2 - kSectScrewZPos);
3602 3 : coolmanifA->AddNode(setpinhead, 1, new TGeoCombiTrans( 0, ypos,-zpos,
3603 2 : new TGeoRotation("",0,-90,0)));
3604 3 : coolmanifC->AddNode(setpinhead, 1, new TGeoCombiTrans( 0, ypos,-zpos,
3605 2 : new TGeoRotation("",0,-90,0)));
3606 :
3607 1 : ypos = tmp - 8.e-5; // Avoid microscopic overlap
3608 : tmp = ypos;
3609 2 : coolmanifA->AddNode(sectclip, 1, new TGeoTranslation( 0, ypos,-zpos));
3610 3 : coolmanifC->AddNode(sectclip, 1, new TGeoCombiTrans ( 0, ypos,-zpos,
3611 2 : new TGeoRotation("",-90,180,90)));
3612 :
3613 1 : ypos -= (kSectClipThick1 + setpinoutclipsh->GetDz());
3614 3 : coolmanifA->AddNode(setpinoutclip, 1, new TGeoCombiTrans( 0, ypos,-zpos,
3615 2 : new TGeoRotation("",0,-90,0)));
3616 3 : coolmanifC->AddNode(setpinoutclip, 1, new TGeoCombiTrans( 0, ypos,-zpos,
3617 2 : new TGeoRotation("",0,-90,0)));
3618 :
3619 1 : ypos = tmp - (kSectClipThick1 + screwoutmanifsh->GetDz());
3620 1 : zpos += (kSectSuppLen2/2 - kSectScrewZPos);
3621 3 : coolmanifA->AddNode(screwoutmanif, 5, new TGeoCombiTrans( 0, ypos,-zpos,
3622 2 : new TGeoRotation("",0,-90,0)));
3623 3 : coolmanifC->AddNode(screwoutmanif, 5, new TGeoCombiTrans( 0, ypos,-zpos,
3624 2 : new TGeoRotation("",0,-90,0)));
3625 1 : zpos -= 2*(kSectSuppLen2/2 - kSectScrewZPos);
3626 3 : coolmanifA->AddNode(screwoutmanif, 6, new TGeoCombiTrans( 0, ypos,-zpos,
3627 2 : new TGeoRotation("",0,-90,0)));
3628 3 : coolmanifC->AddNode(screwoutmanif, 6, new TGeoCombiTrans( 0, ypos,-zpos,
3629 2 : new TGeoRotation("",0,-90,0)));
3630 :
3631 1 : xpos = manifblksh->GetDX() - kCoolManifCollXPos;
3632 1 : ypos = manifblksh->GetDY() + manifcollcyl1sh->GetDz();
3633 1 : zpos =-manifblksh->GetDZ() + kCoolManifCollZ0;
3634 8 : for (Int_t i=0; i<3; i++) {
3635 6 : coolmanifA->AddNode(manifcollcyl1, 2*i+1,
3636 9 : new TGeoCombiTrans( xpos, -ypos, zpos,
3637 6 : new TGeoRotation("",0,90,0)));
3638 6 : coolmanifA->AddNode(manifcollcyl1, 2*i+2,
3639 9 : new TGeoCombiTrans(-xpos, -ypos, zpos,
3640 6 : new TGeoRotation("",0,90,0)));
3641 6 : coolmanifC->AddNode(manifcollcyl1, 2*i+1,
3642 9 : new TGeoCombiTrans( xpos, -ypos, zpos,
3643 6 : new TGeoRotation("",0,90,0)));
3644 6 : coolmanifC->AddNode(manifcollcyl1, 2*i+2,
3645 9 : new TGeoCombiTrans(-xpos, -ypos, zpos,
3646 6 : new TGeoRotation("",0,90,0)));
3647 3 : Double_t y = ypos + manifcollcyl1sh->GetDz() + manifcollcyl2sh->GetDz();
3648 6 : coolmanifA->AddNode(manifcollcyl2, 2*i+1,
3649 9 : new TGeoCombiTrans( xpos, -y, zpos,
3650 6 : new TGeoRotation("",0,90,0)));
3651 6 : coolmanifA->AddNode(manifcollcyl2, 2*i+2,
3652 9 : new TGeoCombiTrans(-xpos, -y, zpos,
3653 6 : new TGeoRotation("",0,90,0)));
3654 6 : coolmanifC->AddNode(manifcollcyl2, 2*i+1,
3655 9 : new TGeoCombiTrans( xpos, -y, zpos,
3656 6 : new TGeoRotation("",0,90,0)));
3657 6 : coolmanifC->AddNode(manifcollcyl2, 2*i+2,
3658 9 : new TGeoCombiTrans(-xpos, -y, zpos,
3659 6 : new TGeoRotation("",0,90,0)));
3660 :
3661 3 : zpos += kCoolManifCollDZ;
3662 : }
3663 :
3664 1 : coolmanifA->GetShape()->ComputeBBox(); //RS: enforce recompting of BBox
3665 1 : coolmanifC->GetShape()->ComputeBBox();
3666 :
3667 : // Now add the cooling tubes to the assembly
3668 1 : CreateCoolingTubes(coolmanifA, kFALSE);
3669 1 : CreateCoolingTubes(coolmanifC, kTRUE);
3670 :
3671 :
3672 : // Finally put everything in the mother volume
3673 1 : radius = kCoolManifRPos + 1.e-5; // Avoid microscopic overlap
3674 1 : zpos = kCoolManifZPos + manifblksh->GetDZ();
3675 22 : for (Int_t i=0; i<10; i++) {
3676 10 : theta = 36.*i;
3677 40 : moth->AddNode(coolmanifA, i+1, new TGeoCombiTrans(radius*SinD(theta),
3678 20 : radius*CosD(theta),
3679 : zpos,
3680 20 : new TGeoRotation("",-theta,0,0)));
3681 40 : moth->AddNode(coolmanifC, i+1, new TGeoCombiTrans(radius*SinD(theta),
3682 20 : radius*CosD(theta),
3683 10 : -zpos,
3684 20 : new TGeoRotation("",90-theta,180,-90)));
3685 : }
3686 :
3687 :
3688 1 : }
3689 :
3690 :
3691 : //______________________________________________________________________
3692 : void AliITSv11GeometrySPD::CreateCoolingTubes(TGeoVolume *moth, Bool_t sideC) const
3693 : {
3694 : //
3695 : // Private method to implement SPD cooling tubes
3696 : // going from the manifolds to the staves
3697 : // Since their form is quite complicate (especially on Side C
3698 : // where capillaries are located) a separate method is used
3699 : // If sideC is true, the cooling tubes on Side C are created
3700 : // along with the cooling loops (aka "capillaries"), otherwise
3701 : // the (simpler) tubes on Side A get created.
3702 : //
3703 : // In all variables: L = Left (X > 0) R = Right (X < 0)
3704 : //
3705 : // Created: 10 Nov 2012 Mario Sitta
3706 : //
3707 : // Data provided by C.Gargiulo from CAD
3708 :
3709 : // Cooling manifolds - THESE VALUES *MUST* MATCH WITH CALLING METHOD!
3710 2 : const Double_t kCoolManifWidth = fgkmm * 22.0;
3711 2 : const Double_t kCoolManifLength = fgkmm * 50.0;
3712 2 : const Double_t kCoolManifThick = fgkmm * 7.0;
3713 2 : const Double_t kCoolManifCollH1 = fgkmm * 2.5;
3714 2 : const Double_t kCoolManifCollH2 = fgkmm * 5.0;
3715 : // Cooling pipes
3716 2 : const Double_t kCoolPipeSideARin = fgkmm * 1.5;
3717 2 : const Double_t kCoolPipeSideARout = fgkmm * 1.8;
3718 2 : const Double_t kCoolPipeSideCRin = fgkmm * 0.5;
3719 2 : const Double_t kCoolPipeSideCRout = fgkmm * 0.85;
3720 2 : const Double_t kCoolPipeHeight = fgkmm * 1.923;
3721 : const Double_t kCoolPipeCRadiusL[3] = {11.0, 14.0, 31.34};// TO BE CHECKED!
3722 : const Double_t kCoolPipeCRadiusR[3] = {12.0, 14.0, 35.54};// TO BE CHECKED!
3723 : const Double_t kCoolPipeARadiusL12[2] = {14.0, 30.0};
3724 : const Double_t kCoolPipeARadiusR12[2] = {14.0, 30.0};
3725 : const Double_t kCoolPipeARadiusL34[2] = {22.0, 30.0};
3726 : const Double_t kCoolPipeARadiusR34[2] = {22.0, 30.0};
3727 : const Double_t kCoolPipeARadiusL[3]= {14.0, 14.0, 31.34}; // TO BE CHECKED!
3728 : const Double_t kCoolPipeARadiusR[3]= {14.0, 14.0, 35.54}; // TO BE CHECKED!
3729 2 : const Double_t kCoolPipeZSPD = fgkcm * 8.47;
3730 : // Cooling pipes position - THESE VALUES *MUST* MATCH WITH CALLING METHOD!
3731 : const Double_t kCoolManifCollXPos = fgkmm * 5.0;
3732 2 : const Double_t kCoolManifCollDZ = fgkmm * 13.0;
3733 2 : const Double_t kCoolManifCollZ0 = fgkmm * 9.0;
3734 :
3735 : Int_t kPurple = 6; // Purple (Root does not define it)
3736 :
3737 : // Local variables
3738 : Double_t xpos, ypos, zpos;
3739 2 : Char_t pipename[11];
3740 :
3741 : //
3742 2 : TGeoMedium *medPhynox = GetMedium("PHYNOX$");
3743 2 : TGeoMedium *medFreon = GetMedium("Freon$");
3744 2 : TGeoMedium *medGasFr = GetMedium("GASEOUS FREON$");
3745 :
3746 : // The cooling tubes are created as CableRound volumes
3747 : // because it's easier to compose them piece by piece
3748 2 : AliITSv11GeomCableRound *coolpipe[6];
3749 :
3750 2 : if (sideC)
3751 14 : for (Int_t i = 0; i<6; i++) {
3752 6 : snprintf(pipename,11,"coolPipeC%d",i+1);
3753 12 : coolpipe[i] = new AliITSv11GeomCableRound(pipename,kCoolPipeSideCRout);
3754 6 : coolpipe[i]->SetNLayers(2);
3755 6 : coolpipe[i]->SetLayer(0, kCoolPipeSideCRin, medFreon, kPurple);
3756 6 : coolpipe[i]->SetLayer(1,(kCoolPipeSideCRout-kCoolPipeSideCRin),
3757 : medPhynox, kYellow);
3758 1 : }
3759 : else
3760 14 : for (Int_t i = 0; i<6; i++) {
3761 6 : snprintf(pipename,11,"coolPipeA%d",i+1);
3762 12 : coolpipe[i] = new AliITSv11GeomCableRound(pipename,kCoolPipeSideARout);
3763 6 : coolpipe[i]->SetNLayers(2);
3764 6 : coolpipe[i]->SetLayer(0, kCoolPipeSideARin, medGasFr, kPurple);
3765 6 : coolpipe[i]->SetLayer(1,(kCoolPipeSideARout-kCoolPipeSideARin),
3766 : medPhynox, kYellow);
3767 : }
3768 :
3769 : // Now place them in the mother assembly
3770 2 : xpos = kCoolManifWidth/2 - kCoolManifCollXPos;
3771 2 : ypos = kCoolManifThick/2 + kCoolManifCollH1 + kCoolManifCollH2;
3772 2 : zpos =-kCoolManifLength/2 + kCoolManifCollZ0;
3773 :
3774 2 : if (sideC) { // On Side C tubes are simpler and can be created in a loop
3775 :
3776 8 : for (Int_t i=0; i<3; i++) {
3777 :
3778 3 : Double_t coordL[3] = { xpos,-ypos,zpos};
3779 3 : Double_t coordR[3] = {-xpos,-ypos,zpos};
3780 3 : Double_t vect[3] = {0, 1, 0};
3781 3 : coolpipe[2*i]->AddCheckPoint(moth, 0, coordL, vect);
3782 3 : coolpipe[2*i+1]->AddCheckPoint(moth, 0, coordR, vect);
3783 3 : coordL[1] -= kCoolPipeHeight;
3784 3 : coordR[1] = coordL[1];
3785 3 : coolpipe[2*i]->AddCheckPoint(moth, 1, coordL, vect);
3786 3 : coolpipe[2*i+1]->AddCheckPoint(moth, 1, coordR, vect);
3787 3 : coordL[1] -= kCoolPipeCRadiusL[i]*fgkmm;
3788 3 : coordL[2] -= kCoolPipeCRadiusL[i]*fgkmm;
3789 3 : coordR[1] -= kCoolPipeCRadiusR[i]*fgkmm;
3790 3 : coordR[2] -= kCoolPipeCRadiusR[i]*fgkmm;
3791 3 : vect[1] = 0;
3792 3 : vect[2] = -1;
3793 3 : coolpipe[2*i]->AddCheckPoint(moth, 2, coordL, vect);
3794 3 : coolpipe[2*i+1]->AddCheckPoint(moth, 2, coordR, vect);
3795 3 : coordL[2] = -kCoolPipeZSPD;
3796 3 : coordR[2] = -kCoolPipeZSPD;
3797 3 : coolpipe[2*i]->AddCheckPoint(moth, 3, coordL, vect);
3798 3 : coolpipe[2*i+1]->AddCheckPoint(moth, 3, coordR, vect);
3799 :
3800 3 : zpos += kCoolManifCollDZ;
3801 3 : }
3802 :
3803 14 : for (Int_t i=0; i<6; i++) {
3804 6 : coolpipe[i]->SetInitialNode(moth);
3805 :
3806 6 : coolpipe[i]->CreateAndInsertTubeSegment(1);
3807 6 : coolpipe[i]->CreateAndInsertTorusSegment(2,180);
3808 6 : coolpipe[i]->CreateAndInsertTubeSegment(3);
3809 : }
3810 :
3811 1 : } else { // On Side A tubes are all different so are created one by one
3812 :
3813 1 : Double_t coordL[3] = { xpos,-ypos,zpos};
3814 1 : Double_t coordR[3] = {-xpos,-ypos,zpos};
3815 1 : Double_t vect[3] = {0, 1, 0};
3816 1 : coolpipe[0]->AddCheckPoint(moth, 0, coordL, vect);
3817 1 : coolpipe[1]->AddCheckPoint(moth, 0, coordR, vect);
3818 1 : coordL[1] -= kCoolPipeHeight;
3819 1 : coordR[1] = coordL[1];
3820 1 : coolpipe[0]->AddCheckPoint(moth, 1, coordL, vect);
3821 1 : coolpipe[1]->AddCheckPoint(moth, 1, coordR, vect);
3822 1 : coordL[1] -= SinD(45) *kCoolPipeARadiusL12[0]*fgkmm;
3823 1 : coordL[2] -= (1+CosD(45))*kCoolPipeARadiusL12[0]*fgkmm;
3824 1 : coordR[1] -= SinD(45) *kCoolPipeARadiusR12[0]*fgkmm;
3825 1 : coordR[2] -= (1+CosD(45))*kCoolPipeARadiusR12[0]*fgkmm;
3826 1 : vect[1] = TMath::Sqrt(2);
3827 1 : vect[2] = -vect[1];
3828 1 : coolpipe[0]->AddCheckPoint(moth, 2, coordL, vect);
3829 1 : coolpipe[1]->AddCheckPoint(moth, 2, coordR, vect);
3830 1 : coordL[1] += (1-CosD(45))*kCoolPipeARadiusL12[1]*fgkmm;
3831 1 : coordL[2] -= SinD(45) *kCoolPipeARadiusL12[1]*fgkmm;
3832 1 : coordR[1] += (1-CosD(45))*kCoolPipeARadiusR12[1]*fgkmm;
3833 1 : coordR[2] -= SinD(45) *kCoolPipeARadiusR12[1]*fgkmm;
3834 1 : vect[1] = 0;
3835 1 : vect[2] = -1;
3836 1 : coolpipe[0]->AddCheckPoint(moth, 3, coordL, vect);
3837 1 : coolpipe[1]->AddCheckPoint(moth, 3, coordR, vect);
3838 1 : coordL[2] = -kCoolPipeZSPD;
3839 1 : coordR[2] = -kCoolPipeZSPD;
3840 1 : coolpipe[0]->AddCheckPoint(moth, 4, coordL, vect);
3841 1 : coolpipe[1]->AddCheckPoint(moth, 4, coordR, vect);
3842 :
3843 1 : coolpipe[0]->SetInitialNode(moth);
3844 1 : coolpipe[0]->CreateAndInsertTubeSegment(1);
3845 1 : coolpipe[0]->CreateAndInsertTorusSegment(2,180);
3846 1 : coolpipe[0]->CreateAndInsertTorusSegment(3,180);
3847 1 : coolpipe[0]->CreateAndInsertTubeSegment(4);
3848 :
3849 1 : coolpipe[1]->SetInitialNode(moth);
3850 1 : coolpipe[1]->CreateAndInsertTubeSegment(1);
3851 1 : coolpipe[1]->CreateAndInsertTorusSegment(2,180);
3852 1 : coolpipe[1]->CreateAndInsertTorusSegment(3,180);
3853 1 : coolpipe[1]->CreateAndInsertTubeSegment(4);
3854 :
3855 1 : zpos += kCoolManifCollDZ;
3856 :
3857 1 : coordL[0] = xpos; coordL[1] = -ypos; coordL[2] = zpos;
3858 1 : coordR[0] =-xpos; coordR[1] = -ypos; coordR[2] = zpos;
3859 1 : vect[0] = 0; vect[1] = 1; vect[2] = 0;
3860 :
3861 1 : coolpipe[2]->AddCheckPoint(moth, 0, coordL, vect);
3862 1 : coolpipe[3]->AddCheckPoint(moth, 0, coordR, vect);
3863 1 : coordL[1] -= kCoolPipeHeight;
3864 1 : coordR[1] = coordL[1];
3865 1 : coolpipe[2]->AddCheckPoint(moth, 1, coordL, vect);
3866 1 : coolpipe[3]->AddCheckPoint(moth, 1, coordR, vect);
3867 1 : coordL[1] -= SinD(45) *kCoolPipeARadiusL34[0]*fgkmm;
3868 1 : coordL[2] -= (1+CosD(45))*kCoolPipeARadiusL34[0]*fgkmm;
3869 1 : coordR[1] -= SinD(45) *kCoolPipeARadiusR34[0]*fgkmm;
3870 1 : coordR[2] -= (1+CosD(45))*kCoolPipeARadiusR34[0]*fgkmm;
3871 1 : vect[1] = TMath::Sqrt(2);
3872 1 : vect[2] = -vect[1];
3873 1 : coolpipe[2]->AddCheckPoint(moth, 2, coordL, vect);
3874 1 : coolpipe[3]->AddCheckPoint(moth, 2, coordR, vect);
3875 1 : coordL[1] += (1-CosD(45))*kCoolPipeARadiusL34[1]*fgkmm;
3876 1 : coordL[2] -= SinD(45) *kCoolPipeARadiusL34[1]*fgkmm;
3877 1 : coordR[1] += (1-CosD(45))*kCoolPipeARadiusR34[1]*fgkmm;
3878 1 : coordR[2] -= SinD(45) *kCoolPipeARadiusR34[1]*fgkmm;
3879 1 : vect[1] = 0;
3880 1 : vect[2] = -1;
3881 1 : coolpipe[2]->AddCheckPoint(moth, 3, coordL, vect);
3882 1 : coolpipe[3]->AddCheckPoint(moth, 3, coordR, vect);
3883 1 : coordL[2] = -kCoolPipeZSPD;
3884 1 : coordR[2] = -kCoolPipeZSPD;
3885 1 : coolpipe[2]->AddCheckPoint(moth, 4, coordL, vect);
3886 1 : coolpipe[3]->AddCheckPoint(moth, 4, coordR, vect);
3887 :
3888 1 : coolpipe[2]->SetInitialNode(moth);
3889 1 : coolpipe[2]->CreateAndInsertTubeSegment(1);
3890 1 : coolpipe[2]->CreateAndInsertTorusSegment(2,180);
3891 1 : coolpipe[2]->CreateAndInsertTorusSegment(3,180);
3892 1 : coolpipe[2]->CreateAndInsertTubeSegment(4);
3893 :
3894 1 : coolpipe[3]->SetInitialNode(moth);
3895 1 : coolpipe[3]->CreateAndInsertTubeSegment(1);
3896 1 : coolpipe[3]->CreateAndInsertTorusSegment(2,180);
3897 1 : coolpipe[3]->CreateAndInsertTorusSegment(3,180);
3898 1 : coolpipe[3]->CreateAndInsertTubeSegment(4);
3899 :
3900 1 : zpos += kCoolManifCollDZ;
3901 :
3902 1 : coordL[0] = xpos; coordL[1] = -ypos; coordL[2] = zpos;
3903 1 : coordR[0] =-xpos; coordR[1] = -ypos; coordR[2] = zpos;
3904 1 : vect[0] = 0; vect[1] = 1; vect[2] = 0;
3905 :
3906 1 : coolpipe[4]->AddCheckPoint(moth, 0, coordL, vect);
3907 1 : coolpipe[5]->AddCheckPoint(moth, 0, coordR, vect);
3908 1 : coordL[1] -= kCoolPipeHeight;
3909 1 : coordR[1] = coordL[1];
3910 1 : coolpipe[4]->AddCheckPoint(moth, 1, coordL, vect);
3911 1 : coolpipe[5]->AddCheckPoint(moth, 1, coordR, vect);
3912 1 : coordL[1] -= kCoolPipeARadiusL[2]*fgkmm;
3913 1 : coordL[2] -= kCoolPipeARadiusL[2]*fgkmm;
3914 1 : coordR[1] -= kCoolPipeARadiusR[2]*fgkmm;
3915 1 : coordR[2] -= kCoolPipeARadiusR[2]*fgkmm;
3916 1 : vect[1] = 0;
3917 1 : vect[2] = -1;
3918 1 : coolpipe[4]->AddCheckPoint(moth, 2, coordL, vect);
3919 1 : coolpipe[5]->AddCheckPoint(moth, 2, coordR, vect);
3920 1 : coordL[2] = -kCoolPipeZSPD;
3921 1 : coordR[2] = -kCoolPipeZSPD;
3922 1 : coolpipe[4]->AddCheckPoint(moth, 3, coordL, vect);
3923 1 : coolpipe[5]->AddCheckPoint(moth, 3, coordR, vect);
3924 :
3925 1 : coolpipe[4]->SetInitialNode(moth);
3926 1 : coolpipe[4]->CreateAndInsertTubeSegment(1);
3927 1 : coolpipe[4]->CreateAndInsertTorusSegment(2,180);
3928 1 : coolpipe[4]->CreateAndInsertTubeSegment(3);
3929 :
3930 1 : coolpipe[5]->SetInitialNode(moth);
3931 1 : coolpipe[5]->CreateAndInsertTubeSegment(1);
3932 1 : coolpipe[5]->CreateAndInsertTorusSegment(2,180);
3933 1 : coolpipe[5]->CreateAndInsertTubeSegment(3);
3934 :
3935 1 : } // if (sideC)
3936 :
3937 2 : if(GetDebug(3))
3938 0 : for (Int_t i=0; i<6; i++)
3939 0 : coolpipe[i]->PrintCheckPoints();
3940 :
3941 2 : }
3942 :
3943 :
3944 : //______________________________________________________________________
3945 : TGeoVolume* AliITSv11GeometrySPD::CreateExtender(
3946 : const Double_t *extenderParams, const TGeoMedium *extenderMedium,
3947 : TArrayD& sizes) const
3948 : {
3949 : //
3950 : // ------------------ CREATE AN EXTENDER ------------------------
3951 : //
3952 : // This function creates the following picture (in plane xOy)
3953 : // Should be useful for the definition of the pixel bus and MCM extenders
3954 : // The origin corresponds to point 0 on the picture, at half-width
3955 : // in Z direction
3956 : //
3957 : // Y 7 6 5
3958 : // ^ +---+---------------------+
3959 : // | / |
3960 : // | / |
3961 : // 0------> X / +---------------------+
3962 : // / / 3 4
3963 : // / /
3964 : // 9 8 / /
3965 : // +-----------+ /
3966 : // | /
3967 : // | /
3968 : // ---> +-----------+---+
3969 : // | 0 1 2
3970 : // |
3971 : // origin (0,0,0)
3972 : //
3973 : //
3974 : // Takes 6 parameters in the following order :
3975 : // |--> par 0 : inner length [0-1] / [9-8]
3976 : // |--> par 1 : thickness ( = [0-9] / [4-5])
3977 : // |--> par 2 : angle of the slope
3978 : // |--> par 3 : total height in local Y direction
3979 : // |--> par 4 : outer length [3-4] / [6-5]
3980 : // |--> par 5 : width in local Z direction
3981 : //
3982 0 : Double_t slopeDeltaX = (extenderParams[3] - extenderParams[1]
3983 0 : * TMath::Cos(extenderParams[2])) /
3984 0 : TMath::Tan(extenderParams[2]);
3985 0 : Double_t extenderXtruX[10] = {
3986 : 0 ,
3987 0 : extenderParams[0] ,
3988 0 : extenderParams[0]+extenderParams[1]*TMath::Sin(extenderParams[2]) ,
3989 0 : extenderParams[0]+extenderParams[1]*TMath::Sin(extenderParams[2])+
3990 : slopeDeltaX ,
3991 0 : extenderParams[0]+extenderParams[1]*TMath::Sin(extenderParams[2])+
3992 0 : slopeDeltaX + extenderParams[4],
3993 0 : extenderParams[0]+extenderParams[1]*TMath::Sin(extenderParams[2])+
3994 0 : slopeDeltaX + extenderParams[4],
3995 0 : extenderParams[0]+extenderParams[1]*TMath::Sin(extenderParams[2])+
3996 : slopeDeltaX ,
3997 0 : extenderParams[0]+extenderParams[1]*TMath::Sin(extenderParams[2])+
3998 0 : slopeDeltaX - extenderParams[1] * TMath::Sin(extenderParams[2]) ,
3999 0 : extenderParams[0] ,
4000 : 0
4001 : };
4002 0 : Double_t extenderXtruY[10] = {
4003 : 0 ,
4004 : 0 ,
4005 0 : extenderParams[1] * (1-TMath::Cos(extenderParams[2])) ,
4006 0 : extenderParams[3] - extenderParams[1] ,
4007 0 : extenderParams[3] - extenderParams[1] ,
4008 0 : extenderParams[3] ,
4009 0 : extenderParams[3] ,
4010 0 : extenderParams[3]-extenderParams[1]*(1-TMath::Cos(extenderParams[2])) ,
4011 0 : extenderParams[1] ,
4012 0 : extenderParams[1]
4013 : };
4014 :
4015 0 : if (sizes.GetSize() != 3) sizes.Set(3);
4016 0 : Double_t &thickness = sizes[0];
4017 0 : Double_t &length = sizes[1];
4018 0 : Double_t &width = sizes[2];
4019 :
4020 0 : thickness = extenderParams[3];
4021 0 : width = extenderParams[5];
4022 0 : length = extenderParams[0]+extenderParams[1]*
4023 0 : TMath::Sin(extenderParams[2])+slopeDeltaX+extenderParams[4];
4024 :
4025 : // creation of the volume
4026 0 : TGeoXtru *extenderXtru = new TGeoXtru(2);
4027 0 : TGeoVolume *extenderXtruVol = new TGeoVolume("ITSSPDextender",extenderXtru,
4028 : extenderMedium);
4029 0 : extenderXtru->DefinePolygon(10,extenderXtruX,extenderXtruY);
4030 0 : extenderXtru->DefineSection(0,-0.5*extenderParams[4]);
4031 0 : extenderXtru->DefineSection(1, 0.5*extenderParams[4]);
4032 0 : return extenderXtruVol;
4033 0 : }
4034 :
4035 : //______________________________________________________________________
4036 : TGeoVolumeAssembly* AliITSv11GeometrySPD::CreateHalfStave(Bool_t isRight,
4037 : Int_t layer,Int_t idxCentral,Int_t idxSide,TArrayD &sizes,TGeoManager *mgr)
4038 : {
4039 : //
4040 : // Implementation of an half-stave, which depends on the side where
4041 : // we are on the stave. The convention for "left" and "right" is the
4042 : // same as for the MCM. The return value is a TGeoAssembly which is
4043 : // structured in such a way that the origin of its local reference
4044 : // frame coincides with the origin of the whole stave.
4045 : // The TArrayD passed by reference will contain details of the shape:
4046 : // - sizes[0] = thickness
4047 : // - sizes[1] = length
4048 : // - sizes[2] = width
4049 : // - sizes[3] = common 'x' position for eventual clips
4050 : // - sizes[4] = common 'y' position for eventual clips
4051 : // - sizes[5] = 'z' position of first clip
4052 : // - sizes[6] = 'z' position of second clip
4053 : //
4054 :
4055 : // ** CHECK **
4056 :
4057 : // idxCentral and idxSide must be different
4058 40 : if (idxCentral == idxSide) {
4059 0 : AliInfo("Ladders must be inserted in half-stave with "
4060 : "different indexes.");
4061 0 : idxSide = idxCentral + 1;
4062 0 : AliInfo(Form("Central ladder will be inserted with index %d",
4063 : idxCentral));
4064 0 : AliInfo(Form("Side ladder will be inserted with index %d",idxSide));
4065 0 : } // end if
4066 :
4067 : // define the separations along Z direction between the objects
4068 40 : Double_t sepLadderLadder = fgkmm * 0.2; // sep. btw the 2 ladders
4069 40 : Double_t sepLadderCenter = fgkmm * 0.4; // sep. btw the "central" ladder
4070 : // and the Z=0 plane in stave ref.
4071 40 : Double_t sepLadderMCM = fgkmm * 0.3; // sep. btw the "external" ladder
4072 : // and MCM
4073 : Double_t sepBusCenter = fgkmm * 0.3; // sep. btw the bus central edge
4074 : // and the Z=0 plane in stave ref.
4075 :
4076 : // ** VOLUMES **
4077 :
4078 : // grounding foil
4079 40 : TArrayD grndSize(3);
4080 : // This one line repalces the 3 bellow, BNS.
4081 80 : TGeoVolume *grndVol = CreateGroundingFoil(isRight, grndSize, mgr);
4082 40 : Double_t &grndThickness = grndSize[0];
4083 40 : Double_t &grndLength = grndSize[1];
4084 :
4085 : // ladder
4086 40 : TArrayD ladderSize(3);
4087 40 : TGeoVolume *ladder = CreateLadder(layer, ladderSize, mgr);
4088 80 : Double_t ladderThickness = ladderSize[0];
4089 80 : Double_t ladderLength = ladderSize[1];
4090 80 : Double_t ladderWidth = ladderSize[2];
4091 :
4092 : // MCM
4093 40 : TArrayD mcmSize(3);
4094 40 : TGeoVolumeAssembly *mcm = CreateMCM(!isRight,mcmSize,mgr);
4095 80 : Double_t mcmThickness = mcmSize[0];
4096 80 : Double_t mcmLength = mcmSize[1];
4097 80 : Double_t mcmWidth = mcmSize[2];
4098 :
4099 : // bus
4100 40 : TArrayD busSize(6);
4101 40 : TGeoVolumeAssembly *bus = CreatePixelBus(isRight, layer, busSize, mgr);
4102 80 : Double_t busThickness = busSize[0];
4103 80 : Double_t busLength = busSize[1];
4104 80 : Double_t busWidth = busSize[2];
4105 :
4106 : // glue between ladders and pixel bus
4107 40 : TGeoMedium *medLadGlue = GetMedium("EPOXY$", mgr);
4108 40 : Double_t ladGlueThickness = fgkmm * 0.1175 - fgkGapLadder;
4109 40 : TGeoVolume *ladderGlue = mgr->MakeBox("ITSSPDladderGlue",medLadGlue,
4110 40 : 0.5*ladGlueThickness, 0.5*busWidth, 0.5*busLength);
4111 40 : ladderGlue->SetLineColor(kYellow + 5);
4112 :
4113 : // create references for the whole object, as usual
4114 40 : sizes.Set(7);
4115 40 : Double_t &fullThickness = sizes[0];
4116 40 : Double_t &fullLength = sizes[1];
4117 40 : Double_t &fullWidth = sizes[2];
4118 :
4119 : // compute the full size of the container
4120 80 : fullLength = sepLadderCenter+2.0*ladderLength+sepLadderMCM+
4121 40 : sepLadderLadder+mcmLength;
4122 40 : fullWidth = ladderWidth;
4123 40 : fullThickness = grndThickness + fgkGapLadder + mcmThickness + busThickness;
4124 : //cout << "HSTAVE FULL THICKNESS = " << fullThickness << endl;
4125 :
4126 : // ** MOVEMENTS **
4127 :
4128 : // grounding foil (shifted only along thickness)
4129 40 : Double_t xGrnd = -0.5*fullThickness + 0.5*grndThickness;
4130 40 : Double_t zGrnd = -0.5*grndLength;
4131 60 : if (!isRight) zGrnd = -zGrnd;
4132 80 : TGeoTranslation *grndTrans = new TGeoTranslation(xGrnd, 0.0, zGrnd);
4133 :
4134 : // ladders (translations along thickness and length)
4135 : // layers must be sorted going from the one at largest Z to the
4136 : // one at smallest Z:
4137 : // -|Zmax| ------> |Zmax|
4138 : // 3 2 1 0
4139 : // then, for layer 1 ladders they must be placed exactly this way,
4140 : // and in layer 2 at the opposite. In order to remember the placements,
4141 : // we define as "inner" and "outer" ladder respectively the one close
4142 : // to barrel center, and the one closer to MCM, respectively.
4143 : Double_t xLad, zLadIn, zLadOut;
4144 40 : xLad = xGrnd + 0.5*(grndThickness + ladderThickness) +
4145 40 : 0.01175 - fgkGapLadder;
4146 40 : zLadIn = -sepLadderCenter - 0.5*ladderLength;
4147 40 : zLadOut = zLadIn - sepLadderLadder - ladderLength;
4148 40 : if (!isRight) {
4149 20 : zLadIn = -zLadIn;
4150 20 : zLadOut = -zLadOut;
4151 20 : } // end if !isRight
4152 80 : TGeoRotation *rotLad = new TGeoRotation(*gGeoIdentity);
4153 40 : rotLad->RotateZ(90.0);
4154 40 : rotLad->RotateY(180.0);
4155 40 : Double_t sensWidth = fgkmm * 12.800;
4156 40 : Double_t chipWidth = fgkmm * 15.950;
4157 40 : Double_t guardRingWidth = fgkmm * 0.560;
4158 40 : Double_t ladderShift = 0.5 * (chipWidth - sensWidth - 2.0*guardRingWidth);
4159 80 : TGeoCombiTrans *trLadIn = new TGeoCombiTrans(xLad,ladderShift,zLadIn,
4160 : rotLad);
4161 80 : TGeoCombiTrans *trLadOut = new TGeoCombiTrans(xLad,ladderShift,zLadOut,
4162 : rotLad);
4163 :
4164 : // MCM (length and thickness direction, placing at same level as the
4165 : // ladder, which implies to recompute the position of center, because
4166 : // ladder and MCM have NOT the same thickness) the two copies of the
4167 : // MCM are placed at the same distance from the center, on both sides
4168 40 : Double_t xMCM = xGrnd + 0.5*grndThickness + 0.5*mcmThickness +
4169 40 : 0.01175 - fgkGapLadder;
4170 40 : Double_t yMCM = 0.5*(fullWidth - mcmWidth);
4171 40 : Double_t zMCM = zLadOut - 0.5*ladderLength - 0.5*mcmLength - sepLadderMCM;
4172 60 : if (!isRight) zMCM = zLadOut + 0.5*ladderLength + 0.5*mcmLength +
4173 : sepLadderMCM;
4174 :
4175 : // create the correction rotations
4176 80 : TGeoRotation *rotMCM = new TGeoRotation(*gGeoIdentity);
4177 40 : rotMCM->RotateY(90.0);
4178 80 : TGeoCombiTrans *trMCM = new TGeoCombiTrans(xMCM, yMCM, zMCM, rotMCM);
4179 :
4180 : // glue between ladders and pixel bus
4181 80 : Double_t xLadGlue = xLad + 0.5*ladderThickness + 0.01175 -
4182 80 : fgkGapLadder + 0.5*ladGlueThickness;
4183 :
4184 : // bus (length and thickness direction)
4185 40 : Double_t xBus = xLadGlue + 0.5*ladGlueThickness + 0.5*busThickness;
4186 40 : Double_t yBus = 0.5*(fullWidth - busWidth) + 0.075; // Hardcode fix of a small overlap
4187 40 : Double_t zBus = -0.5*busLength - sepBusCenter;
4188 60 : if (!isRight) zBus = -zBus;
4189 80 : TGeoTranslation *trBus = new TGeoTranslation(xBus, yBus, zBus);
4190 :
4191 80 : TGeoTranslation *trLadGlue = new TGeoTranslation(xLadGlue, 0.0, zBus);
4192 :
4193 : // create the container
4194 : TGeoVolumeAssembly *container = 0;
4195 40 : if (idxCentral+idxSide==5) {
4196 40 : container = new TGeoVolumeAssembly("ITSSPDhalf-Stave1");
4197 20 : } else {
4198 40 : container = new TGeoVolumeAssembly("ITSSPDhalf-Stave0");
4199 : } // end if
4200 :
4201 : // add to container all objects
4202 40 : container->AddNode(grndVol, 1, grndTrans);
4203 : // ladders are inserted in different order to respect numbering scheme
4204 : // which is inverted when going from outer to inner layer
4205 40 : container->AddNode(ladder, idxCentral+1, trLadIn);
4206 40 : container->AddNode(ladder, idxSide+1, trLadOut);
4207 40 : container->AddNode(ladderGlue, 1, trLadGlue);
4208 40 : container->AddNode(mcm, 1, trMCM);
4209 40 : container->AddNode(bus, 1, trBus);
4210 :
4211 : // since the clips are placed in correspondence of two pt1000s,
4212 : // their position is computed here, but they are not added by default
4213 : // it will be the StavesInSector method which will decide to add them
4214 : // anyway, to recovery some size informations on the clip, it must be
4215 : // created
4216 40 : TArrayD clipSize;
4217 : // TGeoVolume *clipDummy = CreateClip(clipSize, kTRUE, mgr);
4218 40 : CreateClip(clipSize, kTRUE, mgr);
4219 : // define clip movements (width direction)
4220 80 : sizes[3] = xBus + 0.5*busThickness;
4221 120 : sizes[4] = 0.5 * (fullWidth - busWidth) - clipSize[6] - fgkmm*0.26;
4222 120 : sizes[5] = zBus + busSize[4];
4223 120 : sizes[6] = zBus + busSize[5];
4224 :
4225 40 : container->GetShape()->ComputeBBox(); //RS: enforce recompting of BBox
4226 :
4227 : return container;
4228 40 : }
4229 : //______________________________________________________________________
4230 : TGeoVolumeAssembly* AliITSv11GeometrySPD::CreateStave(Int_t layer,
4231 : TArrayD &sizes, TGeoManager *mgr)
4232 : {
4233 : //
4234 : // This method uses all other ones which create pieces of the stave
4235 : // and assemblies everything together, in order to return the whole
4236 : // stave implementation, which is returned as a TGeoVolumeAssembly,
4237 : // due to the presence of some parts which could generate fake overlaps
4238 : // when put on the sector.
4239 : // This assembly contains, going from bottom to top in the thickness
4240 : // direction:
4241 : // - the complete grounding foil, defined by the "CreateGroundingFoil"
4242 : // method which already joins some glue and real groudning foil
4243 : // layers for the whole stave (left + right);
4244 : // - 4 ladders, which are sorted according to the ALICE numbering
4245 : // scheme, which depends on the layer we are building this stave for;
4246 : // - 2 MCMs (a left and a right one);
4247 : // - 2 pixel buses (a left and a right one);
4248 : // ---
4249 : // Arguments:
4250 : // - the layer number, which determines the displacement and naming
4251 : // of sensitive volumes
4252 : // - a TArrayD passed by reference which will contain the size
4253 : // of virtual box containing the stave
4254 : // - the TGeoManager
4255 : //
4256 :
4257 : // create the container
4258 60 : TGeoVolumeAssembly *container = new TGeoVolumeAssembly(Form(
4259 : "ITSSPDlay%d-Stave",layer));
4260 : // define the indexes of the ladders in order to have the correct order
4261 : // keeping in mind that the staves will be inserted as they are on layer
4262 : // 2, while they are rotated around their local Y axis when inserted
4263 : // on layer 1, so in this case they must be put in the "wrong" order
4264 : // to turn out to be right at the end. The convention is:
4265 : // -|Zmax| ------> |Zmax|
4266 : // 3 2 1 0
4267 : // with respect to the "native" stave reference frame, "left" is in
4268 : // the positive Z this leads the definition of these indexes:
4269 : Int_t idxCentralL, idxSideL, idxCentralR, idxSideR;
4270 :
4271 20 : if (layer == 1) {
4272 : idxSideL = 3;
4273 : idxCentralL = 2;
4274 : idxCentralR = 1;
4275 : idxSideR = 0;
4276 10 : } else {
4277 : idxSideL = 0;
4278 : idxCentralL = 1;
4279 : idxCentralR = 2;
4280 : idxSideR = 3;
4281 : } // end if layer ==1
4282 :
4283 : // create the two half-staves
4284 20 : TArrayD sizeL, sizeR;
4285 20 : TGeoVolumeAssembly *hstaveL = CreateHalfStave(kFALSE, layer, idxCentralL,
4286 : idxSideL, sizeL,mgr);
4287 20 : TGeoVolumeAssembly *hstaveR = CreateHalfStave(kTRUE, layer, idxCentralR,
4288 : idxSideR, sizeR, mgr);
4289 : // copy the size to the stave's one
4290 20 : sizes.Set(9);
4291 60 : sizes[0] = sizeL[0];
4292 80 : sizes[1] = sizeR[1] + sizeL[1];
4293 60 : sizes[2] = sizeL[2];
4294 60 : sizes[3] = sizeL[3];
4295 60 : sizes[4] = sizeL[4];
4296 60 : sizes[5] = sizeL[5];
4297 60 : sizes[6] = sizeL[6];
4298 60 : sizes[7] = sizeR[5];
4299 60 : sizes[8] = sizeR[6];
4300 :
4301 : // add to container all objects
4302 20 : container->AddNode(hstaveL, 1);
4303 20 : container->AddNode(hstaveR, 1);
4304 :
4305 20 : container->GetShape()->ComputeBBox(); //RS: enforce recompting of BBox
4306 : return container;
4307 20 : }
4308 : //______________________________________________________________________
4309 : void AliITSv11GeometrySPD::SetAddStave(Bool_t *mask)
4310 : {
4311 : //
4312 : // Define a mask which states qhich staves must be placed.
4313 : // It is a string which must contain '0' or '1' depending if
4314 : // a stave must be placed or not.
4315 : // Each place is referred to one of the staves, so the first
4316 : // six characters of the string will be checked.
4317 : //
4318 : Int_t i;
4319 :
4320 0 : for (i = 0; i < 6; i++) fAddStave[i] = mask[i];
4321 0 : }
4322 : //______________________________________________________________________
4323 : void AliITSv11GeometrySPD::StavesInSector(TGeoVolume *moth, TGeoManager *mgr)
4324 : {
4325 : //
4326 : // Unification of essentially two methods:
4327 : // - the one which creates the sector structure
4328 : // - the one which returns the complete stave
4329 : // ---
4330 : // For compatibility, this method requires the same arguments
4331 : // asked by "CarbonFiberSector" method, which is recalled here.
4332 : // Like this cited method, this one does not return any value,
4333 : // but it inserts in the mother volume (argument 'moth') all the stuff
4334 : // which composes the complete SPD sector.
4335 : // ---
4336 : // In the following, the stave numbering order used for arrays is the
4337 : // same as defined in the GetSectorMountingPoints():
4338 : // /5
4339 : // /\/4
4340 : // 1\ \/3
4341 : // 0|___\/2
4342 : // ---
4343 : // Arguments: see description of "CarbonFiberSector" method.
4344 : //
4345 :
4346 20 : Double_t shift[6]; // shift from the innermost position in the
4347 : // sector placement plane (where the stave
4348 : // edge is in the point where the rounded
4349 : // corner begins)
4350 :
4351 10 : shift[0] = fgkmm * -0.691;
4352 10 : shift[1] = fgkmm * 5.041;
4353 10 : shift[2] = fgkmm * 1.816;
4354 10 : shift[3] = fgkmm * -0.610;
4355 10 : shift[4] = fgkmm * -0.610;
4356 10 : shift[5] = fgkmm * -0.610;
4357 :
4358 : // corrections after interaction with Andrea and CAD
4359 10 : Double_t corrX[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
4360 10 : Double_t corrY[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
4361 :
4362 10 : corrX[0] = 0.0046;
4363 10 : corrX[1] = -0.0041;
4364 10 : corrX[2] = corrX[3] = corrX[4] = corrX[5] = -0.0016;
4365 :
4366 10 : corrY[0] = -0.0007;
4367 10 : corrY[1] = -0.0009;
4368 10 : corrY[2] = corrY[3] = corrY[4] = corrY[5] = -0.0003;
4369 :
4370 10 : corrX[0] += 0.00026;
4371 10 : corrY[0] += -0.00080;
4372 :
4373 10 : corrX[1] += 0.00018;
4374 10 : corrY[1] += -0.00086;
4375 :
4376 10 : corrX[2] += 0.00020;
4377 10 : corrY[2] += -0.00062;
4378 :
4379 10 : corrX[3] += 0.00017;
4380 10 : corrY[3] += -0.00076;
4381 :
4382 10 : corrX[4] += 0.00016;
4383 10 : corrY[4] += -0.00096;
4384 :
4385 10 : corrX[5] += 0.00018;
4386 10 : corrY[5] += -0.00107;
4387 :
4388 : // create stave volumes (different for layer 1 and 2)
4389 20 : TArrayD staveSizes1(9), staveSizes2(9), clipSize(5);
4390 20 : Double_t &staveHeight = staveSizes1[2], &staveThickness = staveSizes1[0];
4391 20 : TGeoVolume *stave1 = CreateStave(1, staveSizes1, mgr);
4392 20 : TGeoVolume *stave2 = CreateStave(2, staveSizes2, mgr);
4393 10 : TGeoVolume *clip = CreateClip(clipSize, kFALSE, mgr);
4394 :
4395 10 : Double_t xL, yL; // leftmost edge of mounting point (XY projection)
4396 10 : Double_t xR, yR; // rightmost edge of mounting point (XY projection)
4397 : Double_t xM, yM; // middle point of the segment L-R
4398 : Double_t dx, dy; // (xL - xR) and (yL - yR)
4399 : Double_t widthLR; // width of the segment L-R
4400 : Double_t angle; // stave rotation angle in degrees
4401 : Double_t diffWidth; // difference between mounting plane width and
4402 : // stave width (smaller)
4403 10 : Double_t xPos, yPos; // final translation of the stave
4404 : Double_t parMovement; // translation in the LR plane direction
4405 :
4406 10 : staveThickness += fgkGapHalfStave;
4407 :
4408 : // loop on staves
4409 : Int_t i, iclip = 1;
4410 140 : for (i = 0; i < 6; i++) {
4411 : // in debug mode, if this stave is not required, it is skipped
4412 60 : if (!fAddStave[i]) continue;
4413 : // retrieve reference points
4414 60 : GetSectorMountingPoints(i, xL, yL, xR, yR);
4415 60 : xM = 0.5 * (xL + xR);
4416 60 : yM = 0.5 * (yL + yR);
4417 60 : dx = xL - xR;
4418 60 : dy = yL - yR;
4419 60 : angle = TMath::ATan2(dy, dx);
4420 60 : widthLR = TMath::Sqrt(dx*dx + dy*dy);
4421 60 : diffWidth = 0.5*(widthLR - staveHeight);
4422 : // first, a movement along this plane must be done
4423 : // by an amount equal to the width difference
4424 : // and then the fixed shift must also be added
4425 60 : parMovement = diffWidth + shift[i];
4426 : // due to stave thickness, another movement must be done
4427 : // in the direction normal to the mounting plane
4428 : // which is computed using an internal method, in a reference
4429 : // frame where the LR segment has its middle point in the origin
4430 : // and axes parallel to the master reference frame
4431 60 : if (i == 0) {
4432 10 : ParallelPosition(-0.5*staveThickness, -parMovement, angle,
4433 : xPos, yPos);
4434 : } // end if i==0
4435 120 : if (i == 1) {
4436 70 : ParallelPosition( 0.5*staveThickness, -parMovement, angle,
4437 : xPos, yPos);
4438 : }else {
4439 50 : ParallelPosition( 0.5*staveThickness, parMovement, angle,
4440 : xPos, yPos);
4441 : } // end if i==1
4442 : // then we go into the true reference frame
4443 60 : xPos += xM;
4444 60 : yPos += yM;
4445 60 : xPos += corrX[i];
4446 60 : yPos += corrY[i];
4447 : // using the parameters found here, compute the
4448 : // translation and rotation of this stave:
4449 120 : TGeoRotation *rot = new TGeoRotation(*gGeoIdentity);
4450 80 : if (i == 0 || i == 1) rot->RotateX(180.0);
4451 120 : rot->RotateZ(90.0 + angle * TMath::RadToDeg());
4452 120 : TGeoCombiTrans *trans = new TGeoCombiTrans(xPos, yPos, 0.0, rot);
4453 60 : if (i == 0 || i == 1) {
4454 80 : moth->AddNode(stave1, i+1, trans);
4455 : }else {
4456 40 : moth->AddNode(stave2, i - 1, trans);
4457 40 : if (i != 2) {
4458 : // except in the case of stave #2,
4459 : // clips must be added, and this is done directly on the sector
4460 : Int_t j;
4461 : //TArrayD clipSize;
4462 60 : TGeoRotation *rotClip = new TGeoRotation(*gGeoIdentity);
4463 30 : rotClip->RotateZ(-90.0);
4464 30 : rotClip->RotateX(180.0);
4465 60 : Double_t x = staveSizes2[3] + fgkGapHalfStave;
4466 60 : Double_t y = staveSizes2[4];
4467 150 : Double_t z[4] = { staveSizes2[5], staveSizes2[6],
4468 120 : staveSizes2[7], staveSizes2[8] };
4469 300 : for (j = 0; j < 4; j++) {
4470 240 : TGeoCombiTrans *trClip = new TGeoCombiTrans(x, y, z[j],
4471 : rotClip);
4472 240 : *trClip = *trans * *trClip;
4473 120 : moth->AddNode(clip, iclip++, trClip);
4474 : } // end for j
4475 30 : } // end if i!=2
4476 : } // end if i==0||i==1 else
4477 60 : } // end for i
4478 :
4479 :
4480 : // Add a box representing the collector for cooling tubes
4481 : // MOVED TO CreateServices() - M.S. 25 jul 12
4482 :
4483 10 : }
4484 : //______________________________________________________________________
4485 : void AliITSv11GeometrySPD::ParallelPosition(Double_t dist1, Double_t dist2,
4486 : Double_t phi, Double_t &x, Double_t &y) const
4487 : {
4488 : //
4489 : // Performs the following steps:
4490 : // 1 - finds a straight line parallel to the one passing through
4491 : // the origin and with angle 'phi' with X axis(phi in RADIANS);
4492 : // 2 - finds another line parallel to the previous one, with a
4493 : // distance 'dist1' from it
4494 : // 3 - takes a reference point in the second line in the intersection
4495 : // between the normal to both lines passing through the origin
4496 : // 4 - finds a point whith has distance 'dist2' from this reference,
4497 : // in the second line (point 2)
4498 : // ----
4499 : // According to the signs given to dist1 and dist2, the point is
4500 : // found in different position w.r. to the origin
4501 : // compute the point
4502 : //
4503 140 : Double_t cs = TMath::Cos(phi);
4504 70 : Double_t sn = TMath::Sin(phi);
4505 :
4506 70 : x = dist2*cs - dist1*sn;
4507 70 : y = dist1*cs + dist2*sn;
4508 70 : }
4509 : //______________________________________________________________________
4510 : Double_t AliITSv11GeometrySPD::GetSPDSectorTranslation(
4511 : Double_t x0,Double_t y0,Double_t x1,Double_t y1,Double_t r) const
4512 : {
4513 : //
4514 : // Comutes the radial translation of a sector to give the
4515 : // proper distance between SPD detectors and the beam pipe.
4516 : // Units in are units out.
4517 : //
4518 :
4519 : //Begin_Html
4520 : /*
4521 : <A HREF="http://www.physics.ohio-state.edu/HIRG/SoftWareDoc/SPD_Sector_Position.png">
4522 : Figure showing the geometry used in the computation below. </A>
4523 : */
4524 : //End_Html
4525 :
4526 : // Inputs:
4527 : // Double_t x0 Point x0 on Sector surface for the inner
4528 : // most detector mounting
4529 : // Double_t y0 Point y0 on Sector surface for the innor
4530 : // most detector mounting
4531 : // Double_t x1 Point x1 on Sector surface for the inner
4532 : // most detector mounting
4533 : // Double_t y1 Point y1 on Sector surface for the innor
4534 : // most detector mounting
4535 : // Double_t r The radial distance this mounting surface
4536 : // should be from the center of the beam pipe.
4537 : // Outputs:
4538 : // none.
4539 : // Return:
4540 : // The distance the SPD sector should be displaced radialy.
4541 : //
4542 : Double_t a,b,c;
4543 :
4544 2 : a = x0-x1;
4545 1 : if(a==0.0) return 0.0;
4546 1 : a = (y0-y1)/a;
4547 1 : b = TMath::Sqrt(1.0+a*a);
4548 1 : c = y0-a*x0-r*b;
4549 1 : return -c;
4550 1 : }
4551 :
4552 : //______________________________________________________________________
4553 : void AliITSv11GeometrySPD::PrintAscii(ostream *os) const
4554 : {
4555 : //
4556 : // Print out class data values in Ascii Form to output stream
4557 : // Inputs:
4558 : // ostream *os Output stream where Ascii data is to be writen
4559 : // Outputs:
4560 : // none.
4561 : // Return:
4562 : // none.
4563 : //
4564 : Int_t i,j,k;
4565 : #if defined __GNUC__
4566 : #if __GNUC__ > 2
4567 0 : ios::fmtflags fmt = cout.flags();
4568 : #else
4569 : Int_t fmt;
4570 : #endif
4571 : #else
4572 : #if defined __ICC || defined __ECC || defined __xlC__
4573 : ios::fmtflags fmt;
4574 : #else
4575 : Int_t fmt;
4576 : #endif
4577 : #endif
4578 :
4579 0 : *os<< fgkGapLadder <<" "<< fgkGapHalfStave<<" "<< 6 <<" ";
4580 0 : for(i=0;i<6;i++) *os<< fAddStave[i] <<" "<<fSPDsectorX0.GetSize();
4581 0 : for(i=0;i<fSPDsectorX0.GetSize();i++) *os<< fSPDsectorX0.GetAt(i) << " ";
4582 0 : for(i=0;i<fSPDsectorX0.GetSize();i++) *os<< fSPDsectorY0.GetAt(i) << " ";
4583 0 : for(i=0;i<fSPDsectorX1.GetSize();i++) *os<< fSPDsectorX1.GetAt(i) << " ";
4584 0 : for(i=0;i<fSPDsectorX1.GetSize();i++) *os<< fSPDsectorY1.GetAt(i) << " ";
4585 0 : *os<<10<<" "<< 2 <<" " << 6 << " "<< 3 <<" ";
4586 0 : for(k=0;k<10;k++)for(i=0;i<6;i++)for(j=0;j<3;j++)
4587 0 : *os<<fTubeEndSector[k][0][i][j]<<" ";
4588 0 : for(k=0;k<10;k++)for(i=0;i<6;i++)for(j=0;j<3;j++)
4589 0 : *os<<fTubeEndSector[k][1][i][j]<<" ";
4590 0 : os->flags(fmt); // reset back to old Formating.
4591 : return;
4592 0 : }
4593 : //
4594 : //______________________________________________________________________
4595 : void AliITSv11GeometrySPD::ReadAscii(istream* is)
4596 : {
4597 : //
4598 : // Read in class data values in Ascii Form to output stream
4599 : // Inputs:
4600 : // istream *is Input stream where Ascii data is to be read in from
4601 : // Outputs:
4602 : // none.
4603 : // Return:
4604 : // none.
4605 : //
4606 0 : Int_t i,j,k,n;
4607 0 : Double_t gapLadder,gapHalfStave;
4608 : const Int_t kLimits = 100;
4609 0 : *is>>gapLadder>>gapHalfStave>>n;
4610 0 : if(n!=6){
4611 0 : AliError(Form("fAddStave Array !=6 n=%d",n));
4612 0 : return;
4613 : } // end if
4614 0 : for(i=0;i<n;i++) *is>>fAddStave[i];
4615 0 : *is>>n;
4616 0 : if(n<0 || n> kLimits){
4617 0 : AliError("Anomalous value for parameter n");
4618 0 : return;
4619 : }
4620 0 : fSPDsectorX0.Set(n);
4621 0 : fSPDsectorY0.Set(n);
4622 0 : fSPDsectorX1.Set(n);
4623 0 : fSPDsectorY1.Set(n);
4624 0 : for(i=0;i<n;i++) *is>>fSPDsectorX0[i];
4625 0 : for(i=0;i<n;i++) *is>>fSPDsectorY0[i];
4626 0 : for(i=0;i<n;i++) *is>>fSPDsectorX1[i];
4627 0 : for(i=0;i<n;i++) *is>>fSPDsectorY1[i];
4628 0 : *is>> i>>j>>n;
4629 0 : if(i!=2||j!=6||n!=3){
4630 0 : Warning("ReadAscii","fTubeEndSector array wrong size [2][6][3],"
4631 : "found [%d][%d][%d]",i,j,n);
4632 0 : return;
4633 : } // end if
4634 0 : for(k=0;k<10;k++)for(i=0;i<6;i++)for(j=0;j<3;j++)
4635 0 : *is>>fTubeEndSector[k][0][i][j];
4636 0 : for(k=0;k<10;k++)for(i=0;i<6;i++)for(j=0;j<3;j++)
4637 0 : *is>>fTubeEndSector[k][1][i][j];
4638 0 : return;
4639 0 : }
4640 : //
4641 : //______________________________________________________________________
4642 : ostream &operator<<(ostream &os,const AliITSv11GeometrySPD &s)
4643 : {
4644 : //
4645 : // Standard output streaming function
4646 : // Inputs:
4647 : // ostream &os output steam
4648 : // AliITSvPPRasymmFMD &s class to be streamed.
4649 : // Output:
4650 : // none.
4651 : // Return:
4652 : // ostream &os The stream pointer
4653 : //
4654 0 : s.PrintAscii(&os);
4655 0 : return os;
4656 : }
4657 : //
4658 : //______________________________________________________________________
4659 : istream &operator>>(istream &is,AliITSv11GeometrySPD &s)
4660 : {
4661 : //
4662 : // Standard inputput streaming function
4663 : // Inputs:
4664 : // istream &is input steam
4665 : // AliITSvPPRasymmFMD &s class to be streamed.
4666 : // Output:
4667 : // none.
4668 : // Return:
4669 : // ostream &os The stream pointer
4670 : //
4671 0 : s.ReadAscii(&is);
4672 0 : return is;
4673 : }
4674 :
|