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