]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONGeometryTransformer.cxx
- Updated for replacement of AliMUONGeometryStore with AliMpExMap
[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
623   const AliMUONGeometryDetElement* kDetElement 
624     = GetDetElement(detElemId);
625   if ( ! kDetElement ) {
626     AliErrorStream() << "Det element " << detElemId << " not found." << endl; 
627     return "";
628   }   
629   
630   // Module Id
631   Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId);
632
633   return GetModuleSymName(moduleId) + "/" + kDetElement->GetDEName();
634 }  
635
636 //
637 // public functions
638 //
639
640 //______________________________________________________________________________
641 Bool_t  
642 AliMUONGeometryTransformer::ReadGeometryData(
643                                 const TString& volPathFileName,
644                                 const TString& transformFileName)
645 {
646 /// Read geometry data from given files;
647 /// if transformFileName has ".root" extension, the transformations
648 /// are loaded from root geometry file, otherwise ASCII file
649 /// format is supposed
650
651   Bool_t result1 = ReadVolPaths(volPathFileName);
652
653   // Get file extension
654   std::string fileName = transformFileName.Data();
655   std::string rootExt = fileName.substr(fileName.size()-5, fileName.size());
656   Bool_t result2;
657   if ( rootExt != ".root" ) 
658     result2 = ReadTransformations(transformFileName);
659   else   
660     result2 = ReadTransformations2(transformFileName);
661   
662   return result1 && result2;
663 }  
664
665 //______________________________________________________________________________
666 Bool_t  
667 AliMUONGeometryTransformer::ReadGeometryData(
668                                 const TString& volPathFileName,
669                                 TGeoManager* tgeoManager)
670 {
671 /// Load geometry data from root geometry using defined
672 /// volume paths from file
673
674   Bool_t result1 = ReadVolPaths(volPathFileName);
675
676   Bool_t result2 = LoadTransforms(tgeoManager);
677   
678   return result1 && result2;
679 }  
680
681 //______________________________________________________________________________
682 Bool_t  
683 AliMUONGeometryTransformer::WriteGeometryData(
684                                  const TString& volPathFileName,
685                                  const TString& transformFileName,
686                                  const TString& misalignFileName) const
687 {
688 /// Write geometry data into given files
689
690   Bool_t result1 = WriteVolumePaths(volPathFileName);
691   Bool_t result2 = WriteTransformations(transformFileName);
692   
693   Bool_t result3 = true;
694   if ( misalignFileName != "" )
695     result3 = WriteMisAlignmentData(misalignFileName);
696   
697   return result1 && result2 && result3;
698 }
699                                  
700 //______________________________________________________________________________
701 Bool_t  
702 AliMUONGeometryTransformer::WriteVolumePaths(const TString& fileName) const
703 {
704 /// Write volume paths for modules and detection element volumes into a file.
705 /// Return true, if writing finished correctly.
706
707   // No writing
708   // if builder is not associated with any geometry module
709   if (fModuleTransformers->GetEntriesFast() == 0) return false;
710
711   // File path
712   TString filePath = gSystem->Getenv("ALICE_ROOT");
713   filePath += "/MUON/data/";
714   filePath += fileName;
715   
716   // Open output file
717   ofstream out(filePath, ios::out);
718   if (!out) {
719     cerr << filePath << endl;   
720     AliError("File not found.");
721     return false;
722   }
723 #if !defined (__DECCXX)
724   out.setf(std::ios::fixed);
725 #endif
726   WriteModuleVolPaths(out);
727   WriteDetElemVolPaths(out);
728   
729   return true;
730 }  
731
732 //______________________________________________________________________________
733 Bool_t  
734 AliMUONGeometryTransformer::WriteTransformations(const TString& fileName) const
735 {
736 /// Write transformations into a file.
737 /// Return true, if writing finished correctly.
738
739   // No writing
740   // if builder is not associated with any geometry module
741   if (fModuleTransformers->GetEntriesFast() == 0) return false;
742
743   // File path
744   TString filePath = gSystem->Getenv("ALICE_ROOT");
745   filePath += "/MUON/data/";
746   filePath += fileName;
747   
748   // Open output file
749   ofstream out(filePath, ios::out);
750   if (!out) {
751     cerr << filePath << endl;   
752     AliError("File not found.");
753     return false;
754   }
755 #if !defined (__DECCXX)
756   out.setf(std::ios::fixed);
757 #endif
758   WriteModuleTransforms(out);
759   WriteDetElemTransforms(out);
760   
761   return true;
762 }  
763
764 //______________________________________________________________________________
765 Bool_t  
766 AliMUONGeometryTransformer::WriteMisAlignmentData(const TString& fileName) const
767 {
768 /// Write misalignment data into a file
769 /// Return true, if writing finished correctly.
770
771   // No writing
772   // if builder is not associated with any geometry module
773   if ( fModuleTransformers->GetEntriesFast() == 0 ) {
774     AliWarningStream() << "No geometry modules defined." << endl;
775     return false;
776   }  
777   
778   // No writing
779   // if builder has no mis-alignment data
780   if ( ! fMisAlignArray ) {
781     AliWarningStream() << "No mis-alignment data defined." << endl;
782     return false;
783   }  
784
785   // File path
786   TString filePath = gSystem->Getenv("ALICE_ROOT");
787   filePath += "/MUON/data/";
788   filePath += fileName;
789   
790   // Write mis-alignment data in the root file
791   TFile file(fileName.Data(), "RECREATE");
792   fMisAlignArray->Write();
793   file.Close();
794   
795   return true;
796 }  
797
798 //_____________________________________________________________________________
799 void AliMUONGeometryTransformer::AddModuleTransformer(
800                           AliMUONGeometryModuleTransformer* moduleTransformer)
801 {
802 /// Add the module transformer to the array
803
804   // Expand the size if not sufficient
805   Int_t moduleId = moduleTransformer->GetModuleId();
806   if (  moduleId >= fModuleTransformers->GetSize() )
807     fModuleTransformers->Expand(moduleId+1);
808
809   fModuleTransformers->AddAt(moduleTransformer, moduleId);
810 }
811
812 //_____________________________________________________________________________
813 void  AliMUONGeometryTransformer::AddMisAlignModule(Int_t moduleId, 
814                                               const TGeoHMatrix& matrix)
815 {
816 /// Build AliAlignObjMatrix with module ID, its volumePath
817 /// and the given delta transformation matrix                                         
818
819   if ( ! fMisAlignArray )
820     fMisAlignArray = new TClonesArray("AliAlignObjMatrix", 200);
821     
822   const AliMUONGeometryModuleTransformer* kTransformer 
823     = GetModuleTransformer(moduleId);
824   if ( ! kTransformer ) {
825     AliErrorStream() << "Module " << moduleId << " not found." << endl; 
826     return;
827   }   
828   
829   // Get unique align object ID
830   Int_t volId = AliAlignObj::LayerToVolUID(AliAlignObj::kMUON, moduleId); 
831
832   // Create mis align matrix
833   TClonesArray& refArray =*fMisAlignArray;
834   Int_t pos = fMisAlignArray->GetEntriesFast();
835   new (refArray[pos]) AliAlignObjMatrix(GetModuleSymName(moduleId), volId, 
836                                         const_cast<TGeoHMatrix&>(matrix),kTRUE);
837 }
838
839 //_____________________________________________________________________________
840 void  AliMUONGeometryTransformer::AddMisAlignDetElement(Int_t detElemId, 
841                                               const TGeoHMatrix& matrix)
842 {
843 /// Build AliAlignObjMatrix with detection element ID, its volumePath
844 /// and the given delta transformation matrix                                         
845
846   if ( ! fMisAlignArray )
847     fMisAlignArray = new TClonesArray("AliAlignObjMatrix", 200);
848
849   const AliMUONGeometryDetElement* kDetElement 
850     = GetDetElement(detElemId);
851
852   if ( ! kDetElement ) {
853     AliErrorStream() << "Det element " << detElemId << " not found." << endl; 
854     return;
855   }   
856   
857   // Get unique align object ID
858   Int_t volId = AliAlignObj::LayerToVolUID(AliAlignObj::kMUON, detElemId); 
859
860   // Create mis align matrix
861   TClonesArray& refArray =*fMisAlignArray;
862   Int_t pos = fMisAlignArray->GetEntriesFast();
863   new(refArray[pos]) AliAlignObjMatrix(GetDESymName(detElemId), volId, 
864                                        const_cast<TGeoHMatrix&>(matrix),kTRUE);
865 }
866
867 //_____________________________________________________________________________
868 void AliMUONGeometryTransformer::AddAlignableVolumes() const
869 {
870 /// Set symbolic names to alignable objects to TGeo
871
872   if ( ! gGeoManager ) {
873     AliWarning("TGeoManager not defined.");
874     return;
875   }  
876
877   // Modules 
878   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
879     AliMUONGeometryModuleTransformer* module 
880       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
881
882     // Set module symbolic name
883     gGeoManager->SetAlignableEntry(GetModuleSymName(module->GetModuleId()), 
884                                    module->GetVolumePath());
885     //cout << "Module sym name: " << GetModuleSymName(module->GetModuleId()) 
886     //     << "  volPath: " << module->GetVolumePath() << endl;
887
888     // Detection elements
889     AliMpExMap* detElements = module->GetDetElementStore();    
890
891     for (Int_t j=0; j<detElements->GetSize(); j++) {
892       AliMUONGeometryDetElement* detElement
893         = (AliMUONGeometryDetElement*)detElements->GetObject(j);
894         
895       // Set detection element symbolic name
896       gGeoManager->SetAlignableEntry(GetDESymName(detElement->GetId()), 
897                                      detElement->GetVolumePath());
898       //cout << "DE name: " << GetDESymName(detElement->GetId()) 
899       //     << "  volPath: " << detElement->GetVolumePath() << endl;
900     }  
901   }     
902 }            
903     
904 //_____________________________________________________________________________
905 TClonesArray* AliMUONGeometryTransformer::CreateZeroAlignmentData() const
906 {
907 /// Create array with zero alignment data
908                                
909   // Create array for zero-alignment objects
910   TClonesArray* array = new TClonesArray("AliAlignObjMatrix", 200);
911   TClonesArray& refArray =*array;
912   array->SetOwner(true);
913
914   // Identity matrix
915   TGeoHMatrix matrix;
916
917   // Modules 
918   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
919     AliMUONGeometryModuleTransformer* module 
920       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
921
922     Int_t moduleId = module->GetModuleId();
923   
924     // Align object ID
925     Int_t volId = AliAlignObj::LayerToVolUID(AliAlignObj::kMUON, moduleId); 
926
927     // Create mis align matrix
928     Int_t pos = array->GetEntriesFast();
929     new (refArray[pos]) AliAlignObjMatrix(GetModuleSymName(moduleId), volId, matrix, kTRUE);
930   }     
931
932   // Detection elements
933   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
934     AliMUONGeometryModuleTransformer* moduleTransformer 
935       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
936     AliMpExMap* detElements = moduleTransformer->GetDetElementStore();    
937
938     for (Int_t j=0; j<detElements->GetSize(); j++) {
939       AliMUONGeometryDetElement* detElement
940         = (AliMUONGeometryDetElement*)detElements->GetObject(j);
941         
942       Int_t detElemId = detElement->GetId();
943   
944       // Align object ID
945       Int_t volId = AliAlignObj::LayerToVolUID(AliAlignObj::kMUON, detElemId); 
946
947       // Create mis align matrix
948       Int_t pos = array->GetEntriesFast();
949       new (refArray[pos]) AliAlignObjMatrix(GetDESymName(detElemId), volId, matrix, kTRUE);
950     }
951   }
952   
953   return array;
954 }       
955
956 //_____________________________________________________________________________
957 void AliMUONGeometryTransformer::Global2Local(Int_t detElemId,
958                  Float_t xg, Float_t yg, Float_t zg, 
959                  Float_t& xl, Float_t& yl, Float_t& zl) const
960 {
961 /// Transform point from the global reference frame (ALIC)
962 /// to the local reference frame of the detection element specified
963 /// by detElemId.
964
965   const AliMUONGeometryModuleTransformer* kTransformer 
966     = GetModuleTransformerByDEId(detElemId);
967   
968   if (kTransformer) 
969     kTransformer->Global2Local(detElemId, xg, yg, zg, xl, yl, zl);
970 }   
971                  
972 //_____________________________________________________________________________
973 void AliMUONGeometryTransformer::Global2Local(Int_t detElemId,
974                  Double_t xg, Double_t yg, Double_t zg, 
975                  Double_t& xl, Double_t& yl, Double_t& zl) const
976 {
977 /// Transform point from the global reference frame (ALIC)
978 /// to the local reference frame of the detection element specified
979 /// by detElemId.
980
981   const AliMUONGeometryModuleTransformer* kTransformer 
982     = GetModuleTransformerByDEId(detElemId);
983   
984   if (kTransformer) 
985     kTransformer->Global2Local(detElemId, xg, yg, zg, xl, yl, zl);
986 }   
987
988 //_____________________________________________________________________________
989 void AliMUONGeometryTransformer::Local2Global(Int_t detElemId,
990                  Float_t xl, Float_t yl, Float_t zl, 
991                  Float_t& xg, Float_t& yg, Float_t& zg) const
992 {                
993 /// Transform point from the local reference frame of the detection element 
994 /// specified by detElemId to the global reference frame (ALIC).
995
996   const AliMUONGeometryModuleTransformer* kTransformer 
997     = GetModuleTransformerByDEId(detElemId);
998     
999   if (kTransformer) 
1000     kTransformer->Local2Global(detElemId, xl, yl, zl, xg, yg, zg);
1001 }   
1002
1003 //_____________________________________________________________________________
1004 void AliMUONGeometryTransformer::Local2Global(Int_t detElemId,
1005                  Double_t xl, Double_t yl, Double_t zl, 
1006                  Double_t& xg, Double_t& yg, Double_t& zg) const
1007 {                
1008 /// Transform point from the local reference frame of the detection element 
1009 /// specified by detElemId to the global reference frame (ALIC).
1010
1011   const AliMUONGeometryModuleTransformer* kTransformer 
1012     = GetModuleTransformerByDEId(detElemId);
1013     
1014   if (kTransformer) 
1015     kTransformer->Local2Global(detElemId, xl, yl, zl, xg, yg, zg);
1016 }   
1017
1018 //_____________________________________________________________________________
1019 const AliMUONGeometryModuleTransformer* 
1020 AliMUONGeometryTransformer::GetModuleTransformer(Int_t index, Bool_t warn) const
1021 {
1022 /// Return the geometry module transformer specified by index
1023
1024   return GetModuleTransformerNonConst(index, warn);
1025 }    
1026
1027 //_____________________________________________________________________________
1028 const AliMUONGeometryModuleTransformer* 
1029 AliMUONGeometryTransformer::GetModuleTransformerByDEId(Int_t detElemId, 
1030                                                        Bool_t warn) const
1031 {
1032 /// Return the geometry module transformer specified by detection element ID
1033
1034   // Get module index
1035   Int_t index = AliMpDEManager::GetGeomModuleId(detElemId);
1036
1037   return GetModuleTransformer(index, warn);
1038 }    
1039
1040 //_____________________________________________________________________________
1041 const AliMUONGeometryDetElement* 
1042 AliMUONGeometryTransformer::GetDetElement(Int_t detElemId, Bool_t warn) const
1043 {
1044 /// Return detection element with given detElemId                              
1045
1046   const AliMUONGeometryModuleTransformer* kTransformer 
1047     = GetModuleTransformerByDEId(detElemId, warn);
1048     
1049   if (!kTransformer) return 0;
1050     
1051   return kTransformer->GetDetElement(detElemId, warn); 
1052 }
1053
1054 //_____________________________________________________________________________
1055 Bool_t  AliMUONGeometryTransformer::HasDE(Int_t detElemId) const
1056 {
1057 /// Return true if detection element with given detElemId is defined
1058
1059   const AliMUONGeometryModuleTransformer* kTransformer 
1060     = GetModuleTransformerByDEId(detElemId, false);
1061     
1062   if (!kTransformer) return false;
1063     
1064   return ( kTransformer->GetDetElement(detElemId, false) != 0 );
1065 }  
1066     
1067