]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONGeometryTransformer.cxx
- Removing use of volpath.dat file, now we can use volume symnames
[u/mrichter/AliRoot.git] / MUON / AliMUONGeometryTransformer.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *      SigmaEffect_thetadegrees                                                                  *
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 purpeateose. It is      *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17 //
18 // ----------------------------
19 // Class AliMUONGeometryTransformer
20 // ----------------------------
21 // Top container class for geometry transformations
22 // Author: Ivana Hrivnacova, IPN Orsay
23
24 #include "AliMUONGeometryTransformer.h"
25 #include "AliMUONGeometryModuleTransformer.h"
26 #include "AliMUONGeometryDetElement.h"
27 #include "AliMUONGeometryBuilder.h"
28
29 #include "AliMpDEManager.h"
30 #include "AliMpConstants.h"
31 #include "AliMpExMap.h"
32
33 #include "AliLog.h"
34 #include "AliAlignObjMatrix.h"
35 #include "AliAlignObj.h"
36
37 #include <Riostream.h>
38 #include <TSystem.h>
39 #include <TClonesArray.h>
40 #include <TGeoManager.h>
41 #include <TGeoPhysicalNode.h>
42 #include <TFile.h>
43 #include <TString.h>
44
45 #include <sstream>
46
47 /// \cond CLASSIMP
48 ClassImp(AliMUONGeometryTransformer)
49 /// \endcond
50
51 const TString  AliMUONGeometryTransformer::fgkDefaultDetectorName = "MUON";
52  
53 //______________________________________________________________________________
54 AliMUONGeometryTransformer::AliMUONGeometryTransformer()
55
56   : TObject(),
57     fDetectorName(fgkDefaultDetectorName),
58     fModuleTransformers(0),
59     fMisAlignArray(0)
60 {
61 /// Standard constructor
62
63   // Create array for geometry modules
64   fModuleTransformers = new TObjArray(100);
65   fModuleTransformers->SetOwner(true);
66 }
67
68 //______________________________________________________________________________
69 AliMUONGeometryTransformer::AliMUONGeometryTransformer(TRootIOCtor* /*ioCtor*/) 
70   : TObject(),
71     fDetectorName(),
72     fModuleTransformers(0),
73     fMisAlignArray(0)
74 {
75 /// Default constructor
76
77
78 //______________________________________________________________________________
79 AliMUONGeometryTransformer::~AliMUONGeometryTransformer()
80 {
81 /// Destructor
82
83   delete fModuleTransformers;
84   delete fMisAlignArray;
85 }
86
87 //
88 // private methods
89 //
90
91 //_____________________________________________________________________________
92 AliMUONGeometryModuleTransformer* 
93 AliMUONGeometryTransformer::GetModuleTransformerNonConst(
94                                           Int_t index, Bool_t warn) const
95 {
96 /// Return the geometry module specified by index
97
98   if (index < 0 || index >= fModuleTransformers->GetEntriesFast()) {
99     if (warn) {
100       AliWarningStream() 
101         << "Index: " << index << " outside limits" << std::endl;
102     }                    
103     return 0;  
104   }  
105
106   return (AliMUONGeometryModuleTransformer*) fModuleTransformers->At(index);
107 }    
108
109 //______________________________________________________________________________
110 TGeoHMatrix AliMUONGeometryTransformer::GetTransform(
111                   Double_t x, Double_t y, Double_t z,
112                   Double_t a1, Double_t a2, Double_t a3, 
113                   Double_t a4, Double_t a5, Double_t a6) const
114 {                 
115 /// Build the transformation from the given parameters
116
117   // Compose transform
118   return TGeoCombiTrans(TGeoTranslation(x, y, z), 
119                         TGeoRotation("rot", a1, a2, a3, a4, a5, a6));
120 }
121
122
123 //______________________________________________________________________________
124 void AliMUONGeometryTransformer::FillModuleTransform(Int_t moduleId,
125                   Double_t x, Double_t y, Double_t z,
126                   Double_t a1, Double_t a2, Double_t a3,
127                   Double_t a4, Double_t a5, Double_t a6) 
128 {
129 /// Fill the transformation of the module.
130
131   AliMUONGeometryModuleTransformer* moduleTransformer
132     = GetModuleTransformerNonConst(moduleId, false);
133
134   if ( !moduleTransformer) {
135     AliErrorStream() 
136       << "Module " << moduleId << " has not volume path defined." << endl;
137   }  
138       
139   // Build the transformation from the parameters
140   TGeoHMatrix transform 
141     = GetTransform(x, y, z, a1, a2, a3, a4, a5, a6);
142       
143   moduleTransformer->SetTransformation(transform);
144 }                  
145   
146 //______________________________________________________________________________
147 void AliMUONGeometryTransformer::FillDetElemTransform(
148                   Int_t detElemId, 
149                   Double_t x, Double_t y, Double_t z,
150                   Double_t a1, Double_t a2, Double_t a3,
151                   Double_t a4, Double_t a5, Double_t a6) 
152 {
153 /// Fill the transformation of the detection element.
154
155   // Module Id
156   Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId);
157
158   // Get module transformer
159   const AliMUONGeometryModuleTransformer* kModuleTransformer
160     = GetModuleTransformer(moduleId);
161
162   if ( ! kModuleTransformer ) {
163     AliFatal(Form("Module transformer not defined, detElemId: %d", detElemId));
164     return;  
165   }  
166
167   // Get detection element
168   AliMUONGeometryDetElement* detElement 
169     = kModuleTransformer->GetDetElement(detElemId);     
170
171   if ( ! detElement ) {
172     AliFatal(Form("Det element %d has not volume path defined", detElemId));
173     return;  
174   }  
175       
176   // Build the transformation from the parameters
177   TGeoHMatrix localTransform 
178     = GetTransform(x, y, z, a1, a2, a3, a4, a5, a6);
179   detElement->SetLocalTransformation(localTransform); 
180    
181   // Compute global transformation
182   TGeoHMatrix globalTransform 
183     = AliMUONGeometryBuilder::Multiply( 
184                                   *kModuleTransformer->GetTransformation(),
185                                   localTransform );
186   detElement->SetGlobalTransformation(globalTransform);
187 }                  
188
189 //______________________________________________________________________________
190 TString  AliMUONGeometryTransformer::ReadModuleTransforms(ifstream& in)
191 {
192 /// Read and fill modules transformations from the stream.
193 /// Return true, if reading finished correctly.
194
195   TString key(AliMUONGeometryModuleTransformer::GetModuleNamePrefix());
196   while ( key == AliMUONGeometryModuleTransformer::GetModuleNamePrefix() ) {
197     Int_t id;
198     Double_t  x, y, z;
199     Double_t  a1, a2, a3, a4, a5, a6;
200     TString dummy;
201   
202     in >> id;
203     in >> dummy;
204     in >> x;
205     in >> y;
206     in >> z;
207     in >> dummy;
208     in >> a1; 
209     in >> a2; 
210     in >> a3; 
211     in >> a4; 
212     in >> a5; 
213     in >> a6; 
214
215     //cout << "moduleId="     << id << "  "
216     //   << "position= " << x << ", " << y << ", " << z << "  "
217     //   << "rotation= " << a1 << ", " << a2 << ", " << a3  << ", "
218     //                   << a4 << ", " << a5 << ", " << a6 
219     //   << endl;   
220          
221     // Fill data
222     FillModuleTransform(id, x, y, z, a1, a2, a3, a4, a5, a6);
223     
224     // Go to next line
225     in >> key;
226   }
227   
228   return key;            
229 }
230
231 //______________________________________________________________________________
232 TString  AliMUONGeometryTransformer::ReadDetElemTransforms(ifstream& in)
233 {
234 /// Read detection elements transformations from the stream.
235 /// Return true, if reading finished correctly.
236
237   TString key(AliMUONGeometryDetElement::GetDENamePrefix());
238   while ( key == AliMUONGeometryDetElement::GetDENamePrefix() ) {
239
240     // Input data
241     Int_t detElemId;
242     Double_t  x, y, z;
243     Double_t  a1, a2, a3, a4, a5, a6;
244     TString dummy;
245   
246     in >> detElemId;
247     in >> dummy;
248     in >> x;
249     in >> y;
250     in >> z;
251     in >> dummy;
252     in >> a1; 
253     in >> a2; 
254     in >> a3; 
255     in >> a4; 
256     in >> a5; 
257     in >> a6; 
258
259     //cout << "detElemId=" << detElemId << "  "
260     //     << "position= " << x << ", " << y << ", " << z << "  "
261     //     << "rotation= " << a1 << ", " << a2 << ", " << a3  << ", "
262     //                     << a4 << ", " << a5 << ", " << a6 
263     //     << endl;   
264          
265     // Fill data
266     FillDetElemTransform(detElemId, x, y, z, a1, a2, a3, a4, a5, a6);    
267     
268     // Go to next line
269     in >> key;
270   } 
271   
272   return key;
273 }
274
275 //______________________________________________________________________________
276 Bool_t  
277 AliMUONGeometryTransformer::ReadTransformations(const TString& fileName)
278 {
279 /// Read transformations from a file.
280 /// Return true, if reading finished correctly.
281
282   // File path
283   TString filePath = gSystem->Getenv("ALICE_ROOT");
284   filePath += "/MUON/data/";
285   filePath += fileName;
286   
287   // Open input file
288   ifstream in(filePath, ios::in);
289   if (!in) {
290     cerr << filePath << endl;   
291     AliFatal("File not found.");
292     return false;
293   }
294
295   TString key;
296   in >> key;
297   while ( !in.eof() ) {
298     if ( key == AliMUONGeometryModuleTransformer::GetModuleNamePrefix() ) 
299       key = ReadModuleTransforms(in);
300     else if ( key == AliMUONGeometryDetElement::GetDENamePrefix() )
301       key = ReadDetElemTransforms(in);
302     else {
303       AliFatal(Form("%s key not recognized",  key.Data()));
304       return false;
305     }
306   }     
307
308   return true;
309 }
310
311 //______________________________________________________________________________
312 Bool_t  
313 AliMUONGeometryTransformer::LoadTransformations()
314 {
315 /// Load transformations for defined modules and detection elements
316 /// using AliGeomManager
317
318   if ( ! AliGeomManager::GetGeometry() ) {
319     AliFatal("Geometry has to be laoded in AliGeomManager first.");
320     return false;
321   }   
322
323   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
324     AliMUONGeometryModuleTransformer* moduleTransformer 
325       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
326
327     // Module symbolic name
328     TString symname = GetModuleSymName(moduleTransformer->GetModuleId());
329     
330     // Set matrix from physical node
331     TGeoHMatrix* matrix = AliGeomManager::GetMatrix(symname);
332     if ( !matrix ) {
333       AliErrorStream() << "Geometry module matrix not found." << endl;
334       return false;
335     }  
336     moduleTransformer->SetTransformation(*matrix);
337     
338     // Loop over detection elements
339     AliMpExMap* detElements = moduleTransformer->GetDetElementStore();    
340    
341     for (Int_t j=0; j<detElements->GetSize(); j++) {
342       AliMUONGeometryDetElement* detElement
343         = (AliMUONGeometryDetElement*)detElements->GetObject(j);
344
345       // Det element  symbolic name
346       TString symname = GetDESymName(detElement->GetId());
347     
348       // Set global matrix from physical node
349       TGeoHMatrix* globalMatrix = AliGeomManager::GetMatrix(symname);
350       if ( !matrix ) {
351         AliErrorStream() << "Detection element matrix not found." << endl;
352         return false;
353       }  
354       detElement->SetGlobalTransformation(*globalMatrix);
355
356       // Set local matrix
357       TGeoHMatrix localMatrix = 
358         AliMUONGeometryBuilder::Multiply(
359            (*matrix).Inverse(), (*globalMatrix) );
360       detElement->SetLocalTransformation(localMatrix);
361     }  
362   } 
363   return true;    
364 }  
365
366 //______________________________________________________________________________
367 void AliMUONGeometryTransformer::WriteTransform(ofstream& out,
368                                    const TGeoMatrix* transform) const
369 {
370 /// Write given transformation 
371
372   out << "   pos: ";
373   const Double_t* xyz = transform->GetTranslation();
374   out << setw(10) << setprecision(4) << xyz[0] << "  " 
375       << setw(10) << setprecision(4) << xyz[1] << "  " 
376       << setw(10) << setprecision(4) << xyz[2];
377
378   out << "   rot: ";
379   const Double_t* rm = transform->GetRotationMatrix();
380   TGeoRotation rotation;
381   rotation.SetMatrix(const_cast<Double_t*>(rm));
382   Double_t a1, a2, a3, a4, a5, a6;
383   rotation.GetAngles(a1, a2, a3, a4, a5, a6);
384       
385   out << setw(8) << setprecision(4) << a1 << "  " 
386       << setw(8) << setprecision(4) << a2 << "  " 
387       << setw(8) << setprecision(4) << a3 << "  " 
388       << setw(8) << setprecision(4) << a4 << "  " 
389       << setw(8) << setprecision(4) << a5 << "  " 
390       << setw(8) << setprecision(4) << a6 << "  " << endl; 
391 }
392
393 //______________________________________________________________________________
394 void AliMUONGeometryTransformer::WriteModuleTransforms(ofstream& out) const
395 {
396 /// Write module transformations for all module transformers
397
398   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
399     AliMUONGeometryModuleTransformer* moduleTransformer 
400       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
401     const TGeoMatrix* transform 
402       = moduleTransformer->GetTransformation();    
403
404     // Write data on out
405     out << AliMUONGeometryModuleTransformer::GetModuleNamePrefix() << " " 
406         << setw(4) << moduleTransformer->GetModuleId();
407     
408     WriteTransform(out, transform);
409   }
410   out << endl;
411 }
412
413 //______________________________________________________________________________
414 void AliMUONGeometryTransformer::WriteDetElemTransforms(ofstream& out) const
415 {
416 /// Write detection element transformations for all detection elements in all 
417 /// module transformers
418
419   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
420     AliMUONGeometryModuleTransformer* moduleTransformer 
421       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
422     AliMpExMap* detElements = moduleTransformer->GetDetElementStore();    
423
424     for (Int_t j=0; j<detElements->GetSize(); j++) {
425       AliMUONGeometryDetElement* detElement
426         = (AliMUONGeometryDetElement*)detElements->GetObject(j);
427       const TGeoMatrix* transform 
428         = detElement->GetLocalTransformation(); 
429         
430       // Write data on out
431       out << AliMUONGeometryDetElement::GetDENamePrefix() << " " 
432           << setw(4) << detElement->GetId();
433      
434       WriteTransform(out, transform);
435     }
436     out << endl;                        
437   }     
438 }
439
440 //______________________________________________________________________________
441 TString AliMUONGeometryTransformer::GetModuleSymName(Int_t moduleId) const
442 {
443 /// Return the module symbolic name (use for alignment)
444
445   return "/" + fDetectorName + "/" 
446              + AliMUONGeometryModuleTransformer::GetModuleName(moduleId);
447 }  
448
449 //______________________________________________________________________________
450 TString AliMUONGeometryTransformer::GetDESymName(Int_t detElemId) const
451 {
452 /// Return the detection element symbolic name (used for alignment)
453
454   // Module Id
455   Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId);
456
457   return GetModuleSymName(moduleId) + "/" 
458          + AliMUONGeometryDetElement::GetDEName(detElemId);
459 }  
460
461 //
462 // public functions
463 //
464
465 //______________________________________________________________________________
466 Bool_t  
467 AliMUONGeometryTransformer::LoadGeometryData(const TString& fileName)
468 {
469 /// Read geometry data either from ASCII file with transformations or
470 /// from root geometry file (if fileName has ".root" extension)
471
472   CreateModules();
473
474   // Get file extension
475   std::string fileName2 = fileName.Data();
476   std::string rootExt = fileName2.substr(fileName2.size()-5, fileName2.size());
477   
478   if ( rootExt != ".root" ) 
479     return ReadTransformations(fileName);
480   else  { 
481     // Load root geometry
482     AliGeomManager::LoadGeometry(fileName.Data());
483     return LoadTransformations();
484   }  
485 }  
486
487 //______________________________________________________________________________
488 Bool_t  
489 AliMUONGeometryTransformer::LoadGeometryData()
490 {
491 /// Load geometry data from already loaded Root geometry using AliGeomManager
492
493   if ( ! AliGeomManager::GetGeometry() ) {
494     AliErrorStream() << "Geometry has not been loaded in AliGeomManager" << endl;
495     return false;
496   }    
497
498   CreateModules();
499
500   return LoadTransformations();
501 }  
502
503 //______________________________________________________________________________
504 Bool_t  
505 AliMUONGeometryTransformer::WriteTransformations(const TString& fileName) const
506 {
507 /// Write transformations into a file.
508 /// Return true, if writing finished correctly.
509
510   // No writing
511   // if builder is not associated with any geometry module
512   if (fModuleTransformers->GetEntriesFast() == 0) return false;
513
514   // File path
515   TString filePath = gSystem->Getenv("ALICE_ROOT");
516   filePath += "/MUON/data/";
517   filePath += fileName;
518   
519   // Open output file
520   ofstream out(filePath, ios::out);
521   if (!out) {
522     cerr << filePath << endl;   
523     AliError("File not found.");
524     return false;
525   }
526 #if !defined (__DECCXX)
527   out.setf(std::ios::fixed);
528 #endif
529   WriteModuleTransforms(out);
530   WriteDetElemTransforms(out);
531   
532   return true;
533 }  
534
535 //______________________________________________________________________________
536 Bool_t  
537 AliMUONGeometryTransformer::WriteMisAlignmentData(const TString& fileName) const
538 {
539 /// Write misalignment data into a file
540 /// Return true, if writing finished correctly.
541
542   // No writing
543   // if builder is not associated with any geometry module
544   if ( fModuleTransformers->GetEntriesFast() == 0 ) {
545     AliWarningStream() << "No geometry modules defined." << endl;
546     return false;
547   }  
548   
549   // No writing
550   // if builder has no mis-alignment data
551   if ( ! fMisAlignArray ) {
552     AliWarningStream() << "No mis-alignment data defined." << endl;
553     return false;
554   }  
555
556   // File path
557   TString filePath = gSystem->Getenv("ALICE_ROOT");
558   filePath += "/MUON/data/";
559   filePath += fileName;
560   
561   // Write mis-alignment data in the root file
562   TFile file(fileName.Data(), "RECREATE");
563   fMisAlignArray->Write();
564   file.Close();
565   
566   return true;
567 }  
568
569 //_____________________________________________________________________________
570 void AliMUONGeometryTransformer::AddModuleTransformer(
571                           AliMUONGeometryModuleTransformer* moduleTransformer)
572 {
573 /// Add the module transformer to the array
574
575   // Expand the size if not sufficient
576   Int_t moduleId = moduleTransformer->GetModuleId();
577   if (  moduleId >= fModuleTransformers->GetSize() )
578     fModuleTransformers->Expand(moduleId+1);
579
580   fModuleTransformers->AddAt(moduleTransformer, moduleId);
581 }
582
583 //_____________________________________________________________________________
584 void  AliMUONGeometryTransformer::AddMisAlignModule(Int_t moduleId, 
585                                               const TGeoHMatrix& matrix)
586 {
587 /// Build AliAlignObjMatrix with module ID, its volumePath
588 /// and the given delta transformation matrix                                         
589
590   if ( ! fMisAlignArray )
591     fMisAlignArray = new TClonesArray("AliAlignObjMatrix", 200);
592     
593   const AliMUONGeometryModuleTransformer* kTransformer 
594     = GetModuleTransformer(moduleId);
595   if ( ! kTransformer ) {
596     AliErrorStream() << "Module " << moduleId << " not found." << endl; 
597     return;
598   }   
599   
600   // Get unique align object ID
601   Int_t volId = AliGeomManager::LayerToVolUID(AliGeomManager::kMUON, moduleId); 
602
603   // Create mis align matrix
604   TClonesArray& refArray =*fMisAlignArray;
605   Int_t pos = fMisAlignArray->GetEntriesFast();
606   new (refArray[pos]) AliAlignObjMatrix(GetModuleSymName(moduleId), volId, 
607                                         const_cast<TGeoHMatrix&>(matrix),kTRUE);
608 }
609
610 //_____________________________________________________________________________
611 void  AliMUONGeometryTransformer::AddMisAlignDetElement(Int_t detElemId, 
612                                               const TGeoHMatrix& matrix)
613 {
614 /// Build AliAlignObjMatrix with detection element ID, its volumePath
615 /// and the given delta transformation matrix                                         
616
617   if ( ! fMisAlignArray )
618     fMisAlignArray = new TClonesArray("AliAlignObjMatrix", 200);
619
620   const AliMUONGeometryDetElement* kDetElement 
621     = GetDetElement(detElemId);
622
623   if ( ! kDetElement ) {
624     AliErrorStream() << "Det element " << detElemId << " not found." << endl; 
625     return;
626   }   
627   
628   // Get unique align object ID
629   Int_t volId = AliGeomManager::LayerToVolUID(AliGeomManager::kMUON, detElemId); 
630
631   // Create mis align matrix
632   TClonesArray& refArray =*fMisAlignArray;
633   Int_t pos = fMisAlignArray->GetEntriesFast();
634   new(refArray[pos]) AliAlignObjMatrix(GetDESymName(detElemId), volId, 
635                                        const_cast<TGeoHMatrix&>(matrix),kTRUE);
636 }
637
638 //______________________________________________________________________________
639 void AliMUONGeometryTransformer::CreateModules()
640 {
641 /// Create modules and their detection elements using info from mapping;
642 /// but do not fill matrices
643
644
645   // Loop over geometry module
646   for (Int_t moduleId = 0; moduleId < AliMpConstants::NofGeomModules(); ++moduleId ) {
647     
648     // Create geometry module transformer
649     AliMUONGeometryModuleTransformer* moduleTransformer
650       = new AliMUONGeometryModuleTransformer(moduleId);
651     AddModuleTransformer(moduleTransformer);
652   }   
653     
654   // Loop over detection elements
655   AliMpDEIterator it;
656   for ( it.First(); ! it.IsDone(); it.Next() ) {
657     
658     Int_t detElemId = it.CurrentDEId();
659     Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId);
660
661     // Get detection element store
662     AliMpExMap* detElements = 
663       GetModuleTransformer(moduleId)->GetDetElementStore();     
664
665     // Add detection element
666     AliMUONGeometryDetElement* detElement 
667       = new AliMUONGeometryDetElement(detElemId);
668     detElements->Add(detElemId, detElement);
669   }   
670 }
671
672 //_____________________________________________________________________________
673 void AliMUONGeometryTransformer::AddAlignableVolumes() const
674 {
675 /// Set symbolic names and matrices to alignable objects to TGeo
676
677   if ( ! gGeoManager ) {
678     AliWarning("TGeoManager not defined.");
679     return;
680   }  
681
682   // Modules 
683   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
684     AliMUONGeometryModuleTransformer* module 
685       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
686
687     // Set module symbolic name
688     TGeoPNEntry* pnEntry
689       = gGeoManager->SetAlignableEntry(GetModuleSymName(module->GetModuleId()),
690                                        module->GetVolumePath());
691     if ( ! pnEntry ) {
692       AliErrorStream() 
693         << "Volume path for geometry module "
694         << module->GetModuleId()
695         << " not found in geometry." << endl;
696     }
697     else {
698       // Set module matrix
699       pnEntry->SetMatrix(new TGeoHMatrix(*module->GetTransformation()));  
700        // the matrix will be deleted via TGeoManager  
701     }                                     
702
703     // Detection elements
704     AliMpExMap* detElements = module->GetDetElementStore();    
705
706     for (Int_t j=0; j<detElements->GetSize(); j++) {
707       AliMUONGeometryDetElement* detElement
708         = (AliMUONGeometryDetElement*)detElements->GetObject(j);
709         
710       // Set detection element symbolic name
711       TGeoPNEntry* pnEntry
712         = gGeoManager->SetAlignableEntry(GetDESymName(detElement->GetId()), 
713                                          detElement->GetVolumePath());
714       if ( ! pnEntry ) {
715         AliErrorStream() 
716           << "Volume path for detection element "
717           << detElement->GetId()
718           << " not found in geometry." << endl;
719       }
720       else {
721         // Set detection element matrix
722         pnEntry->SetMatrix(new TGeoHMatrix(*detElement->GetGlobalTransformation()));                                      
723          // the matrix will be deleted via TGeoManager 
724       }                                      
725     }  
726   }     
727 }            
728     
729 //_____________________________________________________________________________
730 TClonesArray* AliMUONGeometryTransformer::CreateZeroAlignmentData() const
731 {
732 /// Create array with zero alignment data
733                                
734   // Create array for zero-alignment objects
735   TClonesArray* array = new TClonesArray("AliAlignObjMatrix", 200);
736   TClonesArray& refArray =*array;
737   array->SetOwner(true);
738
739   // Identity matrix
740   TGeoHMatrix matrix;
741
742   // Modules 
743   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
744     AliMUONGeometryModuleTransformer* module 
745       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
746
747     Int_t moduleId = module->GetModuleId();
748   
749     // Align object ID
750     Int_t volId = AliGeomManager::LayerToVolUID(AliGeomManager::kMUON, moduleId); 
751
752     // Create mis align matrix
753     Int_t pos = array->GetEntriesFast();
754     new (refArray[pos]) AliAlignObjMatrix(GetModuleSymName(moduleId), volId, matrix, kTRUE);
755   }     
756
757   // Detection elements
758   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
759     AliMUONGeometryModuleTransformer* moduleTransformer 
760       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
761     AliMpExMap* detElements = moduleTransformer->GetDetElementStore();    
762
763     for (Int_t j=0; j<detElements->GetSize(); j++) {
764       AliMUONGeometryDetElement* detElement
765         = (AliMUONGeometryDetElement*)detElements->GetObject(j);
766         
767       Int_t detElemId = detElement->GetId();
768   
769       // Align object ID
770       Int_t volId = AliGeomManager::LayerToVolUID(AliGeomManager::kMUON, detElemId); 
771
772       // Create mis align matrix
773       Int_t pos = array->GetEntriesFast();
774       new (refArray[pos]) AliAlignObjMatrix(GetDESymName(detElemId), volId, matrix, kTRUE);
775     }
776   }
777   
778   return array;
779 }       
780
781 //_____________________________________________________________________________
782 void AliMUONGeometryTransformer::ClearMisAlignmentData()
783 {
784 /// Clear the array of misalignment data
785
786   if ( ! fMisAlignArray ) return;
787   
788   fMisAlignArray->Delete();
789 }  
790                                
791 //_____________________________________________________________________________
792 void AliMUONGeometryTransformer::Global2Local(Int_t detElemId,
793                  Float_t xg, Float_t yg, Float_t zg, 
794                  Float_t& xl, Float_t& yl, Float_t& zl) const
795 {
796 /// Transform point from the global reference frame (ALIC)
797 /// to the local reference frame of the detection element specified
798 /// by detElemId.
799
800   const AliMUONGeometryModuleTransformer* kTransformer 
801     = GetModuleTransformerByDEId(detElemId);
802   
803   if (kTransformer) 
804     kTransformer->Global2Local(detElemId, xg, yg, zg, xl, yl, zl);
805 }   
806                  
807 //_____________________________________________________________________________
808 void AliMUONGeometryTransformer::Global2Local(Int_t detElemId,
809                  Double_t xg, Double_t yg, Double_t zg, 
810                  Double_t& xl, Double_t& yl, Double_t& zl) const
811 {
812 /// Transform point from the global reference frame (ALIC)
813 /// to the local reference frame of the detection element specified
814 /// by detElemId.
815
816   const AliMUONGeometryModuleTransformer* kTransformer 
817     = GetModuleTransformerByDEId(detElemId);
818   
819   if (kTransformer) 
820     kTransformer->Global2Local(detElemId, xg, yg, zg, xl, yl, zl);
821 }   
822
823 //_____________________________________________________________________________
824 void AliMUONGeometryTransformer::Local2Global(Int_t detElemId,
825                  Float_t xl, Float_t yl, Float_t zl, 
826                  Float_t& xg, Float_t& yg, Float_t& zg) const
827 {                
828 /// Transform point from the local reference frame of the detection element 
829 /// specified by detElemId to the global reference frame (ALIC).
830
831   const AliMUONGeometryModuleTransformer* kTransformer 
832     = GetModuleTransformerByDEId(detElemId);
833     
834   if (kTransformer) 
835     kTransformer->Local2Global(detElemId, xl, yl, zl, xg, yg, zg);
836 }   
837
838 //_____________________________________________________________________________
839 void AliMUONGeometryTransformer::Local2Global(Int_t detElemId,
840                  Double_t xl, Double_t yl, Double_t zl, 
841                  Double_t& xg, Double_t& yg, Double_t& zg) const
842 {                
843 /// Transform point from the local reference frame of the detection element 
844 /// specified by detElemId to the global reference frame (ALIC).
845
846   const AliMUONGeometryModuleTransformer* kTransformer 
847     = GetModuleTransformerByDEId(detElemId);
848     
849   if (kTransformer) 
850     kTransformer->Local2Global(detElemId, xl, yl, zl, xg, yg, zg);
851 }   
852
853 //_____________________________________________________________________________
854 const AliMUONGeometryModuleTransformer* 
855 AliMUONGeometryTransformer::GetModuleTransformer(Int_t index, Bool_t warn) const
856 {
857 /// Return the geometry module transformer specified by index
858
859   return GetModuleTransformerNonConst(index, warn);
860 }    
861
862 //_____________________________________________________________________________
863 const AliMUONGeometryModuleTransformer* 
864 AliMUONGeometryTransformer::GetModuleTransformerByDEId(Int_t detElemId, 
865                                                        Bool_t warn) const
866 {
867 /// Return the geometry module transformer specified by detection element ID
868
869   // Get module index
870   Int_t index = AliMpDEManager::GetGeomModuleId(detElemId);
871
872   return GetModuleTransformer(index, warn);
873 }    
874
875 //_____________________________________________________________________________
876 const AliMUONGeometryDetElement* 
877 AliMUONGeometryTransformer::GetDetElement(Int_t detElemId, Bool_t warn) const
878 {
879 /// Return detection element with given detElemId                              
880
881   const AliMUONGeometryModuleTransformer* kTransformer 
882     = GetModuleTransformerByDEId(detElemId, warn);
883     
884   if (!kTransformer) return 0;
885     
886   return kTransformer->GetDetElement(detElemId, warn); 
887 }
888
889 //_____________________________________________________________________________
890 Bool_t  AliMUONGeometryTransformer::HasDE(Int_t detElemId) const
891 {
892 /// Return true if detection element with given detElemId is defined
893
894   const AliMUONGeometryModuleTransformer* kTransformer 
895     = GetModuleTransformerByDEId(detElemId, false);
896     
897   if (!kTransformer) return false;
898     
899   return ( kTransformer->GetDetElement(detElemId, false) != 0 );
900 }  
901     
902