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