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