Temporary fix for 2 overlaps in SPD/FMD (M. Sitta)
[u/mrichter/AliRoot.git] / STEER / AliGeomManager.cxx
CommitLineData
67dd5535 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// Implementation of AliGeomManager, the geometry manager class
17// which interfaces to TGeo and the look-up table mapping unique
18// volume indices to symbolic volume names. For that it collects
19// several static methods.
20//-------------------------------------------------------------------------
21
22#include <TClass.h>
23#include <TFile.h>
24#include <TGeoManager.h>
25#include <TObjString.h>
26#include <TGeoPhysicalNode.h>
27#include <TClonesArray.h>
28#include <TGeoMatrix.h>
29#include <TGeoPhysicalNode.h>
99de26a3 30#include <TSystem.h>
5590c6c3 31#include <TStopwatch.h>
32#include <TGeoOverlap.h>
33#include <TPluginManager.h>
34#include <TROOT.h>
67dd5535 35
36#include "AliGeomManager.h"
37#include "AliLog.h"
38#include "AliAlignObj.h"
90dbf5fb 39#include "AliAlignObjParams.h"
67dd5535 40#include "AliCDBManager.h"
41#include "AliCDBStorage.h"
42#include "AliCDBEntry.h"
43
44ClassImp(AliGeomManager)
45
46Int_t AliGeomManager::fgLayerSize[kLastLayer - kFirstLayer] = {
47 80, 160, // ITS SPD first and second layer
48 84, 176, // ITS SDD first and second layer
49 748, 950, // ITS SSD first and second layer
50 36, 36, // TPC inner and outer chambers
51 90, 90, 90, 90, 90, 90, // 6 TRD chambers' layers
52 1638, // TOF
df117114 53 5, 5, // PHOS,CPV
67dd5535 54 7, // HMPID ??
3dfc15c0 55 1, // MUON ??
56 12 // EMCAL
67dd5535 57};
58
59const char* AliGeomManager::fgLayerName[kLastLayer - kFirstLayer] = {
60 "ITS inner pixels layer", "ITS outer pixels layer",
61 "ITS inner drifts layer", "ITS outer drifts layer",
62 "ITS inner strips layer", "ITS outer strips layer",
63 "TPC inner chambers layer", "TPC outer chambers layer",
64 "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3",
65 "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
66 "TOF layer",
df117114 67 "PHOS EMC layer","PHOS CPV layer",
3dfc15c0 68 "HMPID layer",
69 "MUON ?",
70 "EMCAL layer"
67dd5535 71};
72
67dd5535 73TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = {
74 0x0,0x0,
75 0x0,0x0,
76 0x0,0x0,
77 0x0,0x0,
78 0x0,0x0,0x0,
79 0x0,0x0,0x0,
80 0x0,
81 0x0,0x0,
82 0x0,
3dfc15c0 83 0x0,
67dd5535 84 0x0
85};
86
36b010bf 87AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = {
88 0x0,0x0,
89 0x0,0x0,
90 0x0,0x0,
91 0x0,0x0,
92 0x0,0x0,0x0,
93 0x0,0x0,0x0,
94 0x0,
95 0x0,0x0,
96 0x0,
3dfc15c0 97 0x0,
36b010bf 98 0x0
99};
67dd5535 100
101TGeoManager* AliGeomManager::fgGeometry = 0x0;
102
103//_____________________________________________________________________________
36b010bf 104void AliGeomManager::LoadGeometry(const char *geomFileName)
67dd5535 105{
9d47e237 106 // initialization
107 // Load geometry either from a file
108 // or from the corresponding CDB entry
67dd5535 109
36b010bf 110 fgGeometry = NULL;
b8cf7791 111 if (geomFileName && (!gSystem->AccessPathName(geomFileName))) {
36b010bf 112 fgGeometry = TGeoManager::Import(geomFileName);
b8cf7791 113 AliInfoClass(Form("From now on using geometry from custom geometry file %s",geomFileName));
36b010bf 114 }
115
116 if (!fgGeometry) {
36b010bf 117 AliCDBPath path("GRP","Geometry","Data");
118
119 AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
120 if(!entry) AliFatalClass("Couldn't load geometry data from CDB!");
121
122 entry->SetOwner(0);
123 fgGeometry = (TGeoManager*) entry->GetObject();
124 if (!fgGeometry) AliFatalClass("Couldn't find TGeoManager in the specified CDB entry!");
b8cf7791 125
126 AliInfoClass(Form("From now on using geometry from CDB base folder %s",
127 AliCDBManager::Instance()->GetURI("Geometry/Align/Data")));
36b010bf 128 }
67dd5535 129
67dd5535 130 InitPNEntriesLUT();
131}
132
133//_____________________________________________________________________________
9d47e237 134void AliGeomManager::SetGeometry(TGeoManager *geom)
135{
136 // Load already active geometry
137 if (!geom) AliFatalClass("Pointer to the active geometry is 0x0!");
138
139 fgGeometry = geom;
9d47e237 140 InitPNEntriesLUT();
9d47e237 141}
142
143//_____________________________________________________________________________
67dd5535 144AliGeomManager::AliGeomManager():
36b010bf 145 TObject()
67dd5535 146{
147 // default constructor
148}
149
150//_____________________________________________________________________________
151AliGeomManager::~AliGeomManager()
152{
153 // dummy destructor
67dd5535 154}
155
156//_____________________________________________________________________________
157Int_t AliGeomManager::LayerSize(Int_t layerId)
158{
159 // Get the layer size for layer corresponding to layerId.
160 // Implemented only for ITS,TPC,TRD,TOF and HMPID
161 //
162 if (layerId < kFirstLayer || layerId >= kLastLayer) {
163 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
164 return 0;
165 }
166 else {
167 return fgLayerSize[layerId - kFirstLayer];
5aedd709 168 }
67dd5535 169}
170
171//_____________________________________________________________________________
172const char* AliGeomManager::LayerName(Int_t layerId)
173{
174 // Get the layer name corresponding to layerId.
175 // Implemented only for ITS,TPC,TRD,TOF and HMPID
176 //
177 if (layerId < kFirstLayer || layerId >= kLastLayer) {
178 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
179 return "Invalid Layer!";
180 }
181 else {
182 return fgLayerName[layerId - kFirstLayer];
5aedd709 183 }
67dd5535 184}
185
186//_____________________________________________________________________________
187UShort_t AliGeomManager::LayerToVolUID(ELayerID layerId, Int_t modId)
188{
189 // From detector (layer) name and module number (according to detector
190 // internal numbering) build the unique numerical identity of that volume
191 // inside ALICE
192 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
193 // remaining 11 for module ID inside det (2048 possible values).
194 // NO check for validity of given modId inside the layer for speed's sake.
195 //
196 return ((UShort_t(layerId) << 11) | UShort_t(modId));
197}
198
199//_____________________________________________________________________________
200UShort_t AliGeomManager::LayerToVolUID(Int_t layerId, Int_t modId)
201{
202 // From detector (layer) name and module number (according to detector
203 // internal numbering) build the unique numerical identity of that volume
204 // inside ALICE
205 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
206 // remaining 11 for module ID inside det (2048 possible values).
207 // NO check for validity of given modId inside the layer for speed's sake.
208 //
209 return ((UShort_t(layerId) << 11) | UShort_t(modId));
210}
211
212//_____________________________________________________________________________
213UShort_t AliGeomManager::LayerToVolUIDSafe(ELayerID layerId, Int_t modId)
214{
215 // From detector (layer) name and module number (according to detector
216 // internal numbering) build the unique numerical identity of that volume
217 // inside ALICE
218 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
219 // remaining 11 for module ID inside det (2048 possible values).
220 // Check validity of given modId inside the layer.
221 //
222 if(modId < 0 || modId >= LayerSize(layerId)){
223 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
224 return 0;
225 }
226 return ((UShort_t(layerId) << 11) | UShort_t(modId));
227}
228
229//_____________________________________________________________________________
230UShort_t AliGeomManager::LayerToVolUIDSafe(Int_t layerId, Int_t modId)
231{
232 // From detector (layer) name and module number (according to detector
233 // internal numbering) build the unique numerical identity of that volume
234 // inside ALICE
235 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
236 // remaining 11 for module ID inside det (2048 possible values).
237 // Check validity of given modId inside the layer.
238 //
239 if(modId < 0 || modId >= LayerSize(layerId)){
240 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
241 return 0;
242 }
243 return ((UShort_t(layerId) << 11) | UShort_t(modId));
244}
245
246//_____________________________________________________________________________
247AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid, Int_t &modId)
248{
249 // From voluid, unique numerical identity of that volume inside ALICE,
250 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
251 // remaining 11 for module ID inside det (2048 possible values)), return
252 // the identity of the layer to which that volume belongs and sets the
253 // argument modId to the identity of that volume internally to the layer.
254 // NO check for validity of given voluid for speed's sake.
255 //
256 modId = voluid & 0x7ff;
257
258 return VolUIDToLayer(voluid);
259}
260
261//_____________________________________________________________________________
262AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid)
263{
264 // From voluid, unique numerical identity of that volume inside ALICE,
265 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
266 // remaining 11 for module ID inside det (2048 possible values)), return
267 // the identity of the layer to which that volume belongs
268 // NO check for validity of given voluid for speed's sake.
269 //
270 return ELayerID(voluid >> 11);
271}
272
273//_____________________________________________________________________________
274AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid, Int_t &modId)
275{
276 // From voluid, unique numerical identity of that volume inside ALICE,
277 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
278 // remaining 11 for module ID inside det (2048 possible values)), returns
279 // the identity of the layer to which that volume belongs and sets the
280 // argument modId to the identity of that volume internally to the layer.
281 // Checks the validity of the given voluid
282 //
283 ELayerID layId = VolUIDToLayerSafe(voluid);
284 if(layId){
285 Int_t mId = Int_t(voluid & 0x7ff);
286 if( mId>=0 && mId<LayerSize(layId)){
287 modId = mId;
288 return layId;
289 }
290 }
291
292 AliErrorClass(Form("Invalid unique volume id: %d !",voluid));
293 modId = -1;
294 return kInvalidLayer;
295
296}
297
298//_____________________________________________________________________________
299AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid)
300{
301 // From voluid, unique numerical identity of that volume inside ALICE,
302 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
303 // remaining 11 for module ID inside det (2048 possible values)), returns
304 // the identity of the layer to which that volume belongs
305 // Checks the validity of the given voluid
306 //
307 if( (voluid >> 11) < kLastLayer) return ELayerID(voluid >> 11);
308
309 AliErrorClass(Form("Invalid layer id: %d !",(voluid >> 11)));
310 return kInvalidLayer;
311
312}
313
314//_____________________________________________________________________________
315Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj)
316{
317 // Get the alignment object which corresponds to the symbolic volume name
318 // symname (in case equal to the TGeo volume path)
319 // The method is extremely slow due to the searching by string,
320 // therefore it should be used with great care!!
321 // This method returns FALSE if the symname of the object was not
322 // valid neither to get a TGeoPEntry nor as a volume path, or if the path
323 // associated to the TGeoPNEntry was not valid.
324 //
325
326 // Reset the alignment object
327 alobj.SetPars(0,0,0,0,0,0);
328 alobj.SetSymName(symname);
329
36b010bf 330 if (!fgGeometry || !fgGeometry->IsClosed()) {
67dd5535 331 AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
332 return kFALSE;
333 }
334
36b010bf 335 if (!fgGeometry->GetListOfPhysicalNodes()) {
67dd5535 336 AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
337 return kFALSE;
338 }
339
67dd5535 340 const char *path;
36b010bf 341 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
67dd5535 342 if(pne){
343 path = pne->GetTitle();
344 }else{
345 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
346 path = symname;
347 }
36b010bf 348 TObjArray* nodesArr = fgGeometry->GetListOfPhysicalNodes();
67dd5535 349 TGeoPhysicalNode* node = NULL;
350 for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
351 TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
352 const char *nodePath = tempNode->GetName();
353 if (strcmp(path,nodePath) == 0) {
354 node = tempNode;
355 break;
356 }
357 }
358
359 if (!node) {
36b010bf 360 if (!fgGeometry->cd(path)) {
67dd5535 361 AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",path));
362 return kFALSE;
363 }
364 else {
365 AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
366 return kTRUE;
367 }
368 }
369
370 TGeoHMatrix align,gprime,g,ginv,l;
371 gprime = *node->GetMatrix();
372 l = *node->GetOriginalMatrix();
373 g = *node->GetMatrix(node->GetLevel()-1);
374 g *= l;
375 ginv = g.Inverse();
376 align = gprime * ginv;
377
378 return alobj.SetMatrix(align);
379}
380
381
382//_____________________________________________________________________________
383void AliGeomManager::InitAlignObjFromGeometry()
384{
5aedd709 385 // Loop over all alignable volumes and extract
386 // the corresponding alignment objects from
387 // the TGeo geometry
67dd5535 388
389 if(fgAlignObjs[0]) return;
5aedd709 390
67dd5535 391 for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; iLayer++) {
392 fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[LayerSize(iLayer)];
393 for (Int_t iModule = 0; iModule < LayerSize(iLayer); iModule++) {
394 UShort_t volid = LayerToVolUID(iLayer,iModule);
90dbf5fb 395 fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjParams("",volid,0,0,0,0,0,0,kTRUE);
67dd5535 396 const char *symname = SymName(volid);
397 if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
398 AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname));
399 }
400 }
5aedd709 401
67dd5535 402}
403
404//_____________________________________________________________________________
5aedd709 405AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid)
406{
67dd5535 407 // Returns the alignment object for given volume ID
408 //
409 Int_t modId;
410 ELayerID layerId = VolUIDToLayer(voluid,modId);
411 return GetAlignObj(layerId,modId);
412}
413
414//_____________________________________________________________________________
415AliAlignObj* AliGeomManager::GetAlignObj(ELayerID layerId, Int_t modId)
416{
417 // Returns pointer to alignment object given its layer and module ID
418 //
419 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
420 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
421 return NULL;
422 }
423 InitAlignObjFromGeometry();
424
425 return fgAlignObjs[layerId-kFirstLayer][modId];
426}
427
428//_____________________________________________________________________________
5aedd709 429const char* AliGeomManager::SymName(UShort_t voluid)
430{
67dd5535 431 // Returns the symbolic volume name for given volume ID
432 //
433 Int_t modId;
434 ELayerID layerId = VolUIDToLayer(voluid,modId);
435 return SymName(layerId,modId);
436}
437
438//_____________________________________________________________________________
439const char* AliGeomManager::SymName(ELayerID layerId, Int_t modId)
440{
441 // Returns the symbolic volume name given for a given layer
442 // and module ID
443 //
ff5970a3 444 if(!fgGeometry){
445 AliErrorClass("No geometry instance loaded yet!");
446 return NULL;
447 }
67dd5535 448 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
449 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
450 return NULL;
451 }
67dd5535 452
a8629c62 453 TGeoPNEntry* pne = fgPNEntry[layerId-kFirstLayer][modId];
454 if(!pne)
455 {
456 AliWarningClass(Form("Module %d of layer %s is not activated!",modId,LayerName(layerId)));
457 return NULL;
458 }
459 return pne->GetName();
460
67dd5535 461}
462
463//_____________________________________________________________________________
ff5970a3 464Bool_t AliGeomManager::CheckSymNamesLUT(const char* detsToBeChecked)
67dd5535 465{
0bf7aade 466 // Check the look-up table which associates the unique numerical identity of
467 // each alignable volume to the corresponding symbolic volume name.
468 // The LUT is now hold inside the geometry and handled by TGeo.
469 // The method is meant to be launched when loading a geometry to verify that
470 // no changes in the symbolic names have been introduced, which would prevent
471 // backward compatibility with alignment objects.
472 // To accept both complete and partial geometry, this method skips the check
473 // for TRD and TOF volumes which are missing in the partial geometry.
474 //
67dd5535 475
ff5970a3 476// TString detsString(detsToBeChecked);
477// if(detsString.Contains("ALL")) detsString="ITS TPC TOF TRD HMPID PHOS EMCAL";
478
479 // Temporary measure to face the case of reconstruction over detectors not present in the geometry
480 TString detsString = "";
481 if(fgGeometry->CheckPath("ALIC_1/ITSV_1")) detsString+="ITS ";
482 if(fgGeometry->CheckPath("ALIC_1/TPC_M_1")) detsString+="TPC ";
83364444 483
484 TString tofsm;
485 TString baseTof("ALIC_1/B077_1/BSEGMO");
486 TString middleTof("_1/BTOF");
487 TString trailTof("_1/FTOA_0");
488 Bool_t tofActive=kFALSE;
489 Bool_t tofSMs[18];
490 for(Int_t sm=0; sm<18; sm++)
491 {
492 tofSMs[sm]=kFALSE;
493 tofsm=baseTof;
494 tofsm += sm;
495 tofsm += middleTof;
496 tofsm += sm;
497 tofsm += trailTof;
498 if(fgGeometry->CheckPath(tofsm.Data()))
499 {
500 tofActive=kTRUE;
501 tofSMs[sm]=kTRUE;
502 }
503 }
504 if(tofActive) detsString+="TOF ";
505
506 TString trdsm;
507 TString baseTrd("ALIC_1/B077_1/BSEGMO");
508 TString middleTrd("_1/BTRD");
509 TString trailTrd("_1/UTR1_1");
510 Bool_t trdActive=kFALSE;
511 Bool_t trdSMs[18];
512 for(Int_t sm=0; sm<18; sm++)
513 {
514 trdSMs[sm]=kFALSE;
515 trdsm=baseTrd;
516 trdsm += sm;
517 trdsm += middleTrd;
518 trdsm += sm;
519 trdsm += trailTrd;
520 if(fgGeometry->CheckPath(trdsm.Data()))
521 {
522 trdActive=kTRUE;
523 trdSMs[sm]=kTRUE;
524 }
525 }
526 if(trdActive) detsString+="TRD ";
527
ff5970a3 528 if(fgGeometry->CheckPath("ALIC_1/B077_1/BSEGMO0_1/BTRD0_1/UTR1_1")) detsString+="TRD ";
529 if(fgGeometry->CheckPath("ALIC_1/Hmp0_0")) detsString+="HMPID ";
530 if(fgGeometry->CheckPath("ALIC_1/PHOS_1")) detsString+="PHOS ";
531 if(fgGeometry->CheckPath("ALIC_1/XEN1_1")) detsString+="EMCAL";
532
533
67dd5535 534 TString symname;
0bf7aade 535 const char* sname;
536 TGeoPNEntry* pne = 0x0;
537 Int_t uid; // global unique identity
538 Int_t modnum; // unique id inside layer; in the following, set it to 0 at the start of each layer
67dd5535 539
ff5970a3 540 if(detsString.Contains("ITS")){
67dd5535 541 /********************* ITS layers ***********************/
ff5970a3 542 AliDebugClass(2,"Checking consistency of symbolic names for ITS layers");
543 TString strSPD = "ITS/SPD";
544 TString strSDD = "ITS/SDD";
545 TString strSSD = "ITS/SSD";
546 TString strStave = "/Stave";
547 TString strHalfStave = "/HalfStave";
548 TString strLadder = "/Ladder";
549 TString strSector = "/Sector";
550 TString strSensor = "/Sensor";
551 TString strEntryName1;
552 TString strEntryName2;
553 TString strEntryName3;
554
555 /********************* SPD layer1 ***********************/
556 {
557 modnum = 0;
558
559 for(Int_t cSect = 0; cSect<10; cSect++){
560 strEntryName1 = strSPD;
561 strEntryName1 += 0;
562 strEntryName1 += strSector;
563 strEntryName1 += cSect;
564
565 for(Int_t cStave =0; cStave<2; cStave++){
566 strEntryName2 = strEntryName1;
567 strEntryName2 += strStave;
568 strEntryName2 += cStave;
569
570 for (Int_t cHS=0; cHS<2; cHS++) {
571 strEntryName3 = strEntryName2;
572 strEntryName3 += strHalfStave;
573 strEntryName3 += cHS;
574
575 for(Int_t cLad =0; cLad<2; cLad++){
576 symname = strEntryName3;
577 symname += strLadder;
578 symname += cLad+cHS*2;
579 uid = LayerToVolUID(kSPD1,modnum++);
580 pne = fgGeometry->GetAlignableEntryByUID(uid);
581 if(!pne)
582 {
583 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
584 return kFALSE;
585 }
586 sname = pne->GetName();
587 if(symname.CompareTo(sname))
588 {
589 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d."
590 "Expected was %s, found was %s!", uid, symname.Data(), sname));
591 return kFALSE;
592 }
0bf7aade 593 }
8f8273a4 594 }
67dd5535 595 }
596 }
597 }
ff5970a3 598
599 /********************* SPD layer2 ***********************/
600 {
601 modnum = 0;
602
603 for(Int_t cSect = 0; cSect<10; cSect++){
604 strEntryName1 = strSPD;
605 strEntryName1 += 1;
606 strEntryName1 += strSector;
607 strEntryName1 += cSect;
608
609 for(Int_t cStave =0; cStave<4; cStave++){
610 strEntryName2 = strEntryName1;
611 strEntryName2 += strStave;
612 strEntryName2 += cStave;
613
614 for (Int_t cHS=0; cHS<2; cHS++) {
615 strEntryName3 = strEntryName2;
616 strEntryName3 += strHalfStave;
617 strEntryName3 += cHS;
618
619 for(Int_t cLad =0; cLad<2; cLad++){
620 symname = strEntryName3;
621 symname += strLadder;
622 symname += cLad+cHS*2;
623 uid = LayerToVolUID(kSPD2,modnum++);
624 pne = fgGeometry->GetAlignableEntryByUID(uid);
625 if(!pne)
626 {
627 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
628 return kFALSE;
629 }
630 sname = pne->GetName();
631 if(symname.CompareTo(sname))
632 {
633 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d."
634 "Expected was %s, found was %s!", uid, symname.Data(), sname));
635 return kFALSE;
636 }
0bf7aade 637 }
8f8273a4 638 }
67dd5535 639 }
640 }
641 }
ff5970a3 642
643 /********************* SDD layer1 ***********************/
644 {
645 modnum=0;
646
647 for(Int_t c1 = 1; c1<=14; c1++){
648 strEntryName1 = strSDD;
649 strEntryName1 += 2;
650 strEntryName1 +=strLadder;
651 strEntryName1 += (c1-1);
652 for(Int_t c2 =1; c2<=6; c2++){
653 symname = strEntryName1;
654 symname += strSensor;
655 symname += (c2-1);
656 uid = LayerToVolUID(kSDD1,modnum++);
657 pne = fgGeometry->GetAlignableEntryByUID(uid);
658 if(!pne)
659 {
660 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
661 return kFALSE;
662 }
663 sname = pne->GetName();
664 if(symname.CompareTo(sname))
665 {
666 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
667 "Expected was %s, found was %s!", uid, symname.Data(), sname));
668 return kFALSE;
669 }
670 }
671 }
672 }
673
674 /********************* SDD layer2 ***********************/
675 {
676 modnum=0;
677
678 for(Int_t c1 = 1; c1<=22; c1++){
679 strEntryName1 = strSDD;
680 strEntryName1 += 3;
681 strEntryName1 +=strLadder;
682 strEntryName1 += (c1-1);
683 for(Int_t c2 = 1; c2<=8; c2++){
684 symname = strEntryName1;
685 symname += strSensor;
686 symname += (c2-1);
687 uid = LayerToVolUID(kSDD2,modnum++);
688 pne = fgGeometry->GetAlignableEntryByUID(uid);
689 if(!pne)
690 {
691 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
692 return kFALSE;
693 }
694 sname = pne->GetName();
695 if(symname.CompareTo(sname))
696 {
697 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
698 "Expected was %s, found was %s!", uid, symname.Data(), sname));
699 return kFALSE;
700 }
701 }
702 }
703 }
704
705 /********************* SSD layer1 ***********************/
706 {
707 modnum=0;
708
709 for(Int_t c1 = 1; c1<=34; c1++){
710 strEntryName1 = strSSD;
711 strEntryName1 += 4;
712 strEntryName1 +=strLadder;
713 strEntryName1 += (c1-1);
714 for(Int_t c2 = 1; c2<=22; c2++){
715 symname = strEntryName1;
716 symname += strSensor;
717 symname += (c2-1);
718 uid = LayerToVolUID(kSSD1,modnum++);
719 pne = fgGeometry->GetAlignableEntryByUID(uid);
720 if(!pne)
721 {
722 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
723 return kFALSE;
724 }
725 sname = pne->GetName();
726 if(symname.CompareTo(sname))
727 {
728 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
729 "Expected was %s, found was %s!", uid, symname.Data(), sname));
730 return kFALSE;
731 }
732 }
733 }
734 }
735
736 /********************* SSD layer2 ***********************/
737 {
738 modnum=0;
739
740 for(Int_t c1 = 1; c1<=38; c1++){
741 strEntryName1 = strSSD;
742 strEntryName1 += 5;
743 strEntryName1 +=strLadder;
744 strEntryName1 += (c1-1);
745 for(Int_t c2 = 1; c2<=25; c2++){
746 symname = strEntryName1;
747 symname += strSensor;
748 symname += (c2-1);
749 uid = LayerToVolUID(kSSD2,modnum++);
750 pne = fgGeometry->GetAlignableEntryByUID(uid);
751 if(!pne)
752 {
753 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
754 return kFALSE;
755 }
756 sname = pne->GetName();
757 if(symname.CompareTo(sname))
758 {
759 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
760 "Expected was %s, found was %s!", uid, symname.Data(), sname));
761 return kFALSE;
762 }
763 }
764 }
765 }
766
767 AliDebugClass(2,"Consistency check for ITS symbolic names finished successfully.");
67dd5535 768 }
769
ff5970a3 770 if(detsString.Contains("TPC"))
67dd5535 771 {
ff5970a3 772 /*************** TPC inner and outer layers ****************/
773
774 AliDebugClass(2,"Checking consistency of symbolic names for TPC layers");
775 TString sAsector="TPC/EndcapA/Sector";
776 TString sCsector="TPC/EndcapC/Sector";
777 TString sInner="/InnerChamber";
778 TString sOuter="/OuterChamber";
779
780 /*************** TPC inner chambers' layer ****************/
781 {
782 modnum = 0;
67dd5535 783
ff5970a3 784 for(Int_t cnt=1; cnt<=18; cnt++)
785 {
786 symname = sAsector;
787 symname += cnt;
788 symname += sInner;
789 uid = LayerToVolUID(kTPC1,modnum++);
0bf7aade 790 pne = fgGeometry->GetAlignableEntryByUID(uid);
791 if(!pne)
792 {
793 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
794 return kFALSE;
795 }
796 sname = pne->GetName();
797 if(symname.CompareTo(sname))
798 {
799 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
800 "Expected was %s, found was %s!", uid, symname.Data(), sname));
801 return kFALSE;
802 }
67dd5535 803 }
67dd5535 804
ff5970a3 805 for(Int_t cnt=1; cnt<=18; cnt++)
806 {
807 symname = sCsector;
808 symname += cnt;
809 symname += sInner;
810 uid = LayerToVolUID(kTPC1,modnum++);
0bf7aade 811 pne = fgGeometry->GetAlignableEntryByUID(uid);
812 if(!pne)
813 {
814 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
815 return kFALSE;
816 }
817 sname = pne->GetName();
818 if(symname.CompareTo(sname))
819 {
820 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
821 "Expected was %s, found was %s!", uid, symname.Data(), sname));
822 return kFALSE;
823 }
67dd5535 824 }
825 }
67dd5535 826
ff5970a3 827 /*************** TPC outer chambers' layer ****************/
828 {
829 modnum = 0;
67dd5535 830
ff5970a3 831 for(Int_t cnt=1; cnt<=18; cnt++)
832 {
833 symname = sAsector;
834 symname += cnt;
835 symname += sOuter;
836 uid = LayerToVolUID(kTPC2,modnum++);
0bf7aade 837 pne = fgGeometry->GetAlignableEntryByUID(uid);
838 if(!pne)
839 {
840 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
841 return kFALSE;
842 }
843 sname = pne->GetName();
844 if(symname.CompareTo(sname))
845 {
846 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
847 "Expected was %s, found was %s!", uid, symname.Data(), sname));
848 return kFALSE;
849 }
67dd5535 850 }
67dd5535 851
ff5970a3 852 for(Int_t cnt=1; cnt<=18; cnt++)
853 {
854 symname = sCsector;
855 symname += cnt;
856 symname += sOuter;
857 uid = LayerToVolUID(kTPC2,modnum++);
0bf7aade 858 pne = fgGeometry->GetAlignableEntryByUID(uid);
859 if(!pne)
860 {
861 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
862 return kFALSE;
863 }
864 sname = pne->GetName();
865 if(symname.CompareTo(sname))
866 {
867 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
868 "Expected was %s, found was %s!", uid, symname.Data(), sname));
869 return kFALSE;
870 }
67dd5535 871 }
872 }
67dd5535 873
ff5970a3 874 AliDebugClass(2,"Consistency check for TPC symbolic names finished successfully.");
67dd5535 875 }
876
ff5970a3 877 if(detsString.Contains("TOF"))
67dd5535 878 {
ff5970a3 879 /********************* TOF layer ***********************/
67dd5535 880
ff5970a3 881 AliDebugClass(2,"Checking consistency of symbolic names for TOF layers");
67dd5535 882 modnum=0;
ff5970a3 883
67dd5535 884 Int_t nstrA=15;
885 Int_t nstrB=19;
886 Int_t nstrC=19;
887 Int_t nSectors=18;
888 Int_t nStrips=nstrA+2*nstrB+2*nstrC;
0bf7aade 889
67dd5535 890 TString snSM = "TOF/sm";
891 TString snSTRIP = "/strip";
892
893 for (Int_t isect = 0; isect < nSectors; isect++) {
894 for (Int_t istr = 1; istr <= nStrips; istr++) {
895 symname = snSM;
896 symname += Form("%02d",isect);
897 symname += snSTRIP;
898 symname += Form("%02d",istr);
0bf7aade 899 uid = LayerToVolUID(kTOF,modnum++);
83364444 900 if(!tofSMs[isect]) continue; // taking possible missing TOF sectors (partial geometry) into account
901 AliDebugClass(2,Form("Consistency check for symnames of TOF supermodule %d.",isect));
0bf7aade 902 if ((isect==13 || isect==14 || isect==15) && (istr >= 39 && istr <= 53)) continue; //taking holes into account
903 pne = fgGeometry->GetAlignableEntryByUID(uid);
904 if(!pne)
905 {
906 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
907 return kFALSE;
908 }
909 sname = pne->GetName();
910 if(symname.CompareTo(sname))
911 {
912 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
913 "Expected was %s, found was %s!", uid, symname.Data(), sname));
914 return kFALSE;
915 }
67dd5535 916 }
917 }
ff5970a3 918
919 AliDebugClass(2,"Consistency check for TOF symbolic names finished successfully.");
67dd5535 920 }
921
ff5970a3 922 if(detsString.Contains("HMPID"))
67dd5535 923 {
ff5970a3 924 /********************* HMPID layer ***********************/
925
926 AliDebugClass(2,"Checking consistency of symbolic names for HMPID layers");
67dd5535 927 TString str = "/HMPID/Chamber";
928
929 for (modnum=0; modnum < 7; modnum++) {
930 symname = str;
931 symname += modnum;
0bf7aade 932 uid = LayerToVolUID(kHMPID,modnum);
933 pne = fgGeometry->GetAlignableEntryByUID(uid);
934 if(!pne)
935 {
936 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
937 return kFALSE;
938 }
939 sname = pne->GetName();
940 if(symname.CompareTo(sname))
941 {
942 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
943 "Expected was %s, found was %s!", uid, symname.Data(), sname));
944 return kFALSE;
945 }
67dd5535 946 }
ff5970a3 947
948 AliDebugClass(2,"Consistency check for HMPID symbolic names finished successfully.");
67dd5535 949 }
950
ff5970a3 951 if(detsString.Contains("TRD"))
67dd5535 952 {
ff5970a3 953 /********************* TRD layers 1-6 *******************/
954 //!! 6 layers with index increasing in outwards direction
955
956 AliDebugClass(2,"Checking consistency of symbolic names for TRD layers");
67dd5535 957 Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
958
959 TString snStr = "TRD/sm";
960 TString snApp1 = "/st";
961 TString snApp2 = "/pl";
962
963 for(Int_t layer=0; layer<6; layer++){
964 modnum=0;
965 for (Int_t isect = 0; isect < 18; isect++) {
966 for (Int_t icham = 0; icham < 5; icham++) {
967 symname = snStr;
968 symname += Form("%02d",isect);
969 symname += snApp1;
970 symname += icham;
971 symname += snApp2;
972 symname += layer;
0bf7aade 973 uid = LayerToVolUID(arTRDlayId[layer],modnum++);
83364444 974 if(!trdSMs[isect]) continue;
975 AliDebugClass(2,Form("Consistency check for symnames of TRD supermodule %d.",isect));
0bf7aade 976 if ((isect==13 || isect==14 || isect==15) && icham==2) continue; //keeping holes into account
977 pne = fgGeometry->GetAlignableEntryByUID(uid);
978 if(!pne)
979 {
980 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
981 return kFALSE;
982 }
983 sname = pne->GetName();
984 if(symname.CompareTo(sname))
985 {
986 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
987 "Expected was %s, found was %s!", uid, symname.Data(), sname));
988 return kFALSE;
989 }
67dd5535 990 }
991 }
992 }
ff5970a3 993
994 AliDebugClass(2,"Consistency check for TRD symbolic names finished successfully.");
67dd5535 995 }
df117114 996
ff5970a3 997 if(detsString.Contains("PHOS"))
df117114 998 {
ff5970a3 999 /********************* PHOS EMC layer ***********************/
df117114 1000
ff5970a3 1001 AliDebugClass(2,"Checking consistency of symbolic names for PHOS layers");
1002
1003 {
1004 TString str = "PHOS/Module";
1005 modnum=0;
1006
1007 for (Int_t iModule=1; iModule <= 5; iModule++) {
1008 symname = str;
1009 symname += iModule;
1010 modnum = iModule-1;
1011 uid = LayerToVolUID(kPHOS1,modnum);
1012 pne = fgGeometry->GetAlignableEntryByUID(uid);
1013 if(!pne)
1014 {
1015 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1016 return kFALSE;
1017 }
1018 sname = pne->GetName();
1019 if(symname.CompareTo(sname))
1020 {
1021 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1022 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1023 return kFALSE;
1024 }
0bf7aade 1025 }
df117114 1026 }
df117114 1027
ff5970a3 1028 /********************* PHOS CPV layer ***********************/
1029 {
1030 TString str = "PHOS/Module";
1031 modnum=0;
f47b9233 1032
ff5970a3 1033 for (Int_t iModule=1; iModule <= 5; iModule++) {
1034 symname = str;
1035 symname += iModule;
1036 symname += "/CPV";
1037 modnum = iModule-1;
1038 uid = LayerToVolUID(kPHOS2,modnum);
1039 pne = fgGeometry->GetAlignableEntryByUID(uid);
1040 if(!pne)
1041 {
1042 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1043 return kFALSE;
1044 }
1045 sname = pne->GetName();
1046 if(symname.CompareTo(sname))
1047 {
1048 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1049 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1050 return kFALSE;
1051 }
0bf7aade 1052 }
f47b9233 1053 }
ff5970a3 1054
1055 AliDebugClass(2,"Consistency check for PHOS symbolic names finished successfully.");
f47b9233 1056 }
1057
ff5970a3 1058 if(detsString.Contains("EMCAL"))
3dfc15c0 1059 {
ff5970a3 1060 /********************* EMCAL layer ***********************/
1061
1062 AliDebugClass(2,"Checking consistency of symbolic names for EMCAL layers");
3dfc15c0 1063 TString str = "EMCAL/FullSupermodule";
1064 modnum=0;
1065
1066 for (Int_t iModule=1; iModule <= 12; iModule++) {
1067 symname = str;
1068 symname += iModule;
1069 if(iModule >10) {
1070 symname = "EMCAL/HalfSupermodule";
1071 symname += iModule-10;
1072 }
1073 modnum = iModule-1;
0bf7aade 1074 uid = LayerToVolUID(kEMCAL,modnum);
1075 pne = fgGeometry->GetAlignableEntryByUID(uid);
1076 if(!pne)
1077 {
1078 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1079 return kFALSE;
1080 }
1081 sname = pne->GetName();
1082 if(symname.CompareTo(sname))
1083 {
1084 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1085 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1086 return kFALSE;
1087 }
3dfc15c0 1088 }
ff5970a3 1089
1090 AliDebugClass(2,"Consistency check for EMCAL symbolic names finished successfully.");
3dfc15c0 1091 }
0bf7aade 1092
1093 return kTRUE;
f47b9233 1094
67dd5535 1095}
1096
1097//_____________________________________________________________________________
1098void AliGeomManager::InitPNEntriesLUT()
1099{
1100 // Initialize the look-up table which associates the unique
1101 // numerical identity of each alignable volume to the
1102 // corresponding TGeoPNEntry.
1103 // The LUTs are static; they are created at the creation of the
1104 // AliGeomManager instance and recreated if the geometry has changed
1105 //
36b010bf 1106 if (fgPNEntry[0]) return;
67dd5535 1107
36b010bf 1108 if(!fgGeometry) {
1109 AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry");
1110 return;
1111 }
25fad4e5 1112
67dd5535 1113 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
36b010bf 1114 fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
1115 for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
0bf7aade 1116 fgPNEntry[iLayer][modnum] = fgGeometry->GetAlignableEntryByUID(LayerToVolUID(iLayer+1,modnum));
36b010bf 1117 }
1118 }
1119}
1120
67dd5535 1121//______________________________________________________________________
1122TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry* pne)
1123{
5aedd709 1124 // Get the global transformation matrix for a given PNEntry
67dd5535 1125 // by quering the TGeoManager
1126
36b010bf 1127 if (!fgGeometry || !fgGeometry->IsClosed()) {
25fad4e5 1128 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
1129 return NULL;
1130 }
5aedd709 1131
67dd5535 1132 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
1133 if (pnode) return pnode->GetMatrix();
1134
1135 const char* path = pne->GetTitle();
36b010bf 1136 if (!fgGeometry->cd(path)) {
67dd5535 1137 AliErrorClass(Form("Volume path %s not valid!",path));
1138 return NULL;
1139 }
36b010bf 1140 return fgGeometry->GetCurrentMatrix();
67dd5535 1141}
1142
1143//______________________________________________________________________
1144TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index)
1145{
1146 // Get the global transformation matrix for a given alignable volume
1147 // identified by its unique ID 'index' by quering the TGeoManager
1148
67dd5535 1149 TGeoPNEntry *pne = GetPNEntry(index);
1150 if (!pne) return NULL;
1151
1152 return GetMatrix(pne);
1153}
1154
1155//______________________________________________________________________
1156TGeoHMatrix* AliGeomManager::GetMatrix(const char* symname)
1157{
1158 // Get the global transformation matrix for a given alignable volume
1159 // identified by its symbolic name 'symname' by quering the TGeoManager
1160
36b010bf 1161 if (!fgGeometry || !fgGeometry->IsClosed()) {
1162 AliErrorClass("No active geometry or geometry not yet closed!");
1163 return NULL;
1164 }
1165
1166 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
67dd5535 1167 if (!pne) return NULL;
1168
1169 return GetMatrix(pne);
1170}
1171
1172//______________________________________________________________________
1173Bool_t AliGeomManager::GetTranslation(Int_t index, Double_t t[3])
1174{
1175 // Get the translation vector for a given module 'index'
1176 // by quering the TGeoManager
1177
1178 TGeoHMatrix *m = GetMatrix(index);
1179 if (!m) return kFALSE;
1180
1181 Double_t *trans = m->GetTranslation();
1182 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1183
1184 return kTRUE;
1185}
1186
1187//______________________________________________________________________
1188Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
1189{
1190 // Get the rotation matrix for a given module 'index'
1191 // by quering the TGeoManager
1192
1193 TGeoHMatrix *m = GetMatrix(index);
1194 if (!m) return kFALSE;
1195
1196 Double_t *rot = m->GetRotationMatrix();
1197 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1198
1199 return kTRUE;
1200}
1201
5d534fe3 1202//_____________________________________________________________________________
1203Bool_t AliGeomManager::GetDeltaForBranch(Int_t index, TGeoHMatrix &inclusiveD)
1204{
1205 // The method sets the matrix passed as argument as the global delta
1206 // (for the volume referred by the unique index) including the displacements
1207 // of all parent volumes in the branch.
1208 //
5d534fe3 1209
1210 TGeoHMatrix go,invgo;
1211 go = *GetOrigGlobalMatrix(index);
1212 invgo = go.Inverse();
5aedd709 1213 inclusiveD = *GetMatrix(index);
5d534fe3 1214 inclusiveD.Multiply(&invgo);
1215
1216 return kTRUE;
1217}
1218
1219//_____________________________________________________________________________
1220Bool_t AliGeomManager::GetDeltaForBranch(AliAlignObj& aao, TGeoHMatrix &inclusiveD)
1221{
1222 // The method sets the matrix passed as argument as the global delta
1223 // (for the volume referred by the alignment object) including the displacements
1224 // of all parent volumes in the brach.
1225 //
1226 Int_t index = aao.GetVolUID();
1227 if(!index){
1228 AliErrorClass("Either the alignment object or its index are not valid");
1229 return kFALSE;
1230 }
1231 return GetDeltaForBranch(index, inclusiveD);
1232}
1233
36b010bf 1234//______________________________________________________________________
1235Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m)
67dd5535 1236{
36b010bf 1237 // Get the global transformation matrix (ideal geometry) for a given alignable volume
0bf7aade 1238 // The alignable volume is identified by 'symname' which has to be either a valid symbolic
1239 // name, the query being performed after alignment, or a valid volume path if the query is
1240 // performed before alignment.
1241 //
36b010bf 1242 m.Clear();
67dd5535 1243
36b010bf 1244 if (!fgGeometry || !fgGeometry->IsClosed()) {
1245 AliErrorClass("No active geometry or geometry not yet closed!");
67dd5535 1246 return kFALSE;
1247 }
36b010bf 1248 if (!fgGeometry->GetListOfPhysicalNodes()) {
67dd5535 1249 AliWarningClass("gGeoManager doesn't contain any aligned nodes!");
36b010bf 1250 if (!fgGeometry->cd(symname)) {
67dd5535 1251 AliErrorClass(Form("Volume path %s not valid!",symname));
1252 return kFALSE;
1253 }
1254 else {
36b010bf 1255 m = *fgGeometry->GetCurrentMatrix();
67dd5535 1256 return kTRUE;
1257 }
1258 }
1259
36b010bf 1260 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
67dd5535 1261 const char* path = NULL;
67dd5535 1262 if(pne){
0bf7aade 1263 m = *pne->GetGlobalOrig();
1264 return kTRUE;
67dd5535 1265 }else{
1266 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
1267 path=symname;
1268 }
1269
36b010bf 1270 return GetOrigGlobalMatrixFromPath(path,m);
1271}
1272
1273//_____________________________________________________________________________
1274Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m)
1275{
5aedd709 1276 // The method returns the global matrix for the volume identified by
1277 // 'path' in the ideal detector geometry.
1278 // The output global matrix is stored in 'm'.
1279 // Returns kFALSE in case TGeo has not been initialized or the volume
1280 // path is not valid.
36b010bf 1281 //
1282 m.Clear();
1283
1284 if (!fgGeometry || !fgGeometry->IsClosed()) {
1285 AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!");
67dd5535 1286 return kFALSE;
1287 }
1288
36b010bf 1289 if (!fgGeometry->CheckPath(path)) {
1290 AliErrorClass(Form("Volume path %s not valid!",path));
1291 return kFALSE;
1292 }
67dd5535 1293
36b010bf 1294 TIter next(fgGeometry->GetListOfPhysicalNodes());
1295 fgGeometry->cd(path);
67dd5535 1296
36b010bf 1297 while(fgGeometry->GetLevel()){
67dd5535 1298
1299 TGeoPhysicalNode *physNode = NULL;
1300 next.Reset();
36b010bf 1301 TGeoNode *node = fgGeometry->GetCurrentNode();
67dd5535 1302 while ((physNode=(TGeoPhysicalNode*)next()))
1303 if (physNode->GetNode() == node) break;
1304
1305 TGeoMatrix *lm = NULL;
1306 if (physNode) {
5aedd709 1307 lm = physNode->GetOriginalMatrix();
1308 if (!lm) lm = node->GetMatrix();
67dd5535 1309 } else
1310 lm = node->GetMatrix();
1311
1312 m.MultiplyLeft(lm);
1313
36b010bf 1314 fgGeometry->CdUp();
67dd5535 1315 }
1316
1317 return kTRUE;
1318}
1319
36b010bf 1320//_____________________________________________________________________________
1321TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(TGeoPNEntry* pne)
1322{
1323 // The method returns global matrix for the ideal detector geometry
1324 // using the corresponding TGeoPNEntry as an input.
5aedd709 1325 // The returned pointer should be copied by the user, since its content could
1326 // be overwritten by a following call to the method.
1327 // In case of missing TGeoManager the method returns NULL.
1328 //
36b010bf 1329 if (!fgGeometry || !fgGeometry->IsClosed()) {
1330 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
1331 return NULL;
1332 }
1333
0bf7aade 1334 return pne->GetGlobalOrig();
36b010bf 1335}
1336
67dd5535 1337//______________________________________________________________________
36b010bf 1338TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(Int_t index)
67dd5535 1339{
5aedd709 1340 // The method returns global matrix from the ideal detector geometry
1341 // for the volume identified by its index.
1342 // The returned pointer should be copied by the user, since its content could
1343 // be overwritten by a following call to the method.
1344 // In case of missing TGeoManager the method returns NULL.
1345 // If possible, the method uses the LUT of original ideal matrices
1346 // for fast access. The LUT is reset in case a
36b010bf 1347 // new geometry is loaded.
5aedd709 1348 //
0bf7aade 1349 TGeoPNEntry* pne = GetPNEntry(index);
1350 return pne->GetGlobalOrig();
67dd5535 1351}
1352
1353//______________________________________________________________________
1354Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3])
1355{
1356 // Get the original translation vector (ideal geometry)
1357 // for a given module 'index' by quering the TGeoManager
1358
36b010bf 1359 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1360 if (!m) return kFALSE;
67dd5535 1361
36b010bf 1362 Double_t *trans = m->GetTranslation();
67dd5535 1363 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1364
1365 return kTRUE;
1366}
1367
1368//______________________________________________________________________
1369Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9])
1370{
1371 // Get the original rotation matrix (ideal geometry)
1372 // for a given module 'index' by quering the TGeoManager
1373
36b010bf 1374 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1375 if (!m) return kFALSE;
67dd5535 1376
36b010bf 1377 Double_t *rot = m->GetRotationMatrix();
67dd5535 1378 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1379
1380 return kTRUE;
1381}
1382
1383//______________________________________________________________________
1384const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
1385{
25fad4e5 1386 // Get the matrix which transforms from the tracking to the local RS
67dd5535 1387 // The method queries directly the TGeoPNEntry
1388
67dd5535 1389 TGeoPNEntry *pne = GetPNEntry(index);
1390 if (!pne) return NULL;
1391
1392 const TGeoHMatrix *m = pne->GetMatrix();
1393 if (!m)
5aedd709 1394 AliErrorClass(Form("TGeoPNEntry (%s) contains no tracking-to-local matrix !",pne->GetName()));
67dd5535 1395
1396 return m;
1397}
1398
1399//______________________________________________________________________
1400Bool_t AliGeomManager::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
1401{
1402 // Get the matrix which transforms from the tracking r.s. to
1403 // the global one.
1404 // Returns kFALSE in case of error.
1405
1406 m.Clear();
1407
1408 TGeoHMatrix *m1 = GetMatrix(index);
1409 if (!m1) return kFALSE;
1410
1411 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
1412 if (!m2) return kFALSE;
1413
1414 m = *m1;
1415 m.Multiply(m2);
1416
1417 return kTRUE;
1418}
1419
1420//_____________________________________________________________________________
1421TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) {
1422 // Returns the TGeoPNEntry for the given global volume ID "voluid"
1423 //
1424 Int_t modId;
1425 ELayerID layerId = VolUIDToLayer(voluid,modId);
1426 return GetPNEntry(layerId,modId);
1427}
1428
1429//_____________________________________________________________________________
67dd5535 1430TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
1431{
1432 // Returns the TGeoPNEntry for a given layer
1433 // and module ID
1434 //
25fad4e5 1435
67dd5535 1436 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
1437 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
1438 return NULL;
1439 }
1440
1441 return fgPNEntry[layerId-kFirstLayer][modId];
1442}
1443
1444//_____________________________________________________________________________
5590c6c3 1445void AliGeomManager::CheckOverlapsOverPNs(Double_t threshold)
1446{
1447 // Check for overlaps/extrusions on physical nodes only;
1448 // this overlap-checker is meant to be used to check overlaps/extrusions
1449 // originated by the application of alignment objects.
1450 //
1451
1452 TObjArray* ovexlist = new TObjArray(64);
1453
1454 AliInfoClass("********* Checking overlaps/extrusions over physical nodes only *********");
1455 TObjArray* pnList = gGeoManager->GetListOfPhysicalNodes();
0cd61c1d 1456 TGeoVolume* mvol = 0;
5590c6c3 1457 TGeoPhysicalNode* pn;
1458 TObjArray* overlaps = new TObjArray(64);
1459 overlaps->SetOwner();
1460
1461 TStopwatch timer2;
1462 timer2.Start();
1463 for(Int_t pni=0; pni<pnList->GetEntriesFast(); pni++){
1464 pn = (TGeoPhysicalNode*) pnList->UncheckedAt(pni);
1465 // checking the volume of the mother (go upper in the tree in case it is an assembly)
1466 Int_t levup=1;
1467 while(((TGeoVolume*)pn->GetVolume(pn->GetLevel()-levup))->IsAssembly()) levup++;
1468 //Printf("Going to upper level");
1469 mvol = pn->GetVolume(pn->GetLevel()-levup);
1470 if(!mvol->IsSelected()){
1471 AliInfoClass(Form("Checking overlaps for volume %s",mvol->GetName()));
1472 mvol->CheckOverlaps(threshold);
1473 ovexlist = gGeoManager->GetListOfOverlaps();
1474 TIter next(ovexlist);
1475 TGeoOverlap *ov;
1476 while ((ov=(TGeoOverlap*)next())) overlaps->Add(ov->Clone());
1477 mvol->SelectVolume();
1478 }
1479 }
1480 mvol->SelectVolume(kTRUE); // clears the list of selected volumes
1481
1482 AliInfoClass(Form("Number of overlapping/extruding PNs: %d",overlaps->GetEntriesFast()));
1483 timer2.Stop();
1484 timer2.Print();
1485
1486 TIter nextN(overlaps);
1487 TGeoOverlap *ovlp;
1488 while ((ovlp=(TGeoOverlap*)nextN())) ovlp->PrintInfo();
1489
1490 overlaps->Delete();
1491 delete overlaps;
1492}
1493
1494//_____________________________________________________________________________
67dd5535 1495Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
1496{
1497 // Calls AddAlignObjsFromCDBSingleDet for the detectors appearing in
1498 // the list passed as argument (called by AliSimulation and
1499 // AliReconstruction)
1500 // Read the alignment objects from CDB.
1501 // Each detector is supposed to have the
1502 // alignment objects in DET/Align/Data CDB path.
1503 // All the detector objects are then collected,
1504 // sorted by geometry level (starting from ALIC) and
1505 // then applied to the TGeo geometry.
1506 // Finally an overlaps check is performed.
1507 //
1508
36b010bf 1509 TObjArray alignObjArray;
1510 alignObjArray.Clear();
1511 alignObjArray.SetOwner(0);
67dd5535 1512
1513 TString alObjsNotLoaded="";
1514 TString alObjsLoaded="";
1515
1516 TString AlignDetsString(AlignDetsList);
1517 TObjArray *detsarr = AlignDetsString.Tokenize(' ');
1518 TIter iter(detsarr);
1519 TObjString *str = 0;
1520
1521 while((str = (TObjString*) iter.Next())){
1522 TString det(str->String());
36b010bf 1523 AliInfoClass(Form("Loading alignment objs for %s",det.Data()));
1524 if(!LoadAlignObjsFromCDBSingleDet(det.Data(),alignObjArray)){
67dd5535 1525 alObjsNotLoaded += det.Data();
1526 alObjsNotLoaded += " ";
1527 } else {
1528 alObjsLoaded += det.Data();
1529 alObjsLoaded += " ";
1530 }
1531 }
b80b98e1 1532 detsarr->Delete();
1533 delete detsarr;
67dd5535 1534
36b010bf 1535 if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s",
1536 alObjsLoaded.Data()));
1537 if(!alObjsNotLoaded.IsNull()) AliInfoClass(Form("Didn't/couldn't load alignment objects for: %s",
1538 alObjsNotLoaded.Data()));
67dd5535 1539
9cb4fe0b 1540 return ApplyAlignObjsToGeom(alignObjArray);
67dd5535 1541}
1542
1543//_____________________________________________________________________________
36b010bf 1544Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName, TObjArray& alignObjArray)
67dd5535 1545{
1546 // Adds the alignable objects found in the CDBEntry for the detector
1547 // passed as argument to the array of all alignment objects to be applyed
1548 // to geometry
1549 //
1550 // Fills array of single detector's alignable objects from CDB
1551
36b010bf 1552 AliDebugClass(2, Form("Loading alignment objs for detector: %s",detName));
67dd5535 1553
1554 AliCDBEntry *entry;
1555
1556 AliCDBPath path(detName,"Align","Data");
1557
1558 entry=AliCDBManager::Instance()->Get(path.GetPath());
1559 if(!entry){
36b010bf 1560 AliDebugClass(2,Form("Couldn't load alignment data for detector %s",detName));
67dd5535 1561 return kFALSE;
1562 }
1563 entry->SetOwner(1);
1564 TClonesArray *alignArray = (TClonesArray*) entry->GetObject();
1565 alignArray->SetOwner(0);
36b010bf 1566 AliDebugClass(2,Form("Found %d alignment objects for %s",
1567 alignArray->GetEntries(),detName));
67dd5535 1568
1569 AliAlignObj *alignObj=0;
1570 TIter iter(alignArray);
1571
1572 // loop over align objects in detector
1573 while( ( alignObj=(AliAlignObj *) iter.Next() ) ){
36b010bf 1574 alignObjArray.Add(alignObj);
67dd5535 1575 }
1576 // delete entry --- Don't delete, it is cached!
1577
36b010bf 1578 AliDebugClass(2, Form("fAlignObjArray entries: %d",alignObjArray.GetEntries() ));
67dd5535 1579 return kTRUE;
1580
1581}
1582
1583//_____________________________________________________________________________
5590c6c3 1584Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray, Bool_t ovlpcheck)
67dd5535 1585{
1586 // Read collection of alignment objects (AliAlignObj derived) saved
1587 // in the TClonesArray alObjArray and apply them to gGeoManager
1588 //
36b010bf 1589 alignObjArray.Sort();
1590 Int_t nvols = alignObjArray.GetEntriesFast();
67dd5535 1591
1592 Bool_t flag = kTRUE;
1593
1594 for(Int_t j=0; j<nvols; j++)
bb1970d8 1595 {
1596 AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
1597 flag = alobj->ApplyToGeometry(ovlpcheck);
1598 if(!flag)
67dd5535 1599 {
027ef5c5 1600 AliWarningClass(Form("Error applying alignment object for volume %s !",alobj->GetSymName()));
bb1970d8 1601 }else{
1602 AliDebugClass(5,Form("Alignment object for volume %s applied successfully",alobj->GetSymName()));
67dd5535 1603 }
1604
bb1970d8 1605 }
1606
1607 if (AliDebugLevelClass() > 5) {
1608 fgGeometry->CheckOverlaps(0.001);
36b010bf 1609 TObjArray* ovexlist = fgGeometry->GetListOfOverlaps();
67dd5535 1610 if(ovexlist->GetEntriesFast()){
36b010bf 1611 AliErrorClass("The application of alignment objects to the geometry caused huge overlaps/extrusions!");
bb1970d8 1612 fgGeometry->PrintOverlaps();
67dd5535 1613 }
1614 }
1615
36b010bf 1616 // Update the TGeoPhysicalNodes
1617 fgGeometry->RefreshPhysicalNodes();
1618
67dd5535 1619 return flag;
1620
1621}
1622
1623//_____________________________________________________________________________
1624Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
1625{
1626 // read collection of alignment objects (AliAlignObj derived) saved
1627 // in the TClonesArray ClArrayName in the file fileName and apply
1628 // them to the geometry
1629 //
1630
1631 TFile* inFile = TFile::Open(fileName,"READ");
1632 if (!inFile || !inFile->IsOpen()) {
1633 AliErrorClass(Form("Could not open file %s !",fileName));
1634 return kFALSE;
1635 }
1636
36b010bf 1637 TClonesArray* alignObjArray = ((TClonesArray*) inFile->Get(clArrayName));
67dd5535 1638 inFile->Close();
36b010bf 1639 if (!alignObjArray) {
67dd5535 1640 AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
1641 return kFALSE;
1642 }
1643
36b010bf 1644 return ApplyAlignObjsToGeom(*alignObjArray);
67dd5535 1645
1646}
1647
1648//_____________________________________________________________________________
1649Bool_t AliGeomManager::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id)
1650{
1651 // read collection of alignment objects (AliAlignObj derived) saved
1652 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1653 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1654 // to the geometry
1655 //
1656
1657 AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param);
1658 AliCDBEntry* entry = storage->Get(Id);
36b010bf 1659 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
67dd5535 1660
36b010bf 1661 return ApplyAlignObjsToGeom(*alignObjArray);
67dd5535 1662
1663}
1664
1665//_____________________________________________________________________________
1666Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
1667{
1668 // read collection of alignment objects (AliAlignObj derived) saved
1669 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1670 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1671 // to the geometry
1672 //
1673
1674 AliCDBParam* param = AliCDBManager::Instance()->CreateParameter(uri);
1675 AliCDBId id(path, runnum, runnum, version, sversion);
1676
1677 return ApplyAlignObjsToGeom(param, id);
1678
1679}
1680
1681//_____________________________________________________________________________
1682Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, Int_t version, Int_t sversion)
1683{
1684 // read collection of alignment objects (AliAlignObj derived) saved
1685 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1686 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1687 // to the geometry
1688 //
1689
1690 AliCDBPath path(detName,"Align","Data");
1691 AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion);
1692
1693 if(!entry) return kFALSE;
36b010bf 1694 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
25fad4e5 1695
36b010bf 1696 return ApplyAlignObjsToGeom(*alignObjArray);
67dd5535 1697}
171c4ef9 1698
171c4ef9 1699