]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSv11GeometrySPD.cxx
Updated ITS version 11 geometry. Requires ROOT version 4 with a special patch
[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 <TPolyLine.h>
31 // Root Geometry includes
32 #include <TGeoManager.h>
33 #include <TGeoVolume.h>
34 #include <TGeoPcon.h>
35 #include <TGeoCone.h>
36 #include <TGeoTube.h> // contaings TGeoTubeSeg
37 #include <TGeoArb8.h>
38 #include <TGeoEltu.h>
39 #include <TGeoXtru.h>
40 #include <TGeoCompositeShape.h>
41 #include <TGeoMatrix.h>
42 //#include <TGeoRotation.h>
43 //#include <TGeoCombiTrans.h>
44 //#include <TGeoTranslation.h>
45 #include "AliITSv11GeometrySPD.h"
46
47 ClassImp(AliITSv11GeometrySPD)
48
49 #define SQ(A) (A)*(A)
50
51 //______________________________________________________________________
52 void AliITSv11GeometrySPD::CarbonFiberSector(TGeoVolume *moth){
53     // Define the detail SPD Carbon fiber support Sector geometry.
54     // Based on the drawings ALICE-Pixel "Construzione Profilo Modulo"
55     // March 25 2004 and ALICE-SUPPORTO "construzione Profilo Modulo"
56     // Define Outside radii as negitive, Outside in the sence that the
57     // center of the arc is outside of the object.
58     // February 16 2004.
59     // Inputs:
60     //   none.
61     // Outputs:
62     //  none.
63     // Return:
64     //  none.
65     TGeoManager *mgr = gGeoManager;
66     TGeoMedium *medSPDcf  = 0; // SPD support cone Carbon Fiber materal number.
67     //TGeoMedium *medSPDfs  = 0; // SPD support cone inserto stesalite 4411w.
68     //TGeoMedium *medSPDfo  = 0; // SPD support cone foam, Rohacell 50A.
69     TGeoMedium *medSPDss  = 0; // SPD support cone screw material,Stainless
70     TGeoMedium *medSPDair = 0; // SPD support cone Air
71     //TGeoMedium *medSPDal  = 0; // SPD support cone SDD mounting bracket Al
72     TGeoMedium *medSPDcoolfl  = 0; // SPD cooling fluid, Freeon
73     medSPDcf = mgr->GetMedium("ITSspdCarbonFiber");
74     //medSPDfs = mgr->GetMedium("ITSspdStaselite4411w");
75     //medSPDfo = mgr->GetMedium("ITSspdRohacell50A");
76     medSPDss = mgr->GetMedium("ITSspdStainlessSteal");
77     medSPDair= mgr->GetMedium("ITSspdAir");
78     medSPDcoolfl= mgr->GetMedium("ITSspdCoolingFluid");
79     //
80     const Double_t ksecDz        = 0.5*500.0*fgkmm;
81     const Double_t ksecLen       = 30.0*fgkmm;
82     const Double_t ksecCthick    = 0.20*fgkmm;
83     const Double_t ksecDipLength = 3.2*fgkmm;
84     const Double_t ksecDipRadii  = 0.4*fgkmm;
85     //const Double_t ksecCoolingTubeExtraDepth = 0.86*fgkmm;
86     //
87     const Double_t ksecX0   = -10.725*fgkmm;
88     const Double_t ksecY0   = -14.853*fgkmm;
89     const Double_t ksecR0   = -0.8*fgkmm; // Outside
90     const Double_t ksecX1   = -13.187*fgkmm;
91     const Double_t ksecY1   = -19.964*fgkmm;
92     const Double_t ksecR1   = +0.6*fgkmm; // Inside
93     //const Double_t ksecDip0 = 5.9*fgkmm;
94     //
95     const Double_t ksecX2   = -3.883*fgkmm;
96     const Double_t ksecY2   = -17.805*fgkmm;
97     const Double_t ksecR2   = +0.80*fgkmm; // Inside Guess. 
98     const Double_t ksecX3   = -3.123*fgkmm;
99     const Double_t ksecY3   = -14.618*fgkmm;
100     const Double_t ksecR3   = -0.6*fgkmm; // Outside
101     //const Double_t ksecDip1 = 8.035*fgkmm;
102     //
103     const Double_t ksecX4   = +11.280*fgkmm;
104     const Double_t ksecY4   = -14.473*fgkmm;
105     const Double_t ksecR4   = +0.8*fgkmm; // Inside
106     const Double_t ksecX5   = +19.544*fgkmm;
107     const Double_t ksecY5   = +10.961*fgkmm;
108     const Double_t ksecR5   = +0.8*fgkmm; // Inside
109     //const Double_t ksecDip2 = 4.553*fgkmm;
110     //
111     const Double_t ksecX6   = +10.830*fgkmm;
112     const Double_t ksecY6   = +16.858*fgkmm;
113     const Double_t ksecR6   = +0.6*fgkmm; // Inside
114     const Double_t ksecX7   = +11.581*fgkmm;
115     const Double_t ksecY7   = +13.317*fgkmm;
116     const Double_t ksecR7   = -0.6*fgkmm; // Outside
117     //const Double_t ksecDip3 = 6.978*fgkmm;
118     //
119     const Double_t ksecX8   = -0.733*fgkmm;
120     const Double_t ksecY8   = +17.486*fgkmm;
121     const Double_t ksecR8   = +0.6*fgkmm; // Inside
122     const Double_t ksecX9   = +0.562*fgkmm;
123     const Double_t ksecY9   = +14.486*fgkmm;
124     const Double_t ksecR9   = -0.6*fgkmm; // Outside
125     //const Double_t ksecDip4 = 6.978*fgkmm;
126     //
127     const Double_t ksecX10  = -12.252*fgkmm;
128     const Double_t ksecY10  = +16.298*fgkmm;
129     const Double_t ksecR10  = +0.6*fgkmm; // Inside
130     const Double_t ksecX11  = -10.445*fgkmm;
131     const Double_t ksecY11  = +13.162*fgkmm;
132     const Double_t ksecR11  = -0.6*fgkmm; // Outside
133     //const Double_t ksecDip5 = 6.978*fgkmm;
134     //
135     const Double_t ksecX12  = -22.276*fgkmm;
136     const Double_t ksecY12  = +12.948*fgkmm;
137     const Double_t ksecR12  = +0.85*fgkmm; // Inside
138     //const Double_t ksecX13 = *fgkmm;
139     //const Double_t ksecY13 = *fgkmm;
140     const Double_t ksecR13  = -0.8*fgkmm; // Outside
141     const Double_t ksecAngleSide13 = 36.0*fgkDegree;
142     //
143     const Int_t ksecNRadii = 20;
144     const Int_t ksecNPointsPerRadii = 4;
145     const Int_t ksecNCoolingTubeDips = 6;
146     // Since the Rounded parts are aproximated by a regular polygon and
147     // a cooling tube of the propper diameter must fit, a scaling factor
148     // increases the size of the polygon for the tube to fit.
149     //const Double_t ksecRCoolScale = 1./TMath::Cos(TMath::Pi()/
150     //                                          (Double_t)ksecNPointsPerRadii);
151     const Double_t ksecZEndLen  = 30.00*fgkmm;
152     //const Double_t ksecZFlangLen= 45.00*fgkmm;
153     const Double_t ksecTl       = 0.860*fgkmm;
154     const Double_t ksecCthick2  = 0.600*fgkmm;
155     //const Double_t ksecCthick3  = 1.800*fgkmm;
156     //const Double_t ksecSidelen  = 22.00*fgkmm;
157     //const Double_t ksecSideD5   = 3.679*fgkmm;
158     //const Double_t ksecSideD12  = 7.066*fgkmm;
159     const Double_t ksecRCoolOut = 2.400*fgkmm;
160     const Double_t ksecRCoolIn  = 2.000*fgkmm;
161     const Double_t ksecDl1      = 5.900*fgkmm;
162     const Double_t ksecDl2      = 8.035*fgkmm;
163     const Double_t ksecDl3      = 4.553*fgkmm;
164     const Double_t ksecDl4      = 6.978*fgkmm;
165     const Double_t ksecDl5      = 6.978*fgkmm;
166     const Double_t ksecDl6      = 6.978*fgkmm;
167     const Double_t ksecCoolTubeThick  = 0.04*fgkmm;
168     const Double_t ksecCoolTubeROuter = 2.6*fgkmm;
169     const Double_t ksecCoolTubeFlatX  = 3.696*fgkmm;
170     const Double_t ksecCoolTubeFlatY  = 0.68*fgkmm;
171     //const Double_t ksecBeamX0   = 0.0*fgkmm; // guess
172     //const Double_t ksecBeamY0   = (15.223+40.)*fgkmm; // guess
173     //
174     const Int_t ksecNPoints = (ksecNPointsPerRadii+1)*ksecNRadii + 8;
175     Double_t secX[ksecNRadii] = {ksecX0,ksecX1,-1000.0,ksecX2 ,ksecX3 ,-1000.0,
176                                  ksecX4,ksecX5,-1000.0,ksecX6 ,ksecX7 ,-1000.0,
177                                  ksecX8,ksecX9,-1000.0,ksecX10,ksecX11,-1000.0,
178                                  ksecX12,-1000.0};
179     Double_t secY[ksecNRadii] = {ksecY0,ksecY1,-1000.0,ksecY2 ,ksecY3 ,-1000.0,
180                                  ksecY4,ksecY5,-1000.0,ksecY6 ,ksecY7 ,-1000.0,
181                                  ksecY8,ksecY9,-1000.0,ksecY10,ksecY11,-1000.0,
182                                  ksecY12,-1000.0};
183     Double_t secR[ksecNRadii] ={ksecR0 ,ksecR1 ,-.5*ksecDipLength-ksecDipRadii,
184                                 ksecR2 ,ksecR3 ,-.5*ksecDipLength-ksecDipRadii,
185                                 ksecR4 ,ksecR5 ,-.5*ksecDipLength-ksecDipRadii,
186                                 ksecR6 ,ksecR7 ,-.5*ksecDipLength-ksecDipRadii,
187                                 ksecR8 ,ksecR9 ,-.5*ksecDipLength-ksecDipRadii,
188                                 ksecR10,ksecR11,-.5*ksecDipLength-ksecDipRadii,
189                                 ksecR12,ksecR13};/*
190     Double_t secDip[ksecNRadii]={0.0,0.0,ksecDip0,0.0,0.0,ksecDip1,
191                                  0.0,0.0,ksecDip2,0.0,0.0,ksecDip3,
192                                  0.0,0.0,ksecDip4,0.0,0.0,ksecDip5,
193                                  0.0,0.0};*/
194     Double_t secX2[ksecNRadii];
195     Double_t secY2[ksecNRadii];
196     Double_t secR2[ksecNRadii] = {
197         ksecR0,ksecR1,ksecRCoolOut,ksecR2,ksecR3,ksecRCoolOut,ksecR4,ksecR5,
198         ksecRCoolOut,ksecR6,ksecR7,ksecRCoolOut,ksecR8,ksecR9,ksecRCoolOut,
199         ksecR10,ksecR11,ksecRCoolOut,ksecR12,ksecR13};
200     Double_t secDip2[ksecNCoolingTubeDips]={ksecDl1,ksecDl2,ksecDl3,
201                                             ksecDl4,ksecDl5,ksecDl6};
202     Double_t secX3[ksecNRadii];
203     Double_t secY3[ksecNRadii];
204     const Int_t ksecDipIndex[ksecNCoolingTubeDips] = {2,5,8,11,14,17};
205     Double_t secAngleStart[ksecNRadii];
206     Double_t secAngleEnd[ksecNRadii];
207     Double_t secAngleStart2[ksecNRadii];
208     Double_t secAngleEnd2[ksecNRadii];
209     Double_t secAngleTurbo[ksecNCoolingTubeDips] = {0.0,0.0,0.0,0.0,0.0,0.0};
210     //Double_t secAngleStart3[ksecNRadii];
211     //Double_t secAngleEnd3[ksecNRadii];
212     Double_t xpp[ksecNPoints],ypp[ksecNPoints];
213     Double_t xpp2[ksecNPoints],ypp2[ksecNPoints];
214     Double_t *xp[ksecNRadii],*xp2[ksecNRadii];
215     Double_t *yp[ksecNRadii],*yp2[ksecNRadii];
216     TGeoXtru *sA0,*sA1,*sB0,*sB1;
217     TGeoEltu *sTA0,*sTA1;
218     TGeoTube *sTB0,*sTB1,*sM0;
219     TGeoRotation    *rot;
220     TGeoTranslation *trans;
221     TGeoCombiTrans  *rotrans;
222     Double_t t,t0,t1,a,b,x0,y0,x1,y1;
223     Int_t i,j,k,m;
224     Bool_t tst;
225
226     if(moth==0){
227         Error("CarbonFiberSector","moth=%p",moth);
228         return;
229     } // end if moth==0
230     //SetDebug(3);
231     for(i=0;i<ksecNRadii;i++){
232         xp[i]  = &(xpp[i*(ksecNPointsPerRadii+1)]);
233         yp[i]  = &(ypp[i*(ksecNPointsPerRadii+1)]);
234         xp2[i] = &(xpp2[i*(ksecNPointsPerRadii+1)]);
235         yp2[i] = &(ypp2[i*(ksecNPointsPerRadii+1)]);
236         secX2[i] = secX[i];
237         secY2[i] = secY[i];
238         secX3[i] = secX[i];
239         secY3[i] = secY[i];
240     } // end for i
241
242     // Find starting and ending angles for all but cooling tube sections
243     secAngleStart[0] = 0.5*ksecAngleSide13;
244     for(i=0;i<ksecNRadii-2;i++){
245         tst = kFALSE;
246         for(j=0;j<ksecNCoolingTubeDips;j++) tst = tst||i==ksecDipIndex[j];
247         if(tst) continue;
248         tst = kFALSE;
249         for(j=0;j<ksecNCoolingTubeDips;j++) tst = tst||(i+1)==ksecDipIndex[j];
250         if(tst) j = i+2;
251         else j = i+1;
252         AnglesForRoundedCorners(secX[i],secY[i],secR[i],
253                                 secX[j],secY[j],secR[j],t0,t1);
254         secAngleEnd[i]   = t0;
255         secAngleStart[j] = t1;
256         if(secR[i]>0.0&&secR[j]>0.0)if(secAngleStart[i]>secAngleEnd[i])
257             secAngleEnd[i] += 360.0;
258         secAngleStart2[i] = secAngleStart[i];
259         secAngleEnd2[i]   = secAngleEnd[i];
260     } // end for i
261     secAngleEnd[ksecNRadii-2]   = secAngleStart[ksecNRadii-2] + 
262                                      (secAngleEnd[ksecNRadii-5]-
263                                       secAngleStart[ksecNRadii-5]);
264     if(secAngleEnd[ksecNRadii-2]<0.0) secAngleEnd[ksecNRadii-2] += 360.0;
265     secAngleStart[ksecNRadii-1] = secAngleEnd[ksecNRadii-2] - 180.0;
266     secAngleEnd[ksecNRadii-1]   = secAngleStart[0];
267     secAngleStart2[ksecNRadii-2] = secAngleStart[ksecNRadii-2];
268     secAngleEnd2[ksecNRadii-2]   = secAngleEnd[ksecNRadii-2];
269     secAngleStart2[ksecNRadii-1] = secAngleStart[ksecNRadii-1];
270     secAngleEnd2[ksecNRadii-1]   = secAngleEnd[ksecNRadii-1];
271     // Find location of circle last rounded corner.
272     i = 0;
273     j = ksecNRadii-2;
274     t0 = TanD(secAngleStart[i]-90.);
275     t1 = TanD(secAngleEnd[j]-90.);
276     t  = secY[i] - secY[j];
277     // Note, secR[i=0] <0; secR[j=18]>0; and secR[j+1=19] <0
278     t += (-secR[i]+secR[j+1])*SinD(secAngleStart[i]);
279     t -= (secR[j]-secR[j+1])*SinD(secAngleEnd[j]);
280     t += t1*secX[j] - t0*secX[i];
281     t += t1*(secR[j]-secR[j+1])*CosD(secAngleEnd[j]);
282     t -= t0*(-secR[i]+secR[j+1])*CosD(secAngleStart[i]);
283     secX[ksecNRadii-1] = t/(t1-t0);
284     secY[ksecNRadii-1] = TanD(90.+0.5*ksecAngleSide13)*
285                           (secX[ksecNRadii-1]-secX[0]) + secY[0];
286     secX2[ksecNRadii-1] = secX[ksecNRadii-1];
287     secY2[ksecNRadii-1] = secY[ksecNRadii-1];
288     secX3[ksecNRadii-1] = secX[ksecNRadii-1];
289     secY3[ksecNRadii-1] = secY[ksecNRadii-1];
290     // find location of cooling tube centers
291     for(i=0;i<ksecNCoolingTubeDips;i++){
292         j = ksecDipIndex[i];
293         x0 = secX[j-1] + TMath::Abs(secR[j-1])*CosD(secAngleEnd[j-1]);
294         y0 = secY[j-1] + TMath::Abs(secR[j-1])*SinD(secAngleEnd[j-1]);
295         x1 = secX[j+1] + TMath::Abs(secR[j+1])*CosD(secAngleStart[j+1]);
296         y1 = secY[j+1] + TMath::Abs(secR[j+1])*SinD(secAngleStart[j+1]);
297         t0 = TMath::Sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
298         t  = secDip2[i]/t0;
299         a  = x0+(x1-x0)*t;
300         b  = y0+(y1-y0)*t;
301         if(a+b*(a-x0)/(b-y0)>0.0){
302             secX[j] = a + TMath::Abs(y1-y0)*2.0*ksecDipRadii/t0;
303             secY[j] = b - TMath::Sign(2.0*ksecDipRadii,y1-y0)*(x1-x0)/t0;
304             secX2[j] = a + TMath::Abs(y1-y0)*ksecTl/t0;
305             secY2[j] = b - TMath::Sign(ksecTl,y1-y0)*(x1-x0)/t0;
306             secX3[j] = a + TMath::Abs(y1-y0)*(2.0*ksecDipRadii-
307                                               0.5*ksecCoolTubeFlatY)/t0;
308             secY3[j] = b - TMath::Sign(2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY,
309                                        y1-y0)*(x1-x0)/t0;
310         }else{
311             secX[j] = a - TMath::Abs(y1-y0)*2.0*ksecDipRadii/t0;
312             secY[j] = b + TMath::Sign(2.0*ksecDipRadii,y1-y0)*(x1-x0)/t0;
313             secX2[j] = a - TMath::Abs(y1-y0)*ksecTl/t0;
314             secY2[j] = b + TMath::Sign(ksecTl,y1-y0)*(x1-x0)/t0;
315             secX3[j] = a - TMath::Abs(y1-y0)*(2.0*ksecDipRadii-
316                                               0.5*ksecCoolTubeFlatY)/t0;
317             secY3[j] = b + TMath::Sign(2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY,
318                                        y1-y0)*(x1-x0)/t0;
319         } // end if
320         // Set up Start and End angles to correspond to start/end of dips.
321         t1 = (secDip2[i]-TMath::Abs(secR[j]))/t0;
322         secAngleStart[j] = TMath::RadToDeg()*TMath::ATan2(
323                                y0+(y1-y0)*t1-secY[j],x0+(x1-x0)*t1-secX[j]);
324         if(secAngleStart[j]<0.0) secAngleStart[j] += 360.0;
325         secAngleStart2[j] = secAngleStart[j];
326         t1 = (secDip2[i]+TMath::Abs(secR[j]))/t0;
327         secAngleEnd[j] = TMath::RadToDeg()*TMath::ATan2(
328                                y0+(y1-y0)*t1-secY[j],x0+(x1-x0)*t1-secX[j]);
329         if(secAngleEnd[j]<0.0) secAngleEnd[j] += 360.0;
330         secAngleEnd2[j]   = secAngleEnd[j];
331         if(secAngleEnd[j]>secAngleStart[j]) secAngleEnd[j] -= 360.0;
332         secR[j] = TMath::Sqrt(secR[j]*secR[j]+4.0*ksecDipRadii*ksecDipRadii);
333     } // end if
334     // Spcial cases
335     secAngleStart2[8] -= 360.;
336     secAngleStart2[11] -= 360.;
337     //
338     SPDsectorShape(ksecNRadii,secX,secY,secR,secAngleStart,secAngleEnd,
339                    ksecNPointsPerRadii,m,xp,yp);
340     //  Fix up dips to be square.
341     for(i=0;i<ksecNCoolingTubeDips;i++){
342         j = ksecDipIndex[i];
343         t = 0.5*ksecDipLength+ksecDipRadii;
344         t0 = TMath::RadToDeg()*TMath::ATan(2.0*ksecDipRadii/t);
345         t1 = secAngleEnd[j] + t0;
346         t0 = secAngleStart[j] - t0;
347         x0 = xp[j][1] = secX[j] + t*CosD(t0);
348         y0 = yp[j][1] = secY[j] + t*SinD(t0);
349         x1 = xp[j][ksecNPointsPerRadii-1] = secX[j] + t*CosD(t1);
350         y1 = yp[j][ksecNPointsPerRadii-1] = secY[j] + t*SinD(t1);
351         t0 = 1./((Double_t)(ksecNPointsPerRadii-2));
352         for(k=2;k<ksecNPointsPerRadii-1;k++){// extra points spread them out.
353             t = ((Double_t)(k-1))*t0;
354             xp[j][k] = x0+(x1-x0)*t;
355             yp[j][k] = y0+(y1-y0)*t;
356         } // end for k
357         secAngleTurbo[i] = -TMath::RadToDeg()*TMath::ATan2(y1-y0,x1-x0);
358         if(GetDebug(3)){ 
359            cout <<"i="<<i<<" angle="<<secAngleTurbo[i]<<" x0,y0{"
360                 <<x0<<","<<y0<<"} x1y1={"<<x1<<","<<y1<<"}"<<endl;
361         } // end if
362     } // end for i
363     sA0 = new TGeoXtru(2);
364     sA0->SetName("ITS SPD Carbon fiber support Sector A0");
365     sA0->DefinePolygon(m,xpp,ypp);
366     sA0->DefineSection(0,-ksecDz);
367     sA0->DefineSection(1,ksecDz);
368     //
369     InsidePoint(xpp[m-1],ypp[m-1],xpp[0],ypp[0],xpp[1],ypp[1],
370                 ksecCthick,xpp2[0],ypp2[0]);
371     for(i=1;i<m-1;i++){
372         j = i/(ksecNPointsPerRadii+1);
373         InsidePoint(xpp[i-1],ypp[i-1],xpp[i],ypp[i],xpp[i+1],ypp[i+1],
374                     ksecCthick,xpp2[i],ypp2[i]);
375     } // end for i
376     InsidePoint(xpp[m-2],ypp[m-2],xpp[m-1],ypp[m-1],xpp[0],ypp[0],
377                 ksecCthick,xpp2[m-1],ypp2[m-1]);
378     // Fix center value of cooling tube dip.
379     // find location of cooling tube centers
380     for(i=0;i<ksecNCoolingTubeDips;i++){
381         j = ksecDipIndex[i];
382         x0 = xp2[j][1];
383         y0 = yp2[j][1];
384         x1 = xp2[j][ksecNPointsPerRadii-1];
385         y1 = yp2[j][ksecNPointsPerRadii-1];
386         t0 = TMath::Sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
387         t  = secDip2[i]/t0;
388         for(k=2;k<ksecNPointsPerRadii-1;k++){// extra points spread them out.
389             t = ((Double_t)(k-1))*t0;
390             xp2[j][k] = x0+(x1-x0)*t;
391             yp2[j][k] = y0+(y1-y0)*t;
392         } // end for k
393     } // end for i
394     sA1 = new TGeoXtru(2);
395     sA1->SetName("ITS SPD Carbon fiber support Sector Air A1");
396     sA1->DefinePolygon(m,xpp2,ypp2);
397     sA1->DefineSection(0,-ksecDz);
398     sA1->DefineSection(1,ksecDz);
399     //
400     // Error in TGeoEltu. Semi-axis X must be < Semi-axis Y (?).
401     sTA0 = new TGeoEltu("ITS SPD Cooling Tube TA0",
402                       0.5* ksecCoolTubeFlatY, 0.5* ksecCoolTubeFlatX,ksecDz);
403     sTA1 = new TGeoEltu("ITS SPD Cooling Tube coolant TA1",
404                         sTA0->GetA()-ksecCoolTubeThick,
405                         sTA0->GetB()-ksecCoolTubeThick,ksecDz);
406     //
407     SPDsectorShape(ksecNRadii,secX2,secY2,secR2,secAngleStart2,secAngleEnd2,
408                    ksecNPointsPerRadii,m,xp,yp);
409     //
410     sB0 = new TGeoXtru(2);
411     sB0->SetName("ITS SPD Carbon fiber support Sector End B0");
412     sB0->DefinePolygon(m,xpp,ypp);
413     sB0->DefineSection(0,ksecDz);
414     sB0->DefineSection(1,ksecDz+ksecZEndLen);
415     //
416     InsidePoint(xpp[m-1],ypp[m-1],xpp[0],ypp[0],xpp[1],ypp[1],
417                 ksecCthick2,xpp2[0],ypp2[0]);
418     for(i=1;i<m-1;i++){
419         t = ksecCthick2;
420         for(k=0;k<ksecNCoolingTubeDips;k++)
421             if((i/(ksecNPointsPerRadii+1))==ksecDipIndex[k]) 
422                 if(!(ksecDipIndex[k]*(ksecNPointsPerRadii+1)==i || 
423                      ksecDipIndex[k]*(ksecNPointsPerRadii+1)+
424                      ksecNPointsPerRadii==i   )) 
425                     t = ksecRCoolOut-ksecRCoolIn;
426         InsidePoint(xpp[i-1],ypp[i-1],xpp[i],ypp[i],xpp[i+1],ypp[i+1],
427                     t,xpp2[i],ypp2[i]);
428     } // end for i
429     InsidePoint(xpp[m-2],ypp[m-2],xpp[m-1],ypp[m-1],xpp[0],ypp[0],
430                 ksecCthick2,xpp2[m-1],ypp2[m-1]);
431     sB1 = new TGeoXtru(2);
432     sB1->SetName("ITS SPD Carbon fiber support Sector Air End B1");
433     sB1->DefinePolygon(m,xpp2,ypp2);
434     sB1->DefineSection(0,ksecDz);
435     sB1->DefineSection(1,ksecDz+ksecLen);
436     sTB0 = new TGeoTube("ITS SPD Cooling Tube End TB0",0.0,
437                        0.5*ksecCoolTubeROuter,0.5*ksecLen);
438     sTB1 = new TGeoTube("ITS SPD Cooling Tube End coolant TB0",0.0,
439                        sTB0->GetRmax()-ksecCoolTubeThick,0.5*ksecLen);
440     //
441     sM0 = new TGeoTube("ITS SPD Sensitive Virutual Volume M0",0.0,8.0,
442                        sA0->GetZ(1)+sB0->GetZ(1));
443     //
444     if(GetDebug()){
445         sM0->InspectShape();
446         sA0->InspectShape();
447         sA1->InspectShape();
448         sB0->InspectShape();
449         sB1->InspectShape();
450     } // end if GetDebug
451     //
452     TGeoVolume *vM0,*vA0,*vA1,*vTA0,*vTA1,*vB0,*vB1,*vTB0,*vTB1;
453     vM0 = new TGeoVolume("ITSSPDSensitiveVirtualvolumeM0",sM0,medSPDair);
454     vM0->SetVisibility(kTRUE);
455     vM0->SetLineColor(7); // light Blue
456     vM0->SetLineWidth(1);
457     vM0->SetFillColor(vM0->GetLineColor());
458     vM0->SetFillStyle(4090); // 90% transparent
459     vA0 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorA0",sA0,medSPDcf);
460     vA0->SetVisibility(kTRUE);
461     vA0->SetLineColor(4); // Blue
462     vA0->SetLineWidth(1);
463     vA0->SetFillColor(vA0->GetLineColor());
464     vA0->SetFillStyle(4010); // 10% transparent
465     vA1 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorAirA1",sA1,medSPDair);
466     vA1->SetVisibility(kTRUE);
467     vA1->SetLineColor(7); // light Blue
468     vA1->SetLineWidth(1);
469     vA1->SetFillColor(vA1->GetLineColor());
470     vA1->SetFillStyle(4090); // 90% transparent
471     vTA0 = new TGeoVolume("ITSSPDCoolingTubeTA0",sTA0,medSPDss);
472     vTA0->SetVisibility(kTRUE);
473     vTA0->SetLineColor(1); // Black
474     vTA0->SetLineWidth(1);
475     vTA0->SetFillColor(vTA0->GetLineColor());
476     vTA0->SetFillStyle(4000); // 0% transparent
477     vTA1 = new TGeoVolume("ITSSPDCoolingTubeFluidTA1",sTA1,medSPDcoolfl);
478     vTA1->SetVisibility(kTRUE);
479     vTA1->SetLineColor(6); // Purple
480     vTA1->SetLineWidth(1);
481     vTA1->SetFillColor(vTA1->GetLineColor());
482     vTA1->SetFillStyle(4000); // 0% transparent
483     vB0 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorEndB0",sB0,medSPDcf);
484     vB0->SetVisibility(kTRUE);
485     vB0->SetLineColor(4); // Blue
486     vB0->SetLineWidth(1);
487     vB0->SetFillColor(vB0->GetLineColor());
488     vB0->SetFillStyle(4010); // 10% transparent
489     vB1 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorEndAirB1",
490                          sB1,medSPDair);
491     vB1->SetVisibility(kTRUE);
492     vB1->SetLineColor(7); // light Blue
493     vB1->SetLineWidth(1);
494     vB1->SetFillColor(vB1->GetLineColor());
495     vB1->SetFillStyle(4090); // 90% transparent
496     vTB0 = new TGeoVolume("ITSSPDCoolingTubeEndTB0",sTB0,medSPDss);
497     vTB0->SetVisibility(kTRUE);
498     vTB0->SetLineColor(1); // Black
499     vTB0->SetLineWidth(1);
500     vTB0->SetFillColor(vTB0->GetLineColor());
501     vTB0->SetFillStyle(4000); // 0% transparent
502     vTB1 = new TGeoVolume("ITSSPDCoolingTubeEndFluidTB1",sTB1,medSPDcoolfl);
503     vTB1->SetVisibility(kTRUE);
504     vTB1->SetLineColor(6); // Purple
505     vTB1->SetLineWidth(1);
506     vTB1->SetFillColor(vTB1->GetLineColor());
507     vTB1->SetFillStyle(4000); // 0% transparent
508     //
509     moth->AddNode(vM0,1,0); // Add virtual volume to mother
510     vA0->AddNode(vA1,1,0); // Put air inside carbon fiber.
511     vB0->AddNode(vB1,1,0); // Put air inside carbon fiber.
512     vTA0->AddNode(vTA1,1,0); // Put air inside carbon fiber.
513     vTB0->AddNode(vTB1,1,0); // Put air inside carbon fiber.
514     for(i=0;i<ksecNCoolingTubeDips;i++){
515         x0 = secX3[ksecDipIndex[i]];
516         y0 = secY3[ksecDipIndex[i]];
517         t = 90.0-secAngleTurbo[i];
518         trans = new TGeoTranslation("",x0,y0,0.5*(sB1->GetZ(0)+sB1->GetZ(1)));
519         vB1->AddNode(vTB0,i+1,trans);
520         rot = new TGeoRotation("",0.0,0.0,t);
521         rotrans = new TGeoCombiTrans("",x0,y0,0.0,rot);
522         vM0->AddNode(vTA0,i+1,rotrans);
523         delete rot; // rot owned by AliITSv11GeometerySPD::CarbonFiberSector
524     } // end for i
525     vM0->AddNode(vA0,1,0);
526     vM0->AddNode(vB0,1,0);
527     // Reflection.
528     vM0->AddNode(vB0,2,new TGeoRotation("",90.,0.,90.,90.,180.,0.));
529     if(GetDebug()){
530         vM0->PrintNodes();
531         vA0->PrintNodes();
532         vA1->PrintNodes();
533         vB0->PrintNodes();
534         vB1->PrintNodes();
535     } // end if GetDebug
536     //
537 }
538 //----------------------------------------------------------------------
539 void AliITSv11GeometrySPD::SPDsectorShape(Int_t n,const Double_t *xc,
540 const Double_t *yc,const Double_t *r,const Double_t *ths,const Double_t *the,
541                                Int_t npr,Int_t &m,Double_t **xp,Double_t **yp){
542     // Code to compute the points that make up the shape of the SPD
543     // Carbon fiber support sections
544     // Inputs:
545     //    Int_t    n       Size of arrays xc,yc, and r.
546     //    Double_t *xc     Array of x values for radii centers.
547     //    Double_t *yc     Array of y values for radii centers.
548     //    Double_t *r      Array of signed radii values.
549     //    Double_t *ths    Array of starting angles [degrees].
550     //    Double_t *the    Array of ending angles [degrees].
551     //    Int_t    npr     The number of lines segments to aproximate the arc.
552     // Outputs:
553     //    Int_t    m       The number of enetries in the arrays *xp[npr+1] 
554     //                     and *yp[npr+1].
555     //    Double_t **xp    Array of x coordinate values of the line segments
556     //                     which make up the SPD support sector shape.
557     //    Double_t **yp    Array of y coordinate values of the line segments
558     //                     which make up the SPD support sector shape.
559     // Return:
560     //    none.
561     Int_t i,k;
562     Double_t t,t0,t1;
563
564     m = n*(npr+1);
565     if(GetDebug(2)){
566         cout <<"    X    \t  Y  \t  R  \t  S  \t  E"<< m <<endl;
567         for(i=0;i<n;i++){
568             cout <<"{"<< xc[i] <<",";
569             cout << yc[i] <<",";
570             cout << r[i] <<",";
571             cout << ths[i] <<",";
572             cout << the[i] <<"},"<< endl;
573         } // end for i
574     } // end if GetDebug
575     //
576     if(GetDebug(3)) cout <<"Double_t sA0 = ["<< n*(npr+1)+1<<"][";
577     if(GetDebug(4)) cout <<"3]{";
578     else if(GetDebug(3)) cout <<"2]{";
579     t0 = (Double_t)npr;
580     for(i=0;i<n;i++){
581         t1 = (the[i]-ths[i])/t0;
582         if(GetDebug(5)) cout<<"t1="<< t1<<endl;
583         for(k=0;k<=npr;k++){
584             t=ths[i]+((Double_t)k)*t1;
585             xp[i][k] = TMath::Abs(r[i])*CosD(t)+xc[i];
586             yp[i][k] = TMath::Abs(r[i])*SinD(t)+yc[i];
587             if(GetDebug(3)){
588                 cout << "{"<<xp[i][k]<<","<<yp[i][k];
589                 if(GetDebug(4)) cout <<","<<t;
590                 cout <<"},";
591             } // end if GetDebug
592         } // end for k
593         if(GetDebug(3)) cout << endl;
594     } // end of i
595     if(GetDebug(3)) cout<<"{"<<xp[0][0]<<","<<yp[0][0];
596     if(GetDebug(4)) cout<<","<< ths[0];
597     if(GetDebug(3)) cout<<"}}"<<endl;
598     //
599     return;
600 }
601 //______________________________________________________________________
602 void AliITSv11GeometrySPD::HalfStave(TGeoVolume *moth){
603     // Define the detail SPD Half Stave geometry.
604     // Inputs:
605     //   none.
606     // Outputs:
607     //  none.
608     // Return:
609     //  none.
610
611     if(moth==0){
612         Error("HalfStave","moth=%p",moth);
613         return;
614     } // end if moth==0
615 }
616 //----------------------------------------------------------------------
617 void AliITSv11GeometrySPD::CreateFigure0(const Char_t *filepath,
618                                          const Char_t *type){
619     // Creates Figure 0 for the documentation of this class. In this
620     // specific case, it creates the X,Y cross section of the SPD suport
621     // section, center and ends. The output is written to a standard
622     // file name to the path specificed.
623     // Inputs:
624     //   const Char_t *filepath  Path where the figure is to be drawn
625     //   const Char_t *type      The type of file, default is gif.
626     // Output:
627     //   none.
628     // Return:
629     //   none.
630     TGeoXtru *sA0,*sA1,*sB0,*sB1;
631     //TPolyMarker *pmA,*pmB;
632     TPolyLine plA0,plA1,plB0,plB1;
633     TCanvas *canvas;
634     TLatex txt;
635     Double_t x=0.0,y=0.0;
636     Int_t i,kNRadii=6;
637
638     if(strcmp(filepath,"")){
639         Error("CreateFigure0","filepath=%s type=%s",filepath,type);
640     } // end if
641     //
642     sA0 = (TGeoXtru*) gGeoManager->GetVolume(
643         "ITSSPDCarbonFiberSupportSectorA0_1")->GetShape();
644     sA1 = (TGeoXtru*) gGeoManager->GetVolume(
645         "ITSSPDCarbonFiberSupportSectorAirA1_1")->GetShape();
646     sB0 = (TGeoXtru*) gGeoManager->GetVolume(
647         "ITSSPDCarbonFiberSupportSectorEndB0_1")->GetShape();
648     sB1 = (TGeoXtru*) gGeoManager->GetVolume(
649         "ITSSPDCarbonFiberSupportSectorEndAirB1_1")->GetShape();
650     //pmA = new TPolyMarker();
651     //pmA.SetMarkerStyle(2); // +
652     //pmA.SetMarkerColor(7); // light blue
653     //pmB = new TPolyMarker();
654     //pmB.SetMarkerStyle(5); // X
655     //pmB.SetMarkerColor(6); // purple
656     plA0.SetPolyLine(sA0->GetNvert());
657     plA0.SetLineColor(1); // black
658     plA0.SetLineStyle(1);
659     plA1.SetPolyLine(sA1->GetNvert());
660     plA1.SetLineColor(2); // red
661     plA1.SetLineStyle(1);
662     plB0.SetPolyLine(sB0->GetNvert());
663     plB0.SetLineColor(3); // Green
664     plB0.SetLineStyle(2);
665     plB1.SetPolyLine(sB1->GetNvert());
666     plB1.SetLineColor(4); // Blue
667     plB1.SetLineStyle(2);
668     //for(i=0;i<kNRadii;i++) pmA.SetPoint(i,xyB1p[i][0],xyB1p[i][1]);
669     //for(i=0;i<kNRadii;i++) pmB.SetPoint(i,xyB1p[i][0],xyB1p[i][1]);
670     for(i=0;i<sA0->GetNvert();i++) plA0.SetPoint(i,sA0->GetX(i),sA0->GetY(i));
671     for(i=0;i<sA1->GetNvert();i++) plA1.SetPoint(i,sA1->GetX(i),sA1->GetY(i));
672     for(i=0;i<sB0->GetNvert();i++) plB0.SetPoint(i,sB0->GetX(i),sB0->GetY(i));
673     for(i=0;i<sB1->GetNvert();i++) plB1.SetPoint(i,sB1->GetX(i),sB1->GetY(i));
674     canvas = new TCanvas("AliITSv11GeometrySPDFig0","",1000,1000);
675     canvas->Range(-3.,-3.,3.,3.);
676     txt.SetTextSize(0.05);
677     txt.SetTextAlign(33);
678     txt.SetTextColor(1);
679     txt.DrawLatex(2.9,2.9,"Section A-A outer Carbon Fiber surface");
680     txt.SetTextColor(2);
681     txt.DrawLatex(2.9,2.5,"Section A-A Inner Carbon Fiber surface");
682     txt.SetTextColor(3);
683     txt.DrawLatex(2.9,2.1,"Section E-E outer Carbon Fiber surface");
684     txt.SetTextColor(4);
685     txt.DrawLatex(2.9,1.7,"Section E-E Inner Carbon Fiber surface");
686     plA0.Draw();
687     plA1.Draw();
688     plB0.Draw();
689     plB1.Draw();
690     //pmA.Draw();
691     //pmB.Draw();
692     //
693     x = 1.0;
694     y = -2.5;
695     Char_t chr[3];
696     for(i=0;i<kNRadii;i++){
697         sprintf(chr,"%2d",i);txt.DrawLatex(x-0.1,y,chr);
698         sprintf(chr,"%8.4",5.000);txt.DrawLatex(x,y,chr);
699         sprintf(chr,"%8.4",5.000);txt.DrawLatex(x+0.5,y,chr);
700         sprintf(chr,"%8.4",5.000);txt.DrawLatex(x+1.0,y,chr);
701         sprintf(chr,"%8.4",5.000);txt.DrawLatex(x+1.5,y,chr);
702         sprintf(chr,"%8.4",5.000);txt.DrawLatex(x+2.0,y,chr);
703         if(kTRUE) txt.DrawLatex(x+2.5,y,"A-A/E-E");
704         else txt.DrawLatex(x+2.5,y,"E-E");
705     } // end for i
706     txt.DrawLatex(x,y,"x_{c} mm");
707     txt.DrawLatex(x+0.5,y,"y_{c} mm");
708     txt.DrawLatex(x+1.0,y,"R mm");
709     txt.DrawLatex(x+1.5,y,"#theta_{start}^{#circle}");
710     txt.DrawLatex(x+2.0,y,"#theta_{end}^{#circle}");
711     txt.DrawLatex(x+2.5,y,"Section");
712     //
713 }