]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONGeometryBuilder.cxx
Pass align option to geometry modules in AddBuilder()
[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 void AliMUONGeometryBuilder::SetAlign(AliMUONVGeometryBuilder* builder)
273 {
274 /// Set align option to all geometry modules associated with the builder
275
276   for (Int_t j=0; j<builder->NofGeometries(); j++) {
277
278     AliMUONGeometryModule* geometry = builder->Geometry(j);
279   
280     geometry->SetAlign(fAlign);
281   }       
282 }            
283
284 //
285 // public functions
286 //
287
288 //_____________________________________________________________________________
289 void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
290 {
291 /// Add the geometry builder to the list
292
293   fGeometryBuilders->Add(geomBuilder);
294   
295   SetAlign(geomBuilder);
296 }
297
298 //______________________________________________________________________________
299 void AliMUONGeometryBuilder::CreateGeometry()
300 {
301 /// Construct geometry using geometry builders.
302
303   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
304
305     // Get the builder
306     AliMUONVGeometryBuilder* builder
307       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
308
309     // Create geometry + envelopes
310     //
311     if (fAlign) {
312       if (builder->ApplyGlobalTransformation())
313         builder->SetReferenceFrame(fGlobalTransformation);
314       builder->ReadTransformations();
315       builder->CreateGeometry();
316     }
317     else {  
318       builder->CreateGeometry();
319       builder->SetTransformations();
320     } 
321
322     // Place module volumes and envelopes
323     //
324     for (Int_t j=0; j<builder->NofGeometries(); j++) {
325
326       AliMUONGeometryModule* geometry = builder->Geometry(j);
327       
328       TGeoCombiTrans appliedGlobalTransform;
329       if (builder->ApplyGlobalTransformation())
330         appliedGlobalTransform = fGlobalTransformation;
331
332       // Place the module volume
333       if ( !geometry->IsVirtual() ) {
334           TGeoHMatrix total 
335             = Multiply ( appliedGlobalTransform, 
336                          (*geometry->GetTransformation()) );
337               
338           PlaceVolume(geometry->GetVolume(), geometry->GetMotherVolume(),
339                       1, total, 0, 0, "ONLY");
340       }               
341   
342       // Loop over envelopes
343       const TObjArray* kEnvelopes = geometry->GetEnvelopeStore()->GetEnvelopes();
344       for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
345
346         // Get envelope
347         AliMUONGeometryEnvelope* env = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
348         const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
349         const char* only = "ONLY";
350         if (env->IsMANY()) only = "MANY";
351
352         if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
353           // virtual envelope + nof constituents = 0 
354           //         => not allowed;
355           //            empty virtual envelope has no sense 
356           AliFatal("Virtual envelope must have constituents.");
357           return;
358         }
359
360         if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
361           // non virtual envelope + nof constituents > 0 
362           //        => not allowed;
363           //           use VMC to place constituents
364           AliFatal("Non virtual envelope cannot have constituents.");
365           return;
366         }
367
368         if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
369           // non virtual envelope + nof constituents = 0 
370           //        => place envelope in ALICE by composed transformation:
371           //           Tglobal * Tch * Tenv
372
373           // Compound chamber transformation with the envelope one
374           if (geometry->IsVirtual()) {
375              TGeoHMatrix total 
376                = Multiply( appliedGlobalTransform, 
377                            (*geometry->GetTransformation()), 
378                            (*kEnvTrans) );
379              PlaceVolume(env->GetName(), geometry->GetMotherVolume(),
380                          env->GetCopyNo(), total, 0, 0, only);
381           }
382           else {
383              TGeoHMatrix total 
384                = (*kEnvTrans);
385              PlaceVolume(env->GetName(), geometry->GetVolume(),
386                          env->GetCopyNo(), total, 0, 0, only);
387           }                      
388         }
389
390         if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
391           // virtual envelope + nof constituents > 0 
392           //         => do not place envelope and place constituents
393           //            in ALICE by composed transformation:
394           //            Tglobal * Tch * Tenv * Tconst   
395
396           for  (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
397             AliMUONGeometryConstituent* constituent
398               = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
399  
400             // Compound chamber transformation with the envelope one + the constituent one
401             if (geometry->IsVirtual()) {
402               TGeoHMatrix total 
403                 = Multiply ( appliedGlobalTransform, 
404                              (*geometry->GetTransformation()),
405                              (*kEnvTrans), 
406                              (*constituent->GetTransformation()) );
407
408               PlaceVolume(constituent->GetName(), geometry->GetMotherVolume(),
409                           constituent->GetCopyNo(), total,
410                           constituent->GetNpar(), constituent->GetParam(), only);
411             }
412             else {                        
413               TGeoHMatrix total 
414                 = Multiply ( (*kEnvTrans),
415                              (*constituent->GetTransformation()) );
416
417               PlaceVolume(constituent->GetName(), geometry->GetVolume(),
418                           constituent->GetCopyNo(), total,
419                           constituent->GetNpar(), constituent->GetParam(), only);
420             }                     
421           }
422         }
423       } // end of loop over envelopes
424     } // end of loop over builder geometries
425   } // end of loop over builders
426 }
427
428 //_____________________________________________________________________________
429 void AliMUONGeometryBuilder::CreateMaterials()
430 {
431 /// Construct materials specific to modules via builders
432   
433   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
434
435     // Get the builder
436     AliMUONVGeometryBuilder* builder
437       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
438
439     // Create materials with each builder
440     if (builder) builder->CreateMaterials();
441   }
442 }
443
444 //______________________________________________________________________________
445 void AliMUONGeometryBuilder::InitGeometry()
446 {
447 /// Initialize geometry
448
449   // Set the chamber (sensitive region) GEANT identifier
450   //
451   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
452
453     // Get the builder
454     AliMUONVGeometryBuilder* builder
455       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
456
457     // Read alignement data if geometry is read from Root file
458     if (gAlice->IsRootGeometry()) {
459       fAlign = true;
460       builder->ReadTransformations();
461     }
462
463     // Set sesitive volumes with each builder
464     builder->SetSensitiveVolumes();
465     
466
467     // Read sensitive volume map from a file
468     builder->ReadSVMap();
469     if (!fAlign)  builder->FillTransformations();
470
471     // Compute global transformations of detection elements
472     FillGlobalTransformations(builder);
473   }  
474 }
475
476 //______________________________________________________________________________
477 void AliMUONGeometryBuilder::WriteTransformations()
478 {
479 /// Write transformations into files per builder
480
481   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
482
483     // Get the builder
484     AliMUONVGeometryBuilder* builder
485       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
486
487     // Set reference frame 
488     // which the transformation will be written with respect to
489     if (builder->ApplyGlobalTransformation())
490       builder->SetReferenceFrame(fGlobalTransformation);
491
492     // Write transformations
493     builder->WriteTransformations();
494   }
495 }
496
497 //______________________________________________________________________________
498 void AliMUONGeometryBuilder::WriteSVMaps(Bool_t rebuild)
499 {
500 /// Write sensitive volume maps into files per builder
501
502   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
503
504     // Get the builder
505     AliMUONVGeometryBuilder* builder
506       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
507
508     // Write transformations      
509     builder->WriteSVMap(rebuild);
510   }
511 }
512
513 //_____________________________________________________________________________
514 void  AliMUONGeometryBuilder::SetGlobalTransformation(
515                                        const TGeoCombiTrans& transform)
516 {
517 /// Set the global transformation
518
519   fGlobalTransformation = transform;
520 }                                      
521
522 //_____________________________________________________________________________
523 void AliMUONGeometryBuilder::SetAlign(Bool_t align)
524
525 /// Set the option for alignement
526
527   fAlign = align; 
528
529   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
530
531     AliMUONVGeometryBuilder* builder
532       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
533     
534     SetAlign(builder); 
535   }   
536 }