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