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