]>
Commit | Line | Data |
---|---|---|
c18195b9 | 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 | //----------------------------------------------------------------- | |
befe2c08 | 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. | |
c18195b9 | 21 | //----------------------------------------------------------------- |
995ad051 | 22 | #include <TGeoManager.h> |
23 | #include <TGeoPhysicalNode.h> | |
24 | ||
c18195b9 | 25 | #include "AliAlignObj.h" |
03b18860 | 26 | #include "AliTrackPointArray.h" |
27 | #include "AliLog.h" | |
c5304981 | 28 | #include "AliAlignObjAngles.h" |
98937d93 | 29 | |
c18195b9 | 30 | ClassImp(AliAlignObj) |
31 | ||
98937d93 | 32 | Int_t AliAlignObj::fgLayerSize[kLastLayer - kFirstLayer] = { |
b760c02e | 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 | |
da027ef2 | 38 | 1638, // TOF |
98937d93 | 39 | 1, 1, // PHOS ?? |
03b18860 | 40 | 7, // RICH ?? |
98937d93 | 41 | 1 // MUON ?? |
42 | }; | |
43 | ||
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", | |
51 | "TOF layer", | |
52 | "?","?", | |
03b18860 | 53 | "RICH layer", |
98937d93 | 54 | "?" |
55 | }; | |
56 | ||
7604a026 | 57 | TString* AliAlignObj::fgVolPath[kLastLayer - kFirstLayer] = { |
03b18860 | 58 | 0x0,0x0, |
59 | 0x0,0x0, | |
60 | 0x0,0x0, | |
61 | 0x0,0x0, | |
62 | 0x0,0x0,0x0, | |
63 | 0x0,0x0,0x0, | |
64 | 0x0, | |
65 | 0x0,0x0, | |
66 | 0x0, | |
67 | 0x0 | |
68 | }; | |
69 | ||
c5304981 | 70 | AliAlignObj** AliAlignObj::fgAlignObjs[kLastLayer - kFirstLayer] = { |
71 | 0x0,0x0, | |
72 | 0x0,0x0, | |
73 | 0x0,0x0, | |
74 | 0x0,0x0, | |
75 | 0x0,0x0,0x0, | |
76 | 0x0,0x0,0x0, | |
77 | 0x0, | |
78 | 0x0,0x0, | |
79 | 0x0, | |
80 | 0x0 | |
81 | }; | |
82 | ||
c18195b9 | 83 | //_____________________________________________________________________________ |
84 | AliAlignObj::AliAlignObj(): | |
fe12e09c | 85 | fVolPath(), |
c18195b9 | 86 | fVolUID(0) |
87 | { | |
03b18860 | 88 | // default constructor |
b760c02e | 89 | InitSymNames(); |
c18195b9 | 90 | } |
91 | ||
92 | //_____________________________________________________________________________ | |
b760c02e | 93 | AliAlignObj::AliAlignObj(const char* symname, UShort_t voluid) : |
fe12e09c | 94 | TObject(), |
b760c02e | 95 | fVolPath(symname), |
fe12e09c | 96 | fVolUID(voluid) |
d9cc42ed | 97 | { |
98 | // standard constructor | |
99 | // | |
d9cc42ed | 100 | } |
101 | ||
d9cc42ed | 102 | //_____________________________________________________________________________ |
c18195b9 | 103 | AliAlignObj::AliAlignObj(const AliAlignObj& theAlignObj) : |
fe12e09c | 104 | TObject(theAlignObj), |
b760c02e | 105 | fVolPath(theAlignObj.GetSymName()), |
fe12e09c | 106 | fVolUID(theAlignObj.GetVolUID()) |
c18195b9 | 107 | { |
108 | //copy constructor | |
c18195b9 | 109 | } |
110 | ||
111 | //_____________________________________________________________________________ | |
112 | AliAlignObj &AliAlignObj::operator =(const AliAlignObj& theAlignObj) | |
113 | { | |
114 | // assignment operator | |
115 | if(this==&theAlignObj) return *this; | |
b760c02e | 116 | fVolPath = theAlignObj.GetSymName(); |
c18195b9 | 117 | fVolUID = theAlignObj.GetVolUID(); |
118 | return *this; | |
119 | } | |
120 | ||
38b3a170 | 121 | //_____________________________________________________________________________ |
122 | AliAlignObj &AliAlignObj::operator*=(const AliAlignObj& theAlignObj) | |
123 | { | |
124 | // multiplication operator | |
125 | // The operator can be used to 'combine' | |
126 | // two alignment objects | |
127 | TGeoHMatrix m1; | |
128 | GetMatrix(m1); | |
129 | TGeoHMatrix m2; | |
130 | theAlignObj.GetMatrix(m2); | |
131 | m1.MultiplyLeft(&m2); | |
132 | SetMatrix(m1); | |
133 | return *this; | |
134 | } | |
135 | ||
c18195b9 | 136 | //_____________________________________________________________________________ |
137 | AliAlignObj::~AliAlignObj() | |
138 | { | |
139 | // dummy destructor | |
140 | } | |
141 | ||
befe2c08 | 142 | //_____________________________________________________________________________ |
143 | void AliAlignObj::SetVolUID(ELayerID detId, Int_t modId) | |
144 | { | |
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). | |
149 | // | |
150 | fVolUID = LayerToVolUID(detId,modId); | |
151 | } | |
152 | ||
153 | //_____________________________________________________________________________ | |
154 | void AliAlignObj::GetVolUID(ELayerID &layerId, Int_t &modId) const | |
155 | { | |
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). | |
160 | // | |
161 | layerId = VolUIDToLayer(fVolUID,modId); | |
162 | } | |
163 | ||
b760c02e | 164 | //_____________________________________________________________________________ |
165 | Bool_t AliAlignObj::GetPars(Double_t tr[], Double_t angles[]) const | |
166 | { | |
167 | GetTranslation(tr); | |
168 | return GetAngles(angles); | |
169 | } | |
170 | ||
4b94e753 | 171 | //_____________________________________________________________________________ |
172 | Int_t AliAlignObj::GetLevel() const | |
173 | { | |
85fbf070 | 174 | // Return the geometry level of the alignable volume to which |
175 | // the alignment object is associated; this is the number of | |
176 | // slashes in the corresponding volume path | |
177 | // | |
178 | if(!gGeoManager){ | |
179 | AliWarning("gGeoManager doesn't exist or it is still opened: unable to return meaningful level value."); | |
180 | return (-1); | |
181 | } | |
182 | const char* symname = GetSymName(); | |
183 | const char* path; | |
184 | TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); | |
185 | if(pne){ | |
186 | path = pne->GetTitle(); | |
187 | }else{ | |
188 | path = symname; | |
189 | } | |
190 | ||
191 | TString path_str = path; | |
192 | if(path_str[0]!='/') path_str.Prepend('/'); | |
193 | return path_str.CountChar('/'); | |
4b94e753 | 194 | } |
195 | ||
196 | //_____________________________________________________________________________ | |
197 | Int_t AliAlignObj::Compare(const TObject *obj) const | |
198 | { | |
199 | // Compare the levels of two | |
200 | // alignment objects | |
201 | // Used in the sorting during | |
202 | // the application of alignment | |
203 | // objects to the geometry | |
204 | Int_t level = GetLevel(); | |
205 | Int_t level2 = ((AliAlignObj *)obj)->GetLevel(); | |
206 | if (level == level2) | |
207 | return 0; | |
208 | else | |
209 | return ((level > level2) ? 1 : -1); | |
210 | } | |
211 | ||
c18195b9 | 212 | //_____________________________________________________________________________ |
213 | void AliAlignObj::AnglesToMatrix(const Double_t *angles, Double_t *rot) const | |
214 | { | |
fdf65bb5 | 215 | // Calculates the rotation matrix using the |
216 | // Euler angles in "x y z" notation | |
c18195b9 | 217 | Double_t degrad = TMath::DegToRad(); |
218 | Double_t sinpsi = TMath::Sin(degrad*angles[0]); | |
219 | Double_t cospsi = TMath::Cos(degrad*angles[0]); | |
220 | Double_t sinthe = TMath::Sin(degrad*angles[1]); | |
221 | Double_t costhe = TMath::Cos(degrad*angles[1]); | |
222 | Double_t sinphi = TMath::Sin(degrad*angles[2]); | |
223 | Double_t cosphi = TMath::Cos(degrad*angles[2]); | |
224 | ||
225 | rot[0] = costhe*cosphi; | |
226 | rot[1] = -costhe*sinphi; | |
227 | rot[2] = sinthe; | |
228 | rot[3] = sinpsi*sinthe*cosphi + cospsi*sinphi; | |
229 | rot[4] = -sinpsi*sinthe*sinphi + cospsi*cosphi; | |
230 | rot[5] = -costhe*sinpsi; | |
231 | rot[6] = -cospsi*sinthe*cosphi + sinpsi*sinphi; | |
232 | rot[7] = cospsi*sinthe*sinphi + sinpsi*cosphi; | |
233 | rot[8] = costhe*cospsi; | |
234 | } | |
235 | ||
236 | //_____________________________________________________________________________ | |
237 | Bool_t AliAlignObj::MatrixToAngles(const Double_t *rot, Double_t *angles) const | |
238 | { | |
fdf65bb5 | 239 | // Calculates the Euler angles in "x y z" notation |
240 | // using the rotation matrix | |
b760c02e | 241 | // Returns false in case the rotation angles can not be |
242 | // extracted from the matrix | |
243 | if(TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) { | |
244 | AliError("Failed to extract roll-pitch-yall angles!"); | |
245 | return kFALSE; | |
246 | } | |
c18195b9 | 247 | Double_t raddeg = TMath::RadToDeg(); |
248 | angles[0]=raddeg*TMath::ATan2(-rot[5],rot[8]); | |
249 | angles[1]=raddeg*TMath::ASin(rot[2]); | |
250 | angles[2]=raddeg*TMath::ATan2(-rot[1],rot[0]); | |
251 | return kTRUE; | |
252 | } | |
253 | ||
03b18860 | 254 | //______________________________________________________________________________ |
255 | void AliAlignObj::Transform(AliTrackPoint &p) const | |
256 | { | |
257 | // The method transforms the space-point coordinates using the | |
258 | // transformation matrix provided by the AliAlignObj | |
259 | // The covariance matrix is not affected since we assume | |
260 | // that the transformations are sufficiently small | |
261 | ||
262 | if (fVolUID != p.GetVolumeID()) | |
263 | AliWarning(Form("Alignment object ID is not equal to the space-point ID (%d != %d)",fVolUID,p.GetVolumeID())); | |
264 | ||
265 | TGeoHMatrix m; | |
266 | GetMatrix(m); | |
267 | Double_t *rot = m.GetRotationMatrix(); | |
268 | Double_t *tr = m.GetTranslation(); | |
269 | ||
270 | Float_t xyzin[3],xyzout[3]; | |
271 | p.GetXYZ(xyzin); | |
272 | for (Int_t i = 0; i < 3; i++) | |
273 | xyzout[i] = tr[i]+ | |
274 | xyzin[0]*rot[3*i]+ | |
275 | xyzin[1]*rot[3*i+1]+ | |
276 | xyzin[2]*rot[3*i+2]; | |
277 | p.SetXYZ(xyzout); | |
278 | ||
279 | } | |
280 | ||
79e21da6 | 281 | //_____________________________________________________________________________ |
03b18860 | 282 | void AliAlignObj::Transform(AliTrackPointArray &array) const |
283 | { | |
e1e6896f | 284 | // This method is used to transform all the track points |
285 | // from the input AliTrackPointArray | |
03b18860 | 286 | AliTrackPoint p; |
287 | for (Int_t i = 0; i < array.GetNPoints(); i++) { | |
288 | array.GetPoint(p,i); | |
289 | Transform(p); | |
290 | array.AddPoint(i,&p); | |
291 | } | |
292 | } | |
293 | ||
c18195b9 | 294 | //_____________________________________________________________________________ |
295 | void AliAlignObj::Print(Option_t *) const | |
296 | { | |
297 | // Print the contents of the | |
298 | // alignment object in angles and | |
299 | // matrix representations | |
300 | Double_t tr[3]; | |
301 | GetTranslation(tr); | |
302 | Double_t angles[3]; | |
303 | GetAngles(angles); | |
304 | TGeoHMatrix m; | |
305 | GetMatrix(m); | |
306 | const Double_t *rot = m.GetRotationMatrix(); | |
c18195b9 | 307 | |
b760c02e | 308 | printf("Volume=%s\n",GetSymName()); |
c041444f | 309 | if (GetVolUID() != 0) { |
310 | ELayerID layerId; | |
311 | Int_t modId; | |
312 | GetVolUID(layerId,modId); | |
313 | printf("VolumeID=%d LayerID=%d ( %s ) ModuleID=%d\n", GetVolUID(),layerId,LayerName(layerId),modId); | |
314 | } | |
315 | printf("%12.8f%12.8f%12.8f Tx = %12.8f Psi = %12.8f\n", rot[0], rot[1], rot[2], tr[0], angles[0]); | |
316 | printf("%12.8f%12.8f%12.8f Ty = %12.8f Theta = %12.8f\n", rot[3], rot[4], rot[5], tr[1], angles[1]); | |
317 | printf("%12.8f%12.8f%12.8f Tz = %12.8f Phi = %12.8f\n", rot[6], rot[7], rot[8], tr[2], angles[2]); | |
318 | ||
319 | } | |
320 | ||
321 | //_____________________________________________________________________________ | |
322 | Int_t AliAlignObj::LayerSize(Int_t layerId) | |
323 | { | |
324 | // Get the corresponding layer size. | |
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 0; | |
329 | } | |
330 | else { | |
331 | return fgLayerSize[layerId - kFirstLayer]; | |
332 | } | |
333 | } | |
334 | ||
335 | //_____________________________________________________________________________ | |
336 | const char* AliAlignObj::LayerName(Int_t layerId) | |
337 | { | |
338 | // Get the corresponding layer name. | |
339 | // Implemented only for ITS,TPC,TRD,TOF and RICH | |
340 | if (layerId < kFirstLayer || layerId >= kLastLayer) { | |
341 | AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer)); | |
342 | return "Invalid Layer!"; | |
343 | } | |
344 | else { | |
345 | return fgLayerName[layerId - kFirstLayer]; | |
346 | } | |
c18195b9 | 347 | } |
348 | ||
c18195b9 | 349 | //_____________________________________________________________________________ |
befe2c08 | 350 | UShort_t AliAlignObj::LayerToVolUID(ELayerID layerId, Int_t modId) |
c18195b9 | 351 | { |
befe2c08 | 352 | // From detector (layer) name and module number (according to detector numbering) |
353 | // build fVolUID, unique numerical identity of that volume inside ALICE | |
354 | // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values), | |
355 | // remaining 11 for module ID inside det (2048 possible values). | |
c18195b9 | 356 | // |
befe2c08 | 357 | return ((UShort_t(layerId) << 11) | UShort_t(modId)); |
c18195b9 | 358 | } |
359 | ||
46ae650f | 360 | //_____________________________________________________________________________ |
361 | UShort_t AliAlignObj::LayerToVolUID(Int_t layerId, Int_t modId) | |
362 | { | |
363 | // From detector (layer) index and module number (according to detector numbering) | |
364 | // build fVolUID, unique numerical identity of that volume inside ALICE | |
365 | // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values), | |
366 | // remaining 11 for module ID inside det (2048 possible values). | |
367 | // | |
368 | return ((UShort_t(layerId) << 11) | UShort_t(modId)); | |
369 | } | |
370 | ||
c18195b9 | 371 | //_____________________________________________________________________________ |
befe2c08 | 372 | AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid, Int_t &modId) |
c18195b9 | 373 | { |
befe2c08 | 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 | modId = voluid & 0x7ff; | |
c18195b9 | 380 | |
befe2c08 | 381 | return VolUIDToLayer(voluid); |
c18195b9 | 382 | } |
383 | ||
384 | //_____________________________________________________________________________ | |
befe2c08 | 385 | AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid) |
c18195b9 | 386 | { |
befe2c08 | 387 | // From detector (layer) name and module number (according to detector numbering) |
388 | // build fVolUID, unique numerical identity of that volume inside ALICE | |
389 | // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values), | |
390 | // remaining 11 for module ID inside det (2048 possible values). | |
391 | // | |
392 | return ELayerID((voluid >> 11) & 0x1f); | |
c18195b9 | 393 | } |
03b18860 | 394 | |
b760c02e | 395 | //_____________________________________________________________________________ |
396 | void AliAlignObj::SetPars(Double_t x, Double_t y, Double_t z, | |
397 | Double_t psi, Double_t theta, Double_t phi) | |
398 | { | |
399 | // Set rotation matrix and translation | |
400 | // using 3 angles and 3 translations | |
401 | SetTranslation(x,y,z); | |
402 | SetRotation(psi,theta,phi); | |
403 | } | |
404 | ||
1bfe7ffc | 405 | //_____________________________________________________________________________ |
406 | Bool_t AliAlignObj::SetLocalPars(Double_t x, Double_t y, Double_t z, | |
407 | Double_t psi, Double_t theta, Double_t phi) | |
408 | { | |
409 | // Set the translations and angles by using parameters | |
410 | // defined in the local (in TGeo means) coordinate system | |
411 | // of the alignable volume. In case that the TGeo was | |
412 | // initialized, returns false and the object parameters are | |
413 | // not set. | |
b760c02e | 414 | TGeoHMatrix m; |
415 | Double_t tr[3] = {x, y, z}; | |
416 | m.SetTranslation(tr); | |
417 | Double_t angles[3] = {psi, theta, phi}; | |
418 | Double_t rot[9]; | |
419 | AnglesToMatrix(angles,rot); | |
420 | m.SetRotation(rot); | |
421 | ||
422 | return SetLocalMatrix(m); | |
423 | ||
424 | } | |
425 | ||
426 | //_____________________________________________________________________________ | |
427 | Bool_t AliAlignObj::SetLocalMatrix(const TGeoMatrix& m) | |
428 | { | |
429 | // Set the translations and angles by using TGeo matrix | |
430 | // defined in the local (in TGeo means) coordinate system | |
431 | // of the alignable volume. In case that the TGeo was | |
432 | // initialized, returns false and the object parameters are | |
433 | // not set. | |
434 | ||
1bfe7ffc | 435 | if (!gGeoManager || !gGeoManager->IsClosed()) { |
436 | AliError("Can't set the alignment object parameters! gGeoManager doesn't exist or it is still opened!"); | |
437 | return kFALSE; | |
438 | } | |
439 | ||
b760c02e | 440 | const char* symname = GetSymName(); |
441 | TGeoPhysicalNode* node; | |
442 | TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); | |
443 | if(pne){ | |
444 | node = gGeoManager->MakeAlignablePN(pne); | |
445 | }else{ | |
446 | AliWarning(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as volume path!",symname)); | |
447 | node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(symname); | |
448 | } | |
449 | ||
1bfe7ffc | 450 | if (!node) { |
b760c02e | 451 | AliError(Form("Volume name or path %s not valid!",symname)); |
1bfe7ffc | 452 | return kFALSE; |
453 | } | |
454 | if (node->IsAligned()) | |
b760c02e | 455 | AliWarning(Form("Volume %s has been already misaligned!",symname)); |
1bfe7ffc | 456 | |
b760c02e | 457 | TGeoHMatrix m1; |
458 | const Double_t *tr = m.GetTranslation(); | |
459 | m1.SetTranslation(tr); | |
460 | const Double_t* rot = m.GetRotationMatrix(); | |
461 | m1.SetRotation(rot); | |
1bfe7ffc | 462 | |
463 | TGeoHMatrix align,gprime,gprimeinv; | |
464 | gprime = *node->GetMatrix(); | |
465 | gprimeinv = gprime.Inverse(); | |
b760c02e | 466 | m1.Multiply(&gprimeinv); |
467 | m1.MultiplyLeft(&gprime); | |
1bfe7ffc | 468 | |
b760c02e | 469 | return SetMatrix(m1); |
470 | } | |
1bfe7ffc | 471 | |
b760c02e | 472 | //_____________________________________________________________________________ |
473 | Bool_t AliAlignObj::SetMatrix(const TGeoMatrix& m) | |
474 | { | |
475 | // Set rotation matrix and translation | |
476 | // using TGeoMatrix | |
477 | SetTranslation(m); | |
478 | return SetRotation(m); | |
1bfe7ffc | 479 | } |
480 | ||
995ad051 | 481 | //_____________________________________________________________________________ |
482 | Bool_t AliAlignObj::ApplyToGeometry() | |
483 | { | |
484 | // Apply the current alignment object | |
485 | // to the TGeo geometry | |
486 | ||
487 | if (!gGeoManager || !gGeoManager->IsClosed()) { | |
488 | AliError("Can't apply the alignment object! gGeoManager doesn't exist or it is still opened!"); | |
489 | return kFALSE; | |
490 | } | |
491 | ||
b760c02e | 492 | const char* symname = GetSymName(); |
493 | const char* path; | |
494 | TGeoPhysicalNode* node; | |
495 | TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); | |
496 | if(pne){ | |
497 | node = gGeoManager->MakeAlignablePN(pne); | |
498 | if(!node) return kFALSE; | |
499 | path = pne->GetTitle(); | |
500 | }else{ | |
501 | AliWarning(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname)); | |
502 | path=symname; | |
503 | if (gGeoManager->GetListOfPhysicalNodes()->FindObject(path)) { | |
504 | AliError(Form("Volume %s has already been misaligned!",path)); | |
505 | return kFALSE; | |
506 | } | |
507 | if (!gGeoManager->cd(path)) { | |
508 | AliError(Form("Volume path %s not valid!",path)); | |
509 | return kFALSE; | |
510 | } | |
511 | node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(path); | |
995ad051 | 512 | } |
48cac49d | 513 | |
48cac49d | 514 | if (!node) { |
b760c02e | 515 | AliError(Form("Volume path %s not valid!",path)); |
995ad051 | 516 | return kFALSE; |
517 | } | |
518 | ||
519 | TGeoHMatrix align,gprime; | |
520 | gprime = *node->GetMatrix(); | |
521 | GetMatrix(align); | |
522 | gprime.MultiplyLeft(&align); | |
523 | TGeoHMatrix *ginv = new TGeoHMatrix; | |
524 | TGeoHMatrix *g = node->GetMatrix(node->GetLevel()-1); | |
525 | *ginv = g->Inverse(); | |
526 | *ginv *= gprime; | |
b760c02e | 527 | AliAlignObj::ELayerID layerId; // unique identity for layer in the alobj |
528 | Int_t modId; // unique identity for volume inside layer in the alobj | |
995ad051 | 529 | GetVolUID(layerId, modId); |
b760c02e | 530 | AliDebug(2,Form("Aligning volume %s of detector layer %d with local ID %d",symname,layerId,modId)); |
995ad051 | 531 | node->Align(ginv); |
532 | ||
533 | return kTRUE; | |
534 | } | |
535 | ||
536 | //_____________________________________________________________________________ | |
b760c02e | 537 | Bool_t AliAlignObj::GetFromGeometry(const char *symname, AliAlignObj &alobj) |
995ad051 | 538 | { |
b760c02e | 539 | // Get the alignment object which corresponds to the symbolic volume name |
540 | // symname (in case equal to the TGeo volume path) | |
541 | // The method is extremely slow due to the searching by string. | |
542 | // Therefore it should be used with great care!! | |
543 | // | |
995ad051 | 544 | |
545 | // Reset the alignment object | |
546 | alobj.SetPars(0,0,0,0,0,0); | |
b760c02e | 547 | alobj.SetSymName(symname); |
995ad051 | 548 | |
549 | if (!gGeoManager || !gGeoManager->IsClosed()) { | |
550 | AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!"); | |
551 | return kFALSE; | |
552 | } | |
553 | ||
554 | if (!gGeoManager->GetListOfPhysicalNodes()) { | |
555 | AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!"); | |
556 | return kFALSE; | |
557 | } | |
558 | ||
b760c02e | 559 | const char *path; |
560 | TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname); | |
561 | if(pne){ | |
562 | path = pne->GetTitle(); | |
563 | }else{ | |
564 | AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname)); | |
565 | path = symname; | |
566 | } | |
995ad051 | 567 | TObjArray* nodesArr = gGeoManager->GetListOfPhysicalNodes(); |
568 | TGeoPhysicalNode* node = NULL; | |
569 | for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) { | |
b760c02e | 570 | TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode); |
571 | const char *nodePath = tempNode->GetName(); | |
572 | if (strcmp(symname,nodePath) == 0) { | |
573 | node = tempNode; | |
574 | break; | |
575 | } | |
995ad051 | 576 | } |
b760c02e | 577 | |
995ad051 | 578 | if (!node) { |
b760c02e | 579 | if (!gGeoManager->cd(symname)) { |
580 | AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",symname)); | |
e1c4b551 | 581 | return kFALSE; |
582 | } | |
583 | else { | |
b760c02e | 584 | AliWarningClass(Form("Volume (%s) has not been misaligned!",symname)); |
e1c4b551 | 585 | return kTRUE; |
586 | } | |
995ad051 | 587 | } |
588 | ||
589 | TGeoHMatrix align,gprime,g,ginv,l; | |
590 | gprime = *node->GetMatrix(); | |
591 | l = *node->GetOriginalMatrix(); | |
592 | g = *node->GetMatrix(node->GetLevel()-1); | |
593 | g *= l; | |
594 | ginv = g.Inverse(); | |
595 | align = gprime * ginv; | |
995ad051 | 596 | |
b760c02e | 597 | return alobj.SetMatrix(align); |
995ad051 | 598 | } |
599 | ||
79e21da6 | 600 | //_____________________________________________________________________________ |
c5304981 | 601 | void AliAlignObj::InitAlignObjFromGeometry() |
602 | { | |
603 | // Loop over all alignable volumes and extract | |
604 | // the corresponding alignment objects from | |
605 | // the TGeo geometry | |
25b4e81e | 606 | |
607 | if(fgAlignObjs[0]) return; | |
c5304981 | 608 | |
b760c02e | 609 | InitSymNames(); |
c5304981 | 610 | |
c041444f | 611 | for (Int_t iLayer = kFirstLayer; iLayer < AliAlignObj::kLastLayer; iLayer++) { |
612 | fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer)]; | |
c5304981 | 613 | for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) { |
c041444f | 614 | UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,iModule); |
b760c02e | 615 | fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0,kTRUE); |
616 | const char *symname = SymName(volid); | |
617 | if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule])) | |
618 | AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname)); | |
c5304981 | 619 | } |
620 | } | |
621 | ||
622 | } | |
623 | ||
e1e6896f | 624 | //_____________________________________________________________________________ |
625 | AliAlignObj* AliAlignObj::GetAlignObj(UShort_t voluid) { | |
626 | // Returns the alignment object for given volume ID | |
627 | Int_t modId; | |
628 | ELayerID layerId = VolUIDToLayer(voluid,modId); | |
629 | return GetAlignObj(layerId,modId); | |
630 | } | |
631 | ||
c5304981 | 632 | //_____________________________________________________________________________ |
633 | AliAlignObj* AliAlignObj::GetAlignObj(ELayerID layerId, Int_t modId) | |
634 | { | |
e1e6896f | 635 | // Returns pointer to alignment object givent its layer and module ID |
c5304981 | 636 | if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){ |
637 | AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1)); | |
638 | return NULL; | |
639 | } | |
b760c02e | 640 | InitAlignObjFromGeometry(); |
641 | ||
c5304981 | 642 | return fgAlignObjs[layerId-kFirstLayer][modId]; |
643 | } | |
644 | ||
e1e6896f | 645 | //_____________________________________________________________________________ |
b760c02e | 646 | const char* AliAlignObj::SymName(UShort_t voluid) { |
e1e6896f | 647 | // Returns the volume path for given volume ID |
648 | Int_t modId; | |
649 | ELayerID layerId = VolUIDToLayer(voluid,modId); | |
b760c02e | 650 | return SymName(layerId,modId); |
e1e6896f | 651 | } |
652 | ||
e7570944 | 653 | //_____________________________________________________________________________ |
b760c02e | 654 | const char* AliAlignObj::SymName(ELayerID layerId, Int_t modId) |
e7570944 | 655 | { |
e1e6896f | 656 | // Returns volume path to alignment object givent its layer and module ID |
e7570944 | 657 | if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){ |
658 | AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1)); | |
659 | return NULL; | |
660 | } | |
b760c02e | 661 | InitSymNames(); |
662 | ||
e7570944 | 663 | return fgVolPath[layerId-kFirstLayer][modId].Data(); |
664 | } | |
665 | ||
03b18860 | 666 | //_____________________________________________________________________________ |
b760c02e | 667 | void AliAlignObj::InitSymNames() |
03b18860 | 668 | { |
669 | // Initialize the LUTs which contain | |
670 | // the TGeo volume paths for each | |
671 | // alignable volume. The LUTs are | |
672 | // static, so they are created during | |
673 | // the creation of the first intance | |
674 | // of AliAlignObj | |
675 | ||
676 | if (fgVolPath[0]) return; | |
677 | ||
678 | for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++) | |
7604a026 | 679 | fgVolPath[iLayer] = new TString[fgLayerSize[iLayer]]; |
03b18860 | 680 | |
681 | /********************* SPD layer1 ***********************/ | |
682 | { | |
683 | Int_t modnum = 0; | |
684 | TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_"; //".../I12A_" | |
685 | TString str1 = "/I10B_"; //"/I10A_"; | |
686 | TString str2 = "/I107_"; //"/I103_" | |
995ad051 | 687 | // TString str3 = "/I101_1/ITS1_1"; |
b760c02e | 688 | TString symname, symname1, symname2; |
03b18860 | 689 | |
690 | for(Int_t c1 = 1; c1<=10; c1++){ | |
b760c02e | 691 | symname = str0; |
692 | symname += c1; | |
693 | symname += str1; | |
03b18860 | 694 | for(Int_t c2 =1; c2<=2; c2++){ |
b760c02e | 695 | symname1 = symname; |
696 | symname1 += c2; | |
697 | symname1 += str2; | |
03b18860 | 698 | for(Int_t c3 =1; c3<=4; c3++){ |
b760c02e | 699 | symname2 = symname1; |
700 | symname2 += c3; | |
701 | // symname2 += str3; | |
702 | fgVolPath[kSPD1-kFirstLayer][modnum] = symname2.Data(); | |
03b18860 | 703 | modnum++; |
704 | } | |
705 | } | |
706 | } | |
707 | } | |
708 | ||
709 | /********************* SPD layer2 ***********************/ | |
710 | { | |
711 | Int_t modnum = 0; | |
712 | TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_"; //".../I12A_" | |
713 | TString str1 = "/I20B_"; //"/I20A" | |
714 | TString str2 = "/I1D7_"; //"/I1D3" | |
995ad051 | 715 | // TString str3 = "/I1D1_1/ITS2_1"; |
b760c02e | 716 | TString symname, symname1, symname2; |
03b18860 | 717 | |
718 | for(Int_t c1 = 1; c1<=10; c1++){ | |
b760c02e | 719 | symname = str0; |
720 | symname += c1; | |
721 | symname += str1; | |
03b18860 | 722 | for(Int_t c2 =1; c2<=4; c2++){ |
b760c02e | 723 | symname1 = symname; |
724 | symname1 += c2; | |
725 | symname1 += str2; | |
03b18860 | 726 | for(Int_t c3 =1; c3<=4; c3++){ |
b760c02e | 727 | symname2 = symname1; |
728 | symname2 += c3; | |
729 | // symname2 += str3; | |
730 | fgVolPath[kSPD2-kFirstLayer][modnum] = symname2.Data(); | |
03b18860 | 731 | modnum++; |
732 | } | |
733 | } | |
734 | } | |
735 | } | |
736 | ||
737 | /********************* SDD layer1 ***********************/ | |
738 | { | |
739 | Int_t modnum=0; | |
740 | TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I004_"; | |
741 | TString str1 = "/I302_"; | |
995ad051 | 742 | // TString str2 = "/ITS3_1"; |
b760c02e | 743 | TString symname, symname1; |
03b18860 | 744 | |
745 | for(Int_t c1 = 1; c1<=14; c1++){ | |
b760c02e | 746 | symname = str0; |
747 | symname += c1; | |
748 | symname += str1; | |
03b18860 | 749 | for(Int_t c2 =1; c2<=6; c2++){ |
b760c02e | 750 | symname1 = symname; |
751 | symname1 += c2; | |
752 | // symname1 += str2; | |
753 | fgVolPath[kSDD1-kFirstLayer][modnum] = symname1.Data(); | |
03b18860 | 754 | modnum++; |
755 | } | |
756 | } | |
757 | } | |
758 | ||
759 | /********************* SDD layer2 ***********************/ | |
760 | { | |
761 | Int_t modnum=0; | |
762 | TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I005_"; | |
763 | TString str1 = "/I402_"; | |
995ad051 | 764 | // TString str2 = "/ITS4_1"; |
b760c02e | 765 | TString symname, symname1; |
03b18860 | 766 | |
767 | for(Int_t c1 = 1; c1<=22; c1++){ | |
b760c02e | 768 | symname = str0; |
769 | symname += c1; | |
770 | symname += str1; | |
03b18860 | 771 | for(Int_t c2 = 1; c2<=8; c2++){ |
b760c02e | 772 | symname1 = symname; |
773 | symname1 += c2; | |
774 | // symname1 += str2; | |
775 | fgVolPath[kSDD2-kFirstLayer][modnum] = symname1.Data(); | |
03b18860 | 776 | modnum++; |
777 | } | |
778 | } | |
779 | } | |
780 | ||
781 | /********************* SSD layer1 ***********************/ | |
782 | { | |
783 | Int_t modnum=0; | |
784 | TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I565_"; | |
785 | TString str1 = "/I562_"; | |
995ad051 | 786 | // TString str2 = "/ITS5_1"; |
b760c02e | 787 | TString symname, symname1; |
03b18860 | 788 | |
789 | for(Int_t c1 = 1; c1<=34; c1++){ | |
b760c02e | 790 | symname = str0; |
791 | symname += c1; | |
792 | symname += str1; | |
03b18860 | 793 | for(Int_t c2 = 1; c2<=22; c2++){ |
b760c02e | 794 | symname1 = symname; |
795 | symname1 += c2; | |
796 | // symname1 += str2; | |
797 | fgVolPath[kSSD1-kFirstLayer][modnum] = symname1.Data(); | |
03b18860 | 798 | modnum++; |
799 | } | |
800 | } | |
801 | } | |
802 | ||
803 | /********************* SSD layer1 ***********************/ | |
804 | { | |
805 | Int_t modnum=0; | |
806 | TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I569_"; | |
807 | TString str1 = "/I566_"; | |
995ad051 | 808 | // TString str2 = "/ITS6_1"; |
b760c02e | 809 | TString symname, symname1; |
03b18860 | 810 | |
811 | for(Int_t c1 = 1; c1<=38; c1++){ | |
b760c02e | 812 | symname = str0; |
813 | symname += c1; | |
814 | symname += str1; | |
03b18860 | 815 | for(Int_t c2 = 1; c2<=25; c2++){ |
b760c02e | 816 | symname1 = symname; |
817 | symname1 += c2; | |
818 | // symname1 += str2; | |
819 | fgVolPath[kSSD2-kFirstLayer][modnum] = symname1.Data(); | |
03b18860 | 820 | modnum++; |
821 | } | |
822 | } | |
823 | } | |
824 | ||
e7570944 | 825 | /*************** TPC inner chambers' layer ****************/ |
826 | { | |
827 | Int_t modnum = 0; | |
828 | TString str1 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_1/TPC_SECT_"; | |
829 | TString str2 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_2/TPC_SECT_"; | |
e1e6896f | 830 | TString strIn = "/TPC_IROC_1"; |
b760c02e | 831 | TString symname; |
e7570944 | 832 | |
833 | for(Int_t cnt=1; cnt<=18; cnt++){ | |
b760c02e | 834 | symname = str1; |
835 | symname += cnt; | |
836 | symname += strIn; | |
837 | fgVolPath[kTPC1-kFirstLayer][modnum] = symname.Data(); | |
e7570944 | 838 | modnum++; |
839 | } | |
840 | for(Int_t cnt=1; cnt<=18; cnt++){ | |
b760c02e | 841 | symname = str2; |
842 | symname += cnt; | |
843 | symname += strIn; | |
844 | fgVolPath[kTPC1-kFirstLayer][modnum] = symname.Data(); | |
e7570944 | 845 | modnum++; |
846 | } | |
847 | } | |
848 | ||
849 | /*************** TPC outer chambers' layer ****************/ | |
850 | { | |
851 | Int_t modnum = 0; | |
852 | TString str1 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_1/TPC_SECT_"; | |
853 | TString str2 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_2/TPC_SECT_"; | |
e1e6896f | 854 | TString strOut = "/TPC_OROC_1"; |
b760c02e | 855 | TString symname; |
e7570944 | 856 | |
857 | for(Int_t cnt=1; cnt<=18; cnt++){ | |
b760c02e | 858 | symname = str1; |
859 | symname += cnt; | |
860 | symname += strOut; | |
861 | fgVolPath[kTPC2-kFirstLayer][modnum] = symname.Data(); | |
e7570944 | 862 | modnum++; |
863 | } | |
864 | for(Int_t cnt=1; cnt<=18; cnt++){ | |
b760c02e | 865 | symname = str2; |
866 | symname += cnt; | |
867 | symname += strOut; | |
868 | fgVolPath[kTPC2-kFirstLayer][modnum] = symname.Data(); | |
e7570944 | 869 | modnum++; |
870 | } | |
871 | } | |
872 | ||
9abb5d7b | 873 | /********************* TOF layer ***********************/ |
874 | { | |
875 | Int_t nstrA=15; | |
876 | Int_t nstrB=19; | |
da027ef2 | 877 | Int_t nstrC=19; |
878 | Int_t nsec=18; | |
9abb5d7b | 879 | Int_t nStripSec=nstrA+2*nstrB+2*nstrC; |
da027ef2 | 880 | Int_t nStrip=nStripSec*nsec; |
9abb5d7b | 881 | |
da027ef2 | 882 | for (Int_t modnum=0; modnum < nStrip; modnum++) { |
9abb5d7b | 883 | |
884 | Int_t sector = modnum/nStripSec; | |
9abb5d7b | 885 | Char_t string1[100]; |
886 | Char_t string2[100]; | |
9abb5d7b | 887 | Int_t icopy=-1; |
de0b6220 | 888 | icopy=sector; |
889 | ||
890 | // Old 6h convention | |
891 | // if(sector<13){ | |
892 | // icopy=sector+5;} | |
893 | // else{ icopy=sector-13;} | |
38b3a170 | 894 | |
06e24a91 | 895 | sprintf(string1,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1/FTOA_0/FLTA_0",sector,sector); |
da027ef2 | 896 | |
9abb5d7b | 897 | Int_t strInSec=modnum%nStripSec; |
da027ef2 | 898 | icopy= strInSec; |
899 | icopy++; | |
900 | sprintf(string2,"FSTR_%i",icopy); | |
9abb5d7b | 901 | Char_t path[100]; |
902 | sprintf(path,"%s/%s",string1,string2); | |
903 | // printf("%d %s\n",modnum,path); | |
904 | fgVolPath[kTOF-kFirstLayer][modnum] = path; | |
905 | } | |
906 | } | |
c8874495 | 907 | |
908 | /********************* RICH layer ***********************/ | |
909 | { | |
910 | TString str = "ALIC_1/RICH_"; | |
b760c02e | 911 | TString symname; |
c8874495 | 912 | |
913 | for (Int_t modnum=0; modnum < 7; modnum++) { | |
b760c02e | 914 | symname = str; |
915 | symname += (modnum+1); | |
916 | fgVolPath[kRICH-kFirstLayer][modnum] = symname.Data(); | |
c8874495 | 917 | } |
918 | } | |
274fcc1a | 919 | |
920 | /********************* TRD layers 0-6 *******************/ | |
921 | { | |
de0b6220 | 922 | TString strSM[18]={"ALIC_1/B077_1/BSEGMO0_1/BTRD0_1/UTR1_1/UTS1_1/UTI1_1/UT", |
923 | "ALIC_1/B077_1/BSEGMO1_1/BTRD1_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
924 | "ALIC_1/B077_1/BSEGMO2_1/BTRD2_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
925 | "ALIC_1/B077_1/BSEGMO3_1/BTRD3_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
926 | "ALIC_1/B077_1/BSEGMO4_1/BTRD4_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
927 | "ALIC_1/B077_1/BSEGMO5_1/BTRD5_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
9ce7d00f | 928 | "ALIC_1/B077_1/BSEGMO6_1/BTRD6_1/UTR1_1/UTS1_1/UTI1_1/UT", |
929 | "ALIC_1/B077_1/BSEGMO7_1/BTRD7_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
930 | "ALIC_1/B077_1/BSEGMO8_1/BTRD8_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
931 | "ALIC_1/B077_1/BSEGMO9_1/BTRD9_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
932 | "ALIC_1/B077_1/BSEGMO10_1/BTRD10_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
933 | "ALIC_1/B077_1/BSEGMO11_1/BTRD11_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
934 | "ALIC_1/B077_1/BSEGMO12_1/BTRD12_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
935 | "ALIC_1/B077_1/BSEGMO13_1/BTRD13_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
936 | "ALIC_1/B077_1/BSEGMO14_1/BTRD14_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
937 | "ALIC_1/B077_1/BSEGMO15_1/BTRD15_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
938 | "ALIC_1/B077_1/BSEGMO16_1/BTRD16_1/UTR1_1/UTS1_1/UTI1_1/UT", | |
de0b6220 | 939 | "ALIC_1/B077_1/BSEGMO17_1/BTRD17_1/UTR1_1/UTS1_1/UTI1_1/UT"}; |
274fcc1a | 940 | TString strPost = "_1"; |
a1a23a88 | 941 | TString zeroStr = "0"; |
b760c02e | 942 | TString symname; |
a1a23a88 | 943 | |
e1e6896f | 944 | Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6}; |
274fcc1a | 945 | |
a1a23a88 | 946 | for(Int_t layer=0; layer<6; layer++){ |
947 | Int_t modnum=0; | |
948 | for(Int_t sm = 0; sm < 18; sm++){ | |
949 | for(Int_t stacknum = 0; stacknum < 5; stacknum++){ | |
950 | Int_t chnum = layer + stacknum*6; | |
b760c02e | 951 | symname = strSM[sm]; |
952 | if(chnum<10) symname += zeroStr; | |
953 | symname += chnum; | |
954 | symname += strPost; | |
955 | fgVolPath[arTRDlayId[layer]-kFirstLayer][modnum] = symname.Data(); | |
274fcc1a | 956 | modnum++; |
957 | } | |
958 | } | |
959 | } | |
960 | } | |
961 | ||
03b18860 | 962 | } |