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