]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliAlignObj.cxx
Adding new calibration flavours for trigger
[u/mrichter/AliRoot.git] / STEER / AliAlignObj.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 //   Implementation of the alignment object class through the abstract
18 //  class AliAlignObj. From it two derived concrete representation of
19 //  alignment object class (AliAlignObjAngles, AliAlignObjMatrix) are
20 //  derived in separate files.
21 //-----------------------------------------------------------------
22 /*****************************************************************************
23  * AliAlignObjAngles: derived alignment class storing alignment information  *
24  *   for a single volume in form of three doubles for the translation        *
25  *   and three doubles for the rotation expressed with the euler angles      *
26  *   in the xyz-convention (http://mathworld.wolfram.com/EulerAngles.html),  *
27  *   also known as roll, pitch, yaw. PLEASE NOTE THE ANGLES SIGNS ARE        *
28  *   INVERSE WITH RESPECT TO THIS REFERENCE!!! In this way the representation*
29  *   is fully consistent with the TGeo Rotation methods.                     *
30  *****************************************************************************/
31
32 #include <TGeoManager.h>
33 #include <TGeoPhysicalNode.h>
34
35 #include "AliAlignObj.h"
36 #include "AliTrackPointArray.h"
37 #include "AliLog.h"
38 #include "AliAlignObjAngles.h"
39  
40 ClassImp(AliAlignObj)
41
42 Int_t AliAlignObj::fgLayerSize[kLastLayer - kFirstLayer] = {
43   80, 160,  // ITS SPD
44   84, 176,  // ITS SDD
45   748, 950, // ITS SSD
46   36, 36,   // TPC
47   90, 90, 90, 90, 90, 90,  // TRD
48   1674,     // TOF
49   1, 1,     // PHOS ??
50   7,        // RICH ??
51   1         // MUON ??
52 };
53
54 const char* AliAlignObj::fgLayerName[kLastLayer - kFirstLayer] = {
55   "ITS inner pixels layer", "ITS outer pixels layer",
56   "ITS inner drifts layer", "ITS outer drifts layer",
57   "ITS inner strips layer", "ITS outer strips layer",
58   "TPC inner chambers layer", "TPC outer chambers layer",
59   "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3",
60   "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
61   "TOF layer",
62   "?","?",
63   "RICH layer",
64   "?"
65 };
66
67 TString* AliAlignObj::fgVolPath[kLastLayer - kFirstLayer] = {
68   0x0,0x0,
69   0x0,0x0,
70   0x0,0x0,
71   0x0,0x0,
72   0x0,0x0,0x0,
73   0x0,0x0,0x0,
74   0x0,
75   0x0,0x0,
76   0x0,
77   0x0
78 };
79
80 AliAlignObj** AliAlignObj::fgAlignObjs[kLastLayer - kFirstLayer] = {
81   0x0,0x0,
82   0x0,0x0,
83   0x0,0x0,
84   0x0,0x0,
85   0x0,0x0,0x0,
86   0x0,0x0,0x0,
87   0x0,
88   0x0,0x0,
89   0x0,
90   0x0
91 };
92
93 //_____________________________________________________________________________
94 AliAlignObj::AliAlignObj():
95   fVolUID(0)
96 {
97   // default constructor
98   InitVolPaths();
99 }
100
101 //_____________________________________________________________________________
102 AliAlignObj::AliAlignObj(const AliAlignObj& theAlignObj) :
103   TObject(theAlignObj)
104 {
105   //copy constructor
106   fVolPath = theAlignObj.GetVolPath();
107   fVolUID = theAlignObj.GetVolUID();
108 }
109
110 //_____________________________________________________________________________
111 AliAlignObj &AliAlignObj::operator =(const AliAlignObj& theAlignObj)
112 {
113   // assignment operator
114   if(this==&theAlignObj) return *this;
115   fVolPath = theAlignObj.GetVolPath();
116   fVolUID = theAlignObj.GetVolUID();
117   return *this;
118 }
119
120 //_____________________________________________________________________________
121 AliAlignObj &AliAlignObj::operator*=(const AliAlignObj& theAlignObj)
122 {
123   // multiplication operator
124   // The operator can be used to 'combine'
125   // two alignment objects
126   TGeoHMatrix m1;
127   GetMatrix(m1);
128   TGeoHMatrix m2;
129   theAlignObj.GetMatrix(m2);
130   m1.MultiplyLeft(&m2);
131   SetMatrix(m1);
132   return *this;
133 }
134
135 //_____________________________________________________________________________
136 AliAlignObj::~AliAlignObj()
137 {
138   // dummy destructor
139 }
140
141 //_____________________________________________________________________________
142 void AliAlignObj::SetVolUID(ELayerID detId, Int_t modId)
143 {
144   // From detector name and module number (according to detector numbering)
145   // build fVolUID, unique numerical identity of that volume inside ALICE
146   // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
147   // remaining 11 for module ID inside det (2048 possible values).
148   //
149   fVolUID = LayerToVolUID(detId,modId);
150 }
151
152 //_____________________________________________________________________________
153 void AliAlignObj::GetVolUID(ELayerID &layerId, Int_t &modId) const
154 {
155   // From detector name and module number (according to detector numbering)
156   // build fVolUID, unique numerical identity of that volume inside ALICE
157   // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
158   // remaining 11 for module ID inside det (2048 possible values).
159   //
160   layerId = VolUIDToLayer(fVolUID,modId);
161 }
162
163 //_____________________________________________________________________________
164 void AliAlignObj::AnglesToMatrix(const Double_t *angles, Double_t *rot) const
165 {
166   // Calculates the rotation matrix using the 
167   // Euler angles in "x y z" notation
168   Double_t degrad = TMath::DegToRad();
169   Double_t sinpsi = TMath::Sin(degrad*angles[0]);
170   Double_t cospsi = TMath::Cos(degrad*angles[0]);
171   Double_t sinthe = TMath::Sin(degrad*angles[1]);
172   Double_t costhe = TMath::Cos(degrad*angles[1]);
173   Double_t sinphi = TMath::Sin(degrad*angles[2]);
174   Double_t cosphi = TMath::Cos(degrad*angles[2]);
175
176   rot[0] =  costhe*cosphi;
177   rot[1] = -costhe*sinphi;
178   rot[2] =  sinthe;
179   rot[3] =  sinpsi*sinthe*cosphi + cospsi*sinphi;
180   rot[4] = -sinpsi*sinthe*sinphi + cospsi*cosphi;
181   rot[5] = -costhe*sinpsi;
182   rot[6] = -cospsi*sinthe*cosphi + sinpsi*sinphi;
183   rot[7] =  cospsi*sinthe*sinphi + sinpsi*cosphi;
184   rot[8] =  costhe*cospsi;
185 }
186
187 //_____________________________________________________________________________
188 Bool_t AliAlignObj::MatrixToAngles(const Double_t *rot, Double_t *angles) const
189 {
190   // Calculates the Euler angles in "x y z" notation
191   // using the rotation matrix
192   if(TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) return kFALSE;
193   Double_t raddeg = TMath::RadToDeg();
194   angles[0]=raddeg*TMath::ATan2(-rot[5],rot[8]);
195   angles[1]=raddeg*TMath::ASin(rot[2]);
196   angles[2]=raddeg*TMath::ATan2(-rot[1],rot[0]);
197   return kTRUE;
198 }
199
200 //______________________________________________________________________________
201 void AliAlignObj::Transform(AliTrackPoint &p) const
202 {
203   // The method transforms the space-point coordinates using the
204   // transformation matrix provided by the AliAlignObj
205   // The covariance matrix is not affected since we assume
206   // that the transformations are sufficiently small
207
208   if (fVolUID != p.GetVolumeID())
209     AliWarning(Form("Alignment object ID is not equal to the space-point ID (%d != %d)",fVolUID,p.GetVolumeID())); 
210
211   TGeoHMatrix m;
212   GetMatrix(m);
213   Double_t *rot = m.GetRotationMatrix();
214   Double_t *tr  = m.GetTranslation();
215
216   Float_t xyzin[3],xyzout[3];
217   p.GetXYZ(xyzin);
218   for (Int_t i = 0; i < 3; i++)
219     xyzout[i] = tr[i]+
220                 xyzin[0]*rot[3*i]+
221                 xyzin[1]*rot[3*i+1]+
222                 xyzin[2]*rot[3*i+2];
223   p.SetXYZ(xyzout);
224   
225 }
226
227 //______________________________________________________________________________
228 void AliAlignObj::Transform(AliTrackPointArray &array) const
229 {
230   AliTrackPoint p;
231   for (Int_t i = 0; i < array.GetNPoints(); i++) {
232     array.GetPoint(p,i);
233     Transform(p);
234     array.AddPoint(i,&p);
235   }
236 }
237
238 //_____________________________________________________________________________
239 void AliAlignObj::Print(Option_t *) const
240 {
241   // Print the contents of the
242   // alignment object in angles and
243   // matrix representations
244   Double_t tr[3];
245   GetTranslation(tr);
246   Double_t angles[3];
247   GetAngles(angles);
248   TGeoHMatrix m;
249   GetMatrix(m);
250   const Double_t *rot = m.GetRotationMatrix();
251 //   printf("Volume=%s ID=%u\n", GetVolPath(),GetVolUID());
252   ELayerID layerId;
253   Int_t modId;
254   GetVolUID(layerId,modId);
255   printf("Volume=%s LayerID=%d ModuleID=%d\n", GetVolPath(),layerId,modId);
256   printf("%12.6f%12.6f%12.6f    Tx = %12.6f    Psi   = %12.6f\n", rot[0], rot[1], rot[2], tr[0], angles[0]);
257   printf("%12.6f%12.6f%12.6f    Ty = %12.6f    Theta = %12.6f\n", rot[3], rot[4], rot[5], tr[1], angles[1]);
258   printf("%12.6f%12.6f%12.6f    Tz = %12.6f    Phi   = %12.6f\n", rot[6], rot[7], rot[8], tr[2], angles[2]);
259
260 }
261
262 //_____________________________________________________________________________
263 UShort_t AliAlignObj::LayerToVolUID(ELayerID layerId, Int_t modId)
264 {
265   // From detector (layer) name and module number (according to detector numbering)
266   // build fVolUID, unique numerical identity of that volume inside ALICE
267   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
268   // remaining 11 for module ID inside det (2048 possible values).
269   //
270   return ((UShort_t(layerId) << 11) | UShort_t(modId));
271 }
272
273 //_____________________________________________________________________________
274 UShort_t AliAlignObj::LayerToVolUID(Int_t   layerId, Int_t modId)
275 {
276   // From detector (layer) index and module number (according to detector numbering)
277   // build fVolUID, unique numerical identity of that volume inside ALICE
278   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
279   // remaining 11 for module ID inside det (2048 possible values).
280   //
281   return ((UShort_t(layerId) << 11) | UShort_t(modId));
282 }
283
284 //_____________________________________________________________________________
285 AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid, Int_t &modId)
286 {
287   // From detector (layer) name and module number (according to detector numbering)
288   // build fVolUID, unique numerical identity of that volume inside ALICE
289   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
290   // remaining 11 for module ID inside det (2048 possible values).
291   //
292   modId = voluid & 0x7ff;
293
294   return VolUIDToLayer(voluid);
295 }
296
297 //_____________________________________________________________________________
298 AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid)
299 {
300   // From detector (layer) name and module number (according to detector numbering)
301   // build fVolUID, unique numerical identity of that volume inside ALICE
302   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
303   // remaining 11 for module ID inside det (2048 possible values).
304   //
305   return ELayerID((voluid >> 11) & 0x1f);
306 }
307
308 //_____________________________________________________________________________
309 Bool_t AliAlignObj::SetLocalPars(Double_t x, Double_t y, Double_t z,
310                                  Double_t psi, Double_t theta, Double_t phi)
311 {
312   // Set the translations and angles by using parameters
313   // defined in the local (in TGeo means) coordinate system
314   // of the alignable volume. In case that the TGeo was
315   // initialized, returns false and the object parameters are
316   // not set.
317   if (!gGeoManager || !gGeoManager->IsClosed()) {
318     AliError("Can't set the alignment object parameters! gGeoManager doesn't exist or it is still opened!");
319     return kFALSE;
320   }
321
322   const char* volpath = GetVolPath();
323   TGeoPhysicalNode* node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(volpath);
324   if (!node) {
325     AliError(Form("Volume path %s not valid!",volpath));
326     return kFALSE;
327   }
328   if (node->IsAligned())
329     AliWarning(Form("Volume %s has been already misaligned!",volpath));
330
331   TGeoHMatrix m;
332   Double_t tr[3];
333   tr[0]=x; tr[1]=y; tr[2]=z;
334   m.SetTranslation(tr);
335   Double_t angles[3] = {psi, theta, phi};
336   Double_t rot[9];
337   AnglesToMatrix(angles,rot);
338   m.SetRotation(rot);
339
340   TGeoHMatrix align,gprime,gprimeinv;
341   gprime = *node->GetMatrix();
342   gprimeinv = gprime.Inverse();
343   m.Multiply(&gprimeinv);
344   m.MultiplyLeft(&gprime);
345
346   SetMatrix(m);
347
348   return kTRUE;
349 }
350
351 //_____________________________________________________________________________
352 Bool_t AliAlignObj::ApplyToGeometry()
353 {
354   // Apply the current alignment object
355   // to the TGeo geometry
356
357   if (!gGeoManager || !gGeoManager->IsClosed()) {
358     AliError("Can't apply the alignment object! gGeoManager doesn't exist or it is still opened!");
359     return kFALSE;
360   }
361   
362   const char* volpath = GetVolPath();
363   TGeoPhysicalNode* node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(volpath);
364   if (!node) {
365     AliError(Form("Volume path %s not valid!",volpath));
366     return kFALSE;
367   }
368   if (node->IsAligned()) {
369     AliWarning(Form("Volume %s has been already misaligned!",volpath));
370     return kFALSE;
371   }
372
373   TGeoHMatrix align,gprime;
374   gprime = *node->GetMatrix();
375   GetMatrix(align);
376   gprime.MultiplyLeft(&align);
377   TGeoHMatrix *ginv = new TGeoHMatrix;
378   TGeoHMatrix *g = node->GetMatrix(node->GetLevel()-1);
379   *ginv = g->Inverse();
380   *ginv *= gprime;
381   AliAlignObj::ELayerID layerId; // unique identity for volume in the alobj
382   Int_t modId; // unique identity for volume in the alobj
383   GetVolUID(layerId, modId);
384   AliInfo(Form("Aligning volume %s of detector layer %d with local ID %d",volpath,layerId,modId));
385   node->Align(ginv);
386
387   return kTRUE;
388 }
389
390 //_____________________________________________________________________________
391 Bool_t AliAlignObj::GetFromGeometry(const char *path, AliAlignObj &alobj)
392 {
393   // Get the alignment object which correspond
394   // to the TGeo volume defined by the 'path'.
395   // The method is extremely slow due to the
396   // searching by string. Therefore it should
397   // be used with great care!!
398
399   // Reset the alignment object
400   alobj.SetPars(0,0,0,0,0,0);
401   alobj.SetVolPath(path);
402
403   if (!gGeoManager || !gGeoManager->IsClosed()) {
404     AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
405     return kFALSE;
406   }
407
408   if (!gGeoManager->GetListOfPhysicalNodes()) {
409     AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
410     return kFALSE;
411   }
412
413   TObjArray* nodesArr = gGeoManager->GetListOfPhysicalNodes();
414   TGeoPhysicalNode* node = NULL;
415   for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
416     node = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
417     const char *nodePath = node->GetName();
418     if (strcmp(path,nodePath) == 0) break;
419   }
420   if (!node) {
421     if (!gGeoManager->cd(path)) {
422       AliErrorClass(Form("Volume path %s not found!",path));
423       return kFALSE;
424     }
425     else {
426       AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
427       return kTRUE;
428     }
429   }
430
431   TGeoHMatrix align,gprime,g,ginv,l;
432   gprime = *node->GetMatrix();
433   l = *node->GetOriginalMatrix();
434   g = *node->GetMatrix(node->GetLevel()-1);
435   g *= l;
436   ginv = g.Inverse();
437   align = gprime * ginv;
438   alobj.SetMatrix(align);
439
440   return kTRUE;
441 }
442
443 void  AliAlignObj::InitAlignObjFromGeometry()
444 {
445   // Loop over all alignable volumes and extract
446   // the corresponding alignment objects from
447   // the TGeo geometry
448
449   if(fgAlignObjs[0]) return;
450   
451   InitVolPaths();
452
453   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
454     fgAlignObjs[iLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer)];
455     for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
456       UShort_t volid = AliAlignObj::LayerToVolUID(iLayer+ AliAlignObj::kFirstLayer,iModule);
457       fgAlignObjs[iLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0);
458       const char *path = GetVolPath(volid);
459       if (!GetFromGeometry(path, *fgAlignObjs[iLayer][iModule]))
460         AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,path));
461     }
462   }
463   
464 }
465
466 //_____________________________________________________________________________
467 AliAlignObj* AliAlignObj::GetAlignObj(ELayerID layerId, Int_t modId)
468 {
469   if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
470     AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
471     return NULL;
472   }
473   return fgAlignObjs[layerId-kFirstLayer][modId];
474 }
475
476 //_____________________________________________________________________________
477 const char* AliAlignObj::GetVolPath(ELayerID layerId, Int_t modId)
478 {
479   if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
480     AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
481     return NULL;
482   }
483   return fgVolPath[layerId-kFirstLayer][modId].Data();
484 }
485
486 //_____________________________________________________________________________
487 void AliAlignObj::InitVolPaths()
488 {
489   // Initialize the LUTs which contain
490   // the TGeo volume paths for each
491   // alignable volume. The LUTs are
492   // static, so they are created during
493   // the creation of the first intance
494   // of AliAlignObj
495
496   if (fgVolPath[0]) return;
497
498   for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++)
499     fgVolPath[iLayer] = new TString[fgLayerSize[iLayer]];
500
501   /*********************       SPD layer1  ***********************/
502   {
503     Int_t modnum = 0;
504     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_"; //".../I12A_"
505     TString str1 = "/I10B_";    //"/I10A_";
506     TString str2 = "/I107_";    //"/I103_"
507     //    TString str3 = "/I101_1/ITS1_1";
508     TString volpath, volpath1, volpath2;
509
510     for(Int_t c1 = 1; c1<=10; c1++){
511       volpath = str0;
512       volpath += c1;
513       volpath += str1;
514       for(Int_t c2 =1; c2<=2; c2++){
515         volpath1 = volpath;
516         volpath1 += c2;
517         volpath1 += str2;
518         for(Int_t c3 =1; c3<=4; c3++){
519           volpath2 = volpath1;
520           volpath2 += c3;
521           //      volpath2 += str3;
522           fgVolPath[kSPD1-kFirstLayer][modnum] = volpath2.Data();
523           modnum++;
524         }
525       }
526     }
527   }
528   
529   /*********************       SPD layer2  ***********************/
530   {
531     Int_t modnum = 0;
532     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_";  //".../I12A_"
533     TString str1 = "/I20B_";  //"/I20A"
534     TString str2 = "/I1D7_";  //"/I1D3"
535     //    TString str3 = "/I1D1_1/ITS2_1";
536     TString volpath, volpath1, volpath2;
537
538     for(Int_t c1 = 1; c1<=10; c1++){
539       volpath = str0;
540       volpath += c1;
541       volpath += str1;
542       for(Int_t c2 =1; c2<=4; c2++){
543         volpath1 = volpath;
544         volpath1 += c2;
545         volpath1 += str2;
546         for(Int_t c3 =1; c3<=4; c3++){
547           volpath2 = volpath1;
548           volpath2 += c3;
549           //      volpath2 += str3;
550           fgVolPath[kSPD2-kFirstLayer][modnum] = volpath2.Data();
551           modnum++;
552         }
553       }
554     }
555   }
556
557   /*********************       SDD layer1  ***********************/
558   {
559     Int_t modnum=0;
560     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I004_";
561     TString str1 = "/I302_";
562     //    TString str2 = "/ITS3_1";
563     TString volpath, volpath1;
564
565     for(Int_t c1 = 1; c1<=14; c1++){
566       volpath = str0;
567       volpath += c1;
568       volpath += str1;
569       for(Int_t c2 =1; c2<=6; c2++){
570         volpath1 = volpath;
571         volpath1 += c2;
572         //      volpath1 += str2;
573         fgVolPath[kSDD1-kFirstLayer][modnum] = volpath1.Data();
574         modnum++;
575       }
576     }
577   }
578
579   /*********************       SDD layer2  ***********************/
580   {
581     Int_t modnum=0;
582     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I005_";
583     TString str1 = "/I402_";
584     //    TString str2 = "/ITS4_1";
585     TString volpath, volpath1;
586
587     for(Int_t c1 = 1; c1<=22; c1++){
588       volpath = str0;
589       volpath += c1;
590       volpath += str1;
591       for(Int_t c2 = 1; c2<=8; c2++){
592         volpath1 = volpath;
593         volpath1 += c2;
594         //      volpath1 += str2;
595         fgVolPath[kSDD2-kFirstLayer][modnum] = volpath1.Data();
596         modnum++;
597       }
598     }
599   }
600
601   /*********************       SSD layer1  ***********************/
602   {
603     Int_t modnum=0;
604     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I565_";
605     TString str1 = "/I562_";
606     //    TString str2 = "/ITS5_1";
607     TString volpath, volpath1;
608
609     for(Int_t c1 = 1; c1<=34; c1++){
610       volpath = str0;
611       volpath += c1;
612       volpath += str1;
613       for(Int_t c2 = 1; c2<=22; c2++){
614         volpath1 = volpath;
615         volpath1 += c2;
616         //      volpath1 += str2;
617         fgVolPath[kSSD1-kFirstLayer][modnum] = volpath1.Data();
618         modnum++;
619       }
620     }
621   }
622
623   /*********************       SSD layer1  ***********************/
624   {
625     Int_t modnum=0;
626     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I569_";
627     TString str1 = "/I566_";
628     //    TString str2 = "/ITS6_1";
629     TString volpath, volpath1;
630
631     for(Int_t c1 = 1; c1<=38; c1++){
632       volpath = str0;
633       volpath += c1;
634       volpath += str1;
635       for(Int_t c2 = 1; c2<=25; c2++){
636         volpath1 = volpath;
637         volpath1 += c2;
638         //      volpath1 += str2;
639         fgVolPath[kSSD2-kFirstLayer][modnum] = volpath1.Data();
640         modnum++;
641       }
642     }
643   }
644
645   /***************    TPC inner chambers' layer    ****************/
646   {
647     Int_t modnum = 0;
648     TString str1 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_1/TPC_SECT_";
649     TString str2 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_2/TPC_SECT_";
650     TString str_in = "/TPC_IROC_1";
651     TString volpath;
652     
653     for(Int_t cnt=1; cnt<=18; cnt++){
654       volpath = str1;
655       volpath += cnt;
656       volpath += str_in;
657       fgVolPath[kTPC1-kFirstLayer][modnum] = volpath.Data();
658       modnum++;
659     }
660     for(Int_t cnt=1; cnt<=18; cnt++){
661       volpath = str2;
662       volpath += cnt;
663       volpath += str_in;
664       fgVolPath[kTPC1-kFirstLayer][modnum] = volpath.Data();
665       modnum++;
666     }
667   }
668
669   /***************    TPC outer chambers' layer    ****************/
670   {
671     Int_t modnum = 0;
672     TString str1 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_1/TPC_SECT_";
673     TString str2 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_2/TPC_SECT_";
674     TString str_out = "/TPC_OROC_1";
675     TString volpath;
676     
677     for(Int_t cnt=1; cnt<=18; cnt++){
678       volpath = str1;
679       volpath += cnt;
680       volpath += str_out;
681       fgVolPath[kTPC2-kFirstLayer][modnum] = volpath.Data();
682       modnum++;
683     }
684     for(Int_t cnt=1; cnt<=18; cnt++){
685       volpath = str2;
686       volpath += cnt;
687       volpath += str_out;
688       fgVolPath[kTPC2-kFirstLayer][modnum] = volpath.Data();
689       modnum++;
690     }
691   }    
692
693   /*********************       TOF layer   ***********************/
694   {
695     Int_t nstrA=15;
696     Int_t nstrB=19;
697     Int_t nstrC=20;
698     Int_t nStripSec=nstrA+2*nstrB+2*nstrC;
699
700     for (Int_t modnum=0; modnum < 1674; modnum++) {
701
702       Int_t sector = modnum/nStripSec;
703       Char_t  string1[100];
704       Char_t  string2[100];
705
706       Int_t icopy=-1;
707
708       if(sector<3){
709         icopy=sector+1;
710         sprintf(string1,"/ALIC_1/B077_1/B075_%i/BTO3_1",icopy);
711       }
712       else if(sector<11){
713         icopy=sector-2;
714         sprintf(string1,"/ALIC_1/B077_1/B071_%i/BTO1_1",icopy);
715       }
716       else if(sector==11 || sector==12){
717         icopy=sector-10;
718         sprintf(string1,"/ALIC_1/B077_1/B074_%i/BTO2_1",icopy);
719       }
720       else {
721         icopy=sector-4;
722         sprintf(string1,"/ALIC_1/B077_1/B071_%i/BTO1_1",icopy);
723       }
724
725       Int_t strInSec=modnum%nStripSec;
726
727       if( strInSec < nstrC){
728         icopy= nstrC - (strInSec+1) + 1;
729         sprintf(string2,"FTOC_1/FLTC_0/FSTR_%i",icopy);
730       }
731       else if(strInSec< nstrC+nstrB){
732  
733         icopy= nstrB - (strInSec-nstrC+1) + 1;
734         sprintf(string2,"FTOB_1/FLTB_0/FSTR_%i",icopy);
735
736       }
737       else if(strInSec< nstrC+nstrB+nstrA){   
738
739         icopy= strInSec-(nstrC+nstrB)+1;
740         sprintf(string2,"FTOA_0/FLTA_0/FSTR_%i",icopy); 
741       }
742       else if(strInSec< nstrC+2*nstrB+nstrA){ 
743
744         icopy= strInSec-(nstrC+nstrB+nstrA)+1;
745         sprintf(string2,"FTOB_2/FLTB_0/FSTR_%i",icopy);
746
747       }
748       else  { 
749
750         icopy= strInSec-(nstrC+2*nstrB+nstrA)+1;
751         sprintf(string2,"FTOC_2/FLTC_0/FSTR_%i",icopy);
752
753       }
754   
755       Char_t  path[100];
756       sprintf(path,"%s/%s",string1,string2); 
757       //      printf("%d  %s\n",modnum,path);
758       fgVolPath[kTOF-kFirstLayer][modnum] = path;
759     }
760   } 
761
762   /*********************      RICH layer   ***********************/
763   {
764     TString str = "ALIC_1/RICH_";
765     TString volpath;
766
767     for (Int_t modnum=0; modnum < 7; modnum++) {
768       volpath = str;
769       volpath += (modnum+1);
770       fgVolPath[kRICH-kFirstLayer][modnum] = volpath.Data();
771     }
772   }
773 }