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