+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
// $Id$
-//
+
+//-----------------------------------------------------------------------------
// Class AliMUONVGeometryBuilder
// -----------------------------
-// Abstract base class for geometry construction per chamber(s).
-//
+// Abstract base class for geometry construction per geometry module(s).
// Author: Ivana Hrivnacova, IPN Orsay
-
-#include <TObjArray.h>
+// 23/01/2004
+//-----------------------------------------------------------------------------
#include "AliMUONVGeometryBuilder.h"
-#include "AliMUONChamber.h"
+#include "AliMUONGeometryModule.h"
+#include "AliMUONGeometryDetElement.h"
+#include "AliMUONGeometryEnvelopeStore.h"
+#include "AliMUONGeometryEnvelope.h"
+#include "AliMUONGeometryConstituent.h"
+#include "AliMUONGeometryBuilder.h"
+#include "AliMUONStringIntMap.h"
+
+#include "AliMpDEManager.h"
+#include "AliMpExMap.h"
+
+#include "AliLog.h"
+#include <Riostream.h>
+#include <TObjArray.h>
+#include <TSystem.h>
+#include <TGeoMatrix.h>
+#include <TVirtualMC.h>
+
+/// \cond CLASSIMP
ClassImp(AliMUONVGeometryBuilder)
+/// \endcond
//______________________________________________________________________________
AliMUONVGeometryBuilder::AliMUONVGeometryBuilder(
- AliMUONChamber* ch1, AliMUONChamber* ch2,
- AliMUONChamber* ch3, AliMUONChamber* ch4,
- AliMUONChamber* ch5, AliMUONChamber* ch6)
+ Int_t firstModuleId,
+ Int_t nofModules)
: TObject(),
- fChambers(0)
+ fGeometryModules(0),
+ fReferenceFrame()
{
-// Standard constructor
-
- // Create the chambers array
- fChambers = new TObjArray();
-
- if (ch1) fChambers->Add(ch1);
- if (ch2) fChambers->Add(ch2);
- if (ch3) fChambers->Add(ch3);
- if (ch4) fChambers->Add(ch4);
- if (ch5) fChambers->Add(ch5);
- if (ch6) fChambers->Add(ch6);
+/// Standard constructor
+ // Create the module geometries array
+ fGeometryModules = new TObjArray();
+ fGeometryModules->SetOwner(kFALSE);
+
+ for (Int_t i=0; i<nofModules; i++ )
+ fGeometryModules->Add(new AliMUONGeometryModule(firstModuleId++));
}
-
//______________________________________________________________________________
AliMUONVGeometryBuilder::AliMUONVGeometryBuilder()
: TObject(),
- fChambers(0)
+ fGeometryModules(0),
+ fReferenceFrame()
+{
+/// Default constructor
+}
+
+//______________________________________________________________________________
+AliMUONVGeometryBuilder::~AliMUONVGeometryBuilder()
{
-// Default constructor
+/// Destructor
+
+ if (fGeometryModules) {
+ fGeometryModules->Clear(); // Sets pointers to 0 since it is not the owner
+ delete fGeometryModules;
+ }
}
+//
+// private methods
+//
//______________________________________________________________________________
-AliMUONVGeometryBuilder::AliMUONVGeometryBuilder(const AliMUONVGeometryBuilder& rhs)
- : TObject(rhs)
+TGeoHMatrix
+AliMUONVGeometryBuilder::ConvertTransform(const TGeoHMatrix& transform) const
{
- Fatal("Copy constructor",
- "Copy constructor is not implemented.");
+/// Convert transformation into the reference frame
+
+ if ( fReferenceFrame.IsIdentity() )
+ return transform;
+ else {
+ return AliMUONGeometryBuilder::Multiply( fReferenceFrame,
+ transform,
+ fReferenceFrame.Inverse() );
+ }
}
//______________________________________________________________________________
-AliMUONVGeometryBuilder::~AliMUONVGeometryBuilder() {
-//
+TGeoHMatrix
+AliMUONVGeometryBuilder::ConvertDETransform(const TGeoHMatrix& transform) const
+{
+/// Convert DE transformation into the reference frame
- delete fChambers;
+ if ( fReferenceFrame.IsIdentity() )
+ return transform;
+ else {
+ return AliMUONGeometryBuilder::Multiply( fReferenceFrame,
+ transform );
+ }
}
//______________________________________________________________________________
-AliMUONVGeometryBuilder&
-AliMUONVGeometryBuilder::operator = (const AliMUONVGeometryBuilder& rhs)
+TString AliMUONVGeometryBuilder::ComposePath(const TString& volName,
+ Int_t copyNo) const
{
- // check assignement to self
- if (this == &rhs) return *this;
+/// Compose path from given volName and copyNo
+
+ TString path = "/";
+ path += volName;
+ path += '_';
+ path += copyNo;
+
+ return path;
+}
+
+//______________________________________________________________________________
+void AliMUONVGeometryBuilder::MapSV(const TString& path0,
+ const TString& volName, Int_t detElemId) const
+{
+/// Update the path with all daughters volumes recursively
+/// and map it to the detection element Id if it is a sensitive volume
+
+ // Get module sensitive volumes map
+ Int_t moduleId = AliMpDEManager::GetGeomModuleId(detElemId);
+ AliMUONStringIntMap* svMap = GetSVMap(moduleId);
- Fatal("operator=",
- "Assignment operator is not implemented.");
+ Int_t nofDaughters = gMC->NofVolDaughters(volName);
+ if (nofDaughters == 0) {
+
+ // Get the name of the last volume in the path
+ Ssiz_t npos1 = path0.Last('/')+1;
+ Ssiz_t npos2 = path0.Last('_');
+ TString volName0(path0(npos1, npos2-npos1));
- return *this;
-}
+ // Check if it is sensitive volume
+ AliMUONGeometryModule* geometry = GetGeometry(moduleId);
+ if ( geometry->IsSensitiveVolume(volName0) &&
+ ! svMap->Get(path0) ) {
+ //cout << ".. adding to the map "
+ // << path0 << " " << detElemId << endl;
+
+ // Map the sensitive volume to detection element
+ svMap->Add(path0, detElemId);
+ }
+ return;
+ }
+
+ for (Int_t i=0; i<nofDaughters; i++) {
+ Int_t copyNo = gMC->VolDaughterCopyNo(volName, i);
+ TString newName = gMC->VolDaughterName(volName, i);
+
+ TString path = path0;
+ path += ComposePath(newName, copyNo);
+
+ MapSV(path, newName, detElemId);
+ }
+}
//
-// public methods
+// protected methods
//
//______________________________________________________________________________
-AliMUONChamber* AliMUONVGeometryBuilder::GetChamber(Int_t chamberId) const
+AliMUONGeometryModule*
+AliMUONVGeometryBuilder::GetGeometry(Int_t moduleId) const
{
-// Returns the chamber specified by chamberId
-// ---
+/// Return the module geometry specified by moduleId
+
+ for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
- for (Int_t i=0; i<fChambers->GetEntriesFast(); i++) {
- AliMUONChamber* chamber = (AliMUONChamber*)fChambers->At(i);
- if ( chamber->GetId() == chamberId) return chamber;
+ AliMUONGeometryModule* geometry
+ = (AliMUONGeometryModule*)fGeometryModules->At(i);
+
+ if ( geometry->GetModuleId() == moduleId) return geometry;
}
return 0;
}
+
+//______________________________________________________________________________
+AliMUONGeometryEnvelopeStore*
+AliMUONVGeometryBuilder::GetEnvelopes(Int_t moduleId) const
+{
+/// Return the envelope store of the module geometry specified by moduleId
+
+ AliMUONGeometryModule* geometry = GetGeometry(moduleId);
+
+ if (!geometry) {
+ AliFatal(Form("Module geometry %d is not defined", moduleId));
+ return 0;
+ }
+
+ return geometry->GetEnvelopeStore();
+}
+
+//______________________________________________________________________________
+AliMUONStringIntMap*
+AliMUONVGeometryBuilder::GetSVMap(Int_t moduleId) const
+{
+/// Return the transformation store of the module geometry specified by moduleId
+
+ AliMUONGeometryModule* geometry = GetGeometry(moduleId);
+
+ if (!geometry) {
+ AliFatal(Form("Geometry %d is not defined", moduleId));
+ return 0;
+ }
+
+ return geometry->GetSVMap();
+}
+
+//______________________________________________________________________________
+Int_t
+AliMUONVGeometryBuilder::GetModuleId(const TString& envName) const
+{
+/// Return module Id which has the envelope with given name
+
+ for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
+
+ AliMUONGeometryModule* geometry
+ = (AliMUONGeometryModule*)fGeometryModules->At(i);
+
+ if ( geometry->GetEnvelopeStore()->FindEnvelope(envName) )
+ return geometry->GetModuleId();
+ }
+
+ return -1;
+}
+
+
+//______________________________________________________________________________
+void AliMUONVGeometryBuilder::SetTranslation(Int_t moduleId,
+ const TGeoTranslation& translation)
+{
+/// Set the translation to the geometry module given by moduleId,
+/// apply reference frame transformation
+
+ AliMUONGeometryModule* geometry = GetGeometry(moduleId);
+
+ if (!geometry) {
+ AliFatal(Form("Geometry %d is not defined", moduleId));
+ return;
+ }
+
+ // Apply frame transform
+ TGeoHMatrix newTransform = ConvertTransform(translation);
+
+ // Set new transformation
+ geometry->SetTransformation(newTransform);
+}
+
+
+//______________________________________________________________________________
+void AliMUONVGeometryBuilder::SetTransformation(Int_t moduleId,
+ const TGeoTranslation& translation,
+ const TGeoRotation& rotation)
+{
+/// Set the transformation to the geometry module given by moduleId,
+/// apply reference frame transformation
+
+ AliMUONGeometryModule* geometry = GetGeometry(moduleId);
+
+ if (!geometry) {
+ AliFatal(Form("Geometry %d is not defined", moduleId));
+ return;
+ }
+
+ TGeoCombiTrans transformation
+ = TGeoCombiTrans(translation, rotation);
+
+ // Apply frame transform
+ TGeoHMatrix newTransform = ConvertTransform(transformation);
+
+ // Set new transformation
+ geometry->SetTransformation(newTransform);
+}
+
+//______________________________________________________________________________
+void AliMUONVGeometryBuilder::SetVolume(Int_t moduleId,
+ const TString& volumeName,
+ Bool_t isVirtual)
+{
+/// Set volume name, virtuality
+
+ TString path = GetGeometry(moduleId)->GetVolumePath();
+ // cout << "in AliMUONVGeometryBuilder::SetVolume " << path.Data() << endl;
+
+ if ( path == "" ) path = "/ALIC_1";
+ path += ComposePath(volumeName, 1);
+
+ GetGeometry(moduleId)->SetVolumePath(path);
+ GetGeometry(moduleId)->SetIsVirtual(isVirtual);
+ // cout << "... set " << path.Data() << endl;
+}
+
+//______________________________________________________________________________
+void AliMUONVGeometryBuilder::SetMotherVolume(Int_t moduleId,
+ const TString& volumeName)
+{
+/// Set mother volume name
+
+ TString motherVolumeName = ComposePath(volumeName, 1);
+
+ TString path = GetGeometry(moduleId)->GetVolumePath();
+ if ( path == "" ) path = "/ALIC_1";
+ path.Insert(7, motherVolumeName);
+
+ GetGeometry(moduleId)->SetVolumePath(path);
+}
+
+//
+// public functions
+//
+
+//______________________________________________________________________________
+void AliMUONVGeometryBuilder::SetReferenceFrame(
+ const TGeoCombiTrans& referenceFrame)
+{
+/// Set reference frame to builder and to all associated geometry
+/// modules
+
+ fReferenceFrame = referenceFrame;
+
+ for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
+ AliMUONGeometryModule* geometry
+ = (AliMUONGeometryModule*)fGeometryModules->At(i);
+ AliMUONGeometryEnvelopeStore* envelopeStore
+ = geometry->GetEnvelopeStore();
+
+ envelopeStore->SetReferenceFrame(referenceFrame);
+ }
+}
+
+//______________________________________________________________________________
+void AliMUONVGeometryBuilder::UpdateDetElements(Bool_t create) const
+{
+/// Create or update detection elements:
+/// - if parameter create is true: detection elements are
+/// created and their global and local transformations are filled from geometry.
+/// - otherwise: only the volume path is passed from geometry
+/// to detection elements
+
+ for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
+ AliMUONGeometryModule* geometry
+ = (AliMUONGeometryModule*)fGeometryModules->At(i);
+
+ const TObjArray* envelopes
+ = geometry->GetEnvelopeStore()->GetEnvelopes();
+
+ AliMpExMap* detElements
+ = geometry->GetTransformer()->GetDetElementStore();
+
+ for (Int_t j=0; j<envelopes->GetEntriesFast(); j++) {
+ AliMUONGeometryEnvelope* envelope
+ = (AliMUONGeometryEnvelope*)envelopes->At(j);
+
+ // skip envelope not corresponding to detection element
+ if ( envelope->GetUniqueID() == 0) continue;
+
+ // Get envelope data
+ Int_t detElemId = envelope->GetUniqueID();
+
+ // Compose full volume path
+ TString volPath = geometry->GetVolumePath();
+ volPath += ComposePath(envelope->GetName(), envelope->GetCopyNo());
+
+ if ( create ) {
+ // Create detection element
+ AliMUONGeometryDetElement* detElement
+ = new AliMUONGeometryDetElement(detElemId, volPath);
+ detElements->Add(detElemId, detElement);
+
+ // Compose local transformation
+ const TGeoCombiTrans* transform = envelope->GetTransformation();
+ // Apply frame transform
+ TGeoHMatrix localTransform = ConvertDETransform(*transform);
+ detElement->SetLocalTransformation(localTransform);
+
+ // Compose global transformation
+ TGeoHMatrix globalTransform
+ = AliMUONGeometryBuilder::Multiply(
+ (*geometry->GetTransformer()->GetTransformation()),
+ localTransform );
+ ;
+ // Set the global transformation to detection element
+ detElement->SetGlobalTransformation(globalTransform);
+ }
+ else {
+ // Get existing det elements
+ AliMUONGeometryDetElement* detElement
+ = (AliMUONGeometryDetElement*)detElements->GetValue(detElemId);
+
+ // Set volume path
+ detElement->SetVolumePath(volPath);
+ }
+ }
+ }
+}
+
+//_____ _________________________________________________________________________
+void AliMUONVGeometryBuilder::RebuildSVMaps(Bool_t withEnvelopes) const
+{
+/// Clear the SV maps in memory and fill them from defined geometry.
+
+ for (Int_t i=0; i<fGeometryModules->GetEntriesFast(); i++) {
+ AliMUONGeometryModule* geometry
+ = (AliMUONGeometryModule*)fGeometryModules->At(i);
+
+ // Clear the map
+ geometry->GetSVMap()->Clear();
+
+ // Fill the map from geometry
+ const TObjArray* envelopes
+ = geometry->GetEnvelopeStore()->GetEnvelopes();
+
+ for (Int_t j=0; j<envelopes->GetEntriesFast(); j++) {
+ AliMUONGeometryEnvelope* envelope
+ = (AliMUONGeometryEnvelope*)envelopes->At(j);
+
+ // skip envelope not corresponding to detection element
+ if ( envelope->GetUniqueID() == 0 ) continue;
+
+ // Get volume path of detection element
+ AliMUONGeometryDetElement* detElement
+ = geometry->GetTransformer()->GetDetElement(envelope->GetUniqueID());
+ std::string path0 = detElement->GetVolumePath().Data();
+
+ if ( ! withEnvelopes && geometry->IsVirtual() ) {
+ std::string vName = geometry->GetTransformer()->GetVolumeName().Data();
+ std::string vPath = ComposePath(vName, 1).Data();
+ path0.erase(path0.find(vPath), vPath.size());
+ }
+
+ if ( ! withEnvelopes && envelope->IsVirtual()) {
+ std::string eName = envelope->GetName();
+ std::string ePath = ComposePath(eName, envelope->GetCopyNo()).Data();
+ path0.erase(path0.find(ePath), ePath.size());
+ }
+
+ if ( ! envelope->IsVirtual() )
+ MapSV(path0, envelope->GetName(), envelope->GetUniqueID());
+ else {
+ for (Int_t k=0; k<envelope->GetConstituents()->GetEntriesFast(); k++) {
+ AliMUONGeometryConstituent* constituent
+ = (AliMUONGeometryConstituent*)envelope->GetConstituents()->At(k);
+ TString path = path0;
+ path += ComposePath(constituent->GetName(), constituent->GetCopyNo());
+ MapSV(path, constituent->GetName(), envelope->GetUniqueID());
+ }
+ }
+ }
+ }
+}
+