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