1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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 #include <TGeoManager.h>
23 #include <TGeoPhysicalNode.h>
25 #include "AliAlignObj.h"
26 #include "AliTrackPointArray.h"
28 #include "AliAlignObjAngles.h"
32 Int_t AliAlignObj::fgLayerSize[kLastLayer - kFirstLayer] = {
33 80, 160, // ITS SPD first and second layer
34 84, 176, // ITS SDD first and second layer
35 748, 950, // ITS SSD first and second layer
36 36, 36, // TPC inner and outer chambers
37 90, 90, 90, 90, 90, 90, // 6 TRD chambers' layers
44 const char* AliAlignObj::fgLayerName[kLastLayer - kFirstLayer] = {
45 "ITS inner pixels layer", "ITS outer pixels layer",
46 "ITS inner drifts layer", "ITS outer drifts layer",
47 "ITS inner strips layer", "ITS outer strips layer",
48 "TPC inner chambers layer", "TPC outer chambers layer",
49 "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3",
50 "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
57 TString* AliAlignObj::fgVolPath[kLastLayer - kFirstLayer] = {
70 AliAlignObj** AliAlignObj::fgAlignObjs[kLastLayer - kFirstLayer] = {
83 //_____________________________________________________________________________
84 AliAlignObj::AliAlignObj():
88 // default constructor
92 //_____________________________________________________________________________
93 AliAlignObj::AliAlignObj(const char* symname, UShort_t voluid) :
98 // standard constructor
102 //_____________________________________________________________________________
103 AliAlignObj::AliAlignObj(const AliAlignObj& theAlignObj) :
104 TObject(theAlignObj),
105 fVolPath(theAlignObj.GetSymName()),
106 fVolUID(theAlignObj.GetVolUID())
111 //_____________________________________________________________________________
112 AliAlignObj &AliAlignObj::operator =(const AliAlignObj& theAlignObj)
114 // assignment operator
115 if(this==&theAlignObj) return *this;
116 fVolPath = theAlignObj.GetSymName();
117 fVolUID = theAlignObj.GetVolUID();
121 //_____________________________________________________________________________
122 AliAlignObj &AliAlignObj::operator*=(const AliAlignObj& theAlignObj)
124 // multiplication operator
125 // The operator can be used to 'combine'
126 // two alignment objects
130 theAlignObj.GetMatrix(m2);
131 m1.MultiplyLeft(&m2);
136 //_____________________________________________________________________________
137 AliAlignObj::~AliAlignObj()
142 //_____________________________________________________________________________
143 void AliAlignObj::SetVolUID(ELayerID detId, Int_t modId)
145 // From detector name and module number (according to detector numbering)
146 // build fVolUID, unique numerical identity of that volume inside ALICE
147 // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
148 // remaining 11 for module ID inside det (2048 possible values).
150 fVolUID = LayerToVolUID(detId,modId);
153 //_____________________________________________________________________________
154 void AliAlignObj::GetVolUID(ELayerID &layerId, Int_t &modId) const
156 // From detector name and module number (according to detector numbering)
157 // build fVolUID, unique numerical identity of that volume inside ALICE
158 // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
159 // remaining 11 for module ID inside det (2048 possible values).
161 layerId = VolUIDToLayer(fVolUID,modId);
164 //_____________________________________________________________________________
165 Bool_t AliAlignObj::GetPars(Double_t tr[], Double_t angles[]) const
168 return GetAngles(angles);
171 //_____________________________________________________________________________
172 Int_t AliAlignObj::GetLevel() const
174 // Return the geometry level of
175 // the alignable volume to which
176 // the alignment object is associated
177 TString symname = fVolPath;
178 if(symname[0]!='/') symname.Prepend('/');
179 return symname.CountChar('/');
182 //_____________________________________________________________________________
183 Int_t AliAlignObj::Compare(const TObject *obj) const
185 // Compare the levels of two
187 // Used in the sorting during
188 // the application of alignment
189 // objects to the geometry
190 Int_t level = GetLevel();
191 Int_t level2 = ((AliAlignObj *)obj)->GetLevel();
195 return ((level > level2) ? 1 : -1);
198 //_____________________________________________________________________________
199 void AliAlignObj::AnglesToMatrix(const Double_t *angles, Double_t *rot) const
201 // Calculates the rotation matrix using the
202 // Euler angles in "x y z" notation
203 Double_t degrad = TMath::DegToRad();
204 Double_t sinpsi = TMath::Sin(degrad*angles[0]);
205 Double_t cospsi = TMath::Cos(degrad*angles[0]);
206 Double_t sinthe = TMath::Sin(degrad*angles[1]);
207 Double_t costhe = TMath::Cos(degrad*angles[1]);
208 Double_t sinphi = TMath::Sin(degrad*angles[2]);
209 Double_t cosphi = TMath::Cos(degrad*angles[2]);
211 rot[0] = costhe*cosphi;
212 rot[1] = -costhe*sinphi;
214 rot[3] = sinpsi*sinthe*cosphi + cospsi*sinphi;
215 rot[4] = -sinpsi*sinthe*sinphi + cospsi*cosphi;
216 rot[5] = -costhe*sinpsi;
217 rot[6] = -cospsi*sinthe*cosphi + sinpsi*sinphi;
218 rot[7] = cospsi*sinthe*sinphi + sinpsi*cosphi;
219 rot[8] = costhe*cospsi;
222 //_____________________________________________________________________________
223 Bool_t AliAlignObj::MatrixToAngles(const Double_t *rot, Double_t *angles) const
225 // Calculates the Euler angles in "x y z" notation
226 // using the rotation matrix
227 // Returns false in case the rotation angles can not be
228 // extracted from the matrix
229 if(TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) {
230 AliError("Failed to extract roll-pitch-yall angles!");
233 Double_t raddeg = TMath::RadToDeg();
234 angles[0]=raddeg*TMath::ATan2(-rot[5],rot[8]);
235 angles[1]=raddeg*TMath::ASin(rot[2]);
236 angles[2]=raddeg*TMath::ATan2(-rot[1],rot[0]);
240 //______________________________________________________________________________
241 void AliAlignObj::Transform(AliTrackPoint &p) const
243 // The method transforms the space-point coordinates using the
244 // transformation matrix provided by the AliAlignObj
245 // The covariance matrix is not affected since we assume
246 // that the transformations are sufficiently small
248 if (fVolUID != p.GetVolumeID())
249 AliWarning(Form("Alignment object ID is not equal to the space-point ID (%d != %d)",fVolUID,p.GetVolumeID()));
253 Double_t *rot = m.GetRotationMatrix();
254 Double_t *tr = m.GetTranslation();
256 Float_t xyzin[3],xyzout[3];
258 for (Int_t i = 0; i < 3; i++)
267 //_____________________________________________________________________________
268 void AliAlignObj::Transform(AliTrackPointArray &array) const
270 // This method is used to transform all the track points
271 // from the input AliTrackPointArray
273 for (Int_t i = 0; i < array.GetNPoints(); i++) {
276 array.AddPoint(i,&p);
280 //_____________________________________________________________________________
281 void AliAlignObj::Print(Option_t *) const
283 // Print the contents of the
284 // alignment object in angles and
285 // matrix representations
292 const Double_t *rot = m.GetRotationMatrix();
294 printf("Volume=%s\n",GetSymName());
295 if (GetVolUID() != 0) {
298 GetVolUID(layerId,modId);
299 printf("VolumeID=%d LayerID=%d ( %s ) ModuleID=%d\n", GetVolUID(),layerId,LayerName(layerId),modId);
301 printf("%12.8f%12.8f%12.8f Tx = %12.8f Psi = %12.8f\n", rot[0], rot[1], rot[2], tr[0], angles[0]);
302 printf("%12.8f%12.8f%12.8f Ty = %12.8f Theta = %12.8f\n", rot[3], rot[4], rot[5], tr[1], angles[1]);
303 printf("%12.8f%12.8f%12.8f Tz = %12.8f Phi = %12.8f\n", rot[6], rot[7], rot[8], tr[2], angles[2]);
307 //_____________________________________________________________________________
308 Int_t AliAlignObj::LayerSize(Int_t layerId)
310 // Get the corresponding layer size.
311 // Implemented only for ITS,TPC,TRD,TOF and RICH
312 if (layerId < kFirstLayer || layerId >= kLastLayer) {
313 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
317 return fgLayerSize[layerId - kFirstLayer];
321 //_____________________________________________________________________________
322 const char* AliAlignObj::LayerName(Int_t layerId)
324 // Get the corresponding layer name.
325 // Implemented only for ITS,TPC,TRD,TOF and RICH
326 if (layerId < kFirstLayer || layerId >= kLastLayer) {
327 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
328 return "Invalid Layer!";
331 return fgLayerName[layerId - kFirstLayer];
335 //_____________________________________________________________________________
336 UShort_t AliAlignObj::LayerToVolUID(ELayerID layerId, Int_t modId)
338 // From detector (layer) name and module number (according to detector numbering)
339 // build fVolUID, unique numerical identity of that volume inside ALICE
340 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
341 // remaining 11 for module ID inside det (2048 possible values).
343 return ((UShort_t(layerId) << 11) | UShort_t(modId));
346 //_____________________________________________________________________________
347 UShort_t AliAlignObj::LayerToVolUID(Int_t layerId, Int_t modId)
349 // From detector (layer) index and module number (according to detector numbering)
350 // build fVolUID, unique numerical identity of that volume inside ALICE
351 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
352 // remaining 11 for module ID inside det (2048 possible values).
354 return ((UShort_t(layerId) << 11) | UShort_t(modId));
357 //_____________________________________________________________________________
358 AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid, Int_t &modId)
360 // From detector (layer) name and module number (according to detector numbering)
361 // build fVolUID, unique numerical identity of that volume inside ALICE
362 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
363 // remaining 11 for module ID inside det (2048 possible values).
365 modId = voluid & 0x7ff;
367 return VolUIDToLayer(voluid);
370 //_____________________________________________________________________________
371 AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid)
373 // From detector (layer) name and module number (according to detector numbering)
374 // build fVolUID, unique numerical identity of that volume inside ALICE
375 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
376 // remaining 11 for module ID inside det (2048 possible values).
378 return ELayerID((voluid >> 11) & 0x1f);
381 //_____________________________________________________________________________
382 void AliAlignObj::SetPars(Double_t x, Double_t y, Double_t z,
383 Double_t psi, Double_t theta, Double_t phi)
385 // Set rotation matrix and translation
386 // using 3 angles and 3 translations
387 SetTranslation(x,y,z);
388 SetRotation(psi,theta,phi);
391 //_____________________________________________________________________________
392 Bool_t AliAlignObj::SetLocalPars(Double_t x, Double_t y, Double_t z,
393 Double_t psi, Double_t theta, Double_t phi)
395 // Set the translations and angles by using parameters
396 // defined in the local (in TGeo means) coordinate system
397 // of the alignable volume. In case that the TGeo was
398 // initialized, returns false and the object parameters are
401 Double_t tr[3] = {x, y, z};
402 m.SetTranslation(tr);
403 Double_t angles[3] = {psi, theta, phi};
405 AnglesToMatrix(angles,rot);
408 return SetLocalMatrix(m);
412 //_____________________________________________________________________________
413 Bool_t AliAlignObj::SetLocalMatrix(const TGeoMatrix& m)
415 // Set the translations and angles by using TGeo matrix
416 // defined in the local (in TGeo means) coordinate system
417 // of the alignable volume. In case that the TGeo was
418 // initialized, returns false and the object parameters are
421 if (!gGeoManager || !gGeoManager->IsClosed()) {
422 AliError("Can't set the alignment object parameters! gGeoManager doesn't exist or it is still opened!");
426 const char* symname = GetSymName();
427 TGeoPhysicalNode* node;
428 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
430 node = gGeoManager->MakeAlignablePN(pne);
432 AliWarning(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as volume path!",symname));
433 node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(symname);
437 AliError(Form("Volume name or path %s not valid!",symname));
440 if (node->IsAligned())
441 AliWarning(Form("Volume %s has been already misaligned!",symname));
444 const Double_t *tr = m.GetTranslation();
445 m1.SetTranslation(tr);
446 const Double_t* rot = m.GetRotationMatrix();
449 TGeoHMatrix align,gprime,gprimeinv;
450 gprime = *node->GetMatrix();
451 gprimeinv = gprime.Inverse();
452 m1.Multiply(&gprimeinv);
453 m1.MultiplyLeft(&gprime);
455 return SetMatrix(m1);
458 //_____________________________________________________________________________
459 Bool_t AliAlignObj::SetMatrix(const TGeoMatrix& m)
461 // Set rotation matrix and translation
464 return SetRotation(m);
467 //_____________________________________________________________________________
468 Bool_t AliAlignObj::ApplyToGeometry()
470 // Apply the current alignment object
471 // to the TGeo geometry
473 if (!gGeoManager || !gGeoManager->IsClosed()) {
474 AliError("Can't apply the alignment object! gGeoManager doesn't exist or it is still opened!");
478 const char* symname = GetSymName();
480 TGeoPhysicalNode* node;
481 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
483 node = gGeoManager->MakeAlignablePN(pne);
484 if(!node) return kFALSE;
485 path = pne->GetTitle();
487 AliWarning(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
489 if (gGeoManager->GetListOfPhysicalNodes()->FindObject(path)) {
490 AliError(Form("Volume %s has already been misaligned!",path));
493 if (!gGeoManager->cd(path)) {
494 AliError(Form("Volume path %s not valid!",path));
497 node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(path);
501 AliError(Form("Volume path %s not valid!",path));
505 TGeoHMatrix align,gprime;
506 gprime = *node->GetMatrix();
508 gprime.MultiplyLeft(&align);
509 TGeoHMatrix *ginv = new TGeoHMatrix;
510 TGeoHMatrix *g = node->GetMatrix(node->GetLevel()-1);
511 *ginv = g->Inverse();
513 AliAlignObj::ELayerID layerId; // unique identity for layer in the alobj
514 Int_t modId; // unique identity for volume inside layer in the alobj
515 GetVolUID(layerId, modId);
516 AliDebug(2,Form("Aligning volume %s of detector layer %d with local ID %d",symname,layerId,modId));
522 //_____________________________________________________________________________
523 Bool_t AliAlignObj::GetFromGeometry(const char *symname, AliAlignObj &alobj)
525 // Get the alignment object which corresponds to the symbolic volume name
526 // symname (in case equal to the TGeo volume path)
527 // The method is extremely slow due to the searching by string.
528 // Therefore it should be used with great care!!
531 // Reset the alignment object
532 alobj.SetPars(0,0,0,0,0,0);
533 alobj.SetSymName(symname);
535 if (!gGeoManager || !gGeoManager->IsClosed()) {
536 AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
540 if (!gGeoManager->GetListOfPhysicalNodes()) {
541 AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
546 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
548 path = pne->GetTitle();
550 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
553 TObjArray* nodesArr = gGeoManager->GetListOfPhysicalNodes();
554 TGeoPhysicalNode* node = NULL;
555 for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
556 TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
557 const char *nodePath = tempNode->GetName();
558 if (strcmp(symname,nodePath) == 0) {
565 if (!gGeoManager->cd(symname)) {
566 AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",symname));
570 AliWarningClass(Form("Volume (%s) has not been misaligned!",symname));
575 TGeoHMatrix align,gprime,g,ginv,l;
576 gprime = *node->GetMatrix();
577 l = *node->GetOriginalMatrix();
578 g = *node->GetMatrix(node->GetLevel()-1);
581 align = gprime * ginv;
583 return alobj.SetMatrix(align);
586 //_____________________________________________________________________________
587 void AliAlignObj::InitAlignObjFromGeometry()
589 // Loop over all alignable volumes and extract
590 // the corresponding alignment objects from
593 if(fgAlignObjs[0]) return;
597 for (Int_t iLayer = kFirstLayer; iLayer < AliAlignObj::kLastLayer; iLayer++) {
598 fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer)];
599 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
600 UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,iModule);
601 fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0,kTRUE);
602 const char *symname = SymName(volid);
603 if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
604 AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname));
610 //_____________________________________________________________________________
611 AliAlignObj* AliAlignObj::GetAlignObj(UShort_t voluid) {
612 // Returns the alignment object for given volume ID
614 ELayerID layerId = VolUIDToLayer(voluid,modId);
615 return GetAlignObj(layerId,modId);
618 //_____________________________________________________________________________
619 AliAlignObj* AliAlignObj::GetAlignObj(ELayerID layerId, Int_t modId)
621 // Returns pointer to alignment object givent its layer and module ID
622 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
623 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
626 InitAlignObjFromGeometry();
628 return fgAlignObjs[layerId-kFirstLayer][modId];
631 //_____________________________________________________________________________
632 const char* AliAlignObj::SymName(UShort_t voluid) {
633 // Returns the volume path for given volume ID
635 ELayerID layerId = VolUIDToLayer(voluid,modId);
636 return SymName(layerId,modId);
639 //_____________________________________________________________________________
640 const char* AliAlignObj::SymName(ELayerID layerId, Int_t modId)
642 // Returns volume path to alignment object givent its layer and module ID
643 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
644 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
649 return fgVolPath[layerId-kFirstLayer][modId].Data();
652 //_____________________________________________________________________________
653 void AliAlignObj::InitSymNames()
655 // Initialize the LUTs which contain
656 // the TGeo volume paths for each
657 // alignable volume. The LUTs are
658 // static, so they are created during
659 // the creation of the first intance
662 if (fgVolPath[0]) return;
664 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++)
665 fgVolPath[iLayer] = new TString[fgLayerSize[iLayer]];
667 /********************* SPD layer1 ***********************/
670 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_"; //".../I12A_"
671 TString str1 = "/I10B_"; //"/I10A_";
672 TString str2 = "/I107_"; //"/I103_"
673 // TString str3 = "/I101_1/ITS1_1";
674 TString symname, symname1, symname2;
676 for(Int_t c1 = 1; c1<=10; c1++){
680 for(Int_t c2 =1; c2<=2; c2++){
684 for(Int_t c3 =1; c3<=4; c3++){
688 fgVolPath[kSPD1-kFirstLayer][modnum] = symname2.Data();
695 /********************* SPD layer2 ***********************/
698 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_"; //".../I12A_"
699 TString str1 = "/I20B_"; //"/I20A"
700 TString str2 = "/I1D7_"; //"/I1D3"
701 // TString str3 = "/I1D1_1/ITS2_1";
702 TString symname, symname1, symname2;
704 for(Int_t c1 = 1; c1<=10; c1++){
708 for(Int_t c2 =1; c2<=4; c2++){
712 for(Int_t c3 =1; c3<=4; c3++){
716 fgVolPath[kSPD2-kFirstLayer][modnum] = symname2.Data();
723 /********************* SDD layer1 ***********************/
726 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I004_";
727 TString str1 = "/I302_";
728 // TString str2 = "/ITS3_1";
729 TString symname, symname1;
731 for(Int_t c1 = 1; c1<=14; c1++){
735 for(Int_t c2 =1; c2<=6; c2++){
739 fgVolPath[kSDD1-kFirstLayer][modnum] = symname1.Data();
745 /********************* SDD layer2 ***********************/
748 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I005_";
749 TString str1 = "/I402_";
750 // TString str2 = "/ITS4_1";
751 TString symname, symname1;
753 for(Int_t c1 = 1; c1<=22; c1++){
757 for(Int_t c2 = 1; c2<=8; c2++){
761 fgVolPath[kSDD2-kFirstLayer][modnum] = symname1.Data();
767 /********************* SSD layer1 ***********************/
770 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I565_";
771 TString str1 = "/I562_";
772 // TString str2 = "/ITS5_1";
773 TString symname, symname1;
775 for(Int_t c1 = 1; c1<=34; c1++){
779 for(Int_t c2 = 1; c2<=22; c2++){
783 fgVolPath[kSSD1-kFirstLayer][modnum] = symname1.Data();
789 /********************* SSD layer1 ***********************/
792 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I569_";
793 TString str1 = "/I566_";
794 // TString str2 = "/ITS6_1";
795 TString symname, symname1;
797 for(Int_t c1 = 1; c1<=38; c1++){
801 for(Int_t c2 = 1; c2<=25; c2++){
805 fgVolPath[kSSD2-kFirstLayer][modnum] = symname1.Data();
811 /*************** TPC inner chambers' layer ****************/
814 TString str1 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_1/TPC_SECT_";
815 TString str2 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_2/TPC_SECT_";
816 TString strIn = "/TPC_IROC_1";
819 for(Int_t cnt=1; cnt<=18; cnt++){
823 fgVolPath[kTPC1-kFirstLayer][modnum] = symname.Data();
826 for(Int_t cnt=1; cnt<=18; cnt++){
830 fgVolPath[kTPC1-kFirstLayer][modnum] = symname.Data();
835 /*************** TPC outer chambers' layer ****************/
838 TString str1 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_1/TPC_SECT_";
839 TString str2 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_2/TPC_SECT_";
840 TString strOut = "/TPC_OROC_1";
843 for(Int_t cnt=1; cnt<=18; cnt++){
847 fgVolPath[kTPC2-kFirstLayer][modnum] = symname.Data();
850 for(Int_t cnt=1; cnt<=18; cnt++){
854 fgVolPath[kTPC2-kFirstLayer][modnum] = symname.Data();
859 /********************* TOF layer ***********************/
865 Int_t nStripSec=nstrA+2*nstrB+2*nstrC;
866 Int_t nStrip=nStripSec*nsec;
868 for (Int_t modnum=0; modnum < nStrip; modnum++) {
870 Int_t sector = modnum/nStripSec;
879 // else{ icopy=sector-13;}
881 sprintf(string1,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1/FTOA_0/FLTA_0",sector,sector);
883 Int_t strInSec=modnum%nStripSec;
886 sprintf(string2,"FSTR_%i",icopy);
888 sprintf(path,"%s/%s",string1,string2);
889 // printf("%d %s\n",modnum,path);
890 fgVolPath[kTOF-kFirstLayer][modnum] = path;
894 /********************* RICH layer ***********************/
896 TString str = "ALIC_1/RICH_";
899 for (Int_t modnum=0; modnum < 7; modnum++) {
901 symname += (modnum+1);
902 fgVolPath[kRICH-kFirstLayer][modnum] = symname.Data();
906 /********************* TRD layers 0-6 *******************/
908 TString strSM[18]={"ALIC_1/B077_1/BSEGMO0_1/BTRD0_1/UTR1_1/UTS1_1/UTI1_1/UT",
909 "ALIC_1/B077_1/BSEGMO1_1/BTRD1_1/UTR1_1/UTS1_1/UTI1_1/UT",
910 "ALIC_1/B077_1/BSEGMO2_1/BTRD2_1/UTR1_1/UTS1_1/UTI1_1/UT",
911 "ALIC_1/B077_1/BSEGMO3_1/BTRD3_1/UTR1_1/UTS1_1/UTI1_1/UT",
912 "ALIC_1/B077_1/BSEGMO4_1/BTRD4_1/UTR1_1/UTS1_1/UTI1_1/UT",
913 "ALIC_1/B077_1/BSEGMO5_1/BTRD5_1/UTR1_1/UTS1_1/UTI1_1/UT",
914 "ALIC_1/B077_1/BSEGMO6_1/BTRD6_1/UTR1_1/UTS1_1/UTI1_1/UT",
915 "ALIC_1/B077_1/BSEGMO7_1/BTRD7_1/UTR1_1/UTS1_1/UTI1_1/UT",
916 "ALIC_1/B077_1/BSEGMO8_1/BTRD8_1/UTR1_1/UTS1_1/UTI1_1/UT",
917 "ALIC_1/B077_1/BSEGMO9_1/BTRD9_1/UTR1_1/UTS1_1/UTI1_1/UT",
918 "ALIC_1/B077_1/BSEGMO10_1/BTRD10_1/UTR1_1/UTS1_1/UTI1_1/UT",
919 "ALIC_1/B077_1/BSEGMO11_1/BTRD11_1/UTR1_1/UTS1_1/UTI1_1/UT",
920 "ALIC_1/B077_1/BSEGMO12_1/BTRD12_1/UTR1_1/UTS1_1/UTI1_1/UT",
921 "ALIC_1/B077_1/BSEGMO13_1/BTRD13_1/UTR1_1/UTS1_1/UTI1_1/UT",
922 "ALIC_1/B077_1/BSEGMO14_1/BTRD14_1/UTR1_1/UTS1_1/UTI1_1/UT",
923 "ALIC_1/B077_1/BSEGMO15_1/BTRD15_1/UTR1_1/UTS1_1/UTI1_1/UT",
924 "ALIC_1/B077_1/BSEGMO16_1/BTRD16_1/UTR1_1/UTS1_1/UTI1_1/UT",
925 "ALIC_1/B077_1/BSEGMO17_1/BTRD17_1/UTR1_1/UTS1_1/UTI1_1/UT"};
926 TString strPost = "_1";
927 TString zeroStr = "0";
930 Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
932 for(Int_t layer=0; layer<6; layer++){
934 for(Int_t sm = 0; sm < 18; sm++){
935 for(Int_t stacknum = 0; stacknum < 5; stacknum++){
936 Int_t chnum = layer + stacknum*6;
938 if(chnum<10) symname += zeroStr;
941 fgVolPath[arTRDlayId[layer]-kFirstLayer][modnum] = symname.Data();