]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSv11GeometrySPD.cxx
Added flow example script
[u/mrichter/AliRoot.git] / ITS / AliITSv11GeometrySPD.cxx
1 /**************************************************************************
2  * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15 //
16 // This class Defines the Geometry for the ITS services and support cones
17 // outside of the 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
25 /* $Id$ */
26
27 // General Root includes
28 #include <Riostream.h>
29 #include <TMath.h>
30 #include <TLatex.h>
31 #include <TCanvas.h>
32 #include <TPolyLine.h>
33 #include <TPolyMarker.h>
34 // Root Geometry includes
35 #include <TGeoVolume.h>
36 #include <TGeoTube.h> // contains TGeoTubeSeg
37 #include <TGeoArb8.h>
38 #include <TGeoEltu.h>
39 #include <TGeoXtru.h>
40 #include <TGeoMatrix.h>
41 #include <TGeoMaterial.h>
42 #include <TGeoMedium.h>
43 #include <TGeoCompositeShape.h>
44 // AliRoot includes
45 #include "AliMagF.h"
46 #include "AliRun.h"
47 // Declaration file
48 #include "AliITSv11GeometrySPD.h"
49
50 ClassImp(AliITSv11GeometrySPD)
51
52 #define SQ(A) (A)*(A)
53
54 //______________________________________________________________________
55 Int_t AliITSv11GeometrySPD::CreateSPDCentralMaterials(Int_t &medOffset, Int_t &matOffset) const
56 {
57     // Define the specific materials used for the ITS SPD central
58     // detectors. Note, These are the same old names. By the ALICE
59     // naming convension, these should start out at ITS SPD ....
60     // This data has been taken from AliITSvPPRasymmFMD::CreateMaterials().
61     // Intputs:
62     //    Int_t  &medOffset   The starting number of the list of media
63     //    Int_t  &matOffset   The starting number of the list of Materials
64     // Outputs:
65     //    Int_t  &medOffset   The ending number of the list of media
66     //    Int_t  &matOffset   The ending number of the list of Materials
67     // Return:
68     //    the last material number used +1 (the next avaiable material number).
69     //Begin_Html
70     /*
71       <img src="http://alice.pd.infn.it/latestdr/all-sections-module.ps"
72        title="SPD Sector drawing with all cross sections defined">
73        <p>The SPD Sector definition.
74       <img src="http://alice.pd.infn.it/latestdr/assembly-10-modules.ps"
75       titile="SPD All Sectors end view with thermal sheald">
76       <p>The SPD all sector end view with thermal sheald.
77       <img src="http://alice.pd.infn.it/latestdr/assembly.ps"
78       title="SPD side view cross section">
79       <p>SPD side view cross section with condes and thermal shealds.
80       <img src="http://alice.pd.infn.it/latestdr/SECTION-A_A.jpg"
81       title="Cross setion A-A"><p>Cross section A-A
82       <img src="http://alice.pd.infn.it/latestdr/SECTION-B_B.jpg"
83       title="Cross section B-B"><p>Cross section B-B
84       <img src="http://alice.pd.infn.it/latestdr/SECTION-C_C.jpg"
85       title-"Cross section C-C"><p>Cross section C-C
86       <img src="http://alice.pd.infn.it/latestdr/SECTION-D_D.jpg"
87       title="Cross section D-D"><p>Cross section D-D
88       <img src="http://alice.pd.infn.it/latestdr/SECTION-F_F.jpg"
89       title="Cross section F-F"><p>Cross section F-F
90       <img src="http://alice.pd.infn.it/latestdr/SECTION-G_G.jpg"
91       title="Cross section G-G"><p>Cross section G-G
92      */
93     //End_Html
94     const Double_t ktmaxfd = 0.1*fgkDegree; // Degree
95     const Double_t kstemax = 1.0*fgkcm; // cm
96     const Double_t kdeemax = 0.1; // Fraction of particle's energy 0<deemax<=1
97     const Double_t kepsil  = 1.0E-4; //
98     const Double_t kstmin  = 0.0*fgkcm; // cm "Default value used"
99     const Double_t ktmaxfdAir = 0.1*fgkDegree; // Degree
100     const Double_t kstemaxAir = 1.0000E+00*fgkcm; // cm
101     const Double_t kdeemaxAir = 0.1; //Fraction of particle's energy 0<deemax<=1
102     const Double_t kepsilAir  = 1.0E-4;//
103     const Double_t kstminAir  = 0.0*fgkcm; // cm "Default value used"
104     const Double_t ktmaxfdSi = 0.1*fgkDegree; // .10000E+01; // Degree
105     const Double_t kstemaxSi = 0.0075*fgkcm; //  .10000E+01; // cm
106     const Double_t kdeemaxSi = 0.1; // Fraction of particle's energy 0<deemax<=1
107     const Double_t kepsilSi  = 1.0E-4;//
108     const Double_t kstminSi  = 0.0*fgkcm; // cm "Default value used"
109     //
110     Int_t matindex=matOffset;
111     Int_t medindex=medOffset;
112     Double_t params[8]={8*0.0};
113     TGeoMaterial *mat;
114     TGeoMixture  *mix;
115     TGeoMedium   *med;
116     //
117     Int_t    ifield = (gAlice->Field()->Integ());
118     Double_t fieldm = (gAlice->Field()->Max());
119     params[1] = (Double_t) ifield;
120     params[2] = fieldm;
121     params[3] = ktmaxfdSi;
122     params[4] = kstemaxSi;
123     params[5] = kdeemaxSi;
124     params[6] = kepsilSi;
125     params[7] = kstminSi;
126
127     mat = new TGeoMaterial("SI",28.086,14.0,2.33*fgkgcm3,
128                            TGeoMaterial::kMatStateSolid,25.0*fgkCelsius,
129                            0.0*fgkPascal);
130     mat->SetIndex(matindex);
131     med = new TGeoMedium("SI",medindex++,mat,params);
132     //med = new TGeoMedium("SI",medindex++,matindex++,0,ifield,
133     //           fieldm,ktmaxfdSi,kstemaxSi,kdeemaxSi,kepsilSi,kstminSi);
134     //
135     mat = new TGeoMaterial("SPD SI CHIP",28.086,14.0,2.33*fgkgcm3,
136                            TGeoMaterial::kMatStateSolid,25.0*fgkCelsius,
137                            0.0*fgkPascal);
138     mat->SetIndex(matindex);
139     med = new TGeoMedium("SPD SI CHIP",medindex++,mat,params);
140     //med = new TGeoMedium("SPD SI CHIP",medindex++,matindex++,0,ifield,
141     //           fieldm,ktmaxfdSi,kstemaxSi,kdeemaxSi,kepsilSi,kstminSi);
142     //
143     mat = new TGeoMaterial("SPD SI BUS",28.086,14.0,2.33*fgkgcm3,
144                            TGeoMaterial::kMatStateSolid,25.0*fgkCelsius,
145                            0.0*fgkPascal);
146     mat->SetIndex(matindex);
147     med = new TGeoMedium("SPD SI BUS",medindex++,mat,params);
148     //med = new TGeoMedium("SPD SI BUS",medindex++,matindex++,0,ifield,
149     //           fieldm,ktmaxfdSi,kstemaxSi,kdeemaxSi,kepsilSi,kstminSi);
150     //
151     // Carbon fiber by fractional weight "C (M55J)"
152     mix = new TGeoMixture("C (M55J)",4,1.9866*fgkgcm3);
153     mix->SetIndex(matindex);
154      // Carbon by fractional weight
155     mix->DefineElement(0,12.0107,6.0,0.908508078);
156     // Nitrogen by fractional weight
157     mix->DefineElement(1,14.0067,7.0,0.010387573); 
158     // Oxigen by fractional weight
159     mix->DefineElement(2,15.9994,8.0,0.055957585); 
160     // Hydrogen by fractional weight
161     mix->DefineElement(3,1.00794,1.0,0.025146765); 
162     mix->SetPressure(0.0*fgkPascal);
163     mix->SetTemperature(25.0*fgkCelsius);
164     mix->SetState(TGeoMaterial::kMatStateSolid);
165     params[3] = ktmaxfd;
166     params[4] = kstemax;
167     params[5] = kdeemax;
168     params[6] = kepsil;
169     params[7] = kstmin;
170     med = new TGeoMedium("ITSspdCarbonFiber",medindex++,mix,params);
171     //med = new TGeoMedium("ITSspdCarbonFiber",medindex++,matindex++,0,ifield,
172     //           fieldm,ktmaxfd,kstemax,kdeemax,kepsil,kstmin);
173     //
174     // Carbon fiber by fractional weight
175     mix = new TGeoMixture("Air",4,1.20479E-3*fgkgcm3);
176     mix->SetIndex(matindex);
177     mix->DefineElement(0,12.0107,6.0,0.000124); // Carbon by fractional weight
178     mix->DefineElement(1,14.0067,7.0,0.755267); // Nitrogen by fractional weight
179     mix->DefineElement(2,15.9994,8.0,0.231781); // Oxigen by fractional weight
180     mix->DefineElement(3,39.948,18.0,0.012827); // Argon by fractional weight
181     mix->SetPressure(101325.0*fgkPascal); // 1 atmosphere
182     mix->SetTemperature(25.0*fgkCelsius);
183     mix->SetState(TGeoMaterial::kMatStateGas);
184     params[3] = ktmaxfdAir;
185     params[4] = kstemaxAir;
186     params[5] = kdeemaxAir;
187     params[6] = kepsilAir;
188     params[7] = kstminAir;
189     med = new TGeoMedium("ITSspdAir",medindex++,mix,params);
190     //med = new TGeoMedium("ITSspdAir",medindex++,matindex++,0,ifield,
191     //         fieldm,ktmaxfdAir,kstemaxAir,kdeemaxAir,kepsilAir,kstminAir);
192     //
193     // Carbon fiber by fractional weight
194     mix = new TGeoMixture("INOX",9,8.03*fgkgcm3);
195     mix->SetIndex(matindex);
196     mix->DefineElement(0,12.0107, 6.0,0.0003); // Carbon by fractional weight
197     mix->DefineElement(1,54.9380,25.0,0.02); // Iron by fractional weight
198     mix->DefineElement(2,28.0855,14.0,0.01); // Sodium by fractional weight
199     mix->DefineElement(3,30.9738,15.0,0.00045); //  by fractional weight
200     mix->DefineElement(4,32.066 ,16.0,0.0003); // by fractional weight
201     mix->DefineElement(5,58.6928,28.0,0.12); // Nickel by fractional weight
202     mix->DefineElement(6,55.9961,24.0,0.17); // by fractional weight
203     mix->DefineElement(7,95.84  ,42.0,0.025); // by fractional weight
204     mix->DefineElement(8,55.845 ,26.0,0.654); // by fractional weight
205     mix->SetPressure(0.0*fgkPascal); //
206     mix->SetTemperature(25.0*fgkCelsius);
207     mix->SetState(TGeoMaterial::kMatStateSolid);
208     params[3] = ktmaxfdAir;
209     params[4] = kstemaxAir;
210     params[5] = kdeemaxAir;
211     params[6] = kepsilAir;
212     params[7] = kstminAir;
213     med = new TGeoMedium("ITSspdStainlessSteel",medindex++,mix,params);
214     //med =new TGeoMedium("ITSspdStainlessSteel",medindex++,matindex++,0,ifield,
215     //         fieldm,ktmaxfdAir,kstemaxAir,kdeemaxAir,kepsilAir,kstminAir);
216     //
217     // Carbon fiber by fractional weight
218     mix->SetIndex(matindex);
219     mix = new TGeoMixture("Freon",2,1.63*fgkgcm3);
220     mix->DefineElement(0,12.0107,6.0,4); // Carbon by fractional weight
221     mix->DefineElement(1,18.9984032,9.0,10); // Florine by fractional weight
222     mix->SetPressure(101325.0*fgkPascal); // 1 atmosphere
223     mix->SetTemperature(25.0*fgkCelsius);
224     mix->SetState(TGeoMaterial::kMatStateLiquid);
225     params[3] = ktmaxfdAir;
226     params[4] = kstemaxAir;
227     params[5] = kdeemaxAir;
228     params[6] = kepsilAir;
229     params[7] = kstminAir;
230     med = new TGeoMedium("ITSspdCoolingFluid",medindex++,mix,params);
231     //med = new TGeoMedium("ITSspdCoolingFluid",medindex++,matindex++,0,ifield,
232     //         fieldm,ktmaxfdAir,kstemaxAir,kdeemaxAir,kepsilAir,kstminAir);
233     //
234     medOffset = medindex;
235     matOffset = matindex;
236     return matOffset;
237 }
238 //______________________________________________________________________
239 void AliITSv11GeometrySPD::InitSPDCentral(Int_t offset,TVirtualMC *vmc) const {
240     // Do any SPD Central detector related initilizations, setting
241     // transport cuts for example.
242     // Some GEANT3 Physics switches
243     // "MULTS"
244     // Multiple scattering. The variable IMULS controls this process. For 
245     // more information see [PHYS320 or 325 or 328].
246     // 0 - No multiple scattering.
247     // 1 - Multiple scattering according to Moli�re theory. Default setting.
248     // 2 - Same as 1. Kept for backward compatibility.
249     // 3 - Pure Gaussian scattering according to the Rossi formula.
250     // "DRAY"
251     // delta ray production. The variable IDRAY controls this process. 
252     // See [PHYS430]
253     // 0 - No delta rays production.
254     // 1 - delta rays production with generation of . Default setting.
255     // 2 - delta rays production without generation of .
256     // "LOSS"
257     // Continuous energy loss. The variable ILOSS controls this process.
258     // 0 - No continuous energy loss, IDRAY is set to 0.
259     // 1 - Continuous energy loss with generation of delta rays above 
260     //     DCUTE (common/GCUTS/) and restricted Landau fluctuations below DCUTE.
261     // 2 - Continuous energy loss without generation of delta rays and full 
262     //     Landau-Vavilov-Gauss fluctuations. In this case the variable IDRAY 
263     //     is forced to 0 to avoid double counting of fluctuations. Default 
264     //     setting.
265     // 3 - Same as 1, kept for backward compatibility.
266     // 4 - Energy loss without fluctuation. The value obtained from the 
267     //     tables is used directly.
268     // Intputs:
269     //    Int_t       offset The material/medium index offset.
270     //    TVirturalMC *vmc The pointer to the virtual Monte Carlo default gMC.
271     // Outputs:
272     //    none.
273     // Return:
274     //    none.
275     Int_t i,n=4;
276
277     for(i=0;i<n;i++){
278       vmc->Gstpar(i+offset,"CUTGAM",30.0*fgkKeV);
279       vmc->Gstpar(i+offset,"CUTELE",30.0*fgkKeV);
280       vmc->Gstpar(i+offset,"CUTNEU",30.0*fgkKeV);
281       vmc->Gstpar(i+offset,"CUTHAD",30.0*fgkKeV);
282       vmc->Gstpar(i+offset,"CUTMUO",30.0*fgkKeV);
283       vmc->Gstpar(i+offset,"BCUTE",30.0*fgkKeV);
284       vmc->Gstpar(i+offset,"BCUTM",30.0*fgkKeV);
285       vmc->Gstpar(i+offset,"DCUTE",30.0*fgkKeV);
286       vmc->Gstpar(i+offset,"DCUTM",30.0*fgkKeV);
287       //vmc->Gstpar(i+offset,"PPCUTM",);
288       //vmc->Gstpar(i+offset,"PAIR",);
289       //vmc->Gstpar(i+offset,"COMPT",);
290       //vmc->Gstpar(i+offset,"PHOT",);
291       //vmc->Gstpar(i+offset,"PFIS",);
292       vmc->Gstpar(i+offset,"DRAY",1);
293       //vmc->Gstpar(i+offset,"ANNI",);
294       //vmc->Gstpar(i+offset,"BREM",);
295       //vmc->Gstpar(i+offset,"HADR",);
296       //vmc->Gstpar(i+offset,"MUNU",);
297       //vmc->Gstpar(i+offset,"DCAY",);
298       vmc->Gstpar(i+offset,"LOSS",1);
299       //vmc->Gstpar(i+offset,"MULS",);
300       //vmc->Gstpar(i+offset,"GHCOR1",);
301       //vmc->Gstpar(i+offset,"BIRK1",);
302       //vmc->Gstpar(i+offset,"BRIK2",);
303       //vmc->Gstpar(i+offset,"BRIK3",);
304       //vmc->Gstpar(i+offset,"LABS",);
305       //vmc->Gstpar(i+offset,"SYNC",);
306       //vmc->Gstpar(i+offset,"STRA",);
307     } // end for i
308 }
309 //______________________________________________________________________
310 void AliITSv11GeometrySPD::SPDSector(TGeoVolume *moth,TGeoManager *mgr){
311     // Position of the Carbon Fiber Assembly based on distance
312     // of closest point of SPD stave to beam pipe figures
313     // all-sections-modules.ps of 7.22mm at section A-A.
314     // Inputs:
315     //   TGeoVolume *moth   the mother volume which this
316     //                      object/volume is to be placed in.
317     // Outputs:
318     //   none.
319     // Return:
320     //   none.
321     const Double_t kSPDclossesStaveAA    = 7.22*fgkmm;
322     const Double_t kSectorStartingAngle  = -72.0*fgkDegree;
323     const Double_t kNSectorsTotal        = 10.; // number
324     const Double_t kSectorRelativeAngle  = 360./kNSectorsTotal*fgkDegree;
325     const Double_t kBeamPipeRadius       = 0.5*60.0*fgkmm;
326     //
327     Int_t i;
328     Double_t angle,radiusSector,xAAtubeCenter0,yAAtubeCenter0;
329     Double_t staveThicknessAA=1.03*fgkmm; // get from stave geometry.
330     TGeoCombiTrans *secRot=new TGeoCombiTrans();
331     TGeoVolume *vCarbonFiberSector;
332     TGeoMedium *medSPDcf;
333
334     medSPDcf = mgr->GetMedium("ITSspdCarbonFiber");
335     vCarbonFiberSector = new TGeoVolumeAssembly("ITSSPDCarbonFiberSectorV");
336     vCarbonFiberSector->SetMedium(medSPDcf);
337     CarbonFiberSector(vCarbonFiberSector,xAAtubeCenter0,yAAtubeCenter0);
338     //SectorPlusStaves(vCarbonFiberSector,xAAtubeCenter0,yAAtubeCenter0);
339     vCarbonFiberSector->SetVisibility(kTRUE); // logical volume
340     // Compute the radial shift out of the sectors.
341     radiusSector = kBeamPipeRadius+kSPDclossesStaveAA+staveThicknessAA;
342     radiusSector *= radiusSector; // squaring;
343     radiusSector -= xAAtubeCenter0*xAAtubeCenter0;
344     radiusSector = -yAAtubeCenter0+TMath::Sqrt(radiusSector);
345     angle = kSectorStartingAngle;
346     secRot->RotateZ(angle);
347     for(i=0;i<(Int_t)kNSectorsTotal;i++){
348         secRot->SetDx(-radiusSector*TMath::Sin(angle/fgkRadian));
349         secRot->SetDy(radiusSector*TMath::Cos(angle/fgkRadian));
350         //secRot->RegisterYourself();
351         moth->AddNode(vCarbonFiberSector,i+1,new TGeoCombiTrans(*secRot));
352         if(GetDebug(5)){
353             printf("i=%d angle=%g angle[rad]=%g radiusSector=%g x=%g y=%g \n",
354                    i,angle,angle/fgkRadian,radiusSector,
355                    -radiusSector*TMath::Sin(angle/fgkRadian),
356                    radiusSector*TMath::Cos(angle/fgkRadian));
357         } // end if GetDebug(5)
358         angle += kSectorRelativeAngle;
359         secRot->RotateZ(kSectorRelativeAngle);
360     } // end for i
361     if(GetDebug(3)){
362         moth->PrintNodes();
363     } // end if GetDebug().
364     delete secRot;
365 }
366 //______________________________________________________________________
367 void AliITSv11GeometrySPD::CarbonFiberSector(TGeoVolume *moth,
368                                              Double_t &xAAtubeCenter0,
369                                              Double_t &yAAtubeCenter0,
370                                              TGeoManager *mgr){
371     // Define the detail SPD Carbon fiber support Sector geometry.
372     // Based on the drawings ALICE-Pixel "Construzione Profilo Modulo"
373     // March 25 2004 and ALICE-SUPPORTO "construzione Profilo Modulo"
374     // Define Outside radii as negitive, Outside in the sence that the
375     // center of the arc is outside of the object.
376     // February 16 2004.
377     // Inputs:
378     //   TGeoVolume *moth  The mother volume to put this object
379     // Outputs:
380     //  Double_t &xAAtubeCenter0  The x location of the outer surface
381     //                            of the cooling tube center for tube 0.
382     //                            This location helps determine where 
383     //                            this sector is to be located (information
384     //                            used for this is the distance the
385     //                            center of the #0 detector is from the
386     //                            beam pipe. Measurements taken at 
387     //                            cross section A-A.
388     //  Double_t &yAAtubeCenter0  The y location of the outer surface
389     //                            of the cooling tube center for tube 0
390     //                            This location helps determine where
391     //                            this sector is to be located (information
392     //                            used for this is the distance the 
393     //                            center of the #0 detector is from the
394     //                            beam pipe. Measurements taken at 
395     //                            cross section A-A.
396     //   TGeoManager *mgr         The TGeoManager as needed, default is
397     //                            gGeoManager.
398     // Return:
399     //  none.
400     TGeoMedium *medSPDcf  = 0; // SPD support cone Carbon Fiber materal number.
401     //TGeoMedium *medSPDfs  = 0; // SPD support cone inserto stesalite 4411w.
402     //TGeoMedium *medSPDfo  = 0; // SPD support cone foam, Rohacell 50A.
403     TGeoMedium *medSPDss  = 0; // SPD support cone screw material,Stainless
404     TGeoMedium *medSPDair = 0; // SPD support cone Air
405     //TGeoMedium *medSPDal  = 0; // SPD support cone SDD mounting bracket Al
406     TGeoMedium *medSPDcoolfl  = 0; // SPD cooling fluid, Freeon
407     medSPDcf = mgr->GetMedium("ITSspdCarbonFiber");
408     //medSPDfs = mgr->GetMedium("ITSspdStaselite4411w");
409     //medSPDfo = mgr->GetMedium("ITSspdRohacell50A");
410     medSPDss = mgr->GetMedium("ITSspdStainlessSteel");
411     medSPDair= mgr->GetMedium("ITSspdAir");
412     medSPDcoolfl= mgr->GetMedium("ITSspdCoolingFluid");
413     //
414     const Double_t ksecDz        = 0.5*500.0*fgkmm;
415     const Double_t ksecLen       = 30.0*fgkmm;
416     const Double_t ksecCthick    = 0.20*fgkmm;
417     const Double_t ksecDipLength = 3.2*fgkmm;
418     const Double_t ksecDipRadii  = 0.4*fgkmm;
419     //const Double_t ksecCoolingTubeExtraDepth = 0.86*fgkmm;
420     // These positions, ksecX*,ksecY* are the center of curvatures
421     // for the different point around the SPD sector. The radii,
422     // inner and outer, are the radous of curvature about the centers
423     // ksecX* and ksecY*. To draw this SPD sector, first plot all of
424     // the ksecX and ksecY points and draw circles of the specified
425     // radius about these points. Connect the circles, such that the
426     // lines are tangent to the circles, in accordance with the
427     // radii being "Inside" or "Outside". These lines and the 
428     // corresponding arc's are the surface of this SPD sector.
429     const Double_t ksecX0   = -10.725*fgkmm;
430     const Double_t ksecY0   = -14.853*fgkmm;
431     const Double_t ksecR0   = -0.8*fgkmm; // Outside
432     const Double_t ksecX1   = -13.187*fgkmm;
433     const Double_t ksecY1   = -19.964*fgkmm;
434     const Double_t ksecR1   = +0.6*fgkmm; // Inside
435     //const Double_t ksecDip0 = 5.9*fgkmm;
436     //
437     const Double_t ksecX2   = -3.883*fgkmm;
438     const Double_t ksecY2   = -17.805*fgkmm;
439     const Double_t ksecR2   = +0.80*fgkmm; // Inside Guess. 
440     const Double_t ksecX3   = -3.123*fgkmm;
441     const Double_t ksecY3   = -14.618*fgkmm;
442     const Double_t ksecR3   = -0.6*fgkmm; // Outside
443     //const Double_t ksecDip1 = 8.035*fgkmm;
444     //
445     const Double_t ksecX4   = +11.280*fgkmm;
446     const Double_t ksecY4   = -14.473*fgkmm;
447     const Double_t ksecR4   = +0.8*fgkmm; // Inside
448     const Double_t ksecX5   = +19.544*fgkmm;
449     const Double_t ksecY5   = +10.961*fgkmm;
450     const Double_t ksecR5   = +0.8*fgkmm; // Inside
451     //const Double_t ksecDip2 = 4.553*fgkmm;
452     //
453     const Double_t ksecX6   = +10.830*fgkmm;
454     const Double_t ksecY6   = +16.858*fgkmm;
455     const Double_t ksecR6   = +0.6*fgkmm; // Inside
456     const Double_t ksecX7   = +11.581*fgkmm;
457     const Double_t ksecY7   = +13.317*fgkmm;
458     const Double_t ksecR7   = -0.6*fgkmm; // Outside
459     //const Double_t ksecDip3 = 6.978*fgkmm;
460     //
461     const Double_t ksecX8   = -0.733*fgkmm;
462     const Double_t ksecY8   = +17.486*fgkmm;
463     const Double_t ksecR8   = +0.6*fgkmm; // Inside
464     const Double_t ksecX9   = +0.562*fgkmm;
465     //const Double_t ksecY9   = +14.486*fgkmm;  // correction by
466     const Double_t ksecY9   = +14.107*fgkmm;    // Alberto
467     const Double_t ksecR9   = -0.6*fgkmm; // Outside
468     //const Double_t ksecDip4 = 6.978*fgkmm;
469     //
470     const Double_t ksecX10  = -12.252*fgkmm;
471     const Double_t ksecY10  = +16.298*fgkmm;
472     const Double_t ksecR10  = +0.6*fgkmm; // Inside
473     const Double_t ksecX11  = -10.445*fgkmm;
474     const Double_t ksecY11  = +13.162*fgkmm;
475     const Double_t ksecR11  = -0.6*fgkmm; // Outside
476     //const Double_t ksecDip5 = 6.978*fgkmm;
477     //
478     const Double_t ksecX12  = -22.276*fgkmm;
479     const Double_t ksecY12  = +12.948*fgkmm;
480     const Double_t ksecR12  = +0.85*fgkmm; // Inside
481     //const Double_t ksecX13 = *fgkmm;
482     //const Double_t ksecY13 = *fgkmm;
483     const Double_t ksecR13  = -0.8*fgkmm; // Outside
484     const Double_t ksecAngleSide13 = 36.0*fgkDegree;
485     //
486     const Int_t ksecNRadii = 20;
487     const Int_t ksecNPointsPerRadii = 4;
488     const Int_t ksecNCoolingTubeDips = 6;
489     // Since the Rounded parts are aproximated by a regular polygon and
490     // a cooling tube of the propper diameter must fit, a scaling factor
491     // increases the size of the polygon for the tube to fit.
492     //const Double_t ksecRCoolScale = 1./TMath::Cos(TMath::Pi()/
493     //                                          (Double_t)ksecNPointsPerRadii);
494     const Double_t ksecZEndLen  = 30.00*fgkmm;
495     //const Double_t ksecZFlangLen= 45.00*fgkmm;
496     const Double_t ksecTl       = 0.860*fgkmm;
497     const Double_t ksecCthick2  = 0.600*fgkmm;
498     //const Double_t ksecCthick3  = 1.800*fgkmm;
499     //const Double_t ksecSidelen  = 22.00*fgkmm;
500     //const Double_t ksecSideD5   = 3.679*fgkmm;
501     //const Double_t ksecSideD12  = 7.066*fgkmm;
502     const Double_t ksecRCoolOut = 2.400*fgkmm;
503     const Double_t ksecRCoolIn  = 2.000*fgkmm;
504     const Double_t ksecDl1      = 5.900*fgkmm;
505     const Double_t ksecDl2      = 8.035*fgkmm;
506     const Double_t ksecDl3      = 4.553*fgkmm;
507     const Double_t ksecDl4      = 6.978*fgkmm;
508     const Double_t ksecDl5      = 6.978*fgkmm;
509     const Double_t ksecDl6      = 6.978*fgkmm;
510     const Double_t ksecCoolTubeThick  = 0.04*fgkmm;
511     const Double_t ksecCoolTubeROuter = 2.6*fgkmm;
512     const Double_t ksecCoolTubeFlatX  = 3.696*fgkmm;
513     const Double_t ksecCoolTubeFlatY  = 0.68*fgkmm;
514     //const Double_t ksecBeamX0   = 0.0*fgkmm; // guess
515     //const Double_t ksecBeamY0   = (15.223+40.)*fgkmm; // guess
516     //
517     const Int_t ksecNPoints = (ksecNPointsPerRadii+1)*ksecNRadii + 8;
518     Double_t secX[ksecNRadii] = {ksecX0,ksecX1,-1000.0,ksecX2 ,ksecX3 ,-1000.0,
519                                  ksecX4,ksecX5,-1000.0,ksecX6 ,ksecX7 ,-1000.0,
520                                  ksecX8,ksecX9,-1000.0,ksecX10,ksecX11,-1000.0,
521                                  ksecX12,-1000.0};
522     Double_t secY[ksecNRadii] = {ksecY0,ksecY1,-1000.0,ksecY2 ,ksecY3 ,-1000.0,
523                                  ksecY4,ksecY5,-1000.0,ksecY6 ,ksecY7 ,-1000.0,
524                                  ksecY8,ksecY9,-1000.0,ksecY10,ksecY11,-1000.0,
525                                  ksecY12,-1000.0};
526     Double_t secR[ksecNRadii] ={ksecR0 ,ksecR1 ,-.5*ksecDipLength-ksecDipRadii,
527                                 ksecR2 ,ksecR3 ,-.5*ksecDipLength-ksecDipRadii,
528                                 ksecR4 ,ksecR5 ,-.5*ksecDipLength-ksecDipRadii,
529                                 ksecR6 ,ksecR7 ,-.5*ksecDipLength-ksecDipRadii,
530                                 ksecR8 ,ksecR9 ,-.5*ksecDipLength-ksecDipRadii,
531                                 ksecR10,ksecR11,-.5*ksecDipLength-ksecDipRadii,
532                                 ksecR12,ksecR13};/*
533     Double_t secDip[ksecNRadii]={0.0,0.0,ksecDip0,0.0,0.0,ksecDip1,
534                                  0.0,0.0,ksecDip2,0.0,0.0,ksecDip3,
535                                  0.0,0.0,ksecDip4,0.0,0.0,ksecDip5,
536                                  0.0,0.0};*/
537     Double_t secX2[ksecNRadii];
538     Double_t secY2[ksecNRadii];
539     Double_t secR2[ksecNRadii] = {
540         ksecR0,ksecR1,ksecRCoolOut,ksecR2,ksecR3,ksecRCoolOut,ksecR4,ksecR5,
541         ksecRCoolOut,ksecR6,ksecR7,ksecRCoolOut,ksecR8,ksecR9,ksecRCoolOut,
542         ksecR10,ksecR11,ksecRCoolOut,ksecR12,ksecR13};
543     Double_t secDip2[ksecNCoolingTubeDips]={ksecDl1,ksecDl2,ksecDl3,
544                                             ksecDl4,ksecDl5,ksecDl6};
545     Double_t secX3[ksecNRadii];
546     Double_t secY3[ksecNRadii];
547     const Int_t ksecDipIndex[ksecNCoolingTubeDips] = {2,5,8,11,14,17};
548     Double_t secAngleStart[ksecNRadii];
549     Double_t secAngleEnd[ksecNRadii];
550     Double_t secAngleStart2[ksecNRadii];
551     Double_t secAngleEnd2[ksecNRadii];
552     Double_t secAngleTurbo[ksecNCoolingTubeDips] = {0.0,0.0,0.0,0.0,0.0,0.0};
553     //Double_t secAngleStart3[ksecNRadii];
554     //Double_t secAngleEnd3[ksecNRadii];
555     Double_t xpp[ksecNPoints],ypp[ksecNPoints];
556     Double_t xpp2[ksecNPoints],ypp2[ksecNPoints];
557     Double_t *xp[ksecNRadii],*xp2[ksecNRadii];
558     Double_t *yp[ksecNRadii],*yp2[ksecNRadii];
559     TGeoXtru *sA0,*sA1,*sB0,*sB1;
560     TGeoEltu *sTA0,*sTA1;
561     TGeoTube *sTB0,*sTB1; //,*sM0;
562     TGeoRotation    *rot;
563     TGeoTranslation *trans;
564     TGeoCombiTrans  *rotrans;
565     Double_t t,t0,t1,a,b,x0,y0,x1,y1;
566     Int_t i,j,k,m;
567     Bool_t tst;
568
569     if(moth==0){
570         Error("CarbonFiberSector","moth=%p",moth);
571         return;
572     } // end if moth==0
573     //SetDebug(3);
574     for(i=0;i<ksecNRadii;i++){
575         xp[i]  = &(xpp[i*(ksecNPointsPerRadii+1)]);
576         yp[i]  = &(ypp[i*(ksecNPointsPerRadii+1)]);
577         xp2[i] = &(xpp2[i*(ksecNPointsPerRadii+1)]);
578         yp2[i] = &(ypp2[i*(ksecNPointsPerRadii+1)]);
579         secX2[i] = secX[i];
580         secY2[i] = secY[i];
581         secX3[i] = secX[i];
582         secY3[i] = secY[i];
583     } // end for i
584
585     // Find starting and ending angles for all but cooling tube sections
586     secAngleStart[0] = 0.5*ksecAngleSide13;
587     for(i=0;i<ksecNRadii-2;i++){
588         tst = kFALSE;
589         for(j=0;j<ksecNCoolingTubeDips;j++) tst = tst||i==ksecDipIndex[j];
590         if(tst) continue;
591         tst = kFALSE;
592         for(j=0;j<ksecNCoolingTubeDips;j++) tst = tst||(i+1)==ksecDipIndex[j];
593         if(tst) j = i+2;
594         else j = i+1;
595         AnglesForRoundedCorners(secX[i],secY[i],secR[i],
596                                 secX[j],secY[j],secR[j],t0,t1);
597         secAngleEnd[i]   = t0;
598         secAngleStart[j] = t1;
599         if(secR[i]>0.0&&secR[j]>0.0)if(secAngleStart[i]>secAngleEnd[i])
600             secAngleEnd[i] += 360.0;
601         secAngleStart2[i] = secAngleStart[i];
602         secAngleEnd2[i]   = secAngleEnd[i];
603     } // end for i
604     secAngleEnd[ksecNRadii-2]   = secAngleStart[ksecNRadii-2] + 
605                                      (secAngleEnd[ksecNRadii-5]-
606                                       secAngleStart[ksecNRadii-5]);
607     if(secAngleEnd[ksecNRadii-2]<0.0) secAngleEnd[ksecNRadii-2] += 360.0;
608     secAngleStart[ksecNRadii-1] = secAngleEnd[ksecNRadii-2] - 180.0;
609     secAngleEnd[ksecNRadii-1]   = secAngleStart[0];
610     secAngleStart2[ksecNRadii-2] = secAngleStart[ksecNRadii-2];
611     secAngleEnd2[ksecNRadii-2]   = secAngleEnd[ksecNRadii-2];
612     secAngleStart2[ksecNRadii-1] = secAngleStart[ksecNRadii-1];
613     secAngleEnd2[ksecNRadii-1]   = secAngleEnd[ksecNRadii-1];
614     // Find location of circle last rounded corner.
615     i = 0;
616     j = ksecNRadii-2;
617     t0 = TanD(secAngleStart[i]-90.);
618     t1 = TanD(secAngleEnd[j]-90.);
619     t  = secY[i] - secY[j];
620     // Note, secR[i=0] <0; secR[j=18]>0; and secR[j+1=19] <0
621     t += (-secR[i]+secR[j+1])*SinD(secAngleStart[i]);
622     t -= (secR[j]-secR[j+1])*SinD(secAngleEnd[j]);
623     t += t1*secX[j] - t0*secX[i];
624     t += t1*(secR[j]-secR[j+1])*CosD(secAngleEnd[j]);
625     t -= t0*(-secR[i]+secR[j+1])*CosD(secAngleStart[i]);
626     secX[ksecNRadii-1] = t/(t1-t0);
627     secY[ksecNRadii-1] = TanD(90.+0.5*ksecAngleSide13)*
628                           (secX[ksecNRadii-1]-secX[0]) + secY[0];
629     secX2[ksecNRadii-1] = secX[ksecNRadii-1];
630     secY2[ksecNRadii-1] = secY[ksecNRadii-1];
631     secX3[ksecNRadii-1] = secX[ksecNRadii-1];
632     secY3[ksecNRadii-1] = secY[ksecNRadii-1];
633     // find location of cooling tube centers
634     for(i=0;i<ksecNCoolingTubeDips;i++){
635         j = ksecDipIndex[i];
636         x0 = secX[j-1] + TMath::Abs(secR[j-1])*CosD(secAngleEnd[j-1]);
637         y0 = secY[j-1] + TMath::Abs(secR[j-1])*SinD(secAngleEnd[j-1]);
638         x1 = secX[j+1] + TMath::Abs(secR[j+1])*CosD(secAngleStart[j+1]);
639         y1 = secY[j+1] + TMath::Abs(secR[j+1])*SinD(secAngleStart[j+1]);
640         t0 = TMath::Sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
641         t  = secDip2[i]/t0;
642         a  = x0+(x1-x0)*t;
643         b  = y0+(y1-y0)*t;
644         if(i==0){ // get location of tube center->Surface for locating
645                   // this sector around the beam pipe. This needs to be
646                   // double checked, but I need my notes for that, Bjorn Nilsen
647             xAAtubeCenter0 = x0+(x1-x0)*t*0.5;
648             yAAtubeCenter0 = y0+(y1-y0)*t*0.5;
649         } // end if i==0
650         if(a+b*(a-x0)/(b-y0)>0.0){
651             secX[j] = a + TMath::Abs(y1-y0)*2.0*ksecDipRadii/t0;
652             secY[j] = b - TMath::Sign(2.0*ksecDipRadii,y1-y0)*(x1-x0)/t0;
653             secX2[j] = a + TMath::Abs(y1-y0)*ksecTl/t0;
654             secY2[j] = b - TMath::Sign(ksecTl,y1-y0)*(x1-x0)/t0;
655             secX3[j] = a + TMath::Abs(y1-y0)*(2.0*ksecDipRadii-
656                                           0.5*ksecCoolTubeFlatY)/t0;
657             secY3[j] = b - TMath::Sign(2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY,
658                                    y1-y0)*(x1-x0)/t0;
659         }else{
660             secX[j] = a - TMath::Abs(y1-y0)*2.0*ksecDipRadii/t0;
661             secY[j] = b + TMath::Sign(2.0*ksecDipRadii,y1-y0)*(x1-x0)/t0;
662             secX2[j] = a - TMath::Abs(y1-y0)*ksecTl/t0;
663             secY2[j] = b + TMath::Sign(ksecTl,y1-y0)*(x1-x0)/t0;
664             secX3[j] = a - TMath::Abs(y1-y0)*(2.0*ksecDipRadii-
665                                           0.5*ksecCoolTubeFlatY)/t0;
666             secY3[j] = b + TMath::Sign(2.0*ksecDipRadii-0.5*ksecCoolTubeFlatY,
667                                       y1-y0)*(x1-x0)/t0;
668         } // end if
669         // Set up Start and End angles to correspond to start/end of dips.
670         t1 = (secDip2[i]-TMath::Abs(secR[j]))/t0;
671         secAngleStart[j] = TMath::RadToDeg()*TMath::ATan2(
672                                y0+(y1-y0)*t1-secY[j],x0+(x1-x0)*t1-secX[j]);
673         if(secAngleStart[j]<0.0) secAngleStart[j] += 360.0;
674         secAngleStart2[j] = secAngleStart[j];
675         t1 = (secDip2[i]+TMath::Abs(secR[j]))/t0;
676         secAngleEnd[j] = TMath::RadToDeg()*TMath::ATan2(
677                                y0+(y1-y0)*t1-secY[j],x0+(x1-x0)*t1-secX[j]);
678         if(secAngleEnd[j]<0.0) secAngleEnd[j] += 360.0;
679         secAngleEnd2[j]   = secAngleEnd[j];
680         if(secAngleEnd[j]>secAngleStart[j]) secAngleEnd[j] -= 360.0;
681         secR[j] = TMath::Sqrt(secR[j]*secR[j]+4.0*ksecDipRadii*ksecDipRadii);
682     } // end for i
683     // Special cases
684     secAngleStart2[8] -= 360.;
685     secAngleStart2[11] -= 360.;
686     //
687     fSPDsectorPoints0.Set(ksecNCoolingTubeDips);
688     fSPDsectorPoints1.Set(ksecNCoolingTubeDips);
689     //
690     for(i=0;i<ksecNCoolingTubeDips;i++){
691         // Find index in xpp[] and ypp[] corresponding to where the
692         // SPD ladders are to be attached. Order them according to
693         // the ALICE numbering schema. Using array of indexes (+-1 for
694         // cooling tubes. For any "bend/dip/edge, there are 
695         // ksecNPointsPerRadii+1 points involved.
696         if(i==0) j=1;
697         else if(i==1) j=0;
698         else j=i;
699         fSPDsectorPoints0[i] = (ksecDipIndex[j]-1)*(ksecNPointsPerRadii+1)+
700                                (ksecNPointsPerRadii);
701         fSPDsectorPoints1[i] = (ksecDipIndex[j]+1)*(ksecNPointsPerRadii+1);
702     } // end for i
703     SPDsectorShape(ksecNRadii,secX,secY,secR,secAngleStart,secAngleEnd,
704                    ksecNPointsPerRadii,m,xp,yp);
705     //  Fix up dips to be square.
706     for(i=0;i<ksecNCoolingTubeDips;i++){
707         j = ksecDipIndex[i];
708         t = 0.5*ksecDipLength+ksecDipRadii;
709         t0 = TMath::RadToDeg()*TMath::ATan(2.0*ksecDipRadii/t);
710         t1 = secAngleEnd[j] + t0;
711         t0 = secAngleStart[j] - t0;
712         x0 = xp[j][1] = secX[j] + t*CosD(t0);
713         y0 = yp[j][1] = secY[j] + t*SinD(t0);
714         x1 = xp[j][ksecNPointsPerRadii-1] = secX[j] + t*CosD(t1);
715         y1 = yp[j][ksecNPointsPerRadii-1] = secY[j] + t*SinD(t1);
716         t0 = 1./((Double_t)(ksecNPointsPerRadii-2));
717         for(k=2;k<ksecNPointsPerRadii-1;k++){// extra points spread them out.
718             t = ((Double_t)(k-1))*t0;
719             xp[j][k] = x0+(x1-x0)*t;
720             yp[j][k] = y0+(y1-y0)*t;
721         } // end for k
722         secAngleTurbo[i] = -TMath::RadToDeg()*TMath::ATan2(y1-y0,x1-x0);
723         if(GetDebug(3)){ 
724            cout <<"i="<<i<<" angle="<<secAngleTurbo[i]<<" x0,y0{"
725                 <<x0<<","<<y0<<"} x1y1={"<<x1<<","<<y1<<"}"<<endl;
726         } // end if
727     } // end for i
728     sA0 = new TGeoXtru(2);
729     // This shape needs to be access later to mount the SPD sector to.
730     //fSPDsectorShapeName = "ITS SPD Carbon fiber support Sector A0";
731     //sA0->SetName(fSPDsectorShapeName.Data());
732     sA0->SetName("ITS SPD Carbon fiber support Sector A0");
733     sA0->DefinePolygon(m,xpp,ypp);
734     sA0->DefineSection(0,-ksecDz);
735     sA0->DefineSection(1,ksecDz);
736     //
737     //printf("SectorA#%d ",0);
738     InsidePoint(xpp[m-1],ypp[m-1],xpp[0],ypp[0],xpp[1],ypp[1],
739                 ksecCthick,xpp2[0],ypp2[0]);
740     for(i=1;i<m-1;i++){
741         j = i/(ksecNPointsPerRadii+1);
742         //printf("SectorA#%d ",i);
743         InsidePoint(xpp[i-1],ypp[i-1],xpp[i],ypp[i],xpp[i+1],ypp[i+1],
744                     ksecCthick,xpp2[i],ypp2[i]);
745     } // end for i
746     //printf("SectorA#%d ",m);
747     InsidePoint(xpp[m-2],ypp[m-2],xpp[m-1],ypp[m-1],xpp[0],ypp[0],
748                 ksecCthick,xpp2[m-1],ypp2[m-1]);
749     // Fix center value of cooling tube dip.
750     // find location of cooling tube centers
751     for(i=0;i<ksecNCoolingTubeDips;i++){
752         j = ksecDipIndex[i];
753         x0 = xp2[j][1];
754         y0 = yp2[j][1];
755         x1 = xp2[j][ksecNPointsPerRadii-1];
756         y1 = yp2[j][ksecNPointsPerRadii-1];
757         t0 = TMath::Sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
758         t  = secDip2[i]/t0;
759         for(k=2;k<ksecNPointsPerRadii-1;k++){// extra points spread them out.
760             t = ((Double_t)(k-1))*t0;
761             xp2[j][k] = x0+(x1-x0)*t;
762             yp2[j][k] = y0+(y1-y0)*t;
763         } // end for k
764     } // end for i
765     sA1 = new TGeoXtru(2);
766     sA1->SetName("ITS SPD Carbon fiber support Sector Air A1");
767     sA1->DefinePolygon(m,xpp2,ypp2);
768     sA1->DefineSection(0,-ksecDz);
769     sA1->DefineSection(1,ksecDz);
770     //
771     // Error in TGeoEltu. Semi-axis X must be < Semi-axis Y (?).
772     sTA0 = new TGeoEltu("ITS SPD Cooling Tube TA0",
773                       0.5* ksecCoolTubeFlatY, 0.5* ksecCoolTubeFlatX,ksecDz);
774     sTA1 = new TGeoEltu("ITS SPD Cooling Tube coolant TA1",
775                         sTA0->GetA()-ksecCoolTubeThick,
776                         sTA0->GetB()-ksecCoolTubeThick,ksecDz);
777     //
778     SPDsectorShape(ksecNRadii,secX2,secY2,secR2,secAngleStart2,secAngleEnd2,
779                    ksecNPointsPerRadii,m,xp,yp);
780     //
781     sB0 = new TGeoXtru(2);
782     sB0->SetName("ITS SPD Carbon fiber support Sector End B0");
783     sB0->DefinePolygon(m,xpp,ypp);
784     sB0->DefineSection(0,ksecDz);
785     sB0->DefineSection(1,ksecDz+ksecZEndLen);
786     //
787     //printf("SectorB#%d ",0);
788     InsidePoint(xpp[m-1],ypp[m-1],xpp[0],ypp[0],xpp[1],ypp[1],
789                 ksecCthick2,xpp2[0],ypp2[0]);
790     for(i=1;i<m-1;i++){
791         t = ksecCthick2;
792         for(k=0;k<ksecNCoolingTubeDips;k++)
793             if((i/(ksecNPointsPerRadii+1))==ksecDipIndex[k]) 
794                 if(!(ksecDipIndex[k]*(ksecNPointsPerRadii+1)==i || 
795                      ksecDipIndex[k]*(ksecNPointsPerRadii+1)+
796                      ksecNPointsPerRadii==i   )) 
797                     t = ksecRCoolOut-ksecRCoolIn;
798         //printf("SectorB#%d ",i);
799         InsidePoint(xpp[i-1],ypp[i-1],xpp[i],ypp[i],xpp[i+1],ypp[i+1],
800                     t,xpp2[i],ypp2[i]);
801     } // end for
802     //printf("SectorB#%d ",m);
803     InsidePoint(xpp[m-2],ypp[m-2],xpp[m-1],ypp[m-1],xpp[0],ypp[0],
804                 ksecCthick2,xpp2[m-1],ypp2[m-1]);
805     sB1 = new TGeoXtru(2);
806     sB1->SetName("ITS SPD Carbon fiber support Sector Air End B1");
807     sB1->DefinePolygon(m,xpp2,ypp2);
808     sB1->DefineSection(0,ksecDz);
809     sB1->DefineSection(1,ksecDz+ksecLen);
810     sTB0 = new TGeoTube("ITS SPD Cooling Tube End TB0",0.0,
811                        0.5*ksecCoolTubeROuter,0.5*ksecLen);
812     sTB1 = new TGeoTube("ITS SPD Cooling Tube End coolant TB0",0.0,
813                        sTB0->GetRmax()-ksecCoolTubeThick,0.5*ksecLen);
814     //
815     //sM0 = new TGeoTube("ITS SPD Sensitive Virutual Volume M0",0.0,8.0,
816     //                   sA0->GetZ(1)+sB0->GetZ(1));
817     //
818     if(GetDebug(3)){
819         if(medSPDcf) medSPDcf->Dump();
820         else printf("medSPDcf=0\n");
821         if(medSPDss) medSPDss->Dump();
822         else printf("medSPDss=0\n");
823         if(medSPDair) medSPDair->Dump();
824         else printf("medSPDAir=0\n");
825         if(medSPDcoolfl) medSPDcoolfl->Dump();
826         else printf("medSPDcoolfl=0\n");
827         //sM0->InspectShape();
828         sA0->InspectShape();
829         sA1->InspectShape();
830         sB0->InspectShape();
831         sB1->InspectShape();
832     } // end if GetDebug
833     //
834     TGeoVolume *vA0,*vA1,*vTA0,*vTA1,*vB0,*vB1,*vTB0,*vTB1;
835     TGeoVolumeAssembly *vM0;
836     vM0 = new TGeoVolumeAssembly("ITSSPDSensitiveVirtualvolumeM0");
837     //vM0 = new TGeoVolume("ITSSPDSensitiveVirtualvolumeM0",sM0,medSPDair);
838     //vM0->SetVisibility(kTRUE);
839     //vM0->SetLineColor(7); // light Blue
840     //vM0->SetLineWidth(1);
841     //vM0->SetFillColor(vM0->GetLineColor());
842     //vM0->SetFillStyle(4090); // 90% transparent
843     // ALBERTO
844     fSPDsectorShapeName = "ITSSPDCarbonFiberSupportSectorA0";
845     vA0 = new TGeoVolume(fSPDsectorShapeName,sA0,medSPDcf);
846     //vA0 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorA0",sA0,medSPDcf);
847     vA0->SetVisibility(kTRUE);
848     vA0->SetLineColor(4); // Blue
849     vA0->SetLineWidth(1);
850     vA0->SetFillColor(vA0->GetLineColor());
851     vA0->SetFillStyle(4010); // 10% transparent
852     vA1 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorAirA1",sA1,medSPDair);
853     vA1->SetVisibility(kTRUE);
854     vA1->SetLineColor(7); // light Blue
855     vA1->SetLineWidth(1);
856     vA1->SetFillColor(vA1->GetLineColor());
857     vA1->SetFillStyle(4090); // 90% transparent
858     vTA0 = new TGeoVolume("ITSSPDCoolingTubeTA0",sTA0,medSPDss);
859     vTA0->SetVisibility(kTRUE);
860     vTA0->SetLineColor(1); // Black
861     vTA0->SetLineWidth(1);
862     vTA0->SetFillColor(vTA0->GetLineColor());
863     vTA0->SetFillStyle(4000); // 0% transparent
864     vTA1 = new TGeoVolume("ITSSPDCoolingTubeFluidTA1",sTA1,medSPDcoolfl);
865     vTA1->SetVisibility(kTRUE);
866     vTA1->SetLineColor(6); // Purple
867     vTA1->SetLineWidth(1);
868     vTA1->SetFillColor(vTA1->GetLineColor());
869     vTA1->SetFillStyle(4000); // 0% transparent
870     vB0 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorEndB0",sB0,medSPDcf);
871     vB0->SetVisibility(kTRUE);
872     vB0->SetLineColor(4); // Blue
873     vB0->SetLineWidth(1);
874     vB0->SetFillColor(vB0->GetLineColor());
875     vB0->SetFillStyle(4010); // 10% transparent
876     vB1 = new TGeoVolume("ITSSPDCarbonFiberSupportSectorEndAirB1",
877                          sB1,medSPDair);
878     vB1->SetVisibility(kTRUE);
879     vB1->SetLineColor(7); // light Blue
880     vB1->SetLineWidth(1);
881     vB1->SetFillColor(vB1->GetLineColor());
882     vB1->SetFillStyle(4090); // 90% transparent
883     vTB0 = new TGeoVolume("ITSSPDCoolingTubeEndTB0",sTB0,medSPDss);
884     vTB0->SetVisibility(kTRUE);
885     vTB0->SetLineColor(1); // Black
886     vTB0->SetLineWidth(1);
887     vTB0->SetFillColor(vTB0->GetLineColor());
888     vTB0->SetFillStyle(4000); // 0% transparent
889     vTB1 = new TGeoVolume("ITSSPDCoolingTubeEndFluidTB1",sTB1,medSPDcoolfl);
890     vTB1->SetVisibility(kTRUE);
891     vTB1->SetLineColor(6); // Purple
892     vTB1->SetLineWidth(1);
893     vTB1->SetFillColor(vTB1->GetLineColor());
894     vTB1->SetFillStyle(4000); // 0% transparent
895     //
896     StavesInSector(vM0);
897     moth->AddNode(vM0,1,0); // Add virtual volume to mother
898     vA0->AddNode(vA1,1,0); // Put air inside carbon fiber.
899     vB0->AddNode(vB1,1,0); // Put air inside carbon fiber.
900     vTA0->AddNode(vTA1,1,0); // Put air inside carbon fiber.
901     vTB0->AddNode(vTB1,1,0); // Put air inside carbon fiber.
902     for(i=0;i<ksecNCoolingTubeDips;i++){
903         x0 = secX3[ksecDipIndex[i]];
904         y0 = secY3[ksecDipIndex[i]];
905         t = 90.0-secAngleTurbo[i];
906         trans = new TGeoTranslation("",x0,y0,0.5*(sB1->GetZ(0)+sB1->GetZ(1)));
907         vB1->AddNode(vTB0,i+1,trans);
908         rot = new TGeoRotation("",0.0,0.0,t);
909         rotrans = new TGeoCombiTrans("",x0,y0,0.0,rot);
910         vM0->AddNode(vTA0,i+1,rotrans);
911         //delete rot; // rot owned by AliITSv11GeometerySPD::CarbonFiberSector
912     } // end for i
913     vM0->AddNode(vA0,1,0);
914     vM0->AddNode(vB0,1,0);
915     // Reflection.
916     vM0->AddNode(vB0,2,new TGeoRotation("",90.,0.,90.,90.,180.,0.));
917     if(GetDebug(3)){
918         vM0->PrintNodes();
919         vA0->PrintNodes();
920         vA1->PrintNodes();
921         vB0->PrintNodes();
922         vB1->PrintNodes();
923         vTA0->PrintNodes();
924         vTA1->PrintNodes();
925         vTB0->PrintNodes();
926         vTB1->PrintNodes();
927     } // end if GetDebug
928     //
929 }
930 //----------------------------------------------------------------------
931 Bool_t AliITSv11GeometrySPD::GetSectorMountingPoints(Int_t index,
932                              Double_t &x0,Double_t &y0,
933                              Double_t &x1,Double_t &y1,TGeoManager *mgr)const{
934     // Return's the mounting locations needed to mount the SPD ladders 
935     // on the SPD Carbon fiber Sectors (A cross section). Coordinate
936     // system is that of the carbon fiber sector TVolume 
937     // "ITSSPDCarbonFiberSupportSectorA0". Index numbering is as follows
938     //                         /5
939     //                        /\/4
940     //                      1\   \/3
941     //                      0|___\/2
942     // Inputs:
943     //    Int_t index   the index for which location on the SPD sector [0-5]
944     // Outputs:
945     //    Double_t &x0     The x0 location or the ladder sector [cm]
946     //    Double_t &y0     The y0 location of the ladder sector [cm]
947     //    Double_t &x1     The x1 location or the ladder sector [cm]
948     //    Double_t &y1     The y1 location of the ladder sector [cm]
949     //    TGeoManager *mgr The Geometry manager to use [gGeoManager]
950     // Return:
951     //     Returns kTRUE if no problems incountered. Returns kFALSE
952     //     if a problem was incountered (for example the shape has 
953     //     not been found.
954     TGeoVolume *spdSectorV=0;
955     TGeoXtru *spdSector=0;
956     Int_t ixy0,ixy1;
957
958     x0 = x1 = y0 = y1 = 0.0;
959     if(index<0 || index>fSPDsectorPoints0.GetSize()){
960       Error("GetSectorMountingPoints","index=%d size=%d",index,
961             fSPDsectorPoints0.GetSize());
962       return kFALSE;
963     }// end if
964     spdSectorV = mgr->GetVolume(fSPDsectorShapeName.Data());
965     if(spdSectorV==0){
966       Error("GetSectorMountingPoints","spdSectorV==0 name=%s",
967             fSPDsectorShapeName.Data());
968       return kFALSE;
969     } // end if
970     spdSector = dynamic_cast<TGeoXtru*>(spdSectorV->GetShape());
971     if(spdSector==0){
972       Error("GetSectorMountingPoints","spdSector==0");
973       return kFALSE;
974     } // end if
975     ixy0 = fSPDsectorPoints0.At(index);
976     ixy1 = fSPDsectorPoints1.At(index);
977     x0 = spdSector->GetX(ixy0);
978     y0 = spdSector->GetY(ixy0);
979     x1 = spdSector->GetX(ixy1);
980     y1 = spdSector->GetY(ixy1);
981     return kTRUE;
982 }
983 //----------------------------------------------------------------------
984 void AliITSv11GeometrySPD::SPDsectorShape(Int_t n,const Double_t *xc,
985 const Double_t *yc,const Double_t *r,const Double_t *ths,const Double_t *the,
986                                Int_t npr,Int_t &m,Double_t **xp,Double_t **yp){
987     // Code to compute the points that make up the shape of the SPD
988     // Carbon fiber support sections
989     // Inputs:
990     //    Int_t    n       Size of arrays xc,yc, and r.
991     //    Double_t *xc     Array of x values for radii centers.
992     //    Double_t *yc     Array of y values for radii centers.
993     //    Double_t *r      Array of signed radii values.
994     //    Double_t *ths    Array of starting angles [degrees].
995     //    Double_t *the    Array of ending angles [degrees].
996     //    Int_t    npr     The number of lines segments to aproximate the arc.
997     // Outputs:
998     //    Int_t    m       The number of enetries in the arrays *xp[npr+1] 
999     //                     and *yp[npr+1].
1000     //    Double_t **xp    Array of x coordinate values of the line segments
1001     //                     which make up the SPD support sector shape.
1002     //    Double_t **yp    Array of y coordinate values of the line segments
1003     //                     which make up the SPD support sector shape.
1004     // Return:
1005     //    none.
1006     Int_t i,k;
1007     Double_t t,t0,t1;
1008
1009     m = n*(npr+1);
1010     if(GetDebug(2)){
1011         cout <<"    X    \t  Y  \t  R  \t  S  \t  E"<< m <<endl;
1012         for(i=0;i<n;i++){
1013             cout <<"{"<< xc[i] <<",";
1014             cout << yc[i] <<",";
1015             cout << r[i] <<",";
1016             cout << ths[i] <<",";
1017             cout << the[i] <<"},"<< endl;
1018         } // end for i
1019     } // end if GetDebug
1020     //
1021     if(GetDebug(3)) cout <<"Double_t sA0 = ["<< n*(npr+1)+1<<"][";
1022     if(GetDebug(4)) cout <<"3]{";
1023     else if(GetDebug(3)) cout <<"2]{";
1024     t0 = (Double_t)npr;
1025     for(i=0;i<n;i++){
1026         t1 = (the[i]-ths[i])/t0;
1027         if(GetDebug(5)) cout<<"t1="<< t1<<endl;
1028         for(k=0;k<=npr;k++){
1029             t=ths[i]+((Double_t)k)*t1;
1030             xp[i][k] = TMath::Abs(r[i])*CosD(t)+xc[i];
1031             yp[i][k] = TMath::Abs(r[i])*SinD(t)+yc[i];
1032             if(GetDebug(3)){
1033                 cout << "{"<<xp[i][k]<<","<<yp[i][k];
1034                 if(GetDebug(4)) cout <<","<<t;
1035                 cout <<"},";
1036             } // end if GetDebug
1037         } // end for k
1038         if(GetDebug(3)) cout << endl;
1039     } // end of i
1040     if(GetDebug(3)) cout<<"{"<<xp[0][0]<<","<<yp[0][0];
1041     if(GetDebug(4)) cout<<","<< ths[0];
1042     if(GetDebug(3)) cout<<"}}"<<endl;
1043     //
1044     return;
1045 }
1046 //----------------------------------------------------------------------
1047 void AliITSv11GeometrySPD::CreateFigure0(const Char_t *filepath,
1048                                          const Char_t *type,
1049                                          TGeoManager *mgr){
1050     // Creates Figure 0 for the documentation of this class. In this
1051     // specific case, it creates the X,Y cross section of the SPD suport
1052     // section, center and ends. The output is written to a standard
1053     // file name to the path specificed.
1054     // Inputs:
1055     //   const Char_t *filepath  Path where the figure is to be drawn
1056     //   const Char_t *type      The type of file, default is gif.
1057     //   TGeoManager  *mgr       The TGeoManager default gGeoManager
1058     // Output:
1059     //   none.
1060     // Return:
1061     //   none.
1062     TGeoXtru *sA0,*sA1,*sB0,*sB1;
1063     //TPolyMarker *pmA,*pmB;
1064     TPolyLine plA0,plA1,plB0,plB1;
1065     TCanvas *canvas;
1066     TLatex txt;
1067     Double_t x=0.0,y=0.0;
1068     Int_t i,kNRadii=6;
1069
1070     if(strcmp(filepath,"")){
1071         Error("CreateFigure0","filepath=%s type=%s",filepath,type);
1072     } // end if
1073     //
1074     sA0 = (TGeoXtru*) mgr->GetVolume(
1075         "ITSSPDCarbonFiberSupportSectorA0_1")->GetShape();
1076     sA1 = (TGeoXtru*) mgr->GetVolume(
1077         "ITSSPDCarbonFiberSupportSectorAirA1_1")->GetShape();
1078     sB0 = (TGeoXtru*) mgr->GetVolume(
1079         "ITSSPDCarbonFiberSupportSectorEndB0_1")->GetShape();
1080     sB1 = (TGeoXtru*) mgr->GetVolume(
1081         "ITSSPDCarbonFiberSupportSectorEndAirB1_1")->GetShape();
1082     //pmA = new TPolyMarker();
1083     //pmA.SetMarkerStyle(2); // +
1084     //pmA.SetMarkerColor(7); // light blue
1085     //pmB = new TPolyMarker();
1086     //pmB.SetMarkerStyle(5); // X
1087     //pmB.SetMarkerColor(6); // purple
1088     plA0.SetPolyLine(sA0->GetNvert());
1089     plA0.SetLineColor(1); // black
1090     plA0.SetLineStyle(1);
1091     plA1.SetPolyLine(sA1->GetNvert());
1092     plA1.SetLineColor(2); // red
1093     plA1.SetLineStyle(1);
1094     plB0.SetPolyLine(sB0->GetNvert());
1095     plB0.SetLineColor(3); // Green
1096     plB0.SetLineStyle(2);
1097     plB1.SetPolyLine(sB1->GetNvert());
1098     plB1.SetLineColor(4); // Blue
1099     plB1.SetLineStyle(2);
1100     //for(i=0;i<kNRadii;i++) pmA.SetPoint(i,xyB1p[i][0],xyB1p[i][1]);
1101     //for(i=0;i<kNRadii;i++) pmB.SetPoint(i,xyB1p[i][0],xyB1p[i][1]);
1102     for(i=0;i<sA0->GetNvert();i++) plA0.SetPoint(i,sA0->GetX(i),sA0->GetY(i));
1103     for(i=0;i<sA1->GetNvert();i++) plA1.SetPoint(i,sA1->GetX(i),sA1->GetY(i));
1104     for(i=0;i<sB0->GetNvert();i++) plB0.SetPoint(i,sB0->GetX(i),sB0->GetY(i));
1105     for(i=0;i<sB1->GetNvert();i++) plB1.SetPoint(i,sB1->GetX(i),sB1->GetY(i));
1106     canvas = new TCanvas("AliITSv11GeometrySPDFig0","",1000,1000);
1107     canvas->Range(-3.,-3.,3.,3.);
1108     txt.SetTextSize(0.05);
1109     txt.SetTextAlign(33);
1110     txt.SetTextColor(1);
1111     txt.DrawLatex(2.9,2.9,"Section A-A outer Carbon Fiber surface");
1112     txt.SetTextColor(2);
1113     txt.DrawLatex(2.9,2.5,"Section A-A Inner Carbon Fiber surface");
1114     txt.SetTextColor(3);
1115     txt.DrawLatex(2.9,2.1,"Section E-E outer Carbon Fiber surface");
1116     txt.SetTextColor(4);
1117     txt.DrawLatex(2.9,1.7,"Section E-E Inner Carbon Fiber surface");
1118     plA0.Draw();
1119     plA1.Draw();
1120     plB0.Draw();
1121     plB1.Draw();
1122     //pmA.Draw();
1123     //pmB.Draw();
1124     //
1125     x = 1.0;
1126     y = -2.5;
1127     Char_t chr[3];
1128     for(i=0;i<kNRadii;i++){
1129         sprintf(chr,"%2d",i);txt.DrawLatex(x-0.1,y,chr);
1130         sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x,y,chr);
1131         sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x+0.5,y,chr);
1132         sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x+1.0,y,chr);
1133         sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x+1.5,y,chr);
1134         sprintf(chr,"%8.4f",5.000);txt.DrawLatex(x+2.0,y,chr);
1135         if(kTRUE) txt.DrawLatex(x+2.5,y,"A-A/E-E");
1136         else txt.DrawLatex(x+2.5,y,"E-E");
1137     } // end for i
1138     txt.DrawLatex(x,y,"x_{c} mm");
1139     txt.DrawLatex(x+0.5,y,"y_{c} mm");
1140     txt.DrawLatex(x+1.0,y,"R mm");
1141     txt.DrawLatex(x+1.5,y,"#theta_{start}^{#circle}");
1142     txt.DrawLatex(x+2.0,y,"#theta_{end}^{#circle}");
1143     txt.DrawLatex(x+2.5,y,"Section");
1144     //
1145 }
1146
1147 //______________________________________________________________________
1148 TGeoVolume* AliITSv11GeometrySPD::CreateLadder(Int_t layer,Double_t &length,
1149                      Double_t &width,Double_t &thickness, TGeoManager *mgr){
1150         // Creates the "ladder" = silicon sensor + 5 chips.
1151         // All parts are implemented as TGeoBBox and inserted 
1152         // into a container which is the return value of this method.
1153         // The sizes of the components come from drawings 
1154         // of the Technical office of INFN Padova.
1155         // Due to the requirement to specify the sensitive volume 
1156         // separately from the rest, the sensor is implemented as the 
1157         // sum of a central sensitive part + a guard ring.
1158         // Also the bump-bondings are added in form of small cylinders.
1159         // ---
1160         // Arguments:
1161         //  - the layer which will own this ladder (MUST be 1 or 2)
1162         //  - the used TGeoManager
1163         // ---
1164         // Returns:
1165         //  - the container TGeoBBox (return value)
1166         //  - the size of the container box (arguments passed by reference)
1167         // ---
1168         // NOTE 1
1169         // Here and in the other methods which contribute to the stave 
1170         // definition a convention is used for the naming of the three 
1171         // dimensions of the volumes:
1172         //  - 'length'    refers to the size in the Z direction of the 
1173         //                ALICE reference frame
1174         //  - 'width'     refers to the "large" dimension orthogonal to 
1175         //                Z axis in the local reference frame of the 
1176         //                object being implemented (e.g., 15.95 mm for 
1177         //                the chips)
1178         //  - 'thickness' refers to the "small" dimension orthogonal to 
1179         //                Z axis, which is also the direction along which 
1180         //                the components are superimposed on each other
1181         // ---
1182         // NOTE 2
1183         // all sizes taken are expressed in mm in drawings, and this is 
1184         // kept as is, to avoid confusion the conversion is made 
1185         // multiplying by the conversion factor
1186         
1187         // ** CRITICAL CHECK **
1188         // layer number can be ONLY 1 or 2
1189         if (layer != 1 && layer != 2) AliFatal("Layer number MUST be 1 or 2");
1190         
1191         // instantiate all required media
1192         TGeoMedium *medAir       = mgr->GetMedium("Air");
1193         TGeoMedium *medSPDSiChip = mgr->GetMedium("SPD SI CHIP");
1194         TGeoMedium *medSi        = mgr->GetMedium("Si");
1195         TGeoMedium *medBumpBond  = mgr->GetMedium("BumpBond");
1196         
1197         // ** Define sizes **
1198         // they are expressed in mm in the drawings so they require conversion
1199         // 'length'    is in the direction of the detector length (Z axis)
1200         // 'thickness' is obvious
1201         // 'width'     is in the direction orthogonal to 'width' and 'thickness'
1202
1203         // for the chip, also the spacing between them is required
1204         Double_t chipThickness  = fgkmm *  0.150;
1205         Double_t chipWidth      = fgkmm * 15.950;
1206         Double_t chipLength     = fgkmm * 13.600;
1207         Double_t chipSpacing    = fgkmm *  0.400;
1208         
1209         // for the sensor, we define the area of sensitive volume
1210         // while the guard ring is added as a separate piece
1211         Double_t sensThickness  = fgkmm *  0.200;
1212         Double_t sensLength     = fgkmm * 69.600;
1213         Double_t sensWidth      = fgkmm * 13.920;
1214         Double_t guardRingWidth = fgkmm *  0.560;
1215         
1216         // bump bond is defined as a small stripe of height = 0.012 mm
1217         // and a suitable width to keep the same volume it has 
1218         // before being compressed (a line of spheres of 0.025 mm radius)
1219         Double_t bbLength    = fgkmm * 0.042;
1220         Double_t bbWidth     = sensWidth;
1221         Double_t bbThickness = fgkmm * 0.012;
1222         Double_t bbPos       = 0.080;   // Z position w.r. to left pixel edge
1223                 
1224         // ** Create volumes **
1225         // the container is the return value, and is built as a box
1226         // whose edges exactly enclose the stuff we inserted here, 
1227         // filled with air. Its name depends on the layer number.
1228         width = chipWidth;
1229         length = sensLength + 2.0*guardRingWidth;
1230         thickness = sensThickness + chipThickness + bbThickness;
1231         TGeoVolume *container = mgr->MakeBox(Form("LAY%d_LADDER", layer),
1232                                medAir, 0.5*thickness, 0.5*width, 0.5*length);
1233         // the chip is a simple box:
1234         TGeoVolume *volChip = mgr->MakeBox("CHIP", medSPDSiChip,
1235                            0.5*chipThickness, 0.5*chipWidth, 0.5*chipLength);
1236         
1237         // the sensor is the union of a box and a border, to separate 
1238         // sensitive part from the rest the sensitive volume (inner part) 
1239         // is named according to the owner layer. To compute the shape 
1240         // subtraction which is needed for this we create two shapes,
1241         // which are two boxes with the same center. The smaller one is 
1242         // then used to define the sensor, while the subtraction of the two
1243         // is used for the guard ring.
1244         TGeoBBox  *shSens = new TGeoBBox(0.5*sensThickness, 0.5*sensWidth, 
1245                                          0.5*sensLength);
1246         TGeoBBox  *shIn   = new TGeoBBox(sensThickness, 0.5*sensWidth, 
1247                                          0.5*sensLength);
1248         TGeoBBox  *shOut  = new TGeoBBox(0.5*sensThickness, 
1249                                          0.5*sensWidth + guardRingWidth, 
1250                                          0.5*sensLength + guardRingWidth);
1251         shIn->SetName("innerBox");
1252         shOut->SetName("outerBox");
1253         TGeoCompositeShape *shBorder = new TGeoCompositeShape("",
1254                                                          "outerBox-innerBox");
1255         TGeoVolume *volSens = new TGeoVolume(Form("LAY%d_SENSOR", layer),
1256                                              shSens, medSi);
1257         TGeoVolume *volBorder = new TGeoVolume("GUARD_RING", shBorder, medSi);
1258
1259         // one line of bumpbonds
1260         TGeoVolume *volBB = mgr->MakeBox("BB", medBumpBond, 0.5*bbThickness,
1261                                          0.5*bbWidth, 0.5*bbLength);
1262                 
1263         // set colors of all objects for visualization  
1264         volSens->SetLineColor(kYellow + 1);
1265         volChip->SetLineColor(kGreen);
1266         volBorder->SetLineColor(kYellow + 3);
1267
1268         // translations for the chip box: direction of length and 
1269         // thickness (moved down)
1270         TGeoTranslation *trChip[5] = {0, 0, 0, 0, 0};
1271         Double_t x = 0.5 * (chipThickness - thickness);
1272         Double_t y = 0.0;
1273         Double_t z = 0.0;
1274         Int_t i;
1275         for (i = 0; i < 5; i++) {
1276                 z = -0.5*length + guardRingWidth + (Double_t)i*chipSpacing + 
1277                   ((Double_t)(i) + 0.5)*chipLength;
1278                 trChip[i] = new TGeoTranslation(x, y, z);
1279         } // end for i
1280         
1281         // translation for the sensor parts: direction of width (moved 
1282         // to edge of container) and thickness (moved up)
1283         x = 0.5 * (thickness - sensThickness);
1284         y = 0.5 * (width - sensWidth - 2.0*guardRingWidth);
1285         z = 0.0;
1286         TGeoTranslation *trSens = new TGeoTranslation(x, y, z);
1287         
1288         // translation for the bump bonds:
1289         // keep same y used for sensors, but change the Z
1290         TGeoTranslation *trBB[160];
1291         //x = 0.5 * (thickness - bbThickness) + 0.5*sensThickness;
1292         x = 0.5 * (thickness - bbThickness) - sensThickness;
1293         z = -0.5 * sensLength + guardRingWidth + fgkmm*0.425 - bbPos;
1294         for (i = 0; i < 160; i++) {
1295                 trBB[i] = new TGeoTranslation(x, y, z);
1296                 switch(i) {
1297                         case  31:
1298                         case  63:
1299                         case  95:
1300                         case 127:
1301                                 z += fgkmm * 0.625 + fgkmm * 0.2;
1302                                 break;
1303                         default:
1304                                 z += fgkmm * 0.425;
1305                 } // end switch
1306         } // end for i
1307                 
1308         // add nodes to container
1309         container->AddNode(volSens, 1, trSens);
1310         container->AddNode(volBorder, 1, trSens);
1311         for (i = 0; i < 160; i++) container->AddNode(volBB, i, trBB[i]);
1312         for (i = 0; i < 5; i++){
1313             container->AddNode(volChip, i + 2, trChip[i]);
1314         } // end for i
1315         
1316         // return the container
1317         return container;
1318 }
1319 /*
1320 //______________________________________________________________________
1321 TGeoVolume* AliITSv11GeometrySPD::CreateGroundingFoilSingle(Bool_t kaptonLayer,
1322     Double_t &length, Double_t &width, Double_t &thickness, TGeoManager *mgr){
1323         //
1324         // Creates the grounding foil layer made in Kapton.
1325         // Both layers of the grounding foil have the same shape, but 
1326         // with small differences in the size of some parts (holes, 
1327         // overall size). The Kapton layer is a little bit wider and 
1328         // has smaller holes.
1329         // ---
1330         // The complete object is created as the superimposition of 
1331         // an XTRU with some holes
1332         // ---
1333         // Whenever possible, the size of the parts is parameterized with 
1334         // variable names, even if their value is fixed according 
1335         // to the design parameters given by engineers' drawings.
1336         // ---
1337         // Returns: a TGeoVolume object which contains all parts of this layer
1338         //
1339         
1340         // The shape of the grounding foil is an irregular polygon, which 
1341         // can easily be implemented as a TGeoXtru using the corners as 
1342         // reference points:
1343         // 
1344         // 0                                                                             1
1345         //  +-----------------------------------------------------------------------------+
1346         //  |                                    7              6      3                |
1347         //  |                                     +--------------+      +----------------+ 2
1348         //  |                         O           |              |      |
1349         //  |                             9 /-----+ 8            +------+ 4
1350         //  |                              /                    5
1351         //  |           11 /--------------/ 10
1352         //  +-------------/ 
1353         // 13           12
1354         //
1355         // in total: 14 points (X is just a referencem but is unused in 
1356         // the implementation. The whole shape can be subdivided into 
1357         // sectors delimited by vertical lines passing througth the 
1358         // points in the lower part of the shape. This convention is 
1359         // used to names their length which is different for each one 
1360         // (the widths, instead, are common for some)   
1361         // instantiate the media:
1362         // - kapton/aluminum for the pysical volumes
1363         TGeoMedium *material = kaptonLayer ? mgr->GetMedium("KAPTON") : 
1364                                                      mgr->GetMedium("AL");
1365         
1366         // label
1367         char type[3];
1368         if (kaptonLayer) {
1369                 strcpy(type, "KP"); 
1370                 thickness = fgkmm * 0.05;
1371         }
1372         else {
1373                 strcpy(type, "AL");
1374                 thickness = fgkmm * 0.02;
1375         }
1376         
1377         // define the length of all sectors (from leftmost to rightmost)
1378         Int_t i;
1379         Double_t sectorLength[] = {140.71,2.48,26.78,4.0,10.0,24.4,10.0,24.81};
1380         if (!kaptonLayer) {
1381                 sectorLength[0] -= 0.2;
1382                 sectorLength[4] -= 0.2;
1383                 sectorLength[5] += 0.4;
1384                 sectorLength[6] -= 0.4;
1385         }
1386         length = 0.0;
1387         for (i = 0; i < 8; i++) {
1388                 sectorLength[i] *= fgkmm;
1389                 length += sectorLength[i];
1390         }
1391                 
1392         // as shown in the drawing, we have three different widths in 
1393         // this shape:
1394         Double_t widthMax  = fgkmm * 15.95;
1395         Double_t widthMed1 = fgkmm * 15.00;
1396         Double_t widthMed2 = fgkmm * 11.00;
1397         Double_t widthMin  = fgkmm *  4.40;
1398         if (!kaptonLayer) {
1399                 widthMax  -= fgkmm * 0.4;
1400                 widthMed1 -= fgkmm * 0.4;
1401                 widthMed2 -= fgkmm * 0.4;
1402                 widthMin  -= fgkmm * 0.4;
1403         }
1404         width = widthMax;
1405         
1406         // the vertices of the polygon are arrays correctly ordered in 
1407         // the counterclockwise direction: initially we place the point 
1408         // 0 in the origin, and all others will be defined accordingly
1409         Double_t x[14], y[14];
1410         x[ 0] = 0.0;
1411         y[ 0] = 0.0;
1412         
1413         x[ 1] = x[0] + length;
1414         y[ 1] = 0.0;
1415         
1416         x[ 2] = x[1];
1417         y[ 2] = -widthMin;
1418         
1419         x[ 3] = x[2] - sectorLength[7];
1420         y[ 3] = y[2];
1421         
1422         x[ 4] = x[3];
1423         y[ 4] = -widthMed2;
1424         
1425         x[ 5] = x[4] - sectorLength[6];
1426         y[ 5] = y[4];
1427         
1428         x[ 6] = x[5];
1429         y[ 6] = -widthMin;
1430         
1431         x[ 7] = x[6] - sectorLength[5];
1432         y[ 7] = y[6];
1433         
1434         x[ 8] = x[7];
1435         y[ 8] = -widthMed2;
1436         
1437         x[ 9] = x[8] - sectorLength[4];
1438         y[ 9] = y[8];
1439         
1440         x[10] = x[9] - sectorLength[3];
1441         y[10] = -widthMed1;
1442          
1443         x[11] = x[10] - sectorLength[2];
1444         y[11] = y[10];
1445         
1446         x[12] = x[11] - sectorLength[1];
1447         y[12] = -widthMax;
1448         
1449         x[13] = x[0];
1450         y[13] = -widthMax;
1451         
1452         // then, we shift all points in such a way that the origin will 
1453         // be at the centers
1454         for (i = 0; i < 14; i++) {
1455                 x[i] -= 0.5*length;
1456                 y[i] += 0.5*width;
1457         }
1458         
1459         // create the shape
1460         char shName[200];
1461         sprintf(shName, "SH_%sGFOIL_FULL", type);
1462         TGeoXtru *shGroundFull = new TGeoXtru(2);
1463         shGroundFull->SetName(shName);
1464         shGroundFull->DefinePolygon(14, x, y);
1465         shGroundFull->DefineSection(0, -0.5*thickness, 0., 0., 1.0);
1466         shGroundFull->DefineSection(1,  0.5*thickness, 0., 0., 1.0);
1467         
1468         // this volume contains some holes which are here implemented 
1469         // as simple boxes of fixed size, which are displaced along the 
1470         // shape itself and then composed using the facilities of the 
1471         // TGeo package
1472
1473         Double_t holeLength = fgkmm * 10.00;
1474         Double_t holeWidth  = fgkmm *  7.50;
1475         Double_t holeSepX0  = fgkmm *  7.05;//separation between center 
1476                                             //of first hole and left border
1477         Double_t holeSepXC  = fgkmm * 14.00;//separation between the 
1478                                             // centers of two consecutive holes
1479         Double_t holeSepX1  = fgkmm * 15.42;//separation between centers 
1480                                             // of 5th and 6th hole
1481         Double_t holeSepX2  = fgkmm * 22.00;//separation between centers 
1482                                             // of 10th and 11th hole
1483         if (!kaptonLayer) {
1484                 holeSepX0  -= fgkmm * 0.2;
1485                 holeLength += fgkmm * 0.4;
1486                 holeWidth  += fgkmm * 0.4;
1487         }
1488         
1489         // X position of hole center (will change for each hole)
1490         Double_t holeX = -0.5*length;
1491         // Y position of center of all holes (= 4.4 mm from upper border)
1492         Double_t holeY = 0.5*(width - holeWidth) - widthMin;
1493         //if (!kaptonLayer) holeY += 0.02;
1494                 
1495         // create a shape for the holes (common)
1496         char holeName[200];
1497         sprintf(holeName, "%sHOLE", type);
1498         TGeoBBox *shHole = 0;
1499         shHole = new TGeoBBox(holeName,0.5*holeLength,0.5*holeWidth,thickness);
1500         
1501         // insert the holes in the XTRU shape:
1502         // starting from the first value of X, they are simply shifted 
1503         // along this axis
1504         char trName[200];
1505         TGeoTranslation *transHole[11];
1506         TString strComposite(shName);
1507         strComposite.Append("-(");
1508         for (Int_t i = 0; i < 11; i++) {
1509                 // set the position of the hole, depending on index
1510                 if (i == 0) {
1511                         holeX += holeSepX0;
1512                 }
1513                 else if (i < 4) {
1514                         holeX += holeSepXC;
1515                 }
1516                 else if (i == 4) {
1517                         holeX += holeSepX1;
1518                 }
1519                 else if (i < 10) {
1520                         holeX += holeSepXC;
1521                 }
1522                 else {
1523                         holeX += holeSepX2;
1524                 }
1525                 sprintf(trName, "%sTR%d", type, i);
1526                 transHole[i] = new TGeoTranslation(trName, holeX, holeY, 0.0);
1527                 transHole[i]->RegisterYourself();
1528                 strComposite.Append(holeName);
1529                 strComposite.Append(":");
1530                 strComposite.Append(trName);
1531                 if (i < 10) strComposite.Append("+");
1532                 //MM            cout << holeX << endl;
1533         }
1534         strComposite.Append(")");
1535         //MM    cout << strComposite.Data() << endl;
1536         
1537         // create composite shape (with holes)
1538         TGeoCompositeShape *shGround = new TGeoCompositeShape(
1539                                  Form("SH_%sGFOIL", type), strComposite.Data());
1540         
1541         // create the volume
1542         TGeoVolume *vol = new TGeoVolume(Form("%sGFOIL",type),shGround,
1543                                                                material);
1544         return vol;
1545 }
1546 */
1547 //______________________________________________________________________
1548 TGeoVolume* AliITSv11GeometrySPD::CreateGroundingFoilSingle(
1549       Bool_t kaptonLayer, Double_t &length, Double_t &width, 
1550       Double_t &thickness, TGeoManager *mgr){
1551         // Creates the grounding foil layer made in Kapton.
1552         // Both layers of the grounding foil have the same shape, but with small
1553         // differences in the size of some parts (holes, overall size).
1554         // The Kapton layer is a little bit wider and has smaller holes.
1555         // ---
1556         // The complete object is created as the sum of the following parts:
1557         // 1) the part which is connected to the chips, which is a 
1558         //    simple BOX with some box-shaped holes at regular intervals
1559         // 2) a trapezoidal connection where the Y size changes
1560         // 3) another box with a unique hole of the same shape and size as above
1561         // 4) another trapezoidal connection where the Y size changes
1562         // 5) a final part which is built as a sequence of 4 BOX volumes
1563         //    where the first and the third are equal and the others have 
1564         //    same size in Y.
1565         // ---
1566         // Whenever possible, the size of the parts is parameterized with 
1567         // variable names, even if their value is fixed according 
1568         // to the design parameters given by engineers' drawings.
1569         // ---
1570         // Returns: a TGeoVolume object which contanis all parts of this layer
1571         //
1572
1573         // instantiate the media:
1574         // - vacuum for the container volume
1575         // - kapton for the pysical volumes
1576         TGeoMedium *vacuum   = mgr->GetMedium("VACUUM");
1577         TGeoMedium *material = mgr->GetMedium("KAPTON");
1578         
1579         // === Define size of all elements ===
1580         Double_t sizeZ      = fgkmm *   0.05;
1581         
1582         Double_t part1X     = fgkmm * 140.71;
1583         Double_t part2X     = fgkmm *   2.48;
1584         Double_t part3X     = fgkmm *  26.78;
1585         Double_t part4X     = fgkmm *   4.00;
1586         Double_t part5X     = fgkmm *  10.00;
1587         Double_t part6X     = fgkmm *  24.40;
1588         Double_t part7X     = fgkmm *  10.00;
1589         Double_t part8X     = fgkmm *  24.81;
1590         
1591         Double_t sizeYMax   = fgkmm *  15.95;
1592         Double_t sizeYMed1  = fgkmm *  15.00;
1593         Double_t sizeYMed2  = fgkmm *  11.00;
1594         Double_t sizeYMin   = fgkmm *   4.40;
1595         
1596         Double_t holeX      = fgkmm *  10.00;
1597         Double_t holeY      = fgkmm *   7.50;
1598         Double_t holeSepX   = fgkmm *  14.00;  // separation between the 
1599                                                // centers of two consecutive 
1600                                                // holes
1601         Double_t holeSepX1  = fgkmm *   1.42;  // to be added after 4th hole 
1602                                                // in volume 1
1603         Double_t holeFirstX = fgkmm *   7.05;  // position of center of first 
1604                                                // hole
1605         Double_t holeSepY   = fgkmm *   4.40;  // dist between hole's and 
1606                                                // volume's upper border
1607         Double_t holeAloneX = fgkmm *  13.28;  // position of hole center 
1608                                                // in box "part 3"
1609
1610         // correct data in case we are on Aluminum foil
1611         if (!kaptonLayer) {
1612                 material = mgr->GetMedium("AL");
1613                 sizeZ       = fgkmm * 0.02;
1614                 part1X     -= fgkmm * 0.2;
1615                 part5X     -= fgkmm * 0.2;
1616                 part6X     += fgkmm * 0.4;
1617                 part7X     -= fgkmm * 0.4;
1618                         
1619                 sizeYMax   -= fgkmm * 0.4;
1620                 sizeYMed1  -= fgkmm * 0.4;
1621                 sizeYMed2  -= fgkmm * 0.4;
1622                 sizeYMin   -= fgkmm * 0.4;
1623         
1624                 holeX      += fgkmm * 0.4;
1625                 holeY      += fgkmm * 0.4;
1626                 holeFirstX -= fgkmm * 0.2;
1627                 holeSepY   -= fgkmm * 0.4;
1628         }
1629         
1630         // define names for the object
1631         char type[4];
1632         if (kaptonLayer) strcpy(type, "KAP"); else strcpy(type, "ALU");
1633         
1634         // compute full length and width
1635         length = part1X + part2X + part3X + part4X + part5X + part6X + 
1636                  part7X + part8X;
1637         width = sizeYMax;
1638         thickness = sizeZ;
1639                 
1640         // grounding foil world, bounded exactly around the limits 
1641         // of the structure
1642         TGeoVolume *container = mgr->MakeBox(Form("GFOIL_%s", type), 
1643                               vacuum, 0.5*length, 0.5*sizeYMax, 0.5*sizeZ);
1644
1645         // === PART 1: box with holes ===
1646
1647         TGeoBBox *shBox1 = 0, *shHole = 0;
1648         shBox1 = new TGeoBBox(Form("GF%s_BOX1", type), 0.5*part1X, 
1649                               0.5*sizeYMax, 0.5*sizeZ);
1650         shHole = new TGeoBBox(Form("GF%s_HOLE", type), 0.5*holeX, 0.5*holeY, 
1651                               0.5*sizeZ + 0.01);
1652
1653         // define the position of all holes and compose the expression
1654         // to define the composite shape (box - holes)
1655         Double_t firstX = -0.5*part1X + holeFirstX;
1656         Double_t transY =  0.5*sizeYMax - holeSepY - 0.5*holeY;
1657         Double_t transX;
1658         TGeoTranslation *transHole[10];
1659         TString strComposite(Form("%s - (", shBox1->GetName()));
1660         for (Int_t i = 0; i < 10; i++) {
1661                 transX = firstX + (Double_t)i * holeSepX;
1662                 if (i > 4) transX += holeSepX1;
1663                 transHole[i] = new TGeoTranslation(Form("TGF%s_HOLE%d",type,i),
1664                                                    transX, transY, 0.0);
1665                 transHole[i]->RegisterYourself();
1666                 strComposite.Append(Form("%s:%s", shHole->GetName(),
1667                                          transHole[i]->GetName()));
1668                 if (i < 9) strComposite.Append("+"); 
1669                 else strComposite.Append(")");
1670         } // end for i
1671         // create composite shape
1672         TGeoCompositeShape *shPart1 = new TGeoCompositeShape(
1673                           Form("GF%s_PART1_SHAPE", type), strComposite.Data());
1674         // create the volume
1675         TGeoVolume *volPart1 = new TGeoVolume(Form("GF%s_PART1", type),
1676                                               shPart1, material);
1677
1678         // === PART 2: first trapezoidal connection
1679         
1680         TGeoArb8 *shTrap1 = new TGeoArb8(0.5*sizeZ);
1681         shTrap1->SetVertex(0, -0.5*part2X,  0.5*sizeYMax);
1682         shTrap1->SetVertex(1,  0.5*part2X,  0.5*sizeYMax);
1683         shTrap1->SetVertex(2,  0.5*part2X,  0.5*sizeYMax - sizeYMed1);
1684         shTrap1->SetVertex(3, -0.5*part2X, -0.5*sizeYMax);
1685         shTrap1->SetVertex(4, -0.5*part2X,  0.5*sizeYMax);
1686         shTrap1->SetVertex(5,  0.5*part2X,  0.5*sizeYMax);
1687         shTrap1->SetVertex(6,  0.5*part2X,  0.5*sizeYMax - sizeYMed1);
1688         shTrap1->SetVertex(7, -0.5*part2X, -0.5*sizeYMax);
1689         TGeoVolume *volPart2 = new TGeoVolume(Form("GF%s_PART2", type),
1690                                               shTrap1, material);
1691         
1692         // === PART 3: other box with one hole
1693         
1694         TGeoBBox *shBox2 = 0;
1695         shBox2 = new TGeoBBox(Form("GF%s_BOX2", type), 0.5*part3X,
1696                               0.5*sizeYMed1, 0.5*sizeZ);
1697                 
1698         // define the position of the hole
1699         transX = holeAloneX - 0.5*part3X;
1700         TGeoTranslation *transHoleAlone = new TGeoTranslation(
1701                         Form("TGF%s_HOLE_ALONE", type), transX, transY, 0.0);
1702         transHoleAlone->RegisterYourself();
1703         // create composite shape
1704         TGeoCompositeShape *shPart3 = new TGeoCompositeShape(
1705                         Form("GF%sPART3_SHAPE", type),
1706                         Form("%s - %s:%s", shBox2->GetName(),
1707                              shHole->GetName(), transHoleAlone->GetName()));
1708         // create the volume
1709         TGeoVolume *volPart3 = new TGeoVolume(Form("GF%s_PART3", type),
1710                                               shPart3, material);
1711                 
1712         // === PART 4: second trapezoidal connection
1713         
1714         TGeoArb8 *shTrap2 = new TGeoArb8(0.5*sizeZ);
1715         shTrap2->SetVertex(0, -0.5*part4X,  0.5*sizeYMed1);
1716         shTrap2->SetVertex(1,  0.5*part4X,  0.5*sizeYMed1);
1717         shTrap2->SetVertex(2,  0.5*part4X,  0.5*sizeYMed1 - sizeYMed2);
1718         shTrap2->SetVertex(3, -0.5*part4X, -0.5*sizeYMed1);
1719         shTrap2->SetVertex(4, -0.5*part4X,  0.5*sizeYMed1);
1720         shTrap2->SetVertex(5,  0.5*part4X,  0.5*sizeYMed1);
1721         shTrap2->SetVertex(6,  0.5*part4X,  0.5*sizeYMed1 - sizeYMed2);
1722         shTrap2->SetVertex(7, -0.5*part4X, -0.5*sizeYMed1);
1723         TGeoVolume *volPart4 = new TGeoVolume(Form("GF%s_PART4", type),
1724                                               shTrap2, material);
1725                 
1726         // === PART 5 --> 8: sequence of boxes ===
1727         
1728         TGeoVolume *volPart5 = mgr->MakeBox(Form("GF%s_BOX3", type),
1729                              material, 0.5*part5X, 0.5*sizeYMed2, 0.5*sizeZ);
1730         TGeoVolume *volPart6 = mgr->MakeBox(Form("GF%s_BOX4", type),
1731                              material, 0.5*part6X, 0.5*sizeYMin , 0.5*sizeZ);
1732         TGeoVolume *volPart7 = mgr->MakeBox(Form("GF%s_BOX5", type),
1733                              material, 0.5*part7X, 0.5*sizeYMed2, 0.5*sizeZ);
1734         TGeoVolume *volPart8 = mgr->MakeBox(Form("GF%s_BOX6", type), 
1735                               material, 0.5*part8X, 0.5*sizeYMin , 0.5*sizeZ);
1736         
1737         // === SET COLOR ===
1738         if (kaptonLayer) {
1739                 volPart1->SetLineColor(kRed + 3);
1740                 volPart2->SetLineColor(kRed + 3);
1741                 volPart3->SetLineColor(kRed + 3);
1742                 volPart4->SetLineColor(kRed + 3);
1743                 volPart5->SetLineColor(kRed + 3);
1744                 volPart6->SetLineColor(kRed + 3);
1745                 volPart7->SetLineColor(kRed + 3);
1746                 volPart8->SetLineColor(kRed + 3);
1747         }else{
1748                 volPart1->SetLineColor(kGreen);
1749                 volPart2->SetLineColor(kGreen);
1750                 volPart3->SetLineColor(kGreen);
1751                 volPart4->SetLineColor(kGreen);
1752                 volPart5->SetLineColor(kGreen);
1753                 volPart6->SetLineColor(kGreen);
1754                 volPart7->SetLineColor(kGreen);
1755                 volPart8->SetLineColor(kGreen);
1756         } // end if (kaptonLayer)
1757                 
1758         // === TRANSLATION OF ALL PARTS ===
1759         
1760         transX = 0.5*(part1X - length);
1761         TGeoTranslation *transPart1 = new TGeoTranslation(transX, 0.0, 0.0);
1762         transX += 0.5*(part1X + part2X);
1763         TGeoTranslation *transPart2 = new TGeoTranslation(transX, 0.0, 0.0);
1764         transX += 0.5*(part2X + part3X);
1765         transY  = 0.5*(sizeYMax - sizeYMed1);
1766         TGeoTranslation *transPart3 = new TGeoTranslation(transX, transY, 0.0);
1767         transX += 0.5*(part3X + part4X);
1768         TGeoTranslation *transPart4 = new TGeoTranslation(transX, transY, 0.0);
1769         transX += 0.5*(part4X + part5X);
1770         transY  = 0.5*(sizeYMax - sizeYMed2);
1771         TGeoTranslation *transPart5 = new TGeoTranslation(transX, transY, 0.0);
1772         transX += 0.5*(part5X + part6X);
1773         transY  = 0.5*(sizeYMax - sizeYMin);
1774         TGeoTranslation *transPart6 = new TGeoTranslation(transX, transY, 0.0);
1775         transX += 0.5*(part6X + part7X);
1776         transY  = 0.5*(sizeYMax - sizeYMed2);
1777         TGeoTranslation *transPart7 = new TGeoTranslation(transX, transY, 0.0);
1778         transX += 0.5*(part7X + part8X);
1779         transY  = 0.5*(sizeYMax - sizeYMin);
1780         TGeoTranslation *transPart8 = new TGeoTranslation(transX, transY, 0.0);
1781         
1782         // add the partial volumes to the container
1783         container->AddNode(volPart1, 1, transPart1);
1784         container->AddNode(volPart2, 2, transPart2);
1785         container->AddNode(volPart3, 3, transPart3);
1786         container->AddNode(volPart4, 4, transPart4);
1787         container->AddNode(volPart5, 5, transPart5);
1788         container->AddNode(volPart6, 6, transPart6);
1789         container->AddNode(volPart7, 7, transPart7);
1790         container->AddNode(volPart8, 8, transPart8);
1791                         
1792         return container;
1793 }
1794
1795 //______________________________________________________________________
1796 TGeoVolume* AliITSv11GeometrySPD::CreateGroundingFoil(Double_t &thickness,
1797                                                       TGeoManager *mgr){
1798         // Joins two Kapton and two Aluminum layers of the grounding foil
1799         // in order to create the complete grounding foil for a whole stave.
1800         // into a unique container volume, which is returned as output.
1801         // The use of the TGeoXtru shape requires that in the separate 
1802         // foils, the Z axis lies perpendicularly to the polygonal basis 
1803         // of this shape;  this caused the components to have their Z 
1804         // axis corresponding to the X axis of the ALICE reference frame 
1805         // and vieceversa; to correct this, a rotation is necessary 
1806         // around their middle axis, to exchange X and Z axes and displace 
1807         // the object correctly in the ALICE frame.
1808         // ---
1809         // Arguments:
1810         //  - the sizes of the container box (passed by reference and 
1811         //    filled here)
1812         //  - the TGeoManager
1813         // ---
1814         // Returns: 
1815         //  - the container TGeoBBox (return value)
1816         //  - the size of the container (reference variables)
1817         //
1818
1819         // sizes of the added volumes, which are filled by passing them 
1820         // to the volume creation methods
1821         Double_t kpLength, kpWidth, kpThick;
1822         Double_t alLength, alWidth, alThick;
1823         // separation between left and right volumes
1824         Double_t separation = fgkmm * 1.42;
1825         
1826         // create the two component volumes (each one will be replicated 
1827         // twice) this gives also the size of their virtual container 
1828         // boxes (just a reference, not a volume)
1829         TGeoVolume *kVol = CreateGroundingFoilSingle(kTRUE, kpLength, 
1830                                                      kpWidth, kpThick, mgr);
1831         TGeoVolume *aVol = CreateGroundingFoilSingle(kFALSE, alLength, 
1832                                                      alWidth, alThick, mgr);
1833         kVol->SetLineColor(kRed);
1834         aVol->SetLineColor(kGray);
1835         
1836         // kapton leads the total size of the foil (including spagcing 
1837         // of 1.42 mm between them in the center)
1838         Double_t length, width;
1839         length    = 2.0 * kpLength + separation;
1840         width     = kpWidth;
1841         thickness = kpThick + alThick;
1842         
1843         // create the container
1844         TGeoMedium *vacuum = mgr->GetMedium("VACUUM");
1845         TGeoVolume *container = mgr->MakeBox("GFOIL", vacuum, 0.5*thickness, 
1846                                              0.5*width, 0.5*length);
1847         
1848         // create the common correction rotations
1849         TGeoRotation *rotCorr1 = new TGeoRotation(*gGeoIdentity);
1850         TGeoRotation *rotCorr2 = new TGeoRotation(*gGeoIdentity);
1851         rotCorr1->RotateY(-90.0);
1852         rotCorr2->RotateY( 90.0);
1853                 
1854         // compute the translations to place the objects at the edges of 
1855         // the volume the kapton foils are also shifted down, and the 
1856         // aluminum foils are shifted up with respect to the thickness 
1857         // direction
1858         TGeoTranslation *kTrans1 = new TGeoTranslation(0.5*(-thickness+kpThick),
1859                                                        0.0,
1860                                                        0.5*(length-kpLength));
1861         TGeoTranslation *kTrans2 = new TGeoTranslation(0.5*(-thickness+kpThick),
1862                                                        0.0,
1863                                                        0.5*(-length+kpLength));
1864         TGeoTranslation *aTrans1 = new TGeoTranslation(0.5*(thickness-alThick),
1865                                                        0.0,
1866                                                     0.5*(length-alLength)-0.02);
1867         TGeoTranslation *aTrans2 = new TGeoTranslation(0.5*(thickness-alThick),
1868                                                        0.0,
1869                                                    0.5*(-length+alLength)+0.02);
1870         
1871         // combine translations and rotations
1872         TGeoCombiTrans *kCombi1 = new TGeoCombiTrans(*kTrans1, *rotCorr1);
1873         TGeoCombiTrans *kCombi2 = new TGeoCombiTrans(*kTrans2, *rotCorr2);
1874         TGeoCombiTrans *aCombi1 = new TGeoCombiTrans(*aTrans1, *rotCorr1);
1875         TGeoCombiTrans *aCombi2 = new TGeoCombiTrans(*aTrans2, *rotCorr2);
1876                 
1877         // add to container
1878         container->AddNode(kVol, 0, kCombi1);
1879         container->AddNode(kVol, 1, kCombi2);
1880         container->AddNode(aVol, 0, aCombi1);
1881         container->AddNode(aVol, 1, aCombi2);
1882         
1883         return container;
1884 }
1885
1886 //______________________________________________________________________
1887 TGeoVolume* AliITSv11GeometrySPD::CreateMCMBase(TGeoManager *geom) const{
1888         // Creates the MCM basis volume.
1889         // It is a little bit more complicated because this is a plain base
1890         // with a poly shape similar to the one of grounding foil but 
1891         // there are also some chips glued to its base and covered with 
1892         // a cave cap.
1893         // ---
1894         // The complete MCM object is created as the sum of the following parts:
1895         // 1) a planar basis shaped according to the MCM typical shape
1896         // 2) some boxes which represent the chips and devices mounted on 
1897         //    this base
1898         // 3) a cave cap which covers the portion of MCM containing these chips
1899         // ---
1900         // Due to the different widths of MCM, it is implemented in a 
1901         // more complicated way:
1902         // - cap and chips will define a sub-volume of this structure, 
1903         //   which can be bounded by a complete box
1904         // - base of MCM will be a separate volume
1905         // - these two objects will need to be glued together into an 
1906         //  upper-level volume
1907         // ---
1908         // This metod creates only the thin base (point 1 in the list)
1909         //
1910         
1911         // medium
1912         TGeoMedium *medBase = geom->GetMedium("MCM BASE");
1913         
1914         // parameterize the interesting sizes of MCM
1915         // it is divided into 3 sectors which have different size in 
1916         // X and Y and are connected by trapezoidal-based shapes, 
1917         // where the oblique angle makes a 45 degrees angle with the 
1918         // vertical, so that the X size and Y size of these "intermezzo"'s 
1919         // is the same
1920         // +--------------------------------+
1921         // |                   sect 2       |
1922         // | sect 1     --------------------+
1923         // +-----------/
1924         Double_t sizeZ = fgkmm * 0.35;
1925         Double_t sizeXtot = fgkmm * 105.6;
1926         Double_t sizeXsector[3] = {fgkmm * 28.4, fgkmm * 41.4, fgkmm * 28.8};
1927         Double_t sizeYsector[3] = {fgkmm * 15.0, fgkmm * 11.0, fgkmm *  8.0};
1928         Double_t sizeSep01 = fgkmm * 4.0, sizeSep12 = fgkmm * 3.0;
1929         Double_t sizeHole = fgkmm * 1.0;
1930         Double_t posHoleX = fgkmm * -0.5*sizeXtot + 26.7 + 0.5*sizeHole;
1931         Double_t posHoleY = fgkmm * -0.5*sizeYsector[0] + 0.5*sizeHole;
1932         
1933         // define the shape of base volume as an XTRU with two identical faces 
1934         // distantiated by the width of the  itself
1935         Double_t x[8], y[8];
1936         x[0] = -0.5*sizeXtot;
1937         y[0] =  0.5*sizeYsector[0];
1938         x[1] = -x[0];
1939         y[1] =  y[0];
1940         x[2] =  x[1];
1941         y[2] =  y[1] - sizeYsector[2];
1942         x[3] =  x[2] - sizeXsector[2];
1943         y[3] =  y[2];
1944         x[4] =  x[3] - sizeSep12;
1945         y[4] =  y[3] - sizeSep12;
1946         x[5] =  x[4] - sizeXsector[1];
1947         y[5] =  y[4];
1948         x[6] =  x[5] - sizeSep01;
1949         y[6] =  y[5] - sizeSep01;
1950         x[7] =  x[0];
1951         y[7] = -y[0];
1952         
1953         // create shape
1954         TGeoXtru *shPoly = new TGeoXtru(2);
1955         shPoly->SetName("SH_MCMBASE_POLY");
1956         shPoly->DefinePolygon(8, x, y);
1957         shPoly->DefineSection(0, -0.5*sizeZ, 0., 0., 1.0);
1958         shPoly->DefineSection(1,  0.5*sizeZ, 0., 0., 1.0);
1959         
1960         // create small hole
1961         TGeoBBox *shHole = 0;
1962         shHole = new TGeoBBox("SH_MCMBASE_HOLE", 0.5*sizeHole, 0.5*sizeHole, 
1963                               0.5*sizeZ+0.01);
1964         TGeoTranslation *transHole = new TGeoTranslation("TR_MCMBASE_HOLE", 
1965                                                     posHoleX, posHoleY, 0.0);
1966         transHole->RegisterYourself(); 
1967         
1968         // create shape intersection
1969         TGeoCompositeShape *shBase = new TGeoCompositeShape("SH_MCMBASE",
1970                           "SH_MCMBASE_POLY - SH_MCMBASE_HOLE:TR_MCMBASE_HOLE");
1971         
1972         // create volume
1973         TGeoVolume *volBase = new TGeoVolume("VOL_MCMBASE", shBase, medBase);
1974         volBase->SetLineColor(kRed);
1975         
1976         return volBase;
1977 }
1978 //______________________________________________________________________
1979 TGeoVolume* AliITSv11GeometrySPD::CreateMCMCoverBorder(TGeoManager *geom){
1980         // Creates the MCM basis volume.
1981         // It is a little bit more complicated because this is a plain base
1982         // with a poly shape similar to the one of grounding foil but there 
1983         // are also some chips glued to its base and covered with a cave cap.
1984         // ---
1985         // The complete MCM object is created as the sum of the following parts:
1986         // 1) a planar basis shaped according to the MCM typical shape
1987         // 2) some boxes which represent the chips and devices mounted on 
1988         //  this base
1989         // 3) a cave cap which covers the portion of MCM containing these chips
1990         // ---
1991         // Due to the different widths of MCM, it is implemented in a more 
1992         // complicated way:
1993         // - cap and chips will define a sub-volume of this structure, 
1994         //   which can be bounded by a complete box
1995         // - base of MCM will be a separate volume
1996         // - these two objects will need to be glued together into an 
1997         //   upper-level volume
1998         // ---
1999         // This metod creates the thicker cap and its contents (points 2-3 
2000         // in the list). Since it covers only two of the three sectors of 
2001         // the MCM base with different width
2002         // the computations and variables related to the largest sector 
2003         // are removed, while
2004         // the other are the same as the other part of the MCM.
2005         //
2006         
2007         // media
2008         TGeoMedium *medCap  = geom->GetMedium("MCM COVER");
2009         
2010         // parameterize the interesting sizes of MCM
2011         // it is divided into 3 sectors which have different size in 
2012         // X and Y and  are connected by trapezoidal-based shapes, 
2013         // where the oblique angle makes a 45 degrees angle with the 
2014         // vertical, so that the X size and Y size of these "intermezzo"'s 
2015         // is the same
2016         // +--------------------------------+
2017         // |                   sect 2       |
2018         // | sect 1     --------------------+
2019         // +-----------/
2020         Double_t sizeZ = fgkmm * 0.3;
2021         Double_t capHeight = fgkmm * 1.7 - sizeZ;
2022         Double_t sizeXtot = fgkmm * 73.2;
2023         Double_t sizeXsector[2] = {fgkmm * 41.4, fgkmm * 28.8};
2024         Double_t sizeYsector[2] = {fgkmm * 11.0, fgkmm *  8.0};
2025         Double_t sizeSep = fgkmm * 3.0;
2026         
2027         // === PART 1: border ===
2028         
2029         // define the shape of base volume as an XTRU with two identical faces 
2030         // distantiated by the width of the  itself
2031         Double_t x[6], y[6];
2032         x[0] = -0.5*sizeXtot;
2033         y[0] =  0.5*sizeYsector[0];
2034         x[1] = -x[0];
2035         y[1] =  y[0];
2036         x[2] =  x[1];
2037         y[2] =  y[1] - sizeYsector[1];
2038         x[3] =  x[2] - sizeXsector[1];
2039         y[3] =  y[2];
2040         x[4] =  x[3] - sizeSep;
2041         y[4] =  y[3] - sizeSep;
2042         x[5] =  x[0];
2043         y[5] = -y[0];
2044         
2045         // create outer border shape with above coordinates
2046         TGeoXtru *capOut = new TGeoXtru(2);
2047         capOut->SetName("SH_MCMCAPOUT");
2048         capOut->DefinePolygon(6, x, y);
2049         capOut->DefineSection(0, -0.5*capHeight, 0., 0., 1.0);
2050         capOut->DefineSection(1,  0.5*capHeight, 0., 0., 1.0);
2051         
2052         // the inner border is built similarly but subtracting the thickness
2053         Double_t angle = 45.0;
2054         Double_t cs = TMath::Cos( 0.5*(TMath::Pi() - angle*TMath::DegToRad()) );
2055         Double_t xin[6], yin[6];
2056         xin[0] = x[0] + sizeZ;
2057         yin[0] = y[0] - sizeZ;
2058         xin[1] = x[1] - sizeZ;
2059         yin[1] = yin[0];
2060         xin[2] = xin[1];
2061         yin[2] = y[2] + sizeZ;
2062         xin[3] = x[3] - sizeZ*cs;
2063         yin[3] = yin[2];
2064         xin[4] = xin[3] - sizeSep;
2065         yin[4] = y[4] + sizeZ;
2066         xin[5] = xin[0];
2067         yin[5] = yin[4];
2068                 
2069         // create inner border shape
2070         TGeoXtru *capIn = new TGeoXtru(2);
2071         capIn->SetName("SH_MCMCAPIN");
2072         capIn->DefinePolygon(6, xin, yin);
2073         capIn->DefineSection(0, -0.5*capHeight-0.01, 0., 0., 1.0);
2074         capIn->DefineSection(1,  0.5*capHeight+0.01, 0., 0., 1.0);
2075         
2076         // compose shape
2077         TGeoCompositeShape *shBorder = new TGeoCompositeShape("SH_MCMCAPBORDER",
2078                                 "SH_MCMCAPOUT-SH_MCMCAPIN");
2079         
2080         // create volume
2081         TGeoVolume *volBorder = new TGeoVolume("VOL_MCMCAPBORDER", shBorder,
2082                                                medCap);
2083         volBorder->SetLineColor(kGreen);
2084         
2085         return volBorder;
2086 }
2087 //______________________________________________________________________
2088 TGeoVolume* AliITSv11GeometrySPD::CreateMCMCoverTop(TGeoManager *geom){
2089         // Creates the MCM basis volume.
2090         // It is a little bit more complicated because this is a plain base
2091         // with a poly shape similar to the one of grounding foil but 
2092         // there are also
2093         // some chips glued to its base and covered with a cave cap.
2094         // ---
2095         // The complete MCM object is created as the sum of the following parts:
2096         // 1) a planar basis shaped according to the MCM typical shape
2097         // 2) some boxes which represent the chips and devices mounted on 
2098         //    this base
2099         // 3) a cave cap which covers the portion of MCM containing these chips
2100         // ---
2101         // Due to the different widths of MCM, it is implemented in a 
2102         // more complicated way:
2103         // - cap and chips will define a sub-volume of this structure, 
2104         //   which can be bounded by a complete box
2105         // - base of MCM will be a separate volume
2106         // - these two objects will need to be glued together into an 
2107         //   upper-level volume
2108         // ---
2109         // This metod creates the thicker cap and its contents (points 
2110         // 2-3 in the list). Since it covers only two of the three 
2111         // sectors of the MCM base with different width
2112         // the computations and variables related to the largest sector 
2113         // are removed, while the other are the same as the other part 
2114         // of the MCM.
2115         //
2116
2117         // media
2118         TGeoMedium *medCap  = geom->GetMedium("MCM COVER");
2119         
2120         // parameterize the interesting sizes of MCM
2121         // it is divided into 3 sectors which have different size in X 
2122         // and Y and  are connected by trapezoidal-based shapes, where 
2123         // the oblique angle makes a 45 degrees angle with the vertical, 
2124         // so that the X size and Y size of these "intermezzo"'s is the same
2125         // +--------------------------------+
2126         // |                   sect 2       |
2127         // | sect 1     --------------------+
2128         // +-----------/
2129         Double_t sizeZ = fgkmm * 0.3;
2130         Double_t sizeXtot = fgkmm * 73.2;
2131         Double_t sizeXsector[2] = {fgkmm * 41.4, fgkmm * 28.8};
2132         Double_t sizeYsector[2] = {fgkmm * 11.0, fgkmm *  8.0};
2133         Double_t sizeSep = fgkmm * 3.0;
2134         
2135         // === PART 1: border ===
2136         
2137         // define the shape of base volume as an XTRU with two identical faces 
2138         // distantiated by the width of the  itself
2139         Double_t x[6], y[6];
2140         x[0] = -0.5*sizeXtot;
2141         y[0] =  0.5*sizeYsector[0];
2142         x[1] = -x[0];
2143         y[1] =  y[0];
2144         x[2] =  x[1];
2145         y[2] =  y[1] - sizeYsector[1];
2146         x[3] =  x[2] - sizeXsector[1];
2147         y[3] =  y[2];
2148         x[4] =  x[3] - sizeSep;
2149         y[4] =  y[3] - sizeSep;
2150         x[5] =  x[0];
2151         y[5] = -y[0];
2152         
2153         // create outer border shape with above coordinates
2154         TGeoXtru *capOut = new TGeoXtru(2);
2155         capOut->SetName("SH_MCMCAPOUT");
2156         capOut->DefinePolygon(6, x, y);
2157         capOut->DefineSection(0, -0.5*sizeZ, 0., 0., 1.0);
2158         capOut->DefineSection(1,  0.5*sizeZ, 0., 0., 1.0);
2159         
2160         // the inner border is built similarly but subtracting the thickness
2161         Double_t angle = 45.0;
2162         Double_t cs = TMath::Cos( 0.5*(TMath::Pi() - angle*TMath::DegToRad()) );
2163         Double_t xin[6], yin[6];
2164         xin[0] = x[0] + sizeZ;
2165         yin[0] = y[0] - sizeZ;
2166         xin[1] = x[1] - sizeZ;
2167         yin[1] = yin[0];
2168         xin[2] = xin[1];
2169         yin[2] = y[2] + sizeZ;
2170         xin[3] = x[3] - sizeZ*cs;
2171         yin[3] = yin[2];
2172         xin[4] = xin[3] - sizeSep;
2173         yin[4] = y[4] + sizeZ;
2174         xin[5] = xin[0];
2175         yin[5] = yin[4];
2176                 
2177         // coverage of upper part (equal to external border, but full)
2178         TGeoXtru *shCover = new TGeoXtru(2);
2179         shCover->SetName("SH_MCMCAPCOVER");
2180         shCover->DefinePolygon(6, x, y);
2181         shCover->DefineSection(0, -0.5*sizeZ, 0., 0., 1.0);
2182         shCover->DefineSection(1,  0.5*sizeZ, 0., 0., 1.0);
2183         
2184         // create volume
2185         TGeoVolume *volCover  = new TGeoVolume("VOL_MCMCAPCOVER", shCover, 
2186                                                medCap);
2187         volCover->SetLineColor(kBlue);
2188         
2189         return volCover;
2190 }
2191 //______________________________________________________________________
2192 TGeoVolumeAssembly* AliITSv11GeometrySPD::CreateStave(Int_t layer, 
2193                              Double_t &fullThickness, TGeoManager *mgr){
2194         // Creates the complete stave as an assembly which contains all 
2195         // the stuff defined in the "CreateStaveBase" method (which are 
2196         // the thin part of the structure) and adds to this the thick 
2197         // cover of the MCM and the Pixel bus. This is done as an 
2198         // assembly to avoid the problem of a "ghost" overlap which occurs
2199         // when putting the stave on the carbon fiber sector, in the case 
2200         // that we define it as a volume container.
2201         // ---
2202         // Arguments:
2203         //     - the layer where the stave has to be put (hard check on this)
2204         //     - the geometry manager
2205         //
2206         
2207         // ** CRITICAL CHECK **
2208         // layer number can be ONLY 1 or 2
2209         if (layer != 1 && layer != 2) 
2210           AliFatal("Required that layer number be 1 or 2");
2211         
2212         // sizes regarding the components
2213         Double_t baseWidth, baseHeight, baseThickness;
2214         Double_t mcmCapBorderThickness = fgkmm *  0.3;
2215         Double_t mcmCapThickness       = fgkmm *  1.7 - mcmCapBorderThickness;
2216         Double_t mcmCapHeight          = fgkmm * 11.0;
2217         Double_t mcmCapWidth           = fgkmm * 73.2;
2218         
2219         // create container
2220         TGeoVolumeAssembly *container = new TGeoVolumeAssembly(
2221                                          Form("LAY%d_FULLSTAVE", layer));
2222         
2223         // create subvolumes
2224         TGeoVolume *staveBase = CreateStaveBase(layer, baseWidth, baseHeight, 
2225                                                 baseThickness, mgr);
2226         TGeoVolume *mcmCapBorder = CreateMCMCoverBorder(mgr);
2227         TGeoVolume *mcmCapTop = CreateMCMCoverTop(mgr);
2228         // bus in z > 0
2229         TGeoVolumeAssembly *bus0 = CreatePixelBusAndExtensions(kTRUE, mgr);
2230         // bus in z < 0
2231         TGeoVolumeAssembly *bus1 = CreatePixelBusAndExtensions(kFALSE, mgr);
2232         
2233         // the full width and height of the area which contains all 
2234         // components corresponds to the one of the stave base built with 
2235         // the "CreateStaveBase" method while the thickness must be 
2236         // computed as the sum of this base + the cover
2237         fullThickness = baseThickness + mcmCapThickness + mcmCapBorderThickness;
2238         
2239         // 1 - MCM cover        
2240                 
2241         // translations (in the X direction, MCM is at the same level as ladder)
2242         Double_t xBase = -0.5*fullThickness + 0.5*baseThickness;
2243         TGeoTranslation *trBase = new TGeoTranslation(xBase, 0.0, 0.0);
2244         Double_t xMCMCapB = xBase + 0.5*baseThickness + 0.5*mcmCapThickness;
2245         Double_t xMCMCapT = xMCMCapB + 0.5*mcmCapThickness + 
2246                                                   0.5*mcmCapBorderThickness;
2247         Double_t yMCMCap  = 0.5*(baseHeight - mcmCapHeight);
2248         Double_t zMCMCap1 = 0.5*baseWidth - 0.5*mcmCapWidth;
2249         Double_t zMCMCap0 = -zMCMCap1;
2250         // correction rotations
2251         TGeoRotation *rotCorr0 = new TGeoRotation(*gGeoIdentity);
2252         TGeoRotation *rotCorr1 = new TGeoRotation(*gGeoIdentity);
2253         rotCorr0->RotateY( 90.0);
2254         rotCorr1->RotateY(-90.0);
2255         TGeoCombiTrans  *trMCMCapBorder0 = new TGeoCombiTrans(xMCMCapB, 
2256                                              yMCMCap, zMCMCap0, rotCorr0);
2257         TGeoCombiTrans  *trMCMCapBorder1 = new TGeoCombiTrans(xMCMCapB, 
2258                                              yMCMCap, zMCMCap1, rotCorr1);
2259         TGeoCombiTrans  *trMCMCapTop0 = new TGeoCombiTrans(xMCMCapT, 
2260                                              yMCMCap, zMCMCap0, rotCorr0);
2261         TGeoCombiTrans  *trMCMCapTop1 = new TGeoCombiTrans(xMCMCapT, 
2262                                              yMCMCap, zMCMCap1, rotCorr1);
2263         // add to container
2264         container->AddNode(staveBase, 0, trBase);
2265         container->AddNode(mcmCapBorder, 0, trMCMCapBorder0);
2266         container->AddNode(mcmCapBorder, 1, trMCMCapBorder1);
2267         container->AddNode(mcmCapTop, 0, trMCMCapTop0);
2268         container->AddNode(mcmCapTop, 1, trMCMCapTop1);
2269         
2270         // 2 - Pixel Bus
2271         
2272         // translations
2273         // for the moment, a correction amount of 0.04 is required to 
2274         // place correctly the object in X and another correction of 
2275         // 0.015 in Z
2276         Double_t busHeight  = fgkmm * 13.8;
2277         Double_t xPixelBus  = xBase + baseThickness + 0.04;
2278         Double_t yPixelBus1 = 0.5*baseHeight - 0.5*busHeight + 
2279                                        0.5*(baseHeight - busHeight);
2280         Double_t zPixelBus0 = -0.25*baseWidth + 0.015 - 0.03;
2281         //Double_t zPixelBus0 = -0.5*(0.5*baseWidth - 0.04);
2282         Double_t zPixelBus1 = -zPixelBus0;
2283         // correction rotations
2284         TGeoRotation *rotCorrBus1 = new TGeoRotation(*gGeoIdentity);
2285         rotCorrBus1->RotateX(180.0);
2286         //TGeoCombiTrans *trBus0 = new TGeoCombiTrans(xPixelBus, 0.0, 
2287         //                                     zPixelBus0, rotCorrBus);
2288         TGeoTranslation *trBus0 = new TGeoTranslation(xPixelBus, 0.0, 
2289                                                            zPixelBus0);
2290         //TGeoTranslation *trBus1 = new TGeoTranslation(xPixelBus, 0.0, 
2291         //                                                 zPixelBus1);
2292         TGeoCombiTrans *trBus1 = new TGeoCombiTrans(xPixelBus, yPixelBus1, 
2293                                                     zPixelBus1, rotCorrBus1);
2294
2295         // add to container
2296         container->AddNode(bus0, 0, trBus0);
2297         container->AddNode(bus1, 1, trBus1);
2298         
2299         return container;
2300 }
2301 //______________________________________________________________________
2302 TGeoVolumeAssembly* AliITSv11GeometrySPD::CreatePixelBusAndExtensions(
2303                                      Bool_t zpos, TGeoManager *mgr){
2304   // Creates an assembly which contains the pixel bus and its extension
2305   // and the extension of the MCM.
2306   // By: Renaud Vernet
2307   // NOTE: to be defined its material and its extension in the outside direction
2308   //
2309   
2310   // ====   constants   =====
2311
2312   //get the media
2313   TGeoMedium   *medPixelBus    = mgr->GetMedium("PIXEL BUS") ;
2314   TGeoMedium   *medPBExtender  = mgr->GetMedium("PIXEL BUS EXTENDER") ;
2315   TGeoMedium   *medMCMExtender = mgr->GetMedium("MCM EXTENDER") ;
2316
2317   //geometrical constants
2318   const Double_t kGroundingThickness    =   0.07  * fgkmm ;
2319   const Double_t kGrounding2pixelBusDz  =   0.625 * fgkmm ;
2320   const Double_t kPixelBusThickness     =   0.28  * fgkmm ;
2321   const Double_t kGroundingWidthX       = 170.501 * fgkmm ;
2322   const Double_t kPixelBusContactDx     =   1.099 * fgkmm ;
2323   const Double_t kPixelBusWidthY        =  13.8   * fgkmm ;
2324   //design=20 deg.
2325   const Double_t kPixelBusContactPhi    =  20.0   * TMath::DegToRad();
2326   //design=?? 70 deg. seems OK
2327   const Double_t kPbExtenderPsi         =  70.0   * TMath::DegToRad(); 
2328   const Double_t kPbExtenderWidthY      =  11.0   * fgkmm ;
2329   const Double_t kPbExtenderTopZ        =   2.72  * fgkmm ;
2330   const Double_t kMcmThickness          =   0.35  * fgkmm ;
2331   const Double_t kMcmExtenderThickness  =   0.20  * fgkmm ;
2332   const Double_t kDeltaMcmMcmextender   =   1.6   * fgkmm ;
2333   const Double_t kHalfStaveTotalLength  = 247.64  * fgkmm ;
2334   const Double_t kDeltaYOrigin          =  15.95/2.* fgkmm ;
2335   const Double_t kDeltaXOrigin          =   1.1    * fgkmm ;
2336   const Double_t kDeltaZOrigin          = kHalfStaveTotalLength / 2. ;
2337
2338   const Double_t kGrounding2pixelBusDz2 = kGrounding2pixelBusDz+
2339                             kGroundingThickness/2. + kPixelBusThickness/2. ;
2340   const Double_t kPixelBusWidthX        = kGroundingWidthX ;
2341   const Double_t kPixelBusRaiseLength   = (kPixelBusContactDx-
2342               kPixelBusThickness*TMath::Sin(kPixelBusContactPhi))/
2343                                       TMath::Cos(kPixelBusContactPhi) ;
2344   const Double_t kPbExtenderBaseZ       = kGrounding2pixelBusDz2 + 
2345               kPixelBusRaiseLength*TMath::Sin(kPixelBusContactPhi) + 
2346               2*kPixelBusThickness*TMath::Sin(kPixelBusContactPhi)*
2347               TMath::Tan(kPixelBusContactPhi) ;
2348   const Double_t kPbExtenderDeltaZ      = kPbExtenderTopZ-kPbExtenderBaseZ ;
2349   const Double_t kPbExtenderEndPointX   = 2*kDeltaZOrigin - kGroundingWidthX - 
2350                         2*kPixelBusThickness*TMath::Sin(kPixelBusContactPhi) ;
2351   const Double_t kMcmextenderEndPointX  = kDeltaZOrigin - 48.2 * fgkmm ;
2352   const Double_t kMcmExtenderWidthY     = kPbExtenderWidthY ;
2353
2354   //=====  end constants  =====
2355
2356   
2357   /*
2358   // -----------------   CREATE THE PIXEL BUS --------------------------
2359   // At the end of the pixel bus, a small piece is added for the contact 
2360   // with the pixel bus extender.
2361   // The whole piece is made with an extrusion, using 7 points
2362   //
2363   //                                   4
2364   //                                  /\
2365   // 6                            5  /  \ 3
2366   //  +-----------------------------+    /
2367   //  |                                 /
2368   //  +-----------------------------+--+
2369   // 0                              1   2
2370   //
2371   // The length of the pixel bus is defined (170.501mm) by the technical design
2372   // this length corresponds to distance [0-1] and [6-5]
2373
2374   */
2375
2376   TGeoVolumeAssembly *pixelBus = new TGeoVolumeAssembly("PIXEL BUS");
2377
2378   // definition of the 7 points for the extrusion
2379   Double_t pixelBusXtruX[7] = {
2380     -kPixelBusWidthX/2. ,
2381     kPixelBusWidthX/2. ,
2382     kPixelBusWidthX/2. + kPixelBusThickness * TMath::Sin(kPixelBusContactPhi) ,
2383     kPixelBusWidthX/2. + kPixelBusThickness * TMath::Sin(kPixelBusContactPhi) +
2384                        kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) ,
2385     kPixelBusWidthX/2. + kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi),
2386     kPixelBusWidthX/2. ,
2387     -kPixelBusWidthX/2.
2388   } ;
2389   Double_t pixelBusXtruY[7] = {
2390     -kPixelBusThickness/2. ,
2391     -kPixelBusThickness/2. ,
2392     -kPixelBusThickness/2. + kPixelBusThickness *
2393                                  (1 - TMath::Cos(kPixelBusContactPhi)) ,
2394     -kPixelBusThickness/2. + kPixelBusThickness *
2395                                  (1 - TMath::Cos(kPixelBusContactPhi)) +
2396                   kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) ,
2397     kPixelBusThickness/2.  + kPixelBusRaiseLength * 
2398                                   TMath::Sin(kPixelBusContactPhi) ,
2399     kPixelBusThickness/2. ,
2400     kPixelBusThickness/2.
2401   } ;
2402
2403   // creation of the volume
2404   TGeoXtru   *pixelBusXtru    = new TGeoXtru(2);
2405   TGeoVolume* pixelBusXtruVol = new TGeoVolume("pixelBusXtru",
2406                                                 pixelBusXtru,medPixelBus) ;
2407   pixelBusXtru->DefinePolygon(7,pixelBusXtruX,pixelBusXtruY);
2408   pixelBusXtru->DefineSection(0,-kPixelBusWidthY/2.);
2409   pixelBusXtru->DefineSection(1, kPixelBusWidthY/2.);
2410   // --------------- END PIXEL BUS -------------------------------------
2411
2412
2413   // ------------------------- CREATE THE PIXEL BUS EXTENDER -----------
2414   // The geometry of the extender is a bit complicated sinceit is constrained
2415   // to be in contact with the pixel bus.
2416   // It consists of an extrusion using 13 points as shows the scheme below :
2417   //
2418   //                             8     7                       6
2419   //                               +---+---------------------+
2420   //                              /                          |
2421   //                             /                           |
2422   //                            /      +---------------------+
2423   //                           /      / 4                     5
2424   //                          /      /
2425   //       11  10          9 /      /
2426   //        +---+-----------+      /
2427   //       /                      /
2428   //      /                      /
2429   //     /      +-----------+---+
2430   // 12 +      / 1         2     3
2431   //     \    /
2432   //      \  /
2433   //        +
2434   //        0
2435
2436   // ====   constants   =====
2437   const Double_t kPbExtenderXtru3L   = 1.5 * fgkmm ; //arbitrary ?
2438   const Double_t kPbExtenderXtru4L   = (kPbExtenderDeltaZ + 
2439                  kPixelBusThickness*(TMath::Cos(kPbExtenderPsi)-2))/
2440                      TMath::Sin(kPbExtenderPsi) ;
2441   //=====  end constants  =====
2442
2443   TGeoVolumeAssembly *pbExtender = new TGeoVolumeAssembly("PIXEL BUS EXTENDER");
2444
2445   Double_t pbExtenderXtruX[13] = {
2446     0, 
2447     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) , 
2448     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) + kPbExtenderXtru3L ,
2449     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) + 
2450            kPbExtenderXtru3L + kPixelBusThickness * TMath::Sin(kPbExtenderPsi) ,
2451     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) + 
2452            kPbExtenderXtru3L + kPixelBusThickness * 
2453            TMath::Sin(kPbExtenderPsi) + kPbExtenderXtru4L * 
2454            TMath::Cos(kPbExtenderPsi) ,
2455     kPbExtenderEndPointX ,
2456     kPbExtenderEndPointX ,
2457     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) + 
2458            kPbExtenderXtru3L + kPixelBusThickness * TMath::Sin(kPbExtenderPsi)+
2459            kPbExtenderXtru4L * TMath::Cos(kPbExtenderPsi) ,
2460     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi)  + 
2461            kPbExtenderXtru3L + kPixelBusThickness * TMath::Sin(kPbExtenderPsi)+
2462            kPbExtenderXtru4L * TMath::Cos(kPbExtenderPsi) - kPixelBusThickness*
2463            TMath::Sin(kPbExtenderPsi),
2464     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) + kPbExtenderXtru3L ,
2465     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) , 
2466     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) - 
2467           kPixelBusThickness*TMath::Sin(kPixelBusContactPhi) , 
2468     -kPixelBusThickness * TMath::Sin(kPixelBusContactPhi)
2469   } ;
2470   Double_t pbExtenderXtruY[13] = {
2471     0, 
2472     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) , 
2473     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) ,
2474     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + 
2475                   kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) ,
2476     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + 
2477                   kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) + 
2478                   kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi) ,
2479     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + 
2480                   kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) + 
2481                   kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi) ,
2482     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + 
2483                   kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) + 
2484                   kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi) + 
2485                   kPixelBusThickness ,
2486     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + 
2487                   kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) + 
2488                   kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi) + 
2489                   kPixelBusThickness ,
2490     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + 
2491                   kPixelBusThickness + kPbExtenderXtru4L * 
2492                   TMath::Sin(kPbExtenderPsi),
2493     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi)+kPixelBusThickness ,
2494     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi)+kPixelBusThickness ,
2495     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi)+kPixelBusThickness*
2496                            TMath::Cos(kPixelBusContactPhi) ,
2497     kPixelBusThickness * TMath::Cos(kPixelBusContactPhi)
2498   } ;
2499   
2500   // creation of the volume
2501   TGeoXtru   *pbExtenderXtru    = new TGeoXtru(2);
2502   TGeoVolume *pbExtenderXtruVol = new TGeoVolume("pbExtenderXtru",
2503                                          pbExtenderXtru,medPBExtender) ;
2504   pbExtenderXtru->DefinePolygon(13,pbExtenderXtruX,pbExtenderXtruY);
2505   pbExtenderXtru->DefineSection(0,-kPbExtenderWidthY/2.);
2506   pbExtenderXtru->DefineSection(1, kPbExtenderWidthY/2.);
2507   // -------------- END PIXEL BUS EXTENDER -----------------------------
2508
2509
2510   // ------------------   CREATE THE MCM EXTENDER    -------------------
2511   // 
2512   // The MCM extender is located betwen the MCM and the Pixel Bus Extender
2513   // It consists of an extrusion using 10 points as shows the scheme below :
2514   //
2515   //                             7     6                       5
2516   //                               +---+---------------------+
2517   //                              /                          |
2518   //                             /                           |
2519   //                            /      +---------------------+
2520   //                           /      / 3                     4
2521   //                          /      /
2522   //            9          8 /      /
2523   //            +-----------+      /
2524   //            |                 /
2525   //            |                /
2526   //            +-----------+---+
2527   //            0          1     2
2528
2529   //constants
2530   const Double_t kMcmExtenderXtru3L  = 1.5  * fgkmm ;
2531   //end constants
2532
2533   TGeoVolumeAssembly *mcmExtender   = new TGeoVolumeAssembly("MCM EXTENDER");
2534   Double_t mcmExtenderXtruX[10] = {
2535     0 ,
2536     kMcmExtenderXtru3L ,
2537     kMcmExtenderXtru3L + kMcmExtenderThickness * TMath::Sin(kPbExtenderPsi) , 
2538     kMcmExtenderXtru3L + kMcmExtenderThickness * TMath::Sin(kPbExtenderPsi) + 
2539                            kDeltaMcmMcmextender / TMath::Tan(kPbExtenderPsi) ,
2540     kMcmextenderEndPointX ,
2541     kMcmextenderEndPointX ,
2542     kMcmExtenderXtru3L + kMcmExtenderThickness * TMath::Sin(kPbExtenderPsi) + 
2543                            kDeltaMcmMcmextender / TMath::Tan(kPbExtenderPsi) ,
2544     kMcmExtenderXtru3L + kDeltaMcmMcmextender / TMath::Tan(kPbExtenderPsi) ,
2545     kMcmExtenderXtru3L ,
2546     0
2547   } ;
2548
2549   Double_t mcmExtenderXtruY[10] = {
2550     0 ,
2551     0 ,
2552     kMcmExtenderThickness*(1.-TMath::Cos(kPbExtenderPsi)),
2553     kMcmExtenderThickness*(1.-TMath::Cos(kPbExtenderPsi))+kDeltaMcmMcmextender,
2554     kMcmExtenderThickness*(1.-TMath::Cos(kPbExtenderPsi))+kDeltaMcmMcmextender,
2555     kMcmExtenderThickness*(2.-TMath::Cos(kPbExtenderPsi))+kDeltaMcmMcmextender,
2556     kMcmExtenderThickness*(2.-TMath::Cos(kPbExtenderPsi))+kDeltaMcmMcmextender,
2557     kMcmExtenderThickness + kDeltaMcmMcmextender ,
2558     kMcmExtenderThickness ,
2559     kMcmExtenderThickness ,
2560   } ;
2561
2562   // creation of the volume
2563   TGeoXtru   *mcmExtenderXtru    = new TGeoXtru(2);
2564   TGeoVolume *mcmExtenderXtruVol = new TGeoVolume("mcmExtenderXtru",
2565                                              mcmExtenderXtru,medMCMExtender) ;
2566   mcmExtenderXtru->DefinePolygon(10,mcmExtenderXtruX,mcmExtenderXtruY);
2567   mcmExtenderXtru->DefineSection(0,-kMcmExtenderWidthY/2.);
2568   mcmExtenderXtru->DefineSection(1, kMcmExtenderWidthY/2.);
2569
2570
2571   //--------------   DEFINITION OF GEOMETRICAL TRANSFORMATIONS ---------
2572   TGeoRotation    * commonRot       = new TGeoRotation("commonRot",0,90,0);
2573   commonRot->MultiplyBy(new TGeoRotation("rot",-90,0,0)) ;
2574   TGeoTranslation * pixelBusTrans   = new TGeoTranslation(kPixelBusThickness/2.
2575                                                  - kDeltaXOrigin + 0.52*fgkmm ,
2576                                           -kPixelBusWidthY/2.+ kDeltaYOrigin , 
2577                                           -kGroundingWidthX/2.+ kDeltaZOrigin) ;
2578   TGeoRotation    * pixelBusRot     = new TGeoRotation(*commonRot);
2579   TGeoTranslation * pbExtenderTrans = new TGeoTranslation(*pixelBusTrans) ;
2580   TGeoRotation    * pbExtenderRot   = new TGeoRotation(*pixelBusRot) ;
2581   pbExtenderTrans->SetDz(*(pbExtenderTrans->GetTranslation()+2)-
2582                    kPixelBusWidthX/2.-2.*kPixelBusThickness*
2583                          TMath::Sin(kPixelBusContactPhi)) ;  
2584   if (!zpos) {
2585     pbExtenderTrans->SetDy(*(pbExtenderTrans->GetTranslation()+1) - 
2586                            (kPixelBusWidthY - kPbExtenderWidthY)/2.);
2587   }else {
2588     pbExtenderTrans->SetDy(*(pbExtenderTrans->GetTranslation()+1) + 
2589                            (kPixelBusWidthY - kPbExtenderWidthY)/2.);
2590   } // end if !zpos
2591   pbExtenderTrans->SetDx(*(pbExtenderTrans->GetTranslation()) +
2592                          kPixelBusThickness/2 + 2*kPixelBusThickness*
2593                          TMath::Sin(kPixelBusContactPhi)*
2594                          TMath::Tan(kPixelBusContactPhi)) ;
2595   TGeoTranslation * mcmExtenderTrans = new TGeoTranslation(0.12*fgkmm + 
2596                                         kMcmThickness - kDeltaXOrigin,
2597                                    pbExtenderTrans->GetTranslation()[1],-4.82);
2598   TGeoRotation    * mcmExtenderRot   = new TGeoRotation(*pbExtenderRot);
2599
2600   //ADD NODES TO ASSEMBLIES
2601   pixelBus    ->AddNode((TGeoVolume*)pixelBusXtruVol,0);
2602   pbExtender  ->AddNode((TGeoVolume*)pbExtenderXtruVol,0);
2603   mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtruVol,0);
2604 //   mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru3Vol,0);
2605 //   mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru3PrimVol,1);
2606 //   mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru4Vol,2);
2607 //   mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru4PrimVol,3);
2608 //   mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru5Vol,4);
2609
2610
2611   //CREATE FINAL VOLUME ASSEMBLY AND ROTATE IT
2612   TGeoVolumeAssembly *assembly = new TGeoVolumeAssembly("EXTENDERS");
2613   assembly->AddNode((TGeoVolume*)pixelBus    ,0, 
2614                     new TGeoCombiTrans(*pixelBusTrans,*pixelBusRot));
2615   assembly->AddNode((TGeoVolume*)pbExtender  ,0, 
2616                     new TGeoCombiTrans(*pbExtenderTrans,*pbExtenderRot));
2617   assembly->AddNode((TGeoVolume*)mcmExtender ,0, 
2618                     new TGeoCombiTrans(*mcmExtenderTrans,*mcmExtenderRot));
2619   assembly->SetTransparency(50);
2620   return assembly ;
2621 }
2622 //______________________________________________________________________
2623 TGeoVolume* AliITSv11GeometrySPD::CreateStaveBase(Int_t layer,
2624            Double_t &fullWidth, Double_t &fullHeight, Double_t &fullThickness,
2625            TGeoManager *mgr){
2626         // Creates a box which contains the followin parts of the whole stave:
2627         // - the two layers of grounding foil
2628         // - the ladders
2629         // - the thin base of the MCM (except its thick cover)
2630         // - the pixel bus
2631         // ---
2632         // Since it is required by detector numbering conventions, 
2633         // it is required as argument the layer which owns this stave.
2634         // This number will be used to define the name of the ladder volume, 
2635         // which must be different for layer1 and layer2 objects.
2636         // ---
2637         // Arguments:
2638         //    - layer number (will be checked to be 1 or 2)
2639         //    - geometry manager
2640         // ---
2641         // Returns:
2642         //    - a TGeoBBox volume containing all this stuff
2643         //    - the size of the container box are stored in the 
2644         //      reference-passed variables
2645         //
2646         // sizes of all objects to be inserted
2647         // these values are used to compute the total volume of the container
2648         // and to compute parametrically the position of each piece, instead
2649         // of putting hard-coded number (this helps in eventually modifying 
2650         // everything)
2651         Double_t mcmThickness    = fgkmm * 0.35;
2652         Double_t grndThickness   = fgkmm * 0.07; // = 0.05 + 0.02
2653         Double_t sepThickness    = fgkmm * 0.05;
2654
2655         Double_t ladderWidth     = fgkmm *  70.72;
2656         Double_t mcmWidth        = fgkmm * 105.60;
2657         Double_t sepLaddersWidth = fgkmm *   0.20;
2658         Double_t sepMCMWidth     = fgkmm *   0.30;
2659         // separations between central ladders in the two half-staves 
2660         Double_t sepLaddersCtr   = fgkmm *   0.40; 
2661
2662         Double_t mcmHeight       = fgkmm *  15.00;
2663         
2664         // compute the size of the container
2665         fullWidth     = 2.0*sepLaddersCtr + 4.0*ladderWidth + 
2666                     2.0*sepMCMWidth + 2.0*sepLaddersWidth + 2.0*mcmWidth;
2667         fullHeight    = fgkmm * 15.95;
2668         fullThickness = grndThickness + sepThickness + mcmThickness;
2669         
2670         // create the container
2671         TGeoVolume *container = mgr->MakeBox(Form("LAY%d_STAVE", layer),
2672                           mgr->GetMedium("VACUUM"), 0.5*fullThickness,
2673                           0.5*fullHeight, 0.5*fullWidth);
2674                 
2675         // fill the container going from bottom to top 
2676         // with respect to the thickness direction
2677         
2678         // 1 - Grounding foil
2679         // volume
2680         TGeoVolume *grndVol = CreateGroundingFoil(grndThickness);
2681         // translation
2682         Double_t xGrnd = -0.5*fullThickness + 0.5*grndThickness;
2683         TGeoTranslation *grndTrans = new TGeoTranslation(xGrnd, 0.0, 0.0);
2684         // add to container
2685         container->AddNode(grndVol, 1, grndTrans);
2686         
2687         // 2 - Ladders
2688         // volume (will be replicated 4 times)
2689         Double_t ladderLength, ladderThickness;
2690         TGeoVolume *ladder = CreateLadder(layer, ladderLength, ladderWidth, 
2691                                           ladderThickness, mgr);
2692         // translations (in thickness direction, the MCM thickness is used)
2693         // layers are sorted going from the one at largest Z to the one 
2694         // at smallest Z:
2695         // -|Zmax| ------> |Zmax|
2696         //      0   1   2   3
2697         // but it is more comfortable to start defining their Z position 
2698         // from center
2699         Double_t xLad  = xGrnd + 0.5*grndThickness + 0.5*mcmThickness + 
2700                          sepThickness;
2701         Double_t zLad1 = -0.5*ladderWidth - sepLaddersCtr;
2702         Double_t zLad0 = zLad1 - ladderWidth - sepLaddersWidth;
2703         Double_t zLad2 = -zLad1;
2704         Double_t zLad3 = -zLad0;
2705         // rotLad->RotateZ(180.0);
2706         TGeoRotation   *rotLad = new TGeoRotation(*gGeoIdentity);
2707         TGeoCombiTrans *trLad0 = new TGeoCombiTrans(xLad, 0.0, zLad0, rotLad);
2708         TGeoCombiTrans *trLad1 = new TGeoCombiTrans(xLad, 0.0, zLad1, rotLad);
2709         TGeoCombiTrans *trLad2 = new TGeoCombiTrans(xLad, 0.0, zLad2, rotLad);
2710         TGeoCombiTrans *trLad3 = new TGeoCombiTrans(xLad, 0.0, zLad3, rotLad);
2711         // add to container
2712         container->AddNode(ladder, 0, trLad0);
2713         container->AddNode(ladder, 1, trLad1);
2714         container->AddNode(ladder, 2, trLad2);
2715         container->AddNode(ladder, 3, trLad3);
2716         
2717         // 3 - MCM (only the base, the cover is added as a separate 
2718         // volume in a more global 'stave' assembly volume (will be 
2719         // replicated twice)
2720         TGeoVolume *mcm = CreateMCMBase(mgr);
2721         // translations (in the X direction, MCM is at the same 
2722         // level as ladder) the two copies of the MCM are placed at 
2723         // the same distance from the center, on both sides and their 
2724         // sorting is the same as ladders' one (MCM0 is at Z < 0, 
2725         // MCM1 at Z > 0);
2726         Double_t xMCM  = xLad;
2727         Double_t yMCM  = 0.5*(fullHeight - mcmHeight);
2728         Double_t zMCM1 = zLad3 + 0.5*ladderWidth + 0.5*mcmWidth + sepMCMWidth;
2729         Double_t zMCM0 = -zMCM1;
2730         // create the common correction rotations
2731         TGeoRotation *rotCorr0 = new TGeoRotation(*gGeoIdentity);
2732         TGeoRotation *rotCorr1 = new TGeoRotation(*gGeoIdentity);
2733         rotCorr0->RotateY( 90.0);
2734         rotCorr1->RotateY(-90.0);
2735         TGeoCombiTrans *trMCM0 = new TGeoCombiTrans(xMCM,yMCM,zMCM0,rotCorr0);
2736         TGeoCombiTrans *trMCM1 = new TGeoCombiTrans(xMCM,yMCM,zMCM1,rotCorr1);
2737         // add to container
2738         container->AddNode(mcm, 0, trMCM0);
2739         container->AddNode(mcm, 1, trMCM1);
2740                 
2741         return container;
2742 }
2743 //______________________________________________________________________
2744 void AliITSv11GeometrySPD::StavesInSector(TGeoVolume *moth, TGeoManager *mgr){
2745         // Unification of essentially two methods:
2746         // - the one which creates the sector structure
2747         // - the one which returns the complete stave
2748         // ---
2749         // For compatibility, this method requires the same arguments
2750         // asked by "CarbonFiberSector" method, which is recalled here.
2751         // Like this cited method, this one does not return any value,
2752         // but it inserts in the mother volume (argument 'moth') all the stuff
2753         // which composes the complete SPD sector.
2754         // ---
2755         // Arguments: see description of "CarbonFiberSector" method.
2756         //
2757         
2758         // This service class is useful to this method only
2759         // to store in a meaningful way the data about the 
2760         // rounded corners of the support, and some computations
2761         // which could turn out to be useful for stave placement
2762         // 'left' and 'right' (L/R) here are considered looking the support
2763         // from the positive Z side.
2764         // The sign of the radius is used to know what kind of tangent
2765         // must be found for the two circles which describe the rounded angles.
2766         class clsSupportPlane {
2767         public:
2768                 // curvature center and radius (with sign) of left corner
2769                 Double_t xL, yL, rL, sL;
2770                 // curvature center and radius (with sign) of right corner
2771                 Double_t xR, yR, rR, sR;
2772                 // shift from the innermost position (where the stave edge is
2773                 // in the point where the rounded corner begins
2774                 Double_t shift;
2775                 
2776                 // Constructor with arguments which allow to set 
2777                 // directly everything since the values are given in 
2778                 // millimiters from drawings, they must be converted to cm
2779                 clsSupportPlane
2780                 (Double_t xLin, Double_t yLin, Double_t rLin, Double_t sLin, 
2781                  Double_t xRin, Double_t yRin, Double_t rRin, Double_t sRin,
2782                  Double_t shiftin) :
2783                  xL(xLin), yL(yLin), rL(rLin), sL(sLin), xR(xRin), yR(yRin), 
2784                  rR(rRin), sR(sRin), shift(shiftin) {
2785                         xL *= fgkmm;
2786                         yL *= fgkmm;
2787                         rL *= fgkmm;
2788                         xR *= fgkmm;
2789                         yR *= fgkmm;
2790                         rR *= fgkmm;
2791                         shift *= fgkmm;
2792                 } // end group.
2793                 
2794                 // Computation of the line tangent to both circles 
2795                 // defined here which is taken above or below the center 
2796                 // according to the radius sign. This method returns:
2797                 //   - the mid-popint of the segment between the two 
2798                 //     points where the tangent touches the two circles, 
2799                 //   - the inclination of this segment
2800                 //   - the half-length of this segment
2801                 Double_t TangentSegment(Double_t &midX, Double_t &midY, 
2802                                         Double_t &phi){
2803                         // compute the straight line which is tangent to 
2804                         // the two circles and extract its inclination 
2805                         // 'phi' w.r. to X axis
2806                         Double_t dx = xL - xR;
2807                         Double_t dy = yL - yR;
2808                         Double_t R  = rL*sL + rR*sR;
2809                         Double_t delta = dy*dy + dx*dx - R*R;
2810                         Double_t tan05phi = (-dy+TMath::Sqrt(delta))/(R - dx);
2811                         phi = 2.0 * TMath::ATan(tan05phi);
2812                         // compute the points where this line touchs the 
2813                         // two circles
2814                         Double_t leftX  = xL + sL*rL*TMath::Cos(phi);
2815                         Double_t leftY  = yL + sL*rL*TMath::Sin(phi);
2816                         Double_t rightX = xR + sR*rR*TMath::Cos(phi);
2817                         Double_t rightY = yR + sR*rR*TMath::Sin(phi);
2818                         // compute the mid point
2819                         midX = 0.5 * (leftX + rightX);
2820                         midY = 0.5 * (leftY + rightY);
2821                         // compute angular coefficient for the line joining
2822                         // the two points found using the above method
2823                         dx = rightX - leftX;
2824                         dy = rightY - leftY;
2825                         phi = TMath::ATan2(dy, dx);
2826                         // compute the half-length of this segment
2827                         Double_t len = 0.5*TMath::Sqrt((rightX-leftX)*
2828                                             (rightX-leftX) + (rightY-leftY)*
2829                                                              (rightY-leftY));
2830                         //MM                    cout << 2.0*len << endl;
2831                         return len;
2832                 } // end function
2833         }; // end class 
2834         // instantiate this class for each layer1 and layer2 corners
2835         clsSupportPlane *plane[6] = {0, 0, 0, 0, 0, 0};
2836         
2837         // layer 2
2838         plane[0] = new clsSupportPlane( 10.830,  16.858, 0.60,  1.,  19.544,  
2839                                         10.961, 0.8,  1.,  1.816);
2840         plane[1] = new clsSupportPlane(- 0.733,  17.486, 0.60,  1.,  11.581,  
2841                                        13.371, 0.6, -1., -0.610);
2842         plane[2] = new clsSupportPlane(-12.252,  16.298, 0.60,  1.,   0.562,  
2843                                        14.107, 0.6, -1., -0.610);
2844         plane[3] = new clsSupportPlane(-22.276,  12.948, 0.85,  1., -10.445,  
2845                                        13.162, 0.6, -1., -0.610);
2846         // layer 1
2847         plane[4] = new clsSupportPlane(- 3.123, -14.618, 0.50,  1.,  11.280, 
2848                                        -14.473, 0.9, -1., -0.691);
2849         plane[5] = new clsSupportPlane(-13.187, -19.964, 0.50, -1., - 3.833, 
2850                                        -17.805, 0.6, -1.,  1.300);
2851         // put the sector in the container
2852         //CarbonFiberSector(moth, xAAtubeCenter0, yAAtubeCenter0, mgr);
2853         
2854         // create stave volume
2855         Double_t staveHeight = 1.595, staveThickness;
2856         TGeoVolume *stave1 = CreateStave(1, staveThickness,mgr);
2857         TGeoVolume *stave2 = CreateStave(2, staveThickness,mgr);
2858                 
2859         // compute positions and rotation angles
2860         Double_t xm, ym, halfPlaneHeight, heightDiff, position, phi, xPos, yPos;
2861         for (Int_t i = 0; i < 6; i++) {
2862             //
2863             // This functioninserted here for test. Added By Bjorn Nilsen
2864             // August 29 2007.
2865             Double_t x0,y0,x1,y1; // should be move out of loop
2866             Bool_t lreturn;
2867             lreturn = GetSectorMountingPoints(i,x0,y0,x1,y1,mgr);
2868             //
2869                 // recall the geometry computations defined for the classe
2870                 halfPlaneHeight = plane[i]->TangentSegment(xm, ym, phi);
2871                 // compute the difference between plane and stave heights
2872                 heightDiff = halfPlaneHeight - 0.5*staveHeight;
2873                 // It is necessary to shift the stave by at least 
2874                 // an amount equal to this difference
2875                 // to avoid overlaps.
2876                 // Moreover, some more shift is done for building reasons,
2877                 // and it depends on the single plane (data-member 'shift')
2878                 position = heightDiff + plane[i]->shift;
2879                 // taking into account this shift plus another in the direction
2880                 // normal to the support plane, due to the stave thickness,
2881                 // the final position of the stave is computed in a temporary 
2882                 // reference frame where the mid-point of the support plane 
2883                 // is in the origin
2884                 if (i < 4) {
2885                         ParallelPosition(0.5*staveThickness, position, phi, 
2886                                          xPos, yPos);
2887                 }else if (i == 4) {
2888                         ParallelPosition(-0.5*staveThickness, -position, phi, 
2889                                          xPos, yPos);
2890                 }else {
2891                         ParallelPosition(-0.5*staveThickness, -position, phi, 
2892                                          xPos, yPos);
2893                 }
2894                 // then we go into the true reference frame
2895                 xPos += xm;
2896                 yPos += ym;
2897                 /*
2898                 // TEMP
2899                 TGeoVolume *tubeTemp1 = mgr->MakeTube("tubeTemp1", NULL, 
2900                                                           0.0, 0.01, 50.0);
2901                 TGeoTranslation *trTemp1 = new TGeoTranslation(xm, ym, 0.0);
2902                 tubeTemp1->SetLineColor(kRed);
2903                 moth->AddNode(tubeTemp1, i + 1, trTemp1);
2904                 TGeoVolume *tubeTemp2 = mgr->MakeTube("tubeTemp2", NULL, 
2905                                                             0.0, 0.01, 50.0);
2906                 TGeoTranslation *trTemp2 = new TGeoTranslation(xPos, yPos, 0.0);
2907                 tubeTemp2->SetLineColor(kBlue);
2908                 moth->AddNode(tubeTemp2, i + 1, trTemp2);
2909                 // END TEMP
2910                 */
2911                 // using the parameters found here, compute the 
2912                 // translation and rotation of this stave:
2913                 TGeoRotation *rot = new TGeoRotation(*gGeoIdentity);
2914                 if (i >= 4) rot->RotateY(180.0);
2915                 rot->RotateZ(90.0 + phi * TMath::RadToDeg());
2916                 TGeoCombiTrans *trans = new TGeoCombiTrans(xPos,yPos,0.0,rot);
2917                 if (i < 4) {
2918                         moth->AddNode(stave2, i, trans);
2919                 }else {
2920                         moth->AddNode(stave1, i - 4, trans);
2921                 } // end if i<4
2922         } // for i
2923 }
2924 //______________________________________________________________________
2925 void AliITSv11GeometrySPD::ParallelPosition(Double_t dist1, Double_t dist2, 
2926                                      Double_t phi, Double_t &x, Double_t &y){
2927         // Performs the following steps:
2928         // 1 - finds a straight line parallel to the one passing through 
2929         //     the origin and with angle 'phi' with X axis (phi in RADIANS);
2930         // 2 - finds another line parallel to the previous one, with a 
2931         //     distance 'dist1' from it
2932         // 3 - takes a reference point in the second line in the 
2933         //     intersection between the normal to both lines passing 
2934         //     through the origin
2935         // 4 - finds a point whith has distance 'dist2' from this 
2936         //     reference, in the second line (point 2)
2937         // ----
2938         // According to the signs given to dist1 and dist2, the point 
2939         // is found in different position w.r. to the origin
2940
2941         // compute the point
2942         Double_t cs = TMath::Cos(phi);
2943         Double_t sn = TMath::Sin(phi);
2944         
2945         x = dist2*cs - dist1*sn;
2946         y = dist1*cs + dist2*sn;
2947 }
2948 //----------------------------------------------------------------------
2949 Bool_t AliITSv11GeometrySPD::Make2DcrossSections(TPolyLine &a0,TPolyLine &a1,
2950                            TPolyLine &b0,TPolyLine &b1,TPolyMarker &p)const{
2951     // Fill the objects with the points representing
2952     // a0 the outer carbon fiber SPD sector shape Cross Section A
2953     // a1 the inner carbon fiber SPD sector shape Cross Section A
2954     // b0 the outer carbon fiber SPD sector shape Cross Section B
2955     // b1 the inner carbon fiber SPD sector shape Cross Section B
2956     //
2957     // Inputs:
2958     //   TPolyLine &a0   The outer carbon fiber SPD sector shape
2959     //   TPolyLine &a1   The Inner carbon fiber SPD sector shape
2960     //   TPolyLine &b0   The outer carbon fiber SPD sector shape
2961     //   TPolyLine &b1   The Inner carbon fiber SPD sector shape
2962     //   TPolyMarker &p  The points where the ladders are to be placed
2963     // Outputs:
2964     //   TPolyLine &a0   The shape filled with the points
2965     //   TPolyLine &a1   The shape filled with the points
2966     //   TPolyLine &b0   The shape filled with the points
2967     //   TPolyLine &b1   The shape filled with the points
2968     //   TPolyMarker &p  The filled array of points
2969     // Return:
2970     //     An error flag.
2971     Int_t n0,n1,i;
2972     Double_t x,y;
2973     TGeoVolume *a0V,*a1V,*b0V,*b1V;
2974     TGeoXtru *a0S,*a1S,*b0S,*b1S;
2975     TGeoManager *mgr = gGeoManager;
2976
2977     a0V = mgr->GetVolume(fSPDsectorShapeName.Data());
2978     a0S = dynamic_cast<TGeoXtru*>(a0V->GetShape());
2979     n0 = a0S->GetNvert();
2980     a0.SetPolyLine(n0+1);
2981     //for(i=0;i<fSPDsectorPoints0.GetSize();i++) 
2982     //  printf("%d %d %d\n",i,fSPDsectorPoints0[i],fSPDsectorPoints1[i]);
2983     for(i=0;i<n0;i++){
2984         x = a0S->GetX(i);
2985         y = a0S->GetY(i);
2986         //printf("%d %g %g\n",i,x,y);
2987         a0.SetPoint(i,x,y);
2988         if(i==0) a0.SetPoint(n0,x,y);
2989     } // end for i
2990     a1V = mgr->GetVolume("ITSSPDCarbonFiberSupportSectorAirA1");
2991     a1S = dynamic_cast<TGeoXtru*>(a1V->GetShape());
2992     n1 = a1S->GetNvert();
2993     a1.SetPolyLine(n1+1);
2994     for(i=0;i<n1;i++){
2995         x = a1S->GetX(i);
2996         y = a1S->GetY(i);
2997         a1.SetPoint(i,x,y);
2998         if(i==0) a1.SetPoint(n1,x,y);
2999     } // end for i
3000     // Cross Section B
3001     b0V = mgr->GetVolume("ITSSPDCarbonFiberSupportSectorEndB0");
3002     b0S = dynamic_cast<TGeoXtru*>(b0V->GetShape());
3003     n0 = b0S->GetNvert();
3004     b0.SetPolyLine(n0+1);
3005     for(i=0;i<n0;i++){
3006         x = b0S->GetX(i);
3007         y = b0S->GetY(i);
3008         b0.SetPoint(i,x,y);
3009         if(i==0) b0.SetPoint(n0,x,y);
3010     } // end for i
3011     b1V = mgr->GetVolume("ITSSPDCarbonFiberSupportSectorEndAirB1");
3012     b1S = dynamic_cast<TGeoXtru*>(b1V->GetShape());
3013     n1 = b1S->GetNvert();
3014     b1.SetPolyLine(n1+1);
3015     for(i=0;i<n1;i++){
3016         x = b1S->GetX(i);
3017         y = b1S->GetY(i);
3018         b1.SetPoint(i,x,y);
3019         if(i==0) b1.SetPoint(n1,x,y);
3020     } // end for i
3021     //
3022     Double_t x0,y0,x1,y1;
3023     p.SetPolyMarker(2*fSPDsectorPoints0.GetSize());
3024     for(i=0;i<fSPDsectorPoints0.GetSize();i++){
3025       GetSectorMountingPoints(i,x0,y0,x1,y1);
3026       p.SetPoint(2*i,x0,y0);
3027       p.SetPoint(2*i+1,x1,y1);
3028     } // end for i
3029     return kTRUE;
3030 }
3031