]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSv11GeometrySPD.cxx
Small correction on distance between bellows.
[u/mrichter/AliRoot.git] / ITS / AliITSv11GeometrySPD.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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 ceneteral volume (except for the Ceneteral support 
18 // cylinders. Other classes define the rest of the ITS. Specificaly the ITS
19 // The SSD support cone,SSD Support centeral cylinder, SDD support cone,
20 // The SDD cupport centeral cylinder, the SPD Thermal Sheald, 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 /* $Id$ */
25 // General Root includes
26 #include <Riostream.h>
27 #include <TMath.h>
28 #include <TLatex.h>
29 #include <TCanvas.h>
30 #include <TView.h>
31 #include <TPolyLine.h>
32 // Root Geometry includes
33 #include <TGeoManager.h>
34 #include <TGeoVolume.h>
35 #include <TGeoPcon.h>
36 #include <TGeoCone.h>
37 #include <TGeoTube.h> // contaings TGeoTubeSeg
38 #include <TGeoArb8.h>
39 #include <TGeoEltu.h>
40 #include <TGeoXtru.h>
41 #include <TGeoCompositeShape.h>
42 #include <TGeoMatrix.h>
43 #include "AliITSv11GeometrySPD.h"
44
45 ClassImp(AliITSv11GeometrySPD)
46
47 #define SQ(A) (A)*(A)
48
49 //______________________________________________________________________
50 AliITSv11GeometrySPD::AliITSv11GeometrySPD() : 
51 AliITSv11Geometry(),
52 fSPDSensitiveVolumeName("ITSSPDDetectorSensitiveVolume"),
53 fThickDetector(0.0),
54 fThickChip(0.0){
55     // Default Constructor for the AliITSv11GeometrySPD
56     // Inputs:
57     //   none.
58     // Outputs:
59     //   none.
60     // Return:
61     //   One Default Constructed AliITSv11GeometrySPD class
62
63     fThickDetector = fkLadDetectorThick;
64     fThickChip     = fkLadChipHight;
65 }
66 //______________________________________________________________________
67 AliITSv11GeometrySPD::AliITSv11GeometrySPD(Int_t debug) : 
68 AliITSv11Geometry(debug),
69 fSPDSensitiveVolumeName("ITSSPDDetectorSensitiveVolume"),
70 fThickDetector(0.0),
71 fThickChip(0.0),
72 fkGrdFoilThick(0.05*fgkmm),
73 fkGrdFoilWidthA(15.95*fgkmm),
74 fkGrdFoilWidthC(4.4*fgkmm),
75 fkGrdFoilLngA(139.89*fgkmm),
76 fkGrdFoilLngB(11.55*fgkmm),
77 fkGrdFoilLngC(82.0*fgkmm),
78 fkGrdFoilNholesAB(5),
79 fkGrdFoilHoleCenterAB(7.8*fgkmm),
80 fkGrdFoilHoleLengthAB(12.0*fgkmm),
81 fkGrdFoilHoleWidthAB(7.5*fgkmm),
82 fkGrdFoilHoleSpacingAB(14.0*fgkmm),
83 fkGrdFoilHoleStartA(1.36*fgkmm),
84 fkGrdFoilHoleStartB(73.08*fgkmm),
85  // Ladder
86 fkLadNChips(5),
87 fkLadChipWidth(15950.0*fgkmicron),
88 fkLadChipHight(150.0*fgkmicron),
89 fkLadChipLength(13490.0*fgkmicron),
90 fkLadGlue0Thick(0.100*fgkmm),
91 fkLadBumpBondThick(30.0*fgkmicron),
92 fkLadDetectorWidth(13700.0*fgkmicron),
93 fkLadDetectorThick(200.0*fgkmicron),
94 fkLadDetectorLength(70710.0*fgkmicron),
95 fkLadSensDetWidth(12800.0*fgkmicron),
96 fkLadSensDetThick(200.0*fgkmicron),
97 fkLadSensDetLength(69490.0*fgkmicron),
98 fkLadChipSpacing0(610.0*fgkmicron),
99 fkLadChipSpacing1((fkLadDetectorLength-(2.*fkLadChipSpacing0+
100         ((Double_t)fkLadNChips)*fkLadChipLength))/((Double_t)(fkLadNChips-1)))
101 {
102     // Default Constructor for the AliITSv11GeometrySPD
103     // Inputs:
104     //   none.
105     // Outputs:
106     //   none.
107     // Return:
108     //   One Default Constructed AliITSv11GeometrySPD class
109
110     fThickDetector = fkLadDetectorThick;
111     fThickChip     = fkLadChipHight;
112 }
113 //______________________________________________________________________
114 TGeoVolume* AliITSv11GeometrySPD::CenteralSPD(TGeoVolume *moth){
115     // Define The Centeral part of the SPD detector.
116     // Inputs:
117     //   TGeoVolume* moth
118     // Outputs:
119     //  none.
120     // Return:
121     //  TGeoVolume * moth
122     Int_t i=2;
123     TGeoVolume *vHSGF,*vLad,*vMoth;
124     TGeoTube *tube;
125
126     tube = new TGeoTube("ITSSPD Temp SPD Mother voluem",0.0,7.0,17.0);
127     vMoth = new TGeoVolume("ITSSPDTempSPDMotherVolume",tube,0);
128
129     moth->AddNode(vMoth,1,0);
130     switch(i){
131     case 0:
132         CarbonFiberSector(vMoth);
133         break;
134     case 1:
135         vHSGF = CreateHalfStaveGroundFoil();
136         vMoth->AddNode(vHSGF,1,0);
137         break;
138     case 2:
139         vLad  = CreateSPDLadder();
140         vMoth->AddNode(vLad,1,0);
141         break;
142     } // end sithch
143
144     return moth;
145 }
146 //______________________________________________________________________
147 TGeoVolume* AliITSv11GeometrySPD::CarbonFiberSector(TGeoVolume *moth){
148     // Define the detail SPD Carbon fiber support Sector geometry.
149     // Based on the drawings ALICE-Pixel "Construzione Profilo Modulo"
150     // March 25 2004 and ALICE-SUPPORTO "construzione Profilo Modulo"
151     // Define Outside radii as negitive, Outside in the sence that the
152     // center of the arc is outside of the object.
153     // February 16 2004.
154     // Inputs:
155     //   TGeoVolume* moth   The mother volume which this object is to be
156     //                      placed in
157     // Outputs:
158     //  none.
159     // Return:
160     //  TGeoVolume*
161     TGeoManager *mgr = gGeoManager;
162     TGeoMedium *medSPDcf  = 0; // SPD support cone Carbon Fiber materal number.
163     //TGeoMedium *medSPDfs  = 0; // SPD support cone inserto stesalite 4411w.
164     //TGeoMedium *medSPDfo  = 0; // SPD support cone foam, Rohacell 50A.
165     TGeoMedium *medSPDss  = 0; // SPD support cone screw material,Stainless
166     TGeoMedium *medSPDair = 0; // SPD support cone Air
167     //TGeoMedium *medSPDal  = 0; // SPD support cone SDD mounting bracket Al
168     TGeoMedium *medSPDcoolfl  = 0; // SPD cooling fluid, Freeon
169     medSPDcf = mgr->GetMedium("ITSspdCarbonFiber");
170     //medSPDfs = mgr->GetMedium("ITSspdStaselite4411w");
171     //medSPDfo = mgr->GetMedium("ITSspdRohacell50A");
172     medSPDss = mgr->GetMedium("ITSspdStainlessSteal");
173     medSPDair= mgr->GetMedium("ITSspdAir");
174     medSPDcoolfl= mgr->GetMedium("ITSspdCoolingFluid");
175     //
176     const Double_t ksecDz        = 0.5*500.0*fgkmm;
177     const Double_t ksecLen       = 30.0*fgkmm;
178     const Double_t ksecCthick    = 0.20*fgkmm;
179     const Double_t ksecDipLength = 3.2*fgkmm;
180     const Double_t ksecDipRadii  = 0.4*fgkmm;
181     //const Double_t ksecCoolingTubeExtraDepth = 0.86*fgkmm;
182     //
183     const Double_t ksecX0   = -10.725*fgkmm;
184     const Double_t ksecY0   = -14.853*fgkmm;
185     const Double_t ksecR0   = -0.8*fgkmm; // Outside
186     const Double_t ksecX1   = -13.187*fgkmm;
187     const Double_t ksecY1   = -19.964*fgkmm;
188     const Double_t ksecR1   = +0.6*fgkmm; // Inside
189     //const Double_t ksecDip0 = 5.9*fgkmm;
190     //
191     const Double_t ksecX2   = -3.883*fgkmm;
192     const Double_t ksecY2   = -17.805*fgkmm;
193     const Double_t ksecR2   = +0.80*fgkmm; // Inside Guess. 
194     const Double_t ksecX3   = -3.123*fgkmm;
195     const Double_t ksecY3   = -14.618*fgkmm;
196     const Double_t ksecR3   = -0.6*fgkmm; // Outside
197     //const Double_t ksecDip1 = 8.035*fgkmm;
198     //
199     const Double_t ksecX4   = +11.280*fgkmm;
200     const Double_t ksecY4   = -14.473*fgkmm;
201     const Double_t ksecR4   = +0.8*fgkmm; // Inside
202     const Double_t ksecX5   = +19.544*fgkmm;
203     const Double_t ksecY5   = +10.961*fgkmm;
204     const Double_t ksecR5   = +0.8*fgkmm; // Inside
205     //const Double_t ksecDip2 = 4.553*fgkmm;
206     //
207     const Double_t ksecX6   = +10.830*fgkmm;
208     const Double_t ksecY6   = +16.858*fgkmm;
209     const Double_t ksecR6   = +0.6*fgkmm; // Inside
210     const Double_t ksecX7   = +11.581*fgkmm;
211     const Double_t ksecY7   = +13.317*fgkmm;
212     const Double_t ksecR7   = -0.6*fgkmm; // Outside
213     //const Double_t ksecDip3 = 6.978*fgkmm;
214     //
215     const Double_t ksecX8   = -0.733*fgkmm;
216     const Double_t ksecY8   = +17.486*fgkmm;
217     const Double_t ksecR8   = +0.6*fgkmm; // Inside
218     const Double_t ksecX9   = +0.562*fgkmm;
219     const Double_t ksecY9   = +14.486*fgkmm;
220     const Double_t ksecR9   = -0.6*fgkmm; // Outside
221     //const Double_t ksecDip4 = 6.978*fgkmm;
222     //
223     const Double_t ksecX10  = -12.252*fgkmm;
224     const Double_t ksecY10  = +16.298*fgkmm;
225     const Double_t ksecR10  = +0.6*fgkmm; // Inside
226     const Double_t ksecX11  = -10.445*fgkmm;
227     const Double_t ksecY11  = +13.162*fgkmm;
228     const Double_t ksecR11  = -0.6*fgkmm; // Outside
229     //const Double_t ksecDip5 = 6.978*fgkmm;
230     //
231     const Double_t ksecX12  = -22.276*fgkmm;
232     const Double_t ksecY12  = +12.948*fgkmm;
233     const Double_t ksecR12  = +0.85*fgkmm; // Inside
234     //const Double_t ksecX13 = *fgkmm;
235     //const Double_t ksecY13 = *fgkmm;
236     const Double_t ksecR13  = -0.8*fgkmm; // Outside
237     const Double_t ksecAngleSide13 = 36.0*fgkDegree;
238     //
239     const Int_t ksecNRadii = 20;
240     const Int_t ksecNPointsPerRadii = 4;
241     const Int_t ksecNCoolingTubeDips = 6;
242     // Since the Rounded parts are aproximated by a regular polygon and
243     // a cooling tube of the propper diameter must fit, a scaling factor
244     // increases the size of the polygon for the tube to fit.
245     //const Double_t ksecRCoolScale = 1./TMath::Cos(TMath::Pi()/
246     //                                          (Double_t)ksecNPointsPerRadii);
247     const Double_t ksecZEndLen  = 30.00*fgkmm;
248     //const Double_t ksecZFlangLen= 45.00*fgkmm;
249     const Double_t ksecTl       = 0.860*fgkmm;
250     const Double_t ksecCthick2  = 0.600*fgkmm;
251     //const Double_t ksecCthick3  = 1.800*fgkmm;
252     //const Double_t ksecSidelen  = 22.00*fgkmm;
253     //const Double_t ksecSideD5   = 3.679*fgkmm;
254     //const Double_t ksecSideD12  = 7.066*fgkmm;
255     const Double_t ksecRCoolOut = 2.400*fgkmm;
256     const Double_t ksecRCoolIn  = 2.000*fgkmm;
257     const Double_t ksecDl1      = 5.900*fgkmm;
258     const Double_t ksecDl2      = 8.035*fgkmm;
259     const Double_t ksecDl3      = 4.553*fgkmm;
260     const Double_t ksecDl4      = 6.978*fgkmm;
261     const Double_t ksecDl5      = 6.978*fgkmm;
262     const Double_t ksecDl6      = 6.978*fgkmm;
263     const Double_t ksecCoolTubeThick  = 0.04*fgkmm;
264     const Double_t ksecCoolTubeROuter = 2.6*fgkmm;
265     const Double_t ksecCoolTubeFlatX  = 3.696*fgkmm;
266     const Double_t ksecCoolTubeFlatY  = 0.68*fgkmm;
267     //const Double_t ksecBeamX0   = 0.0*fgkmm; // guess
268     //const Double_t ksecBeamY0   = (15.223+40.)*fgkmm; // guess
269     //
270     const Int_t ksecNPoints = (ksecNPointsPerRadii+1)*ksecNRadii + 8;
271     Double_t secX[ksecNRadii] = {ksecX0,ksecX1,-1000.0,ksecX2 ,ksecX3 ,-1000.0,
272                                  ksecX4,ksecX5,-1000.0,ksecX6 ,ksecX7 ,-1000.0,
273                                  ksecX8,ksecX9,-1000.0,ksecX10,ksecX11,-1000.0,
274                                  ksecX12,-1000.0};
275     Double_t secY[ksecNRadii] = {ksecY0,ksecY1,-1000.0,ksecY2 ,ksecY3 ,-1000.0,
276                                  ksecY4,ksecY5,-1000.0,ksecY6 ,ksecY7 ,-1000.0,
277                                  ksecY8,ksecY9,-1000.0,ksecY10,ksecY11,-1000.0,
278                                  ksecY12,-1000.0};
279     Double_t secR[ksecNRadii] ={ksecR0 ,ksecR1 ,-.5*ksecDipLength-ksecDipRadii,
280                                 ksecR2 ,ksecR3 ,-.5*ksecDipLength-ksecDipRadii,
281                                 ksecR4 ,ksecR5 ,-.5*ksecDipLength-ksecDipRadii,
282                                 ksecR6 ,ksecR7 ,-.5*ksecDipLength-ksecDipRadii,
283                                 ksecR8 ,ksecR9 ,-.5*ksecDipLength-ksecDipRadii,
284                                 ksecR10,ksecR11,-.5*ksecDipLength-ksecDipRadii,
285                                 ksecR12,ksecR13};/*
286     Double_t secDip[ksecNRadii]={0.0,0.0,ksecDip0,0.0,0.0,ksecDip1,
287                                  0.0,0.0,ksecDip2,0.0,0.0,ksecDip3,
288                                  0.0,0.0,ksecDip4,0.0,0.0,ksecDip5,
289                                  0.0,0.0};*/
290     Double_t secX2[ksecNRadii];
291     Double_t secY2[ksecNRadii];
292     Double_t secR2[ksecNRadii] = {
293         ksecR0,ksecR1,ksecRCoolOut,ksecR2,ksecR3,ksecRCoolOut,ksecR4,ksecR5,
294         ksecRCoolOut,ksecR6,ksecR7,ksecRCoolOut,ksecR8,ksecR9,ksecRCoolOut,
295         ksecR10,ksecR11,ksecRCoolOut,ksecR12,ksecR13};
296     Double_t secDip2[ksecNCoolingTubeDips]={ksecDl1,ksecDl2,ksecDl3,
297                                             ksecDl4,ksecDl5,ksecDl6};
298     Double_t secX3[ksecNRadii];
299     Double_t secY3[ksecNRadii];
300     const Int_t ksecDipIndex[ksecNCoolingTubeDips] = {2,5,8,11,14,17};
301     Double_t secAngleStart[ksecNRadii];
302     Double_t secAngleEnd[ksecNRadii];
303     Double_t secAngleStart2[ksecNRadii];
304     Double_t secAngleEnd2[ksecNRadii];
305     Double_t secAngleTurbo[ksecNCoolingTubeDips] = {0.0,0.0,0.0,0.0,0.0,0.0};
306     //Double_t secAngleStart3[ksecNRadii];
307     //Double_t secAngleEnd3[ksecNRadii];
308     Double_t xpp[ksecNPoints],ypp[ksecNPoints];
309     Double_t xpp2[ksecNPoints],ypp2[ksecNPoints];
310     Double_t *xp[ksecNRadii],*xp2[ksecNRadii];
311     Double_t *yp[ksecNRadii],*yp2[ksecNRadii];
312     TGeoXtru *sA0,*sA1,*sB0,*sB1;
313     TGeoEltu *sTA0,*sTA1;
314     TGeoTube *sTB0,*sTB1,*sM0;
315     TGeoRotation    *rot;
316     TGeoTranslation *trans;
317     TGeoCombiTrans  *rotrans;
318     Double_t t,t0,t1,a,b,x0,y0,x1,y1;
319     Int_t i,j,k,m;
320     Bool_t tst;
321
322     if(moth==0){
323         Error("CarbonFiberSector","moth=%p",moth);
324         return moth;
325     } // end if moth==0
326     //SetDebug(3);
327     for(i=0;i<ksecNRadii;i++){
328         xp[i]  = &(xpp[i*(ksecNPointsPerRadii+1)]);
329         yp[i]  = &(ypp[i*(ksecNPointsPerRadii+1)]);
330         xp2[i] = &(xpp2[i*(ksecNPointsPerRadii+1)]);
331         yp2[i] = &(ypp2[i*(ksecNPointsPerRadii+1)]);
332         secX2[i] = secX[i];
333         secY2[i] = secY[i];
334         secX3[i] = secX[i];
335         secY3[i] = secY[i];
336     } // end for i
337
338     // Find starting and ending angles for all but cooling tube sections
339     secAngleStart[0] = 0.5*ksecAngleSide13;
340     for(i=0;i<ksecNRadii-2;i++){
341         tst = kFALSE;
342         for(j=0;j<ksecNCoolingTubeDips;j++) tst = tst||i==ksecDipIndex[j];
343         if(tst) continue;
344         tst = kFALSE;
345         for(j=0;j<ksecNCoolingTubeDips;j++) tst = tst||(i+1)==ksecDipIndex[j];
346         if(tst) j = i+2;
347         else j = i+1;
348         AnglesForRoundedCorners(secX[i],secY[i],secR[i],
349                                 secX[j],secY[j],secR[j],t0,t1);
350         secAngleEnd[i]   = t0;
351         secAngleStart[j] = t1;
352         if(secR[i]>0.0&&secR[j]>0.0)if(secAngleStart[i]>secAngleEnd[i])
353             secAngleEnd[i] += 360.0;
354         secAngleStart2[i] = secAngleStart[i];
355         secAngleEnd2[i]   = secAngleEnd[i];
356     } // end for i
357     secAngleEnd[ksecNRadii-2]   = secAngleStart[ksecNRadii-2] + 
358                                      (secAngleEnd[ksecNRadii-5]-
359                                       secAngleStart[ksecNRadii-5]);
360     if(secAngleEnd[ksecNRadii-2]<0.0) secAngleEnd[ksecNRadii-2] += 360.0;
361     secAngleStart[ksecNRadii-1] = secAngleEnd[ksecNRadii-2] - 180.0;
362     secAngleEnd[ksecNRadii-1]   = secAngleStart[0];
363     secAngleStart2[ksecNRadii-2] = secAngleStart[ksecNRadii-2];
364     secAngleEnd2[ksecNRadii-2]   = secAngleEnd[ksecNRadii-2];
365     secAngleStart2[ksecNRadii-1] = secAngleStart[ksecNRadii-1];
366     secAngleEnd2[ksecNRadii-1]   = secAngleEnd[ksecNRadii-1];
367     // Find location of circle last rounded corner.
368     i = 0;
369     j = ksecNRadii-2;
370     t0 = TanD(secAngleStart[i]-90.);
371     t1 = TanD(secAngleEnd[j]-90.);
372     t  = secY[i] - secY[j];
373     // Note, secR[i=0] <0; secR[j=18]>0; and secR[j+1=19] <0
374     t += (-secR[i]+secR[j+1])*SinD(secAngleStart[i]);
375     t -= (secR[j]-secR[j+1])*SinD(secAngleEnd[j]);
376     t += t1*secX[j] - t0*secX[i];
377     t += t1*(secR[j]-secR[j+1])*CosD(secAngleEnd[j]);
378     t -= t0*(-secR[i]+secR[j+1])*CosD(secAngleStart[i]);
379     secX[ksecNRadii-1] = t/(t1-t0);
380     secY[ksecNRadii-1] = TanD(90.+0.5*ksecAngleSide13)*
381                           (secX[ksecNRadii-1]-secX[0]) + secY[0];
382     secX2[ksecNRadii-1] = secX[ksecNRadii-1];
383     secY2[ksecNRadii-1] = secY[ksecNRadii-1];
384     secX3[ksecNRadii-1] = secX[ksecNRadii-1];
385     secY3[ksecNRadii-1] = secY[ksecNRadii-1];
386     // find location of cooling tube centers
387     for(i=0;i<ksecNCoolingTubeDips;i++){
388         j = ksecDipIndex[i];
389         x0 = secX[j-1] + TMath::Abs(secR[j-1])*CosD(secAngleEnd[j-1]);
390         y0 = secY[j-1] + TMath::Abs(secR[j-1])*SinD(secAngleEnd[j-1]);
391         x1 = secX[j+1] + TMath::Abs(secR[j+1])*CosD(secAngleStart[j+1]);
392         y1 = secY[j+1] + TMath::Abs(secR[j+1])*SinD(secAngleStart[j+1]);
393         t0 = TMath::Sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
394         t  = secDip2[i]/t0;
395         a  = x0+(x1-x0)*t;
396         b  = y0+(y1-y0)*t;
397         if(a+b*(a-x0)/(b-y0)>0.0){
398             secX[j] = a + TMath::Abs(y1-y0)*2.0*ksecDipRadii/t0;
399             secY[j] = b - TMath::Sign(2.0*ksecDipRadii,y1-y0)*(x1-x0)/t0;
400             secX2[j] = a + TMath::Abs(y1-y0)*ksecTl/t0;
401             secY2[j] = b - TMath::Sign(ksecTl,y1-y0)*(x1-x0)/t0;
402             secX3[j] = a + TMath::Abs(y1-y0)*(2.0*ksecDipRadii-
403                                               0.5*ksecCoolTubeFlatY)/t0;
404             secY3[j] = b - TMath::Sign(2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY,
405                                        y1-y0)*(x1-x0)/t0;
406         }else{
407             secX[j] = a - TMath::Abs(y1-y0)*2.0*ksecDipRadii/t0;
408             secY[j] = b + TMath::Sign(2.0*ksecDipRadii,y1-y0)*(x1-x0)/t0;
409             secX2[j] = a - TMath::Abs(y1-y0)*ksecTl/t0;
410             secY2[j] = b + TMath::Sign(ksecTl,y1-y0)*(x1-x0)/t0;
411             secX3[j] = a - TMath::Abs(y1-y0)*(2.0*ksecDipRadii-
412                                               0.5*ksecCoolTubeFlatY)/t0;
413             secY3[j] = b + TMath::Sign(2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY,
414                                        y1-y0)*(x1-x0)/t0;
415         } // end if
416         // Set up Start and End angles to correspond to start/end of dips.
417         t1 = (secDip2[i]-TMath::Abs(secR[j]))/t0;
418         secAngleStart[j] = TMath::RadToDeg()*TMath::ATan2(
419                                y0+(y1-y0)*t1-secY[j],x0+(x1-x0)*t1-secX[j]);
420         if(secAngleStart[j]<0.0) secAngleStart[j] += 360.0;
421         secAngleStart2[j] = secAngleStart[j];
422         t1 = (secDip2[i]+TMath::Abs(secR[j]))/t0;
423         secAngleEnd[j] = TMath::RadToDeg()*TMath::ATan2(
424                                y0+(y1-y0)*t1-secY[j],x0+(x1-x0)*t1-secX[j]);
425         if(secAngleEnd[j]<0.0) secAngleEnd[j] += 360.0;
426         secAngleEnd2[j]   = secAngleEnd[j];
427         if(secAngleEnd[j]>secAngleStart[j]) secAngleEnd[j] -= 360.0;
428         secR[j] = TMath::Sqrt(secR[j]*secR[j]+4.0*ksecDipRadii*ksecDipRadii);
429     } // end if
430     // Spcial cases
431     secAngleStart2[8] -= 360.;
432     secAngleStart2[11] -= 360.;
433     //
434     SPDsectorShape(ksecNRadii,secX,secY,secR,secAngleStart,secAngleEnd,
435                    ksecNPointsPerRadii,m,xp,yp);
436     //  Fix up dips to be square.
437     for(i=0;i<ksecNCoolingTubeDips;i++){
438         j = ksecDipIndex[i];
439         t = 0.5*ksecDipLength+ksecDipRadii;
440         t0 = TMath::RadToDeg()*TMath::ATan(2.0*ksecDipRadii/t);
441         t1 = secAngleEnd[j] + t0;
442         t0 = secAngleStart[j] - t0;
443         x0 = xp[j][1] = secX[j] + t*CosD(t0);
444         y0 = yp[j][1] = secY[j] + t*SinD(t0);
445         x1 = xp[j][ksecNPointsPerRadii-1] = secX[j] + t*CosD(t1);
446         y1 = yp[j][ksecNPointsPerRadii-1] = secY[j] + t*SinD(t1);
447         t0 = 1./((Double_t)(ksecNPointsPerRadii-2));
448         for(k=2;k<ksecNPointsPerRadii-1;k++){// extra points spread them out.
449             t = ((Double_t)(k-1))*t0;
450             xp[j][k] = x0+(x1-x0)*t;
451             yp[j][k] = y0+(y1-y0)*t;
452         } // end for k
453         secAngleTurbo[i] = -TMath::RadToDeg()*TMath::ATan2(y1-y0,x1-x0);
454         if(GetDebug(3)){ 
455             Info("CarbonFiberSector","i=%d angle=%f x0,y0{%f,%f} "
456                  "x1y1={%f,%f,}",i,secAngleTurbo[i],x0,0,x1,y1);
457         } // end if
458     } // end for i
459     sA0 = new TGeoXtru(2);
460     sA0->SetName("ITS SPD Carbon fiber support Sector A0");
461     sA0->DefinePolygon(m,xpp,ypp);
462     sA0->DefineSection(0,-ksecDz);
463     sA0->DefineSection(1,ksecDz);
464     //
465     InsidePoint(xpp[m-1],ypp[m-1],xpp[0],ypp[0],xpp[1],ypp[1],
466                 ksecCthick,xpp2[0],ypp2[0]);
467     for(i=1;i<m-1;i++){
468         j = i/(ksecNPointsPerRadii+1);
469         InsidePoint(xpp[i-1],ypp[i-1],xpp[i],ypp[i],xpp[i+1],ypp[i+1],
470                     ksecCthick,xpp2[i],ypp2[i]);
471     } // end for i
472     InsidePoint(xpp[m-2],ypp[m-2],xpp[m-1],ypp[m-1],xpp[0],ypp[0],
473                 ksecCthick,xpp2[m-1],ypp2[m-1]);
474     // Fix center value of cooling tube dip.
475     // find location of cooling tube centers
476     for(i=0;i<ksecNCoolingTubeDips;i++){
477         j = ksecDipIndex[i];
478         x0 = xp2[j][1];
479         y0 = yp2[j][1];
480         x1 = xp2[j][ksecNPointsPerRadii-1];
481         y1 = yp2[j][ksecNPointsPerRadii-1];
482         t0 = TMath::Sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
483         t  = secDip2[i]/t0;
484         for(k=2;k<ksecNPointsPerRadii-1;k++){// extra points spread them out.
485             t = ((Double_t)(k-1))*t0;
486             xp2[j][k] = x0+(x1-x0)*t;
487             yp2[j][k] = y0+(y1-y0)*t;
488         } // end for k
489     } // end for i
490     sA1 = new TGeoXtru(2);
491     sA1->SetName("ITS SPD Carbon fiber support Sector Air A1");
492     sA1->DefinePolygon(m,xpp2,ypp2);
493     sA1->DefineSection(0,-ksecDz);
494     sA1->DefineSection(1,ksecDz);
495     //
496     // Error in TGeoEltu. Semi-axis X must be < Semi-axis Y (?).
497     sTA0 = new TGeoEltu("ITS SPD Cooling Tube TA0",
498                       0.5* ksecCoolTubeFlatY, 0.5* ksecCoolTubeFlatX,ksecDz);
499     sTA1 = new TGeoEltu("ITS SPD Cooling Tube coolant TA1",
500                         sTA0->GetA()-ksecCoolTubeThick,
501                         sTA0->GetB()-ksecCoolTubeThick,ksecDz);
502     //
503     SPDsectorShape(ksecNRadii,secX2,secY2,secR2,secAngleStart2,secAngleEnd2,
504                    ksecNPointsPerRadii,m,xp,yp);
505     //
506     sB0 = new TGeoXtru(2);
507     sB0->SetName("ITS SPD Carbon fiber support Sector End B0");
508     sB0->DefinePolygon(m,xpp,ypp);
509     sB0->DefineSection(0,ksecDz);
510     sB0->DefineSection(1,ksecDz+ksecZEndLen);
511     //
512     InsidePoint(xpp[m-1],ypp[m-1],xpp[0],ypp[0],xpp[1],ypp[1],
513                 ksecCthick2,xpp2[0],ypp2[0]);
514     for(i=1;i<m-1;i++){
515         t = ksecCthick2;
516         for(k=0;k<ksecNCoolingTubeDips;k++)
517             if((i/(ksecNPointsPerRadii+1))==ksecDipIndex[k]) 
518                 if(!(ksecDipIndex[k]*(ksecNPointsPerRadii+1)==i || 
519                      ksecDipIndex[k]*(ksecNPointsPerRadii+1)+
520                      ksecNPointsPerRadii==i   )) 
521                     t = ksecRCoolOut-ksecRCoolIn;
522         InsidePoint(xpp[i-1],ypp[i-1],xpp[i],ypp[i],xpp[i+1],ypp[i+1],
523                     t,xpp2[i],ypp2[i]);
524     } // end for i
525     InsidePoint(xpp[m-2],ypp[m-2],xpp[m-1],ypp[m-1],xpp[0],ypp[0],
526                 ksecCthick2,xpp2[m-1],ypp2[m-1]);
527     sB1 = new TGeoXtru(2);
528     sB1->SetName("ITS SPD Carbon fiber support Sector Air End B1");
529     sB1->DefinePolygon(m,xpp2,ypp2);
530     sB1->DefineSection(0,ksecDz);
531     sB1->DefineSection(1,ksecDz+ksecLen);
532     sTB0 = new TGeoTube("ITS SPD Cooling Tube End TB0",0.0,
533                        0.5*ksecCoolTubeROuter,0.5*ksecLen);
534     sTB1 = new TGeoTube("ITS SPD Cooling Tube End coolant TB0",0.0,
535                        sTB0->GetRmax()-ksecCoolTubeThick,0.5*ksecLen);
536     //
537     sM0 = new TGeoTube("ITS SPD Sensitive Virutual Volume M0",0.0,8.0,
538                        sA0->GetZ(1)+sB0->GetZ(1));
539     //
540     if(GetDebug()){
541         sM0->InspectShape();
542         sA0->InspectShape();
543         sA1->InspectShape();
544         sB0->InspectShape();
545         sB1->InspectShape();
546     } // end if GetDebug
547     //
548     TGeoVolume *vM0,*vA0,*vA1,*vTA0,*vTA1,*vB0,*vB1,*vTB0,*vTB1;
549     vM0 = new TGeoVolume("ITSSPDSensitiveVirtualvolumeM0",sM0,medSPDair);
550     vM0->SetVisibility(kTRUE);
551     vM0->SetLineColor(7); // light Blue
552     vM0->SetLineWidth(1);
553     vM0->SetFillColor(vM0->GetLineColor());
554     vM0->SetFillStyle(4090); // 90% transparent
555     vA0 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorA0",sA0,medSPDcf);
556     vA0->SetVisibility(kTRUE);
557     vA0->SetLineColor(4); // Blue
558     vA0->SetLineWidth(1);
559     vA0->SetFillColor(vA0->GetLineColor());
560     vA0->SetFillStyle(4010); // 10% transparent
561     vA1 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorAirA1",sA1,medSPDair);
562     vA1->SetVisibility(kTRUE);
563     vA1->SetLineColor(7); // light Blue
564     vA1->SetLineWidth(1);
565     vA1->SetFillColor(vA1->GetLineColor());
566     vA1->SetFillStyle(4090); // 90% transparent
567     vTA0 = new TGeoVolume("ITSSPDCoolingTubeTA0",sTA0,medSPDss);
568     vTA0->SetVisibility(kTRUE);
569     vTA0->SetLineColor(1); // Black
570     vTA0->SetLineWidth(1);
571     vTA0->SetFillColor(vTA0->GetLineColor());
572     vTA0->SetFillStyle(4000); // 0% transparent
573     vTA1 = new TGeoVolume("ITSSPDCoolingTubeFluidTA1",sTA1,medSPDcoolfl);
574     vTA1->SetVisibility(kTRUE);
575     vTA1->SetLineColor(6); // Purple
576     vTA1->SetLineWidth(1);
577     vTA1->SetFillColor(vTA1->GetLineColor());
578     vTA1->SetFillStyle(4000); // 0% transparent
579     vB0 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorEndB0",sB0,medSPDcf);
580     vB0->SetVisibility(kTRUE);
581     vB0->SetLineColor(4); // Blue
582     vB0->SetLineWidth(1);
583     vB0->SetFillColor(vB0->GetLineColor());
584     vB0->SetFillStyle(4010); // 10% transparent
585     vB1 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorEndAirB1",
586                          sB1,medSPDair);
587     vB1->SetVisibility(kTRUE);
588     vB1->SetLineColor(7); // light Blue
589     vB1->SetLineWidth(1);
590     vB1->SetFillColor(vB1->GetLineColor());
591     vB1->SetFillStyle(4090); // 90% transparent
592     vTB0 = new TGeoVolume("ITSSPDCoolingTubeEndTB0",sTB0,medSPDss);
593     vTB0->SetVisibility(kTRUE);
594     vTB0->SetLineColor(1); // Black
595     vTB0->SetLineWidth(1);
596     vTB0->SetFillColor(vTB0->GetLineColor());
597     vTB0->SetFillStyle(4000); // 0% transparent
598     vTB1 = new TGeoVolume("ITSSPDCoolingTubeEndFluidTB1",sTB1,medSPDcoolfl);
599     vTB1->SetVisibility(kTRUE);
600     vTB1->SetLineColor(6); // Purple
601     vTB1->SetLineWidth(1);
602     vTB1->SetFillColor(vTB1->GetLineColor());
603     vTB1->SetFillStyle(4000); // 0% transparent
604     //
605     moth->AddNode(vM0,1,0); // Add virtual volume to mother
606     vA0->AddNode(vA1,1,0); // Put air inside carbon fiber.
607     vB0->AddNode(vB1,1,0); // Put air inside carbon fiber.
608     vTA0->AddNode(vTA1,1,0); // Put air inside carbon fiber.
609     vTB0->AddNode(vTB1,1,0); // Put air inside carbon fiber.
610     for(i=0;i<ksecNCoolingTubeDips;i++){
611         x0 = secX3[ksecDipIndex[i]];
612         y0 = secY3[ksecDipIndex[i]];
613         t = 90.0-secAngleTurbo[i];
614         trans = new TGeoTranslation("",x0,y0,0.5*(sB1->GetZ(0)+sB1->GetZ(1)));
615         vB1->AddNode(vTB0,i+1,trans);
616         rot = new TGeoRotation("",0.0,0.0,t);
617         rotrans = new TGeoCombiTrans("",x0,y0,0.0,rot);
618         vM0->AddNode(vTA0,i+1,rotrans);
619         delete rot; // rot owned by AliITSv11GeometerySPD::CarbonFiberSector
620     } // end for i
621     vM0->AddNode(vA0,1,0);
622     vM0->AddNode(vB0,1,0);
623     // Reflection.
624     vM0->AddNode(vB0,2,new TGeoRotation("",90.,0.,90.,90.,180.,0.));
625     if(GetDebug()){
626         vM0->PrintNodes();
627         vA0->PrintNodes();
628         vA1->PrintNodes();
629         vB0->PrintNodes();
630         vB1->PrintNodes();
631     } // end if GetDebug
632     //
633     return moth;
634 }
635 //----------------------------------------------------------------------
636 void AliITSv11GeometrySPD::SPDsectorShape(Int_t n,const Double_t *xc,
637 const Double_t *yc,const Double_t *r,const Double_t *ths,const Double_t *the,
638                                Int_t npr,Int_t &m,Double_t **xp,Double_t **yp){
639     // Code to compute the points that make up the shape of the SPD
640     // Carbon fiber support sections
641     // Inputs:
642     //    Int_t    n       Size of arrays xc,yc, and r.
643     //    Double_t *xc     Array of x values for radii centers.
644     //    Double_t *yc     Array of y values for radii centers.
645     //    Double_t *r      Array of signed radii values.
646     //    Double_t *ths    Array of starting angles [degrees].
647     //    Double_t *the    Array of ending angles [degrees].
648     //    Int_t    npr     The number of lines segments to aproximate the arc.
649     // Outputs:
650     //    Int_t    m       The number of enetries in the arrays *xp[npr+1] 
651     //                     and *yp[npr+1].
652     //    Double_t **xp    Array of x coordinate values of the line segments
653     //                     which make up the SPD support sector shape.
654     //    Double_t **yp    Array of y coordinate values of the line segments
655     //                     which make up the SPD support sector shape.
656     // Return:
657     //    none.
658     Int_t i,k;
659     Double_t t,t0,t1;
660
661     m = n*(npr+1);
662     if(GetDebug(2)){
663         Info("SPDsectorShape","    X    \t  Y  \t  R  \t  S  \t  E%d", m);
664         for(i=0;i<n;i++){
665             Info("SPDsectorShape","{%f,%f,%f,%f,%f}",
666                  xc[i],yc[i],r[i],ths[i],the[i]);
667         } // end for i
668     } // end if GetDebug
669     //
670     if(GetDebug(3)) cout <<"Double_t sA0 = ["<< n*(npr+1)+1<<"][";
671     if(GetDebug(4)) cout <<"3]{";
672     else if(GetDebug(3)) cout <<"2]{";
673     t0 = (Double_t)npr;
674     for(i=0;i<n;i++){
675         t1 = (the[i]-ths[i])/t0;
676         if(GetDebug(5)) cout<<"t1="<< t1<<endl;
677         for(k=0;k<=npr;k++){
678             t=ths[i]+((Double_t)k)*t1;
679             xp[i][k] = TMath::Abs(r[i])*CosD(t)+xc[i];
680             yp[i][k] = TMath::Abs(r[i])*SinD(t)+yc[i];
681             if(GetDebug(3)){
682                 cout << "{"<<xp[i][k]<<","<<yp[i][k];
683                 if(GetDebug(4)) cout <<","<<t;
684                 cout <<"},";
685             } // end if GetDebug
686         } // end for k
687         if(GetDebug(3)) cout << endl;
688     } // end of i
689     if(GetDebug(3)) cout<<"{"<<xp[0][0]<<","<<yp[0][0];
690     if(GetDebug(4)) cout<<","<< ths[0];
691     if(GetDebug(3)) cout<<"}}"<<endl;
692     //
693     return;
694 }
695 //______________________________________________________________________
696 TGeoVolume* AliITSv11GeometrySPD::CreateHalfStaveGroundFoil(){
697     // Define the detail SPD Half Stave geometry.
698     // Inputs:
699     //   none.
700     // Outputs:
701     //  none.
702     // Return:
703     //  TGeoVolume* The volume containing the half stave grounding foil.
704
705     TGeoManager *mgr = gGeoManager;
706     TGeoMedium *medSPDair = 0; // SPD Air
707     TGeoMedium *medSPDCu  = 0; // SPD Copper conductor
708     TGeoMedium *medSPDSiNs  = 0; // SPD Silicon non-sensitive material
709     TGeoMedium *medSPDSiSv  = 0; // SPD Silicon Sensitive material
710     TGeoMedium *medSPDStaveGlue = 0; // SPD Glue used on Half Staves
711
712     medSPDair       = mgr->GetMedium("ITSspdAir");
713     medSPDCu        = mgr->GetMedium("ITSspdCopper");
714     medSPDSiNs      = mgr->GetMedium("ITSspdSiliconNonSensitive");
715     medSPDSiSv      = mgr->GetMedium("ITSspdSiliconSensitive");
716     medSPDStaveGlue = mgr->GetMedium("ITSspdStaveGlue");
717     //
718     Double_t origin[3] = {0.0,0.0,0.0};
719     TGeoBBox *sA0,*sA1,*sA3,*sB2;
720     TGeoArb8 *sA2;
721     TGeoTubeSeg *sB1;
722
723     sA0 = new TGeoBBox("ITS SPD Half Stave Grounding Foil A0",
724                        0.5*fkGrdFoilWidthA,0.5*fkGrdFoilThick,0.5*(
725                 fkGrdFoilLngA+fkGrdFoilLngB+fkGrdFoilLngC),origin);
726     origin[2] = 0.5*fkGrdFoilLngA;
727     sA1 = new TGeoBBox("ITS SPD Half Stave Gounding Foil Copper A1",
728             0.5*fkGrdFoilWidthA,0.5*fkGrdFoilThick,0.5*fkGrdFoilLngA,origin);
729     origin[0] = 0.5*(fkGrdFoilWidthA-fkGrdFoilWidthC);
730     origin[2] = -(fkGrdFoilLngA+fkGrdFoilLngB+0.5*fkGrdFoilLngC);
731     sA3 = new TGeoBBox("ITS SPD Half Stave Gounding Foil copper A3",
732             0.5*fkGrdFoilWidthC,0.5*fkGrdFoilThick,0.5*fkGrdFoilLngC,origin);
733     sA2 = new TGeoArb8("ITS SPD Half Stave Gounding Foil Copper A2",
734                        0.5*fkGrdFoilLngB);
735     sA2->SetVertex(0,-sA1->GetDX(),+sA1->GetDY());
736     sA2->SetVertex(1,+sA1->GetDX(),+sA1->GetDY());
737     sA2->SetVertex(2,+sA1->GetDX(),-sA1->GetDY());
738     sA2->SetVertex(3,-sA1->GetDX(),-sA1->GetDY());
739     sA2->SetVertex(4,origin[0]-sA3->GetDX(),+sA3->GetDY());
740     sA2->SetVertex(5,origin[0]+sA3->GetDX(),+sA3->GetDY());
741     sA2->SetVertex(6,origin[0]+sA3->GetDX(),-sA3->GetDY());
742     sA2->SetVertex(7,origin[0]-sA3->GetDX(),-sA3->GetDY());
743     sB1 = new TGeoTubeSeg("ITS SPD Half Stave Ground Foil Hole B1",
744                           0.0,0.5*fkGrdFoilHoleWidthAB,sA1->GetDY(),0.,180.);
745     sB2 = new TGeoBBox("ITS SPD Half Stave Ground Foil Hole B2",
746                        0.5*fkGrdFoilHoleWidthAB,sA1->GetDY(),
747                        0.5*(fkGrdFoilHoleLengthAB-fkGrdFoilHoleWidthAB),0);
748     //
749     TGeoVolume *vA0,*vA1,*vA2,*vA3,*vB1,*vB2;
750     vA0 = new TGeoVolume("ITSSPDHalfStaveGroundFoilA0",sA0,medSPDair);
751     vA0->SetVisibility(kTRUE);
752     vA0->SetLineColor(7); // light Blue
753     vA0->SetLineWidth(1);
754     vA0->SetFillColor(vA0->GetLineColor());
755     vA0->SetFillStyle(4090); // 90% transparent
756     vB1 = new TGeoVolume("ITSSPDHalfStaveGoundFoilHoleB1",sB1,medSPDair);
757     vB1->SetVisibility(kTRUE);
758     vB1->SetLineColor(7); // light Blue
759     vB1->SetLineWidth(1);
760     vB1->SetFillColor(vB1->GetLineColor());
761     vB1->SetFillStyle(4090); // 90% transparent
762     vB2 = new TGeoVolume("ITSSPDHalfStaveGoundFoilHoleB2",sB2,medSPDair);
763     vB2->SetVisibility(kTRUE);
764     vB2->SetLineColor(7); // light Blue
765     vB2->SetLineWidth(1);
766     vB2->SetFillColor(vB2->GetLineColor());
767     vB2->SetFillStyle(4090); // 90% transparent
768     vA1 = new TGeoVolume("ITSSPDHalfStaveGoundFoilCopperA1",sA1,medSPDCu);
769     vA1->SetVisibility(kTRUE);
770     vA1->SetLineColor(2); // red
771     vA1->SetLineWidth(1);
772     vA1->SetFillColor(vA1->GetLineColor());
773     vA1->SetFillStyle(4000); // 00% transparent
774     vA2 = new TGeoVolume("ITSSPDHalfStaveGoundFoilCopperA2",sA2,medSPDCu);
775     vA2->SetVisibility(kTRUE);
776     vA2->SetLineColor(2); // red
777     vA2->SetLineWidth(1);
778     vA2->SetFillColor(vA2->GetLineColor());
779     vA2->SetFillStyle(4000); // 00% transparent
780     vA3 = new TGeoVolume("ITSSPDHalfStaveGoundFoilCopperA3",sA3,medSPDCu);
781     vA3->SetVisibility(kTRUE);
782     vA3->SetLineColor(2); // red
783     vA3->SetLineWidth(1);
784     vA3->SetFillColor(vA3->GetLineColor());
785     vA3->SetFillStyle(4000); // 00% transparent
786     //
787     vA0->AddNode(vA1,1,0);
788     vA0->AddNode(vA2,1,new TGeoTranslation(0.0,0.0,
789                                            2.0*sA1->GetDZ()+sA2->GetDz()));
790     vA0->AddNode(vA3,1,0);
791     TGeoRotation left("",-90.0,0.0,0.0), right("",90.0,0.0,0.0);
792     Int_t i,ncopyB1=1,ncopyB2=1;
793     for(i=0;i<fkGrdFoilNholesAB;i++){
794         origin[0] = 0.0;
795         origin[1] = 0.0;
796         origin[2] = fkGrdFoilHoleStartA+((Double_t)i)*fkGrdFoilHoleSpacingAB;
797         vA1->AddNode(vB1,ncopyB1,0); // double check
798         vA1->AddNode(vB2,ncopyB2,new TGeoTranslation(0.0,0.0,
799                                         origin[2]+0.5*fkGrdFoilHoleLengthAB));
800         vA1->AddNode(vB1,ncopyB1,0); // double check
801     } // end for i
802     for(i=0;i<fkGrdFoilNholesAB;i++){
803         origin[0] = 0.0;
804         origin[1] = 0.0;
805         origin[2] = fkGrdFoilHoleStartB+((Double_t)i)*fkGrdFoilHoleSpacingAB;
806         new TGeoTranslation(0.0,0.0,origin[2]+sB1->GetRmax());
807         vA1->AddNode(vB1,ncopyB1,0); // double check
808         vA1->AddNode(vB2,ncopyB2,new TGeoTranslation(0.0,0.0,
809                                       origin[2]+0.5*fkGrdFoilHoleLengthAB));
810         new TGeoTranslation(0.0,0.0,origin[2]+sB1->GetRmax()+2.0*sB2->GetDZ());
811         vA1->AddNode(vB1,ncopyB1,0); // double check
812     } // end for i
813     return vA0;
814 }
815 //______________________________________________________________________
816 TGeoVolume* AliITSv11GeometrySPD::CreateSPDLadder(){
817     // Define the detail SPD Half Stave geometry.
818     // Inputs:
819     //   none.
820     // Outputs:
821     //  none.
822     // Return:
823     //  TGeoVolume* of the volume containing the SPD Ladder.
824     TGeoMedium *medSPDair       = 0; // SPD Air
825     TGeoMedium *medSPDCu        = 0; // SPD Copper conductor
826     TGeoMedium *medSPDSiNs      = 0; // SPD Silicon non-sensitive material
827     TGeoMedium *medSPDSiSv      = 0; // SPD Silicon Sensitive material
828     TGeoMedium *medSPDStaveGlue = 0; // SPD Glue used on Half Staves
829     TGeoMedium *medSPDLadGlue   = 0; // SPD Glue used on Half Staves
830     TGeoMedium *medSPDBumpBonds = 0; // SPD Bump bond material
831     TGeoBBox *sM0,*sGlue0,*sChip,*sBB,*sDet,*sSenDet,*sGlue1;
832     Double_t x,y,z;
833
834     TGeoManager *mgr = gGeoManager;
835     medSPDair       = mgr->GetMedium("ITSspdAir");
836     medSPDCu        = mgr->GetMedium("ITSspdCopper");
837     medSPDSiNs      = mgr->GetMedium("ITSspdSiliconNonSensitive");
838     medSPDSiSv      = mgr->GetMedium("ITSspdSiliconSensitive");
839     medSPDStaveGlue = mgr->GetMedium("ITSspdStaveGlue");
840     medSPDLadGlue   = mgr->GetMedium("ITSspdLadderGlue");
841     medSPDBumpBonds = mgr->GetMedium("ITSspdBumpBond");
842     //
843     sChip   = new TGeoBBox("ITS SPD Chip",0.5*fkLadChipWidth,0.5*fThickChip,
844                            0.5*fkLadChipLength);
845     sGlue0  = new TGeoBBox("ITS SPD Ladder bottom Glue0",sChip->GetDX(),
846                            0.5*fkLadGlue0Thick,sChip->GetDZ());
847     sDet    = new TGeoBBox("ITS SPD Detector Det",0.5*fkLadDetectorWidth,
848                            0.5*fThickDetector,0.5*fkLadDetectorLength);
849     sBB     = new TGeoBBox("ITS SPD BumpBond BB",sDet->GetDX(),
850                            0.5*fkLadBumpBondThick,sChip->GetDZ());
851     sSenDet = new TGeoBBox(CreateSensitivevolumeName("_shape"),
852                   0.5*fkLadSensDetWidth,sDet->GetDY(),0.5*fkLadSensDetLength);
853     sGlue1  = new TGeoBBox("ITS SPD Ladder Top Glue1",
854                            sDet->GetDX(),0.5*fkLadGlue0Thick,sDet->GetDZ());
855     x = TMath::Max(sChip->GetDX(),sDet->GetDX());
856     y = sGlue0->GetDY()+sChip->GetDY()+sBB->GetDY()+sDet->GetDY()+
857         sGlue1->GetDY();
858     z = ((Double_t) fkLadNChips)*sChip->GetDZ()+2.*0.5*fkLadChipSpacing0 +
859         ((Double_t) fkLadNChips-1)*0.5*fkLadChipSpacing1;
860     z = TMath::Max(z,sDet->GetDZ());
861     sM0 = new TGeoBBox("ITS SPD Ladder M0",x,y,z);
862     if(GetDebug()){
863         sGlue0->InspectShape();
864         sChip->InspectShape();
865         sBB->InspectShape();
866         sDet->InspectShape();
867         sSenDet->InspectShape();
868         sGlue1->InspectShape();
869         sM0->InspectShape();
870     } // end if GetDebug
871     //
872     TGeoVolume *vM0,*vGlue0,*vChip,*vBB,*vDet,*vSenDet,*vGlue1;
873     vM0 = new TGeoVolume("ITSSPDLadderM0",sM0,medSPDair);
874     vM0->SetVisibility(kFALSE);
875     vM0->SetLineColor(8); // White
876     vM0->SetLineWidth(1);
877     vM0->SetFillColor(vM0->GetLineColor());
878     vM0->SetFillStyle(4000); // 100% transparent
879     vGlue0 = new TGeoVolume("ITSSPDLadderGlue0",sGlue0,medSPDLadGlue);
880     vGlue0->SetVisibility(kTRUE);
881     vGlue0->SetLineColor(5); // Yellow
882     vGlue0->SetLineWidth(1);
883     vGlue0->SetFillColor(vGlue0->GetLineColor());
884     vGlue0->SetFillStyle(4050); // 50% transparent
885     vGlue1 = new TGeoVolume("ITSSPDLadderGlue1",sGlue1,medSPDLadGlue);
886     vGlue1->SetVisibility(kTRUE);
887     vGlue1->SetLineColor(5); // Yellow
888     vGlue1->SetLineWidth(1);
889     vGlue1->SetFillColor(vGlue1->GetLineColor());
890     vGlue1->SetFillStyle(4050); // 50% transparent
891     vChip = new TGeoVolume("ITSSPDLadderChip",sChip,medSPDSiNs);
892     vChip->SetVisibility(kTRUE);
893     vChip->SetLineColor(4); // blue
894     vChip->SetLineWidth(1);
895     vChip->SetFillColor(vChip->GetLineColor());
896     vChip->SetFillStyle(4100); // 0% transparent
897     vBB = new TGeoVolume("ITSSPDLadderBumpBond",sBB,medSPDBumpBonds);
898     vBB->SetVisibility(kTRUE);
899     vBB->SetLineColor(1); // black
900     vBB->SetLineWidth(1);
901     vBB->SetFillColor(vBB->GetLineColor());
902     vBB->SetFillStyle(4100); // 0% transparent
903     vDet = new TGeoVolume("ITSSPDLadderDet",sDet,medSPDSiNs);
904     vDet->SetVisibility(kTRUE);
905     vDet->SetLineColor(4); // blue
906     vDet->SetLineWidth(1);
907     vDet->SetFillColor(vDet->GetLineColor());
908     vDet->SetFillStyle(4100); // 0% transparent
909     vSenDet =new TGeoVolume(GetSensitivevolumeName(),sSenDet,medSPDSiSv);
910     vSenDet->SetVisibility(kTRUE);
911     vSenDet->SetLineColor(4); // blue
912     vSenDet->SetLineWidth(1);
913     vSenDet->SetFillColor(vSenDet->GetLineColor());
914     vSenDet->SetFillStyle(4100); // 0% transparent
915     //
916     vDet->AddNode(vSenDet,1,0); // Put sensitive volume inside detector
917     TGeoTranslation *tran;
918     Int_t i,nCopyGlue0=1,nCopyChip=1,nCopyBB=1;
919     Double_t xb,yg0,yc,yb,yd,yg1;
920     x   = 0.0;
921     xb  = -sM0->GetDX() + sDet->GetDX();
922     yg0 = -sM0->GetDY()+sGlue0->GetDY();
923     yc  = yg0 + sGlue0->GetDY() + sChip->GetDY();
924     yb  = yc  + sChip->GetDY()  + sBB->GetDY();
925     yd  = yb  + sBB->GetDY()    + sDet->GetDY();
926     yg1 = yd  + sDet->GetDY()   + sGlue1->GetDY();
927     z   = -sM0->GetDZ() + fkLadChipSpacing0 + sChip->GetDZ();
928     for(i=0;i<fkLadNChips;i++){
929         tran = new TGeoTranslation(x,yg0,z);
930         vM0->AddNode(vGlue0,nCopyGlue0++,tran);
931         tran = new TGeoTranslation(x,yc,z);
932         vM0->AddNode(vChip,nCopyChip++,tran);
933         tran = new TGeoTranslation(xb,yb,z);
934         vM0->AddNode(vBB,nCopyBB++,tran);
935         z += fkLadChipSpacing1 + 2.0*sChip->GetDZ();
936     } // end for i
937     tran = new TGeoTranslation(xb,yd,0.0);
938     vM0->AddNode(vDet,1,tran);
939     tran = new TGeoTranslation(xb,yg1,0.0);
940     vM0->AddNode(vGlue1,1,tran);
941     if(GetDebug()){
942         vGlue0->PrintNodes();
943         vChip->PrintNodes();
944         vBB->PrintNodes();
945         vDet->PrintNodes();
946         vSenDet->PrintNodes();
947         vGlue1->PrintNodes();
948         vM0->PrintNodes();
949     } // end if GetDebug
950     return vM0;
951 }
952 //----------------------------------------------------------------------
953 void AliITSv11GeometrySPD::CreateFigure0(const Char_t *filepath,
954                                          const Char_t *type){
955     // Creates Figure 0 for the documentation of this class. In this
956     // specific case, it creates the X,Y cross section of the SPD suport
957     // section, center and ends. The output is written to a standard
958     // file name to the path specificed.
959     // Inputs:
960     //   const Char_t *filepath  Path where the figure is to be drawn
961     //   const Char_t *type      The type of file, default is gif.
962     // Output:
963     //   none.
964     // Return:
965     //   none.
966     TGeoXtru *sA0,*sA1,*sB0,*sB1;
967     //TPolyMarker *pmA,*pmB;
968     TPolyLine plA0,plA1,plB0,plB1;
969     TCanvas *canvas;
970     TLatex txt;
971     Double_t x=0.0,y=0.0;
972     Int_t i,kNRadii=6;
973
974     if(strcmp(filepath,"")){
975         Error("CreateFigure0","filepath=%s type=%s",filepath,type);
976     } // end if
977     //
978     sA0 = (TGeoXtru*) gGeoManager->GetVolume(
979         "ITSSPDCarbonFiberSupportSectorA0_1")->GetShape();
980     sA1 = (TGeoXtru*) gGeoManager->GetVolume(
981         "ITSSPDCarbonFiberSupportSectorAirA1_1")->GetShape();
982     sB0 = (TGeoXtru*) gGeoManager->GetVolume(
983         "ITSSPDCarbonFiberSupportSectorEndB0_1")->GetShape();
984     sB1 = (TGeoXtru*) gGeoManager->GetVolume(
985         "ITSSPDCarbonFiberSupportSectorEndAirB1_1")->GetShape();
986     //pmA = new TPolyMarker();
987     //pmA.SetMarkerStyle(2); // +
988     //pmA.SetMarkerColor(7); // light blue
989     //pmB = new TPolyMarker();
990     //pmB.SetMarkerStyle(5); // X
991     //pmB.SetMarkerColor(6); // purple
992     plA0.SetPolyLine(sA0->GetNvert());
993     plA0.SetLineColor(1); // black
994     plA0.SetLineStyle(1);
995     plA1.SetPolyLine(sA1->GetNvert());
996     plA1.SetLineColor(2); // red
997     plA1.SetLineStyle(1);
998     plB0.SetPolyLine(sB0->GetNvert());
999     plB0.SetLineColor(3); // Green
1000     plB0.SetLineStyle(2);
1001     plB1.SetPolyLine(sB1->GetNvert());
1002     plB1.SetLineColor(4); // Blue
1003     plB1.SetLineStyle(2);
1004     //for(i=0;i<kNRadii;i++) pmA.SetPoint(i,xyB1p[i][0],xyB1p[i][1]);
1005     //for(i=0;i<kNRadii;i++) pmB.SetPoint(i,xyB1p[i][0],xyB1p[i][1]);
1006     for(i=0;i<sA0->GetNvert();i++) plA0.SetPoint(i,sA0->GetX(i),sA0->GetY(i));
1007     for(i=0;i<sA1->GetNvert();i++) plA1.SetPoint(i,sA1->GetX(i),sA1->GetY(i));
1008     for(i=0;i<sB0->GetNvert();i++) plB0.SetPoint(i,sB0->GetX(i),sB0->GetY(i));
1009     for(i=0;i<sB1->GetNvert();i++) plB1.SetPoint(i,sB1->GetX(i),sB1->GetY(i));
1010     canvas = new TCanvas("AliITSv11GeometrySPDFig0","",1000,1000);
1011     canvas->Range(-3.,-3.,3.,3.);
1012     txt.SetTextSize(0.05);
1013     txt.SetTextAlign(33);
1014     txt.SetTextColor(1);
1015     txt.DrawLatex(2.9,2.9,"Section A-A outer Carbon Fiber surface");
1016     txt.SetTextColor(2);
1017     txt.DrawLatex(2.9,2.5,"Section A-A Inner Carbon Fiber surface");
1018     txt.SetTextColor(3);
1019     txt.DrawLatex(2.9,2.1,"Section E-E outer Carbon Fiber surface");
1020     txt.SetTextColor(4);
1021     txt.DrawLatex(2.9,1.7,"Section E-E Inner Carbon Fiber surface");
1022     plA0.Draw();
1023     plA1.Draw();
1024     plB0.Draw();
1025     plB1.Draw();
1026     //pmA.Draw();
1027     //pmB.Draw();
1028     //
1029     x = 1.0;
1030     y = -2.5;
1031     Char_t chr[3];
1032     for(i=0;i<kNRadii;i++){
1033         sprintf(chr,"%2d",i);txt.DrawLatex(x-0.1,y,chr);
1034         sprintf(chr,"%8.4",5.000);txt.DrawLatex(x,y,chr);
1035         sprintf(chr,"%8.4",5.000);txt.DrawLatex(x+0.5,y,chr);
1036         sprintf(chr,"%8.4",5.000);txt.DrawLatex(x+1.0,y,chr);
1037         sprintf(chr,"%8.4",5.000);txt.DrawLatex(x+1.5,y,chr);
1038         sprintf(chr,"%8.4",5.000);txt.DrawLatex(x+2.0,y,chr);
1039         if(kTRUE) txt.DrawLatex(x+2.5,y,"A-A/E-E");
1040         else txt.DrawLatex(x+2.5,y,"E-E");
1041     } // end for i
1042     txt.DrawLatex(x,y,"x_{c} mm");
1043     txt.DrawLatex(x+0.5,y,"y_{c} mm");
1044     txt.DrawLatex(x+1.0,y,"R mm");
1045     txt.DrawLatex(x+1.5,y,"#theta_{start}^{#circle}");
1046     txt.DrawLatex(x+2.0,y,"#theta_{end}^{#circle}");
1047     txt.DrawLatex(x+2.5,y,"Section");
1048     //
1049 }
1050 //----------------------------------------------------------------------
1051 void AliITSv11GeometrySPD::CreateFigureLadder(const Char_t *filepath,
1052                                          const Char_t *type){
1053     // Creates Figure 0 for the documentation of this class. In this
1054     // specific case, it creates the X,Y cross section of the SPD suport
1055     // section, center and ends. The output is written to a standard
1056     // file name to the path specificed.
1057     // Inputs:
1058     //   const Char_t *filepath  Path where the figure is to be drawn
1059     //   const Char_t *type      The type of file, default is gif.
1060     // Output:
1061     //   none.
1062     // Return:
1063     //   none.
1064     TGeoVolume *vLad;
1065     TCanvas *canvas;
1066     TLatex txt;
1067     TGeoManager *mgr = gGeoManager;
1068
1069     if((vLad = mgr->GetVolume("ITSSPDLadderM0"))==0){
1070         printf("file=%s type=%s\n",filepath,type);
1071         vLad = CreateSPDLadder();
1072     } // end if
1073     //
1074     canvas = new TCanvas("canvas","ITS SPD Ladder",900,450);
1075     //canvas->Divide(2,1);
1076     //canvas->cd(1);
1077     //TVirtualPad *pad1 = canvas->GetPad(1);
1078     //TView *view1 = pad1->GetView();
1079     //if(view1){
1080     //    view1->FrontView(pad1);
1081     //}
1082     vLad->Draw();
1083     //pad1->Update();
1084     //
1085 /*    canvas->cd(2);
1086     TVirtualPad *pad2 = canvas->GetPad(2);
1087     TView *view2 = pad2->GetView();
1088     if(view2){
1089         view2->TopView(pad2);
1090     }
1091     vLad->Draw();
1092 */    //pad2->Update();
1093     canvas->Update();
1094 }