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