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