New constructors added to AliAlignObj and the derived classes (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   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 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 //   printf("Volume=%s ID=%u\n", GetVolPath(),GetVolUID());
295   ELayerID layerId;
296   Int_t modId;
297   GetVolUID(layerId,modId);
298   printf("Volume=%s LayerID=%d ModuleID=%d\n", GetVolPath(),layerId,modId);
299   printf("%12.6f%12.6f%12.6f    Tx = %12.6f    Psi   = %12.6f\n", rot[0], rot[1], rot[2], tr[0], angles[0]);
300   printf("%12.6f%12.6f%12.6f    Ty = %12.6f    Theta = %12.6f\n", rot[3], rot[4], rot[5], tr[1], angles[1]);
301   printf("%12.6f%12.6f%12.6f    Tz = %12.6f    Phi   = %12.6f\n", rot[6], rot[7], rot[8], tr[2], angles[2]);
302
303 }
304
305 //_____________________________________________________________________________
306 UShort_t AliAlignObj::LayerToVolUID(ELayerID layerId, Int_t modId)
307 {
308   // From detector (layer) name and module number (according to detector numbering)
309   // build fVolUID, unique numerical identity of that volume inside ALICE
310   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
311   // remaining 11 for module ID inside det (2048 possible values).
312   //
313   return ((UShort_t(layerId) << 11) | UShort_t(modId));
314 }
315
316 //_____________________________________________________________________________
317 UShort_t AliAlignObj::LayerToVolUID(Int_t   layerId, Int_t modId)
318 {
319   // From detector (layer) index and module number (according to detector numbering)
320   // build fVolUID, unique numerical identity of that volume inside ALICE
321   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
322   // remaining 11 for module ID inside det (2048 possible values).
323   //
324   return ((UShort_t(layerId) << 11) | UShort_t(modId));
325 }
326
327 //_____________________________________________________________________________
328 AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid, Int_t &modId)
329 {
330   // From detector (layer) name and module number (according to detector numbering)
331   // build fVolUID, unique numerical identity of that volume inside ALICE
332   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
333   // remaining 11 for module ID inside det (2048 possible values).
334   //
335   modId = voluid & 0x7ff;
336
337   return VolUIDToLayer(voluid);
338 }
339
340 //_____________________________________________________________________________
341 AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid)
342 {
343   // From detector (layer) name and module number (according to detector numbering)
344   // build fVolUID, unique numerical identity of that volume inside ALICE
345   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
346   // remaining 11 for module ID inside det (2048 possible values).
347   //
348   return ELayerID((voluid >> 11) & 0x1f);
349 }
350
351 //_____________________________________________________________________________
352 Bool_t AliAlignObj::SetLocalPars(Double_t x, Double_t y, Double_t z,
353                                  Double_t psi, Double_t theta, Double_t phi)
354 {
355   // Set the translations and angles by using parameters
356   // defined in the local (in TGeo means) coordinate system
357   // of the alignable volume. In case that the TGeo was
358   // initialized, returns false and the object parameters are
359   // not set.
360   if (!gGeoManager || !gGeoManager->IsClosed()) {
361     AliError("Can't set the alignment object parameters! gGeoManager doesn't exist or it is still opened!");
362     return kFALSE;
363   }
364
365   const char* volpath = GetVolPath();
366   TGeoPhysicalNode* node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(volpath);
367   if (!node) {
368     AliError(Form("Volume path %s not valid!",volpath));
369     return kFALSE;
370   }
371   if (node->IsAligned())
372     AliWarning(Form("Volume %s has been already misaligned!",volpath));
373
374   TGeoHMatrix m;
375   Double_t tr[3];
376   tr[0]=x; tr[1]=y; tr[2]=z;
377   m.SetTranslation(tr);
378   Double_t angles[3] = {psi, theta, phi};
379   Double_t rot[9];
380   AnglesToMatrix(angles,rot);
381   m.SetRotation(rot);
382
383   TGeoHMatrix align,gprime,gprimeinv;
384   gprime = *node->GetMatrix();
385   gprimeinv = gprime.Inverse();
386   m.Multiply(&gprimeinv);
387   m.MultiplyLeft(&gprime);
388
389   SetMatrix(m);
390
391   return kTRUE;
392 }
393
394 //_____________________________________________________________________________
395 Bool_t AliAlignObj::ApplyToGeometry()
396 {
397   // Apply the current alignment object
398   // to the TGeo geometry
399
400   if (!gGeoManager || !gGeoManager->IsClosed()) {
401     AliError("Can't apply the alignment object! gGeoManager doesn't exist or it is still opened!");
402     return kFALSE;
403   }
404   
405   const char* volpath = GetVolPath();
406   TGeoPhysicalNode* node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(volpath);
407   if (!node) {
408     AliError(Form("Volume path %s not valid!",volpath));
409     return kFALSE;
410   }
411   if (node->IsAligned()) {
412     AliWarning(Form("Volume %s has been already misaligned!",volpath));
413     return kFALSE;
414   }
415
416   TGeoHMatrix align,gprime;
417   gprime = *node->GetMatrix();
418   GetMatrix(align);
419   gprime.MultiplyLeft(&align);
420   TGeoHMatrix *ginv = new TGeoHMatrix;
421   TGeoHMatrix *g = node->GetMatrix(node->GetLevel()-1);
422   *ginv = g->Inverse();
423   *ginv *= gprime;
424   AliAlignObj::ELayerID layerId; // unique identity for volume in the alobj
425   Int_t modId; // unique identity for volume in the alobj
426   GetVolUID(layerId, modId);
427   AliInfo(Form("Aligning volume %s of detector layer %d with local ID %d",volpath,layerId,modId));
428   node->Align(ginv);
429
430   return kTRUE;
431 }
432
433 //_____________________________________________________________________________
434 Bool_t AliAlignObj::GetFromGeometry(const char *path, AliAlignObj &alobj)
435 {
436   // Get the alignment object which correspond
437   // to the TGeo volume defined by the 'path'.
438   // The method is extremely slow due to the
439   // searching by string. Therefore it should
440   // be used with great care!!
441
442   // Reset the alignment object
443   alobj.SetPars(0,0,0,0,0,0);
444   alobj.SetVolPath(path);
445
446   if (!gGeoManager || !gGeoManager->IsClosed()) {
447     AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
448     return kFALSE;
449   }
450
451   if (!gGeoManager->GetListOfPhysicalNodes()) {
452     AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
453     return kFALSE;
454   }
455
456   TObjArray* nodesArr = gGeoManager->GetListOfPhysicalNodes();
457   TGeoPhysicalNode* node = NULL;
458   for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
459     node = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
460     const char *nodePath = node->GetName();
461     if (strcmp(path,nodePath) == 0) break;
462   }
463   if (!node) {
464     if (!gGeoManager->cd(path)) {
465       AliErrorClass(Form("Volume path %s not found!",path));
466       return kFALSE;
467     }
468     else {
469       AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
470       return kTRUE;
471     }
472   }
473
474   TGeoHMatrix align,gprime,g,ginv,l;
475   gprime = *node->GetMatrix();
476   l = *node->GetOriginalMatrix();
477   g = *node->GetMatrix(node->GetLevel()-1);
478   g *= l;
479   ginv = g.Inverse();
480   align = gprime * ginv;
481   alobj.SetMatrix(align);
482
483   return kTRUE;
484 }
485
486 void  AliAlignObj::InitAlignObjFromGeometry()
487 {
488   // Loop over all alignable volumes and extract
489   // the corresponding alignment objects from
490   // the TGeo geometry
491
492   if(fgAlignObjs[0]) return;
493   
494   InitVolPaths();
495
496   for (Int_t iLayer = 0; iLayer < (AliAlignObj::kLastLayer - AliAlignObj::kFirstLayer); iLayer++) {
497     fgAlignObjs[iLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer)];
498     for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
499       UShort_t volid = AliAlignObj::LayerToVolUID(iLayer+ AliAlignObj::kFirstLayer,iModule);
500       fgAlignObjs[iLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0);
501       const char *path = GetVolPath(volid);
502       if (!GetFromGeometry(path, *fgAlignObjs[iLayer][iModule]))
503         AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,path));
504     }
505   }
506   
507 }
508
509 //_____________________________________________________________________________
510 AliAlignObj* AliAlignObj::GetAlignObj(ELayerID layerId, Int_t modId)
511 {
512   if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
513     AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
514     return NULL;
515   }
516   return fgAlignObjs[layerId-kFirstLayer][modId];
517 }
518
519 //_____________________________________________________________________________
520 const char* AliAlignObj::GetVolPath(ELayerID layerId, Int_t modId)
521 {
522   if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
523     AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
524     return NULL;
525   }
526   return fgVolPath[layerId-kFirstLayer][modId].Data();
527 }
528
529 //_____________________________________________________________________________
530 void AliAlignObj::InitVolPaths()
531 {
532   // Initialize the LUTs which contain
533   // the TGeo volume paths for each
534   // alignable volume. The LUTs are
535   // static, so they are created during
536   // the creation of the first intance
537   // of AliAlignObj
538
539   if (fgVolPath[0]) return;
540
541   for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++)
542     fgVolPath[iLayer] = new TString[fgLayerSize[iLayer]];
543
544   /*********************       SPD layer1  ***********************/
545   {
546     Int_t modnum = 0;
547     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_"; //".../I12A_"
548     TString str1 = "/I10B_";    //"/I10A_";
549     TString str2 = "/I107_";    //"/I103_"
550     //    TString str3 = "/I101_1/ITS1_1";
551     TString volpath, volpath1, volpath2;
552
553     for(Int_t c1 = 1; c1<=10; c1++){
554       volpath = str0;
555       volpath += c1;
556       volpath += str1;
557       for(Int_t c2 =1; c2<=2; c2++){
558         volpath1 = volpath;
559         volpath1 += c2;
560         volpath1 += str2;
561         for(Int_t c3 =1; c3<=4; c3++){
562           volpath2 = volpath1;
563           volpath2 += c3;
564           //      volpath2 += str3;
565           fgVolPath[kSPD1-kFirstLayer][modnum] = volpath2.Data();
566           modnum++;
567         }
568       }
569     }
570   }
571   
572   /*********************       SPD layer2  ***********************/
573   {
574     Int_t modnum = 0;
575     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_";  //".../I12A_"
576     TString str1 = "/I20B_";  //"/I20A"
577     TString str2 = "/I1D7_";  //"/I1D3"
578     //    TString str3 = "/I1D1_1/ITS2_1";
579     TString volpath, volpath1, volpath2;
580
581     for(Int_t c1 = 1; c1<=10; c1++){
582       volpath = str0;
583       volpath += c1;
584       volpath += str1;
585       for(Int_t c2 =1; c2<=4; c2++){
586         volpath1 = volpath;
587         volpath1 += c2;
588         volpath1 += str2;
589         for(Int_t c3 =1; c3<=4; c3++){
590           volpath2 = volpath1;
591           volpath2 += c3;
592           //      volpath2 += str3;
593           fgVolPath[kSPD2-kFirstLayer][modnum] = volpath2.Data();
594           modnum++;
595         }
596       }
597     }
598   }
599
600   /*********************       SDD layer1  ***********************/
601   {
602     Int_t modnum=0;
603     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I004_";
604     TString str1 = "/I302_";
605     //    TString str2 = "/ITS3_1";
606     TString volpath, volpath1;
607
608     for(Int_t c1 = 1; c1<=14; c1++){
609       volpath = str0;
610       volpath += c1;
611       volpath += str1;
612       for(Int_t c2 =1; c2<=6; c2++){
613         volpath1 = volpath;
614         volpath1 += c2;
615         //      volpath1 += str2;
616         fgVolPath[kSDD1-kFirstLayer][modnum] = volpath1.Data();
617         modnum++;
618       }
619     }
620   }
621
622   /*********************       SDD layer2  ***********************/
623   {
624     Int_t modnum=0;
625     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I005_";
626     TString str1 = "/I402_";
627     //    TString str2 = "/ITS4_1";
628     TString volpath, volpath1;
629
630     for(Int_t c1 = 1; c1<=22; c1++){
631       volpath = str0;
632       volpath += c1;
633       volpath += str1;
634       for(Int_t c2 = 1; c2<=8; c2++){
635         volpath1 = volpath;
636         volpath1 += c2;
637         //      volpath1 += str2;
638         fgVolPath[kSDD2-kFirstLayer][modnum] = volpath1.Data();
639         modnum++;
640       }
641     }
642   }
643
644   /*********************       SSD layer1  ***********************/
645   {
646     Int_t modnum=0;
647     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I565_";
648     TString str1 = "/I562_";
649     //    TString str2 = "/ITS5_1";
650     TString volpath, volpath1;
651
652     for(Int_t c1 = 1; c1<=34; c1++){
653       volpath = str0;
654       volpath += c1;
655       volpath += str1;
656       for(Int_t c2 = 1; c2<=22; c2++){
657         volpath1 = volpath;
658         volpath1 += c2;
659         //      volpath1 += str2;
660         fgVolPath[kSSD1-kFirstLayer][modnum] = volpath1.Data();
661         modnum++;
662       }
663     }
664   }
665
666   /*********************       SSD layer1  ***********************/
667   {
668     Int_t modnum=0;
669     TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I569_";
670     TString str1 = "/I566_";
671     //    TString str2 = "/ITS6_1";
672     TString volpath, volpath1;
673
674     for(Int_t c1 = 1; c1<=38; c1++){
675       volpath = str0;
676       volpath += c1;
677       volpath += str1;
678       for(Int_t c2 = 1; c2<=25; c2++){
679         volpath1 = volpath;
680         volpath1 += c2;
681         //      volpath1 += str2;
682         fgVolPath[kSSD2-kFirstLayer][modnum] = volpath1.Data();
683         modnum++;
684       }
685     }
686   }
687
688   /***************    TPC inner chambers' layer    ****************/
689   {
690     Int_t modnum = 0;
691     TString str1 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_1/TPC_SECT_";
692     TString str2 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_2/TPC_SECT_";
693     TString str_in = "/TPC_IROC_1";
694     TString volpath;
695     
696     for(Int_t cnt=1; cnt<=18; cnt++){
697       volpath = str1;
698       volpath += cnt;
699       volpath += str_in;
700       fgVolPath[kTPC1-kFirstLayer][modnum] = volpath.Data();
701       modnum++;
702     }
703     for(Int_t cnt=1; cnt<=18; cnt++){
704       volpath = str2;
705       volpath += cnt;
706       volpath += str_in;
707       fgVolPath[kTPC1-kFirstLayer][modnum] = volpath.Data();
708       modnum++;
709     }
710   }
711
712   /***************    TPC outer chambers' layer    ****************/
713   {
714     Int_t modnum = 0;
715     TString str1 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_1/TPC_SECT_";
716     TString str2 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_2/TPC_SECT_";
717     TString str_out = "/TPC_OROC_1";
718     TString volpath;
719     
720     for(Int_t cnt=1; cnt<=18; cnt++){
721       volpath = str1;
722       volpath += cnt;
723       volpath += str_out;
724       fgVolPath[kTPC2-kFirstLayer][modnum] = volpath.Data();
725       modnum++;
726     }
727     for(Int_t cnt=1; cnt<=18; cnt++){
728       volpath = str2;
729       volpath += cnt;
730       volpath += str_out;
731       fgVolPath[kTPC2-kFirstLayer][modnum] = volpath.Data();
732       modnum++;
733     }
734   }    
735
736   /*********************       TOF layer   ***********************/
737   {
738     Int_t nstrA=15;
739     Int_t nstrB=19;
740     Int_t nstrC=20;
741     Int_t nStripSec=nstrA+2*nstrB+2*nstrC;
742
743     for (Int_t modnum=0; modnum < 1674; modnum++) {
744
745       Int_t sector = modnum/nStripSec;
746       Char_t  string1[100];
747       Char_t  string2[100];
748
749       Int_t icopy=-1;
750
751       if(sector<3){
752         icopy=sector+1;
753         sprintf(string1,"/ALIC_1/B077_1/B075_%i/BTO3_1",icopy);
754       }
755       else if(sector<11){
756         icopy=sector-2;
757         sprintf(string1,"/ALIC_1/B077_1/B071_%i/BTO1_1",icopy);
758       }
759       else if(sector==11 || sector==12){
760         icopy=sector-10;
761         sprintf(string1,"/ALIC_1/B077_1/B074_%i/BTO2_1",icopy);
762       }
763       else {
764         icopy=sector-4;
765         sprintf(string1,"/ALIC_1/B077_1/B071_%i/BTO1_1",icopy);
766       }
767
768       Int_t strInSec=modnum%nStripSec;
769
770       if( strInSec < nstrC){
771         icopy= nstrC - (strInSec+1) + 1;
772         sprintf(string2,"FTOC_1/FLTC_0/FSTR_%i",icopy);
773       }
774       else if(strInSec< nstrC+nstrB){
775  
776         icopy= nstrB - (strInSec-nstrC+1) + 1;
777         sprintf(string2,"FTOB_1/FLTB_0/FSTR_%i",icopy);
778
779       }
780       else if(strInSec< nstrC+nstrB+nstrA){   
781
782         icopy= strInSec-(nstrC+nstrB)+1;
783         sprintf(string2,"FTOA_0/FLTA_0/FSTR_%i",icopy); 
784       }
785       else if(strInSec< nstrC+2*nstrB+nstrA){ 
786
787         icopy= strInSec-(nstrC+nstrB+nstrA)+1;
788         sprintf(string2,"FTOB_2/FLTB_0/FSTR_%i",icopy);
789
790       }
791       else  { 
792
793         icopy= strInSec-(nstrC+2*nstrB+nstrA)+1;
794         sprintf(string2,"FTOC_2/FLTC_0/FSTR_%i",icopy);
795
796       }
797   
798       Char_t  path[100];
799       sprintf(path,"%s/%s",string1,string2); 
800       //      printf("%d  %s\n",modnum,path);
801       fgVolPath[kTOF-kFirstLayer][modnum] = path;
802     }
803   } 
804
805   /*********************      RICH layer   ***********************/
806   {
807     TString str = "ALIC_1/RICH_";
808     TString volpath;
809
810     for (Int_t modnum=0; modnum < 7; modnum++) {
811       volpath = str;
812       volpath += (modnum+1);
813       fgVolPath[kRICH-kFirstLayer][modnum] = volpath.Data();
814     }
815   }
816
817   /*********************      TRD layers 0-6   *******************/
818   {
819   TString strSM[18]={"ALIC_1/B077_1/B075_1/BTR3_1/UTR3_3/UTS3_3/UTI3_3/UT",
820                      "ALIC_1/B077_1/B075_2/BTR3_1/UTR3_3/UTS3_3/UTI3_3/UT",
821                      "ALIC_1/B077_1/B075_3/BTR3_1/UTR3_3/UTS3_3/UTI3_3/UT",
822                      "ALIC_1/B077_1/B071_6/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
823                      "ALIC_1/B077_1/B071_7/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
824                      "ALIC_1/B077_1/B071_8/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
825                      "ALIC_1/B077_1/B071_9/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
826                      "ALIC_1/B077_1/B071_10/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
827                      "ALIC_1/B077_1/B071_11/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
828                      "ALIC_1/B077_1/B071_12/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
829                      "ALIC_1/B077_1/B071_13/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
830                      "ALIC_1/B077_1/B074_1/BTR2_1/UTR2_2/UTS2_2/UTI2_2/UT",
831                      "ALIC_1/B077_1/B074_2/BTR2_1/UTR2_2/UTS2_2/UTI2_2/UT",
832                      "ALIC_1/B077_1/B071_1/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
833                      "ALIC_1/B077_1/B071_2/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
834                      "ALIC_1/B077_1/B071_3/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
835                      "ALIC_1/B077_1/B071_4/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT",
836                      "ALIC_1/B077_1/B071_5/BTR1_1/UTR1_1/UTS1_1/UTI1_1/UT"};
837     Int_t start[18] = {60,60,60,0,0,0,0,0,0,0,0,30,30,0,0,0,0,0};
838     TString strPost = "_1";
839     TString ZeroStr = "0";
840
841     Int_t layer, sm, stacknum, chnum, modnum;
842     TString volpath;
843     Int_t TRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
844
845     for(layer=0; layer<6; layer++){
846       modnum=0;
847       for(sm = 0; sm<18; sm++){
848         for(stacknum = 0; stacknum<5; stacknum++){
849           chnum = start[sm] + layer + stacknum*6;
850           volpath = strSM[sm];
851           if(chnum<10) volpath += ZeroStr;
852           volpath += chnum;
853           volpath += strPost;
854           fgVolPath[TRDlayId[layer]-kFirstLayer][modnum] = volpath.Data();
855           modnum++;
856         }
857       }
858     }
859   }
860
861 }