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