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