]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONGeometryTransformer.cxx
Adding method CreateZeroAlignmentData (Ivana)
[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   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
378     AliMUONGeometryModuleTransformer* moduleTransformer 
379       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
380
381     // Module path
382     TString path = moduleTransformer->GetVolumePath();
383     
384     // Make physical node
385     TGeoPhysicalNode* moduleNode = tgeoManager->MakePhysicalNode(path);
386     if ( ! moduleNode ) {
387       AliErrorStream() 
388         << "Module id: " << moduleTransformer->GetModuleId()
389         << " volume path: " << path << " not found in geometry." << endl;
390         return false;
391     }    
392     
393     // Set matrix from physical node
394     TGeoHMatrix matrix = *moduleNode->GetMatrix();
395     moduleTransformer->SetTransformation(matrix);
396     
397     // Loop over detection elements
398     AliMUONGeometryStore* detElements 
399       = moduleTransformer->GetDetElementStore();    
400    
401     for (Int_t j=0; j<detElements->GetNofEntries(); j++) {
402       AliMUONGeometryDetElement* detElement
403         = (AliMUONGeometryDetElement*)detElements->GetEntry(j);
404
405       // Det element path
406       TString dePath = detElement->GetVolumePath();
407
408       // Make physical node
409       TGeoPhysicalNode* deNode = tgeoManager->MakePhysicalNode(dePath);
410       if ( ! deNode ) {
411         AliErrorStream() 
412           << "Det element id: " << detElement->GetId()
413           << " volume path: " << path << " not found in geometry." << endl;
414           return false;
415       } 
416          
417       // Set global matrix from physical node
418       TGeoHMatrix globalMatrix = *deNode->GetMatrix();
419       detElement->SetGlobalTransformation(globalMatrix);
420
421       // Set local matrix
422       TGeoHMatrix localMatrix = 
423         AliMUONGeometryBuilder::Multiply(
424            matrix.Inverse(), globalMatrix );
425       detElement->SetLocalTransformation(localMatrix);
426     }  
427   } 
428   return true;    
429 }  
430
431 //______________________________________________________________________________
432 Bool_t  
433 AliMUONGeometryTransformer::ReadVolPaths(const TString& fileName)
434 {
435 // Reads detection element volume paths from a file
436 // Returns true, if reading finished correctly.
437 // ---
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   ReadVolPaths(in);
453   return true;
454 }
455
456 //______________________________________________________________________________
457 Bool_t  
458 AliMUONGeometryTransformer::ReadTransformations(const TString& fileName)
459 {
460 // Reads transformations from a file
461 // Returns true, if reading finished correctly.
462 // ---
463
464   // File path
465   TString filePath = gSystem->Getenv("ALICE_ROOT");
466   filePath += "/MUON/data/";
467   filePath += fileName;
468   
469   // Open input file
470   ifstream in(filePath, ios::in);
471   if (!in) {
472     cerr << filePath << endl;   
473     AliFatal("File not found.");
474     return false;
475   }
476
477   TString key;
478   in >> key;
479   while ( !in.eof() ) {
480     if (key == TString("CH")) 
481       key = ReadModuleTransforms(in);
482     else if (key == TString("DE"))
483       key = ReadDetElemTransforms(in);
484     else {
485       AliFatal(Form("%s key not recognized",  key.Data()));
486       return false;
487     }
488   }     
489
490   return true;
491 }
492
493 //______________________________________________________________________________
494 Bool_t  
495 AliMUONGeometryTransformer::ReadTransformations2(const TString& fileName)
496 {
497 // Reads transformations from root geometry file
498 // Returns true, if reading finished correctly.
499 // ---
500
501   // File path
502   TString filePath = gSystem->Getenv("ALICE_ROOT");
503   filePath += "/MUON/data/";
504   filePath += fileName;
505   
506   // Load root geometry
507   TGeoManager* tgeoManager = TGeoManager::Import(fileName);
508
509   // Retrieve matrices
510   LoadTransforms(tgeoManager);     
511
512   return true;
513 }
514
515 //______________________________________________________________________________
516 void AliMUONGeometryTransformer::WriteTransform(ofstream& out,
517                                    const TGeoMatrix* transform) const
518 {
519 // Writes the transformations 
520 // ---
521
522   out << "   pos: ";
523   const Double_t* xyz = transform->GetTranslation();
524   out << setw(10) << setprecision(4) << xyz[0] << "  " 
525       << setw(10) << setprecision(4) << xyz[1] << "  " 
526       << setw(10) << setprecision(4) << xyz[2];
527
528   out << "   rot: ";
529   const Double_t* rm = transform->GetRotationMatrix();
530   TGeoRotation rotation;
531   rotation.SetMatrix(const_cast<Double_t*>(rm));
532   Double_t a1, a2, a3, a4, a5, a6;
533   rotation.GetAngles(a1, a2, a3, a4, a5, a6);
534       
535   out << setw(8) << setprecision(4) << a1 << "  " 
536       << setw(8) << setprecision(4) << a2 << "  " 
537       << setw(8) << setprecision(4) << a3 << "  " 
538       << setw(8) << setprecision(4) << a4 << "  " 
539       << setw(8) << setprecision(4) << a5 << "  " 
540       << setw(8) << setprecision(4) << a6 << "  " << endl; 
541 }
542
543 //______________________________________________________________________________
544 void AliMUONGeometryTransformer::WriteModuleVolPaths(ofstream& out) const
545 {
546 // Write modules volume paths
547
548   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
549     AliMUONGeometryModuleTransformer* moduleTransformer 
550       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
551
552     // Write data on out
553     out << "CH " 
554         << setw(4) << moduleTransformer->GetModuleId() << "    " 
555         << moduleTransformer->GetVolumePath() << endl;
556   }     
557   out << endl;                  
558 }
559
560 //______________________________________________________________________________
561 void AliMUONGeometryTransformer::WriteDetElemVolPaths(ofstream& out) const
562 {
563 // Write detection elements volume paths
564
565   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
566     AliMUONGeometryModuleTransformer* moduleTransformer 
567       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
568     AliMUONGeometryStore* detElements 
569       = moduleTransformer->GetDetElementStore();    
570
571     for (Int_t j=0; j<detElements->GetNofEntries(); j++) {
572       AliMUONGeometryDetElement* detElement
573         = (AliMUONGeometryDetElement*)detElements->GetEntry(j);
574         
575       // Write data on out
576       out << "DE " 
577           << setw(4) << detElement->GetId() << "    " 
578           << detElement->GetVolumePath() << endl;
579     }
580     out << endl;                        
581   }     
582 }
583
584 //______________________________________________________________________________
585 void AliMUONGeometryTransformer::WriteModuleTransforms(ofstream& out) const
586 {
587 // Write modules transformations
588
589   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
590     AliMUONGeometryModuleTransformer* moduleTransformer 
591       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
592     const TGeoMatrix* transform 
593       = moduleTransformer->GetTransformation();    
594
595     // Write data on out
596     out << "CH " 
597         << setw(4) << moduleTransformer->GetModuleId() + 1;
598     
599     WriteTransform(out, transform);
600   }
601   out << endl;
602 }
603
604 //______________________________________________________________________________
605 void AliMUONGeometryTransformer::WriteDetElemTransforms(ofstream& out) const
606 {
607 // Writes detection elements transformations
608 // ---
609
610   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
611     AliMUONGeometryModuleTransformer* moduleTransformer 
612       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
613     AliMUONGeometryStore* detElements 
614       = moduleTransformer->GetDetElementStore();    
615
616     for (Int_t j=0; j<detElements->GetNofEntries(); j++) {
617       AliMUONGeometryDetElement* detElement
618         = (AliMUONGeometryDetElement*)detElements->GetEntry(j);
619       const TGeoMatrix* transform 
620         = detElement->GetLocalTransformation(); 
621         
622       // Write data on out
623       out << "DE " << setw(4) << detElement->GetId();
624      
625       WriteTransform(out, transform);
626     }
627     out << endl;                        
628   }     
629 }
630
631 //
632 // public functions
633 //
634
635 //______________________________________________________________________________
636 Bool_t  
637 AliMUONGeometryTransformer::ReadGeometryData(
638                                 const TString& volPathFileName,
639                                 const TString& transformFileName)
640 {
641 /// Read geometry data from given files;
642 /// if transformFileName has ".root" extension, the transformations
643 /// are loaded from root geometry file, otherwise ASCII file
644 /// format is supposed
645
646   Bool_t result1 = ReadVolPaths(volPathFileName);
647
648   // Get file extension
649   std::string fileName = transformFileName.Data();
650   std::string rootExt = fileName.substr(fileName.size()-5, fileName.size());
651   Bool_t result2;
652   if ( rootExt != ".root" ) 
653     result2 = ReadTransformations(transformFileName);
654   else   
655     result2 = ReadTransformations2(transformFileName);
656   
657   return result1 && result2;
658 }  
659
660 //______________________________________________________________________________
661 Bool_t  
662 AliMUONGeometryTransformer::ReadGeometryData(
663                                 const TString& volPathFileName,
664                                 TGeoManager* tgeoManager)
665 {
666 /// Load geometry data from root geometry using defined
667 /// voluem paths from file
668
669   Bool_t result1 = ReadVolPaths(volPathFileName);
670
671   Bool_t result2 = LoadTransforms(tgeoManager);
672   
673   return result1 && result2;
674 }  
675
676 //______________________________________________________________________________
677 Bool_t  
678 AliMUONGeometryTransformer::WriteGeometryData(
679                                  const TString& volPathFileName,
680                                  const TString& transformFileName,
681                                  const TString& misalignFileName) const
682 {
683 /// Write geometry data into given files
684
685   Bool_t result1 = WriteVolumePaths(volPathFileName);
686   Bool_t result2 = WriteTransformations(transformFileName);
687   
688   Bool_t result3 = true;
689   if ( misalignFileName != "" )
690     result3 = WriteMisAlignmentData(misalignFileName);
691   
692   return result1 && result2 && result3;
693 }
694                                  
695 //______________________________________________________________________________
696 Bool_t  
697 AliMUONGeometryTransformer::WriteVolumePaths(const TString& fileName) const
698 {
699 // Writes volume paths for modules and detection element volumes into a file
700 // Returns true, if writing finished correctly.
701 // ---
702
703   // No writing
704   // if builder is not associated with any geometry module
705   if (fModuleTransformers->GetEntriesFast() == 0) return false;
706
707   // File path
708   TString filePath = gSystem->Getenv("ALICE_ROOT");
709   filePath += "/MUON/data/";
710   filePath += fileName;
711   
712   // Open output file
713   ofstream out(filePath, ios::out);
714   if (!out) {
715     cerr << filePath << endl;   
716     AliError("File not found.");
717     return false;
718   }
719 #if !defined (__DECCXX)
720   out.setf(std::ios::fixed);
721 #endif
722   WriteModuleVolPaths(out);
723   WriteDetElemVolPaths(out);
724   
725   return true;
726 }  
727
728 //______________________________________________________________________________
729 Bool_t  
730 AliMUONGeometryTransformer::WriteTransformations(const TString& fileName) const
731 {
732 // Writes transformations into a file
733 // Returns true, if writing finished correctly.
734 // ---
735
736   // No writing
737   // if builder is not associated with any geometry module
738   if (fModuleTransformers->GetEntriesFast() == 0) return false;
739
740   // File path
741   TString filePath = gSystem->Getenv("ALICE_ROOT");
742   filePath += "/MUON/data/";
743   filePath += fileName;
744   
745   // Open output file
746   ofstream out(filePath, ios::out);
747   if (!out) {
748     cerr << filePath << endl;   
749     AliError("File not found.");
750     return false;
751   }
752 #if !defined (__DECCXX)
753   out.setf(std::ios::fixed);
754 #endif
755   WriteModuleTransforms(out);
756   WriteDetElemTransforms(out);
757   
758   return true;
759 }  
760
761 //______________________________________________________________________________
762 Bool_t  
763 AliMUONGeometryTransformer::WriteMisAlignmentData(const TString& fileName) const
764 {
765 // Writes misalignment data into a file
766 // Returns true, if writing finished correctly.
767 // ---
768
769   // No writing
770   // if builder is not associated with any geometry module
771   if ( fModuleTransformers->GetEntriesFast() == 0 ) {
772     AliWarningStream() << "No geometry modules defined." << endl;
773     return false;
774   }  
775   
776   // No writing
777   // if builder has no mis-alignment data
778   if ( ! fMisAlignArray ) {
779     AliWarningStream() << "No mis-alignment data defined." << endl;
780     return false;
781   }  
782
783   // File path
784   TString filePath = gSystem->Getenv("ALICE_ROOT");
785   filePath += "/MUON/data/";
786   filePath += fileName;
787   
788   // Write mis-alignment data in the root file
789   TFile file(fileName.Data(), "RECREATE");
790   fMisAlignArray->Write();
791   file.Close();
792   
793   return true;
794 }  
795
796 //_____________________________________________________________________________
797 void AliMUONGeometryTransformer::AddModuleTransformer(
798                           AliMUONGeometryModuleTransformer* moduleTransformer)
799 {
800 /// Add the geometrymodule to the array
801
802   fModuleTransformers->AddAt(moduleTransformer, 
803                              moduleTransformer->GetModuleId());
804 }
805
806 //_____________________________________________________________________________
807 void  AliMUONGeometryTransformer::AddMisAlignModule(Int_t moduleId, 
808                                               const TGeoHMatrix& matrix)
809 {
810 /// Build AliAlignObjMatrix with module ID, its volumePaths
811 /// and the given delta transformation matrix                                         
812
813   if ( ! fMisAlignArray )
814     fMisAlignArray = new TClonesArray("AliAlignObjMatrix", 200);
815     
816   const AliMUONGeometryModuleTransformer* kTransformer 
817     = GetModuleTransformer(moduleId);
818   if ( ! kTransformer ) {
819     AliErrorStream() << "Module " << moduleId << " not found." << endl; 
820     return;
821   }   
822   
823   // Get path  
824   TString path = kTransformer->GetVolumePath(); 
825   
826   // Get unique align object ID
827   Int_t volId = AliAlignObj::LayerToVolUID(AliAlignObj::kMUON, moduleId); 
828
829   // Create mis align matrix
830   TClonesArray& refArray =*fMisAlignArray;
831   Int_t pos = fMisAlignArray->GetEntriesFast();
832   new (refArray[pos]) AliAlignObjMatrix(path.Data(), volId, 
833                               const_cast<TGeoHMatrix&>(matrix));
834 }
835
836 //_____________________________________________________________________________
837 void  AliMUONGeometryTransformer::AddMisAlignDetElement(Int_t detElemId, 
838                                               const TGeoHMatrix& matrix)
839 {
840 /// Build AliAlignObjMatrix with detection element ID, its volumePaths
841 /// and the given delta transformation matrix                                         
842
843   if ( ! fMisAlignArray )
844     fMisAlignArray = new TClonesArray("AliAlignObjMatrix", 200);
845
846   const AliMUONGeometryDetElement* kDetElement 
847     = GetDetElement(detElemId);
848
849   if ( ! kDetElement ) {
850     AliErrorStream() << "Det element " << detElemId << " not found." << endl; 
851     return;
852   }   
853   
854   // Get path  
855   TString path = kDetElement->GetVolumePath(); 
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(path.Data(), volId, 
864                               const_cast<TGeoHMatrix&>(matrix));
865 }
866
867 //_____________________________________________________________________________
868 TClonesArray* AliMUONGeometryTransformer::CreateZeroAlignmentData() const
869 {
870 /// Create array with zero alignment data
871                                
872   // Create array for zero-alignment objects
873   TClonesArray* array = new TClonesArray("AliAlignObjMatrix", 200);
874   TClonesArray& refArray =*array;
875   array->SetOwner(true);
876
877   // Identity matrix
878   TGeoHMatrix matrix;
879
880   // Modules 
881   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
882     AliMUONGeometryModuleTransformer* module 
883       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
884
885     TString path = module->GetVolumePath(); 
886     Int_t moduleId = module->GetModuleId();
887   
888     // Align object ID
889     Int_t volId = AliAlignObj::LayerToVolUID(AliAlignObj::kMUON, moduleId); 
890
891     // Create mis align matrix
892     Int_t pos = array->GetEntriesFast();
893     new (refArray[pos]) AliAlignObjMatrix(path.Data(), volId, matrix);
894   }     
895
896   // Detection elements
897   for (Int_t i=0; i<fModuleTransformers->GetEntriesFast(); i++) {
898     AliMUONGeometryModuleTransformer* moduleTransformer 
899       = (AliMUONGeometryModuleTransformer*)fModuleTransformers->At(i);
900     AliMUONGeometryStore* detElements 
901       = moduleTransformer->GetDetElementStore();    
902
903     for (Int_t j=0; j<detElements->GetNofEntries(); j++) {
904       AliMUONGeometryDetElement* detElement
905         = (AliMUONGeometryDetElement*)detElements->GetEntry(j);
906         
907       TString path = detElement->GetVolumePath(); 
908       Int_t detElemId = detElement->GetId();
909   
910       // Align object ID
911       Int_t volId = AliAlignObj::LayerToVolUID(AliAlignObj::kMUON, detElemId); 
912
913       // Create mis align matrix
914       Int_t pos = array->GetEntriesFast();
915       new (refArray[pos]) AliAlignObjMatrix(path.Data(), volId, matrix);
916     }
917   }
918   
919   return array;
920 }       
921
922 //_____________________________________________________________________________
923 void AliMUONGeometryTransformer::Global2Local(Int_t detElemId,
924                  Float_t xg, Float_t yg, Float_t zg, 
925                  Float_t& xl, Float_t& yl, Float_t& zl) const
926 {
927 /// Transform point from the global reference frame (ALIC)
928 /// to the local reference frame of the detection element specified
929 /// by detElemId.
930
931   const AliMUONGeometryModuleTransformer* kTransformer 
932     = GetModuleTransformerByDEId(detElemId);
933   
934   if (kTransformer) 
935     kTransformer->Global2Local(detElemId, xg, yg, zg, xl, yl, zl);
936 }   
937                  
938 //_____________________________________________________________________________
939 void AliMUONGeometryTransformer::Global2Local(Int_t detElemId,
940                  Double_t xg, Double_t yg, Double_t zg, 
941                  Double_t& xl, Double_t& yl, Double_t& zl) const
942 {
943 /// Transform point from the global reference frame (ALIC)
944 /// to the local reference frame of the detection element specified
945 /// by detElemId.
946
947   const AliMUONGeometryModuleTransformer* kTransformer 
948     = GetModuleTransformerByDEId(detElemId);
949   
950   if (kTransformer) 
951     kTransformer->Global2Local(detElemId, xg, yg, zg, xl, yl, zl);
952 }   
953
954 //_____________________________________________________________________________
955 void AliMUONGeometryTransformer::Local2Global(Int_t detElemId,
956                  Float_t xl, Float_t yl, Float_t zl, 
957                  Float_t& xg, Float_t& yg, Float_t& zg) const
958 {                
959 /// Transform point from the local reference frame of the detection element 
960 /// specified by detElemId to the global reference frame (ALIC).
961
962   const AliMUONGeometryModuleTransformer* kTransformer 
963     = GetModuleTransformerByDEId(detElemId);
964     
965   if (kTransformer) 
966     kTransformer->Local2Global(detElemId, xl, yl, zl, xg, yg, zg);
967 }   
968
969 //_____________________________________________________________________________
970 void AliMUONGeometryTransformer::Local2Global(Int_t detElemId,
971                  Double_t xl, Double_t yl, Double_t zl, 
972                  Double_t& xg, Double_t& yg, Double_t& zg) const
973 {                
974 /// Transform point from the local reference frame of the detection element 
975 /// specified by detElemId to the global reference frame (ALIC).
976
977   const AliMUONGeometryModuleTransformer* kTransformer 
978     = GetModuleTransformerByDEId(detElemId);
979     
980   if (kTransformer) 
981     kTransformer->Local2Global(detElemId, xl, yl, zl, xg, yg, zg);
982 }   
983
984 //_____________________________________________________________________________
985 const AliMUONGeometryModuleTransformer* 
986 AliMUONGeometryTransformer::GetModuleTransformer(Int_t index, Bool_t warn) const
987 {
988 /// Return the geometry module specified by index
989
990   return GetModuleTransformerNonConst(index, warn);
991 }    
992
993 //_____________________________________________________________________________
994 const AliMUONGeometryModuleTransformer* 
995 AliMUONGeometryTransformer::GetModuleTransformerByDEId(Int_t detElemId, 
996                                                        Bool_t warn) const
997 {
998 /// Return the geometry module specified by index
999
1000   // Get module index
1001   Int_t index = AliMUONGeometryStore::GetModuleId(detElemId);
1002
1003   return GetModuleTransformer(index, warn);
1004 }    
1005
1006 //_____________________________________________________________________________
1007 const AliMUONGeometryDetElement* 
1008 AliMUONGeometryTransformer::GetDetElement(Int_t detElemId, Bool_t warn) const
1009 {
1010 /// Return detection ellemnt with given detElemId                              
1011
1012   const AliMUONGeometryModuleTransformer* kTransformer 
1013     = GetModuleTransformerByDEId(detElemId, warn);
1014     
1015   if (!kTransformer) return 0;
1016     
1017   return kTransformer->GetDetElement(detElemId, warn); 
1018 }
1019
1020 //_____________________________________________________________________________
1021 Bool_t  AliMUONGeometryTransformer::HasDE(Int_t detElemId) const
1022 {
1023 /// Return true if detection element with given detElemId is defined
1024
1025   const AliMUONGeometryModuleTransformer* kTransformer 
1026     = GetModuleTransformerByDEId(detElemId, false);
1027     
1028   if (!kTransformer) return false;
1029     
1030   return ( kTransformer->GetDetElement(detElemId, false) != 0 );
1031 }  
1032     
1033