]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSInitGeometry.cxx
Changes to obey coding conventions
[u/mrichter/AliRoot.git] / ITS / AliITSInitGeometry.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17 $Id$
18 */
19 ////////////////////////////////////////////////////////////////
20 //  This class initializes the class AliITSgeom
21 //  The initialization is done starting from 
22 //  a geometry coded by means of the ROOT geometrical modeler
23 //  This initialization can be used both for simulation and reconstruction
24 ///////////////////////////////////////////////////////////////
25
26 #include <TArrayD.h>
27 #include <TArrayF.h>
28 #include <TStopwatch.h>
29 #include <AliITSgeomSPD.h>
30 #include <AliITSgeomSDD.h>
31 #include <AliITSgeomSSD.h>
32 #include <AliITSsegmentationSPD.h>
33 #include <AliITSsegmentationSDD.h>
34 #include <AliITSsegmentationSSD.h>
35 #include <TGeoManager.h>
36 #include <TGeoVolume.h>
37 #include <TGeoShape.h>
38 #include <TGeoBBox.h>
39 #include <TGeoTrd1.h>
40 #include <TGeoTrd2.h>
41 #include <TGeoArb8.h>
42 #include <TGeoTube.h>
43 #include <TGeoCone.h>
44 #include <TGeoSphere.h>
45 #include <TGeoPara.h>
46 #include <TGeoPgon.h>
47 #include <TGeoPcon.h>
48 #include <TGeoEltu.h>
49 #include <TGeoHype.h>
50
51 #include "AliITSgeom.h"
52 #include "AliITSInitGeometry.h"
53
54 ClassImp(AliITSInitGeometry)
55 //______________________________________________________________________
56 AliITSInitGeometry::AliITSInitGeometry():
57 TObject(),
58 fName(),
59 fMinorVersion(0),
60 fMajorVersion(0),
61 fTiming(kFALSE),
62 fSegGeom(kFALSE),
63 fDecode(kFALSE){
64     // Default Creator
65     // Inputs:
66     //   none.
67     // Outputs:
68     //   none.
69     // Return:
70     //   A default inilized AliITSInitGeometry object
71 }
72 //______________________________________________________________________
73 AliITSInitGeometry::AliITSInitGeometry(const Char_t *name,Int_t minorversion):
74 TObject(),
75 fName(name),
76 fMinorVersion(minorversion),
77 fMajorVersion(0),
78 fTiming(kFALSE),
79 fSegGeom(kFALSE),
80 fDecode(kFALSE){
81     // Default Creator
82     // Inputs:
83     //   none.
84     // Outputs:
85     //   none.
86     // Return:
87     //   A default inilized AliITSInitGeometry object
88
89     if(fName.CompareTo("AliITSvPPRasymmFMD")==0)if(fMinorVersion==1||
90                                                    fMinorVersion==2){
91         fMajorVersion=10;
92         return;
93     } // end if
94     // if not defined geometry error
95     Error("AliITSInitGeometry(name,version)"," Name must be AliITSvPPRasymmFMD"
96         " and version must be 1 or 2 for now.");
97     fMinorVersion = 0;
98     fName = "";
99     return;
100 }
101 //______________________________________________________________________
102 AliITSgeom* AliITSInitGeometry::CreateAliITSgeom(){
103     // Creates and Initilizes the geometry transformation class AliITSgeom
104     // to values appropreate to this specific geometry. Now that
105     // the segmentation is part of AliITSgeom, the detector
106     // segmentations are also defined here.
107     // Inputs:
108     //   none.
109     // Outputs:
110     //   none.
111     // Return:
112     //   A pointer to a new properly inilized AliITSgeom class. If
113     //   pointer = 0 then failed to init.
114
115     AliITSgeom *geom = new AliITSgeom();
116     if(!InitAliITSgeom(geom)){ // Error initilization failed
117         delete geom;
118         geom = 0;
119     } // end if
120     return geom;
121 }
122 //______________________________________________________________________
123 Bool_t AliITSInitGeometry::InitAliITSgeom(AliITSgeom *geom){
124     // Initilizes the geometry transformation class AliITSgeom
125     // to values appropreate to this specific geometry. Now that
126     // the segmentation is part of AliITSgeom, the detector
127     // segmentations are also defined here.
128     // Inputs:
129     //   AliITSgeom *geom  A pointer to the AliITSgeom class
130     // Outputs:
131     //   AliITSgeom *geom  This pointer recreated and properly inilized.
132     // Return:
133     //   none.
134
135     switch(fMajorVersion){
136     case 10:{ // only case defined so far
137         return InitAliITSgeomPPRasymmFMD(geom);
138     }break; // end case
139     default:{
140         Error("InitAliITSgeom","Undefine geomtery");
141         return kFALSE;
142     } break; // end case
143     } // end switch
144     return kFALSE;
145 }
146 //______________________________________________________________________
147 Bool_t AliITSInitGeometry::InitAliITSgeomPPRasymmFMD(AliITSgeom *geom){
148     // Initilizes the geometry transformation class AliITSgeom
149     // to values appropreate to this specific geometry. Now that
150     // the segmentation is part of AliITSgeom, the detector
151     // segmentations are also defined here.
152     // Inputs:
153     //   AliITSgeom *geom  A pointer to the AliITSgeom class
154     // Outputs:
155     //   AliITSgeom *geom  This pointer recreated and properly inilized.
156     // Return:
157     //   none.
158   //    const Double_t kcm2micron = 1.0E4;
159     const Int_t kItype=0; // Type of transormation defined 0=> Geant
160     const Int_t klayers = 6; // number of layers in the ITS
161     const Int_t kladders[klayers]   = {20,40,14,22,34,38}; // Number of ladders
162     const Int_t kdetectors[klayers] = {4,4,6,8,22,25};// number of detector/lad
163     const AliITSDetector kIdet[6]   = {kSPD,kSPD,kSDD,kSDD,kSSD,kSSD};
164     const TString kPathbase = "/ALIC_1/ITSV_1/ITSD_1/";
165     const TString kNames[2][klayers] = {
166         {"%sIT12_1/I12A_%d/I10A_%d/I103_%d/I101_1/ITS1_1", // lay=1
167          "%sIT12_1/I12A_%d/I20A_%d/I1D3_%d/I1D1_1/ITS2_1", // lay=2
168          "%sIT34_1/I004_%d/I302_%d/ITS3_%d/", // lay=3
169          "%sIT34_1/I005_%d/I402_%d/ITS4_%d/", // lay=4
170          "%sIT56_1/I565_%d/I562_%d/ITS5_%d/", // lay=5
171          "%sIT56_1/I569_%d/I566_%d/ITS6_%d/"},// lay=6
172         {"%sIT12_1/I12B_%d/I10B_%d/I107_%d/I101_1/ITS1_1", // lay=1
173          "%sIT12_1/I12B_%d/I20B_%d/I1D7_%d/I1D1_1/ITS2_1", // lay=2
174          "%sIT34_1/I004_%d/I302_%d/ITS3_%d", // lay=3
175          "%sIT34_1/I005_%d/I402_%d/ITS4_%d", // lay=4
176          "%sIT56_1/I565_%d/I562_%d/ITS5_%d", // lay=5
177          "%sIT56_1/I569_%d/I566_%d/ITS6_%d"}};// Lay=6
178     /*
179       Int_t itsGeomTreeCopys[knlayers][3]= {{10, 2, 4},// lay=1
180       {10, 4, 4},// lay=2
181       {14, 6, 1},// lay=3
182       {22, 8, 1},// lay=4
183       {34,22, 1},// lay=5
184       {38,25, 1}};//lay=6
185     */
186     Int_t mod,nmods=0,lay,lad,det,cpn0,cpn1,cpn2;
187     Double_t tran[3]={0.0,0.0,0.0},rot[10]={9*0.0,1.0};
188     TArrayD shapePar;
189     TString path,shapeName;
190     TGeoHMatrix materix;
191     Bool_t initSeg[3]={kFALSE,kFALSE,kFALSE};
192     TStopwatch *time = 0x0;if(fTiming) time=new TStopwatch();
193
194     if(fTiming) time->Start();
195     for(mod=0;mod<klayers;mod++) nmods += kladders[mod]*kdetectors[mod];
196     geom->Init(kItype,klayers,kladders,kdetectors,nmods);
197     for(mod=0;mod<nmods;mod++){
198         DecodeDetectorLayers(mod,lay,lad,det); // Write
199         geom->CreateMatrix(mod,lay,lad,det,kIdet[lay-1],tran,rot);
200         RecodeDetector(mod,cpn0,cpn1,cpn2); // Write reusing lay,lad,det.
201         path.Form(kNames[fMinorVersion-1][lay-1].Data(),
202                   kPathbase.Data(),cpn0,cpn1,cpn2);
203         geom->GetGeomMatrix(mod)->SetPath(path);
204         GetTransformation(path.Data(),materix);
205         geom->SetTrans(mod,materix.GetTranslation());
206         geom->SetRotMatrix(mod,materix.GetRotationMatrix());
207         if(initSeg[kIdet[lay-1]]) continue;
208         GetShape(path,shapeName,shapePar);
209         if(shapeName.CompareTo("BOX")){
210             Error("InitITSgeom","Geometry changed without proper code update"
211                   "or error in reading geometry. Shape is not BOX.");
212             return kFALSE;
213         } // end if
214         InitGeomShapePPRasymmFMD(kIdet[lay-1],initSeg,shapePar,geom);
215     } // end for module
216     if(fTiming){
217         time->Stop();
218         time->Print();
219         delete time;
220     } // end if
221     return kTRUE;
222 }
223 //______________________________________________________________________
224 Bool_t AliITSInitGeometry::InitGeomShapePPRasymmFMD(AliITSDetector idet,
225                                                        Bool_t *initSeg,
226                                                        TArrayD &shapePar,
227                                                        AliITSgeom *geom){
228     // Initilizes the geometry segmentation class AliITSgeomS?D, or
229     // AliITSsegmentationS?D depending on the vaule of fSegGeom,
230     // to values appropreate to this specific geometry. Now that
231     // the segmentation is part of AliITSgeom, the detector
232     // segmentations are also defined here.
233     // Inputs:
234     //   Int_t      lay    The layer number/name.
235     //   AliITSgeom *geom  A pointer to the AliITSgeom class
236     // Outputs:
237     //   AliITSgeom *geom  This pointer recreated and properly inilized.
238     // Return:
239     //   none.
240   //   const Double_t kcm2micron = 1.0E4;
241     const Double_t kmicron2cm = 1.0E-4;
242     Int_t i;
243     TArrayF shapeParF;
244
245     shapeParF.Set(shapePar.GetSize());
246     for(i=0;i<shapePar.GetSize();i++) shapeParF[i]=shapePar[i];
247     switch (idet){
248     case kSPD:{
249         initSeg[idet] = kTRUE;
250         AliITSgeomSPD *geomSPD = new AliITSgeomSPD425Short();
251         Float_t bx[256],bz[280];
252         for(i=000;i<256;i++) bx[i] =  50.0*kmicron2cm; // in x all are 50 microns.
253         for(i=000;i<160;i++) bz[i] = 425.0*kmicron2cm; // most are 425 microns
254         // except below
255         for(i=160;i<280;i++) bz[i] =   0.0*kmicron2cm; // Outside of detector.
256         bz[ 31] = bz[ 32] = 625.0*kmicron2cm; // first chip boundry
257         bz[ 63] = bz[ 64] = 625.0*kmicron2cm; // first chip boundry
258         bz[ 95] = bz[ 96] = 625.0*kmicron2cm; // first chip boundry
259         bz[127] = bz[128] = 625.0*kmicron2cm; // first chip boundry
260         bz[160] = 425.0*kmicron2cm;// Set so that there is no zero pixel size for fNz.
261         geomSPD->ReSetBins(shapeParF[1],256,bx,160,bz);
262         geom->ReSetShape(idet,geomSPD);
263     }break;
264     case kSDD:{
265         initSeg[idet] = kTRUE;
266         AliITSgeomSDD *geomSDD = new AliITSgeomSDD256(shapeParF.GetSize(),
267                                                       shapeParF.GetArray());
268         geom->ReSetShape(idet,geomSDD);
269     }break;
270     case kSSD:{
271         initSeg[idet] = kTRUE;
272         AliITSgeomSSD *geomSSD = new AliITSgeomSSD275and75(
273             shapeParF.GetSize(),shapeParF.GetArray());
274         geom->ReSetShape(idet,geomSSD);
275     }break;
276     default:{// Others, Note no kSDDp or kSSDp in this geometry.
277         geom->ReSetShape(idet,0);
278         Info("InitGeomShapePPRasymmFMD",
279              "default Dx=%f Dy=%f Dz=%f default=%d",
280              shapePar[0],shapePar[1],shapePar[2],idet);
281     }break;
282     } // end switch
283     return kTRUE;
284 }
285 //______________________________________________________________________
286 Bool_t AliITSInitGeometry::InitSegmentationPPRasymmFMD(AliITSDetector idet,
287                                                        Bool_t *initSeg,
288                                                        TArrayD &shapePar,
289                                                        AliITSgeom *geom){
290     // Initilizes the geometry segmentation class AliITSgeomS?D, or
291     // AliITSsegmentationS?D depending on the vaule of fSegGeom,
292     // to values appropreate to this specific geometry. Now that
293     // the segmentation is part of AliITSgeom, the detector
294     // segmentations are also defined here.
295     // Inputs:
296     //   Int_t      lay    The layer number/name.
297     //   AliITSgeom *geom  A pointer to the AliITSgeom class
298     // Outputs:
299     //   AliITSgeom *geom  This pointer recreated and properly inilized.
300     // Return:
301     //   none.
302     const Double_t kcm2micron = 1.0E4;
303     Int_t i;
304
305     switch (idet){
306     case kSPD:{
307         initSeg[idet] = kTRUE;
308         AliITSsegmentationSPD *segSPD = new AliITSsegmentationSPD();
309         segSPD->SetDetSize(2.*shapePar[0]*kcm2micron, // X
310                            2.*shapePar[2]*kcm2micron, // Z
311                            2.*shapePar[1]*kcm2micron);// Y  Microns
312         segSPD->SetNPads(256,160);// Number of Bins in x and z
313         Float_t bx[256],bz[280];
314         for(i=000;i<256;i++) bx[i] =  50.0; // in x all are 50 microns.
315         for(i=000;i<160;i++) bz[i] = 425.0; // most are 425 microns
316         // except below
317         for(i=160;i<280;i++) bz[i] =   0.0; // Outside of detector.
318         bz[ 31] = bz[ 32] = 625.0; // first chip boundry
319         bz[ 63] = bz[ 64] = 625.0; // first chip boundry
320         bz[ 95] = bz[ 96] = 625.0; // first chip boundry
321         bz[127] = bz[128] = 625.0; // first chip boundry
322         bz[160] = 425.0;// Set so that there is no zero pixel size for fNz.
323         segSPD->SetBinSize(bx,bz); // Based on AliITSgeomSPD for now.
324         geom->ReSetShape(idet,segSPD);
325     }break;
326     case kSDD:{
327         initSeg[idet] = kTRUE;
328         AliITSsegmentationSDD *segSDD = new AliITSsegmentationSDD();
329         segSDD->SetDetSize(shapePar[0]*kcm2micron, // X
330                            2.*shapePar[2]*kcm2micron, // Z
331                            2.*shapePar[1]*kcm2micron);// Y  Microns
332         segSDD->SetNPads(256,256);// Anodes, Samples
333         geom->ReSetShape(idet,segSDD);
334     }break;
335     case kSSD:{
336         initSeg[idet] = kTRUE;
337         AliITSsegmentationSSD *segSSD = new AliITSsegmentationSSD();
338         segSSD->SetDetSize(2.*shapePar[0]*kcm2micron, // X
339                            2.*shapePar[2]*kcm2micron, // Z
340                            2.*shapePar[1]*kcm2micron);// Y  Microns.
341         segSSD->SetPadSize(95.,0.); // strip x pitch in microns
342         segSSD->SetNPads(768,2); // number of strips on each side, sides.
343         segSSD->SetAngles(0.0075,0.0275); // strip angels rad P and N side.
344         segSSD->SetAnglesLay5(0.0075,0.0275);//strip angels rad P and N
345         segSSD->SetAnglesLay6(0.0275,0.0075);//strip angels rad P and N
346         geom->ReSetShape(idet,segSSD);
347     }break;
348     default:{// Others, Note no kSDDp or kSSDp in this geometry.
349         geom->ReSetShape(idet,0);
350         Info("InitSegmentationPPRasymmFMD",
351              "default segmentation Dx=%f Dy=%f Dz=%f default=%d",
352              shapePar[0],shapePar[1],shapePar[2],idet);
353     }break;
354     } // end switch
355     return kTRUE;
356 }
357 //______________________________________________________________________
358 Bool_t AliITSInitGeometry::GetTransformation(const TString &volumePath,
359                                              TGeoHMatrix &mat){
360     // Returns the Transformation matrix between the volume specified
361     // by the path volumePath and the Top or mater volume. The format
362     // of the path volumePath is as follows (assuming ALIC is the Top volume)
363     // "/ALIC_1/DDIP_1/S05I_2/S05H_1/S05G_3". Here ALIC is the top most
364     // or master volume which has only 1 instance of. Of all of the daughter
365     // volumes of ALICE, DDIP volume copy #1 is indicated. Similarly for
366     // the daughter volume of DDIP is S05I copy #2 and so on.
367     // Inputs:
368     //   TString& volumePath  The volume path to the specific volume
369     //                        for which you want the matrix. Volume name
370     //                        hierarchy is separated by "/" while the
371     //                        copy number is appended using a "_".
372     // Outputs:
373     //  TGeoHMatrix &mat      A matrix with its values set to those
374     //                        appropriate to the Local to Master transformation
375     // Return:
376     //   A logical value if kFALSE then an error occurred and no change to
377     //   mat was made.
378
379     // We have to preserve the modeler state
380
381     // Preserve the modeler state.
382     gGeoManager->PushPath();
383     if (!gGeoManager->cd(volumePath.Data())) {
384         gGeoManager->PopPath();
385         Error("GetTransformation","Error in cd-ing to ",volumePath.Data());
386         return kFALSE;
387     } // end if !gGeoManager
388     mat = *gGeoManager->GetCurrentMatrix();
389     // Retstore the modeler state.
390     gGeoManager->PopPath();
391     return kTRUE;
392 }
393 //______________________________________________________________________
394 Bool_t AliITSInitGeometry::GetShape(const TString &volumePath,
395                                     TString &shapeType,TArrayD &par){
396     // Returns the shape and its parameters for the volume specified
397     // by volumeName.
398     // Inputs:
399     //   TString& volumeName  The volume name
400     // Outputs:
401     //   TString &shapeType   Shape type
402     //   TArrayD &par         A TArrayD of parameters with all of the
403     //                        parameters of the specified shape.
404     // Return:
405     //   A logical indicating whether there was an error in getting this
406     //   information
407     Int_t npar;
408     gGeoManager->PushPath();
409     if (!gGeoManager->cd(volumePath.Data())) {
410         gGeoManager->PopPath();
411         return kFALSE;
412     }
413     TGeoVolume * vol = gGeoManager->GetCurrentVolume();
414     gGeoManager->PopPath();
415     if (!vol) return kFALSE;
416     TGeoShape *shape = vol->GetShape();
417     TClass *classType = shape->IsA();
418     if (classType==TGeoBBox::Class()) {
419         shapeType = "BOX";
420         npar = 3;
421         par.Set(npar);
422         TGeoBBox *box = (TGeoBBox*)shape;
423         par.AddAt(box->GetDX(),0);
424         par.AddAt(box->GetDY(),1);
425         par.AddAt(box->GetDZ(),2);
426         return kTRUE;
427     }
428     if (classType==TGeoTrd1::Class()) {
429         shapeType = "TRD1";
430         npar = 4;
431         par.Set(npar);
432         TGeoTrd1 *trd1 = (TGeoTrd1*)shape;
433         par.AddAt(trd1->GetDx1(),0);
434         par.AddAt(trd1->GetDx2(),1);
435         par.AddAt(trd1->GetDy(), 2);
436         par.AddAt(trd1->GetDz(), 3);
437         return kTRUE;
438     }
439     if (classType==TGeoTrd2::Class()) {
440         shapeType = "TRD2";
441         npar = 5;
442         par.Set(npar);
443         TGeoTrd2 *trd2 = (TGeoTrd2*)shape;
444         par.AddAt(trd2->GetDx1(),0);
445         par.AddAt(trd2->GetDx2(),1);
446         par.AddAt(trd2->GetDy1(),2);
447         par.AddAt(trd2->GetDy2(),3);
448         par.AddAt(trd2->GetDz(), 4);
449         return kTRUE;
450     }
451     if (classType==TGeoTrap::Class()) {
452         shapeType = "TRAP";
453         npar = 11;
454         par.Set(npar);
455         TGeoTrap *trap = (TGeoTrap*)shape;
456         Double_t tth = TMath::Tan(trap->GetTheta()*TMath::DegToRad());
457         par.AddAt(trap->GetDz(),0);
458         par.AddAt(tth*TMath::Cos(trap->GetPhi()*TMath::DegToRad()),1);
459         par.AddAt(tth*TMath::Sin(trap->GetPhi()*TMath::DegToRad()),2);
460         par.AddAt(trap->GetH1(),3);
461         par.AddAt(trap->GetBl1(),4);
462         par.AddAt(trap->GetTl1(),5);
463         par.AddAt(TMath::Tan(trap->GetAlpha1()*TMath::DegToRad()),6);
464         par.AddAt(trap->GetH2(),7);
465         par.AddAt(trap->GetBl2(),8);
466         par.AddAt(trap->GetTl2(),9);
467         par.AddAt(TMath::Tan(trap->GetAlpha2()*TMath::DegToRad()),10);
468         return kTRUE;
469     }
470     if (classType==TGeoTube::Class()) {
471         shapeType = "TUBE";
472         npar = 3;
473         par.Set(npar);
474         TGeoTube *tube = (TGeoTube*)shape;
475         par.AddAt(tube->GetRmin(),0);
476         par.AddAt(tube->GetRmax(),1);
477         par.AddAt(tube->GetDz(),2);
478         return kTRUE;
479     }
480     if (classType==TGeoTubeSeg::Class()) {
481         shapeType = "TUBS";
482         npar = 5;
483         par.Set(npar);
484         TGeoTubeSeg *tubs = (TGeoTubeSeg*)shape;
485         par.AddAt(tubs->GetRmin(),0);
486         par.AddAt(tubs->GetRmax(),1);
487         par.AddAt(tubs->GetDz(),2);
488         par.AddAt(tubs->GetPhi1(),3);
489         par.AddAt(tubs->GetPhi2(),4);
490         return kTRUE;
491     }
492     if (classType==TGeoCone::Class()) {
493         shapeType = "CONE";
494         npar = 5;
495         par.Set(npar);
496         TGeoCone *cone = (TGeoCone*)shape;
497         par.AddAt(cone->GetDz(),0);
498         par.AddAt(cone->GetRmin1(),1);
499         par.AddAt(cone->GetRmax1(),2);
500         par.AddAt(cone->GetRmin2(),3);
501         par.AddAt(cone->GetRmax2(),4);
502         return kTRUE;
503     }
504     if (classType==TGeoConeSeg::Class()) {
505         shapeType = "CONS";
506         npar = 7;
507         par.Set(npar);
508         TGeoConeSeg *cons = (TGeoConeSeg*)shape;
509         par.AddAt(cons->GetDz(),0);
510         par.AddAt(cons->GetRmin1(),1);
511         par.AddAt(cons->GetRmax1(),2);
512         par.AddAt(cons->GetRmin2(),3);
513         par.AddAt(cons->GetRmax2(),4);
514         par.AddAt(cons->GetPhi1(),5);
515         par.AddAt(cons->GetPhi2(),6);
516         return kTRUE;
517     }
518     if (classType==TGeoSphere::Class()) {
519         shapeType = "SPHE";
520         npar = 6;
521         par.Set(npar);
522         
523         TGeoSphere *sphe = (TGeoSphere*)shape;
524         par.AddAt(sphe->GetRmin(),0);
525         par.AddAt(sphe->GetRmax(),1);
526         par.AddAt(sphe->GetTheta1(),2);
527         par.AddAt(sphe->GetTheta2(),3);
528         par.AddAt(sphe->GetPhi1(),4);
529         par.AddAt(sphe->GetPhi2(),5);
530         return kTRUE;
531     }
532     if (classType==TGeoPara::Class()) {
533         shapeType = "PARA";
534         npar = 6;
535         par.Set(npar);
536         TGeoPara *para = (TGeoPara*)shape;
537         par.AddAt(para->GetX(),0);
538         par.AddAt(para->GetY(),1);
539         par.AddAt(para->GetZ(),2);
540         par.AddAt(para->GetTxy(),3);
541         par.AddAt(para->GetTxz(),4);
542         par.AddAt(para->GetTyz(),5);
543         return kTRUE;
544     }
545     if (classType==TGeoPgon::Class()) {
546         shapeType = "PGON";
547         TGeoPgon *pgon = (TGeoPgon*)shape;
548         Int_t nz = pgon->GetNz();
549         const Double_t *rmin = pgon->GetRmin();
550         const Double_t *rmax = pgon->GetRmax();
551         const Double_t *z = pgon->GetZ();
552         npar = 4 + 3*nz;
553         par.Set(npar);
554         par.AddAt(pgon->GetPhi1(),0);
555         par.AddAt(pgon->GetDphi(),1);
556         par.AddAt(pgon->GetNedges(),2);
557         par.AddAt(pgon->GetNz(),3);
558         for (Int_t i=0; i<nz; i++) {
559             par.AddAt(z[i], 4+3*i);
560             par.AddAt(rmin[i], 4+3*i+1);
561             par.AddAt(rmax[i], 4+3*i+2);
562         }
563         return kTRUE;
564     }
565     if (classType==TGeoPcon::Class()) {
566         shapeType = "PCON";
567         TGeoPcon *pcon = (TGeoPcon*)shape;
568         Int_t nz = pcon->GetNz();
569         const Double_t *rmin = pcon->GetRmin();
570         const Double_t *rmax = pcon->GetRmax();
571         const Double_t *z = pcon->GetZ();
572         npar = 3 + 3*nz;
573         par.Set(npar);
574         par.AddAt(pcon->GetPhi1(),0);
575         par.AddAt(pcon->GetDphi(),1);
576         par.AddAt(pcon->GetNz(),2);
577         for (Int_t i=0; i<nz; i++) {
578             par.AddAt(z[i], 3+3*i);
579             
580             par.AddAt(rmin[i], 3+3*i+1);
581             par.AddAt(rmax[i], 3+3*i+2);
582         }
583         return kTRUE;
584     }
585     if (classType==TGeoEltu::Class()) {
586         shapeType = "ELTU";
587         npar = 3;
588         par.Set(npar);
589         TGeoEltu *eltu = (TGeoEltu*)shape;
590         par.AddAt(eltu->GetA(),0);
591         par.AddAt(eltu->GetB(),1);
592         par.AddAt(eltu->GetDz(),2);
593         return kTRUE;
594     }
595     if (classType==TGeoHype::Class()) {
596         shapeType = "HYPE";
597         npar = 5;
598         par.Set(npar);
599         TGeoHype *hype = (TGeoHype*)shape;
600         par.AddAt(TMath::Sqrt(hype->RadiusHypeSq(0.,kTRUE)),0);
601         par.AddAt(TMath::Sqrt(hype->RadiusHypeSq(0.,kFALSE)),1);
602         par.AddAt(hype->GetDZ(),2);
603         par.AddAt(hype->GetStIn(),3);
604         par.AddAt(hype->GetStOut(),4);
605         return kTRUE;
606     }
607     if (classType==TGeoGtra::Class()) {
608         shapeType = "GTRA";
609         npar = 12;
610         par.Set(npar);
611         TGeoGtra *trap = (TGeoGtra*)shape;
612         Double_t tth = TMath::Tan(trap->GetTheta()*TMath::DegToRad());
613         par.AddAt(trap->GetDz(),0);
614         par.AddAt(tth*TMath::Cos(trap->GetPhi()*TMath::DegToRad()),1);
615         par.AddAt(tth*TMath::Sin(trap->GetPhi()*TMath::DegToRad()),2);
616         par.AddAt(trap->GetH1(),3);
617         par.AddAt(trap->GetBl1(),4);
618         par.AddAt(trap->GetTl1(),5);
619         par.AddAt(TMath::Tan(trap->GetAlpha1()*TMath::DegToRad()),6);
620         par.AddAt(trap->GetH2(),7);
621         par.AddAt(trap->GetBl2(),8);
622         par.AddAt(trap->GetTl2(),9);
623         par.AddAt(TMath::Tan(trap->GetAlpha2()*TMath::DegToRad()),10);
624         par.AddAt(trap->GetTwistAngle(),11);
625         return kTRUE;
626     }
627     if (classType==TGeoCtub::Class()) {
628         shapeType = "CTUB";
629         npar = 11;
630         par.Set(npar);
631         TGeoCtub *ctub = (TGeoCtub*)shape;
632         const Double_t *lx = ctub->GetNlow();
633         const Double_t *tx = ctub->GetNhigh();
634         par.AddAt(ctub->GetRmin(),0);
635         par.AddAt(ctub->GetRmax(),1);
636         par.AddAt(ctub->GetDz(),2);
637         par.AddAt(ctub->GetPhi1(),3);
638         par.AddAt(ctub->GetPhi2(),4);
639         par.AddAt(lx[0],5);
640         par.AddAt(lx[1],6);
641         par.AddAt(lx[2],7);
642         par.AddAt(tx[0],8);
643         par.AddAt(tx[1],9);
644         par.AddAt(tx[2],10);
645         return kTRUE;
646     }
647     Error("GetShape","Getting shape parameters for shape %s not implemented",
648           shape->ClassName());
649     return kFALSE;
650 }
651 //______________________________________________________________________
652 void AliITSInitGeometry::DecodeDetector(Int_t &mod,Int_t layer,Int_t cpn0,
653                                         Int_t cpn1,Int_t cpn2) const {
654     // decode geometry into detector module number. There are two decoding
655     // Scheams. Old which does not follow the ALICE coordinate system
656     // requirements, and New which dose.
657     // Inputs:
658     //    Int_t layer    The ITS layer
659     //    Int_t cpn0     The lowest copy number
660     //    Int_t cpn1     The middle copy number
661     //    Int_t cpn2     the highest copy number
662     // Output:
663     //    Int_t &mod     The module number assoicated with this set
664     //                   of copy numbers.
665     // Return:
666     //    none.
667     const Int_t kDetPerLadderSPD[2]={2,4};
668     const Int_t kDetPerLadder[6]={4,4,6,8,22,25};
669     const Int_t kLadPerLayer[6]={20,40,14,22,34,38};
670     Int_t lay=-1,lad=-1,det=-1,i;
671
672     if(fDecode){ // New decoding scheam
673         switch (layer){
674         case 1:{
675             lay = layer;
676             det = 5-cpn2;
677             if(cpn0==4&&cpn1==1) lad=1;
678             else if(cpn0==4&&cpn1==2) lad=20;
679             else if(cpn0<4){
680                 lad = 8-cpn1-kDetPerLadderSPD[layer-1]*(cpn0-1);
681             }else{ // cpn0>4
682                 lad = 28-cpn1-kDetPerLadderSPD[layer-1]*(cpn0-1);
683             } // end if
684         } break;
685         case 2:{
686             lay = layer;
687             det = 5-cpn2;
688             if(cpn0==4&&cpn1==1) lad=1;
689             else if(cpn0<4){
690                 lad = 14-cpn1-kDetPerLadderSPD[layer-1]*(cpn0-1);
691             }else{ // cpn0>4
692                 lad = 54-cpn1-kDetPerLadderSPD[layer-1]*(cpn0-1);
693             } // end if
694         } break;
695         case 3:{
696             lay = layer;
697             if(cpn0<5) lad = 5-cpn0;
698             else lad = 19-cpn0;
699             det = 7-cpn1;
700         } break;
701         case 4:{
702             lay = layer;
703             if(cpn0<7) lad = 7-cpn0;
704             else lad = 29-cpn0;
705             det = 9-cpn1;
706         } break;
707         case 5:{
708             lay = layer;
709             if(cpn0<10) lad = 10-cpn0;
710             else lad = 44-cpn0;
711             det = 23-cpn1;
712         } break;
713         case 6:{
714             lay = layer;
715             if(cpn0<9) lad = 9-cpn0;
716             else lad = 47-cpn0;
717             det = 26-cpn1;
718         } break;
719         } // end switch
720         mod = 0;
721         for(i=0;i<layer-1;i++) mod += kLadPerLayer[i]*kDetPerLadder[i];
722         mod += kDetPerLadder[layer-1]*(lad-1)+det-1;// module start at zero.
723         return;
724     } // end if
725     // Old decoding scheam
726     switch(layer){
727     case 1: case 2:{
728         lay = layer;
729         lad = cpn1+kDetPerLadderSPD[layer-1]*(cpn0-1);
730         det = cpn2;
731         }break;
732     case 3: case 4:{
733         lay = layer;
734         lad = cpn0;
735         det = cpn1;
736         }break;
737     case 5: case 6:{
738         lay = layer;
739         lad = cpn0;
740         det = cpn1;
741         }break;
742     default:{
743         }break;
744     } // end switch
745     mod = 0;
746     for(i=0;i<layer-1;i++) mod += kLadPerLayer[i]*kDetPerLadder[i];
747     mod += kDetPerLadder[layer-1]*(lad-1)+det-1;// module start at zero.
748     return;
749 }
750 //______________________________________________________________________
751 void AliITSInitGeometry::RecodeDetector(Int_t mod,Int_t &cpn0,
752                                         Int_t &cpn1,Int_t &cpn2){
753     // decode geometry into detector module number. There are two decoding
754     // Scheams. Old which does not follow the ALICE coordinate system
755     // requirements, and New which dose.
756     // Inputs:
757     //    Int_t mod      The module number assoicated with this set
758     //                   of copy numbers.
759     // Output:
760     //    Int_t cpn0     The lowest copy number
761     //    Int_t cpn1     The middle copy number
762     //    Int_t cpn2     the highest copy number
763     // Return:
764     //    none.
765     const Int_t kITSgeoTreeCopys[6][3]= {{10, 2, 4},// lay=1
766                                          {10, 4, 4},// lay=2
767                                          {14, 6, 1},// lay=3
768                                          {22, 8, 1},// lay=4
769                                          {34,22, 1},// lay=5
770                                          {38,25, 1}};//lay=6
771     const Int_t kDetPerLadderSPD[2]={2,4};
772     //    const Int_t kDetPerLadder[6]={4,4,6,8,22,25};
773     //    const Int_t kLadPerLayer[6]={20,40,14,22,34,38};
774     Int_t lay,lad,det;
775
776     cpn0 = cpn1 = cpn2 = 0;
777     DecodeDetectorLayers(mod,lay,lad,det);
778     if(fDecode){ // New decoding scheam
779         switch (lay){
780         case 1:{
781             cpn2 = 5-det;     // Detector 1-4
782             cpn1 = 1+(lad-1)%kDetPerLadderSPD[lay-1];
783             cpn0 = 5-(lad+kDetPerLadderSPD[lay-1])/kDetPerLadderSPD[lay-1];
784             if(mod>27) cpn0 = 15-(lad+kDetPerLadderSPD[lay-1])/
785                            kDetPerLadderSPD[lay-1];
786         } break;
787         case 2:{
788             cpn2 = 5-det;     // Detector 1-4
789             cpn1 = 4-(lad+2)%kDetPerLadderSPD[lay-1];
790             cpn0 = 1+(14-cpn1-lad)/kDetPerLadderSPD[lay-1];
791             if(mod>131) cpn0 = 1+(54-lad-cpn1)/kDetPerLadderSPD[lay-1];
792         } break;
793         case 3:{
794             cpn2 = 1;
795             if(lad<5) cpn0 = 5-lad;
796             else cpn0 = 19-lad;
797             cpn1 = 7-det;
798         } break;
799         case 4:{
800             cpn2 = 1;
801             if(lad<7) cpn0 = 7-lad;
802             else cpn0 = 29-lad;
803             cpn1 = 9-det;
804         } break;
805         case 5:{
806             cpn2 = 1;
807             if(lad<10) cpn0 = 10-lad;
808             else cpn0 = 44-lad;
809             cpn1 = 23-det;
810         } break;
811         case 6:{
812             cpn2 = 1;
813             if(lad<9) cpn0 = 9-lad;
814             else cpn0 = 47-lad;
815             cpn1 = 26-det;
816         } break;
817         default:{
818             Error("RecodeDetector","New: mod=%d lay=%d not 1-6.");
819             return;
820         } break;
821         } // end switch
822         if(cpn0<1||cpn1<1||cpn2<1||
823            cpn0>kITSgeoTreeCopys[lay-1][0]||
824            cpn1>kITSgeoTreeCopys[lay-1][1]||
825            cpn2>kITSgeoTreeCopys[lay-1][2])
826             Error("RecodeDetector",
827                   "cpn0=%d cpn1=%d cpn2=%d mod=%d lay=%d lad=%d det=%d",
828                   cpn0,cpn1,cpn2,mod,lay,lad,det);
829         return;
830     } // end if
831     // Old encoding
832     switch (lay){
833     case 1: case 2:{
834         cpn2 = det;     // Detector 1-4
835         cpn0 = (lad+kDetPerLadderSPD[lay-1]-1)/kDetPerLadderSPD[lay-1];
836         cpn1 = (lad+kDetPerLadderSPD[lay-1]-1)%kDetPerLadderSPD[lay-1] + 1;
837     } break;
838     case 3: case 4: case 5 : case 6:{
839         cpn2 = 1;
840         cpn1 = det;
841         cpn0 = lad;
842     } break;
843     default:{
844         Error("RecodeDetector","Old: mod=%d lay=%d not 1-6.");
845         return;
846     } break;
847     } // end switch
848     if(cpn0<1||cpn1<1||cpn2<1||
849        cpn0>kITSgeoTreeCopys[lay-1][0]||
850        cpn1>kITSgeoTreeCopys[lay-1][1]||
851        cpn2>kITSgeoTreeCopys[lay-1][2])
852         Error("RecodeDetector",
853               "cpn0=%d cpn1=%d cpn2=%d mod=%d lay=%d lad=%d det=%d",
854               cpn0,cpn1,cpn2,mod,lay,lad,det);
855     return;
856 }
857 //______________________________________________________________________
858 void AliITSInitGeometry::DecodeDetectorLayers(Int_t mod,Int_t &lay,
859                                               Int_t &lad,Int_t &det){
860     // decode geometry into detector module number. There are two decoding
861     // Scheams. Old which does not follow the ALICE coordinate system
862     // requirements, and New which dose. Note, this use of layer ladder
863     // and detector numbers are strictly for internal use of this
864     // specific code. They do not represent the "standard" layer ladder
865     // or detector numbering except in a very old and obsoleate sence.
866     // Inputs:
867     //    Int_t mod      The module number assoicated with this set
868     //                   of copy numbers.
869     // Output:
870     //    Int_t lay     The layer number
871     //    Int_t lad     The ladder number
872     //    Int_t det     the dettector number
873     // Return:
874     //    none.
875   //    const Int_t kDetPerLadderSPD[2]={2,4};
876     const Int_t kDetPerLadder[6]={4,4,6,8,22,25};
877     const Int_t kLadPerLayer[6]={20,40,14,22,34,38};
878     Int_t mod2;
879
880     det  = 0;
881     lad  = 0;
882     lay  = 0;
883     mod2 = 0;
884     do{
885         mod2 += kLadPerLayer[lay]*kDetPerLadder[lay];
886         lay++;
887     }while(mod2<=mod); // end while
888     if(lay>6||lay<1) Error("DecodeDetectorLayers","0<lay=%d>6",lay);
889     mod2 -= kLadPerLayer[lay-1]*kDetPerLadder[lay-1];
890     do{
891         lad++;
892         mod2 += kDetPerLadder[lay-1];
893     }while(mod2<=mod); // end while
894     if(lad>kLadPerLayer[lay-1]||lad<1) Error("DecodeDetectorLayera",
895             "lad=%d>kLadPerLayer[lay-1=%d]=%d mod=%d mod2=%d",lad,lay-1,
896                                             kLadPerLayer[lay-1],mod,mod2);
897     mod2 -= kDetPerLadder[lay-1];
898     det = mod-mod2+1;
899     if(det>kDetPerLadder[lay-1]||det<1) Error("DecodeDetectorLayers",
900            "det=%d>detPerLayer[lay-1=%d]=%d mod=%d mod2=%d lad=%d",det,
901                                   lay-1,kDetPerLadder[lay-1],mod,mod2,lad);
902     return;
903 }
904