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