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