update of V11 SPD and support geometry (B. Nilsen)
[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 // General Root includes
25 #include <Riostream.h>
26 #include <TMath.h>
27 #include <TLatex.h>
28 #include <TCanvas.h>
29 #include <TPolyLine.h>
30 // Root Geometry includes
31 #include <TGeoVolume.h>
32 #include <TGeoPcon.h>
33 #include <TGeoCone.h>
34 #include <TGeoTube.h> // contaings TGeoTubeSeg
35 #include <TGeoArb8.h>
36 #include <TGeoEltu.h>
37 #include <TGeoXtru.h>
38 #include <TGeoCompositeShape.h>
39 #include <TGeoMatrix.h>
40 #include <TGeoMaterial.h>
41 #include <TGeoMedium.h>
42 #include "AliMagF.h"
43 #include "AliRun.h"
44 //#include <TGeoRotation.h>
45 //#include <TGeoCombiTrans.h>
46 //#include <TGeoTranslation.h>
47 #include "AliITSv11GeometrySPD.h"
48
49 ClassImp(AliITSv11GeometrySPD)
50
51 #define SQ(A) (A)*(A)
52
53 //______________________________________________________________________
54 Int_t AliITSv11GeometrySPD::CreateSPDCenteralMaterials(Int_t &medOffset,
55                                                        Int_t &matOffset){
56     // Define the specific materials used for the ITS SPD centeral
57     // detectors. Note, These are the same old names. By the ALICE
58     // naming convension, these should start out at ITS SPD ....
59     // This data has been taken from AliITSvPPRasymmFMD::CreateMaterials().
60     // Intputs:
61     //    Int_t  &medOffset   The starting number of the list of media
62     //    Int_t  &matOffset   The starting number of the list of Materials
63     // Outputs:
64     //    Int_t  &medOffset   The ending number of the list of media
65     //    Int_t  &matOffset   The ending number of the list of Materials
66     // Return:
67     //    the last material number used +1 (the next avaiable material number).
68     //Begin_Html
69     /*
70       <img src="http://alice.pd.infn.it/latestdr/all-sections-module.ps"
71        title="SPD Sector drawing with all cross sections defined">
72        <p>The SPD Sector definition.
73       <img src="http://alice.pd.infn.it/latestdr/assembly-10-modules.ps"
74       titile="SPD All Sectors end view with thermal sheald">
75       <p>The SPD all sector end view with thermal sheald.
76       <img src="http://alice.pd.infn.it/latestdr/assembly.ps"
77       title="SPD side view cross section">
78       <p>SPD side view cross section with condes and thermal shealds.
79       <img src="http://alice.pd.infn.it/latestdr/SECTION-A_A.jpg"
80       title="Cross setion A-A"><p>Cross section A-A
81       <img src="http://alice.pd.infn.it/latestdr/SECTION-B_B.jpg"
82       title="Cross section B-B"><p>Cross section B-B
83       <img src="http://alice.pd.infn.it/latestdr/SECTION-C_C.jpg"
84       title-"Cross section C-C"><p>Cross section C-C
85       <img src="http://alice.pd.infn.it/latestdr/SECTION-D_D.jpg"
86       title="Cross section D-D"><p>Cross section D-D
87       <img src="http://alice.pd.infn.it/latestdr/SECTION-F_F.jpg"
88       title="Cross section F-F"><p>Cross section F-F
89       <img src="http://alice.pd.infn.it/latestdr/SECTION-G_G.jpg"
90       title="Cross section G-G"><p>Cross section G-G
91      */
92     //End_Html
93     const Double_t ktmaxfd = 0.1*fgkDegree; // Degree
94     const Double_t kstemax = 1.0*fgkcm; // cm
95     const Double_t kdeemax = 0.1; // Fraction of particle's energy 0<deemax<=1
96     const Double_t kepsil  = 1.0E-4; //
97     const Double_t kstmin  = 0.0*fgkcm; // cm "Default value used"
98     const Double_t ktmaxfdAir = 0.1*fgkDegree; // Degree
99     const Double_t kstemaxAir = 1.0000E+00*fgkcm; // cm
100     const Double_t kdeemaxAir = 0.1; // Fraction of particle's energy 0<deemax<=1
101     const Double_t kepsilAir  = 1.0E-4;//
102     const Double_t kstminAir  = 0.0*fgkcm; // cm "Default value used"
103     const Double_t ktmaxfdSi = 0.1*fgkDegree; // .10000E+01; // Degree
104     const Double_t kstemaxSi = 0.0075*fgkcm; //  .10000E+01; // cm
105     const Double_t kdeemaxSi = 0.1; // Fraction of particle's energy 0<deemax<=1
106     const Double_t kepsilSi  = 1.0E-4;//
107     const Double_t kstminSi  = 0.0*fgkcm; // cm "Default value used"
108     //
109     Int_t matindex=matOffset;
110     Int_t medindex=medOffset;
111     Double_t params[8]={8*0.0};
112     TGeoMaterial *mat;
113     TGeoMixture  *mix;
114     TGeoMedium   *med;
115     //
116     Int_t    ifield = (gAlice->Field()->Integ());
117     Double_t fieldm = (gAlice->Field()->Max());
118     params[1] = (Double_t) ifield;
119     params[2] = fieldm;
120     params[3] = ktmaxfdSi;
121     params[4] = kstemaxSi;
122     params[5] = kdeemaxSi;
123     params[6] = kepsilSi;
124     params[7] = kstminSi;
125
126     mat = new TGeoMaterial("SI",28.086,14.0,2.33*fgkgcm3,
127                            TGeoMaterial::kMatStateSolid,25.0*fgkCelsius,
128                            0.0*fgkPascal);
129     mat->SetIndex(matindex);
130     med = new TGeoMedium("SI",medindex++,mat,params);
131     //med = new TGeoMedium("SI",medindex++,matindex++,0,ifield,
132     //           fieldm,ktmaxfdSi,kstemaxSi,kdeemaxSi,kepsilSi,kstminSi);
133     //
134     mat = new TGeoMaterial("SPD SI CHIP",28.086,14.0,2.33*fgkgcm3,
135                            TGeoMaterial::kMatStateSolid,25.0*fgkCelsius,
136                            0.0*fgkPascal);
137     mat->SetIndex(matindex);
138     med = new TGeoMedium("SPD SI CHIP",medindex++,mat,params);
139     //med = new TGeoMedium("SPD SI CHIP",medindex++,matindex++,0,ifield,
140     //           fieldm,ktmaxfdSi,kstemaxSi,kdeemaxSi,kepsilSi,kstminSi);
141     //
142     mat = new TGeoMaterial("SPD SI BUS",28.086,14.0,2.33*fgkgcm3,
143                            TGeoMaterial::kMatStateSolid,25.0*fgkCelsius,
144                            0.0*fgkPascal);
145     mat->SetIndex(matindex);
146     med = new TGeoMedium("SPD SI BUS",medindex++,mat,params);
147     //med = new TGeoMedium("SPD SI BUS",medindex++,matindex++,0,ifield,
148     //           fieldm,ktmaxfdSi,kstemaxSi,kdeemaxSi,kepsilSi,kstminSi);
149     //
150     mix = new TGeoMixture("C (M55J)",4,1.9866*fgkgcm3);// Carbon fiber by fractional weight "C (M55J)"
151     mix->SetIndex(matindex);
152     mix->DefineElement(0,12.0107,6.0,0.908508078); // Carbon by fractional weight
153     mix->DefineElement(1,14.0067,7.0,0.010387573); // Nitrogen by fractional weight
154     mix->DefineElement(2,15.9994,8.0,0.055957585); // Oxigen by fractional weight
155     mix->DefineElement(3,1.00794,1.0,0.025146765); // Hydrogen by fractional weight
156     mix->SetPressure(0.0*fgkPascal);
157     mix->SetTemperature(25.0*fgkCelsius);
158     mix->SetState(TGeoMaterial::kMatStateSolid);
159     params[3] = ktmaxfd;
160     params[4] = kstemax;
161     params[5] = kdeemax;
162     params[6] = kepsil;
163     params[7] = kstmin;
164     med = new TGeoMedium("ITSspdCarbonFiber",medindex++,mix,params);
165     //med = new TGeoMedium("ITSspdCarbonFiber",medindex++,matindex++,0,ifield,
166     //           fieldm,ktmaxfd,kstemax,kdeemax,kepsil,kstmin);
167     //
168     mix = new TGeoMixture("Air",4,1.20479E-3*fgkgcm3);// Carbon fiber by fractional weight
169     mix->SetIndex(matindex);
170     mix->DefineElement(0,12.0107,6.0,0.000124); // Carbon by fractional weight
171     mix->DefineElement(1,14.0067,7.0,0.755267); // Nitrogen by fractional weight
172     mix->DefineElement(2,15.9994,8.0,0.231781); // Oxigen by fractional weight
173     mix->DefineElement(3,39.948,18.0,0.012827); // Argon by fractional weight
174     mix->SetPressure(101325.0*fgkPascal); // 1 atmosphere
175     mix->SetTemperature(25.0*fgkCelsius);
176     mix->SetState(TGeoMaterial::kMatStateGas);
177     params[3] = ktmaxfdAir;
178     params[4] = kstemaxAir;
179     params[5] = kdeemaxAir;
180     params[6] = kepsilAir;
181     params[7] = kstminAir;
182     med = new TGeoMedium("ITSspdAir",medindex++,mix,params);
183     //med = new TGeoMedium("ITSspdAir",medindex++,matindex++,0,ifield,
184     //         fieldm,ktmaxfdAir,kstemaxAir,kdeemaxAir,kepsilAir,kstminAir);
185     //
186     mix = new TGeoMixture("INOX",9,8.03*fgkgcm3);// Carbon fiber by fractional weight
187     mix->SetIndex(matindex);
188     mix->DefineElement(0,12.0107, 6.0,0.0003); // Carbon by fractional weight
189     mix->DefineElement(1,54.9380,25.0,0.02); // Iron by fractional weight
190     mix->DefineElement(2,28.0855,14.0,0.01); // Sodium by fractional weight
191     mix->DefineElement(3,30.9738,15.0,0.00045); //  by fractional weight
192     mix->DefineElement(4,32.066 ,16.0,0.0003); // by fractional weight
193     mix->DefineElement(5,58.6928,28.0,0.12); // Nickel by fractional weight
194     mix->DefineElement(6,55.9961,24.0,0.17); // by fractional weight
195     mix->DefineElement(7,95.84  ,42.0,0.025); // by fractional weight
196     mix->DefineElement(8,55.845 ,26.0,0.654); // by fractional weight
197     mix->SetPressure(0.0*fgkPascal); //
198     mix->SetTemperature(25.0*fgkCelsius);
199     mix->SetState(TGeoMaterial::kMatStateSolid);
200     params[3] = ktmaxfdAir;
201     params[4] = kstemaxAir;
202     params[5] = kdeemaxAir;
203     params[6] = kepsilAir;
204     params[7] = kstminAir;
205     med = new TGeoMedium("ITSspdStainlessSteel",medindex++,mix,params);
206     //med = new TGeoMedium("ITSspdStainlessSteel",medindex++,matindex++,0,ifield,
207     //         fieldm,ktmaxfdAir,kstemaxAir,kdeemaxAir,kepsilAir,kstminAir);
208     //
209     mix = new TGeoMixture("Freon",2,1.63*fgkgcm3);// Carbon fiber by fractional weight
210     mix->SetIndex(matindex);
211     mix->DefineElement(0,12.0107,6.0,4); // Carbon by fractional weight
212     mix->DefineElement(1,18.9984032,9.0,10); // Florine by fractional weight
213     mix->SetPressure(101325.0*fgkPascal); // 1 atmosphere
214     mix->SetTemperature(25.0*fgkCelsius);
215     mix->SetState(TGeoMaterial::kMatStateLiquid);
216     params[3] = ktmaxfdAir;
217     params[4] = kstemaxAir;
218     params[5] = kdeemaxAir;
219     params[6] = kepsilAir;
220     params[7] = kstminAir;
221     med = new TGeoMedium("ITSspdCoolingFluid",medindex++,mix,params);
222     //med = new TGeoMedium("ITSspdCoolingFluid",medindex++,matindex++,0,ifield,
223     //         fieldm,ktmaxfdAir,kstemaxAir,kdeemaxAir,kepsilAir,kstminAir);
224     //
225     medOffset = medindex;
226     matOffset = matindex;
227     return matOffset;
228 }
229 //______________________________________________________________________
230 void AliITSv11GeometrySPD::InitSPDCenteral(Int_t offset,TVirtualMC *vmc){
231     // Do any SPD Centeral detector related initilizations, setting
232     // transport cuts for example.
233     // Some GEANT3 Physics switches
234     // "MULTS"
235     // Multiple scattering. The variable IMULS controls this process. For 
236     // more information see [PHYS320 or 325 or 328].
237     // 0 - No multiple scattering.
238     // 1 - Multiple scattering according to Molière theory. Default setting.
239     // 2 - Same as 1. Kept for backward compatibility.
240     // 3 - Pure Gaussian scattering according to the Rossi formula.
241     // "DRAY"
242     // delta ray production. The variable IDRAY controls this process. See [PHYS430]
243     // 0 - No delta rays production.
244     // 1 - delta rays production with generation of . Default setting.
245     // 2 - delta rays production without generation of .
246     // "LOSS"
247     // Continuous energy loss. The variable ILOSS controls this process.
248     // 0 - No continuous energy loss, IDRAY is set to 0.
249     // 1 - Continuous energy loss with generation of delta rays above 
250     //     DCUTE (common/GCUTS/) and restricted Landau fluctuations below  DCUTE.
251     // 2 - Continuous energy loss without generation of delta rays and full 
252     //     Landau-Vavilov-Gauss fluctuations. In this case the variable IDRAY 
253     //     is forced to 0 to avoid double counting of fluctuations. Default setting.
254     // 3 - Same as 1, kept for backward compatibility.
255     // 4 - Energy loss without fluctuation. The value obtained from the tables is 
256     //     used directly.
257     // Intputs:
258     //    Int_t       offset The material/medium index offset.
259     //    TVirturalMC *vmc The pointer to the virtual Monte Carlo default gMC.
260     // Outputs:
261     //    none.
262     // Return:
263     //    none.
264     Int_t i,n=4;
265
266     for(i=0;i<n;i++){
267       vmc->Gstpar(i+offset,"CUTGAM",30.0*fgkKeV);
268       vmc->Gstpar(i+offset,"CUTELE",30.0*fgkKeV);
269       vmc->Gstpar(i+offset,"CUTNEU",30.0*fgkKeV);
270       vmc->Gstpar(i+offset,"CUTHAD",30.0*fgkKeV);
271       vmc->Gstpar(i+offset,"CUTMUO",30.0*fgkKeV);
272       vmc->Gstpar(i+offset,"BCUTE",30.0*fgkKeV);
273       vmc->Gstpar(i+offset,"BCUTM",30.0*fgkKeV);
274       vmc->Gstpar(i+offset,"DCUTE",30.0*fgkKeV);
275       vmc->Gstpar(i+offset,"DCUTM",30.0*fgkKeV);
276       //vmc->Gstpar(i+offset,"PPCUTM",);
277       //vmc->Gstpar(i+offset,"PAIR",);
278       //vmc->Gstpar(i+offset,"COMPT",);
279       //vmc->Gstpar(i+offset,"PHOT",);
280       //vmc->Gstpar(i+offset,"PFIS",);
281       vmc->Gstpar(i+offset,"DRAY",1);
282       //vmc->Gstpar(i+offset,"ANNI",);
283       //vmc->Gstpar(i+offset,"BREM",);
284       //vmc->Gstpar(i+offset,"HADR",);
285       //vmc->Gstpar(i+offset,"MUNU",);
286       //vmc->Gstpar(i+offset,"DCAY",);
287       vmc->Gstpar(i+offset,"LOSS",1);
288       //vmc->Gstpar(i+offset,"MULS",);
289       //vmc->Gstpar(i+offset,"GHCOR1",);
290       //vmc->Gstpar(i+offset,"BIRK1",);
291       //vmc->Gstpar(i+offset,"BRIK2",);
292       //vmc->Gstpar(i+offset,"BRIK3",);
293       //vmc->Gstpar(i+offset,"LABS",);
294       //vmc->Gstpar(i+offset,"SYNC",);
295       //vmc->Gstpar(i+offset,"STRA",);
296     } // end for i
297 }
298 //______________________________________________________________________
299 void AliITSv11GeometrySPD::SPDSector(TGeoVolume *moth,TGeoManager *mgr){
300     // Position of the Carbon Fiber Assembly based on distance
301     // of closest point of SPD stave to beam pipe figures
302     // all-sections-modules.ps of 7.22mm at section A-A.
303     // Inputs:
304     //   TGeoVolume *moth   the mother volume which this
305     //                      object/volume is to be placed in.
306     // Outputs:
307     //   none.
308     // Return:
309     //   none.
310     const Double_t kSPDclossesStaveAA    = 7.22*fgkmm;
311     const Double_t kSectorStartingAngle  = -72.0*fgkDegree;
312     const Double_t kNSectorsTotal        = 10.; // number
313     const Double_t kSectorRelativeAngle  = 360./kNSectorsTotal*fgkDegree;
314     const Double_t kBeamPipeRadius       = 0.5*60.0*fgkmm;
315     //
316     Int_t i;
317     Double_t angle,radiusSector,xAAtubeCenter0,yAAtubeCenter0;
318     Double_t staveThicknessAA=1.03*fgkmm; // get from stave geometry.
319     TGeoCombiTrans *secRot=new TGeoCombiTrans();
320     TGeoVolume *vCarbonFiberSector;
321     TGeoMedium *medSPDcf;
322
323     medSPDcf = mgr->GetMedium("ITSspdCarbonFiber");
324     vCarbonFiberSector = new TGeoVolumeAssembly("ITSSPDCarbonFiberSectorV");
325     vCarbonFiberSector->SetMedium(medSPDcf);
326     CarbonFiberSector(vCarbonFiberSector,xAAtubeCenter0,yAAtubeCenter0);
327     vCarbonFiberSector->SetVisibility(kFALSE); // logical volume
328     // Compute the radial shift out of the sectors.
329     radiusSector = kBeamPipeRadius+kSPDclossesStaveAA+staveThicknessAA;
330     radiusSector *= radiusSector; // squaring;
331     radiusSector -= xAAtubeCenter0*xAAtubeCenter0;
332     radiusSector = -yAAtubeCenter0+TMath::Sqrt(radiusSector);
333     angle = kSectorStartingAngle;
334     secRot->RotateZ(angle);
335     for(i=0;i<(Int_t)kNSectorsTotal;i++){
336         secRot->SetDx(-radiusSector*TMath::Sin(angle/fgkRadian));
337         secRot->SetDy(radiusSector*TMath::Cos(angle/fgkRadian));
338         //secRot->RegisterYourself();
339         moth->AddNode(vCarbonFiberSector,i+1,new TGeoCombiTrans(*secRot));
340         printf("i=%d angle=%g angle[rad]=%g radiusSector=%g x=%g y=%g \n",
341                i,angle,angle/fgkRadian,radiusSector,
342                -radiusSector*TMath::Sin(angle/fgkRadian),
343                radiusSector*TMath::Cos(angle/fgkRadian));
344         angle += kSectorRelativeAngle;
345         secRot->RotateZ(kSectorRelativeAngle);
346     } // end for i
347     if(GetDebug()){
348         moth->PrintNodes();
349     } // end if GetDebug().
350     delete secRot;
351 }
352 //______________________________________________________________________
353 void AliITSv11GeometrySPD::CarbonFiberSector(TGeoVolume *moth,
354                                              Double_t &xAAtubeCenter0,
355                                              Double_t &yAAtubeCenter0,
356                                              TGeoManager *mgr){
357     // Define the detail SPD Carbon fiber support Sector geometry.
358     // Based on the drawings ALICE-Pixel "Construzione Profilo Modulo"
359     // March 25 2004 and ALICE-SUPPORTO "construzione Profilo Modulo"
360     // Define Outside radii as negitive, Outside in the sence that the
361     // center of the arc is outside of the object.
362     // February 16 2004.
363     // Inputs:
364     //   TGeoVolume *moth  The mother volume to put this object
365     // Outputs:
366     //  Double_t &xAAtubeCenter0  The x location of the outer surface
367     //                            of the cooling tube center for tube 0.
368     //                            This location helps determine where 
369     //                            this sector is to be located (information
370     //                            used for this is the distance the
371     //                            center of the #0 detector is from the
372     //                            beam pipe. Measurements taken at 
373     //                            cross section A-A.
374     //  Double_t &yAAtubeCenter0  The y location of the outer surface
375     //                            of the cooling tube center for tube 0
376     //                            This location helps determine where
377     //                            this sector is to be located (information
378     //                            used for this is the distance the 
379     //                            center of the #0 detector is from the
380     //                            beam pipe. Measurements taken at 
381     //                            cross section A-A.
382     //   TGeoManager *mgr         The TGeoManager as needed, default is
383     //                            gGeoManager.
384     // Return:
385     //  none.
386     TGeoMedium *medSPDcf  = 0; // SPD support cone Carbon Fiber materal number.
387     //TGeoMedium *medSPDfs  = 0; // SPD support cone inserto stesalite 4411w.
388     //TGeoMedium *medSPDfo  = 0; // SPD support cone foam, Rohacell 50A.
389     TGeoMedium *medSPDss  = 0; // SPD support cone screw material,Stainless
390     TGeoMedium *medSPDair = 0; // SPD support cone Air
391     //TGeoMedium *medSPDal  = 0; // SPD support cone SDD mounting bracket Al
392     TGeoMedium *medSPDcoolfl  = 0; // SPD cooling fluid, Freeon
393     medSPDcf = mgr->GetMedium("ITSspdCarbonFiber");
394     //medSPDfs = mgr->GetMedium("ITSspdStaselite4411w");
395     //medSPDfo = mgr->GetMedium("ITSspdRohacell50A");
396     medSPDss = mgr->GetMedium("ITSspdStainlessSteel");
397     medSPDair= mgr->GetMedium("ITSspdAir");
398     medSPDcoolfl= mgr->GetMedium("ITSspdCoolingFluid");
399     //
400     const Double_t ksecDz        = 0.5*500.0*fgkmm;
401     const Double_t ksecLen       = 30.0*fgkmm;
402     const Double_t ksecCthick    = 0.20*fgkmm;
403     const Double_t ksecDipLength = 3.2*fgkmm;
404     const Double_t ksecDipRadii  = 0.4*fgkmm;
405     //const Double_t ksecCoolingTubeExtraDepth = 0.86*fgkmm;
406     // These positions, ksecX*,ksecY* are the center of curvatures
407     // for the different point around the SPD sector. The radii,
408     // inner and outer, are the radous of curvature about the centers
409     // ksecX* and ksecY*. To draw this SPD sector, first plot all of
410     // the ksecX and ksecY points and draw circles of the specified
411     // radius about these points. Connect the circles, such that the
412     // lines are tangent to the circles, in accordance with the
413     // radii being "Inside" or "Outside". These lines and the 
414     // corresponding arc's are the surface of this SPD sector.
415     const Double_t ksecX0   = -10.725*fgkmm;
416     const Double_t ksecY0   = -14.853*fgkmm;
417     const Double_t ksecR0   = -0.8*fgkmm; // Outside
418     const Double_t ksecX1   = -13.187*fgkmm;
419     const Double_t ksecY1   = -19.964*fgkmm;
420     const Double_t ksecR1   = +0.6*fgkmm; // Inside
421     //const Double_t ksecDip0 = 5.9*fgkmm;
422     //
423     const Double_t ksecX2   = -3.883*fgkmm;
424     const Double_t ksecY2   = -17.805*fgkmm;
425     const Double_t ksecR2   = +0.80*fgkmm; // Inside Guess. 
426     const Double_t ksecX3   = -3.123*fgkmm;
427     const Double_t ksecY3   = -14.618*fgkmm;
428     const Double_t ksecR3   = -0.6*fgkmm; // Outside
429     //const Double_t ksecDip1 = 8.035*fgkmm;
430     //
431     const Double_t ksecX4   = +11.280*fgkmm;
432     const Double_t ksecY4   = -14.473*fgkmm;
433     const Double_t ksecR4   = +0.8*fgkmm; // Inside
434     const Double_t ksecX5   = +19.544*fgkmm;
435     const Double_t ksecY5   = +10.961*fgkmm;
436     const Double_t ksecR5   = +0.8*fgkmm; // Inside
437     //const Double_t ksecDip2 = 4.553*fgkmm;
438     //
439     const Double_t ksecX6   = +10.830*fgkmm;
440     const Double_t ksecY6   = +16.858*fgkmm;
441     const Double_t ksecR6   = +0.6*fgkmm; // Inside
442     const Double_t ksecX7   = +11.581*fgkmm;
443     const Double_t ksecY7   = +13.317*fgkmm;
444     const Double_t ksecR7   = -0.6*fgkmm; // Outside
445     //const Double_t ksecDip3 = 6.978*fgkmm;
446     //
447     const Double_t ksecX8   = -0.733*fgkmm;
448     const Double_t ksecY8   = +17.486*fgkmm;
449     const Double_t ksecR8   = +0.6*fgkmm; // Inside
450     const Double_t ksecX9   = +0.562*fgkmm;
451     const Double_t ksecY9   = +14.486*fgkmm;
452     const Double_t ksecR9   = -0.6*fgkmm; // Outside
453     //const Double_t ksecDip4 = 6.978*fgkmm;
454     //
455     const Double_t ksecX10  = -12.252*fgkmm;
456     const Double_t ksecY10  = +16.298*fgkmm;
457     const Double_t ksecR10  = +0.6*fgkmm; // Inside
458     const Double_t ksecX11  = -10.445*fgkmm;
459     const Double_t ksecY11  = +13.162*fgkmm;
460     const Double_t ksecR11  = -0.6*fgkmm; // Outside
461     //const Double_t ksecDip5 = 6.978*fgkmm;
462     //
463     const Double_t ksecX12  = -22.276*fgkmm;
464     const Double_t ksecY12  = +12.948*fgkmm;
465     const Double_t ksecR12  = +0.85*fgkmm; // Inside
466     //const Double_t ksecX13 = *fgkmm;
467     //const Double_t ksecY13 = *fgkmm;
468     const Double_t ksecR13  = -0.8*fgkmm; // Outside
469     const Double_t ksecAngleSide13 = 36.0*fgkDegree;
470     //
471     const Int_t ksecNRadii = 20;
472     const Int_t ksecNPointsPerRadii = 4;
473     const Int_t ksecNCoolingTubeDips = 6;
474     // Since the Rounded parts are aproximated by a regular polygon and
475     // a cooling tube of the propper diameter must fit, a scaling factor
476     // increases the size of the polygon for the tube to fit.
477     //const Double_t ksecRCoolScale = 1./TMath::Cos(TMath::Pi()/
478     //                                          (Double_t)ksecNPointsPerRadii);
479     const Double_t ksecZEndLen  = 30.00*fgkmm;
480     //const Double_t ksecZFlangLen= 45.00*fgkmm;
481     const Double_t ksecTl       = 0.860*fgkmm;
482     const Double_t ksecCthick2  = 0.600*fgkmm;
483     //const Double_t ksecCthick3  = 1.800*fgkmm;
484     //const Double_t ksecSidelen  = 22.00*fgkmm;
485     //const Double_t ksecSideD5   = 3.679*fgkmm;
486     //const Double_t ksecSideD12  = 7.066*fgkmm;
487     const Double_t ksecRCoolOut = 2.400*fgkmm;
488     const Double_t ksecRCoolIn  = 2.000*fgkmm;
489     const Double_t ksecDl1      = 5.900*fgkmm;
490     const Double_t ksecDl2      = 8.035*fgkmm;
491     const Double_t ksecDl3      = 4.553*fgkmm;
492     const Double_t ksecDl4      = 6.978*fgkmm;
493     const Double_t ksecDl5      = 6.978*fgkmm;
494     const Double_t ksecDl6      = 6.978*fgkmm;
495     const Double_t ksecCoolTubeThick  = 0.04*fgkmm;
496     const Double_t ksecCoolTubeROuter = 2.6*fgkmm;
497     const Double_t ksecCoolTubeFlatX  = 3.696*fgkmm;
498     const Double_t ksecCoolTubeFlatY  = 0.68*fgkmm;
499     //const Double_t ksecBeamX0   = 0.0*fgkmm; // guess
500     //const Double_t ksecBeamY0   = (15.223+40.)*fgkmm; // guess
501     //
502     const Int_t ksecNPoints = (ksecNPointsPerRadii+1)*ksecNRadii + 8;
503     Double_t secX[ksecNRadii] = {ksecX0,ksecX1,-1000.0,ksecX2 ,ksecX3 ,-1000.0,
504                                  ksecX4,ksecX5,-1000.0,ksecX6 ,ksecX7 ,-1000.0,
505                                  ksecX8,ksecX9,-1000.0,ksecX10,ksecX11,-1000.0,
506                                  ksecX12,-1000.0};
507     Double_t secY[ksecNRadii] = {ksecY0,ksecY1,-1000.0,ksecY2 ,ksecY3 ,-1000.0,
508                                  ksecY4,ksecY5,-1000.0,ksecY6 ,ksecY7 ,-1000.0,
509                                  ksecY8,ksecY9,-1000.0,ksecY10,ksecY11,-1000.0,
510                                  ksecY12,-1000.0};
511     Double_t secR[ksecNRadii] ={ksecR0 ,ksecR1 ,-.5*ksecDipLength-ksecDipRadii,
512                                 ksecR2 ,ksecR3 ,-.5*ksecDipLength-ksecDipRadii,
513                                 ksecR4 ,ksecR5 ,-.5*ksecDipLength-ksecDipRadii,
514                                 ksecR6 ,ksecR7 ,-.5*ksecDipLength-ksecDipRadii,
515                                 ksecR8 ,ksecR9 ,-.5*ksecDipLength-ksecDipRadii,
516                                 ksecR10,ksecR11,-.5*ksecDipLength-ksecDipRadii,
517                                 ksecR12,ksecR13};/*
518     Double_t secDip[ksecNRadii]={0.0,0.0,ksecDip0,0.0,0.0,ksecDip1,
519                                  0.0,0.0,ksecDip2,0.0,0.0,ksecDip3,
520                                  0.0,0.0,ksecDip4,0.0,0.0,ksecDip5,
521                                  0.0,0.0};*/
522     Double_t secX2[ksecNRadii];
523     Double_t secY2[ksecNRadii];
524     Double_t secR2[ksecNRadii] = {
525         ksecR0,ksecR1,ksecRCoolOut,ksecR2,ksecR3,ksecRCoolOut,ksecR4,ksecR5,
526         ksecRCoolOut,ksecR6,ksecR7,ksecRCoolOut,ksecR8,ksecR9,ksecRCoolOut,
527         ksecR10,ksecR11,ksecRCoolOut,ksecR12,ksecR13};
528     Double_t secDip2[ksecNCoolingTubeDips]={ksecDl1,ksecDl2,ksecDl3,
529                                             ksecDl4,ksecDl5,ksecDl6};
530     Double_t secX3[ksecNRadii];
531     Double_t secY3[ksecNRadii];
532     const Int_t ksecDipIndex[ksecNCoolingTubeDips] = {2,5,8,11,14,17};
533     Double_t secAngleStart[ksecNRadii];
534     Double_t secAngleEnd[ksecNRadii];
535     Double_t secAngleStart2[ksecNRadii];
536     Double_t secAngleEnd2[ksecNRadii];
537     Double_t secAngleTurbo[ksecNCoolingTubeDips] = {0.0,0.0,0.0,0.0,0.0,0.0};
538     //Double_t secAngleStart3[ksecNRadii];
539     //Double_t secAngleEnd3[ksecNRadii];
540     Double_t xpp[ksecNPoints],ypp[ksecNPoints];
541     Double_t xpp2[ksecNPoints],ypp2[ksecNPoints];
542     Double_t *xp[ksecNRadii],*xp2[ksecNRadii];
543     Double_t *yp[ksecNRadii],*yp2[ksecNRadii];
544     TGeoXtru *sA0,*sA1,*sB0,*sB1;
545     TGeoEltu *sTA0,*sTA1;
546     TGeoTube *sTB0,*sTB1,*sM0;
547     TGeoRotation    *rot;
548     TGeoTranslation *trans;
549     TGeoCombiTrans  *rotrans;
550     Double_t t,t0,t1,a,b,x0,y0,x1,y1;
551     Int_t i,j,k,m;
552     Bool_t tst;
553
554     if(moth==0){
555         Error("CarbonFiberSector","moth=%p",moth);
556         return;
557     } // end if moth==0
558     //SetDebug(3);
559     for(i=0;i<ksecNRadii;i++){
560         xp[i]  = &(xpp[i*(ksecNPointsPerRadii+1)]);
561         yp[i]  = &(ypp[i*(ksecNPointsPerRadii+1)]);
562         xp2[i] = &(xpp2[i*(ksecNPointsPerRadii+1)]);
563         yp2[i] = &(ypp2[i*(ksecNPointsPerRadii+1)]);
564         secX2[i] = secX[i];
565         secY2[i] = secY[i];
566         secX3[i] = secX[i];
567         secY3[i] = secY[i];
568     } // end for i
569
570     // Find starting and ending angles for all but cooling tube sections
571     secAngleStart[0] = 0.5*ksecAngleSide13;
572     for(i=0;i<ksecNRadii-2;i++){
573         tst = kFALSE;
574         for(j=0;j<ksecNCoolingTubeDips;j++) tst = tst||i==ksecDipIndex[j];
575         if(tst) continue;
576         tst = kFALSE;
577         for(j=0;j<ksecNCoolingTubeDips;j++) tst = tst||(i+1)==ksecDipIndex[j];
578         if(tst) j = i+2;
579         else j = i+1;
580         AnglesForRoundedCorners(secX[i],secY[i],secR[i],
581                                 secX[j],secY[j],secR[j],t0,t1);
582         secAngleEnd[i]   = t0;
583         secAngleStart[j] = t1;
584         if(secR[i]>0.0&&secR[j]>0.0)if(secAngleStart[i]>secAngleEnd[i])
585             secAngleEnd[i] += 360.0;
586         secAngleStart2[i] = secAngleStart[i];
587         secAngleEnd2[i]   = secAngleEnd[i];
588     } // end for i
589     secAngleEnd[ksecNRadii-2]   = secAngleStart[ksecNRadii-2] + 
590                                      (secAngleEnd[ksecNRadii-5]-
591                                       secAngleStart[ksecNRadii-5]);
592     if(secAngleEnd[ksecNRadii-2]<0.0) secAngleEnd[ksecNRadii-2] += 360.0;
593     secAngleStart[ksecNRadii-1] = secAngleEnd[ksecNRadii-2] - 180.0;
594     secAngleEnd[ksecNRadii-1]   = secAngleStart[0];
595     secAngleStart2[ksecNRadii-2] = secAngleStart[ksecNRadii-2];
596     secAngleEnd2[ksecNRadii-2]   = secAngleEnd[ksecNRadii-2];
597     secAngleStart2[ksecNRadii-1] = secAngleStart[ksecNRadii-1];
598     secAngleEnd2[ksecNRadii-1]   = secAngleEnd[ksecNRadii-1];
599     // Find location of circle last rounded corner.
600     i = 0;
601     j = ksecNRadii-2;
602     t0 = TanD(secAngleStart[i]-90.);
603     t1 = TanD(secAngleEnd[j]-90.);
604     t  = secY[i] - secY[j];
605     // Note, secR[i=0] <0; secR[j=18]>0; and secR[j+1=19] <0
606     t += (-secR[i]+secR[j+1])*SinD(secAngleStart[i]);
607     t -= (secR[j]-secR[j+1])*SinD(secAngleEnd[j]);
608     t += t1*secX[j] - t0*secX[i];
609     t += t1*(secR[j]-secR[j+1])*CosD(secAngleEnd[j]);
610     t -= t0*(-secR[i]+secR[j+1])*CosD(secAngleStart[i]);
611     secX[ksecNRadii-1] = t/(t1-t0);
612     secY[ksecNRadii-1] = TanD(90.+0.5*ksecAngleSide13)*
613                           (secX[ksecNRadii-1]-secX[0]) + secY[0];
614     secX2[ksecNRadii-1] = secX[ksecNRadii-1];
615     secY2[ksecNRadii-1] = secY[ksecNRadii-1];
616     secX3[ksecNRadii-1] = secX[ksecNRadii-1];
617     secY3[ksecNRadii-1] = secY[ksecNRadii-1];
618     // find location of cooling tube centers
619     for(i=0;i<ksecNCoolingTubeDips;i++){
620         j = ksecDipIndex[i];
621         x0 = secX[j-1] + TMath::Abs(secR[j-1])*CosD(secAngleEnd[j-1]);
622         y0 = secY[j-1] + TMath::Abs(secR[j-1])*SinD(secAngleEnd[j-1]);
623         x1 = secX[j+1] + TMath::Abs(secR[j+1])*CosD(secAngleStart[j+1]);
624         y1 = secY[j+1] + TMath::Abs(secR[j+1])*SinD(secAngleStart[j+1]);
625         t0 = TMath::Sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
626         t  = secDip2[i]/t0;
627         a  = x0+(x1-x0)*t;
628         b  = y0+(y1-y0)*t;
629         if(i==0){ // get location of tube center->Surface for locating
630                   // this sector around the beam pipe. This needs to be
631                   // double checked, but I need my notes for that, Bjorn Nilsen
632             xAAtubeCenter0 = x0+(x1-x0)*t*0.5;
633             yAAtubeCenter0 = y0+(y1-y0)*t*0.5;
634         } // end if i==0
635         if(a+b*(a-x0)/(b-y0)>0.0){
636             secX[j] = a + TMath::Abs(y1-y0)*2.0*ksecDipRadii/t0;
637             secY[j] = b - TMath::Sign(2.0*ksecDipRadii,y1-y0)*(x1-x0)/t0;
638             secX2[j] = a + TMath::Abs(y1-y0)*ksecTl/t0;
639             secY2[j] = b - TMath::Sign(ksecTl,y1-y0)*(x1-x0)/t0;
640             secX3[j] = a + TMath::Abs(y1-y0)*(2.0*ksecDipRadii-
641                                           0.5*ksecCoolTubeFlatY)/t0;
642             secY3[j] = b - TMath::Sign(2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY,
643                                    y1-y0)*(x1-x0)/t0;
644         }else{
645             secX[j] = a - TMath::Abs(y1-y0)*2.0*ksecDipRadii/t0;
646             secY[j] = b + TMath::Sign(2.0*ksecDipRadii,y1-y0)*(x1-x0)/t0;
647             secX2[j] = a - TMath::Abs(y1-y0)*ksecTl/t0;
648             secY2[j] = b + TMath::Sign(ksecTl,y1-y0)*(x1-x0)/t0;
649             secX3[j] = a - TMath::Abs(y1-y0)*(2.0*ksecDipRadii-
650                                           0.5*ksecCoolTubeFlatY)/t0;
651             secY3[j] = b + TMath::Sign(2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY,
652                                       y1-y0)*(x1-x0)/t0;
653         } // end if
654         // Set up Start and End angles to correspond to start/end of dips.
655         t1 = (secDip2[i]-TMath::Abs(secR[j]))/t0;
656         secAngleStart[j] = TMath::RadToDeg()*TMath::ATan2(
657                                y0+(y1-y0)*t1-secY[j],x0+(x1-x0)*t1-secX[j]);
658         if(secAngleStart[j]<0.0) secAngleStart[j] += 360.0;
659         secAngleStart2[j] = secAngleStart[j];
660         t1 = (secDip2[i]+TMath::Abs(secR[j]))/t0;
661         secAngleEnd[j] = TMath::RadToDeg()*TMath::ATan2(
662                                y0+(y1-y0)*t1-secY[j],x0+(x1-x0)*t1-secX[j]);
663         if(secAngleEnd[j]<0.0) secAngleEnd[j] += 360.0;
664         secAngleEnd2[j]   = secAngleEnd[j];
665         if(secAngleEnd[j]>secAngleStart[j]) secAngleEnd[j] -= 360.0;
666         secR[j] = TMath::Sqrt(secR[j]*secR[j]+4.0*ksecDipRadii*ksecDipRadii);
667     } // end for i
668     // Spcial cases
669     secAngleStart2[8] -= 360.;
670     secAngleStart2[11] -= 360.;
671     //
672     SPDsectorShape(ksecNRadii,secX,secY,secR,secAngleStart,secAngleEnd,
673                    ksecNPointsPerRadii,m,xp,yp);
674     //  Fix up dips to be square.
675     for(i=0;i<ksecNCoolingTubeDips;i++){
676         j = ksecDipIndex[i];
677         t = 0.5*ksecDipLength+ksecDipRadii;
678         t0 = TMath::RadToDeg()*TMath::ATan(2.0*ksecDipRadii/t);
679         t1 = secAngleEnd[j] + t0;
680         t0 = secAngleStart[j] - t0;
681         x0 = xp[j][1] = secX[j] + t*CosD(t0);
682         y0 = yp[j][1] = secY[j] + t*SinD(t0);
683         x1 = xp[j][ksecNPointsPerRadii-1] = secX[j] + t*CosD(t1);
684         y1 = yp[j][ksecNPointsPerRadii-1] = secY[j] + t*SinD(t1);
685         t0 = 1./((Double_t)(ksecNPointsPerRadii-2));
686         for(k=2;k<ksecNPointsPerRadii-1;k++){// extra points spread them out.
687             t = ((Double_t)(k-1))*t0;
688             xp[j][k] = x0+(x1-x0)*t;
689             yp[j][k] = y0+(y1-y0)*t;
690         } // end for k
691         secAngleTurbo[i] = -TMath::RadToDeg()*TMath::ATan2(y1-y0,x1-x0);
692         if(GetDebug(3)){ 
693            cout <<"i="<<i<<" angle="<<secAngleTurbo[i]<<" x0,y0{"
694                 <<x0<<","<<y0<<"} x1y1={"<<x1<<","<<y1<<"}"<<endl;
695         } // end if
696     } // end for i
697     sA0 = new TGeoXtru(2);
698     sA0->SetName("ITS SPD Carbon fiber support Sector A0");
699     sA0->DefinePolygon(m,xpp,ypp);
700     sA0->DefineSection(0,-ksecDz);
701     sA0->DefineSection(1,ksecDz);
702     //
703     InsidePoint(xpp[m-1],ypp[m-1],xpp[0],ypp[0],xpp[1],ypp[1],
704                 ksecCthick,xpp2[0],ypp2[0]);
705     for(i=1;i<m-1;i++){
706         j = i/(ksecNPointsPerRadii+1);
707         InsidePoint(xpp[i-1],ypp[i-1],xpp[i],ypp[i],xpp[i+1],ypp[i+1],
708                     ksecCthick,xpp2[i],ypp2[i]);
709     } // end for i
710     InsidePoint(xpp[m-2],ypp[m-2],xpp[m-1],ypp[m-1],xpp[0],ypp[0],
711                 ksecCthick,xpp2[m-1],ypp2[m-1]);
712     // Fix center value of cooling tube dip.
713     // find location of cooling tube centers
714     for(i=0;i<ksecNCoolingTubeDips;i++){
715         j = ksecDipIndex[i];
716         x0 = xp2[j][1];
717         y0 = yp2[j][1];
718         x1 = xp2[j][ksecNPointsPerRadii-1];
719         y1 = yp2[j][ksecNPointsPerRadii-1];
720         t0 = TMath::Sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
721         t  = secDip2[i]/t0;
722         for(k=2;k<ksecNPointsPerRadii-1;k++){// extra points spread them out.
723             t = ((Double_t)(k-1))*t0;
724             xp2[j][k] = x0+(x1-x0)*t;
725             yp2[j][k] = y0+(y1-y0)*t;
726         } // end for k
727     } // end for i
728     sA1 = new TGeoXtru(2);
729     sA1->SetName("ITS SPD Carbon fiber support Sector Air A1");
730     sA1->DefinePolygon(m,xpp2,ypp2);
731     sA1->DefineSection(0,-ksecDz);
732     sA1->DefineSection(1,ksecDz);
733     //
734     // Error in TGeoEltu. Semi-axis X must be < Semi-axis Y (?).
735     sTA0 = new TGeoEltu("ITS SPD Cooling Tube TA0",
736                       0.5* ksecCoolTubeFlatY, 0.5* ksecCoolTubeFlatX,ksecDz);
737     sTA1 = new TGeoEltu("ITS SPD Cooling Tube coolant TA1",
738                         sTA0->GetA()-ksecCoolTubeThick,
739                         sTA0->GetB()-ksecCoolTubeThick,ksecDz);
740     //
741     SPDsectorShape(ksecNRadii,secX2,secY2,secR2,secAngleStart2,secAngleEnd2,
742                    ksecNPointsPerRadii,m,xp,yp);
743     //
744     sB0 = new TGeoXtru(2);
745     sB0->SetName("ITS SPD Carbon fiber support Sector End B0");
746     sB0->DefinePolygon(m,xpp,ypp);
747     sB0->DefineSection(0,ksecDz);
748     sB0->DefineSection(1,ksecDz+ksecZEndLen);
749     //
750     InsidePoint(xpp[m-1],ypp[m-1],xpp[0],ypp[0],xpp[1],ypp[1],
751                 ksecCthick2,xpp2[0],ypp2[0]);
752     for(i=1;i<m-1;i++){
753         t = ksecCthick2;
754         for(k=0;k<ksecNCoolingTubeDips;k++)
755             if((i/(ksecNPointsPerRadii+1))==ksecDipIndex[k]) 
756                 if(!(ksecDipIndex[k]*(ksecNPointsPerRadii+1)==i || 
757                      ksecDipIndex[k]*(ksecNPointsPerRadii+1)+
758                      ksecNPointsPerRadii==i   )) 
759                     t = ksecRCoolOut-ksecRCoolIn;
760         InsidePoint(xpp[i-1],ypp[i-1],xpp[i],ypp[i],xpp[i+1],ypp[i+1],
761                     t,xpp2[i],ypp2[i]);
762     } // end for i
763     InsidePoint(xpp[m-2],ypp[m-2],xpp[m-1],ypp[m-1],xpp[0],ypp[0],
764                 ksecCthick2,xpp2[m-1],ypp2[m-1]);
765     sB1 = new TGeoXtru(2);
766     sB1->SetName("ITS SPD Carbon fiber support Sector Air End B1");
767     sB1->DefinePolygon(m,xpp2,ypp2);
768     sB1->DefineSection(0,ksecDz);
769     sB1->DefineSection(1,ksecDz+ksecLen);
770     sTB0 = new TGeoTube("ITS SPD Cooling Tube End TB0",0.0,
771                        0.5*ksecCoolTubeROuter,0.5*ksecLen);
772     sTB1 = new TGeoTube("ITS SPD Cooling Tube End coolant TB0",0.0,
773                        sTB0->GetRmax()-ksecCoolTubeThick,0.5*ksecLen);
774     //
775     sM0 = new TGeoTube("ITS SPD Sensitive Virutual Volume M0",0.0,8.0,
776                        sA0->GetZ(1)+sB0->GetZ(1));
777     //
778     if(GetDebug()){
779         cout<<"medSPDcf= "<<medSPDcf<<endl;
780         //        printf("medSPDcf=%x\n",medSPDcf);
781         if(medSPDcf) medSPDcf->Dump();
782         cout<<"medSPDss= "<<medSPDss<<endl;
783         //       printf("medSPDss=%x\n",medSPDss);
784         if(medSPDss) medSPDss->Dump();
785         cout<<"medSPDair= "<<medSPDair<<endl;
786         //       printf("medSPDair=%x\n",medSPDair);
787         if(medSPDair) medSPDair->Dump();
788         cout<<"medSPDcoolfl= "<<medSPDcoolfl<<endl;
789         //       printf("medSPDcoolfl=%x\n",medSPDcoolfl);
790         if(medSPDcoolfl) medSPDcoolfl->Dump();
791         sM0->InspectShape();
792         sA0->InspectShape();
793         sA1->InspectShape();
794         sB0->InspectShape();
795         sB1->InspectShape();
796     } // end if GetDebug
797     //
798     TGeoVolume *vM0,*vA0,*vA1,*vTA0,*vTA1,*vB0,*vB1,*vTB0,*vTB1;
799     vM0 = new TGeoVolume("ITSSPDSensitiveVirtualvolumeM0",sM0,medSPDair);
800     vM0->SetVisibility(kTRUE);
801     vM0->SetLineColor(7); // light Blue
802     vM0->SetLineWidth(1);
803     vM0->SetFillColor(vM0->GetLineColor());
804     vM0->SetFillStyle(4090); // 90% transparent
805     vA0 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorA0",sA0,medSPDcf);
806     vA0->SetVisibility(kTRUE);
807     vA0->SetLineColor(4); // Blue
808     vA0->SetLineWidth(1);
809     vA0->SetFillColor(vA0->GetLineColor());
810     vA0->SetFillStyle(4010); // 10% transparent
811     vA1 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorAirA1",sA1,medSPDair);
812     vA1->SetVisibility(kTRUE);
813     vA1->SetLineColor(7); // light Blue
814     vA1->SetLineWidth(1);
815     vA1->SetFillColor(vA1->GetLineColor());
816     vA1->SetFillStyle(4090); // 90% transparent
817     vTA0 = new TGeoVolume("ITSSPDCoolingTubeTA0",sTA0,medSPDss);
818     vTA0->SetVisibility(kTRUE);
819     vTA0->SetLineColor(1); // Black
820     vTA0->SetLineWidth(1);
821     vTA0->SetFillColor(vTA0->GetLineColor());
822     vTA0->SetFillStyle(4000); // 0% transparent
823     vTA1 = new TGeoVolume("ITSSPDCoolingTubeFluidTA1",sTA1,medSPDcoolfl);
824     vTA1->SetVisibility(kTRUE);
825     vTA1->SetLineColor(6); // Purple
826     vTA1->SetLineWidth(1);
827     vTA1->SetFillColor(vTA1->GetLineColor());
828     vTA1->SetFillStyle(4000); // 0% transparent
829     vB0 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorEndB0",sB0,medSPDcf);
830     vB0->SetVisibility(kTRUE);
831     vB0->SetLineColor(4); // Blue
832     vB0->SetLineWidth(1);
833     vB0->SetFillColor(vB0->GetLineColor());
834     vB0->SetFillStyle(4010); // 10% transparent
835     vB1 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorEndAirB1",
836                          sB1,medSPDair);
837     vB1->SetVisibility(kTRUE);
838     vB1->SetLineColor(7); // light Blue
839     vB1->SetLineWidth(1);
840     vB1->SetFillColor(vB1->GetLineColor());
841     vB1->SetFillStyle(4090); // 90% transparent
842     vTB0 = new TGeoVolume("ITSSPDCoolingTubeEndTB0",sTB0,medSPDss);
843     vTB0->SetVisibility(kTRUE);
844     vTB0->SetLineColor(1); // Black
845     vTB0->SetLineWidth(1);
846     vTB0->SetFillColor(vTB0->GetLineColor());
847     vTB0->SetFillStyle(4000); // 0% transparent
848     vTB1 = new TGeoVolume("ITSSPDCoolingTubeEndFluidTB1",sTB1,medSPDcoolfl);
849     vTB1->SetVisibility(kTRUE);
850     vTB1->SetLineColor(6); // Purple
851     vTB1->SetLineWidth(1);
852     vTB1->SetFillColor(vTB1->GetLineColor());
853     vTB1->SetFillStyle(4000); // 0% transparent
854     //
855     moth->AddNode(vM0,1,0); // Add virtual volume to mother
856     vA0->AddNode(vA1,1,0); // Put air inside carbon fiber.
857     vB0->AddNode(vB1,1,0); // Put air inside carbon fiber.
858     vTA0->AddNode(vTA1,1,0); // Put air inside carbon fiber.
859     vTB0->AddNode(vTB1,1,0); // Put air inside carbon fiber.
860     for(i=0;i<ksecNCoolingTubeDips;i++){
861         x0 = secX3[ksecDipIndex[i]];
862         y0 = secY3[ksecDipIndex[i]];
863         t = 90.0-secAngleTurbo[i];
864         trans = new TGeoTranslation("",x0,y0,0.5*(sB1->GetZ(0)+sB1->GetZ(1)));
865         vB1->AddNode(vTB0,i+1,trans);
866         rot = new TGeoRotation("",0.0,0.0,t);
867         rotrans = new TGeoCombiTrans("",x0,y0,0.0,rot);
868         vM0->AddNode(vTA0,i+1,rotrans);
869         //delete rot; // rot owned by AliITSv11GeometerySPD::CarbonFiberSector
870     } // end for i
871     vM0->AddNode(vA0,1,0);
872     vM0->AddNode(vB0,1,0);
873     // Reflection.
874     vM0->AddNode(vB0,2,new TGeoRotation("",90.,0.,90.,90.,180.,0.));
875     if(GetDebug()){
876         vM0->PrintNodes();
877         vA0->PrintNodes();
878         vA1->PrintNodes();
879         vB0->PrintNodes();
880         vB1->PrintNodes();
881         vTA0->PrintNodes();
882         vTA1->PrintNodes();
883         vTB0->PrintNodes();
884         vTB1->PrintNodes();
885     } // end if GetDebug
886     //
887 }
888 //----------------------------------------------------------------------
889 void AliITSv11GeometrySPD::SPDsectorShape(Int_t n,const Double_t *xc,
890 const Double_t *yc,const Double_t *r,const Double_t *ths,const Double_t *the,
891                                Int_t npr,Int_t &m,Double_t **xp,Double_t **yp){
892     // Code to compute the points that make up the shape of the SPD
893     // Carbon fiber support sections
894     // Inputs:
895     //    Int_t    n       Size of arrays xc,yc, and r.
896     //    Double_t *xc     Array of x values for radii centers.
897     //    Double_t *yc     Array of y values for radii centers.
898     //    Double_t *r      Array of signed radii values.
899     //    Double_t *ths    Array of starting angles [degrees].
900     //    Double_t *the    Array of ending angles [degrees].
901     //    Int_t    npr     The number of lines segments to aproximate the arc.
902     // Outputs:
903     //    Int_t    m       The number of enetries in the arrays *xp[npr+1] 
904     //                     and *yp[npr+1].
905     //    Double_t **xp    Array of x coordinate values of the line segments
906     //                     which make up the SPD support sector shape.
907     //    Double_t **yp    Array of y coordinate values of the line segments
908     //                     which make up the SPD support sector shape.
909     // Return:
910     //    none.
911     Int_t i,k;
912     Double_t t,t0,t1;
913
914     m = n*(npr+1);
915     if(GetDebug(2)){
916         cout <<"    X    \t  Y  \t  R  \t  S  \t  E"<< m <<endl;
917         for(i=0;i<n;i++){
918             cout <<"{"<< xc[i] <<",";
919             cout << yc[i] <<",";
920             cout << r[i] <<",";
921             cout << ths[i] <<",";
922             cout << the[i] <<"},"<< endl;
923         } // end for i
924     } // end if GetDebug
925     //
926     if(GetDebug(3)) cout <<"Double_t sA0 = ["<< n*(npr+1)+1<<"][";
927     if(GetDebug(4)) cout <<"3]{";
928     else if(GetDebug(3)) cout <<"2]{";
929     t0 = (Double_t)npr;
930     for(i=0;i<n;i++){
931         t1 = (the[i]-ths[i])/t0;
932         if(GetDebug(5)) cout<<"t1="<< t1<<endl;
933         for(k=0;k<=npr;k++){
934             t=ths[i]+((Double_t)k)*t1;
935             xp[i][k] = TMath::Abs(r[i])*CosD(t)+xc[i];
936             yp[i][k] = TMath::Abs(r[i])*SinD(t)+yc[i];
937             if(GetDebug(3)){
938                 cout << "{"<<xp[i][k]<<","<<yp[i][k];
939                 if(GetDebug(4)) cout <<","<<t;
940                 cout <<"},";
941             } // end if GetDebug
942         } // end for k
943         if(GetDebug(3)) cout << endl;
944     } // end of i
945     if(GetDebug(3)) cout<<"{"<<xp[0][0]<<","<<yp[0][0];
946     if(GetDebug(4)) cout<<","<< ths[0];
947     if(GetDebug(3)) cout<<"}}"<<endl;
948     //
949     return;
950 }
951 //______________________________________________________________________
952 void AliITSv11GeometrySPD::HalfStave(TGeoVolume *moth,Double_t &thicknessAA,
953                                      TGeoManager *mgr){
954     // Define the detail SPD Half Stave geometry.
955     // Inputs:
956     //   TGeoVolume  *moth  The mother volume to place this object.
957     //   Int_t      &thicknessAA Thickness of stave at section A-A
958     //   TGeoManager *mgr   TGeoManager default gGeoManager
959     // Outputs:
960     //  none.
961     // Return:
962     //  none.
963
964     thicknessAA = 1.03*fgkmm; // Default value
965     if(moth==0){
966       Error("HalfStave","moth=%p mgr=%p",moth,mgr);
967         return;
968     } // end if moth==0
969 }
970 //----------------------------------------------------------------------
971 void AliITSv11GeometrySPD::CreateFigure0(const Char_t *filepath,
972                                          const Char_t *type,
973                                          TGeoManager *mgr){
974     // Creates Figure 0 for the documentation of this class. In this
975     // specific case, it creates the X,Y cross section of the SPD suport
976     // section, center and ends. The output is written to a standard
977     // file name to the path specificed.
978     // Inputs:
979     //   const Char_t *filepath  Path where the figure is to be drawn
980     //   const Char_t *type      The type of file, default is gif.
981     //   TGeoManager  *mgr       The TGeoManager default gGeoManager
982     // Output:
983     //   none.
984     // Return:
985     //   none.
986     TGeoXtru *sA0,*sA1,*sB0,*sB1;
987     //TPolyMarker *pmA,*pmB;
988     TPolyLine plA0,plA1,plB0,plB1;
989     TCanvas *canvas;
990     TLatex txt;
991     Double_t x=0.0,y=0.0;
992     Int_t i,kNRadii=6;
993
994     if(strcmp(filepath,"")){
995         Error("CreateFigure0","filepath=%s type=%s",filepath,type);
996     } // end if
997     //
998     sA0 = (TGeoXtru*) mgr->GetVolume(
999         "ITSSPDCarbonFiberSupportSectorA0_1")->GetShape();
1000     sA1 = (TGeoXtru*) mgr->GetVolume(
1001         "ITSSPDCarbonFiberSupportSectorAirA1_1")->GetShape();
1002     sB0 = (TGeoXtru*) mgr->GetVolume(
1003         "ITSSPDCarbonFiberSupportSectorEndB0_1")->GetShape();
1004     sB1 = (TGeoXtru*) mgr->GetVolume(
1005         "ITSSPDCarbonFiberSupportSectorEndAirB1_1")->GetShape();
1006     //pmA = new TPolyMarker();
1007     //pmA.SetMarkerStyle(2); // +
1008     //pmA.SetMarkerColor(7); // light blue
1009     //pmB = new TPolyMarker();
1010     //pmB.SetMarkerStyle(5); // X
1011     //pmB.SetMarkerColor(6); // purple
1012     plA0.SetPolyLine(sA0->GetNvert());
1013     plA0.SetLineColor(1); // black
1014     plA0.SetLineStyle(1);
1015     plA1.SetPolyLine(sA1->GetNvert());
1016     plA1.SetLineColor(2); // red
1017     plA1.SetLineStyle(1);
1018     plB0.SetPolyLine(sB0->GetNvert());
1019     plB0.SetLineColor(3); // Green
1020     plB0.SetLineStyle(2);
1021     plB1.SetPolyLine(sB1->GetNvert());
1022     plB1.SetLineColor(4); // Blue
1023     plB1.SetLineStyle(2);
1024     //for(i=0;i<kNRadii;i++) pmA.SetPoint(i,xyB1p[i][0],xyB1p[i][1]);
1025     //for(i=0;i<kNRadii;i++) pmB.SetPoint(i,xyB1p[i][0],xyB1p[i][1]);
1026     for(i=0;i<sA0->GetNvert();i++) plA0.SetPoint(i,sA0->GetX(i),sA0->GetY(i));
1027     for(i=0;i<sA1->GetNvert();i++) plA1.SetPoint(i,sA1->GetX(i),sA1->GetY(i));
1028     for(i=0;i<sB0->GetNvert();i++) plB0.SetPoint(i,sB0->GetX(i),sB0->GetY(i));
1029     for(i=0;i<sB1->GetNvert();i++) plB1.SetPoint(i,sB1->GetX(i),sB1->GetY(i));
1030     canvas = new TCanvas("AliITSv11GeometrySPDFig0","",1000,1000);
1031     canvas->Range(-3.,-3.,3.,3.);
1032     txt.SetTextSize(0.05);
1033     txt.SetTextAlign(33);
1034     txt.SetTextColor(1);
1035     txt.DrawLatex(2.9,2.9,"Section A-A outer Carbon Fiber surface");
1036     txt.SetTextColor(2);
1037     txt.DrawLatex(2.9,2.5,"Section A-A Inner Carbon Fiber surface");
1038     txt.SetTextColor(3);
1039     txt.DrawLatex(2.9,2.1,"Section E-E outer Carbon Fiber surface");
1040     txt.SetTextColor(4);
1041     txt.DrawLatex(2.9,1.7,"Section E-E Inner Carbon Fiber surface");
1042     plA0.Draw();
1043     plA1.Draw();
1044     plB0.Draw();
1045     plB1.Draw();
1046     //pmA.Draw();
1047     //pmB.Draw();
1048     //
1049     x = 1.0;
1050     y = -2.5;
1051     Char_t chr[3];
1052     for(i=0;i<kNRadii;i++){
1053         sprintf(chr,"%2d",i);txt.DrawLatex(x-0.1,y,chr);
1054         sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x,y,chr);
1055         sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x+0.5,y,chr);
1056         sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x+1.0,y,chr);
1057         sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x+1.5,y,chr);
1058         sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x+2.0,y,chr);
1059         if(kTRUE) txt.DrawLatex(x+2.5,y,"A-A/E-E");
1060         else txt.DrawLatex(x+2.5,y,"E-E");
1061     } // end for i
1062     txt.DrawLatex(x,y,"x_{c} mm");
1063     txt.DrawLatex(x+0.5,y,"y_{c} mm");
1064     txt.DrawLatex(x+1.0,y,"R mm");
1065     txt.DrawLatex(x+1.5,y,"#theta_{start}^{#circle}");
1066     txt.DrawLatex(x+2.0,y,"#theta_{end}^{#circle}");
1067     txt.DrawLatex(x+2.5,y,"Section");
1068     //
1069 }