]>
Commit | Line | Data |
---|---|---|
db486a6e | 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 | } |