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