]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliAlignObj.cxx
Log message moved to debug (R.Grosso)
[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   1638,     // 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 char* volpath, UShort_t voluid) : TObject()
103 {
104   // standard constructor
105   //
106   fVolPath=volpath;
107   fVolUID=voluid;
108 }
109
110 AliAlignObj::AliAlignObj(const char* volpath, ELayerID detId, Int_t volId) : TObject()
111 {
112   // standard constructor
113   // 
114   fVolPath=volpath;
115   SetVolUID(detId,volId); 
116 }
117
118 //_____________________________________________________________________________
119 AliAlignObj::AliAlignObj(const AliAlignObj& theAlignObj) :
120   TObject(theAlignObj)
121 {
122   //copy constructor
123   fVolPath = theAlignObj.GetVolPath();
124   fVolUID = theAlignObj.GetVolUID();
125 }
126
127 //_____________________________________________________________________________
128 AliAlignObj &AliAlignObj::operator =(const AliAlignObj& theAlignObj)
129 {
130   // assignment operator
131   if(this==&theAlignObj) return *this;
132   fVolPath = theAlignObj.GetVolPath();
133   fVolUID = theAlignObj.GetVolUID();
134   return *this;
135 }
136
137 //_____________________________________________________________________________
138 AliAlignObj &AliAlignObj::operator*=(const AliAlignObj& theAlignObj)
139 {
140   // multiplication operator
141   // The operator can be used to 'combine'
142   // two alignment objects
143   TGeoHMatrix m1;
144   GetMatrix(m1);
145   TGeoHMatrix m2;
146   theAlignObj.GetMatrix(m2);
147   m1.MultiplyLeft(&m2);
148   SetMatrix(m1);
149   return *this;
150 }
151
152 //_____________________________________________________________________________
153 AliAlignObj::~AliAlignObj()
154 {
155   // dummy destructor
156 }
157
158 //_____________________________________________________________________________
159 void AliAlignObj::SetVolUID(ELayerID detId, Int_t modId)
160 {
161   // From detector name and module number (according to detector numbering)
162   // build fVolUID, unique numerical identity of that volume inside ALICE
163   // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
164   // remaining 11 for module ID inside det (2048 possible values).
165   //
166   fVolUID = LayerToVolUID(detId,modId);
167 }
168
169 //_____________________________________________________________________________
170 void AliAlignObj::GetVolUID(ELayerID &layerId, Int_t &modId) const
171 {
172   // From detector name and module number (according to detector numbering)
173   // build fVolUID, unique numerical identity of that volume inside ALICE
174   // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
175   // remaining 11 for module ID inside det (2048 possible values).
176   //
177   layerId = VolUIDToLayer(fVolUID,modId);
178 }
179
180 //_____________________________________________________________________________
181 Int_t AliAlignObj::GetLevel() const
182 {
183   // Return the geometry level of
184   // the alignable volume to which
185   // the alignment object is associated
186   TString volpath = fVolPath;
187   return (volpath.CountChar('/')+1);
188 }
189
190 //_____________________________________________________________________________
191 Int_t AliAlignObj::Compare(const TObject *obj) const
192 {
193   // Compare the levels of two
194   // alignment objects
195   // Used in the sorting during
196   // the application of alignment
197   // objects to the geometry
198   Int_t level = GetLevel();
199   Int_t level2 = ((AliAlignObj *)obj)->GetLevel();
200   if (level == level2)
201     return 0;
202   else
203     return ((level > level2) ? 1 : -1);
204 }
205
206 //_____________________________________________________________________________
207 void AliAlignObj::AnglesToMatrix(const Double_t *angles, Double_t *rot) const
208 {
209   // Calculates the rotation matrix using the 
210   // Euler angles in "x y z" notation
211   Double_t degrad = TMath::DegToRad();
212   Double_t sinpsi = TMath::Sin(degrad*angles[0]);
213   Double_t cospsi = TMath::Cos(degrad*angles[0]);
214   Double_t sinthe = TMath::Sin(degrad*angles[1]);
215   Double_t costhe = TMath::Cos(degrad*angles[1]);
216   Double_t sinphi = TMath::Sin(degrad*angles[2]);
217   Double_t cosphi = TMath::Cos(degrad*angles[2]);
218
219   rot[0] =  costhe*cosphi;
220   rot[1] = -costhe*sinphi;
221   rot[2] =  sinthe;
222   rot[3] =  sinpsi*sinthe*cosphi + cospsi*sinphi;
223   rot[4] = -sinpsi*sinthe*sinphi + cospsi*cosphi;
224   rot[5] = -costhe*sinpsi;
225   rot[6] = -cospsi*sinthe*cosphi + sinpsi*sinphi;
226   rot[7] =  cospsi*sinthe*sinphi + sinpsi*cosphi;
227   rot[8] =  costhe*cospsi;
228 }
229
230 //_____________________________________________________________________________
231 Bool_t AliAlignObj::MatrixToAngles(const Double_t *rot, Double_t *angles) const
232 {
233   // Calculates the Euler angles in "x y z" notation
234   // using the rotation matrix
235   if(TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) return kFALSE;
236   Double_t raddeg = TMath::RadToDeg();
237   angles[0]=raddeg*TMath::ATan2(-rot[5],rot[8]);
238   angles[1]=raddeg*TMath::ASin(rot[2]);
239   angles[2]=raddeg*TMath::ATan2(-rot[1],rot[0]);
240   return kTRUE;
241 }
242
243 //______________________________________________________________________________
244 void AliAlignObj::Transform(AliTrackPoint &p) const
245 {
246   // The method transforms the space-point coordinates using the
247   // transformation matrix provided by the AliAlignObj
248   // The covariance matrix is not affected since we assume
249   // that the transformations are sufficiently small
250
251   if (fVolUID != p.GetVolumeID())
252     AliWarning(Form("Alignment object ID is not equal to the space-point ID (%d != %d)",fVolUID,p.GetVolumeID())); 
253
254   TGeoHMatrix m;
255   GetMatrix(m);
256   Double_t *rot = m.GetRotationMatrix();
257   Double_t *tr  = m.GetTranslation();
258
259   Float_t xyzin[3],xyzout[3];
260   p.GetXYZ(xyzin);
261   for (Int_t i = 0; i < 3; i++)
262     xyzout[i] = tr[i]+
263                 xyzin[0]*rot[3*i]+
264                 xyzin[1]*rot[3*i+1]+
265                 xyzin[2]*rot[3*i+2];
266   p.SetXYZ(xyzout);
267   
268 }
269
270 //_____________________________________________________________________________
271 void AliAlignObj::Transform(AliTrackPointArray &array) const
272 {
273   AliTrackPoint p;
274   for (Int_t i = 0; i < array.GetNPoints(); i++) {
275     array.GetPoint(p,i);
276     Transform(p);
277     array.AddPoint(i,&p);
278   }
279 }
280
281 //_____________________________________________________________________________
282 void AliAlignObj::Print(Option_t *) const
283 {
284   // Print the contents of the
285   // alignment object in angles and
286   // matrix representations
287   Double_t tr[3];
288   GetTranslation(tr);
289   Double_t angles[3];
290   GetAngles(angles);
291   TGeoHMatrix m;
292   GetMatrix(m);
293   const Double_t *rot = m.GetRotationMatrix();
294
295   printf("Volume=%s\n",GetVolPath());
296   if (GetVolUID() != 0) {
297     ELayerID layerId;
298     Int_t modId;
299     GetVolUID(layerId,modId);
300     printf("VolumeID=%d LayerID=%d ( %s ) ModuleID=%d\n", GetVolUID(),layerId,LayerName(layerId),modId);
301   }
302   printf("%12.8f%12.8f%12.8f    Tx = %12.8f    Psi   = %12.8f\n", rot[0], rot[1], rot[2], tr[0], angles[0]);
303   printf("%12.8f%12.8f%12.8f    Ty = %12.8f    Theta = %12.8f\n", rot[3], rot[4], rot[5], tr[1], angles[1]);
304   printf("%12.8f%12.8f%12.8f    Tz = %12.8f    Phi   = %12.8f\n", rot[6], rot[7], rot[8], tr[2], angles[2]);
305
306 }
307
308 //_____________________________________________________________________________
309 Int_t AliAlignObj::LayerSize(Int_t layerId)
310 {
311   // Get the corresponding layer size.
312   // Implemented only for ITS,TPC,TRD,TOF and RICH
313   if (layerId < kFirstLayer || layerId >= kLastLayer) {
314     AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
315     return 0;
316   }
317   else {
318     return fgLayerSize[layerId - kFirstLayer];
319  }
320 }
321
322 //_____________________________________________________________________________
323 const char* AliAlignObj::LayerName(Int_t layerId)
324 {
325   // Get the corresponding layer name.
326   // Implemented only for ITS,TPC,TRD,TOF and RICH
327   if (layerId < kFirstLayer || layerId >= kLastLayer) {
328     AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
329     return "Invalid Layer!";
330   }
331   else {
332     return fgLayerName[layerId - kFirstLayer];
333  }
334 }
335
336 //_____________________________________________________________________________
337 UShort_t AliAlignObj::LayerToVolUID(ELayerID layerId, Int_t modId)
338 {
339   // From detector (layer) name and module number (according to detector numbering)
340   // build fVolUID, unique numerical identity of that volume inside ALICE
341   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
342   // remaining 11 for module ID inside det (2048 possible values).
343   //
344   return ((UShort_t(layerId) << 11) | UShort_t(modId));
345 }
346
347 //_____________________________________________________________________________
348 UShort_t AliAlignObj::LayerToVolUID(Int_t   layerId, Int_t modId)
349 {
350   // From detector (layer) index and module number (according to detector numbering)
351   // build fVolUID, unique numerical identity of that volume inside ALICE
352   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
353   // remaining 11 for module ID inside det (2048 possible values).
354   //
355   return ((UShort_t(layerId) << 11) | UShort_t(modId));
356 }
357
358 //_____________________________________________________________________________
359 AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid, Int_t &modId)
360 {
361   // From detector (layer) name and module number (according to detector numbering)
362   // build fVolUID, unique numerical identity of that volume inside ALICE
363   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
364   // remaining 11 for module ID inside det (2048 possible values).
365   //
366   modId = voluid & 0x7ff;
367
368   return VolUIDToLayer(voluid);
369 }
370
371 //_____________________________________________________________________________
372 AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid)
373 {
374   // From detector (layer) name and module number (according to detector numbering)
375   // build fVolUID, unique numerical identity of that volume inside ALICE
376   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
377   // remaining 11 for module ID inside det (2048 possible values).
378   //
379   return ELayerID((voluid >> 11) & 0x1f);
380 }
381
382 //_____________________________________________________________________________
383 Bool_t AliAlignObj::SetLocalPars(Double_t x, Double_t y, Double_t z,
384                                  Double_t psi, Double_t theta, Double_t phi)
385 {
386   // Set the translations and angles by using parameters
387   // defined in the local (in TGeo means) coordinate system
388   // of the alignable volume. In case that the TGeo was
389   // initialized, returns false and the object parameters are
390   // not set.
391   if (!gGeoManager || !gGeoManager->IsClosed()) {
392     AliError("Can't set the alignment object parameters! gGeoManager doesn't exist or it is still opened!");
393     return kFALSE;
394   }
395
396   const char* volpath = GetVolPath();
397   TGeoPhysicalNode* node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(volpath);
398   if (!node) {
399     AliError(Form("Volume path %s not valid!",volpath));
400     return kFALSE;
401   }
402   if (node->IsAligned())
403     AliWarning(Form("Volume %s has been already misaligned!",volpath));
404
405   TGeoHMatrix m;
406   Double_t tr[3];
407   tr[0]=x; tr[1]=y; tr[2]=z;
408   m.SetTranslation(tr);
409   Double_t angles[3] = {psi, theta, phi};
410   Double_t rot[9];
411   AnglesToMatrix(angles,rot);
412   m.SetRotation(rot);
413
414   TGeoHMatrix align,gprime,gprimeinv;
415   gprime = *node->GetMatrix();
416   gprimeinv = gprime.Inverse();
417   m.Multiply(&gprimeinv);
418   m.MultiplyLeft(&gprime);
419
420   SetMatrix(m);
421
422   return kTRUE;
423 }
424
425 //_____________________________________________________________________________
426 Bool_t AliAlignObj::ApplyToGeometry()
427 {
428   // Apply the current alignment object
429   // to the TGeo geometry
430
431   if (!gGeoManager || !gGeoManager->IsClosed()) {
432     AliError("Can't apply the alignment object! gGeoManager doesn't exist or it is still opened!");
433     return kFALSE;
434   }
435   
436   const char* volpath = GetVolPath();
437   TGeoPhysicalNode* node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(volpath);
438   if (!node) {
439     AliError(Form("Volume path %s not valid!",volpath));
440     return kFALSE;
441   }
442   if (node->IsAligned()) {
443     AliWarning(Form("Volume %s has been already misaligned!",volpath));
444     return kFALSE;
445   }
446
447   TGeoHMatrix align,gprime;
448   gprime = *node->GetMatrix();
449   GetMatrix(align);
450   gprime.MultiplyLeft(&align);
451   TGeoHMatrix *ginv = new TGeoHMatrix;
452   TGeoHMatrix *g = node->GetMatrix(node->GetLevel()-1);
453   *ginv = g->Inverse();
454   *ginv *= gprime;
455   AliAlignObj::ELayerID layerId; // unique identity for volume in the alobj
456   Int_t modId; // unique identity for volume in the alobj
457   GetVolUID(layerId, modId);
458   AliDebug(2,Form("Aligning volume %s of detector layer %d with local ID %d",volpath,layerId,modId));
459   node->Align(ginv);
460
461   return kTRUE;
462 }
463
464 //_____________________________________________________________________________
465 Bool_t AliAlignObj::GetFromGeometry(const char *path, AliAlignObj &alobj)
466 {
467   // Get the alignment object which correspond
468   // to the TGeo volume defined by the 'path'.
469   // The method is extremely slow due to the
470   // searching by string. Therefore it should
471   // be used with great care!!
472
473   // Reset the alignment object
474   alobj.SetPars(0,0,0,0,0,0);
475   alobj.SetVolPath(path);
476
477   if (!gGeoManager || !gGeoManager->IsClosed()) {
478     AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
479     return kFALSE;
480   }
481
482   if (!gGeoManager->GetListOfPhysicalNodes()) {
483     AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
484     return kFALSE;
485   }
486
487   TObjArray* nodesArr = gGeoManager->GetListOfPhysicalNodes();
488   TGeoPhysicalNode* node = NULL;
489   for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
490     node = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
491     const char *nodePath = node->GetName();
492     if (strcmp(path,nodePath) == 0) break;
493   }
494   if (!node) {
495     if (!gGeoManager->cd(path)) {
496       AliErrorClass(Form("Volume path %s not found!",path));
497       return kFALSE;
498     }
499     else {
500       AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
501       return kTRUE;
502     }
503   }
504
505   TGeoHMatrix align,gprime,g,ginv,l;
506   gprime = *node->GetMatrix();
507   l = *node->GetOriginalMatrix();
508   g = *node->GetMatrix(node->GetLevel()-1);
509   g *= l;
510   ginv = g.Inverse();
511   align = gprime * ginv;
512   alobj.SetMatrix(align);
513
514   return kTRUE;
515 }
516
517 //_____________________________________________________________________________
518 void  AliAlignObj::InitAlignObjFromGeometry()
519 {
520   // Loop over all alignable volumes and extract
521   // the corresponding alignment objects from
522   // the TGeo geometry
523
524   if(fgAlignObjs[0]) return;
525   
526   InitVolPaths();
527
528   for (Int_t iLayer = kFirstLayer; iLayer < AliAlignObj::kLastLayer; iLayer++) {
529     fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer)];
530     for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
531       UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,iModule);
532       fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0);
533       const char *path = GetVolPath(volid);
534       if (!GetFromGeometry(path, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
535         AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,path));
536     }
537   }
538   
539 }
540
541 //_____________________________________________________________________________
542 AliAlignObj* AliAlignObj::GetAlignObj(ELayerID layerId, Int_t modId)
543 {
544   if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
545     AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
546     return NULL;
547   }
548   return fgAlignObjs[layerId-kFirstLayer][modId];
549 }
550
551 //_____________________________________________________________________________
552 const char* AliAlignObj::GetVolPath(ELayerID layerId, Int_t modId)
553 {
554   if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
555     AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
556     return NULL;
557   }
558   return fgVolPath[layerId-kFirstLayer][modId].Data();
559 }
560
561 //_____________________________________________________________________________
562 void AliAlignObj::InitVolPaths()
563 {
564   // Initialize the LUTs which contain
565   // the TGeo volume paths for each
566   // alignable volume. The LUTs are
567   // static, so they are created during
568   // the creation of the first intance
569   // of AliAlignObj
570
571   if (fgVolPath[0]) return;
572
573   for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++)
574     fgVolPath[iLayer] = new TString[fgLayerSize[iLayer]];
575
576   /*********************       SPD layer1  ***********************/
577   {
578     Int_t modnum = 0;
579     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_"; //".../I12A_"
580     TString str1 = "/I10B_";    //"/I10A_";
581     TString str2 = "/I107_";    //"/I103_"
582     //    TString str3 = "/I101_1/ITS1_1";
583     TString volpath, volpath1, volpath2;
584
585     for(Int_t c1 = 1; c1<=10; c1++){
586       volpath = str0;
587       volpath += c1;
588       volpath += str1;
589       for(Int_t c2 =1; c2<=2; c2++){
590         volpath1 = volpath;
591         volpath1 += c2;
592         volpath1 += str2;
593         for(Int_t c3 =1; c3<=4; c3++){
594           volpath2 = volpath1;
595           volpath2 += c3;
596           //      volpath2 += str3;
597           fgVolPath[kSPD1-kFirstLayer][modnum] = volpath2.Data();
598           modnum++;
599         }
600       }
601     }
602   }
603   
604   /*********************       SPD layer2  ***********************/
605   {
606     Int_t modnum = 0;
607     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_";  //".../I12A_"
608     TString str1 = "/I20B_";  //"/I20A"
609     TString str2 = "/I1D7_";  //"/I1D3"
610     //    TString str3 = "/I1D1_1/ITS2_1";
611     TString volpath, volpath1, volpath2;
612
613     for(Int_t c1 = 1; c1<=10; c1++){
614       volpath = str0;
615       volpath += c1;
616       volpath += str1;
617       for(Int_t c2 =1; c2<=4; c2++){
618         volpath1 = volpath;
619         volpath1 += c2;
620         volpath1 += str2;
621         for(Int_t c3 =1; c3<=4; c3++){
622           volpath2 = volpath1;
623           volpath2 += c3;
624           //      volpath2 += str3;
625           fgVolPath[kSPD2-kFirstLayer][modnum] = volpath2.Data();
626           modnum++;
627         }
628       }
629     }
630   }
631
632   /*********************       SDD layer1  ***********************/
633   {
634     Int_t modnum=0;
635     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I004_";
636     TString str1 = "/I302_";
637     //    TString str2 = "/ITS3_1";
638     TString volpath, volpath1;
639
640     for(Int_t c1 = 1; c1<=14; c1++){
641       volpath = str0;
642       volpath += c1;
643       volpath += str1;
644       for(Int_t c2 =1; c2<=6; c2++){
645         volpath1 = volpath;
646         volpath1 += c2;
647         //      volpath1 += str2;
648         fgVolPath[kSDD1-kFirstLayer][modnum] = volpath1.Data();
649         modnum++;
650       }
651     }
652   }
653
654   /*********************       SDD layer2  ***********************/
655   {
656     Int_t modnum=0;
657     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I005_";
658     TString str1 = "/I402_";
659     //    TString str2 = "/ITS4_1";
660     TString volpath, volpath1;
661
662     for(Int_t c1 = 1; c1<=22; c1++){
663       volpath = str0;
664       volpath += c1;
665       volpath += str1;
666       for(Int_t c2 = 1; c2<=8; c2++){
667         volpath1 = volpath;
668         volpath1 += c2;
669         //      volpath1 += str2;
670         fgVolPath[kSDD2-kFirstLayer][modnum] = volpath1.Data();
671         modnum++;
672       }
673     }
674   }
675
676   /*********************       SSD layer1  ***********************/
677   {
678     Int_t modnum=0;
679     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I565_";
680     TString str1 = "/I562_";
681     //    TString str2 = "/ITS5_1";
682     TString volpath, volpath1;
683
684     for(Int_t c1 = 1; c1<=34; c1++){
685       volpath = str0;
686       volpath += c1;
687       volpath += str1;
688       for(Int_t c2 = 1; c2<=22; c2++){
689         volpath1 = volpath;
690         volpath1 += c2;
691         //      volpath1 += str2;
692         fgVolPath[kSSD1-kFirstLayer][modnum] = volpath1.Data();
693         modnum++;
694       }
695     }
696   }
697
698   /*********************       SSD layer1  ***********************/
699   {
700     Int_t modnum=0;
701     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I569_";
702     TString str1 = "/I566_";
703     //    TString str2 = "/ITS6_1";
704     TString volpath, volpath1;
705
706     for(Int_t c1 = 1; c1<=38; c1++){
707       volpath = str0;
708       volpath += c1;
709       volpath += str1;
710       for(Int_t c2 = 1; c2<=25; c2++){
711         volpath1 = volpath;
712         volpath1 += c2;
713         //      volpath1 += str2;
714         fgVolPath[kSSD2-kFirstLayer][modnum] = volpath1.Data();
715         modnum++;
716       }
717     }
718   }
719
720   /***************    TPC inner chambers' layer    ****************/
721   {
722     Int_t modnum = 0;
723     TString str1 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_1/TPC_SECT_";
724     TString str2 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_2/TPC_SECT_";
725     TString str_in = "/TPC_IROC_1";
726     TString volpath;
727     
728     for(Int_t cnt=1; cnt<=18; cnt++){
729       volpath = str1;
730       volpath += cnt;
731       volpath += str_in;
732       fgVolPath[kTPC1-kFirstLayer][modnum] = volpath.Data();
733       modnum++;
734     }
735     for(Int_t cnt=1; cnt<=18; cnt++){
736       volpath = str2;
737       volpath += cnt;
738       volpath += str_in;
739       fgVolPath[kTPC1-kFirstLayer][modnum] = volpath.Data();
740       modnum++;
741     }
742   }
743
744   /***************    TPC outer chambers' layer    ****************/
745   {
746     Int_t modnum = 0;
747     TString str1 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_1/TPC_SECT_";
748     TString str2 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_2/TPC_SECT_";
749     TString str_out = "/TPC_OROC_1";
750     TString volpath;
751     
752     for(Int_t cnt=1; cnt<=18; cnt++){
753       volpath = str1;
754       volpath += cnt;
755       volpath += str_out;
756       fgVolPath[kTPC2-kFirstLayer][modnum] = volpath.Data();
757       modnum++;
758     }
759     for(Int_t cnt=1; cnt<=18; cnt++){
760       volpath = str2;
761       volpath += cnt;
762       volpath += str_out;
763       fgVolPath[kTPC2-kFirstLayer][modnum] = volpath.Data();
764       modnum++;
765     }
766   }    
767
768   /*********************       TOF layer   ***********************/
769   {
770     Int_t nstrA=15;
771     Int_t nstrB=19;
772     Int_t nstrC=19;
773     Int_t nsec=18;
774     Int_t nStripSec=nstrA+2*nstrB+2*nstrC;
775     Int_t nStrip=nStripSec*nsec;
776
777     for (Int_t modnum=0; modnum < nStrip; modnum++) {
778
779       Int_t sector = modnum/nStripSec;
780       Char_t  string1[100];
781       Char_t  string2[100];
782
783       Int_t icopy=-1;
784
785       if(sector<3){
786         icopy=sector+1;
787         sprintf(string1,"/ALIC_1/B077_1/B075_%i/BTO3_1/FTOA_0/FLTA_0",icopy);
788       }
789       else if(sector<11){
790         icopy=sector+3;
791         sprintf(string1,"/ALIC_1/B077_1/B071_%i/BTO1_1/FTOA_0/FLTA_0",icopy);
792       }
793       else if(sector==11 || sector==12){
794         icopy=sector-10;
795         sprintf(string1,"/ALIC_1/B077_1/B074_%i/BTO2_1/FTOA_0/FLTA_0",icopy);
796       }
797       else {
798         icopy=sector-12;
799         sprintf(string1,"/ALIC_1/B077_1/B071_%i/BTO1_1/FTOA_0/FLTA_0",icopy);
800       }
801       
802       Int_t strInSec=modnum%nStripSec;
803       icopy= strInSec;
804       icopy++;
805       sprintf(string2,"FSTR_%i",icopy);      
806       Char_t  path[100];
807       sprintf(path,"%s/%s",string1,string2); 
808       //      printf("%d  %s\n",modnum,path);
809       fgVolPath[kTOF-kFirstLayer][modnum] = path;
810     }
811   } 
812
813   /*********************      RICH layer   ***********************/
814   {
815     TString str = "ALIC_1/RICH_";
816     TString volpath;
817
818     for (Int_t modnum=0; modnum < 7; modnum++) {
819       volpath = str;
820       volpath += (modnum+1);
821       fgVolPath[kRICH-kFirstLayer][modnum] = volpath.Data();
822     }
823   }
824
825   /*********************      TRD layers 0-6   *******************/
826   {
827     TString strSM[18]={"ALIC_1/B077_1/B075_1/BTR3_1/UTR1_3/UTS1_1/UTI1_1/UT",
828                        "ALIC_1/B077_1/B075_2/BTR3_1/UTR1_3/UTS1_1/UTI1_1/UT",
829                        "ALIC_1/B077_1/B075_3/BTR3_1/UTR1_3/UTS1_1/UTI1_1/UT",
830                        "ALIC_1/B077_1/B071_6/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
831                        "ALIC_1/B077_1/B071_7/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
832                        "ALIC_1/B077_1/B071_8/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
833                        "ALIC_1/B077_1/B071_9/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
834                        "ALIC_1/B077_1/B071_10/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
835                        "ALIC_1/B077_1/B071_11/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
836                        "ALIC_1/B077_1/B071_12/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
837                        "ALIC_1/B077_1/B071_13/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
838                        "ALIC_1/B077_1/B074_1/BTR2_1/UTR1_2/UTS1_1/UTI1_1/UT",
839                        "ALIC_1/B077_1/B074_2/BTR2_1/UTR1_2/UTS1_1/UTI1_1/UT",
840                        "ALIC_1/B077_1/B071_1/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
841                        "ALIC_1/B077_1/B071_2/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
842                        "ALIC_1/B077_1/B071_3/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
843                        "ALIC_1/B077_1/B071_4/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
844                        "ALIC_1/B077_1/B071_5/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT"};
845     TString strPost = "_1";
846     TString zeroStr = "0";
847     TString volpath;
848
849     Int_t TRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
850
851     for(Int_t layer=0; layer<6; layer++){
852       Int_t modnum=0;
853       for(Int_t sm = 0; sm < 18; sm++){
854         for(Int_t stacknum = 0; stacknum < 5; stacknum++){
855           Int_t chnum = layer + stacknum*6;
856           volpath = strSM[sm];
857           if(chnum<10) volpath += zeroStr;
858           volpath += chnum;
859           volpath += strPost;
860           fgVolPath[TRDlayId[layer]-kFirstLayer][modnum] = volpath.Data();
861           modnum++;
862         }
863       }
864     }
865   }
866
867 }