Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[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 <TGeoManager.h>
30 #include <TGeoMatrix.h>
31 #include <TGeoVolume.h>
32 #include <TGeoShape.h>
33 #include <TGeoBBox.h>
34 #include <TGeoTrd1.h>
35 #include <TGeoTrd2.h>
36 #include <TGeoArb8.h>
37 #include <TGeoTube.h>
38 #include <TGeoCone.h>
39 #include <TGeoSphere.h>
40 #include <TGeoPara.h>
41 #include <TGeoPgon.h>
42 #include <TGeoPcon.h>
43 #include <TGeoEltu.h>
44 #include <TGeoHype.h>
45 #include <TMath.h>
46
47 #include "AliLog.h"
48 #include "AliITSsegmentationSPD.h"
49 #include "AliITSsegmentationSDD.h"
50 #include "AliITSsegmentationSSD.h"
51 #include "AliITSInitGeometry.h"
52 #include <TDatime.h>
53
54 ClassImp(AliITSInitGeometry)
55
56 //______________________________________________________________________
57 AliITSInitGeometry::AliITSInitGeometry():
58 TObject(),                   // Base Class
59 fName(0),                    // Geometry name
60 fMajorVersion(kvDefault),    // Major versin number
61 fTiming(kFALSE),             // Flag to start inilization timing
62 fSegGeom(kFALSE),            // Flag to switch between the old use of
63                              // AliITSgeomS?D class, or AliITSsegmentation
64                              // class in fShape of AliITSgeom class.
65 fDecode(kFALSE),             // Flag for new/old decoding
66 fDebug(0){                   // Debug flag
67     // Default Creator
68     // Inputs:
69     //   none.
70     // Outputs:
71     //   none.
72     // Return:
73     //   A default inilized AliITSInitGeometry object
74
75     fName = "Undefined";
76 }
77 //______________________________________________________________________
78 AliITSInitGeometry::AliITSInitGeometry(AliITSVersion_t version):
79 TObject(),                   // Base Class
80 fName(0),                    // Geometry name
81 fMajorVersion(version),      // Major version number
82 fTiming(kFALSE),             // Flag to start inilization timing
83 fSegGeom(kFALSE),            // Flag to switch between the old use of
84                              // AliITSgeomS?D class, or AliITSsegmentation
85                              // class in fShape of AliITSgeom class.
86 fDecode(kFALSE),             // Flag for new/old decoding
87 fDebug(0){                   // Debug flag
88     // Default Creator
89     // Inputs:
90     //   none.
91     // Outputs:
92     //   none.
93     // Return:
94     //   A default inilized AliITSInitGeometry object
95
96   switch (version) {
97     case kv11:
98         fName="AliITSv11";
99         break;
100     case kvDefault:
101     default:
102         AliFatal(Form("Undefined geometry: fMajorVersion=%d, ",(Int_t)fMajorVersion));
103         fName = "Undefined";
104         break;
105     } // switch
106 }
107 //______________________________________________________________________
108 AliITSgeom* AliITSInitGeometry::CreateAliITSgeom(){
109     // Creates and Initilizes the geometry transformation class AliITSgeom
110     // to values appropreate to this specific geometry. Now that
111     // the segmentation is part of AliITSgeom, the detector
112     // segmentations are also defined here.
113     // Inputs:
114     //   none.
115     // Outputs:
116     //   none.
117     // Return:
118     //   A pointer to a new properly inilized AliITSgeom class. If
119     //   pointer = 0 then failed to init.
120
121
122   AliITSVersion_t version = kvDefault;
123   TDatime datetime;
124   TGeoVolume *itsV = gGeoManager->GetVolume("ITSV");
125   if(!itsV){
126     AliError("Can't find ITS volume ITSV, exiting - nothing done!");
127     return 0;
128   }// end if
129   const Char_t *title = itsV->GetTitle();
130   if(!ReadVersionString(title,version))
131     Warning("UpdateInternalGeometry","Can't read title=%s\n",title);
132   SetTiming(kFALSE);
133   SetSegGeom(kFALSE);
134   SetDecoding(kFALSE);
135   AliITSgeom *geom = CreateAliITSgeom(version);
136   AliDebug(1,"AliITSgeom object has been initialized from TGeo\n");
137   return geom;
138 }
139 //______________________________________________________________________
140 AliITSgeom* AliITSInitGeometry::CreateAliITSgeom(Int_t major){
141     // Creates and Initilizes the geometry transformation class AliITSgeom
142     // to values appropreate to this specific geometry. Now that
143     // the segmentation is part of AliITSgeom, the detector
144     // segmentations are also defined here.
145     // Inputs:
146     //   Int_t major   major version, see AliITSVersion_t
147     //   
148     // Outputs:
149     //   none.
150     // Return:
151     //   A pointer to a new properly inilized AliITSgeom class. If
152     //   pointer = 0 then failed to init.
153
154     switch(major){
155     case kv11:
156         SetGeometryName("AliITSv11");
157         SetVersion(kv11);
158         break;
159     case kvDefault:
160     default:
161         SetGeometryName("Undefined");
162         SetVersion(kvDefault);
163         break;
164     } // end switch
165     AliITSgeom *geom = new AliITSgeom();
166     if(!InitAliITSgeom(geom)){ // Error initilization failed
167         delete geom;
168         geom = 0;
169     } // end if
170     return geom;
171 }
172 //______________________________________________________________________
173 Bool_t AliITSInitGeometry::InitAliITSgeom(AliITSgeom *geom){
174   // Initilizes the geometry transformation class AliITSgeom
175   // to values appropreate to this specific geometry. Now that
176   // the segmentation is part of AliITSgeom, the detector
177   // segmentations are also defined here.
178   // Inputs:
179   //   AliITSgeom *geom  A pointer to the AliITSgeom class
180   // Outputs:
181   //   AliITSgeom *geom  This pointer recreated and properly inilized.
182   // Return:
183   //   none.
184
185     if(!gGeoManager){
186         AliFatal("The geometry manager has not been initialized (e.g. "
187                  "TGeoManager::Import(\"geometry.root\")should be "
188                  "called in advance) - exit forced");
189         return kFALSE;
190     } // end if
191     switch(fMajorVersion) {
192     case kv11: {
193         return InitAliITSgeomV11(geom);
194     } break; // end case
195     case kvDefault: default: {
196         AliFatal("Undefined geometry");
197         return kFALSE;
198     } break; // end case
199     } // end switch
200     return kFALSE;
201 }
202 //______________________________________________________________________
203 void AliITSInitGeometry::TransposeTGeoHMatrix(TGeoHMatrix *m)const{
204     // Transpose the rotation matrix part of a TGeoHMatrix. This
205     // is needed because TGeo stores the transpose of the rotation
206     // matrix as compared to what AliITSgeomMatrix uses (and Geant3).
207     // Inputs:
208     //    TGeoHMatrix *m  The matrix to be transposed
209     // Outputs:
210     //    TGEoHMatrix *m  The transposed matrix
211     // Return:
212     //    none.
213     Int_t i;
214     Double_t r[9];
215
216     if(m==0) return; // no matrix to transpose.
217     for(i=0;i<9;i += 4) r[i] = m->GetRotationMatrix()[i]; // diagonals
218     r[1] = m->GetRotationMatrix()[3];
219     r[2] = m->GetRotationMatrix()[6];
220     r[3] = m->GetRotationMatrix()[1];
221     r[5] = m->GetRotationMatrix()[7];
222     r[6] = m->GetRotationMatrix()[2];
223     r[7] = m->GetRotationMatrix()[5];
224     m->SetRotation(r);
225     return;
226 }
227
228
229 //______________________________________________________________________
230 Bool_t AliITSInitGeometry::InitAliITSgeomV11(AliITSgeom *geom){
231   // Initilizes the geometry transformation class AliITSgeom
232   // Now that the segmentation is part of AliITSgeom, the detector
233   // segmentations are also defined here.
234   //
235   // Inputs:
236   //   AliITSgeom *geom  A pointer to the AliITSgeom class
237   // Outputs:
238   //   AliITSgeom *geom  This pointer recreated and properly inilized.
239   // LG
240
241   const Int_t kItype  = 0; // Type of transformation defined 0=> Geant
242   const Int_t klayers = 6; // number of layers in the ITS
243   const Int_t kladders[klayers]   = {20,40,14,22,34,38}; // Number of ladders
244   const Int_t kdetectors[klayers] = {4,4,6,8,22,25};// number of detector/lad
245   const AliITSDetector kIdet[6]   = {kSPD,kSPD,kSDD,kSDD,kSSD,kSSD};
246   const TString kPathbase = "/ALIC_1/ITSV_1/";
247
248   const char *pathSPDsens1, *pathSPDsens2;
249   pathSPDsens1="%sITSSPD_1/ITSSPDCarbonFiberSectorV_%d/ITSSPDSensitiveVirtualvolumeM0_1/ITSSPDlay1-Stave_%d/ITSSPDhalf-Stave%d_1/ITSSPDlay1-Ladder_%d/ITSSPDlay1-sensor_1";
250   pathSPDsens2="%sITSSPD_1/ITSSPDCarbonFiberSectorV_%d/ITSSPDSensitiveVirtualvolumeM0_1/ITSSPDlay2-Stave_%d/ITSSPDhalf-Stave%d_1/ITSSPDlay2-Ladder_%d/ITSSPDlay2-sensor_1";
251
252   const char *pathSDDsens1, *pathSDDsens2;
253   pathSDDsens1 = "%sITSsddLayer3_1/ITSsddLadd_%d/ITSsddSensor3_%d/ITSsddWafer3_%d/ITSsddSensitivL3_1";
254   pathSDDsens2 = "%sITSsddLayer4_1/ITSsddLadd_%d/ITSsddSensor4_%d/ITSsddWafer4_%d/ITSsddSensitivL4_1";
255
256   const char *pathSSDsens1, *pathSSDsens2;
257   pathSSDsens1 = "%sITSssdLayer5_1/ITSssdLay5Ladd_%d/ITSssdSensor5_%d/ITSssdSensitivL5_1";
258   pathSSDsens2 = "%sITSssdLayer6_1/ITSssdLay6Ladd_%d/ITSssdSensor6_%d/ITSssdSensitivL6_1";
259
260   const TString kNames[klayers] = {
261     pathSPDsens1, // lay=1
262     pathSPDsens2, // lay=2
263     pathSDDsens1, // lay=3
264     pathSDDsens2, // lay=4
265     pathSSDsens1, // lay=5
266     pathSSDsens2};// Lay=6
267   
268   Int_t mod,nmods=0, lay, lad, det, cpn0, cpn1, cpn2, cpnHS=1;
269   Double_t tran[3]={0.,0.,0.}, rot[10]={9*0.0,1.0};
270   TArrayD shapePar;
271   TString path, shapeName;
272   TGeoHMatrix matrix;
273   Bool_t initSeg[3]={kFALSE, kFALSE, kFALSE};
274   TStopwatch *time = 0x0;
275   if(fTiming) time = new TStopwatch();
276
277   if(fTiming) time->Start();
278   for(mod=0;mod<klayers;mod++) nmods += kladders[mod]*kdetectors[mod];
279   geom->Init(kItype,klayers,kladders,kdetectors,nmods);
280
281   for(mod=0; mod<nmods; mod++) {
282
283     DecodeDetectorLayers(mod,lay,lad,det);
284     geom->CreateMatrix(mod,lay,lad,det,kIdet[lay-1],tran,rot);
285     RecodeDetector(mod,cpn0,cpn1,cpn2);
286
287     if (kIdet[lay-1]==kSPD) { // we need 1 more copy number because of the half-stave
288       if (det<3) cpnHS = 0; else cpnHS = 1;
289       path.Form(kNames[lay-1].Data(),kPathbase.Data(),cpn0,cpn1,cpnHS,cpn2);
290     } else {
291       path.Form(kNames[lay-1].Data(),kPathbase.Data(),cpn0,cpn1,cpn2);
292     };
293
294     geom->GetGeomMatrix(mod)->SetPath(path);
295     GetTransformation(path.Data(),matrix);
296     geom->SetTrans(mod,matrix.GetTranslation());
297     TransposeTGeoHMatrix(&matrix); //Transpose TGeo's rotation matrixes
298     geom->SetRotMatrix(mod,matrix.GetRotationMatrix());
299     if(initSeg[kIdet[lay-1]]) continue;
300     GetShape(path,shapeName,shapePar);
301     if(shapeName.CompareTo("BOX")){
302       Error("InitITSgeom","Geometry changed without proper code update"
303             "or error in reading geometry. Shape is not BOX.");
304       return kFALSE;
305     } // end if
306   } // end for module
307
308   if(fTiming){
309     time->Stop();
310     time->Print();
311     delete time;
312   } // end if
313   return kTRUE;
314 }
315
316 //_______________________________________________________________________
317 Bool_t AliITSInitGeometry::GetTransformation(const TString &volumePath,
318                                              TGeoHMatrix &mat){
319     // Returns the Transformation matrix between the volume specified
320     // by the path volumePath and the Top or mater volume. The format
321     // of the path volumePath is as follows (assuming ALIC is the Top volume)
322     // "/ALIC_1/DDIP_1/S05I_2/S05H_1/S05G_3". Here ALIC is the top most
323     // or master volume which has only 1 instance of. Of all of the daughter
324     // volumes of ALICE, DDIP volume copy #1 is indicated. Similarly for
325     // the daughter volume of DDIP is S05I copy #2 and so on.
326     // Inputs:
327     //   TString& volumePath  The volume path to the specific volume
328     //                        for which you want the matrix. Volume name
329     //                        hierarchy is separated by "/" while the
330     //                        copy number is appended using a "_".
331     // Outputs:
332     //  TGeoHMatrix &mat      A matrix with its values set to those
333     //                        appropriate to the Local to Master transformation
334     // Return:
335     //   A logical value if kFALSE then an error occurred and no change to
336     //   mat was made.
337
338     // We have to preserve the modeler state
339
340     // Preserve the modeler state.
341     gGeoManager->PushPath();
342     if (!gGeoManager->cd(volumePath.Data())) {
343       gGeoManager->PopPath();
344       Error("GetTransformation","Error in cd-ing to %s",volumePath.Data());
345       return kFALSE;
346     } // end if !gGeoManager
347     mat = *gGeoManager->GetCurrentMatrix();
348     // Retstore the modeler state.
349     gGeoManager->PopPath();
350     return kTRUE;
351 }
352 //______________________________________________________________________
353 Bool_t AliITSInitGeometry::GetShape(const TString &volumePath,
354                                     TString &shapeType,TArrayD &par){
355     // Returns the shape and its parameters for the volume specified
356     // by volumeName.
357     // Inputs:
358     //   TString& volumeName  The volume name
359     // Outputs:
360     //   TString &shapeType   Shape type
361     //   TArrayD &par         A TArrayD of parameters with all of the
362     //                        parameters of the specified shape.
363     // Return:
364     //   A logical indicating whether there was an error in getting this
365     //   information
366     Int_t npar;
367     gGeoManager->PushPath();
368     if (!gGeoManager->cd(volumePath.Data())) {
369         gGeoManager->PopPath();
370         return kFALSE;
371     }
372     TGeoVolume * vol = gGeoManager->GetCurrentVolume();
373     gGeoManager->PopPath();
374     if (!vol) return kFALSE;
375     TGeoShape *shape = vol->GetShape();
376     TClass *classType = shape->IsA();
377     if (classType==TGeoBBox::Class()) {
378         shapeType = "BOX";
379         npar = 3;
380         par.Set(npar);
381         TGeoBBox *box = (TGeoBBox*)shape;
382         par.AddAt(box->GetDX(),0);
383         par.AddAt(box->GetDY(),1);
384         par.AddAt(box->GetDZ(),2);
385         return kTRUE;
386     } // end if
387     if (classType==TGeoTrd1::Class()) {
388         shapeType = "TRD1";
389         npar = 4;
390         par.Set(npar);
391         TGeoTrd1 *trd1 = (TGeoTrd1*)shape;
392         par.AddAt(trd1->GetDx1(),0);
393         par.AddAt(trd1->GetDx2(),1);
394         par.AddAt(trd1->GetDy(), 2);
395         par.AddAt(trd1->GetDz(), 3);
396         return kTRUE;
397     } // end if
398     if (classType==TGeoTrd2::Class()) {
399         shapeType = "TRD2";
400         npar = 5;
401         par.Set(npar);
402         TGeoTrd2 *trd2 = (TGeoTrd2*)shape;
403         par.AddAt(trd2->GetDx1(),0);
404         par.AddAt(trd2->GetDx2(),1);
405         par.AddAt(trd2->GetDy1(),2);
406         par.AddAt(trd2->GetDy2(),3);
407         par.AddAt(trd2->GetDz(), 4);
408         return kTRUE;
409     } // end if
410     if (classType==TGeoTrap::Class()) {
411         shapeType = "TRAP";
412         npar = 11;
413         par.Set(npar);
414         TGeoTrap *trap = (TGeoTrap*)shape;
415         Double_t tth = TMath::Tan(trap->GetTheta()*TMath::DegToRad());
416         par.AddAt(trap->GetDz(),0);
417         par.AddAt(tth*TMath::Cos(trap->GetPhi()*TMath::DegToRad()),1);
418         par.AddAt(tth*TMath::Sin(trap->GetPhi()*TMath::DegToRad()),2);
419         par.AddAt(trap->GetH1(),3);
420         par.AddAt(trap->GetBl1(),4);
421         par.AddAt(trap->GetTl1(),5);
422         par.AddAt(TMath::Tan(trap->GetAlpha1()*TMath::DegToRad()),6);
423         par.AddAt(trap->GetH2(),7);
424         par.AddAt(trap->GetBl2(),8);
425         par.AddAt(trap->GetTl2(),9);
426         par.AddAt(TMath::Tan(trap->GetAlpha2()*TMath::DegToRad()),10);
427         return kTRUE;
428     } // end if
429     if (classType==TGeoTube::Class()) {
430         shapeType = "TUBE";
431         npar = 3;
432         par.Set(npar);
433         TGeoTube *tube = (TGeoTube*)shape;
434         par.AddAt(tube->GetRmin(),0);
435         par.AddAt(tube->GetRmax(),1);
436         par.AddAt(tube->GetDz(),2);
437         return kTRUE;
438     } // end if
439     if (classType==TGeoTubeSeg::Class()) {
440         shapeType = "TUBS";
441         npar = 5;
442         par.Set(npar);
443         TGeoTubeSeg *tubs = (TGeoTubeSeg*)shape;
444         par.AddAt(tubs->GetRmin(),0);
445         par.AddAt(tubs->GetRmax(),1);
446         par.AddAt(tubs->GetDz(),2);
447         par.AddAt(tubs->GetPhi1(),3);
448         par.AddAt(tubs->GetPhi2(),4);
449         return kTRUE;
450     } // end if
451     if (classType==TGeoCone::Class()) {
452         shapeType = "CONE";
453         npar = 5;
454         par.Set(npar);
455         TGeoCone *cone = (TGeoCone*)shape;
456         par.AddAt(cone->GetDz(),0);
457         par.AddAt(cone->GetRmin1(),1);
458         par.AddAt(cone->GetRmax1(),2);
459         par.AddAt(cone->GetRmin2(),3);
460         par.AddAt(cone->GetRmax2(),4);
461         return kTRUE;
462     } // end if
463     if (classType==TGeoConeSeg::Class()) {
464         shapeType = "CONS";
465         npar = 7;
466         par.Set(npar);
467         TGeoConeSeg *cons = (TGeoConeSeg*)shape;
468         par.AddAt(cons->GetDz(),0);
469         par.AddAt(cons->GetRmin1(),1);
470         par.AddAt(cons->GetRmax1(),2);
471         par.AddAt(cons->GetRmin2(),3);
472         par.AddAt(cons->GetRmax2(),4);
473         par.AddAt(cons->GetPhi1(),5);
474         par.AddAt(cons->GetPhi2(),6);
475         return kTRUE;
476     } // end if
477     if (classType==TGeoSphere::Class()) {
478         shapeType = "SPHE";
479         npar = 6;
480         par.Set(npar);
481         
482         TGeoSphere *sphe = (TGeoSphere*)shape;
483         par.AddAt(sphe->GetRmin(),0);
484         par.AddAt(sphe->GetRmax(),1);
485         par.AddAt(sphe->GetTheta1(),2);
486         par.AddAt(sphe->GetTheta2(),3);
487         par.AddAt(sphe->GetPhi1(),4);
488         par.AddAt(sphe->GetPhi2(),5);
489         return kTRUE;
490     } // end if
491     if (classType==TGeoPara::Class()) {
492         shapeType = "PARA";
493         npar = 6;
494         par.Set(npar);
495         TGeoPara *para = (TGeoPara*)shape;
496         par.AddAt(para->GetX(),0);
497         par.AddAt(para->GetY(),1);
498         par.AddAt(para->GetZ(),2);
499         par.AddAt(para->GetTxy(),3);
500         par.AddAt(para->GetTxz(),4);
501         par.AddAt(para->GetTyz(),5);
502         return kTRUE;
503     } // end if
504     if (classType==TGeoPgon::Class()) {
505         shapeType = "PGON";
506         TGeoPgon *pgon = (TGeoPgon*)shape;
507         Int_t nz = pgon->GetNz();
508         const Double_t *rmin = pgon->GetRmin();
509         const Double_t *rmax = pgon->GetRmax();
510         const Double_t *z = pgon->GetZ();
511         npar = 4 + 3*nz;
512         par.Set(npar);
513         par.AddAt(pgon->GetPhi1(),0);
514         par.AddAt(pgon->GetDphi(),1);
515         par.AddAt(pgon->GetNedges(),2);
516         par.AddAt(pgon->GetNz(),3);
517         for (Int_t i=0; i<nz; i++) {
518             par.AddAt(z[i], 4+3*i);
519             par.AddAt(rmin[i], 4+3*i+1);
520             par.AddAt(rmax[i], 4+3*i+2);
521         }
522         return kTRUE;
523     } // end if
524     if (classType==TGeoPcon::Class()) {
525         shapeType = "PCON";
526         TGeoPcon *pcon = (TGeoPcon*)shape;
527         Int_t nz = pcon->GetNz();
528         const Double_t *rmin = pcon->GetRmin();
529         const Double_t *rmax = pcon->GetRmax();
530         const Double_t *z = pcon->GetZ();
531         npar = 3 + 3*nz;
532         par.Set(npar);
533         par.AddAt(pcon->GetPhi1(),0);
534         par.AddAt(pcon->GetDphi(),1);
535         par.AddAt(pcon->GetNz(),2);
536         for (Int_t i=0; i<nz; i++) {
537             par.AddAt(z[i], 3+3*i);
538             
539             par.AddAt(rmin[i], 3+3*i+1);
540             par.AddAt(rmax[i], 3+3*i+2);
541         }
542         return kTRUE;
543     } // end if
544     if (classType==TGeoEltu::Class()) {
545         shapeType = "ELTU";
546         npar = 3;
547         par.Set(npar);
548         TGeoEltu *eltu = (TGeoEltu*)shape;
549         par.AddAt(eltu->GetA(),0);
550         par.AddAt(eltu->GetB(),1);
551         par.AddAt(eltu->GetDz(),2);
552         return kTRUE;
553     } // end if
554     if (classType==TGeoHype::Class()) {
555         shapeType = "HYPE";
556         npar = 5;
557         par.Set(npar);
558         TGeoHype *hype = (TGeoHype*)shape;
559         par.AddAt(TMath::Sqrt(hype->RadiusHypeSq(0.,kTRUE)),0);
560         par.AddAt(TMath::Sqrt(hype->RadiusHypeSq(0.,kFALSE)),1);
561         par.AddAt(hype->GetDZ(),2);
562         par.AddAt(hype->GetStIn(),3);
563         par.AddAt(hype->GetStOut(),4);
564         return kTRUE;
565     } // end if
566     if (classType==TGeoGtra::Class()) {
567         shapeType = "GTRA";
568         npar = 12;
569         par.Set(npar);
570         TGeoGtra *trap = (TGeoGtra*)shape;
571         Double_t tth = TMath::Tan(trap->GetTheta()*TMath::DegToRad());
572         par.AddAt(trap->GetDz(),0);
573         par.AddAt(tth*TMath::Cos(trap->GetPhi()*TMath::DegToRad()),1);
574         par.AddAt(tth*TMath::Sin(trap->GetPhi()*TMath::DegToRad()),2);
575         par.AddAt(trap->GetH1(),3);
576         par.AddAt(trap->GetBl1(),4);
577         par.AddAt(trap->GetTl1(),5);
578         par.AddAt(TMath::Tan(trap->GetAlpha1()*TMath::DegToRad()),6);
579         par.AddAt(trap->GetH2(),7);
580         par.AddAt(trap->GetBl2(),8);
581         par.AddAt(trap->GetTl2(),9);
582         par.AddAt(TMath::Tan(trap->GetAlpha2()*TMath::DegToRad()),10);
583         par.AddAt(trap->GetTwistAngle(),11);
584         return kTRUE;
585     } // end if
586     if (classType==TGeoCtub::Class()) {
587         shapeType = "CTUB";
588         npar = 11;
589         par.Set(npar);
590         TGeoCtub *ctub = (TGeoCtub*)shape;
591         const Double_t *lx = ctub->GetNlow();
592         const Double_t *tx = ctub->GetNhigh();
593         par.AddAt(ctub->GetRmin(),0);
594         par.AddAt(ctub->GetRmax(),1);
595         par.AddAt(ctub->GetDz(),2);
596         par.AddAt(ctub->GetPhi1(),3);
597         par.AddAt(ctub->GetPhi2(),4);
598         par.AddAt(lx[0],5);
599         par.AddAt(lx[1],6);
600         par.AddAt(lx[2],7);
601         par.AddAt(tx[0],8);
602         par.AddAt(tx[1],9);
603         par.AddAt(tx[2],10);
604         return kTRUE;
605     } // end if
606     Error("GetShape","Getting shape parameters for shape %s not implemented",
607           shape->ClassName());
608     shapeType = "Unknown";
609     return kFALSE;
610 }
611 //______________________________________________________________________
612 void AliITSInitGeometry::DecodeDetector(
613     Int_t &mod,Int_t layer,Int_t cpn0,Int_t cpn1,Int_t cpn2) const {
614     // decode geometry into detector module number. There are two decoding
615     // Scheams. Old which does not follow the ALICE coordinate system
616     // requirements, and New which dose.
617     // Inputs:
618     //    Int_t layer    The ITS layer
619     //    Int_t cpn0     The lowest copy number
620     //    Int_t cpn1     The middle copy number
621     //    Int_t cpn2     the highest copy number
622     // Output:
623     //    Int_t &mod     The module number assoicated with this set
624     //                   of copy numbers.
625     // Return:
626     //    none.
627
628     // This is a FIXED switch yard function. I (Bjorn Nilsen) Don't 
629     // like them but I see not better way for the moment.
630     switch (fMajorVersion){
631     case kvDefault:{
632         Error("DecodeDetector","Major version = kvDefault, not supported");
633     }break;
634     case kv11:{
635         return DecodeDetectorv11(mod,layer,cpn0,cpn1,cpn2);
636     }break;
637     default:{
638         Error("DecodeDetector","Major version = %d, not supported",
639               (Int_t)fMajorVersion);
640         return;
641     }break;
642     } // end switch
643     return;
644 }
645 //______________________________________________________________________
646 void AliITSInitGeometry::RecodeDetector(Int_t mod,Int_t &cpn0,
647                                         Int_t &cpn1,Int_t &cpn2){
648     // decode geometry into detector module number. There are two decoding
649     // Scheams. Old which does not follow the ALICE coordinate system
650     // requirements, and New which dose.
651     // Inputs:
652     //    Int_t mod      The module number assoicated with this set
653     //                   of copy numbers.
654     // Output:
655     //    Int_t cpn0     The lowest copy number
656     //    Int_t cpn1     The middle copy number
657     //    Int_t cpn2     the highest copy number
658     // Return:
659     //    none.
660
661     // This is a FIXED switch yard function. I (Bjorn Nilsen) Don't 
662     // like them but I see not better way for the moment.
663     switch (fMajorVersion){
664     case kvDefault:{
665         Error("RecodeDetector","Major version = kvDefault, not supported");
666         return;
667     }
668     case kv11:{
669         return RecodeDetectorv11(mod,cpn0,cpn1,cpn2);
670     }break;
671     default:{
672         Error("RecodeDetector","Major version = %d, not supported",
673               (Int_t)fMajorVersion);
674         return;
675     }break;
676     } // end switch
677     return;
678 }
679 //______________________________________________________________________
680 void AliITSInitGeometry::DecodeDetectorLayers(Int_t mod,Int_t &layer,
681                                               Int_t &lad,Int_t &det){
682     // decode geometry into detector module number. There are two decoding
683     // Scheams. Old which does not follow the ALICE coordinate system
684     // requirements, and New which dose. Note, this use of layer ladder
685     // and detector numbers are strictly for internal use of this
686     // specific code. They do not represent the "standard" layer ladder
687     // or detector numbering except in a very old and obsoleate sence.
688     // Inputs:
689     //    Int_t mod      The module number assoicated with this set
690     //                   of copy numbers.
691     // Output:
692     //    Int_t lay     The layer number
693     //    Int_t lad     The ladder number
694     //    Int_t det     the dettector number
695     // Return:
696     //    none.
697
698     // This is a FIXED switch yard function. I (Bjorn Nilsen) Don't 
699     // like them but I see not better way for the moment.
700     switch (fMajorVersion) {
701     case kvDefault:{
702         Error("DecodeDetectorLayers",
703               "Major version = kvDefault, not supported");
704         return;
705     }break;
706     case kv11:{
707         return DecodeDetectorLayersv11(mod,layer,lad,det);
708     }break;
709     default:{
710         Error("DecodeDetectorLayers","Major version = %d, not supported",
711               (Int_t)fMajorVersion);
712         return;
713     }break;
714     } // end switch
715     return;
716 }
717
718 //______________________________________________________________________
719 void AliITSInitGeometry::DecodeDetectorv11(Int_t &mod,Int_t layer,
720                                  Int_t cpn0,Int_t cpn1,Int_t cpn2) const {
721     // decode geometry into detector module number
722     // Inputs:
723     //    Int_t layer    The ITS layer
724     //    Int_t cpn0     The lowest copy number
725     //    Int_t cpn1     The middle copy number
726     //    Int_t cpn2     the highest copy number
727     // Output:
728     //    Int_t &mod     The module number assoicated with this set
729     //                   of copy numbers.
730     // Return:
731     //    none.
732   const Int_t kDetPerLadderSPD[2]={2,4};
733   const Int_t kDetPerLadder[6]={4,4,6,8,22,25};
734   const Int_t kLadPerLayer[6]={20,40,14,22,34,38};
735   Int_t lad=-1,det=-1;
736   
737   switch(layer) {
738   case 1: case 2:{
739     lad = cpn1+kDetPerLadderSPD[layer-1]*(cpn0-1);
740     det = cpn2;
741   } break;
742   case 3: case 4:{
743     lad = cpn0+1;
744     det = cpn1+1;
745   } break;
746   case 5: case 6:{
747     lad = cpn0+1;
748     det = cpn1+1;
749   } break;
750   default:{
751   } break;
752   } // end switch
753   mod = 0;
754   for(Int_t i=0;i<layer-1;i++) mod += kLadPerLayer[i]*kDetPerLadder[i];
755   mod += kDetPerLadder[layer-1]*(lad-1)+det-1;// module start at zero.
756   return;
757 }
758
759
760 //______________________________________________________________________
761 void AliITSInitGeometry::RecodeDetectorv11(Int_t mod,Int_t &cpn0,
762                                            Int_t &cpn1,Int_t &cpn2) {
763     // decode geometry into detector module number using the new decoding
764     // Scheme.
765     // Inputs:
766     //    Int_t mod      The module number assoicated with this set
767     //                   of copy numbers.
768     // Output:
769     //    Int_t cpn0     The lowest copy number  (SPD sector or SDD/SSD ladder)
770     //    Int_t cpn1     The middle copy number  (SPD stave or SDD/SSD module)
771     //    Int_t cpn2     the highest copy number (SPD ladder or 1 for SDD/SSD)
772     // Return:
773     //    none.
774     const Int_t kDetPerLadderSPD[2]={2,4};
775     Int_t lay,lad,det;
776
777     DecodeDetectorLayersv11(mod,lay,lad,det);
778     if (lay<3) { // SPD
779         cpn2 = det;     // Detector 1-4
780         cpn0 = (lad+kDetPerLadderSPD[lay-1]-1)/kDetPerLadderSPD[lay-1];
781         cpn1 = (lad+kDetPerLadderSPD[lay-1]-1)%kDetPerLadderSPD[lay-1] + 1;
782     } else { // SDD and SSD
783         cpn2 = 1;
784         cpn1 = det;
785         cpn0 = lad;
786         if (lay<5) { // SDD
787           cpn1--;
788           cpn0--;
789         } else { //SSD
790           cpn1--;
791           cpn0--;
792         } // end if Lay<5/else
793     } // end if lay<3/else
794
795 }
796
797
798 //______________________________________________________________________
799 void AliITSInitGeometry::DecodeDetectorLayersv11(Int_t mod,Int_t &lay,
800                                                  Int_t &lad,Int_t &det) {
801
802   // decode module number into detector indices for v11
803   // mod starts from 0
804   // lay, lad, det start from 1
805
806   // Inputs:
807   //    Int_t mod      The module number associated with this set
808   //                   of copy numbers.
809   // Output:
810   //    Int_t lay     The layer number
811   //    Int_t lad     The ladder number
812   //    Int_t det     the dettector number
813
814   const Int_t kDetPerLadder[6] = {4,4,6,8,22,25};
815   const Int_t kLadPerLayer[6]  = {20,40,14,22,34,38};
816   
817   Int_t mod2 = 0;
818   lay  = 0;
819   
820   do {
821     mod2 += kLadPerLayer[lay]*kDetPerLadder[lay];
822     lay++;
823   } while(mod2<=mod); // end while
824   if(lay>6) Error("DecodeDetectorLayers","lay=%d>6",lay);
825
826   mod2 = kLadPerLayer[lay-1]*kDetPerLadder[lay-1] - mod2+mod;
827   lad = mod2/kDetPerLadder[lay-1];
828
829   if(lad>=kLadPerLayer[lay-1]||lad<0) Error("DecodeDetectorLayers",
830                                       "lad=%d not in the correct range",lad);
831   det = (mod2 - lad*kDetPerLadder[lay-1])+1;
832   if(det>kDetPerLadder[lay-1]||det<1) Error("DecodeDetectorLayers",
833                                       "det=%d not in the correct range",det);
834   lad++;
835 }
836
837 //______________________________________________________________________
838 Bool_t AliITSInitGeometry::WriteVersionString(Char_t *str,Int_t length,AliITSVersion_t maj)const{
839     // fills the string str with the major version number
840     // Inputs:
841     //   Char_t *str          The character string to hold the major version number
842     //   Int_t  length        The maximum number of characters which 
843     //                        can be accommodated by this string. 
844     //                        str[length-1] must exist
845     //   AliITSVersion_t maj  The major number
846
847
848     Int_t i = (Int_t)maj;
849  
850     snprintf(str,length-1,"Major Version= %d",i);
851     return kTRUE;
852 }
853 //______________________________________________________________________
854 Bool_t AliITSInitGeometry::ReadVersionString(const Char_t *str,AliITSVersion_t &maj)const{
855     // fills the string str with the major and minor version number
856     // Inputs:
857     //   Char_t *str   The character string to holding the major version number
858     //   Int_t  length The maximum number of characters which can be
859     //                 accommodated by this string. str[length-1] must exist
860     // Outputs:
861     //   AliITSVersion_t maj  The major number
862
863     // Return:
864     //   kTRUE if no errors
865
866   Bool_t retcode=kFALSE;
867   Int_t n=strlen(str);
868   if(n<15) return retcode; // not enough space for numbers
869   Int_t m,i;
870   m = sscanf(str,"Major Version= %2d",&i);
871   maj = kvDefault;
872   if(m>0){
873     retcode = kTRUE;
874     if(i==11){
875       maj = kv11;
876     }
877   }
878   return retcode;
879 }
880
881