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