ffa14a0084427f8d3e0fc0edac1299cad4bd4893
[u/mrichter/AliRoot.git] / MUON / AliMUONVGeometryBuilder.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
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 purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 // $Id$
17 //
18 // Class AliMUONVGeometryBuilder
19 // -----------------------------
20 // Abstract base class for geometry construction per geometry module(s).
21 // Author: Ivana Hrivnacova, IPN Orsay
22 // 23/01/2004
23
24 #include <Riostream.h>
25 #include <TObjArray.h>
26 #include <TSystem.h>
27 #include <TGeoMatrix.h>
28 #include <TVirtualMC.h>
29
30 #include "AliMUONVGeometryBuilder.h"
31 #include "AliMUONGeometryModule.h"
32 #include "AliMUONGeometryDetElement.h"
33 #include "AliMUONGeometryStore.h"
34 #include "AliMUONGeometryEnvelopeStore.h"
35 #include "AliMUONGeometryEnvelope.h"
36 #include "AliMUONGeometryConstituent.h"
37 #include "AliMUONGeometryBuilder.h"
38 #include "AliMUONStringIntMap.h"
39 #include "AliLog.h"
40
41 ClassImp(AliMUONVGeometryBuilder)
42
43 //______________________________________________________________________________
44 AliMUONVGeometryBuilder::AliMUONVGeometryBuilder(
45                             Int_t moduleId1, Int_t moduleId2,
46                             Int_t moduleId3, Int_t moduleId4,
47                             Int_t moduleId5, Int_t moduleId6)
48  : TObject(),
49    fGeometryModules(0),
50    fReferenceFrame()
51  {
52 // Standard constructor
53
54   // Create the module geometries array
55   fGeometryModules = new TObjArray();
56   
57   if ( moduleId1 >= 0 ) 
58     fGeometryModules->Add(new AliMUONGeometryModule(moduleId1));
59  
60   if ( moduleId2 >= 0 ) 
61     fGeometryModules->Add(new AliMUONGeometryModule(moduleId2));
62
63   if ( moduleId3 >= 0 ) 
64     fGeometryModules->Add(new AliMUONGeometryModule(moduleId3));
65
66   if ( moduleId4 >= 0 ) 
67     fGeometryModules->Add(new AliMUONGeometryModule(moduleId4));
68
69   if ( moduleId5 >= 0 ) 
70     fGeometryModules->Add(new AliMUONGeometryModule(moduleId5));
71
72   if ( moduleId6 >= 0 ) 
73     fGeometryModules->Add(new AliMUONGeometryModule(moduleId6));
74 }
75
76 //______________________________________________________________________________
77 AliMUONVGeometryBuilder::AliMUONVGeometryBuilder()
78  : TObject(),
79    fGeometryModules(0),
80    fReferenceFrame()
81 {
82 // Default constructor
83 }
84
85
86 //______________________________________________________________________________
87 AliMUONVGeometryBuilder::AliMUONVGeometryBuilder(const AliMUONVGeometryBuilder& rhs)
88   : TObject(rhs)
89 {
90 // Protected copy constructor
91
92   AliFatal("Copy constructor is not implemented.");
93 }
94
95 //______________________________________________________________________________
96 AliMUONVGeometryBuilder::~AliMUONVGeometryBuilder() {
97 //
98   if (fGeometryModules) {
99     fGeometryModules->Clear(); // Sets pointers to 0 since it is not the owner
100     delete fGeometryModules;
101   }
102 }
103
104 //______________________________________________________________________________
105 AliMUONVGeometryBuilder& 
106 AliMUONVGeometryBuilder::operator = (const AliMUONVGeometryBuilder& rhs) 
107 {
108 // Protected assignement operator
109
110   // check assignement to self
111   if (this == &rhs) return *this;
112
113   AliFatal("Assignment operator is not implemented.");
114     
115   return *this;  
116 }
117
118 //
119 // private methods
120 //
121
122 //______________________________________________________________________________
123 TGeoHMatrix 
124 AliMUONVGeometryBuilder::ConvertTransform(const TGeoHMatrix& transform) const
125 {
126 // Convert transformation into the reference frame
127
128   if ( fReferenceFrame.IsIdentity() )
129     return transform;
130   else  {
131     return AliMUONGeometryBuilder::Multiply( fReferenceFrame,
132                                              transform,
133                                              fReferenceFrame.Inverse() );  
134   }                         
135 }
136
137 //______________________________________________________________________________
138 TGeoHMatrix 
139 AliMUONVGeometryBuilder::ConvertDETransform(const TGeoHMatrix& transform) const
140 {
141 // Convert transformation into the reference frame
142
143   if ( fReferenceFrame.IsIdentity() )
144     return transform;
145   else  {
146     return AliMUONGeometryBuilder::Multiply( fReferenceFrame,
147                                              transform );  
148   }                         
149 }
150
151 //______________________________________________________________________________
152 TString  AliMUONVGeometryBuilder::ComposePath(const TString& volName,
153                                               Int_t copyNo) const
154 {
155 // Compose path from given volName and copyNo
156 // ---
157
158   TString path = "/";
159   path += volName;
160   path += '_';
161   path += copyNo;
162   
163   return path;
164 }  
165
166 //______________________________________________________________________________
167 void AliMUONVGeometryBuilder::MapSV(const TString& path0, 
168                                     const TString& volName, Int_t detElemId) const
169 {
170 // Update the path with all daughters volumes recursively
171 // and map it to the detection element Id if it is a sensitive volume
172 // ---
173
174   // Get module sensitive volumes map
175   Int_t moduleId = AliMUONGeometryStore::GetModuleId(detElemId);
176   AliMUONStringIntMap* svMap = GetSVMap(moduleId);     
177
178   Int_t nofDaughters = gMC->NofVolDaughters(volName);
179   if (nofDaughters == 0) {
180
181     // Get the name of the last volume in the path
182     Ssiz_t npos1 = path0.Last('/')+1; 
183     Ssiz_t npos2 = path0.Last('_');
184     TString volName(path0(npos1, npos2-npos1));  
185     
186     // Check if it is sensitive volume
187     Int_t moduleId = AliMUONGeometryStore::GetModuleId(detElemId);
188     AliMUONGeometryModule* geometry = GetGeometry(moduleId);
189     if (  geometry->IsSensitiveVolume(volName) &&
190         ! svMap->Get(path0) ) {
191       //cout << ".. adding to the map  " 
192       //     <<  path0 << "  "  << detElemId << endl;
193     
194       // Map the sensitive volume to detection element
195       svMap->Add(path0, detElemId); 
196     }  
197     return; 
198   }  
199
200   for (Int_t i=0; i<nofDaughters; i++) {
201     Int_t copyNo = gMC->VolDaughterCopyNo(volName, i);
202     TString newName =  gMC->VolDaughterName(volName, i);
203             
204     TString path = path0;
205     path += ComposePath(newName, copyNo);
206
207     MapSV(path, newName, detElemId);
208   }
209 }     
210
211 //
212 // protected methods
213 //
214
215 //______________________________________________________________________________
216 AliMUONGeometryModule*  
217 AliMUONVGeometryBuilder::GetGeometry(Int_t moduleId) const
218 {
219 // Returns the module geometry specified by moduleId
220 // ---
221
222   for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
223
224     AliMUONGeometryModule* geometry 
225       = (AliMUONGeometryModule*)fGeometryModules->At(i);
226
227     if ( geometry->GetModuleId() == moduleId) return geometry;
228   }   
229   
230   return 0;
231 }  
232
233 //______________________________________________________________________________
234 AliMUONGeometryEnvelopeStore*  
235 AliMUONVGeometryBuilder::GetEnvelopes(Int_t moduleId) const
236 {
237 // Returns the envelope store of the module geometry specified by moduleId
238 // ---
239
240   AliMUONGeometryModule* geometry = GetGeometry(moduleId);
241   
242   if (!geometry) {
243     AliFatal(Form("Module geometry %d is not defined", moduleId)); 
244     return 0;
245   }
246   
247   return geometry->GetEnvelopeStore();
248 }  
249
250 //______________________________________________________________________________
251 AliMUONStringIntMap*  
252 AliMUONVGeometryBuilder::GetSVMap(Int_t moduleId) const
253 {
254 // Returns the transformation store of the module geometry specified by moduleId
255 // ---
256
257   AliMUONGeometryModule* geometry = GetGeometry(moduleId);
258   
259   if (!geometry) {
260     AliFatal(Form("Geometry %d is not defined", moduleId)); 
261     return 0;
262   }
263   
264   return geometry->GetSVMap();
265 }  
266
267 //______________________________________________________________________________
268 void AliMUONVGeometryBuilder::SetTranslation(Int_t moduleId, 
269                                   const TGeoTranslation& translation)
270 {
271 // Sets the translation to the geometry module given by moduleId,
272 // applies reference frame transformation 
273 // ---
274
275   AliMUONGeometryModule* geometry = GetGeometry(moduleId);
276   
277   if (!geometry) {
278     AliFatal(Form("Geometry %d is not defined", moduleId)); 
279     return;
280   }
281   
282   // Apply frame transform
283   TGeoHMatrix newTransform = ConvertTransform(translation);
284
285   // Set new transformation
286   geometry->SetTransformation(newTransform);
287 }  
288
289
290 //______________________________________________________________________________
291 void AliMUONVGeometryBuilder::SetTransformation(Int_t moduleId, 
292                                   const TGeoTranslation& translation,
293                                   const TGeoRotation& rotation)
294 {
295 // Sets the translation to the geometry module given by moduleId,
296 // applies reference frame transformation 
297 // ---
298
299   AliMUONGeometryModule* geometry = GetGeometry(moduleId);
300   
301   if (!geometry) {
302     AliFatal(Form("Geometry %d is not defined", moduleId)); 
303     return;
304   }
305   
306   TGeoCombiTrans transformation 
307     = TGeoCombiTrans(translation, rotation);
308
309   // Apply frame transform
310   TGeoHMatrix newTransform = ConvertTransform(transformation);
311
312   // Set new transformation
313   geometry->SetTransformation(newTransform);
314 }  
315
316 //______________________________________________________________________________
317 void AliMUONVGeometryBuilder::SetVolume(Int_t moduleId, 
318                                  const TString& volumeName, 
319                                  Bool_t isVirtual)
320 {
321 /// Set volume name, virtuality
322
323   TString path = GetGeometry(moduleId)->GetVolumePath();
324   // cout << "in AliMUONVGeometryBuilder::SetVolume " << path.Data() << endl;
325   
326   if ( path == "" ) path = "/ALIC_1";
327   path += ComposePath(volumeName, 1);
328
329   GetGeometry(moduleId)->SetVolumePath(path);
330   GetGeometry(moduleId)->SetIsVirtual(isVirtual);
331   // cout << "... set " << path.Data() << endl;
332 }                                
333
334 //______________________________________________________________________________
335 void AliMUONVGeometryBuilder::SetMotherVolume(Int_t moduleId, 
336                                  const TString& volumeName)
337 {
338 /// Set mother volume name
339
340   TString motherVolumeName = ComposePath(volumeName, 1);
341
342   TString path = GetGeometry(moduleId)->GetVolumePath();
343   if ( path == "" ) path = "/ALIC_1";
344   path.Insert(7, motherVolumeName);  
345   
346   GetGeometry(moduleId)->SetVolumePath(path);
347 }                                
348
349 //
350 // public functions
351 //
352
353 //______________________________________________________________________________
354 void  AliMUONVGeometryBuilder::SetReferenceFrame(
355                                   const TGeoCombiTrans& referenceFrame)
356
357 /// Set reference frame to builder and to all associated geometry 
358 /// modules
359
360   fReferenceFrame = referenceFrame; 
361
362   for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
363     AliMUONGeometryModule* geometry 
364       = (AliMUONGeometryModule*)fGeometryModules->At(i);
365     AliMUONGeometryEnvelopeStore* envelopeStore 
366       = geometry->GetEnvelopeStore();
367       
368     envelopeStore->SetReferenceFrame(referenceFrame);
369   }          
370 }
371
372
373 //______________________________________________________________________________
374 void  AliMUONVGeometryBuilder::CreateDetElements() const
375 {
376 /// Create detection element and fill their global and
377 /// local transformations from geometry.
378
379   for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
380     AliMUONGeometryModule* geometry 
381       = (AliMUONGeometryModule*)fGeometryModules->At(i);
382       
383     const TObjArray* envelopes 
384       = geometry->GetEnvelopeStore()->GetEnvelopes();    
385     
386     AliMUONGeometryStore* detElements 
387       = geometry->GetTransformer()->GetDetElementStore(); 
388       
389     for (Int_t j=0; j<envelopes->GetEntriesFast(); j++) {
390       AliMUONGeometryEnvelope* envelope
391         = (AliMUONGeometryEnvelope*)envelopes->At(j);
392
393       // skip envelope not corresponding to detection element
394       if ( envelope->GetUniqueID() == 0) continue;
395        
396       // Get envelope data 
397       Int_t detElemId = envelope->GetUniqueID();        
398
399       // Compose full volume path
400       TString volPath = geometry->GetVolumePath();
401       volPath += ComposePath(envelope->GetName(), envelope->GetCopyNo());
402
403       // Create detection element 
404       AliMUONGeometryDetElement* detElement
405         = new AliMUONGeometryDetElement(detElemId, volPath);
406       detElements->Add(detElemId, detElement);
407
408       // Compose  local transformation
409       const TGeoCombiTrans* transform = envelope->GetTransformation(); 
410       // Apply frame transform
411       TGeoHMatrix localTransform = ConvertDETransform(*transform);
412       detElement->SetLocalTransformation(localTransform);
413
414       // Compose global transformation
415       TGeoHMatrix globalTransform 
416         = AliMUONGeometryBuilder::Multiply( 
417                     (*geometry->GetTransformer()->GetTransformation()),
418                      localTransform );
419                     ;
420       // Set the global transformation to detection element
421       detElement->SetGlobalTransformation(globalTransform);
422       
423     }  
424   }
425 }
426 //_____ _________________________________________________________________________
427 void  AliMUONVGeometryBuilder::RebuildSVMaps(Bool_t withEnvelopes) const
428 {
429 // Clear the SV maps in memory and fill them from defined geometry.
430 // ---
431
432   for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
433     AliMUONGeometryModule* geometry 
434       = (AliMUONGeometryModule*)fGeometryModules->At(i);
435     
436     // Clear the map   
437     geometry->GetSVMap()->Clear();
438      
439     // Fill the map from geometry
440     const TObjArray* envelopes 
441       = geometry->GetEnvelopeStore()->GetEnvelopes();    
442
443     for (Int_t j=0; j<envelopes->GetEntriesFast(); j++) {
444       AliMUONGeometryEnvelope* envelope
445         = (AliMUONGeometryEnvelope*)envelopes->At(j);
446
447       // skip envelope not corresponding to detection element
448       if ( envelope->GetUniqueID() == 0 ) continue;
449       
450       // Get volume path of detection element
451       AliMUONGeometryDetElement* detElement
452         = geometry->GetTransformer()->GetDetElement(envelope->GetUniqueID());
453       std::string path0 = detElement->GetVolumePath().Data();   
454         
455       if ( ! withEnvelopes && geometry->IsVirtual() ) {
456          std::string vName = geometry->GetTransformer()->GetVolumeName().Data();
457          std::string vPath = ComposePath(vName, 1).Data();
458          path0.erase(path0.find(vPath), vPath.size());
459       }  
460        
461       if ( ! withEnvelopes && envelope->IsVirtual()) {
462          std::string eName = envelope->GetName();
463          std::string ePath = ComposePath(eName, envelope->GetCopyNo()).Data();
464          path0.erase(path0.find(ePath), ePath.size());
465       }
466
467       if ( ! envelope->IsVirtual() )
468         MapSV(path0, envelope->GetName(), envelope->GetUniqueID());
469       else {    
470         for  (Int_t k=0; k<envelope->GetConstituents()->GetEntriesFast(); k++) {
471           AliMUONGeometryConstituent* constituent
472             = (AliMUONGeometryConstituent*)envelope->GetConstituents()->At(k);
473          TString path = path0;
474          path += ComposePath(constituent->GetName(), constituent->GetCopyNo());
475          MapSV(path, constituent->GetName(), envelope->GetUniqueID());
476         }
477       }
478     }  
479   }                  
480 }
481