1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 // Class AliMUONVGeometryBuilder
19 // -----------------------------
20 // Abstract base class for geometry construction per geometry module(s).
21 // Author: Ivana Hrivnacova, IPN Orsay
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"
33 #include "AliMpDEManager.h"
34 #include "AliMpExMap.h"
38 #include <Riostream.h>
39 #include <TObjArray.h>
41 #include <TGeoMatrix.h>
42 #include <TVirtualMC.h>
45 ClassImp(AliMUONVGeometryBuilder)
48 //______________________________________________________________________________
49 AliMUONVGeometryBuilder::AliMUONVGeometryBuilder(
56 /// Standard constructor
58 // Create the module geometries array
59 fGeometryModules = new TObjArray();
61 for (Int_t i=0; i<nofModules; i++ )
62 fGeometryModules->Add(new AliMUONGeometryModule(firstModuleId++));
65 //______________________________________________________________________________
66 AliMUONVGeometryBuilder::AliMUONVGeometryBuilder()
71 /// Default constructor
74 //______________________________________________________________________________
75 AliMUONVGeometryBuilder::~AliMUONVGeometryBuilder()
79 if (fGeometryModules) {
80 fGeometryModules->Clear(); // Sets pointers to 0 since it is not the owner
81 delete fGeometryModules;
89 //______________________________________________________________________________
91 AliMUONVGeometryBuilder::ConvertTransform(const TGeoHMatrix& transform) const
93 /// Convert transformation into the reference frame
95 if ( fReferenceFrame.IsIdentity() )
98 return AliMUONGeometryBuilder::Multiply( fReferenceFrame,
100 fReferenceFrame.Inverse() );
104 //______________________________________________________________________________
106 AliMUONVGeometryBuilder::ConvertDETransform(const TGeoHMatrix& transform) const
108 /// Convert DE transformation into the reference frame
110 if ( fReferenceFrame.IsIdentity() )
113 return AliMUONGeometryBuilder::Multiply( fReferenceFrame,
118 //______________________________________________________________________________
119 TString AliMUONVGeometryBuilder::ComposePath(const TString& volName,
122 /// Compose path from given volName and copyNo
132 //______________________________________________________________________________
133 void AliMUONVGeometryBuilder::MapSV(const TString& path0,
134 const TString& volName, Int_t detElemId) const
136 /// Update the path with all daughters volumes recursively
137 /// and map it to the detection element Id if it is a sensitive volume
139 // Get module sensitive volumes map
140 Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId);
141 AliMUONStringIntMap* svMap = GetSVMap(moduleId);
143 Int_t nofDaughters = gMC->NofVolDaughters(volName);
144 if (nofDaughters == 0) {
146 // Get the name of the last volume in the path
147 Ssiz_t npos1 = path0.Last('/')+1;
148 Ssiz_t npos2 = path0.Last('_');
149 TString volName(path0(npos1, npos2-npos1));
151 // Check if it is sensitive volume
152 Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId);
153 AliMUONGeometryModule* geometry = GetGeometry(moduleId);
154 if ( geometry->IsSensitiveVolume(volName) &&
155 ! svMap->Get(path0) ) {
156 //cout << ".. adding to the map "
157 // << path0 << " " << detElemId << endl;
159 // Map the sensitive volume to detection element
160 svMap->Add(path0, detElemId);
165 for (Int_t i=0; i<nofDaughters; i++) {
166 Int_t copyNo = gMC->VolDaughterCopyNo(volName, i);
167 TString newName = gMC->VolDaughterName(volName, i);
169 TString path = path0;
170 path += ComposePath(newName, copyNo);
172 MapSV(path, newName, detElemId);
180 //______________________________________________________________________________
181 AliMUONGeometryModule*
182 AliMUONVGeometryBuilder::GetGeometry(Int_t moduleId) const
184 /// Return the module geometry specified by moduleId
186 for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
188 AliMUONGeometryModule* geometry
189 = (AliMUONGeometryModule*)fGeometryModules->At(i);
191 if ( geometry->GetModuleId() == moduleId) return geometry;
197 //______________________________________________________________________________
198 AliMUONGeometryEnvelopeStore*
199 AliMUONVGeometryBuilder::GetEnvelopes(Int_t moduleId) const
201 /// Return the envelope store of the module geometry specified by moduleId
203 AliMUONGeometryModule* geometry = GetGeometry(moduleId);
206 AliFatal(Form("Module geometry %d is not defined", moduleId));
210 return geometry->GetEnvelopeStore();
213 //______________________________________________________________________________
215 AliMUONVGeometryBuilder::GetSVMap(Int_t moduleId) const
217 /// Return the transformation store of the module geometry specified by moduleId
219 AliMUONGeometryModule* geometry = GetGeometry(moduleId);
222 AliFatal(Form("Geometry %d is not defined", moduleId));
226 return geometry->GetSVMap();
229 //______________________________________________________________________________
231 AliMUONVGeometryBuilder::GetModuleId(const TString& envName) const
233 /// Return module Id which has the envelope with given name
235 for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
237 AliMUONGeometryModule* geometry
238 = (AliMUONGeometryModule*)fGeometryModules->At(i);
240 if ( geometry->GetEnvelopeStore()->FindEnvelope(envName) )
241 return geometry->GetModuleId();
248 //______________________________________________________________________________
249 void AliMUONVGeometryBuilder::SetTranslation(Int_t moduleId,
250 const TGeoTranslation& translation)
252 /// Set the translation to the geometry module given by moduleId,
253 /// apply reference frame transformation
255 AliMUONGeometryModule* geometry = GetGeometry(moduleId);
258 AliFatal(Form("Geometry %d is not defined", moduleId));
262 // Apply frame transform
263 TGeoHMatrix newTransform = ConvertTransform(translation);
265 // Set new transformation
266 geometry->SetTransformation(newTransform);
270 //______________________________________________________________________________
271 void AliMUONVGeometryBuilder::SetTransformation(Int_t moduleId,
272 const TGeoTranslation& translation,
273 const TGeoRotation& rotation)
275 /// Set the transformation to the geometry module given by moduleId,
276 /// apply reference frame transformation
278 AliMUONGeometryModule* geometry = GetGeometry(moduleId);
281 AliFatal(Form("Geometry %d is not defined", moduleId));
285 TGeoCombiTrans transformation
286 = TGeoCombiTrans(translation, rotation);
288 // Apply frame transform
289 TGeoHMatrix newTransform = ConvertTransform(transformation);
291 // Set new transformation
292 geometry->SetTransformation(newTransform);
295 //______________________________________________________________________________
296 void AliMUONVGeometryBuilder::SetVolume(Int_t moduleId,
297 const TString& volumeName,
300 /// Set volume name, virtuality
302 TString path = GetGeometry(moduleId)->GetVolumePath();
303 // cout << "in AliMUONVGeometryBuilder::SetVolume " << path.Data() << endl;
305 if ( path == "" ) path = "/ALIC_1";
306 path += ComposePath(volumeName, 1);
308 GetGeometry(moduleId)->SetVolumePath(path);
309 GetGeometry(moduleId)->SetIsVirtual(isVirtual);
310 // cout << "... set " << path.Data() << endl;
313 //______________________________________________________________________________
314 void AliMUONVGeometryBuilder::SetMotherVolume(Int_t moduleId,
315 const TString& volumeName)
317 /// Set mother volume name
319 TString motherVolumeName = ComposePath(volumeName, 1);
321 TString path = GetGeometry(moduleId)->GetVolumePath();
322 if ( path == "" ) path = "/ALIC_1";
323 path.Insert(7, motherVolumeName);
325 GetGeometry(moduleId)->SetVolumePath(path);
332 //______________________________________________________________________________
333 void AliMUONVGeometryBuilder::SetReferenceFrame(
334 const TGeoCombiTrans& referenceFrame)
336 /// Set reference frame to builder and to all associated geometry
339 fReferenceFrame = referenceFrame;
341 for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
342 AliMUONGeometryModule* geometry
343 = (AliMUONGeometryModule*)fGeometryModules->At(i);
344 AliMUONGeometryEnvelopeStore* envelopeStore
345 = geometry->GetEnvelopeStore();
347 envelopeStore->SetReferenceFrame(referenceFrame);
352 //______________________________________________________________________________
353 void AliMUONVGeometryBuilder::CreateDetElements() const
355 /// Create detection elements and fill their global and
356 /// local transformations from geometry.
358 for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
359 AliMUONGeometryModule* geometry
360 = (AliMUONGeometryModule*)fGeometryModules->At(i);
362 const TObjArray* envelopes
363 = geometry->GetEnvelopeStore()->GetEnvelopes();
365 AliMpExMap* detElements
366 = geometry->GetTransformer()->GetDetElementStore();
368 for (Int_t j=0; j<envelopes->GetEntriesFast(); j++) {
369 AliMUONGeometryEnvelope* envelope
370 = (AliMUONGeometryEnvelope*)envelopes->At(j);
372 // skip envelope not corresponding to detection element
373 if ( envelope->GetUniqueID() == 0) continue;
376 Int_t detElemId = envelope->GetUniqueID();
378 // Compose full volume path
379 TString volPath = geometry->GetVolumePath();
380 volPath += ComposePath(envelope->GetName(), envelope->GetCopyNo());
382 // Create detection element
383 AliMUONGeometryDetElement* detElement
384 = new AliMUONGeometryDetElement(detElemId, volPath);
385 detElements->Add(detElemId, detElement);
387 // Compose local transformation
388 const TGeoCombiTrans* transform = envelope->GetTransformation();
389 // Apply frame transform
390 TGeoHMatrix localTransform = ConvertDETransform(*transform);
391 detElement->SetLocalTransformation(localTransform);
393 // Compose global transformation
394 TGeoHMatrix globalTransform
395 = AliMUONGeometryBuilder::Multiply(
396 (*geometry->GetTransformer()->GetTransformation()),
399 // Set the global transformation to detection element
400 detElement->SetGlobalTransformation(globalTransform);
405 //_____ _________________________________________________________________________
406 void AliMUONVGeometryBuilder::RebuildSVMaps(Bool_t withEnvelopes) const
408 /// Clear the SV maps in memory and fill them from defined geometry.
410 for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
411 AliMUONGeometryModule* geometry
412 = (AliMUONGeometryModule*)fGeometryModules->At(i);
415 geometry->GetSVMap()->Clear();
417 // Fill the map from geometry
418 const TObjArray* envelopes
419 = geometry->GetEnvelopeStore()->GetEnvelopes();
421 for (Int_t j=0; j<envelopes->GetEntriesFast(); j++) {
422 AliMUONGeometryEnvelope* envelope
423 = (AliMUONGeometryEnvelope*)envelopes->At(j);
425 // skip envelope not corresponding to detection element
426 if ( envelope->GetUniqueID() == 0 ) continue;
428 // Get volume path of detection element
429 AliMUONGeometryDetElement* detElement
430 = geometry->GetTransformer()->GetDetElement(envelope->GetUniqueID());
431 std::string path0 = detElement->GetVolumePath().Data();
433 if ( ! withEnvelopes && geometry->IsVirtual() ) {
434 std::string vName = geometry->GetTransformer()->GetVolumeName().Data();
435 std::string vPath = ComposePath(vName, 1).Data();
436 path0.erase(path0.find(vPath), vPath.size());
439 if ( ! withEnvelopes && envelope->IsVirtual()) {
440 std::string eName = envelope->GetName();
441 std::string ePath = ComposePath(eName, envelope->GetCopyNo()).Data();
442 path0.erase(path0.find(ePath), ePath.size());
445 if ( ! envelope->IsVirtual() )
446 MapSV(path0, envelope->GetName(), envelope->GetUniqueID());
448 for (Int_t k=0; k<envelope->GetConstituents()->GetEntriesFast(); k++) {
449 AliMUONGeometryConstituent* constituent
450 = (AliMUONGeometryConstituent*)envelope->GetConstituents()->At(k);
451 TString path = path0;
452 path += ComposePath(constituent->GetName(), constituent->GetCopyNo());
453 MapSV(path, constituent->GetName(), envelope->GetUniqueID());