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