]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONGeometryBuilder.cxx
disable global transformation for trigger & transform.dat files in new ALICE coordina...
[u/mrichter/AliRoot.git] / MUON / AliMUONGeometryBuilder.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 // Class AliMUONGeometryBuilder
19 // ----------------------------
20 // Manager class for geometry construction via geometry builders.
21 //
22 // Author: Ivana Hrivnacova, IPN Orsay
23
24 #include <TObjArray.h>
25 #include <TVirtualMC.h>
26
27 #include "AliMUONGeometryBuilder.h"
28 #include "AliMUONVGeometryBuilder.h"    
29 #include "AliMUONGeometryModule.h"      
30 #include "AliMUONGeometryEnvelope.h"    
31 #include "AliMUONGeometryEnvelopeStore.h"
32 #include "AliMUONGeometryDetElement.h"
33 #include "AliMUONGeometryStore.h"
34 #include "AliMUONGeometryConstituent.h" 
35 #include "AliModule.h"
36 #include "AliLog.h"
37 #include "AliRun.h"
38
39
40 ClassImp(AliMUONGeometryBuilder)
41  
42 // static functions
43
44 //______________________________________________________________________________
45 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1, 
46                                              const TGeoMatrix& m2)
47 {
48 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
49
50   if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
51   
52   if (m1.IsIdentity()) return m2;
53   
54   if (m2.IsIdentity()) return m1;
55   
56   return m1 * m2;
57 }
58
59 //______________________________________________________________________________
60 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1, 
61                                              const TGeoMatrix& m2,
62                                              const TGeoMatrix& m3)
63 {                                            
64 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
65
66   if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())  
67     return TGeoHMatrix();
68   
69   if (m1.IsIdentity()) return Multiply(m2, m3);
70   
71   if (m2.IsIdentity()) return Multiply(m1, m3);
72   
73   if (m3.IsIdentity()) return Multiply(m1, m2);
74   
75   return m1 * m2 * m3;
76 }
77
78 //______________________________________________________________________________
79 TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1, 
80                                              const TGeoMatrix& m2,
81                                              const TGeoMatrix& m3,
82                                              const TGeoMatrix& m4)
83 {                                            
84 /// Temporary fix for problem with matrix multiplication in Root 5.02/00
85
86   if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())  
87     return TGeoHMatrix();
88   
89   if (m1.IsIdentity()) return Multiply(m2, m3, m4);
90   
91   if (m2.IsIdentity()) return Multiply(m1, m3, m4);
92   
93   if (m3.IsIdentity()) return Multiply(m1, m2, m4);
94   
95   if (m4.IsIdentity()) return Multiply(m1, m2, m3);
96   
97   return m1 * m2 * m3 * m4;
98 }
99
100 //______________________________________________________________________________
101 AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
102   : TObject(),
103     fModule(module),
104     fAlign(false),
105     fGlobalTransformation(), 
106     fGeometryBuilders(0)
107 {
108 /// Standard constructor
109
110   fGeometryBuilders = new TObjArray(100);
111 }
112
113 //______________________________________________________________________________
114 AliMUONGeometryBuilder::AliMUONGeometryBuilder() 
115   : TObject(),
116     fModule(0),
117     fAlign(false),
118     fGlobalTransformation(),
119     fGeometryBuilders(0)
120 {
121 /// Default constructor
122
123
124 //______________________________________________________________________________
125 AliMUONGeometryBuilder::AliMUONGeometryBuilder(const AliMUONGeometryBuilder& right) 
126   : TObject(right) 
127 {  
128 /// Copy constructor (not implemented)
129
130   AliFatal("Copy constructor not provided.");
131 }
132
133 //______________________________________________________________________________
134 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
135 {
136 /// Destructor
137   if (fGeometryBuilders){
138     fGeometryBuilders->Delete();
139     delete fGeometryBuilders;
140   }
141 }
142
143 //______________________________________________________________________________
144 AliMUONGeometryBuilder& 
145 AliMUONGeometryBuilder::operator=(const AliMUONGeometryBuilder& right)
146 {
147 /// Assignement operator (not implemented)
148
149   // check assignement to self
150   if (this == &right) return *this;
151
152   AliFatal("Assignement operator not provided.");
153     
154   return *this;  
155 }    
156
157 //
158 // private functions
159 //
160
161 //______________________________________________________________________________
162 void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName, 
163                             Int_t copyNo, const TGeoHMatrix& matrix, 
164                             Int_t npar, Double_t* param, const char* only) const
165 {
166 /// Place the volume specified by name with the given transformation matrix
167
168   // Do not apply global transformation 
169   // if mother volume was already placed in 
170   // the new system of coordinates (that is MUON in negative Z)
171   // (as it is applied on the mother volume)
172   TGeoHMatrix transform(matrix);
173   if (mName == TString("DDIP"))
174     transform = fGlobalTransformation.Inverse() * transform;
175      
176   // Decompose transformation
177   const Double_t* xyz = transform.GetTranslation();
178   const Double_t* rm = transform.GetRotationMatrix();
179         
180   //cout << "Got translation: "
181   //     << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
182         
183   //cout << "Got rotation: "
184   //     << rm[0] << " " << rm[1] << " " << rm[2] << endl
185   //     << rm[3] << " " << rm[4] << " " << rm[5] << endl
186   //     << rm[6] << " " << rm[7] << " " << rm[8] << endl;
187
188   // Check for presence of rotation
189   // (will be nice to be available in TGeo)
190   const Double_t kTolerance = 1e-04;
191   Bool_t isRotation = true; 
192   if (TMath::Abs(rm[0] - 1.) < kTolerance &&
193       TMath::Abs(rm[1] - 0.) < kTolerance &&
194       TMath::Abs(rm[2] - 0.) < kTolerance &&
195       TMath::Abs(rm[3] - 0.) < kTolerance &&
196       TMath::Abs(rm[4] - 1.) < kTolerance &&
197       TMath::Abs(rm[5] - 0.) < kTolerance &&
198       TMath::Abs(rm[6] - 0.) < kTolerance &&
199       TMath::Abs(rm[7] - 0.) < kTolerance &&
200       TMath::Abs(rm[8] - 1.) < kTolerance) isRotation = false; 
201
202   Int_t krot = 0;
203   if (isRotation) {
204     TGeoRotation rot;
205     rot.SetMatrix(const_cast<Double_t*>(transform.GetRotationMatrix()));
206     Double_t theta1, phi1, theta2, phi2, theta3, phi3;
207     rot.GetAngles(theta1, phi1, theta2, phi2, theta3, phi3);
208         
209     //cout << "angles: " 
210     //     << theta1 << " " << phi1 << " "
211     //     << theta2 << " " << phi2 << " "
212     //     << theta3 << " " << phi3 << endl;
213         
214     fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
215   }     
216         
217   // Place the volume in ALIC
218   if (npar == 0)
219     gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
220   else 
221     gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
222                 param, npar);
223
224
225
226 //______________________________________________________________________________
227 void AliMUONGeometryBuilder::FillGlobalTransformations(
228                                  AliMUONVGeometryBuilder* builder)
229 {
230 /// Compute and set global transformations to detection elements
231 /// for each chamber geometry
232
233   for (Int_t j=0; j<builder->NofGeometries(); j++) {
234
235     AliMUONGeometryModule* geometry = builder->Geometry(j);
236     AliMUONGeometryStore* detElements = geometry->GetDetElementStore();
237
238     for (Int_t k=0; k<detElements->GetNofEntries(); k++) {
239      
240       AliMUONGeometryDetElement* detElement 
241         = (AliMUONGeometryDetElement*)detElements->GetEntry(k);
242           
243       if (!detElement) AliFatal("Detection element not found.") 
244           
245       const TGeoCombiTrans* localTransform 
246         = detElement->GetLocalTransformation();
247
248       TGeoCombiTrans appliedGlobalTransform;
249       if (builder->ApplyGlobalTransformation())
250         appliedGlobalTransform = fGlobalTransformation;
251
252       // Compose global transformation
253       TGeoHMatrix total 
254         = Multiply( appliedGlobalTransform,
255                     (*geometry->GetTransformation()),
256                     (*localTransform) );
257           
258       // Convert TGeoHMatrix to TGeoCombiTrans
259       TGeoCombiTrans globalTransform(localTransform->GetName());
260       globalTransform.SetTranslation(total.GetTranslation());  
261       TGeoRotation rotation;
262       rotation.SetMatrix(total.GetRotationMatrix());
263       globalTransform.SetRotation(rotation);  
264  
265       // Set the global transformation to detection element
266       detElement->SetGlobalTransformation(globalTransform);
267     }
268   }                         
269 }            
270
271 //
272 // public functions
273 //
274
275 //_____________________________________________________________________________
276 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
277 {
278 /// Add the geometry builder to the list
279
280   fGeometryBuilders->Add(geomBuilder);
281 }
282
283 //______________________________________________________________________________
284 void AliMUONGeometryBuilder::CreateGeometry()
285 {
286 /// Construct geometry using geometry builders.
287
288   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
289
290     // Get the builder
291     AliMUONVGeometryBuilder* builder
292       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
293
294     // Create geometry + envelopes
295     //
296     if (fAlign) {
297       if (builder->ApplyGlobalTransformation())
298         builder->SetReferenceFrame(fGlobalTransformation);
299       builder->ReadTransformations();
300       builder->CreateGeometry();
301     }
302     else {  
303       builder->CreateGeometry();
304       builder->SetTransformations();
305     } 
306
307     // Place module volumes and envelopes
308     //
309     for (Int_t j=0; j<builder->NofGeometries(); j++) {
310
311       AliMUONGeometryModule* geometry = builder->Geometry(j);
312       
313       TGeoCombiTrans appliedGlobalTransform;
314       if (builder->ApplyGlobalTransformation())
315         appliedGlobalTransform = fGlobalTransformation;
316
317       // Place the module volume
318       if ( !geometry->IsVirtual() ) {
319           TGeoHMatrix total 
320             = Multiply ( appliedGlobalTransform, 
321                          (*geometry->GetTransformation()) );
322               
323           PlaceVolume(geometry->GetVolume(), geometry->GetMotherVolume(),
324                       1, total, 0, 0, "ONLY");
325       }               
326   
327       // Loop over envelopes
328       const TObjArray* kEnvelopes = geometry->GetEnvelopeStore()->GetEnvelopes();
329       for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
330
331         // Get envelope
332         AliMUONGeometryEnvelope* env = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
333         const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
334         const char* only = "ONLY";
335         if (env->IsMANY()) only = "MANY";
336
337         if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
338           // virtual envelope + nof constituents = 0 
339           //         => not allowed;
340           //            empty virtual envelope has no sense 
341           AliFatal("Virtual envelope must have constituents.");
342           return;
343         }
344
345         if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
346           // non virtual envelope + nof constituents > 0 
347           //        => not allowed;
348           //           use VMC to place constituents
349           AliFatal("Non virtual envelope cannot have constituents.");
350           return;
351         }
352
353         if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
354           // non virtual envelope + nof constituents = 0 
355           //        => place envelope in ALICE by composed transformation:
356           //           Tglobal * Tch * Tenv
357
358           // Compound chamber transformation with the envelope one
359           if (geometry->IsVirtual()) {
360              TGeoHMatrix total 
361                = Multiply( appliedGlobalTransform, 
362                            (*geometry->GetTransformation()), 
363                            (*kEnvTrans) );
364              PlaceVolume(env->GetName(), geometry->GetMotherVolume(),
365                          env->GetCopyNo(), total, 0, 0, only);
366           }
367           else {
368              TGeoHMatrix total 
369                = (*kEnvTrans);
370              PlaceVolume(env->GetName(), geometry->GetVolume(),
371                          env->GetCopyNo(), total, 0, 0, only);
372           }                      
373         }
374
375         if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
376           // virtual envelope + nof constituents > 0 
377           //         => do not place envelope and place constituents
378           //            in ALICE by composed transformation:
379           //            Tglobal * Tch * Tenv * Tconst   
380
381           for  (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
382             AliMUONGeometryConstituent* constituent
383               = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
384  
385             // Compound chamber transformation with the envelope one + the constituent one
386             if (geometry->IsVirtual()) {
387               TGeoHMatrix total 
388                 = Multiply ( appliedGlobalTransform, 
389                              (*geometry->GetTransformation()),
390                              (*kEnvTrans), 
391                              (*constituent->GetTransformation()) );
392
393               PlaceVolume(constituent->GetName(), geometry->GetMotherVolume(),
394                           constituent->GetCopyNo(), total,
395                           constituent->GetNpar(), constituent->GetParam(), only);
396             }
397             else {                        
398               TGeoHMatrix total 
399                 = Multiply ( (*kEnvTrans),
400                              (*constituent->GetTransformation()) );
401
402               PlaceVolume(constituent->GetName(), geometry->GetVolume(),
403                           constituent->GetCopyNo(), total,
404                           constituent->GetNpar(), constituent->GetParam(), only);
405             }                     
406           }
407         }
408       } // end of loop over envelopes
409     } // end of loop over builder geometries
410   } // end of loop over builders
411 }
412
413 //_____________________________________________________________________________
414 void AliMUONGeometryBuilder::CreateMaterials()
415 {
416 /// Construct materials specific to modules via builders
417   
418   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
419
420     // Get the builder
421     AliMUONVGeometryBuilder* builder
422       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
423
424     // Create materials with each builder
425     if (builder) builder->CreateMaterials();
426   }
427 }
428
429 //______________________________________________________________________________
430 void AliMUONGeometryBuilder::InitGeometry()
431 {
432 /// Initialize geometry
433
434   // Set the chamber (sensitive region) GEANT identifier
435   //
436   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
437
438     // Get the builder
439     AliMUONVGeometryBuilder* builder
440       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
441
442     // Read alignement data if geometry is read from Root file
443     if (gAlice->IsRootGeometry()) {
444       fAlign = true;
445       builder->ReadTransformations();
446     }
447
448     // Set sesitive volumes with each builder
449     builder->SetSensitiveVolumes();
450     
451
452     // Read sensitive volume map from a file
453     builder->ReadSVMap();
454     if (!fAlign)  builder->FillTransformations();
455
456     // Compute global transformations of detection elements
457     FillGlobalTransformations(builder);
458   }  
459 }
460
461 //______________________________________________________________________________
462 void AliMUONGeometryBuilder::WriteTransformations()
463 {
464 /// Write transformations into files per builder
465
466   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
467
468     // Get the builder
469     AliMUONVGeometryBuilder* builder
470       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
471
472     // Set reference frame 
473     // which the transformation will be written with respect to
474     if (builder->ApplyGlobalTransformation())
475       builder->SetReferenceFrame(fGlobalTransformation);
476
477     // Write transformations
478     builder->WriteTransformations();
479   }
480 }
481
482 //______________________________________________________________________________
483 void AliMUONGeometryBuilder::WriteSVMaps(Bool_t rebuild)
484 {
485 /// Write sensitive volume maps into files per builder
486
487   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
488
489     // Get the builder
490     AliMUONVGeometryBuilder* builder
491       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
492
493     // Write transformations      
494     builder->WriteSVMap(rebuild);
495   }
496 }
497
498 //_____________________________________________________________________________
499 void  AliMUONGeometryBuilder::SetGlobalTransformation(
500                                        const TGeoCombiTrans& transform)
501 {
502 /// Set the global transformation
503
504   fGlobalTransformation = transform;
505 }                                      
506
507 //_____________________________________________________________________________
508 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
509
510 /// Set the option for alignement
511
512   fAlign = align; 
513
514   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
515
516     // Get the builder
517     AliMUONVGeometryBuilder* builder
518       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
519
520     for (Int_t j=0; j<builder->NofGeometries(); j++) {
521
522       AliMUONGeometryModule* geometry = builder->Geometry(j);
523   
524       geometry->SetAlign(align);
525     }     
526   }       
527 }