]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSInitGeometry.cxx
The v11 geometry can now be used instead the v11hybrid. This is just a clean-up....
[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 const Bool_t AliITSInitGeometry::fgkOldSPDbarrel = kFALSE;
57 const Bool_t AliITSInitGeometry::fgkOldSDDbarrel = kFALSE;
58 const Bool_t AliITSInitGeometry::fgkOldSSDbarrel = kFALSE;
59 const Bool_t AliITSInitGeometry::fgkOldSDDcone   = kFALSE;
60 const Bool_t AliITSInitGeometry::fgkOldSSDcone   = kFALSE;
61 const Bool_t AliITSInitGeometry::fgkOldSPDshield = kFALSE;
62 const Bool_t AliITSInitGeometry::fgkOldSDDshield = kTRUE;
63 const Bool_t AliITSInitGeometry::fgkOldSSDshield = kTRUE;
64 const Bool_t AliITSInitGeometry::fgkOldServices  = kFALSE;
65 const Bool_t AliITSInitGeometry::fgkOldSupports  = kFALSE;
66 //______________________________________________________________________
67 AliITSInitGeometry::AliITSInitGeometry():
68 TObject(),                   // Base Class
69 fName(0),                    // Geometry name
70 fMinorVersion(-1),           // Minor version number/type
71 fMajorVersion(kvDefault),    // Major versin number
72 fTiming(kFALSE),             // Flag to start inilization timing
73 fSegGeom(kFALSE),            // Flag to switch between the old use of
74                              // AliITSgeomS?D class, or AliITSsegmentation
75                              // class in fShape of AliITSgeom class.
76 fDecode(kFALSE),             // Flag for new/old decoding
77 fDebug(0){                   // Debug flag
78     // Default Creator
79     // Inputs:
80     //   none.
81     // Outputs:
82     //   none.
83     // Return:
84     //   A default inilized AliITSInitGeometry object
85
86     fName = "Undefined";
87 }
88 //______________________________________________________________________
89 AliITSInitGeometry::AliITSInitGeometry(AliITSVersion_t version,
90                                        Int_t minorversion):
91 TObject(),                   // Base Class
92 fName(0),                    // Geometry name
93 fMinorVersion(minorversion), // Minor version number/type
94 fMajorVersion(version),      // Major versin number
95 fTiming(kFALSE),             // Flag to start inilization timing
96 fSegGeom(kFALSE),            // Flag to switch between the old use of
97                              // AliITSgeomS?D class, or AliITSsegmentation
98                              // class in fShape of AliITSgeom class.
99 fDecode(kFALSE),             // Flag for new/old decoding
100 fDebug(0){                   // Debug flag
101     // Default Creator
102     // Inputs:
103     //   none.
104     // Outputs:
105     //   none.
106     // Return:
107     //   A default inilized AliITSInitGeometry object
108
109   switch (version) {
110     case kv11:
111         fName="AliITSv11";
112         break;
113     case kv11Hybrid:
114         fName="AliITSv11Hybrid";
115         break;
116     case kvDefault:
117     default:
118         AliFatal(Form("Undefined geometry: fMajorVersion=%d, "
119                       "fMinorVersion= %d",(Int_t)fMajorVersion,fMinorVersion));
120         fName = "Undefined";
121         break;
122     } // switch
123 }
124 //______________________________________________________________________
125 AliITSgeom* AliITSInitGeometry::CreateAliITSgeom(){
126     // Creates and Initilizes the geometry transformation class AliITSgeom
127     // to values appropreate to this specific geometry. Now that
128     // the segmentation is part of AliITSgeom, the detector
129     // segmentations are also defined here.
130     // Inputs:
131     //   none.
132     // Outputs:
133     //   none.
134     // Return:
135     //   A pointer to a new properly inilized AliITSgeom class. If
136     //   pointer = 0 then failed to init.
137
138
139   AliITSVersion_t version = kvDefault;
140   Int_t minor = 0;
141   TDatime datetime;
142   TGeoVolume *itsV = gGeoManager->GetVolume("ITSV");
143   if(!itsV){
144     Error("CreateAliITSgeom","Can't find ITS volume ITSV, aborting");
145     return 0;
146   }// end if
147   const Char_t *title = itsV->GetTitle();
148   if(!ReadVersionString(title,(Int_t)strlen(title),version,minor,
149                         datetime))
150     Warning("UpdateInternalGeometry","Can't read title=%s\n",title);
151   SetTiming(kFALSE);
152   SetSegGeom(kFALSE);
153   SetDecoding(kFALSE);
154   AliITSgeom *geom = CreateAliITSgeom(version,minor);
155   AliDebug(1,"AliITSgeom object has been initialized from TGeo\n");
156   return geom;
157 }
158 //______________________________________________________________________
159 AliITSgeom* AliITSInitGeometry::CreateAliITSgeom(Int_t major,Int_t minor){
160     // Creates and Initilizes the geometry transformation class AliITSgeom
161     // to values appropreate to this specific geometry. Now that
162     // the segmentation is part of AliITSgeom, the detector
163     // segmentations are also defined here.
164     // Inputs:
165     //   Int_t major   major version, see AliITSVersion_t
166     //   Int_t minor   minor version
167     // Outputs:
168     //   none.
169     // Return:
170     //   A pointer to a new properly inilized AliITSgeom class. If
171     //   pointer = 0 then failed to init.
172
173     switch(major){
174     case kv11:
175         SetGeometryName("AliITSv11");
176         SetVersion(kv11,minor);
177         break;
178     case kv11Hybrid:
179         SetGeometryName("AliITSv11Hybrid");
180         SetVersion(kv11Hybrid,minor);
181         break;
182     case kvDefault:
183     default:
184         SetGeometryName("Undefined");
185         SetVersion(kvDefault,minor);
186         break;
187     } // end switch
188     AliITSgeom *geom = new AliITSgeom();
189     if(!InitAliITSgeom(geom)){ // Error initilization failed
190         delete geom;
191         geom = 0;
192     } // end if
193     return geom;
194 }
195 //______________________________________________________________________
196 Bool_t AliITSInitGeometry::InitAliITSgeom(AliITSgeom *geom){
197   // Initilizes the geometry transformation class AliITSgeom
198   // to values appropreate to this specific geometry. Now that
199   // the segmentation is part of AliITSgeom, the detector
200   // segmentations are also defined here.
201   // Inputs:
202   //   AliITSgeom *geom  A pointer to the AliITSgeom class
203   // Outputs:
204   //   AliITSgeom *geom  This pointer recreated and properly inilized.
205   // Return:
206   //   none.
207
208     if(!gGeoManager){
209         AliFatal("The geometry manager has not been initialized (e.g. "
210                  "TGeoManager::Import(\"geometry.root\")should be "
211                  "called in advance) - exit forced");
212         return kFALSE;
213     } // end if
214     switch(fMajorVersion) {
215     case kv11Hybrid: { 
216         return InitAliITSgeomV11Hybrid(geom);
217     } break; // end case
218     case kv11: {
219         return InitAliITSgeomV11(geom);
220     } break; // end case
221     case kvDefault: default: {
222         AliFatal("Undefined geometry");
223         return kFALSE;
224     } break; // end case
225     } // end switch
226     return kFALSE;
227 }
228 //______________________________________________________________________
229 void AliITSInitGeometry::TransposeTGeoHMatrix(TGeoHMatrix *m)const{
230     // Transpose the rotation matrix part of a TGeoHMatrix. This
231     // is needed because TGeo stores the transpose of the rotation
232     // matrix as compared to what AliITSgeomMatrix uses (and Geant3).
233     // Inputs:
234     //    TGeoHMatrix *m  The matrix to be transposed
235     // Outputs:
236     //    TGEoHMatrix *m  The transposed matrix
237     // Return:
238     //    none.
239     Int_t i;
240     Double_t r[9];
241
242     if(m==0) return; // no matrix to transpose.
243     for(i=0;i<9;i += 4) r[i] = m->GetRotationMatrix()[i]; // diagonals
244     r[1] = m->GetRotationMatrix()[3];
245     r[2] = m->GetRotationMatrix()[6];
246     r[3] = m->GetRotationMatrix()[1];
247     r[5] = m->GetRotationMatrix()[7];
248     r[6] = m->GetRotationMatrix()[2];
249     r[7] = m->GetRotationMatrix()[5];
250     m->SetRotation(r);
251     return;
252 }
253
254
255 //______________________________________________________________________
256 Bool_t AliITSInitGeometry::InitAliITSgeomV11Hybrid(AliITSgeom *geom){
257     // Initilizes the geometry transformation class AliITSgeom
258     // to values appropreate to this specific geometry. Now that
259     // the segmentation is part of AliITSgeom, the detector
260     // segmentations are also defined here.
261     // Inputs:
262     //   AliITSgeom *geom  A pointer to the AliITSgeom class
263     // Outputs:
264     //   AliITSgeom *geom  This pointer recreated and properly inilized.
265     // Return:
266     //   none.
267
268   const Int_t kItype  = 0; // Type of transformation defined 0=> Geant
269   const Int_t klayers = 6; // number of layers in the ITS
270   const Int_t kladders[klayers]   = {20,40,14,22,34,38}; // Number of ladders
271   const Int_t kdetectors[klayers] = {4,4,6,8,22,25};// number of detector/lad
272   const AliITSDetector kIdet[6]   = {kSPD,kSPD,kSDD,kSDD,kSSD,kSSD};
273   const TString kPathbase = "/ALIC_1/ITSV_1/";
274
275   const char *pathSPDsens1, *pathSPDsens2;
276   if (SPDIsTGeoNative()) {
277     pathSPDsens1="%sITSSPD_1/ITSSPDCarbonFiberSectorV_%d/ITSSPDSensitiveVirtualvolumeM0_1/ITSSPDlay1-Stave_%d/ITSSPDhalf-Stave%d_1/ITSSPDlay1-Ladder_%d/ITSSPDlay1-sensor_1";
278     pathSPDsens2="%sITSSPD_1/ITSSPDCarbonFiberSectorV_%d/ITSSPDSensitiveVirtualvolumeM0_1/ITSSPDlay2-Stave_%d/ITSSPDhalf-Stave%d_1/ITSSPDlay2-Ladder_%d/ITSSPDlay2-sensor_1";
279   } else{
280     pathSPDsens1 = "%sITSD_1/IT12_1/I12B_%d/I10B_%d/L1H-STAVE%d_1/I107_%d/I101_1/ITS1_1";
281     pathSPDsens2 = "%sITSD_1/IT12_1/I12B_%d/I20B_%d/L2H-STAVE%d_1/I1D7_%d/I1D1_1/ITS2_1";
282   }
283
284   const char *pathSDDsens1, *pathSDDsens2;
285   if (SDDIsTGeoNative()) {
286     pathSDDsens1 = "%sITSsddLayer3_1/ITSsddLadd_%d/ITSsddSensor3_%d/ITSsddWafer3_%d/ITSsddSensitivL3_1";
287     pathSDDsens2 = "%sITSsddLayer4_1/ITSsddLadd_%d/ITSsddSensor4_%d/ITSsddWafer4_%d/ITSsddSensitivL4_1";
288   } else{
289     pathSDDsens1 = "%sITSD_1/IT34_1/I004_%d/I302_%d/ITS3_%d";
290     pathSDDsens2 = "%sITSD_1/IT34_1/I005_%d/I402_%d/ITS4_%d";
291   }
292
293   const char *pathSSDsens1, *pathSSDsens2;
294   if (SSDIsTGeoNative()) {
295     pathSSDsens1 = "%sITSssdLayer5_1/ITSssdLay5Ladd_%d/ITSssdSensor5_%d/ITSssdSensitivL5_1";
296     pathSSDsens2 = "%sITSssdLayer6_1/ITSssdLay6Ladd_%d/ITSssdSensor6_%d/ITSssdSensitivL6_1";
297   } else{
298     pathSSDsens1 = "%sITSD_1/IT56_1/I565_%d/I562_%d/ITS5_%d";
299     pathSSDsens2 = "%sITSD_1/IT56_1/I569_%d/I566_%d/ITS6_%d";
300   }
301
302   const TString kNames[klayers] = {
303     pathSPDsens1, // lay=1
304     pathSPDsens2, // lay=2
305     pathSDDsens1, // lay=3
306     pathSDDsens2, // lay=4
307     pathSSDsens1, // lay=5
308     pathSSDsens2};// Lay=6
309   
310   Int_t mod,nmods=0, lay, lad, det, cpn0, cpn1, cpn2, cpnHS=1;
311   Double_t tran[3]={0.,0.,0.}, rot[10]={9*0.0,1.0};
312   TArrayD shapePar;
313   TString path, shapeName;
314   TGeoHMatrix matrix;
315   Bool_t initSeg[3]={kFALSE, kFALSE, kFALSE};
316   TStopwatch *time = 0x0;
317   if(fTiming) time = new TStopwatch();
318
319   if(fTiming) time->Start();
320   for(mod=0;mod<klayers;mod++) nmods += kladders[mod]*kdetectors[mod];
321   geom->Init(kItype,klayers,kladders,kdetectors,nmods);
322
323   for(mod=0; mod<nmods; mod++) {
324
325     DecodeDetectorLayers(mod,lay,lad,det);
326     geom->CreateMatrix(mod,lay,lad,det,kIdet[lay-1],tran,rot);
327     RecodeDetectorv11Hybrid(mod,cpn0,cpn1,cpn2);
328
329 //     if (SPDIsTGeoNative())
330 //       if (kIdet[lay-1]==kSPD) {
331 //      cpn0 = lad-1;
332 //      cpn1 = det-1;
333 //      cpn2 = 1;
334 //       }
335 //     if (SDDIsTGeoNative())
336 //       if (kIdet[lay-1]==kSDD) {
337 //      cpn0 = lad-1;
338 //      cpn1 = det-1;
339 //      cpn2 = 1;
340 //       }
341 //     if (SSDIsTGeoNative())
342 //       if (kIdet[lay-1]==kSSD) {
343 //      cpn0 = lad-1;
344 //      cpn1 = det-1;
345 //      cpn2 = 1;
346 //       }
347
348     if (kIdet[lay-1]==kSPD) { // we need 1 more copy number because of the half-stave
349       if (det<3) cpnHS = 0; else cpnHS = 1;
350       path.Form(kNames[lay-1].Data(),kPathbase.Data(),cpn0,cpn1,cpnHS,cpn2);
351     } else {
352       path.Form(kNames[lay-1].Data(),kPathbase.Data(),cpn0,cpn1,cpn2);
353     };
354
355     geom->GetGeomMatrix(mod)->SetPath(path);
356     GetTransformation(path.Data(),matrix);
357     geom->SetTrans(mod,matrix.GetTranslation());
358     TransposeTGeoHMatrix(&matrix); //Transpose TGeo's rotation matrixes
359     geom->SetRotMatrix(mod,matrix.GetRotationMatrix());
360     if(initSeg[kIdet[lay-1]]) continue;
361     GetShape(path,shapeName,shapePar);
362     if(shapeName.CompareTo("BOX")){
363       Error("InitITSgeom","Geometry changed without proper code update"
364             "or error in reading geometry. Shape is not BOX.");
365       return kFALSE;
366     } // end if
367   } // end for module
368
369   if(fTiming){
370     time->Stop();
371     time->Print();
372     delete time;
373   } // end if
374   return kTRUE;
375 }
376 //______________________________________________________________________
377 Bool_t AliITSInitGeometry::InitAliITSgeomV11(AliITSgeom *geom){
378   // Initilizes the geometry transformation class AliITSgeom
379   // Now that the segmentation is part of AliITSgeom, the detector
380   // segmentations are also defined here.
381   //
382   // Inputs:
383   //   AliITSgeom *geom  A pointer to the AliITSgeom class
384   // Outputs:
385   //   AliITSgeom *geom  This pointer recreated and properly inilized.
386   // LG
387
388   const Int_t kItype  = 0; // Type of transformation defined 0=> Geant
389   const Int_t klayers = 6; // number of layers in the ITS
390   const Int_t kladders[klayers]   = {20,40,14,22,34,38}; // Number of ladders
391   const Int_t kdetectors[klayers] = {4,4,6,8,22,25};// number of detector/lad
392   const AliITSDetector kIdet[6]   = {kSPD,kSPD,kSDD,kSDD,kSSD,kSSD};
393   const TString kPathbase = "/ALIC_1/ITSV_1/";
394
395   const char *pathSPDsens1, *pathSPDsens2;
396   pathSPDsens1="%sITSSPD_1/ITSSPDCarbonFiberSectorV_%d/ITSSPDSensitiveVirtualvolumeM0_1/ITSSPDlay1-Stave_%d/ITSSPDhalf-Stave%d_1/ITSSPDlay1-Ladder_%d/ITSSPDlay1-sensor_1";
397   pathSPDsens2="%sITSSPD_1/ITSSPDCarbonFiberSectorV_%d/ITSSPDSensitiveVirtualvolumeM0_1/ITSSPDlay2-Stave_%d/ITSSPDhalf-Stave%d_1/ITSSPDlay2-Ladder_%d/ITSSPDlay2-sensor_1";
398
399   const char *pathSDDsens1, *pathSDDsens2;
400   pathSDDsens1 = "%sITSsddLayer3_1/ITSsddLadd_%d/ITSsddSensor3_%d/ITSsddWafer3_%d/ITSsddSensitivL3_1";
401   pathSDDsens2 = "%sITSsddLayer4_1/ITSsddLadd_%d/ITSsddSensor4_%d/ITSsddWafer4_%d/ITSsddSensitivL4_1";
402
403   const char *pathSSDsens1, *pathSSDsens2;
404   pathSSDsens1 = "%sITSssdLayer5_1/ITSssdLay5Ladd_%d/ITSssdSensor5_%d/ITSssdSensitivL5_1";
405   pathSSDsens2 = "%sITSssdLayer6_1/ITSssdLay6Ladd_%d/ITSssdSensor6_%d/ITSssdSensitivL6_1";
406
407   const TString kNames[klayers] = {
408     pathSPDsens1, // lay=1
409     pathSPDsens2, // lay=2
410     pathSDDsens1, // lay=3
411     pathSDDsens2, // lay=4
412     pathSSDsens1, // lay=5
413     pathSSDsens2};// Lay=6
414   
415   Int_t mod,nmods=0, lay, lad, det, cpn0, cpn1, cpn2, cpnHS=1;
416   Double_t tran[3]={0.,0.,0.}, rot[10]={9*0.0,1.0};
417   TArrayD shapePar;
418   TString path, shapeName;
419   TGeoHMatrix matrix;
420   Bool_t initSeg[3]={kFALSE, kFALSE, kFALSE};
421   TStopwatch *time = 0x0;
422   if(fTiming) time = new TStopwatch();
423
424   if(fTiming) time->Start();
425   for(mod=0;mod<klayers;mod++) nmods += kladders[mod]*kdetectors[mod];
426   geom->Init(kItype,klayers,kladders,kdetectors,nmods);
427
428   for(mod=0; mod<nmods; mod++) {
429
430     DecodeDetectorLayers(mod,lay,lad,det);
431     geom->CreateMatrix(mod,lay,lad,det,kIdet[lay-1],tran,rot);
432     RecodeDetector(mod,cpn0,cpn1,cpn2);
433
434     if (kIdet[lay-1]==kSPD) { // we need 1 more copy number because of the half-stave
435       if (det<3) cpnHS = 0; else cpnHS = 1;
436       path.Form(kNames[lay-1].Data(),kPathbase.Data(),cpn0,cpn1,cpnHS,cpn2);
437     } else {
438       path.Form(kNames[lay-1].Data(),kPathbase.Data(),cpn0,cpn1,cpn2);
439     };
440
441     geom->GetGeomMatrix(mod)->SetPath(path);
442     GetTransformation(path.Data(),matrix);
443     geom->SetTrans(mod,matrix.GetTranslation());
444     TransposeTGeoHMatrix(&matrix); //Transpose TGeo's rotation matrixes
445     geom->SetRotMatrix(mod,matrix.GetRotationMatrix());
446     if(initSeg[kIdet[lay-1]]) continue;
447     GetShape(path,shapeName,shapePar);
448     if(shapeName.CompareTo("BOX")){
449       Error("InitITSgeom","Geometry changed without proper code update"
450             "or error in reading geometry. Shape is not BOX.");
451       return kFALSE;
452     } // end if
453   } // end for module
454
455   if(fTiming){
456     time->Stop();
457     time->Print();
458     delete time;
459   } // end if
460   return kTRUE;
461 }
462
463 //_______________________________________________________________________
464 Bool_t AliITSInitGeometry::GetTransformation(const TString &volumePath,
465                                              TGeoHMatrix &mat){
466     // Returns the Transformation matrix between the volume specified
467     // by the path volumePath and the Top or mater volume. The format
468     // of the path volumePath is as follows (assuming ALIC is the Top volume)
469     // "/ALIC_1/DDIP_1/S05I_2/S05H_1/S05G_3". Here ALIC is the top most
470     // or master volume which has only 1 instance of. Of all of the daughter
471     // volumes of ALICE, DDIP volume copy #1 is indicated. Similarly for
472     // the daughter volume of DDIP is S05I copy #2 and so on.
473     // Inputs:
474     //   TString& volumePath  The volume path to the specific volume
475     //                        for which you want the matrix. Volume name
476     //                        hierarchy is separated by "/" while the
477     //                        copy number is appended using a "_".
478     // Outputs:
479     //  TGeoHMatrix &mat      A matrix with its values set to those
480     //                        appropriate to the Local to Master transformation
481     // Return:
482     //   A logical value if kFALSE then an error occurred and no change to
483     //   mat was made.
484
485     // We have to preserve the modeler state
486
487     // Preserve the modeler state.
488     gGeoManager->PushPath();
489     if (!gGeoManager->cd(volumePath.Data())) {
490       gGeoManager->PopPath();
491       Error("GetTransformation","Error in cd-ing to %s",volumePath.Data());
492       return kFALSE;
493     } // end if !gGeoManager
494     mat = *gGeoManager->GetCurrentMatrix();
495     // Retstore the modeler state.
496     gGeoManager->PopPath();
497     return kTRUE;
498 }
499 //______________________________________________________________________
500 Bool_t AliITSInitGeometry::GetShape(const TString &volumePath,
501                                     TString &shapeType,TArrayD &par){
502     // Returns the shape and its parameters for the volume specified
503     // by volumeName.
504     // Inputs:
505     //   TString& volumeName  The volume name
506     // Outputs:
507     //   TString &shapeType   Shape type
508     //   TArrayD &par         A TArrayD of parameters with all of the
509     //                        parameters of the specified shape.
510     // Return:
511     //   A logical indicating whether there was an error in getting this
512     //   information
513     Int_t npar;
514     gGeoManager->PushPath();
515     if (!gGeoManager->cd(volumePath.Data())) {
516         gGeoManager->PopPath();
517         return kFALSE;
518     }
519     TGeoVolume * vol = gGeoManager->GetCurrentVolume();
520     gGeoManager->PopPath();
521     if (!vol) return kFALSE;
522     TGeoShape *shape = vol->GetShape();
523     TClass *classType = shape->IsA();
524     if (classType==TGeoBBox::Class()) {
525         shapeType = "BOX";
526         npar = 3;
527         par.Set(npar);
528         TGeoBBox *box = (TGeoBBox*)shape;
529         par.AddAt(box->GetDX(),0);
530         par.AddAt(box->GetDY(),1);
531         par.AddAt(box->GetDZ(),2);
532         return kTRUE;
533     } // end if
534     if (classType==TGeoTrd1::Class()) {
535         shapeType = "TRD1";
536         npar = 4;
537         par.Set(npar);
538         TGeoTrd1 *trd1 = (TGeoTrd1*)shape;
539         par.AddAt(trd1->GetDx1(),0);
540         par.AddAt(trd1->GetDx2(),1);
541         par.AddAt(trd1->GetDy(), 2);
542         par.AddAt(trd1->GetDz(), 3);
543         return kTRUE;
544     } // end if
545     if (classType==TGeoTrd2::Class()) {
546         shapeType = "TRD2";
547         npar = 5;
548         par.Set(npar);
549         TGeoTrd2 *trd2 = (TGeoTrd2*)shape;
550         par.AddAt(trd2->GetDx1(),0);
551         par.AddAt(trd2->GetDx2(),1);
552         par.AddAt(trd2->GetDy1(),2);
553         par.AddAt(trd2->GetDy2(),3);
554         par.AddAt(trd2->GetDz(), 4);
555         return kTRUE;
556     } // end if
557     if (classType==TGeoTrap::Class()) {
558         shapeType = "TRAP";
559         npar = 11;
560         par.Set(npar);
561         TGeoTrap *trap = (TGeoTrap*)shape;
562         Double_t tth = TMath::Tan(trap->GetTheta()*TMath::DegToRad());
563         par.AddAt(trap->GetDz(),0);
564         par.AddAt(tth*TMath::Cos(trap->GetPhi()*TMath::DegToRad()),1);
565         par.AddAt(tth*TMath::Sin(trap->GetPhi()*TMath::DegToRad()),2);
566         par.AddAt(trap->GetH1(),3);
567         par.AddAt(trap->GetBl1(),4);
568         par.AddAt(trap->GetTl1(),5);
569         par.AddAt(TMath::Tan(trap->GetAlpha1()*TMath::DegToRad()),6);
570         par.AddAt(trap->GetH2(),7);
571         par.AddAt(trap->GetBl2(),8);
572         par.AddAt(trap->GetTl2(),9);
573         par.AddAt(TMath::Tan(trap->GetAlpha2()*TMath::DegToRad()),10);
574         return kTRUE;
575     } // end if
576     if (classType==TGeoTube::Class()) {
577         shapeType = "TUBE";
578         npar = 3;
579         par.Set(npar);
580         TGeoTube *tube = (TGeoTube*)shape;
581         par.AddAt(tube->GetRmin(),0);
582         par.AddAt(tube->GetRmax(),1);
583         par.AddAt(tube->GetDz(),2);
584         return kTRUE;
585     } // end if
586     if (classType==TGeoTubeSeg::Class()) {
587         shapeType = "TUBS";
588         npar = 5;
589         par.Set(npar);
590         TGeoTubeSeg *tubs = (TGeoTubeSeg*)shape;
591         par.AddAt(tubs->GetRmin(),0);
592         par.AddAt(tubs->GetRmax(),1);
593         par.AddAt(tubs->GetDz(),2);
594         par.AddAt(tubs->GetPhi1(),3);
595         par.AddAt(tubs->GetPhi2(),4);
596         return kTRUE;
597     } // end if
598     if (classType==TGeoCone::Class()) {
599         shapeType = "CONE";
600         npar = 5;
601         par.Set(npar);
602         TGeoCone *cone = (TGeoCone*)shape;
603         par.AddAt(cone->GetDz(),0);
604         par.AddAt(cone->GetRmin1(),1);
605         par.AddAt(cone->GetRmax1(),2);
606         par.AddAt(cone->GetRmin2(),3);
607         par.AddAt(cone->GetRmax2(),4);
608         return kTRUE;
609     } // end if
610     if (classType==TGeoConeSeg::Class()) {
611         shapeType = "CONS";
612         npar = 7;
613         par.Set(npar);
614         TGeoConeSeg *cons = (TGeoConeSeg*)shape;
615         par.AddAt(cons->GetDz(),0);
616         par.AddAt(cons->GetRmin1(),1);
617         par.AddAt(cons->GetRmax1(),2);
618         par.AddAt(cons->GetRmin2(),3);
619         par.AddAt(cons->GetRmax2(),4);
620         par.AddAt(cons->GetPhi1(),5);
621         par.AddAt(cons->GetPhi2(),6);
622         return kTRUE;
623     } // end if
624     if (classType==TGeoSphere::Class()) {
625         shapeType = "SPHE";
626         npar = 6;
627         par.Set(npar);
628         
629         TGeoSphere *sphe = (TGeoSphere*)shape;
630         par.AddAt(sphe->GetRmin(),0);
631         par.AddAt(sphe->GetRmax(),1);
632         par.AddAt(sphe->GetTheta1(),2);
633         par.AddAt(sphe->GetTheta2(),3);
634         par.AddAt(sphe->GetPhi1(),4);
635         par.AddAt(sphe->GetPhi2(),5);
636         return kTRUE;
637     } // end if
638     if (classType==TGeoPara::Class()) {
639         shapeType = "PARA";
640         npar = 6;
641         par.Set(npar);
642         TGeoPara *para = (TGeoPara*)shape;
643         par.AddAt(para->GetX(),0);
644         par.AddAt(para->GetY(),1);
645         par.AddAt(para->GetZ(),2);
646         par.AddAt(para->GetTxy(),3);
647         par.AddAt(para->GetTxz(),4);
648         par.AddAt(para->GetTyz(),5);
649         return kTRUE;
650     } // end if
651     if (classType==TGeoPgon::Class()) {
652         shapeType = "PGON";
653         TGeoPgon *pgon = (TGeoPgon*)shape;
654         Int_t nz = pgon->GetNz();
655         const Double_t *rmin = pgon->GetRmin();
656         const Double_t *rmax = pgon->GetRmax();
657         const Double_t *z = pgon->GetZ();
658         npar = 4 + 3*nz;
659         par.Set(npar);
660         par.AddAt(pgon->GetPhi1(),0);
661         par.AddAt(pgon->GetDphi(),1);
662         par.AddAt(pgon->GetNedges(),2);
663         par.AddAt(pgon->GetNz(),3);
664         for (Int_t i=0; i<nz; i++) {
665             par.AddAt(z[i], 4+3*i);
666             par.AddAt(rmin[i], 4+3*i+1);
667             par.AddAt(rmax[i], 4+3*i+2);
668         }
669         return kTRUE;
670     } // end if
671     if (classType==TGeoPcon::Class()) {
672         shapeType = "PCON";
673         TGeoPcon *pcon = (TGeoPcon*)shape;
674         Int_t nz = pcon->GetNz();
675         const Double_t *rmin = pcon->GetRmin();
676         const Double_t *rmax = pcon->GetRmax();
677         const Double_t *z = pcon->GetZ();
678         npar = 3 + 3*nz;
679         par.Set(npar);
680         par.AddAt(pcon->GetPhi1(),0);
681         par.AddAt(pcon->GetDphi(),1);
682         par.AddAt(pcon->GetNz(),2);
683         for (Int_t i=0; i<nz; i++) {
684             par.AddAt(z[i], 3+3*i);
685             
686             par.AddAt(rmin[i], 3+3*i+1);
687             par.AddAt(rmax[i], 3+3*i+2);
688         }
689         return kTRUE;
690     } // end if
691     if (classType==TGeoEltu::Class()) {
692         shapeType = "ELTU";
693         npar = 3;
694         par.Set(npar);
695         TGeoEltu *eltu = (TGeoEltu*)shape;
696         par.AddAt(eltu->GetA(),0);
697         par.AddAt(eltu->GetB(),1);
698         par.AddAt(eltu->GetDz(),2);
699         return kTRUE;
700     } // end if
701     if (classType==TGeoHype::Class()) {
702         shapeType = "HYPE";
703         npar = 5;
704         par.Set(npar);
705         TGeoHype *hype = (TGeoHype*)shape;
706         par.AddAt(TMath::Sqrt(hype->RadiusHypeSq(0.,kTRUE)),0);
707         par.AddAt(TMath::Sqrt(hype->RadiusHypeSq(0.,kFALSE)),1);
708         par.AddAt(hype->GetDZ(),2);
709         par.AddAt(hype->GetStIn(),3);
710         par.AddAt(hype->GetStOut(),4);
711         return kTRUE;
712     } // end if
713     if (classType==TGeoGtra::Class()) {
714         shapeType = "GTRA";
715         npar = 12;
716         par.Set(npar);
717         TGeoGtra *trap = (TGeoGtra*)shape;
718         Double_t tth = TMath::Tan(trap->GetTheta()*TMath::DegToRad());
719         par.AddAt(trap->GetDz(),0);
720         par.AddAt(tth*TMath::Cos(trap->GetPhi()*TMath::DegToRad()),1);
721         par.AddAt(tth*TMath::Sin(trap->GetPhi()*TMath::DegToRad()),2);
722         par.AddAt(trap->GetH1(),3);
723         par.AddAt(trap->GetBl1(),4);
724         par.AddAt(trap->GetTl1(),5);
725         par.AddAt(TMath::Tan(trap->GetAlpha1()*TMath::DegToRad()),6);
726         par.AddAt(trap->GetH2(),7);
727         par.AddAt(trap->GetBl2(),8);
728         par.AddAt(trap->GetTl2(),9);
729         par.AddAt(TMath::Tan(trap->GetAlpha2()*TMath::DegToRad()),10);
730         par.AddAt(trap->GetTwistAngle(),11);
731         return kTRUE;
732     } // end if
733     if (classType==TGeoCtub::Class()) {
734         shapeType = "CTUB";
735         npar = 11;
736         par.Set(npar);
737         TGeoCtub *ctub = (TGeoCtub*)shape;
738         const Double_t *lx = ctub->GetNlow();
739         const Double_t *tx = ctub->GetNhigh();
740         par.AddAt(ctub->GetRmin(),0);
741         par.AddAt(ctub->GetRmax(),1);
742         par.AddAt(ctub->GetDz(),2);
743         par.AddAt(ctub->GetPhi1(),3);
744         par.AddAt(ctub->GetPhi2(),4);
745         par.AddAt(lx[0],5);
746         par.AddAt(lx[1],6);
747         par.AddAt(lx[2],7);
748         par.AddAt(tx[0],8);
749         par.AddAt(tx[1],9);
750         par.AddAt(tx[2],10);
751         return kTRUE;
752     } // end if
753     Error("GetShape","Getting shape parameters for shape %s not implemented",
754           shape->ClassName());
755     shapeType = "Unknown";
756     return kFALSE;
757 }
758 //______________________________________________________________________
759 void AliITSInitGeometry::DecodeDetector(
760     Int_t &mod,Int_t layer,Int_t cpn0,Int_t cpn1,Int_t cpn2) const {
761     // decode geometry into detector module number. There are two decoding
762     // Scheams. Old which does not follow the ALICE coordinate system
763     // requirements, and New which dose.
764     // Inputs:
765     //    Int_t layer    The ITS layer
766     //    Int_t cpn0     The lowest copy number
767     //    Int_t cpn1     The middle copy number
768     //    Int_t cpn2     the highest copy number
769     // Output:
770     //    Int_t &mod     The module number assoicated with this set
771     //                   of copy numbers.
772     // Return:
773     //    none.
774
775     // This is a FIXED switch yard function. I (Bjorn Nilsen) Don't 
776     // like them but I see not better way for the moment.
777     switch (fMajorVersion){
778     case kvDefault:{
779         Error("DecodeDetector","Major version = kvDefault, not supported");
780     }break;
781     case kv11:{
782         return DecodeDetectorv11(mod,layer,cpn0,cpn1,cpn2);
783     }break;
784     case kv11Hybrid:{
785         return DecodeDetectorv11Hybrid(mod,layer,cpn0,cpn1,cpn2);
786     }break;
787     default:{
788         Error("DecodeDetector","Major version = %d, not supported",
789               (Int_t)fMajorVersion);
790         return;
791     }break;
792     } // end switch
793     return;
794 }
795 //______________________________________________________________________
796 void AliITSInitGeometry::RecodeDetector(Int_t mod,Int_t &cpn0,
797                                         Int_t &cpn1,Int_t &cpn2){
798     // decode geometry into detector module number. There are two decoding
799     // Scheams. Old which does not follow the ALICE coordinate system
800     // requirements, and New which dose.
801     // Inputs:
802     //    Int_t mod      The module number assoicated with this set
803     //                   of copy numbers.
804     // Output:
805     //    Int_t cpn0     The lowest copy number
806     //    Int_t cpn1     The middle copy number
807     //    Int_t cpn2     the highest copy number
808     // Return:
809     //    none.
810
811     // This is a FIXED switch yard function. I (Bjorn Nilsen) Don't 
812     // like them but I see not better way for the moment.
813     switch (fMajorVersion){
814     case kvDefault:{
815         Error("RecodeDetector","Major version = kvDefault, not supported");
816         return;
817     }
818     case kv11:{
819         return RecodeDetectorv11(mod,cpn0,cpn1,cpn2);
820     }break;
821     case kv11Hybrid:{
822         return RecodeDetectorv11Hybrid(mod,cpn0,cpn1,cpn2);
823     }break;
824     default:{
825         Error("RecodeDetector","Major version = %d, not supported",
826               (Int_t)fMajorVersion);
827         return;
828     }break;
829     } // end switch
830     return;
831 }
832 //______________________________________________________________________
833 void AliITSInitGeometry::DecodeDetectorLayers(Int_t mod,Int_t &layer,
834                                               Int_t &lad,Int_t &det){
835     // decode geometry into detector module number. There are two decoding
836     // Scheams. Old which does not follow the ALICE coordinate system
837     // requirements, and New which dose. Note, this use of layer ladder
838     // and detector numbers are strictly for internal use of this
839     // specific code. They do not represent the "standard" layer ladder
840     // or detector numbering except in a very old and obsoleate sence.
841     // Inputs:
842     //    Int_t mod      The module number assoicated with this set
843     //                   of copy numbers.
844     // Output:
845     //    Int_t lay     The layer number
846     //    Int_t lad     The ladder number
847     //    Int_t det     the dettector number
848     // Return:
849     //    none.
850
851     // This is a FIXED switch yard function. I (Bjorn Nilsen) Don't 
852     // like them but I see not better way for the moment.
853     switch (fMajorVersion) {
854     case kvDefault:{
855         Error("DecodeDetectorLayers",
856               "Major version = kvDefault, not supported");
857         return;
858     }break;
859     case kv11:{
860         return DecodeDetectorLayersv11(mod,layer,lad,det);
861     }break;
862     case kv11Hybrid:{
863         return DecodeDetectorLayersv11Hybrid(mod,layer,lad,det);
864     }break;
865     default:{
866         Error("DecodeDetectorLayers","Major version = %d, not supported",
867               (Int_t)fMajorVersion);
868         return;
869     }break;
870     } // end switch
871     return;
872 }
873
874 //______________________________________________________________________
875 void AliITSInitGeometry::DecodeDetectorv11Hybrid(Int_t &mod,Int_t layer,
876                                  Int_t cpn0,Int_t cpn1,Int_t cpn2) const {
877     // decode geometry into detector module number
878     // Inputs:
879     //    Int_t layer    The ITS layer
880     //    Int_t cpn0     The lowest copy number
881     //    Int_t cpn1     The middle copy number
882     //    Int_t cpn2     the highest copy number
883     // Output:
884     //    Int_t &mod     The module number assoicated with this set
885     //                   of copy numbers.
886     // Return:
887     //    none.
888   const Int_t kDetPerLadderSPD[2]={2,4};
889   const Int_t kDetPerLadder[6]={4,4,6,8,22,25};
890   const Int_t kLadPerLayer[6]={20,40,14,22,34,38};
891   Int_t lad=-1,det=-1;
892   
893   switch(layer) {
894   case 1: case 2:{
895     if (SPDIsTGeoNative()) {
896       lad = cpn1+kDetPerLadderSPD[layer-1]*(cpn0-1);
897       det = cpn2;
898     } else {
899       lad = cpn1+kDetPerLadderSPD[layer-1]*(cpn0-1);
900       det = cpn2;
901     }
902   } break;
903   case 3: case 4:{
904     if (SDDIsTGeoNative()) {
905       lad = cpn0+1;
906       det = cpn1+1;
907     } else {
908       lad = cpn0;
909       det = cpn1;
910     }
911   } break;
912   case 5: case 6:{
913     if (SSDIsTGeoNative()) {
914       lad = cpn0+1;
915       det = cpn1+1;
916     } else {
917       lad = cpn0;
918       det = cpn1;
919     }
920   } break;
921   default:{
922   } break;
923   } // end switch
924   mod = 0;
925   for(Int_t i=0;i<layer-1;i++) mod += kLadPerLayer[i]*kDetPerLadder[i];
926   mod += kDetPerLadder[layer-1]*(lad-1)+det-1;// module start at zero.
927   return;
928 }
929
930 //______________________________________________________________________
931 void AliITSInitGeometry::DecodeDetectorv11(Int_t &mod,Int_t layer,
932                                  Int_t cpn0,Int_t cpn1,Int_t cpn2) const {
933     // decode geometry into detector module number
934     // Inputs:
935     //    Int_t layer    The ITS layer
936     //    Int_t cpn0     The lowest copy number
937     //    Int_t cpn1     The middle copy number
938     //    Int_t cpn2     the highest copy number
939     // Output:
940     //    Int_t &mod     The module number assoicated with this set
941     //                   of copy numbers.
942     // Return:
943     //    none.
944   const Int_t kDetPerLadderSPD[2]={2,4};
945   const Int_t kDetPerLadder[6]={4,4,6,8,22,25};
946   const Int_t kLadPerLayer[6]={20,40,14,22,34,38};
947   Int_t lad=-1,det=-1;
948   
949   switch(layer) {
950   case 1: case 2:{
951     lad = cpn1+kDetPerLadderSPD[layer-1]*(cpn0-1);
952     det = cpn2;
953   } break;
954   case 3: case 4:{
955     lad = cpn0+1;
956     det = cpn1+1;
957   } break;
958   case 5: case 6:{
959     lad = cpn0+1;
960     det = cpn1+1;
961   } break;
962   default:{
963   } break;
964   } // end switch
965   mod = 0;
966   for(Int_t i=0;i<layer-1;i++) mod += kLadPerLayer[i]*kDetPerLadder[i];
967   mod += kDetPerLadder[layer-1]*(lad-1)+det-1;// module start at zero.
968   return;
969 }
970
971 //______________________________________________________________________
972 void AliITSInitGeometry::RecodeDetectorv11Hybrid(Int_t mod,Int_t &cpn0,
973                                         Int_t &cpn1,Int_t &cpn2) {
974     // decode geometry into detector module number. There are two decoding
975     // Scheams. Old which does not follow the ALICE coordinate system
976     // requirements, and New which does.
977     // Inputs:
978     //    Int_t mod      The module number assoicated with this set
979     //                   of copy numbers.
980     // Output:
981     //    Int_t cpn0     The lowest copy number  (SPD sector or SDD/SSD ladder)
982     //    Int_t cpn1     The middle copy number  (SPD stave or SDD/SSD module)
983     //    Int_t cpn2     the highest copy number (SPD ladder or 1 for SDD/SSD)
984     // Return:
985     //    none.
986     const Int_t kDetPerLadderSPD[2]={2,4};
987     Int_t lay,lad,det;
988
989     DecodeDetectorLayersv11Hybrid(mod,lay,lad,det);
990     if (lay<3) { // SPD
991         cpn2 = det;     // Detector 1-4
992         cpn0 = (lad+kDetPerLadderSPD[lay-1]-1)/kDetPerLadderSPD[lay-1];
993         cpn1 = (lad+kDetPerLadderSPD[lay-1]-1)%kDetPerLadderSPD[lay-1] + 1;
994         //if (SPDIsTGeoNative()) {
995         //    cpn2--;
996         //    cpn1--;
997         //}
998     } else { // SDD and SSD
999         cpn2 = 1;
1000         cpn1 = det;
1001         cpn0 = lad;
1002         if (lay<5) { // SDD
1003             if (SDDIsTGeoNative()) {
1004                 cpn1--;
1005                 cpn0--;
1006             } // end if SDDIsTGeoNative()
1007         } else { //SSD
1008             if (SSDIsTGeoNative()) {
1009                 cpn1--;
1010                 cpn0--;
1011             }// end if SSDIsTGeoNative()
1012         } // end if Lay<5/else
1013     } // end if lay<3/else
1014     /*printf("AliITSInitGeometry::RecodeDetectorv11Hybrid:"
1015            "mod=%d lay=%d lad=%d det=%d cpn0=%d cpn1=%d cpn2=%d\n",
1016            mod,lay,lad,det,cpn0,cpn1,cpn2);*/
1017 }
1018
1019 //______________________________________________________________________
1020 void AliITSInitGeometry::RecodeDetectorv11(Int_t mod,Int_t &cpn0,
1021                                            Int_t &cpn1,Int_t &cpn2) {
1022     // decode geometry into detector module number using the new decoding
1023     // Scheme.
1024     // Inputs:
1025     //    Int_t mod      The module number assoicated with this set
1026     //                   of copy numbers.
1027     // Output:
1028     //    Int_t cpn0     The lowest copy number  (SPD sector or SDD/SSD ladder)
1029     //    Int_t cpn1     The middle copy number  (SPD stave or SDD/SSD module)
1030     //    Int_t cpn2     the highest copy number (SPD ladder or 1 for SDD/SSD)
1031     // Return:
1032     //    none.
1033     const Int_t kDetPerLadderSPD[2]={2,4};
1034     Int_t lay,lad,det;
1035
1036     DecodeDetectorLayersv11(mod,lay,lad,det);
1037     if (lay<3) { // SPD
1038         cpn2 = det;     // Detector 1-4
1039         cpn0 = (lad+kDetPerLadderSPD[lay-1]-1)/kDetPerLadderSPD[lay-1];
1040         cpn1 = (lad+kDetPerLadderSPD[lay-1]-1)%kDetPerLadderSPD[lay-1] + 1;
1041     } else { // SDD and SSD
1042         cpn2 = 1;
1043         cpn1 = det;
1044         cpn0 = lad;
1045         if (lay<5) { // SDD
1046           cpn1--;
1047           cpn0--;
1048         } else { //SSD
1049           cpn1--;
1050           cpn0--;
1051         } // end if Lay<5/else
1052     } // end if lay<3/else
1053     /*printf("AliITSInitGeometry::RecodeDetectorv11Hybrid:"
1054            "mod=%d lay=%d lad=%d det=%d cpn0=%d cpn1=%d cpn2=%d\n",
1055            mod,lay,lad,det,cpn0,cpn1,cpn2);*/
1056 }
1057
1058 //______________________________________________________________________
1059 void AliITSInitGeometry::DecodeDetectorLayersv11Hybrid(Int_t mod,Int_t &lay,
1060                                               Int_t &lad,Int_t &det) {
1061
1062   // decode module number into detector indices for v11Hybrid
1063   // mod starts from 0
1064   // lay, lad, det start from 1
1065
1066   // Inputs:
1067   //    Int_t mod      The module number associated with this set
1068   //                   of copy numbers.
1069   // Output:
1070   //    Int_t lay     The layer number
1071   //    Int_t lad     The ladder number
1072   //    Int_t det     the dettector number
1073
1074   const Int_t kDetPerLadder[6] = {4,4,6,8,22,25};
1075   const Int_t kLadPerLayer[6]  = {20,40,14,22,34,38};
1076   
1077   Int_t mod2 = 0;
1078   lay  = 0;
1079   
1080   do {
1081     mod2 += kLadPerLayer[lay]*kDetPerLadder[lay];
1082     lay++;
1083   } while(mod2<=mod); // end while
1084   if(lay>6) Error("DecodeDetectorLayers","lay=%d>6",lay);
1085
1086   mod2 = kLadPerLayer[lay-1]*kDetPerLadder[lay-1] - mod2+mod;
1087   lad = mod2/kDetPerLadder[lay-1];
1088
1089   if(lad>=kLadPerLayer[lay-1]||lad<0) Error("DecodeDetectorLayers",
1090                                       "lad=%d not in the correct range",lad);
1091   det = (mod2 - lad*kDetPerLadder[lay-1])+1;
1092   if(det>kDetPerLadder[lay-1]||det<1) Error("DecodeDetectorLayers",
1093                                       "det=%d not in the correct range",det);
1094   lad++;
1095 }
1096
1097 //______________________________________________________________________
1098 void AliITSInitGeometry::DecodeDetectorLayersv11(Int_t mod,Int_t &lay,
1099                                                  Int_t &lad,Int_t &det) {
1100
1101   // decode module number into detector indices for v11
1102   // mod starts from 0
1103   // lay, lad, det start from 1
1104
1105   // Inputs:
1106   //    Int_t mod      The module number associated with this set
1107   //                   of copy numbers.
1108   // Output:
1109   //    Int_t lay     The layer number
1110   //    Int_t lad     The ladder number
1111   //    Int_t det     the dettector number
1112
1113   const Int_t kDetPerLadder[6] = {4,4,6,8,22,25};
1114   const Int_t kLadPerLayer[6]  = {20,40,14,22,34,38};
1115   
1116   Int_t mod2 = 0;
1117   lay  = 0;
1118   
1119   do {
1120     mod2 += kLadPerLayer[lay]*kDetPerLadder[lay];
1121     lay++;
1122   } while(mod2<=mod); // end while
1123   if(lay>6) Error("DecodeDetectorLayers","lay=%d>6",lay);
1124
1125   mod2 = kLadPerLayer[lay-1]*kDetPerLadder[lay-1] - mod2+mod;
1126   lad = mod2/kDetPerLadder[lay-1];
1127
1128   if(lad>=kLadPerLayer[lay-1]||lad<0) Error("DecodeDetectorLayers",
1129                                       "lad=%d not in the correct range",lad);
1130   det = (mod2 - lad*kDetPerLadder[lay-1])+1;
1131   if(det>kDetPerLadder[lay-1]||det<1) Error("DecodeDetectorLayers",
1132                                       "det=%d not in the correct range",det);
1133   lad++;
1134 }
1135
1136 //______________________________________________________________________
1137 Bool_t AliITSInitGeometry::WriteVersionString(Char_t *str,Int_t length,
1138                         AliITSVersion_t maj,Int_t min,
1139                         const Char_t *cvsDate,const Char_t *cvsRevision)const{
1140     // fills the string str with the major and minor version number
1141     // Inputs:
1142     //   Char_t *str          The character string to hold the major 
1143     //                        and minor version numbers in
1144     //   Int_t  length        The maximum number of characters which 
1145     //                        can be accomidated by this string. 
1146     //                        str[length-1] must exist and will be set to zero
1147     //   AliITSVersion_t maj  The major number
1148     //   Int_t           min  The minor number
1149     //   Char_t *cvsDate      The date string from cvs
1150     //   Char_t *cvsRevision  The Revision string from cvs
1151     // Outputs:
1152     //   Char_t *str          The character string holding the major and minor
1153     //                        version numbers. str[length-1] must exist
1154     //                        and will be set to zero
1155     // Return:
1156     //   kTRUE if no errors
1157     Char_t cvslikedate[30];
1158     Int_t i,n,cvsDateLength,cvsRevisionLength;
1159
1160     cvsDateLength = (Int_t)strlen(cvsDate);
1161     if(cvsDateLength>30){ // svn string, make a cvs like string
1162         i=0;n=0;
1163         do{
1164             cvslikedate[i] = cvsDate[i];
1165             if(cvsDate[i]=='+' || cvsDate[i++]=='-'){
1166                 n++; // count number of -
1167                 cvslikedate[i-1] = '/'; // replace -'s by /'s.
1168             } // end if
1169         } while(n<3&&i<30); // once additonal - of time zone reach exit
1170         cvslikedate[i-1] = '$'; // put $ at end then zero.
1171         for(;i<30;i++) cvslikedate[i]=0;// i starts wher do loop left off.
1172     }else{
1173         for(i=0;i<cvsDateLength&&i<30;i++) cvslikedate[i]=cvsDate[i];
1174     }// end if
1175     cvsDateLength = (Int_t)strlen(cvslikedate);
1176     cvsRevisionLength = (Int_t)strlen(cvsRevision);
1177     i = (Int_t)maj;
1178     n = 50+(Int_t)(TMath::Log10(TMath::Abs((Double_t)i)))+1+
1179         (Int_t)(TMath::Log10(TMath::Abs((Double_t)min)))+1
1180         +cvsDateLength-6+cvsRevisionLength-10;
1181     if(GetDebug()>1) printf("AliITSInitGeometry::WriteVersionString:"
1182                         "length=%d major=%d minor=%d cvsDate=%s[%d] "
1183                         "cvsRevision=%s[%d] n=%d\n",length,i,min,cvslikedate,
1184                         cvsDateLength,cvsRevision,cvsRevisionLength,n);
1185     if(i<0) n++;
1186     if(min<0) n++;
1187     if(length<n){// not enough space to write in output string.
1188         Warning("WriteVersionString","Output string not long enough "
1189                 "lenght=%d must be at least %d long\n",length,n);
1190         return kFALSE;
1191     } // end if length<n
1192     char *cvsrevision = new char[cvsRevisionLength-10];
1193     char *cvsdate = new char[cvsDateLength-6];
1194     for(i=0;i<cvsRevisionLength-10;i++)
1195         if(10+i<cvsRevisionLength-1)
1196             cvsrevision[i] = cvsRevision[10+i]; else cvsrevision[i] = 0;
1197     for(i=0;i<cvsDateLength-6;i++) if(6+i<cvsDateLength-1)
1198         cvsdate[i] = cvslikedate[6+i]; else cvsdate[i] = 0;
1199     for(i=0;i<length;i++) str[i] = 0; // zero it out for now.
1200     i = (Int_t)maj;
1201     snprintf(str,length-1,"Major Version= %d Minor Version= %d Revision: %s Date: %s",i,min,cvsrevision,cvsdate);
1202     /* this gives compilation warnings on some compilers: descriptor zu
1203     if(GetDebug()>1)printf("AliITSInitGeometry::WriteVersionString: "
1204                        "n=%d str=%s revision[%zu] date[%zu]\n",
1205                        n,str,strlen(cvsrevision),strlen(cvsdate));
1206     */
1207     delete[] cvsrevision;
1208     delete[] cvsdate;
1209     return kTRUE;
1210 }
1211 //______________________________________________________________________
1212 Bool_t AliITSInitGeometry::ReadVersionString(const Char_t *str,Int_t length,
1213                                              AliITSVersion_t &maj,Int_t &min,
1214                                              TDatime &dt)const{
1215     // fills the string str with the major and minor version number
1216     // Inputs:
1217     //   Char_t *str   The character string to holding the major and minor
1218     //                 version numbers in
1219     //   Int_t  length The maximum number of characters which can be
1220     //                 accomidated by this string. str[length-1] must exist
1221     // Outputs:
1222     //   Char_t *str   The character string holding the major and minor
1223     //                 version numbers unchanged. str[length-1] must exist.
1224     //   AliITSVersion_t maj  The major number
1225     //   Int_t           min  The minor number
1226     //   TDatime         dt   The date and time of the cvs commit
1227     // Return:
1228     //   kTRUE if no errors
1229     Bool_t ok;
1230     Char_t cvsRevision[10],cvsDate[11],cvsTime[9];
1231     Int_t i,m,n=strlen(str),year,month,day,hours,minuits,seconds;
1232     memset(cvsRevision,0,10*sizeof(Char_t));
1233     memset(cvsDate,0,11*sizeof(Char_t));    
1234     memset(cvsTime,0,9*sizeof(Char_t));
1235
1236     if(GetDebug()>1)printf("AliITSInitGeometry::ReadVersionString:"
1237                        "str=%s length=%d\n",
1238                        str,length);
1239     if(n<35) return kFALSE; // not enough space for numbers
1240     m = sscanf(str,"Major Version= %d  Minor Version= %d Revision: %9s "
1241                "Date: %10s %8s",&i,&min,cvsRevision,cvsDate,cvsTime);
1242     ok = m==5;
1243     if(!ok) return !ok;
1244     m = sscanf(cvsDate,"%d/%d/%d",&year,&month,&day);
1245     ok = m==3;
1246     if(!ok) return !ok;
1247     m = sscanf(cvsTime,"%d:%d:%d",&hours,&minuits,&seconds);
1248     ok = m==3;
1249     if(!ok) return !ok;
1250     dt.Set(year,month,day,hours,minuits,seconds);
1251     if(GetDebug()>1)printf("AliITSInitGeometry::ReadVersionString: i=%d "
1252                      "min=%d cvsRevision=%s cvsDate=%s cvsTime=%s m=%d\n",
1253                        i,min,cvsRevision,cvsDate,cvsTime,m);
1254     if(GetDebug()>1)printf("AliITSInitGeometry::ReadVersionString: year=%d"
1255                        " month=%d day=%d hours=%d minuits=%d seconds=%d\n",
1256                        year,month,day,hours,minuits,seconds);
1257     switch (i){
1258     case kv11:{
1259         maj = kv11;
1260     } break;
1261     case kv11Hybrid:{
1262         maj = kv11Hybrid;
1263     } break;
1264     default:{
1265         maj = kvDefault;
1266     } break;
1267     } // end switch
1268     return ok;
1269 }