]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSv11GeometrySPD.cxx
Corrections for coding convenions violations
[u/mrichter/AliRoot.git] / ITS / AliITSv11GeometrySPD.cxx
1 /**************************************************************************
2  * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15 //
16 // This class Defines the Geometry for the ITS services and support cones
17 // outside of the ceneteral volume (except for the Ceneteral support 
18 // cylinders. Other classes define the rest of the ITS. Specificaly the ITS
19 // The SSD support cone, SSD Support centeral cylinder, SDD support cone,
20 // The SDD cupport centeral cylinder, the SPD Thermal Sheald, The supports
21 // and cable trays on both the RB26 (muon dump) and RB24 sides, and all of
22 // the cabling from the ladders/stave ends out past the TPC.
23 //
24
25 /* $Id$ */
26
27 // General Root includes
28 #include <Riostream.h>
29 #include <TMath.h>
30 #include <TLatex.h>
31 #include <TCanvas.h>
32 #include <TPolyLine.h>
33 // 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::CreateSPDCentralMaterials(Int_t &medOffset, Int_t &matOffset) const
60 {
61     // Define the specific materials used for the ITS SPD central
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::InitSPDCentral(Int_t offset,TVirtualMC *vmc) const {
236     // Do any SPD Central 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         // The sizes of the components come from drawings 
1076         // of the Technical office of INFN Padova.
1077         // Due to the requirement to specify the sensitive volume separately from the rest,
1078         // the sensor is implemented as the sum of a central sensitive part + a guard ring.
1079         // Also the bump-bondings are added in form of small cylinders.
1080         // ---
1081         // Arguments:
1082         //  - the layer which will own this ladder (MUST be 1 or 2)
1083         //  - the used TGeoManager
1084         // ---
1085         // Returns:
1086         //  - the container TGeoBBox (return value)
1087         //  - the size of the container box (arguments passed by reference)
1088         // ---
1089         // NOTE 1
1090         // Here and in the other methods which contribute to the stave definition
1091         // a convention is used for the naming of the three dimensions of the volumes:
1092         //  - 'length'    refers to the size in the Z direction of the ALICE reference frame
1093         //  - 'width'     refers to the "large" dimension orthogonal to Z axis in the local reference 
1094         //                frame of the object being implemented (e.g., 15.95 mm for the chips)
1095         //  - 'thickness' refers to the "small" dimension orthogonal to Z axis, which is also
1096         //                the direction along which the components are superimposed on each other
1097         // ---
1098         // NOTE 2
1099         // all sizes taken are expressed in mm in drawings, and this is kept as is, to avoid confusion
1100         // the conversion is made multiplying by the conversion factor
1101         //
1102         
1103         // ** CRITICAL CHECK **
1104         // layer number can be ONLY 1 or 2
1105         if (layer != 1 && layer != 2) AliFatal("Layer number MUST be 1 or 2");
1106         
1107         // instantiate all required media
1108         TGeoMedium *medAir       = mgr->GetMedium("Air");
1109         TGeoMedium *medSPDSiChip = mgr->GetMedium("SPD SI CHIP");
1110         TGeoMedium *medSi        = mgr->GetMedium("Si");
1111         TGeoMedium *medBumpBond  = mgr->GetMedium("BumpBond");
1112         
1113         // ** Define sizes **
1114         // they are expressed in mm in the drawings so they require conversion
1115         // 'length'    is in the direction of the detector length (Z axis)
1116         // 'thickness' is obvious
1117         // 'width'     is in the direction orthogonal to 'width' and 'thickness'
1118         
1119         // for the chip, also the spacing between them is required
1120         Double_t chipThickness  = fgkmm *  0.150;
1121         Double_t chipWidth      = fgkmm * 15.950;
1122         Double_t chipLength     = fgkmm * 13.600;
1123         Double_t chipSpacing    = fgkmm *  0.400;
1124         
1125         // for the sensor, we define the area of sensitive volume
1126         // while the guard ring is added as a separate piece
1127         Double_t sensThickness  = fgkmm *  0.200;
1128         Double_t sensLength     = fgkmm * 69.600;
1129         Double_t sensWidth      = fgkmm * 13.920;
1130         Double_t guardRingWidth = fgkmm *  0.560;
1131         
1132         // bump bond is defined as a small stripe of height = 0.012 mm
1133         // and a suitable width to keep the same volume it has 
1134         // before being compressed (a line of spheres of 0.025 mm radius)
1135         Double_t bbLength    = fgkmm * 0.042;
1136         Double_t bbWidth     = sensWidth;
1137         Double_t bbThickness = fgkmm * 0.012;
1138         Double_t bbPos       = 0.080;           // Z position w.r. to left pixel edge
1139                 
1140         // ** Create volumes **
1141         // the container is the return value, and is built as a box
1142         // whose edges exactly enclose the stuff we inserted here, filled with air.
1143         // Its name depends on the layer number.
1144         width = chipWidth;
1145         length = sensLength + 2.0*guardRingWidth;
1146         thickness = sensThickness + chipThickness + bbThickness;
1147         TGeoVolume *container = mgr->MakeBox(Form("LAY%d_LADDER", layer), medAir, 0.5*thickness, 0.5*width, 0.5*length);
1148         
1149         // the chip is a simple box:
1150         TGeoVolume *volChip = mgr->MakeBox("CHIP", medSPDSiChip, 0.5*chipThickness, 0.5*chipWidth, 0.5*chipLength);
1151         
1152         // the sensor is the union of a box and a border, to separate sensitive part from the rest
1153         // the sensitive volume (inner part) is named according to the owner layer.
1154         // To compute the shape subtraction which is needed for this we create two shapes,
1155         // which are two boxes with the same center.
1156         // The smaller one is then used to define the sensor, while the subtraction of the two
1157         // is used for the guard ring.
1158         TGeoBBox  *shSens = new TGeoBBox(0.5*sensThickness, 0.5*sensWidth, 0.5*sensLength);
1159         TGeoBBox  *shIn   = new TGeoBBox(sensThickness, 0.5*sensWidth, 0.5*sensLength);
1160         TGeoBBox  *shOut  = new TGeoBBox(0.5*sensThickness, 0.5*sensWidth + guardRingWidth, 0.5*sensLength + guardRingWidth);
1161         shIn->SetName("innerBox");
1162         shOut->SetName("outerBox");
1163         TGeoCompositeShape *shBorder = new TGeoCompositeShape("", "outerBox-innerBox");
1164         TGeoVolume *volSens = new TGeoVolume(Form("LAY%d_SENSOR", layer), shSens, medSi);
1165         TGeoVolume *volBorder = new TGeoVolume("GUARD_RING", shBorder, medSi);
1166         
1167         // one line of bumpbonds
1168         TGeoVolume *volBB = mgr->MakeBox("BB", medBumpBond, 0.5*bbThickness, 0.5*bbWidth, 0.5*bbLength);
1169                         
1170         // set colors of all objects for visualization  
1171         volSens->SetLineColor(kYellow + 1);
1172         volChip->SetLineColor(kGreen);
1173         volBorder->SetLineColor(kYellow + 3);
1174
1175         // translations for the chip box: direction of length and thickness (moved down)
1176         TGeoTranslation *trChip[5] = {0, 0, 0, 0, 0};
1177         Double_t x = 0.5 * (chipThickness - thickness);
1178         Double_t y = 0.0;
1179         Double_t z = 0.0;
1180         Int_t i;
1181         for (i = 0; i < 5; i++) {
1182                 z = -0.5*length + guardRingWidth + (Double_t)i*chipSpacing + ((Double_t)(i) + 0.5)*chipLength;
1183                 trChip[i] = new TGeoTranslation(x, y, z);
1184         }
1185         
1186         // translation for the sensor parts: direction of width (moved to edge of container) and thickness (moved up)
1187         x = 0.5 * (thickness - sensThickness);
1188         y = 0.5 * (width - sensWidth - 2.0*guardRingWidth);
1189         z = 0.0;
1190         TGeoTranslation *trSens = new TGeoTranslation(x, y, z);
1191         
1192         // translation for the bump bonds:
1193         // keep same y used for sensors, but change the Z
1194         TGeoTranslation *trBB[160];
1195         //x = 0.5 * (thickness - bbThickness) + 0.5*sensThickness;
1196         x = 0.5 * (thickness - bbThickness) - sensThickness;
1197         z = -0.5 * sensLength + guardRingWidth + fgkmm*0.425 - bbPos;
1198         for (i = 0; i < 160; i++) {
1199                 trBB[i] = new TGeoTranslation(x, y, z);
1200                 switch(i) {
1201                         case  31:
1202                         case  63:
1203                         case  95:
1204                         case 127:
1205                                 z += fgkmm * 0.625 + fgkmm * 0.2;
1206                                 break;
1207                         default:
1208                                 z += fgkmm * 0.425;
1209                 }
1210         }
1211                 
1212         // add nodes to container
1213         container->AddNode(volSens, 1, trSens);
1214         container->AddNode(volBorder, 1, trSens);
1215         for (i = 0; i < 160; i++) container->AddNode(volBB, i, trBB[i]);
1216         for (i = 0; i < 5; i++) container->AddNode(volChip, i + 2, trChip[i]);
1217         
1218         // return the container
1219         return container;
1220 }
1221
1222 /*
1223 //___________________________________________________________________________________________________________________
1224 TGeoVolume* AliITSv11GeometrySPD::CreateGroundingFoilSingle
1225 (Bool_t kaptonLayer, Double_t &length, Double_t &width, Double_t &thickness, TGeoManager *mgr)
1226 {
1227         //
1228         // Creates the grounding foil layer made in Kapton.
1229         // Both layers of the grounding foil have the same shape, but with small
1230         // differences in the size of some parts (holes, overall size).
1231         // The Kapton layer is a little bit wider and has smaller holes.
1232         // ---
1233         // The complete object is created as the superimposition of an XTRU with some holes
1234         // ---
1235         // Whenever possible, the size of the parts is parameterized with 
1236         // variable names, even if their value is fixed according 
1237         // to the design parameters given by engineers' drawings.
1238         // ---
1239         // Returns: a TGeoVolume object which contains all parts of this layer
1240         //
1241         
1242         // The shape of the grounding foil is an irregular polygon, which can easily be implemented as 
1243         // a TGeoXtru using the corners as reference points:
1244         // 
1245         // 0                                                                                                     1
1246         //  +---------------------------------------------------------------------------------------------------+
1247         //  |                                                            7              6      3                |
1248         //  |                                                            +--------------+      +----------------+ 2
1249         //  |                                                O           |              |      |
1250         //  |                                                    9 /-----+ 8            +------+ 4
1251         //  |                                                     /                    5
1252         //  |                                  11 /--------------/ 10
1253         //  +------------------------------------/ 
1254         // 13                                    12
1255         //
1256         // in total: 14 points (X is just a referencem but is unused in the implementation.
1257         // The whole shape can be subdivided into sectors delimited by vertical lines passing
1258         // througth the points in the lower part of the shape. This convention is used to names
1259         // their length which is different for each one (the widths, instead, are common for some)      
1260
1261         // instantiate the media:
1262         // - kapton/aluminum for the pysical volumes
1263         TGeoMedium *material = kaptonLayer ? mgr->GetMedium("KAPTON") : mgr->GetMedium("AL");
1264         
1265         // label
1266         char type[3];
1267         if (kaptonLayer) {
1268                 strcpy(type, "KP"); 
1269                 thickness = fgkmm * 0.05;
1270         }
1271         else {
1272                 strcpy(type, "AL");
1273                 thickness = fgkmm * 0.02;
1274         }
1275         
1276         // define the length of all sectors (from leftmost to rightmost)
1277         Int_t i;
1278         Double_t sectorLength[] = { 140.71,  2.48,  26.78,  4.00,  10.00,  24.40,  10.00,  24.81 };
1279         if (!kaptonLayer) {
1280                 sectorLength[0] -= 0.2;
1281                 sectorLength[4] -= 0.2;
1282                 sectorLength[5] += 0.4;
1283                 sectorLength[6] -= 0.4;
1284         }
1285         length = 0.0;
1286         for (i = 0; i < 8; i++) {
1287                 sectorLength[i] *= fgkmm;
1288                 length += sectorLength[i];
1289         }
1290                 
1291         // as shown in the drawing, we have three different widths in this shape:
1292         Double_t widthMax  = fgkmm * 15.95;
1293         Double_t widthMed1 = fgkmm * 15.00;
1294         Double_t widthMed2 = fgkmm * 11.00;
1295         Double_t widthMin  = fgkmm *  4.40;
1296         if (!kaptonLayer) {
1297                 widthMax  -= fgkmm * 0.4;
1298                 widthMed1 -= fgkmm * 0.4;
1299                 widthMed2 -= fgkmm * 0.4;
1300                 widthMin  -= fgkmm * 0.4;
1301         }
1302         width = widthMax;
1303         
1304         // the vertices of the polygon are arrays correctly ordered in the counterclockwise direction:
1305         // initially we place the point 0 in the origin, and all others will be defined accordingly
1306         Double_t x[14], y[14];
1307         x[ 0] = 0.0;
1308         y[ 0] = 0.0;
1309         
1310         x[ 1] = x[0] + length;
1311         y[ 1] = 0.0;
1312         
1313         x[ 2] = x[1];
1314         y[ 2] = -widthMin;
1315         
1316         x[ 3] = x[2] - sectorLength[7];
1317         y[ 3] = y[2];
1318         
1319         x[ 4] = x[3];
1320         y[ 4] = -widthMed2;
1321         
1322         x[ 5] = x[4] - sectorLength[6];
1323         y[ 5] = y[4];
1324         
1325         x[ 6] = x[5];
1326         y[ 6] = -widthMin;
1327         
1328         x[ 7] = x[6] - sectorLength[5];
1329         y[ 7] = y[6];
1330         
1331         x[ 8] = x[7];
1332         y[ 8] = -widthMed2;
1333         
1334         x[ 9] = x[8] - sectorLength[4];
1335         y[ 9] = y[8];
1336         
1337         x[10] = x[9] - sectorLength[3];
1338         y[10] = -widthMed1;
1339          
1340         x[11] = x[10] - sectorLength[2];
1341         y[11] = y[10];
1342         
1343         x[12] = x[11] - sectorLength[1];
1344         y[12] = -widthMax;
1345         
1346         x[13] = x[0];
1347         y[13] = -widthMax;
1348         
1349         // then, we shift all points in such a way that the origin will be at the centers
1350         for (i = 0; i < 14; i++) {
1351                 x[i] -= 0.5*length;
1352                 y[i] += 0.5*width;
1353         }
1354         
1355         // create the shape
1356         char shName[200];
1357         sprintf(shName, "SH_%sGFOIL_FULL", type);
1358         TGeoXtru *shGroundFull = new TGeoXtru(2);
1359         shGroundFull->SetName(shName);
1360         shGroundFull->DefinePolygon(14, x, y);
1361         shGroundFull->DefineSection(0, -0.5*thickness, 0., 0., 1.0);
1362         shGroundFull->DefineSection(1,  0.5*thickness, 0., 0., 1.0);
1363         
1364         // this volume contains some holes which are here implemented as simple boxes
1365         // of fixed size, which are displaced along the shape itself and then composed
1366         // using the facilities of the TGeo package
1367         
1368         Double_t holeLength = fgkmm * 10.00;
1369         Double_t holeWidth  = fgkmm *  7.50;
1370         Double_t holeSepX0  = fgkmm *  7.05;  // separation between center of first hole and left border
1371         Double_t holeSepXC  = fgkmm * 14.00;  // separation between the centers of two consecutive holes
1372         Double_t holeSepX1  = fgkmm * 15.42;  // separation between centers of 5th and 6th hole
1373         Double_t holeSepX2  = fgkmm * 22.00;  // separation between centers of 10th and 11th hole
1374         if (!kaptonLayer) {
1375                 holeSepX0  -= fgkmm * 0.2;
1376                 holeLength += fgkmm * 0.4;
1377                 holeWidth  += fgkmm * 0.4;
1378         }
1379         
1380         // X position of hole center (will change for each hole)
1381         Double_t holeX = -0.5*length;
1382         // Y position of center of all holes (= 4.4 mm from upper border)
1383         Double_t holeY = 0.5*(width - holeWidth) - widthMin;
1384         //if (!kaptonLayer) holeY += 0.02;
1385                 
1386         // create a shape for the holes (common)
1387         char holeName[200];
1388         sprintf(holeName, "%sHOLE", type);
1389         TGeoBBox *shHole = 0;
1390         shHole = new TGeoBBox(holeName, 0.5*holeLength, 0.5*holeWidth, thickness);
1391         
1392         // insert the holes in the XTRU shape:
1393         // starting from the first value of X, they are simply shifted along this axis
1394         char trName[200];
1395         TGeoTranslation *transHole[11];
1396         TString strComposite(shName);
1397         strComposite.Append("-(");
1398         for (Int_t i = 0; i < 11; i++) {
1399                 // set the position of the hole, depending on index
1400                 if (i == 0) {
1401                         holeX += holeSepX0;
1402                 }
1403                 else if (i < 4) {
1404                         holeX += holeSepXC;
1405                 }
1406                 else if (i == 4) {
1407                         holeX += holeSepX1;
1408                 }
1409                 else if (i < 10) {
1410                         holeX += holeSepXC;
1411                 }
1412                 else {
1413                         holeX += holeSepX2;
1414                 }
1415                 sprintf(trName, "%sTR%d", type, i);
1416                 transHole[i] = new TGeoTranslation(trName, holeX, holeY, 0.0);
1417                 transHole[i]->RegisterYourself();
1418                 strComposite.Append(holeName);
1419                 strComposite.Append(":");
1420                 strComposite.Append(trName);
1421                 if (i < 10) strComposite.Append("+");
1422                 //MM            cout << holeX << endl;
1423         }
1424         strComposite.Append(")");
1425         //MM    cout << strComposite.Data() << endl;
1426         
1427         // create composite shape (with holes)
1428         TGeoCompositeShape *shGround = new TGeoCompositeShape(Form("SH_%sGFOIL", type), strComposite.Data());
1429         
1430         // create the volume
1431         TGeoVolume *vol = new TGeoVolume(Form("%sGFOIL", type), shGround, material);
1432         return vol;
1433 }
1434 */
1435
1436 //___________________________________________________________________________________________________________________
1437 TGeoVolume* AliITSv11GeometrySPD::CreateGroundingFoilSingle
1438 (Bool_t kaptonLayer, Double_t &length, Double_t &width, Double_t &thickness, TGeoManager *mgr)
1439 {
1440         //
1441         // Creates the grounding foil layer made in Kapton.
1442         // Both layers of the grounding foil have the same shape, but with small
1443         // differences in the size of some parts (holes, overall size).
1444         // The Kapton layer is a little bit wider and has smaller holes.
1445         // ---
1446         // The complete object is created as the sum of the following parts:
1447         // 1) the part which is connected to the chips, which is a 
1448         //    simple BOX with some box-shaped holes at regular intervals
1449         // 2) a trapezoidal connection where the Y size changes
1450         // 3) another box with a unique hole of the same shape and size as above
1451         // 4) another trapezoidal connection where the Y size changes
1452         // 5) a final part which is built as a sequence of 4 BOX volumes
1453         //    where the first and the third are equal and the others have same size in Y.
1454         // ---
1455         // Whenever possible, the size of the parts is parameterized with 
1456         // variable names, even if their value is fixed according 
1457         // to the design parameters given by engineers' drawings.
1458         // ---
1459         // Returns: a TGeoVolume object which contanis all parts of this layer
1460         //
1461
1462         // instantiate the media:
1463         // - vacuum for the container volume
1464         // - kapton for the pysical volumes
1465         TGeoMedium *vacuum   = mgr->GetMedium("VACUUM");
1466         TGeoMedium *material = mgr->GetMedium("KAPTON");
1467         
1468         // === Define size of all elements ===
1469         Double_t sizeZ      = fgkmm *   0.05;
1470         
1471         Double_t part1X     = fgkmm * 140.71;
1472         Double_t part2X     = fgkmm *   2.48;
1473         Double_t part3X     = fgkmm *  26.78;
1474         Double_t part4X     = fgkmm *   4.00;
1475         Double_t part5X     = fgkmm *  10.00;
1476         Double_t part6X     = fgkmm *  24.40;
1477         Double_t part7X     = fgkmm *  10.00;
1478         Double_t part8X     = fgkmm *  24.81;
1479         
1480         Double_t sizeYMax   = fgkmm *  15.95;
1481         Double_t sizeYMed1  = fgkmm *  15.00;
1482         Double_t sizeYMed2  = fgkmm *  11.00;
1483         Double_t sizeYMin   = fgkmm *   4.40;
1484         
1485         Double_t holeX      = fgkmm *  10.00;
1486         Double_t holeY      = fgkmm *   7.50;
1487         Double_t holeSepX   = fgkmm *  14.00;  // separation between the centers of two consecutive holes
1488         Double_t holeSepX1  = fgkmm *   1.42;  // to be added after 4th hole in volume 1
1489         Double_t holeFirstX = fgkmm *   7.05;  // position of center of first hole
1490         Double_t holeSepY   = fgkmm *   4.40;  // dist between hole's and volume's upper border
1491         Double_t holeAloneX = fgkmm *  13.28;  // position of hole center in box "part 3"
1492         
1493         // correct data in case we are on Aluminum foil
1494         if (!kaptonLayer) {
1495                 material = mgr->GetMedium("AL");
1496                 sizeZ       = fgkmm * 0.02;
1497                 part1X     -= fgkmm * 0.2;
1498                 part5X     -= fgkmm * 0.2;
1499                 part6X     += fgkmm * 0.4;
1500                 part7X     -= fgkmm * 0.4;
1501                         
1502                 sizeYMax   -= fgkmm * 0.4;
1503                 sizeYMed1  -= fgkmm * 0.4;
1504                 sizeYMed2  -= fgkmm * 0.4;
1505                 sizeYMin   -= fgkmm * 0.4;
1506         
1507                 holeX      += fgkmm * 0.4;
1508                 holeY      += fgkmm * 0.4;
1509                 holeFirstX -= fgkmm * 0.2;
1510                 holeSepY   -= fgkmm * 0.4;
1511         }
1512         
1513         // define names for the object
1514         char type[4];
1515         if (kaptonLayer) strcpy(type, "KAP"); else strcpy(type, "ALU");
1516         
1517         // compute full length and width
1518         length = part1X + part2X + part3X + part4X + part5X + part6X + part7X + part8X;
1519         width = sizeYMax;
1520         thickness = sizeZ;
1521                 
1522         // grounding foil world, bounded exactly around the limits of the structure
1523         TGeoVolume *container = mgr->MakeBox(Form("GFOIL_%s", type), vacuum, 0.5*length, 0.5*sizeYMax, 0.5*sizeZ);
1524         
1525         // === PART 1: box with holes ===
1526         
1527         TGeoBBox *shBox1 = 0, *shHole = 0;
1528         shBox1 = new TGeoBBox(Form("GF%s_BOX1", type), 0.5*part1X, 0.5*sizeYMax, 0.5*sizeZ);
1529         shHole = new TGeoBBox(Form("GF%s_HOLE", type), 0.5*holeX, 0.5*holeY, 0.5*sizeZ + 0.01);
1530         
1531         // define the position of all holes and compose the expression
1532         // to define the composite shape (box - holes)
1533         Double_t firstX = -0.5*part1X + holeFirstX;
1534         Double_t transY =  0.5*sizeYMax - holeSepY - 0.5*holeY;
1535         Double_t transX;
1536         TGeoTranslation *transHole[10];
1537         TString strComposite(Form("%s - (", shBox1->GetName()));
1538         for (Int_t i = 0; i < 10; i++) {
1539                 transX = firstX + (Double_t)i * holeSepX;
1540                 if (i > 4) transX += holeSepX1;
1541                 transHole[i] = new TGeoTranslation(Form("TGF%s_HOLE%d", type, i), transX, transY, 0.0);
1542                 transHole[i]->RegisterYourself();
1543                 strComposite.Append(Form("%s:%s", shHole->GetName(), transHole[i]->GetName()));
1544                 if (i < 9) strComposite.Append("+"); else strComposite.Append(")");
1545 }
1546         // create composite shape
1547         TGeoCompositeShape *shPart1 = new TGeoCompositeShape(Form("GF%s_PART1_SHAPE", type), strComposite.Data());
1548         // create the volume
1549         TGeoVolume *volPart1 = new TGeoVolume(Form("GF%s_PART1", type), shPart1, material);
1550         
1551         // === PART 2: first trapezoidal connection
1552         
1553         TGeoArb8 *shTrap1 = new TGeoArb8(0.5*sizeZ);
1554         shTrap1->SetVertex(0, -0.5*part2X,  0.5*sizeYMax);
1555         shTrap1->SetVertex(1,  0.5*part2X,  0.5*sizeYMax);
1556         shTrap1->SetVertex(2,  0.5*part2X,  0.5*sizeYMax - sizeYMed1);
1557         shTrap1->SetVertex(3, -0.5*part2X, -0.5*sizeYMax);
1558         shTrap1->SetVertex(4, -0.5*part2X,  0.5*sizeYMax);
1559         shTrap1->SetVertex(5,  0.5*part2X,  0.5*sizeYMax);
1560         shTrap1->SetVertex(6,  0.5*part2X,  0.5*sizeYMax - sizeYMed1);
1561         shTrap1->SetVertex(7, -0.5*part2X, -0.5*sizeYMax);
1562         TGeoVolume *volPart2 = new TGeoVolume(Form("GF%s_PART2", type), shTrap1, material);
1563         
1564         // === PART 3: other box with one hole
1565         
1566         TGeoBBox *shBox2 = 0;
1567         shBox2 = new TGeoBBox(Form("GF%s_BOX2", type), 0.5*part3X, 0.5*sizeYMed1, 0.5*sizeZ);
1568                 
1569         // define the position of the hole
1570         transX = holeAloneX - 0.5*part3X;
1571         TGeoTranslation *transHoleAlone = new TGeoTranslation(Form("TGF%s_HOLE_ALONE", type), transX, transY, 0.0);
1572         transHoleAlone->RegisterYourself();
1573         // create composite shape
1574         TGeoCompositeShape *shPart3 = new TGeoCompositeShape(Form("GF%sPART3_SHAPE", type), Form("%s - %s:%s", shBox2->GetName(), shHole->GetName(), transHoleAlone->GetName()));
1575         // create the volume
1576         TGeoVolume *volPart3 = new TGeoVolume(Form("GF%s_PART3", type), shPart3, material);
1577                 
1578         // === PART 4: second trapezoidal connection
1579         
1580         TGeoArb8 *shTrap2 = new TGeoArb8(0.5*sizeZ);
1581         shTrap2->SetVertex(0, -0.5*part4X,  0.5*sizeYMed1);
1582         shTrap2->SetVertex(1,  0.5*part4X,  0.5*sizeYMed1);
1583         shTrap2->SetVertex(2,  0.5*part4X,  0.5*sizeYMed1 - sizeYMed2);
1584         shTrap2->SetVertex(3, -0.5*part4X, -0.5*sizeYMed1);
1585         shTrap2->SetVertex(4, -0.5*part4X,  0.5*sizeYMed1);
1586         shTrap2->SetVertex(5,  0.5*part4X,  0.5*sizeYMed1);
1587         shTrap2->SetVertex(6,  0.5*part4X,  0.5*sizeYMed1 - sizeYMed2);
1588         shTrap2->SetVertex(7, -0.5*part4X, -0.5*sizeYMed1);
1589         TGeoVolume *volPart4 = new TGeoVolume(Form("GF%s_PART4", type), shTrap2, material);
1590                 
1591         // === PART 5 --> 8: sequence of boxes ===
1592         
1593         TGeoVolume *volPart5 = mgr->MakeBox(Form("GF%s_BOX3", type), material, 0.5*part5X, 0.5*sizeYMed2, 0.5*sizeZ);
1594         TGeoVolume *volPart6 = mgr->MakeBox(Form("GF%s_BOX4", type), material, 0.5*part6X, 0.5*sizeYMin , 0.5*sizeZ);
1595         TGeoVolume *volPart7 = mgr->MakeBox(Form("GF%s_BOX5", type), material, 0.5*part7X, 0.5*sizeYMed2, 0.5*sizeZ);
1596         TGeoVolume *volPart8 = mgr->MakeBox(Form("GF%s_BOX6", type), material, 0.5*part8X, 0.5*sizeYMin , 0.5*sizeZ);
1597         
1598         // === SET COLOR ===
1599         if (kaptonLayer) {
1600                 volPart1->SetLineColor(kRed + 3);
1601                 volPart2->SetLineColor(kRed + 3);
1602                 volPart3->SetLineColor(kRed + 3);
1603                 volPart4->SetLineColor(kRed + 3);
1604                 volPart5->SetLineColor(kRed + 3);
1605                 volPart6->SetLineColor(kRed + 3);
1606                 volPart7->SetLineColor(kRed + 3);
1607                 volPart8->SetLineColor(kRed + 3);
1608         }
1609         else {
1610                 volPart1->SetLineColor(kGreen);
1611                 volPart2->SetLineColor(kGreen);
1612                 volPart3->SetLineColor(kGreen);
1613                 volPart4->SetLineColor(kGreen);
1614                 volPart5->SetLineColor(kGreen);
1615                 volPart6->SetLineColor(kGreen);
1616                 volPart7->SetLineColor(kGreen);
1617                 volPart8->SetLineColor(kGreen);
1618         }
1619                 
1620         // === TRANSLATION OF ALL PARTS ===
1621         
1622         transX = 0.5*(part1X - length);
1623         TGeoTranslation *transPart1 = new TGeoTranslation(transX, 0.0, 0.0);
1624         transX += 0.5*(part1X + part2X);
1625         TGeoTranslation *transPart2 = new TGeoTranslation(transX, 0.0, 0.0);
1626         transX += 0.5*(part2X + part3X);
1627         transY  = 0.5*(sizeYMax - sizeYMed1);
1628         TGeoTranslation *transPart3 = new TGeoTranslation(transX, transY, 0.0);
1629         transX += 0.5*(part3X + part4X);
1630         TGeoTranslation *transPart4 = new TGeoTranslation(transX, transY, 0.0);
1631         transX += 0.5*(part4X + part5X);
1632         transY  = 0.5*(sizeYMax - sizeYMed2);
1633         TGeoTranslation *transPart5 = new TGeoTranslation(transX, transY, 0.0);
1634         transX += 0.5*(part5X + part6X);
1635         transY  = 0.5*(sizeYMax - sizeYMin);
1636         TGeoTranslation *transPart6 = new TGeoTranslation(transX, transY, 0.0);
1637         transX += 0.5*(part6X + part7X);
1638         transY  = 0.5*(sizeYMax - sizeYMed2);
1639         TGeoTranslation *transPart7 = new TGeoTranslation(transX, transY, 0.0);
1640         transX += 0.5*(part7X + part8X);
1641         transY  = 0.5*(sizeYMax - sizeYMin);
1642         TGeoTranslation *transPart8 = new TGeoTranslation(transX, transY, 0.0);
1643         
1644         // add the partial volumes to the container
1645         container->AddNode(volPart1, 1, transPart1);
1646         container->AddNode(volPart2, 2, transPart2);
1647         container->AddNode(volPart3, 3, transPart3);
1648         container->AddNode(volPart4, 4, transPart4);
1649         container->AddNode(volPart5, 5, transPart5);
1650         container->AddNode(volPart6, 6, transPart6);
1651         container->AddNode(volPart7, 7, transPart7);
1652         container->AddNode(volPart8, 8, transPart8);
1653                         
1654         return container;
1655 }
1656
1657 //___________________________________________________________________________________________________________________
1658 TGeoVolume* AliITSv11GeometrySPD::CreateGroundingFoil(Double_t &thickness, TGeoManager *mgr)
1659 {
1660         //
1661         // Joins two Kapton and two Aluminum layers of the grounding foil
1662         // in order to create the complete grounding foil for a whole stave.
1663         // into a unique container volume, which is returned as output.
1664         // The use of the TGeoXtru shape requires that in the separate foils, the Z axis
1665         // lies perpendicularly to the polygonal basis of this shape; this caused the components
1666         // to have their Z axis corresponding to the X axis of the ALICE reference frame and 
1667         // vieceversa; to correct this, a rotation is necessary around their middle axis, 
1668         // to exchange X and Z axes and displace the object correctly in the ALICE frame.
1669         // ---
1670         // Arguments:
1671         //  - the sizes of the container box (passed by reference and filled here)
1672         //  - the TGeoManager
1673         // ---
1674         // Returns: 
1675         //  - the container TGeoBBox (return value)
1676         //  - the size of the container (reference variables)
1677         //
1678         
1679         // sizes of the added volumes, which are filled by passing them 
1680         // to the volume creation methods
1681         Double_t kpLength, kpWidth, kpThick;
1682         Double_t alLength, alWidth, alThick;
1683         Double_t separation = fgkmm * 1.42;  // separation between left and right volumes
1684         
1685         // create the two component volumes (each one will be replicated twice)
1686         // this gives also the size of their virtual container boxes (just a reference, not a volume)
1687         TGeoVolume *kVol = CreateGroundingFoilSingle(kTRUE, kpLength, kpWidth, kpThick, mgr);
1688         TGeoVolume *aVol = CreateGroundingFoilSingle(kFALSE, alLength, alWidth, alThick, mgr);
1689         kVol->SetLineColor(kRed);
1690         aVol->SetLineColor(kGray);
1691         
1692         // kapton leads the total size of the foil (including spagcing of 1.42 mm between them in the center)
1693         Double_t length, width;
1694         length    = 2.0 * kpLength + separation;
1695         width     = kpWidth;
1696         thickness = kpThick + alThick;
1697         
1698         // create the container
1699         TGeoMedium *vacuum = mgr->GetMedium("VACUUM");
1700         TGeoVolume *container = mgr->MakeBox("GFOIL", vacuum, 0.5*thickness, 0.5*width, 0.5*length);
1701         
1702         // create the common correction rotations
1703         TGeoRotation *rotCorr1 = new TGeoRotation(*gGeoIdentity);
1704         TGeoRotation *rotCorr2 = new TGeoRotation(*gGeoIdentity);
1705         rotCorr1->RotateY(-90.0);
1706         rotCorr2->RotateY( 90.0);
1707                 
1708         // compute the translations to place the objects at the edges of the volume
1709         // the kapton foils are also shifted down, and the aluminum foils are shifted up
1710         // with respect to the thickness direction
1711         TGeoTranslation *kTrans1 = new TGeoTranslation(0.5*(-thickness + kpThick), 0.0, 0.5*( length - kpLength));
1712         TGeoTranslation *kTrans2 = new TGeoTranslation(0.5*(-thickness + kpThick), 0.0, 0.5*(-length + kpLength));
1713         TGeoTranslation *aTrans1 = new TGeoTranslation(0.5*( thickness - alThick), 0.0, 0.5*( length - alLength) - 0.02);
1714         TGeoTranslation *aTrans2 = new TGeoTranslation(0.5*( thickness - alThick), 0.0, 0.5*(-length + alLength) + 0.02);
1715         
1716         // combine translations and rotations
1717         TGeoCombiTrans *kCombi1 = new TGeoCombiTrans(*kTrans1, *rotCorr1);
1718         TGeoCombiTrans *kCombi2 = new TGeoCombiTrans(*kTrans2, *rotCorr2);
1719         TGeoCombiTrans *aCombi1 = new TGeoCombiTrans(*aTrans1, *rotCorr1);
1720         TGeoCombiTrans *aCombi2 = new TGeoCombiTrans(*aTrans2, *rotCorr2);
1721                 
1722         // add to container
1723         container->AddNode(kVol, 0, kCombi1);
1724         container->AddNode(kVol, 1, kCombi2);
1725         container->AddNode(aVol, 0, aCombi1);
1726         container->AddNode(aVol, 1, aCombi2);
1727         
1728         return container;
1729 }
1730
1731 //______________________________________________________________________
1732 TGeoVolume* AliITSv11GeometrySPD::CreateMCMBase(TGeoManager *geom) const
1733 {
1734         //
1735         // Creates the MCM basis volume.
1736         // It is a little bit more complicated because this is a plain base
1737         // with a poly shape similar to the one of grounding foil but there are also
1738         // some chips glued to its base and covered with a cave cap.
1739         // ---
1740         // The complete MCM object is created as the sum of the following parts:
1741         // 1) a planar basis shaped according to the MCM typical shape
1742         // 2) some boxes which represent the chips and devices mounted on this base
1743         // 3) a cave cap which covers the portion of MCM containing these chips
1744         // ---
1745         // Due to the different widths of MCM, it is implemented in a more complicated way:
1746         // - cap and chips will define a sub-volume of this structure, which can be bounded
1747         //   by a complete box
1748         // - base of MCM will be a separate volume
1749         // - these two objects will need to be glued together into an upper-level volume
1750         // ---
1751         // This metod creates only the thin base (point 1 in the list)
1752         //
1753         
1754         // medium
1755         TGeoMedium *medBase = geom->GetMedium("MCM BASE");
1756         
1757         // parameterize the interesting sizes of MCM
1758         // it is divided into 3 sectors which have different size in X and Y and 
1759         // are connected by trapezoidal-based shapes, where the oblique angle
1760         // makes a 45 degrees angle with the vertical, so that the X size and Y size
1761         // of these "intermezzo"'s is the same
1762         // +--------------------------------+
1763         // |                   sect 2       |
1764         // | sect 1     --------------------+
1765         // +-----------/
1766         Double_t sizeZ = fgkmm * 0.35;
1767         Double_t sizeXtot = fgkmm * 105.6;
1768         Double_t sizeXsector[3] = {fgkmm * 28.4, fgkmm * 41.4, fgkmm * 28.8};
1769         Double_t sizeYsector[3] = {fgkmm * 15.0, fgkmm * 11.0, fgkmm *  8.0};
1770         Double_t sizeSep01 = fgkmm * 4.0, sizeSep12 = fgkmm * 3.0;
1771         Double_t sizeHole = fgkmm * 1.0;
1772         Double_t posHoleX = fgkmm * -0.5*sizeXtot + 26.7 + 0.5*sizeHole;
1773         Double_t posHoleY = fgkmm * -0.5*sizeYsector[0] + 0.5*sizeHole;
1774         
1775         // define the shape of base volume as an XTRU with two identical faces 
1776         // distantiated by the width of the  itself
1777         Double_t x[8], y[8];
1778         x[0] = -0.5*sizeXtot;
1779         y[0] =  0.5*sizeYsector[0];
1780         x[1] = -x[0];
1781         y[1] =  y[0];
1782         x[2] =  x[1];
1783         y[2] =  y[1] - sizeYsector[2];
1784         x[3] =  x[2] - sizeXsector[2];
1785         y[3] =  y[2];
1786         x[4] =  x[3] - sizeSep12;
1787         y[4] =  y[3] - sizeSep12;
1788         x[5] =  x[4] - sizeXsector[1];
1789         y[5] =  y[4];
1790         x[6] =  x[5] - sizeSep01;
1791         y[6] =  y[5] - sizeSep01;
1792         x[7] =  x[0];
1793         y[7] = -y[0];
1794         
1795         // create shape
1796         TGeoXtru *shPoly = new TGeoXtru(2);
1797         shPoly->SetName("SH_MCMBASE_POLY");
1798         shPoly->DefinePolygon(8, x, y);
1799         shPoly->DefineSection(0, -0.5*sizeZ, 0., 0., 1.0);
1800         shPoly->DefineSection(1,  0.5*sizeZ, 0., 0., 1.0);
1801         
1802         // create small hole
1803         TGeoBBox *shHole = 0;
1804         shHole = new TGeoBBox("SH_MCMBASE_HOLE", 0.5*sizeHole, 0.5*sizeHole, 0.5*sizeZ+0.01);
1805         TGeoTranslation *transHole = new TGeoTranslation("TR_MCMBASE_HOLE", posHoleX, posHoleY, 0.0);
1806         transHole->RegisterYourself(); 
1807         
1808         // create shape intersection
1809         TGeoCompositeShape *shBase = new TGeoCompositeShape("SH_MCMBASE", "SH_MCMBASE_POLY - SH_MCMBASE_HOLE:TR_MCMBASE_HOLE");
1810         
1811         // create volume
1812         TGeoVolume *volBase = new TGeoVolume("VOL_MCMBASE", shBase, medBase);
1813         volBase->SetLineColor(kRed);
1814         
1815         return volBase;
1816 }
1817
1818
1819 //______________________________________________________________________
1820 TGeoVolume* AliITSv11GeometrySPD::CreateMCMCoverBorder(TGeoManager *geom)
1821 {
1822         //
1823         // Creates the MCM basis volume.
1824         // It is a little bit more complicated because this is a plain base
1825         // with a poly shape similar to the one of grounding foil but there are also
1826         // some chips glued to its base and covered with a cave cap.
1827         // ---
1828         // The complete MCM object is created as the sum of the following parts:
1829         // 1) a planar basis shaped according to the MCM typical shape
1830         // 2) some boxes which represent the chips and devices mounted on this base
1831         // 3) a cave cap which covers the portion of MCM containing these chips
1832         // ---
1833         // Due to the different widths of MCM, it is implemented in a more complicated way:
1834         // - cap and chips will define a sub-volume of this structure, which can be bounded
1835         //   by a complete box
1836         // - base of MCM will be a separate volume
1837         // - these two objects will need to be glued together into an upper-level volume
1838         // ---
1839         // This metod creates the thicker cap and its contents (points 2-3 in the list).
1840         // Since it covers only two of the three sectors of the MCM base with different width
1841         // the computations and variables related to the largest sector are removed, while
1842         // the other are the same as the other part of the MCM.
1843         //
1844         
1845         // media
1846         TGeoMedium *medCap  = geom->GetMedium("MCM COVER");
1847         
1848         // parameterize the interesting sizes of MCM
1849         // it is divided into 3 sectors which have different size in X and Y and 
1850         // are connected by trapezoidal-based shapes, where the oblique angle
1851         // makes a 45 degrees angle with the vertical, so that the X size and Y size
1852         // of these "intermezzo"'s is the same
1853         // +--------------------------------+
1854         // |                   sect 2       |
1855         // | sect 1     --------------------+
1856         // +-----------/
1857         Double_t sizeZ = fgkmm * 0.3;
1858         Double_t capHeight = fgkmm * 1.7 - sizeZ;
1859         Double_t sizeXtot = fgkmm * 73.2;
1860         Double_t sizeXsector[2] = {fgkmm * 41.4, fgkmm * 28.8};
1861         Double_t sizeYsector[2] = {fgkmm * 11.0, fgkmm *  8.0};
1862         Double_t sizeSep = fgkmm * 3.0;
1863         
1864         // === PART 1: border ===
1865         
1866         // define the shape of base volume as an XTRU with two identical faces 
1867         // distantiated by the width of the  itself
1868         Double_t x[6], y[6];
1869         x[0] = -0.5*sizeXtot;
1870         y[0] =  0.5*sizeYsector[0];
1871         x[1] = -x[0];
1872         y[1] =  y[0];
1873         x[2] =  x[1];
1874         y[2] =  y[1] - sizeYsector[1];
1875         x[3] =  x[2] - sizeXsector[1];
1876         y[3] =  y[2];
1877         x[4] =  x[3] - sizeSep;
1878         y[4] =  y[3] - sizeSep;
1879         x[5] =  x[0];
1880         y[5] = -y[0];
1881         
1882         // create outer border shape with above coordinates
1883         TGeoXtru *capOut = new TGeoXtru(2);
1884         capOut->SetName("SH_MCMCAPOUT");
1885         capOut->DefinePolygon(6, x, y);
1886         capOut->DefineSection(0, -0.5*capHeight, 0., 0., 1.0);
1887         capOut->DefineSection(1,  0.5*capHeight, 0., 0., 1.0);
1888         
1889         // the inner border is built similarly but subtracting the thickness
1890         Double_t angle = 45.0;
1891         Double_t cs = TMath::Cos( 0.5*(TMath::Pi() - angle*TMath::DegToRad()) );
1892         Double_t xin[6], yin[6];
1893         xin[0] = x[0] + sizeZ;
1894         yin[0] = y[0] - sizeZ;
1895         xin[1] = x[1] - sizeZ;
1896         yin[1] = yin[0];
1897         xin[2] = xin[1];
1898         yin[2] = y[2] + sizeZ;
1899         xin[3] = x[3] - sizeZ*cs;
1900         yin[3] = yin[2];
1901         xin[4] = xin[3] - sizeSep;
1902         yin[4] = y[4] + sizeZ;
1903         xin[5] = xin[0];
1904         yin[5] = yin[4];
1905                 
1906         // create inner border shape
1907         TGeoXtru *capIn = new TGeoXtru(2);
1908         capIn->SetName("SH_MCMCAPIN");
1909         capIn->DefinePolygon(6, xin, yin);
1910         capIn->DefineSection(0, -0.5*capHeight-0.01, 0., 0., 1.0);
1911         capIn->DefineSection(1,  0.5*capHeight+0.01, 0., 0., 1.0);
1912         
1913         // compose shape
1914         TGeoCompositeShape *shBorder = new TGeoCompositeShape("SH_MCMCAPBORDER", "SH_MCMCAPOUT-SH_MCMCAPIN");
1915         
1916         // create volume
1917         TGeoVolume *volBorder = new TGeoVolume("VOL_MCMCAPBORDER", shBorder, medCap);
1918         volBorder->SetLineColor(kGreen);
1919         
1920         return volBorder;
1921 }
1922
1923 //______________________________________________________________________
1924 TGeoVolume* AliITSv11GeometrySPD::CreateMCMCoverTop(TGeoManager *geom)
1925 {
1926         //
1927         // Creates the MCM basis volume.
1928         // It is a little bit more complicated because this is a plain base
1929         // with a poly shape similar to the one of grounding foil but there are also
1930         // some chips glued to its base and covered with a cave cap.
1931         // ---
1932         // The complete MCM object is created as the sum of the following parts:
1933         // 1) a planar basis shaped according to the MCM typical shape
1934         // 2) some boxes which represent the chips and devices mounted on this base
1935         // 3) a cave cap which covers the portion of MCM containing these chips
1936         // ---
1937         // Due to the different widths of MCM, it is implemented in a more complicated way:
1938         // - cap and chips will define a sub-volume of this structure, which can be bounded
1939         //   by a complete box
1940         // - base of MCM will be a separate volume
1941         // - these two objects will need to be glued together into an upper-level volume
1942         // ---
1943         // This metod creates the thicker cap and its contents (points 2-3 in the list).
1944         // Since it covers only two of the three sectors of the MCM base with different width
1945         // the computations and variables related to the largest sector are removed, while
1946         // the other are the same as the other part of the MCM.
1947         //
1948         
1949         // media
1950         TGeoMedium *medCap  = geom->GetMedium("MCM COVER");
1951         
1952         // parameterize the interesting sizes of MCM
1953         // it is divided into 3 sectors which have different size in X and Y and 
1954         // are connected by trapezoidal-based shapes, where the oblique angle
1955         // makes a 45 degrees angle with the vertical, so that the X size and Y size
1956         // of these "intermezzo"'s is the same
1957         // +--------------------------------+
1958         // |                   sect 2       |
1959         // | sect 1     --------------------+
1960         // +-----------/
1961         Double_t sizeZ = fgkmm * 0.3;
1962         Double_t sizeXtot = fgkmm * 73.2;
1963         Double_t sizeXsector[2] = {fgkmm * 41.4, fgkmm * 28.8};
1964         Double_t sizeYsector[2] = {fgkmm * 11.0, fgkmm *  8.0};
1965         Double_t sizeSep = fgkmm * 3.0;
1966         
1967         // === PART 1: border ===
1968         
1969         // define the shape of base volume as an XTRU with two identical faces 
1970         // distantiated by the width of the  itself
1971         Double_t x[6], y[6];
1972         x[0] = -0.5*sizeXtot;
1973         y[0] =  0.5*sizeYsector[0];
1974         x[1] = -x[0];
1975         y[1] =  y[0];
1976         x[2] =  x[1];
1977         y[2] =  y[1] - sizeYsector[1];
1978         x[3] =  x[2] - sizeXsector[1];
1979         y[3] =  y[2];
1980         x[4] =  x[3] - sizeSep;
1981         y[4] =  y[3] - sizeSep;
1982         x[5] =  x[0];
1983         y[5] = -y[0];
1984         
1985         // create outer border shape with above coordinates
1986         TGeoXtru *capOut = new TGeoXtru(2);
1987         capOut->SetName("SH_MCMCAPOUT");
1988         capOut->DefinePolygon(6, x, y);
1989         capOut->DefineSection(0, -0.5*sizeZ, 0., 0., 1.0);
1990         capOut->DefineSection(1,  0.5*sizeZ, 0., 0., 1.0);
1991         
1992         // the inner border is built similarly but subtracting the thickness
1993         Double_t angle = 45.0;
1994         Double_t cs = TMath::Cos( 0.5*(TMath::Pi() - angle*TMath::DegToRad()) );
1995         Double_t xin[6], yin[6];
1996         xin[0] = x[0] + sizeZ;
1997         yin[0] = y[0] - sizeZ;
1998         xin[1] = x[1] - sizeZ;
1999         yin[1] = yin[0];
2000         xin[2] = xin[1];
2001         yin[2] = y[2] + sizeZ;
2002         xin[3] = x[3] - sizeZ*cs;
2003         yin[3] = yin[2];
2004         xin[4] = xin[3] - sizeSep;
2005         yin[4] = y[4] + sizeZ;
2006         xin[5] = xin[0];
2007         yin[5] = yin[4];
2008                 
2009         // coverage of upper part (equal to external border, but full)
2010         TGeoXtru *shCover = new TGeoXtru(2);
2011         shCover->SetName("SH_MCMCAPCOVER");
2012         shCover->DefinePolygon(6, x, y);
2013         shCover->DefineSection(0, -0.5*sizeZ, 0., 0., 1.0);
2014         shCover->DefineSection(1,  0.5*sizeZ, 0., 0., 1.0);
2015         
2016         // create volume
2017         TGeoVolume *volCover  = new TGeoVolume("VOL_MCMCAPCOVER", shCover, medCap);
2018         volCover->SetLineColor(kBlue);
2019         
2020         return volCover;
2021 }
2022
2023 //______________________________________________________________________
2024 TGeoVolumeAssembly* AliITSv11GeometrySPD::CreateStave
2025 (Int_t layer, Double_t &fullThickness, TGeoManager *mgr)
2026 {
2027         //
2028         // Creates the complete stave as an assembly which contains all the stuff defined
2029         // in the "CreateStaveBase" method (which are the thin part of the structure)
2030         // and adds to this the thick cover of the MCM and the Pixel bus.
2031         // This is done as an assembly to avoid the problem of a "ghost" overlap which occurs
2032         // when putting the stave on the carbon fiber sector, in the case that we define it
2033         // as a volume container.
2034         // ---
2035         // Arguments:
2036         //     - the layer where the stave has to be put (hard check on this)
2037         //     - the geometry manager
2038         //
2039         
2040         // ** CRITICAL CHECK **
2041         // layer number can be ONLY 1 or 2
2042         if (layer != 1 && layer != 2) AliFatal("Required that layer number be 1 or 2");
2043         
2044         // sizes regarding the components
2045         Double_t baseWidth, baseHeight, baseThickness;
2046         Double_t mcmCapBorderThickness = fgkmm *  0.3;
2047         Double_t mcmCapThickness       = fgkmm *  1.7 - mcmCapBorderThickness;
2048         Double_t mcmCapHeight          = fgkmm * 11.0;
2049         Double_t mcmCapWidth           = fgkmm * 73.2;
2050         
2051         // create container
2052         TGeoVolumeAssembly *container = new TGeoVolumeAssembly(Form("LAY%d_FULLSTAVE", layer));
2053         
2054         // create subvolumes
2055         TGeoVolume *staveBase = CreateStaveBase(layer, baseWidth, baseHeight, baseThickness, mgr);
2056         TGeoVolume *mcmCapBorder = CreateMCMCoverBorder(mgr);
2057         TGeoVolume *mcmCapTop = CreateMCMCoverTop(mgr);
2058         TGeoVolumeAssembly *bus0 = CreatePixelBusAndExtensions(kTRUE, mgr);   // bus in z > 0
2059         TGeoVolumeAssembly *bus1 = CreatePixelBusAndExtensions(kFALSE, mgr);  // bus in z < 0
2060         
2061         // the full width and height of the area which contains all components
2062         // corresponds to the one of the stave base built with the "CreateStaveBase" method
2063         // while the thickness must be computed as the sum of this base + the cover
2064         fullThickness = baseThickness + mcmCapThickness + mcmCapBorderThickness;
2065         
2066         // 1 - MCM cover        
2067                 
2068         // translations (in the X direction, MCM is at the same level as ladder)
2069         Double_t xBase = -0.5*fullThickness + 0.5*baseThickness;
2070         TGeoTranslation *trBase = new TGeoTranslation(xBase, 0.0, 0.0);
2071         Double_t xMCMCapB = xBase + 0.5*baseThickness + 0.5*mcmCapThickness;
2072         Double_t xMCMCapT = xMCMCapB + 0.5*mcmCapThickness + 0.5*mcmCapBorderThickness;
2073         Double_t yMCMCap  = 0.5*(baseHeight - mcmCapHeight);
2074         Double_t zMCMCap1 = 0.5*baseWidth - 0.5*mcmCapWidth;
2075         Double_t zMCMCap0 = -zMCMCap1;
2076         // correction rotations
2077         TGeoRotation *rotCorr0 = new TGeoRotation(*gGeoIdentity);
2078         TGeoRotation *rotCorr1 = new TGeoRotation(*gGeoIdentity);
2079         rotCorr0->RotateY( 90.0);
2080         rotCorr1->RotateY(-90.0);
2081         TGeoCombiTrans  *trMCMCapBorder0 = new TGeoCombiTrans(xMCMCapB, yMCMCap, zMCMCap0, rotCorr0);
2082         TGeoCombiTrans  *trMCMCapBorder1 = new TGeoCombiTrans(xMCMCapB, yMCMCap, zMCMCap1, rotCorr1);
2083         TGeoCombiTrans  *trMCMCapTop0 = new TGeoCombiTrans(xMCMCapT, yMCMCap, zMCMCap0, rotCorr0);
2084         TGeoCombiTrans  *trMCMCapTop1 = new TGeoCombiTrans(xMCMCapT, yMCMCap, zMCMCap1, rotCorr1);
2085         // add to container
2086         container->AddNode(staveBase, 0, trBase);
2087         container->AddNode(mcmCapBorder, 0, trMCMCapBorder0);
2088         container->AddNode(mcmCapBorder, 1, trMCMCapBorder1);
2089         container->AddNode(mcmCapTop, 0, trMCMCapTop0);
2090         container->AddNode(mcmCapTop, 1, trMCMCapTop1);
2091         
2092         // 2 - Pixel Bus
2093         
2094         // translations
2095         // for the moment, a correction amount of 0.04 is required to place correctly the object in X
2096         // and another correction of 0.015 in Z
2097         Double_t busHeight  = fgkmm * 13.8;
2098         Double_t xPixelBus  = xBase + baseThickness + 0.04;
2099         Double_t yPixelBus1 = 0.5*baseHeight - 0.5*busHeight + 0.5*(baseHeight - busHeight);
2100         Double_t zPixelBus0 = -0.25*baseWidth + 0.015 - 0.03;
2101         //Double_t zPixelBus0 = -0.5*(0.5*baseWidth - 0.04);
2102         Double_t zPixelBus1 = -zPixelBus0;
2103         // correction rotations
2104         TGeoRotation *rotCorrBus1 = new TGeoRotation(*gGeoIdentity);
2105         rotCorrBus1->RotateX(180.0);
2106         //TGeoCombiTrans *trBus0 = new TGeoCombiTrans(xPixelBus, 0.0, zPixelBus0, rotCorrBus);
2107         TGeoTranslation *trBus0 = new TGeoTranslation(xPixelBus, 0.0, zPixelBus0);
2108         //TGeoTranslation *trBus1 = new TGeoTranslation(xPixelBus, 0.0, zPixelBus1);
2109         TGeoCombiTrans *trBus1 = new TGeoCombiTrans(xPixelBus, yPixelBus1, zPixelBus1, rotCorrBus1);
2110
2111         // add to container
2112         container->AddNode(bus0, 0, trBus0);
2113         container->AddNode(bus1, 1, trBus1);
2114         
2115         return container;
2116 }
2117
2118 //______________________________________________________________________
2119 TGeoVolumeAssembly* AliITSv11GeometrySPD::CreatePixelBusAndExtensions(Bool_t zpos, TGeoManager *mgr)
2120 {
2121   //
2122   // Creates an assembly which contains the pixel bus and its extension
2123   // and the extension of the MCM.
2124   // By: Renaud Vernet
2125   // NOTE: to be defined its material and its extension in the outside direction
2126   //
2127   
2128   // ====   constants   =====
2129
2130   //get the media
2131   TGeoMedium   *medPixelBus    = mgr->GetMedium("PIXEL BUS") ;
2132   TGeoMedium   *medPBExtender  = mgr->GetMedium("PIXEL BUS EXTENDER") ;
2133   TGeoMedium   *medMCMExtender = mgr->GetMedium("MCM EXTENDER") ;
2134
2135   //geometrical constants
2136   const Double_t kGroundingThickness    =   0.07  * fgkmm ;
2137   const Double_t kGrounding2pixelBusDz  =   0.625 * fgkmm ;
2138   const Double_t kPixelBusThickness     =   0.28  * fgkmm ;
2139   const Double_t kGroundingWidthX       = 170.501 * fgkmm ;
2140   const Double_t kPixelBusContactDx     =   1.099 * fgkmm ;
2141   const Double_t kPixelBusWidthY        =  13.8   * fgkmm ;
2142   const Double_t kPixelBusContactPhi    =  20.0   * TMath::Pi()/180. ; //design=20 deg.
2143   const Double_t kPbExtenderPsi         =  70.0   * TMath::Pi()/180. ; //design=?? 70 deg. seems OK
2144   const Double_t kPbExtenderWidthY      =  11.0   * fgkmm ;
2145   const Double_t kPbExtenderTopZ        =   2.72  * fgkmm ;
2146   const Double_t kMcmThickness          =   0.35  * fgkmm ;
2147   const Double_t kMcmExtenderThickness  =   0.20  * fgkmm ;
2148   const Double_t kDeltaMcmMcmextender   =   1.6   * fgkmm ;
2149   const Double_t kHalfStaveTotalLength  = 247.64  * fgkmm ;
2150   const Double_t kDeltaYOrigin          =  15.95/2.* fgkmm ;
2151   const Double_t kDeltaXOrigin          =   1.1    * fgkmm ;
2152   const Double_t kDeltaZOrigin          = kHalfStaveTotalLength / 2. ;
2153
2154   const Double_t kGrounding2pixelBusDz2 = kGrounding2pixelBusDz+kGroundingThickness/2. + kPixelBusThickness/2. ;
2155   const Double_t kPixelBusWidthX        = kGroundingWidthX ;
2156   const Double_t kPixelBusRaiseLength   = (kPixelBusContactDx-kPixelBusThickness*TMath::Sin(kPixelBusContactPhi))/TMath::Cos(kPixelBusContactPhi) ;
2157   const Double_t kPbExtenderBaseZ       = kGrounding2pixelBusDz2 + kPixelBusRaiseLength*TMath::Sin(kPixelBusContactPhi) + 2*kPixelBusThickness*TMath::Sin(kPixelBusContactPhi)*TMath::Tan(kPixelBusContactPhi) ;
2158   const Double_t kPbExtenderDeltaZ      = kPbExtenderTopZ-kPbExtenderBaseZ ;
2159
2160   const Double_t kPbExtenderEndPointX   = 2*kDeltaZOrigin - kGroundingWidthX - 2*kPixelBusThickness*TMath::Sin(kPixelBusContactPhi) ;
2161   const Double_t kMcmextenderEndPointX  = kDeltaZOrigin - 48.2 * fgkmm ;
2162   const Double_t kMcmExtenderWidthY     = kPbExtenderWidthY ;
2163
2164   //=====  end constants  =====
2165
2166   
2167   /*
2168   // -----------------   CREATE THE PIXEL BUS --------------------------
2169   // At the end of the pixel bus, a small piece is added for the contact 
2170   // with the pixel bus extender.
2171   // The whole piece is made with an extrusion, using 7 points
2172   //
2173   //                                   4
2174   //                                  /\
2175   // 6                            5  /  \ 3
2176   //  +-----------------------------+    /
2177   //  |                                 /
2178   //  +-----------------------------+--+
2179   // 0                              1   2
2180   //
2181   // The length of the pixel bus is defined (170.501mm) by the technical design
2182   // this length corresponds to distance [0-1] and [6-5]
2183
2184   */
2185
2186   TGeoVolumeAssembly *pixelBus = new TGeoVolumeAssembly("PIXEL BUS");
2187
2188   // definition of the 7 points for the extrusion
2189   Double_t pixelBusXtruX[7] = {
2190     -kPixelBusWidthX/2. ,
2191     kPixelBusWidthX/2. ,
2192     kPixelBusWidthX/2. + kPixelBusThickness * TMath::Sin(kPixelBusContactPhi) ,
2193     kPixelBusWidthX/2. + kPixelBusThickness * TMath::Sin(kPixelBusContactPhi) + kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) ,
2194     kPixelBusWidthX/2. + kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) ,
2195     kPixelBusWidthX/2. ,
2196     -kPixelBusWidthX/2.
2197   } ;
2198   Double_t pixelBusXtruY[7] = {
2199     -kPixelBusThickness/2. ,
2200     -kPixelBusThickness/2. ,
2201     -kPixelBusThickness/2. + kPixelBusThickness * (1 - TMath::Cos(kPixelBusContactPhi)) ,
2202     -kPixelBusThickness/2. + kPixelBusThickness * (1 - TMath::Cos(kPixelBusContactPhi)) + kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) ,
2203     kPixelBusThickness/2.  + kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) ,
2204     kPixelBusThickness/2. ,
2205     kPixelBusThickness/2.
2206   } ;
2207
2208   // creation of the volume
2209   TGeoXtru   *pixelBusXtru    = new TGeoXtru(2);
2210   TGeoVolume* pixelBusXtruVol = new TGeoVolume("pixelBusXtru",pixelBusXtru,medPixelBus) ;
2211   pixelBusXtru->DefinePolygon(7,pixelBusXtruX,pixelBusXtruY);
2212   pixelBusXtru->DefineSection(0,-kPixelBusWidthY/2.);
2213   pixelBusXtru->DefineSection(1, kPixelBusWidthY/2.);
2214   // --------------- END PIXEL BUS ----------------------------------------------------
2215
2216
2217   // ------------------------- CREATE THE PIXEL BUS EXTENDER --------------------------
2218   // The geometry of the extender is a bit complicated sinceit is constrained
2219   // to be in contact with the pixel bus.
2220   // It consists of an extrusion using 13 points as shows the scheme below :
2221   //                                                                                     
2222   //                             8     7                       6                         
2223   //                               +---+---------------------+                           
2224   //                              /                          |                           
2225   //                             /                           |                           
2226   //                            /      +---------------------+                           
2227   //                           /      / 4                     5                          
2228   //                          /      /                                                   
2229   //       11  10          9 /      /                                                    
2230   //        +---+-----------+      /                                                     
2231   //       /                      /                                                      
2232   //      /                      /                                                       
2233   //     /      +-----------+---+                                                        
2234   // 12 +      / 1         2     3                                                       
2235   //     \    /                                                                          
2236   //      \  /                                                                           
2237   //        +                                                                            
2238   //        0                                                                            
2239   //                                                                                     
2240
2241
2242   // ====   constants   =====
2243   const Double_t kPbExtenderXtru3L   = 1.5 * fgkmm ; //arbitrary ?
2244   const Double_t kPbExtenderXtru4L   = (kPbExtenderDeltaZ + kPixelBusThickness*(TMath::Cos(kPbExtenderPsi)-2))/TMath::Sin(kPbExtenderPsi) ;
2245   //=====  end constants  =====
2246
2247   TGeoVolumeAssembly *pbExtender = new TGeoVolumeAssembly("PIXEL BUS EXTENDER");
2248
2249   Double_t pbExtenderXtruX[13] = {
2250     0, 
2251     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) , 
2252     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) + kPbExtenderXtru3L ,
2253     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) + kPbExtenderXtru3L + kPixelBusThickness * TMath::Sin(kPbExtenderPsi) , 
2254     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) + kPbExtenderXtru3L + kPixelBusThickness * TMath::Sin(kPbExtenderPsi) + kPbExtenderXtru4L * TMath::Cos(kPbExtenderPsi) ,
2255     kPbExtenderEndPointX ,
2256     kPbExtenderEndPointX ,
2257     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) + kPbExtenderXtru3L + kPixelBusThickness * TMath::Sin(kPbExtenderPsi) + kPbExtenderXtru4L * TMath::Cos(kPbExtenderPsi) ,
2258     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi)  + kPbExtenderXtru3L + kPixelBusThickness * TMath::Sin(kPbExtenderPsi) + kPbExtenderXtru4L * TMath::Cos(kPbExtenderPsi) - kPixelBusThickness * TMath::Sin(kPbExtenderPsi),
2259     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) + kPbExtenderXtru3L ,
2260     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) , 
2261     kPixelBusRaiseLength * TMath::Cos(kPixelBusContactPhi) - kPixelBusThickness*TMath::Sin(kPixelBusContactPhi) , 
2262     -kPixelBusThickness * TMath::Sin(kPixelBusContactPhi)
2263   } ;
2264   Double_t pbExtenderXtruY[13] = {
2265     0, 
2266     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) , 
2267     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) ,
2268     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) ,
2269     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) + kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi) ,
2270     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) + kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi) ,
2271     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) + kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi) + kPixelBusThickness ,
2272     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + kPixelBusThickness * (1-TMath::Cos(kPbExtenderPsi)) + kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi) + kPixelBusThickness ,
2273     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + kPixelBusThickness + kPbExtenderXtru4L * TMath::Sin(kPbExtenderPsi)
2274     ,
2275     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + kPixelBusThickness ,
2276     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + kPixelBusThickness ,
2277     kPixelBusRaiseLength * TMath::Sin(kPixelBusContactPhi) + kPixelBusThickness*TMath::Cos(kPixelBusContactPhi) ,
2278     kPixelBusThickness * TMath::Cos(kPixelBusContactPhi)
2279   } ;
2280   
2281   // creation of the volume
2282   TGeoXtru   *pbExtenderXtru    = new TGeoXtru(2);
2283   TGeoVolume *pbExtenderXtruVol = new TGeoVolume("pbExtenderXtru",pbExtenderXtru,medPBExtender) ;
2284   pbExtenderXtru->DefinePolygon(13,pbExtenderXtruX,pbExtenderXtruY);
2285   pbExtenderXtru->DefineSection(0,-kPbExtenderWidthY/2.);
2286   pbExtenderXtru->DefineSection(1, kPbExtenderWidthY/2.);
2287   // -------------- END PIXEL BUS EXTENDER -------------------------------------------------
2288
2289
2290   // ------------------   CREATE THE MCM EXTENDER    ------------------------------------
2291   // 
2292   // The MCM extender is located betwen the MCM and the Pixel Bus Extender
2293   // It consists of an extrusion using 10 points as shows the scheme below :
2294   //                                                                                     
2295   //                             7     6                       5                         
2296   //                               +---+---------------------+                           
2297   //                              /                          |                           
2298   //                             /                           |                           
2299   //                            /      +---------------------+                           
2300   //                           /      / 3                     4                          
2301   //                          /      /                                                   
2302   //            9          8 /      /                                                    
2303   //            +-----------+      /                                                     
2304   //            |                 /                                                      
2305   //            |                /                                                       
2306   //            +-----------+---+                                                        
2307   //            0          1     2                                                       
2308   //                                                                                     
2309
2310
2311   //constants
2312   const Double_t kMcmExtenderXtru3L  = 1.5  * fgkmm ;
2313   //end constants
2314
2315   TGeoVolumeAssembly *mcmExtender   = new TGeoVolumeAssembly("MCM EXTENDER");
2316   Double_t mcmExtenderXtruX[10] = {
2317     0 ,
2318     kMcmExtenderXtru3L ,
2319     kMcmExtenderXtru3L + kMcmExtenderThickness * TMath::Sin(kPbExtenderPsi) , 
2320     kMcmExtenderXtru3L + kMcmExtenderThickness * TMath::Sin(kPbExtenderPsi) + kDeltaMcmMcmextender / TMath::Tan(kPbExtenderPsi) ,
2321     kMcmextenderEndPointX ,
2322     kMcmextenderEndPointX ,
2323     kMcmExtenderXtru3L + kMcmExtenderThickness * TMath::Sin(kPbExtenderPsi) + kDeltaMcmMcmextender / TMath::Tan(kPbExtenderPsi) ,
2324     kMcmExtenderXtru3L + kDeltaMcmMcmextender / TMath::Tan(kPbExtenderPsi) ,
2325     kMcmExtenderXtru3L ,
2326     0
2327   } ;
2328
2329   Double_t mcmExtenderXtruY[10] = {
2330     0 ,
2331     0 ,
2332     kMcmExtenderThickness * (1-TMath::Cos(kPbExtenderPsi)) ,
2333     kMcmExtenderThickness * (1-TMath::Cos(kPbExtenderPsi)) + kDeltaMcmMcmextender ,
2334     kMcmExtenderThickness * (1-TMath::Cos(kPbExtenderPsi)) + kDeltaMcmMcmextender ,
2335     kMcmExtenderThickness * (2-TMath::Cos(kPbExtenderPsi)) + kDeltaMcmMcmextender ,
2336     kMcmExtenderThickness * (2-TMath::Cos(kPbExtenderPsi)) + kDeltaMcmMcmextender ,
2337     kMcmExtenderThickness + kDeltaMcmMcmextender ,
2338     kMcmExtenderThickness ,
2339     kMcmExtenderThickness ,
2340   } ;
2341
2342   // creation of the volume
2343   TGeoXtru   *mcmExtenderXtru    = new TGeoXtru(2);
2344   TGeoVolume *mcmExtenderXtruVol = new TGeoVolume("mcmExtenderXtru",mcmExtenderXtru,medMCMExtender) ;
2345   mcmExtenderXtru->DefinePolygon(10,mcmExtenderXtruX,mcmExtenderXtruY);
2346   mcmExtenderXtru->DefineSection(0,-kMcmExtenderWidthY/2.);
2347   mcmExtenderXtru->DefineSection(1, kMcmExtenderWidthY/2.);
2348
2349
2350   //--------------   DEFINITION OF GEOMETRICAL TRANSFORMATIONS -------------------
2351   TGeoRotation    * commonRot       = new TGeoRotation("commonRot",0,90,0);
2352   commonRot->MultiplyBy(new TGeoRotation("rot",-90,0,0)) ;
2353   TGeoTranslation * pixelBusTrans   = new TGeoTranslation(kPixelBusThickness/2. - kDeltaXOrigin + 0.52*fgkmm ,
2354                                                           -kPixelBusWidthY/2.     + kDeltaYOrigin , 
2355                                                           -kGroundingWidthX/2.    + kDeltaZOrigin) ;
2356   TGeoRotation    * pixelBusRot     = new TGeoRotation(*commonRot);
2357   TGeoTranslation * pbExtenderTrans = new TGeoTranslation(*pixelBusTrans) ;
2358   TGeoRotation    * pbExtenderRot   = new TGeoRotation(*pixelBusRot) ;
2359   pbExtenderTrans->SetDz(*(pbExtenderTrans->GetTranslation()+2) - kPixelBusWidthX/2. - 2*kPixelBusThickness*TMath::Sin(kPixelBusContactPhi)) ;  
2360   if (!zpos) {
2361     pbExtenderTrans->SetDy(*(pbExtenderTrans->GetTranslation()+1) - (kPixelBusWidthY - kPbExtenderWidthY)/2.);
2362   }
2363   else {
2364     pbExtenderTrans->SetDy(*(pbExtenderTrans->GetTranslation()+1) + (kPixelBusWidthY - kPbExtenderWidthY)/2.);
2365   }
2366   pbExtenderTrans->SetDx(*(pbExtenderTrans->GetTranslation()) + kPixelBusThickness/2 + 2*kPixelBusThickness*TMath::Sin(kPixelBusContactPhi)*TMath::Tan(kPixelBusContactPhi)) ;
2367   TGeoTranslation * mcmExtenderTrans = new TGeoTranslation(0.12*fgkmm + kMcmThickness - kDeltaXOrigin,
2368                                                            pbExtenderTrans->GetTranslation()[1],
2369                                                            -4.82);
2370   TGeoRotation    * mcmExtenderRot   = new TGeoRotation(*pbExtenderRot);
2371   
2372
2373   //ADD NODES TO ASSEMBLIES
2374   pixelBus    ->AddNode((TGeoVolume*)pixelBusXtruVol,0);
2375   pbExtender  ->AddNode((TGeoVolume*)pbExtenderXtruVol,0);
2376   mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtruVol,0);
2377 //   mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru3Vol,0);
2378 //   mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru3PrimVol,1);
2379 //   mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru4Vol,2);
2380 //   mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru4PrimVol,3);
2381 //   mcmExtender ->AddNode((TGeoVolume*)mcmExtenderXtru5Vol,4);
2382
2383
2384   //CREATE FINAL VOLUME ASSEMBLY AND ROTATE IT
2385   TGeoVolumeAssembly *assembly = new TGeoVolumeAssembly("EXTENDERS");
2386   assembly->AddNode((TGeoVolume*)pixelBus    ,0, new TGeoCombiTrans(*pixelBusTrans,*pixelBusRot));
2387   assembly->AddNode((TGeoVolume*)pbExtender  ,0, new TGeoCombiTrans(*pbExtenderTrans,*pbExtenderRot));
2388   assembly->AddNode((TGeoVolume*)mcmExtender ,0, new TGeoCombiTrans(*mcmExtenderTrans,*mcmExtenderRot));
2389 assembly->SetTransparency(50);
2390   return assembly ;
2391 }
2392
2393 //______________________________________________________________________
2394 TGeoVolume* AliITSv11GeometrySPD::CreateStaveBase
2395 (Int_t layer, Double_t &fullWidth, Double_t &fullHeight, Double_t &fullThickness, TGeoManager *mgr)
2396 {
2397         //
2398         // Creates a box which contains the followin parts of the whole stave:
2399         // - the two layers of grounding foil
2400         // - the ladders
2401         // - the thin base of the MCM (except its thick cover)
2402         // - the pixel bus
2403         // ---
2404         // Since it is required by detector numbering conventions, 
2405         // it is required as argument the layer which owns this stave.
2406         // This number will be used to define the name of the ladder volume, 
2407         // which must be different for layer1 and layer2 objects.
2408         // ---
2409         // Arguments:
2410         //    - layer number (will be checked to be 1 or 2)
2411         //    - geometry manager
2412         // ---
2413         // Returns:
2414         //    - a TGeoBBox volume containing all this stuff
2415         //    - the size of the container box are stored in the reference-passed variables
2416         //
2417         
2418         // sizes of all objects to be inserted
2419         // these values are used to compute the total volume of the container
2420         // and to compute parametrically the position of each piece, instead
2421         // of putting hard-coded number (this helps in eventually modifying everything)
2422         Double_t mcmThickness    = fgkmm * 0.35;
2423         Double_t grndThickness   = fgkmm * 0.07; // = 0.05 + 0.02
2424         Double_t sepThickness    = fgkmm * 0.05;
2425
2426         Double_t ladderWidth     = fgkmm *  70.72;
2427         Double_t mcmWidth        = fgkmm * 105.60;
2428         Double_t sepLaddersWidth = fgkmm *   0.20;
2429         Double_t sepMCMWidth     = fgkmm *   0.30;
2430         Double_t sepLaddersCtr   = fgkmm *   0.40; // separations between central ladders in the two half-staves 
2431
2432         Double_t mcmHeight       = fgkmm *  15.00;
2433         
2434         // compute the size of the container
2435         fullWidth     = 2.0*sepLaddersCtr + 4.0*ladderWidth + 2.0*sepMCMWidth + 2.0*sepLaddersWidth + 2.0*mcmWidth;
2436         fullHeight    = fgkmm * 15.95;
2437         fullThickness = grndThickness + sepThickness + mcmThickness;
2438         
2439         // create the container
2440         TGeoVolume *container = mgr->MakeBox(Form("LAY%d_STAVE", layer), mgr->GetMedium("VACUUM"), 0.5*fullThickness, 0.5*fullHeight, 0.5*fullWidth);
2441                 
2442         // fill the container going from bottom to top 
2443         // with respect to the thickness direction
2444         
2445         // 1 - Grounding foil
2446         // volume
2447         TGeoVolume *grndVol = CreateGroundingFoil(grndThickness);
2448         // translation
2449         Double_t xGrnd = -0.5*fullThickness + 0.5*grndThickness;
2450         TGeoTranslation *grndTrans = new TGeoTranslation(xGrnd, 0.0, 0.0);
2451         // add to container
2452         container->AddNode(grndVol, 1, grndTrans);
2453         
2454         // 2 - Ladders
2455         // volume (will be replicated 4 times)
2456         Double_t ladderLength, ladderThickness;
2457         TGeoVolume *ladder = CreateLadder(layer, ladderLength, ladderWidth, ladderThickness, mgr);
2458         // translations (in thickness direction, the MCM thickness is used)
2459         // layers are sorted going from the one at largest Z to the one at smallest Z:
2460         // -|Zmax| ------> |Zmax|
2461         //      0   1   2   3
2462         // but it is more comfortable to start defining their Z position from center
2463         Double_t xLad  = xGrnd + 0.5*grndThickness + 0.5*mcmThickness + sepThickness;
2464         Double_t zLad1 = -0.5*ladderWidth - sepLaddersCtr;
2465         Double_t zLad0 = zLad1 - ladderWidth - sepLaddersWidth;
2466         Double_t zLad2 = -zLad1;
2467         Double_t zLad3 = -zLad0;
2468         TGeoRotation   *rotLad = new TGeoRotation(*gGeoIdentity);// rotLad->RotateZ(180.0);
2469         TGeoCombiTrans *trLad0 = new TGeoCombiTrans(xLad, 0.0, zLad0, rotLad);
2470         TGeoCombiTrans *trLad1 = new TGeoCombiTrans(xLad, 0.0, zLad1, rotLad);
2471         TGeoCombiTrans *trLad2 = new TGeoCombiTrans(xLad, 0.0, zLad2, rotLad);
2472         TGeoCombiTrans *trLad3 = new TGeoCombiTrans(xLad, 0.0, zLad3, rotLad);
2473         // add to container
2474         container->AddNode(ladder, 0, trLad0);
2475         container->AddNode(ladder, 1, trLad1);
2476         container->AddNode(ladder, 2, trLad2);
2477         container->AddNode(ladder, 3, trLad3);
2478         
2479         // 3 - MCM (only the base, the cover is added as a separate volume in a more global 'stave' assembly
2480         // volume (will be replicated twice)
2481         TGeoVolume *mcm = CreateMCMBase(mgr);
2482         // translations (in the X direction, MCM is at the same level as ladder)
2483         // the two copies of the MCM are placed at the same distance from the center, on both sides
2484         // and their sorting is the same as ladders' one (MCM0 is at Z < 0, MCM1 at Z > 0);
2485         Double_t xMCM  = xLad;
2486         Double_t yMCM  = 0.5*(fullHeight - mcmHeight);
2487         Double_t zMCM1 = zLad3 + 0.5*ladderWidth + 0.5*mcmWidth + sepMCMWidth;
2488         Double_t zMCM0 = -zMCM1;
2489         // create the common correction rotations
2490         TGeoRotation *rotCorr0 = new TGeoRotation(*gGeoIdentity);
2491         TGeoRotation *rotCorr1 = new TGeoRotation(*gGeoIdentity);
2492         rotCorr0->RotateY( 90.0);
2493         rotCorr1->RotateY(-90.0);
2494         TGeoCombiTrans *trMCM0 = new TGeoCombiTrans(xMCM, yMCM, zMCM0, rotCorr0);
2495         TGeoCombiTrans *trMCM1 = new TGeoCombiTrans(xMCM, yMCM, zMCM1, rotCorr1);
2496         // add to container
2497         container->AddNode(mcm, 0, trMCM0);
2498         container->AddNode(mcm, 1, trMCM1);
2499                 
2500         return container;
2501 }
2502
2503 //______________________________________________________________________
2504 void AliITSv11GeometrySPD::StavesInSector(TGeoVolume *moth, TGeoManager *mgr)
2505 {
2506         //
2507         // Unification of essentially two methods:
2508         // - the one which creates the sector structure
2509         // - the one which returns the complete stave
2510         // ---
2511         // For compatibility, this method requires the same arguments
2512         // asked by "CarbonFiberSector" method, which is recalled here.
2513         // Like this cited method, this one does not return any value,
2514         // but it inserts in the mother volume (argument 'moth') all the stuff
2515         // which composes the complete SPD sector.
2516         // ---
2517         // Arguments: see description of "CarbonFiberSector" method.
2518         //
2519         
2520         // This service class is useful to this method only
2521         // to store in a meaningful way the data about the 
2522         // rounded corners of the support, and some computations
2523         // which could turn out to be useful for stave placement
2524         // 'left' and 'right' (L/R) here are considered looking the support
2525         // from the positive Z side.
2526         // The sign of the radius is used to know what kind of tangent
2527         // must be found for the two circles which describe the rounded angles.
2528         class clsSupportPlane {
2529         public:
2530                 Double_t xL, yL, rL, sL;  // curvature center and radius (with sign) of left corner
2531                 Double_t xR, yR, rR, sR;  // curvature center and radius (with sign) of right corner
2532                 Double_t shift;           // shift from the innermost position (where the stave edge is
2533                                           // in the point where the rounded corner begins
2534                 
2535                 // Constructor with arguments which allow to set directly everything
2536                 // since the values are given in millimiters from drawings, they must be converted to cm
2537                 clsSupportPlane
2538                 (Double_t xLin, Double_t yLin, Double_t rLin, Double_t sLin, 
2539                  Double_t xRin, Double_t yRin, Double_t rRin, Double_t sRin, Double_t shiftin) :
2540                  xL(xLin), yL(yLin), rL(rLin), sL(sLin), xR(xRin), yR(yRin), rR(rRin), sR(sRin), shift(shiftin) 
2541                 {
2542                         xL *= fgkmm;
2543                         yL *= fgkmm;
2544                         rL *= fgkmm;
2545                         xR *= fgkmm;
2546                         yR *= fgkmm;
2547                         rR *= fgkmm;
2548                         shift *= fgkmm;
2549                 }
2550                 
2551                 // Computation of the line tangent to both circles defined here
2552                 // which is taken above or below the center according to the radius sign.
2553                 // This method returns:
2554                 //   - the mid-popint of the segment between the two points where the tangent touches the two circles, 
2555                 //   - the inclination of this segment
2556                 //   - the half-length of this segment
2557                 Double_t TangentSegment(Double_t &midX, Double_t &midY, Double_t &phi)
2558                 {
2559                         // compute the straight line which is tangent to the two circles
2560                         // and extract its inclination 'phi' w.r. to X axis
2561                         Double_t dx = xL - xR;
2562                         Double_t dy = yL - yR;
2563                         Double_t R  = rL*sL + rR*sR;
2564                         Double_t delta = dy*dy + dx*dx - R*R;
2565                         Double_t tan05phi = (-dy + TMath::Sqrt(delta)) / (R - dx);
2566                         phi = 2.0 * TMath::ATan(tan05phi);
2567                         // compute the points where this line touchs the two circles
2568                         Double_t leftX  = xL + sL*rL*TMath::Cos(phi);
2569                         Double_t leftY  = yL + sL*rL*TMath::Sin(phi);
2570                         Double_t rightX = xR + sR*rR*TMath::Cos(phi);
2571                         Double_t rightY = yR + sR*rR*TMath::Sin(phi);
2572                         // compute the mid point
2573                         midX = 0.5 * (leftX + rightX);
2574                         midY = 0.5 * (leftY + rightY);
2575                         // compute angular coefficient for the line joining
2576                         // the two points found using the above method
2577                         dx = rightX - leftX;
2578                         dy = rightY - leftY;
2579                         phi = TMath::ATan2(dy, dx);
2580                         // compute the half-length of this segment
2581                         Double_t len = 0.5*TMath::Sqrt((rightX-leftX)*(rightX-leftX) + (rightY-leftY)*(rightY-leftY));
2582                         //MM                    cout << 2.0*len << endl;
2583                         return len;
2584                 }
2585         };
2586         
2587         // instantiate this class for each layer1 and layer2 corners
2588         clsSupportPlane *plane[6] = {0, 0, 0, 0, 0, 0};
2589         
2590         // layer 2
2591         plane[0] = new clsSupportPlane( 10.830,  16.858, 0.60,  1.,  19.544,  10.961, 0.8,  1.,  1.816);
2592         plane[1] = new clsSupportPlane(- 0.733,  17.486, 0.60,  1.,  11.581,  13.371, 0.6, -1., -0.610);
2593         plane[2] = new clsSupportPlane(-12.252,  16.298, 0.60,  1.,   0.562,  14.107, 0.6, -1., -0.610);
2594         plane[3] = new clsSupportPlane(-22.276,  12.948, 0.85,  1., -10.445,  13.162, 0.6, -1., -0.610);
2595         // layer 1
2596         plane[4] = new clsSupportPlane(- 3.123, -14.618, 0.50,  1.,  11.280, -14.473, 0.9, -1., -0.691);
2597         plane[5] = new clsSupportPlane(-13.187, -19.964, 0.50, -1., - 3.833, -17.805, 0.6, -1.,  1.300);
2598         
2599         // put the sector in the container
2600         //CarbonFiberSector(moth, xAAtubeCenter0, yAAtubeCenter0, mgr);
2601         
2602         // create stave volume
2603         Double_t staveHeight = 1.595, staveThickness;
2604         TGeoVolume *stave1 = CreateStave(1, staveThickness, gGeoManager);
2605         TGeoVolume *stave2 = CreateStave(2, staveThickness, gGeoManager);
2606                 
2607         // compute positions and rotation angles
2608         Double_t xm, ym, halfPlaneHeight, heightDiff, position, phi, xPos, yPos;
2609         for (Int_t i = 0; i < 6; i++) {
2610                 // recall the geometry computations defined for the classe
2611                 halfPlaneHeight = plane[i]->TangentSegment(xm, ym, phi);
2612                 // compute the difference between plane and stave heights
2613                 heightDiff = halfPlaneHeight - 0.5*staveHeight;
2614                 // It is necessary to shift the stave by at least 
2615                 // an amount equal to this difference
2616                 // to avoid overlaps.
2617                 // Moreover, some more shift is done for building reasons,
2618                 // and it depends on the single plane (data-member 'shift')
2619                 position = heightDiff + plane[i]->shift;
2620                 // taking into account this shift plus another in the direction
2621                 // normal to the support plane, due to the stave thickness,
2622                 // the final position of the stave is computed in a temporary reference frame
2623                 // where the mid-point of the support plane is in the origin
2624                 if (i < 4) {
2625                         ParallelPosition(0.5*staveThickness, position, phi, xPos, yPos);
2626                 }
2627                 else if (i == 4) {
2628                         ParallelPosition(-0.5*staveThickness, -position, phi, xPos, yPos);
2629                 }
2630                 else {
2631                         ParallelPosition(-0.5*staveThickness, -position, phi, xPos, yPos);
2632                 }
2633                 // then we go into the true reference frame
2634                 xPos += xm;
2635                 yPos += ym;
2636                 /*
2637                 // TEMP
2638                 TGeoVolume *tubeTemp1 = mgr->MakeTube("tubeTemp1", NULL, 0.0, 0.01, 50.0);
2639                 TGeoTranslation *trTemp1 = new TGeoTranslation(xm, ym, 0.0);
2640                 tubeTemp1->SetLineColor(kRed);
2641                 moth->AddNode(tubeTemp1, i + 1, trTemp1);
2642                 TGeoVolume *tubeTemp2 = mgr->MakeTube("tubeTemp2", NULL, 0.0, 0.01, 50.0);
2643                 TGeoTranslation *trTemp2 = new TGeoTranslation(xPos, yPos, 0.0);
2644                 tubeTemp2->SetLineColor(kBlue);
2645                 moth->AddNode(tubeTemp2, i + 1, trTemp2);
2646                 // END TEMP
2647                 */
2648                 // using the parameters found here, compute the 
2649                 // translation and rotation of this stave:
2650                 TGeoRotation *rot = new TGeoRotation(*gGeoIdentity);
2651                 if (i >= 4) rot->RotateY(180.0);
2652                 rot->RotateZ(90.0 + phi * TMath::RadToDeg());
2653                 TGeoCombiTrans *trans = new TGeoCombiTrans(xPos, yPos, 0.0, rot);
2654                 if (i < 4) {
2655                         moth->AddNode(stave2, i, trans);
2656                 }
2657                 else {
2658                         moth->AddNode(stave1, i - 4, trans);
2659                 }
2660         }
2661 }
2662
2663 //______________________________________________________________________
2664 void AliITSv11GeometrySPD::ParallelPosition(Double_t dist1, Double_t dist2, Double_t phi, Double_t &x, Double_t &y)
2665 {
2666         //
2667         // Performs the following steps:
2668         // 1 - finds a straight line parallel to the one passing through the origin and with angle 'phi' with X axis
2669         //     (phi in RADIANS);
2670         // 2 - finds another line parallel to the previous one, with a distance 'dist1' from it
2671         // 3 - takes a reference point in the second line in the intersection between the normal to both lines 
2672         //     passing through the origin
2673         // 4 - finds a point whith has distance 'dist2' from this reference, in the second line (point 2)
2674         // ----
2675         // According to the signs given to dist1 and dist2, the point is found in different position w.r. to the origin
2676         //
2677         
2678         // compute the point
2679         Double_t cs = TMath::Cos(phi);
2680         Double_t sn = TMath::Sin(phi);
2681         
2682         x = dist2*cs - dist1*sn;
2683         y = dist1*cs + dist2*sn;
2684 }
2685