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