**************************************************************************/
// $Id$
-//
+
+//-----------------------------------------------------------------------------
// Class AliMUONGeometryBuilder
// ----------------------------
-// MUON manager class for geometry construction,
-// separated form AliMUONv1
-//
+// Manager class for geometry construction via geometry builders.
// Author: Ivana Hrivnacova, IPN Orsay
-
-#include <TClonesArray.h>
-#include <TGeoMatrix.h>
-#include <TVirtualMC.h>
+//-----------------------------------------------------------------------------
#include "AliMUONGeometryBuilder.h"
-#include "AliMUON.h"
-#include "AliMUONChamber.h"
-#include "AliMUONConstants.h"
#include "AliMUONVGeometryBuilder.h"
-#include "AliMUONChamberGeometry.h"
+#include "AliMUONGeometry.h"
+#include "AliMUONGeometryTransformer.h"
+#include "AliMUONGeometryModule.h"
+#include "AliMUONGeometryModuleTransformer.h"
#include "AliMUONGeometryEnvelope.h"
#include "AliMUONGeometryEnvelopeStore.h"
-#include "AliMUONGeometryConstituent.h"
-#include "AliMagF.h"
+#include "AliMUONGeometryDetElement.h"
+#include "AliMUONGeometryConstituent.h"
+
+#include "AliMpDEManager.h"
+
+#include "AliModule.h"
+#include "AliSimulation.h"
+#include "AliLog.h"
#include "AliRun.h"
+#include <TObjArray.h>
+#include <TVirtualMC.h>
+#include <TGeoManager.h>
+
+using std::endl;
+/// \cond CLASSIMP
ClassImp(AliMUONGeometryBuilder)
-
-//______________________________________________________________________________//___________________________________________
-AliMUONGeometryBuilder::AliMUONGeometryBuilder()
- : TObject(),
- fMUON(0),
- fAlign(false),
- fGlobalTransformation(0),
- fGeometryBuilders(0)
+/// \endcond
+
+//
+// static functions
+//
+
+//______________________________________________________________________________
+const TString& AliMUONGeometryBuilder::GetDefaultTransformFileName()
{
-// Default constructor
-}
+ ///< default transformations file name
+ static const TString kDefaultTransformFileName = "transform.dat";
+ return kDefaultTransformFileName;
+}
-//______________________________________________________________________________//___________________________________________
-AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliMUON* muon)
- : TObject(),
- fMUON(muon),
- fAlign(false),
- fGlobalTransformation(0),
- fGeometryBuilders(0)
+//______________________________________________________________________________
+const TString& AliMUONGeometryBuilder::GetDefaultSVMapFileName()
{
-// Standars constructor
+ ///< default svmaps file name
+ static const TString kDefaultSVMapFileName = "svmap.dat";
+ return kDefaultSVMapFileName;
+}
- // Define the global transformation:
- // Transformation from the old ALICE coordinate system to a new one:
- // x->-x, z->-z
- TGeoRotation* rotGlobal
- = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
- fGlobalTransformation = new TGeoCombiTrans(0., 0., 0., rotGlobal);
+//______________________________________________________________________________
+const TString& AliMUONGeometryBuilder::GetOutFileNameExtension()
+{
+ ///< default output file name extension
+ static const TString kOutFileNameExtension = ".out";
+ return kOutFileNameExtension;
+}
- fGeometryBuilders = new TObjArray(AliMUONConstants::NCh());
+
+//______________________________________________________________________________
+TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
+ const TGeoMatrix& m2)
+{
+/// Temporary fix for problem with matrix multiplication in Root 5.02/00
+
+ if (m1.IsIdentity() && m2.IsIdentity()) return TGeoHMatrix();
+
+ if (m1.IsIdentity()) return m2;
+
+ if (m2.IsIdentity()) return m1;
+
+ return m1 * m2;
}
//______________________________________________________________________________
-AliMUONGeometryBuilder::AliMUONGeometryBuilder(const AliMUONGeometryBuilder& right)
- : TObject(right)
-{
- // copy constructor (not implemented)
+TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
+ const TGeoMatrix& m2,
+ const TGeoMatrix& m3)
+{
+/// Temporary fix for problem with matrix multiplication in Root 5.02/00
+
+ if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity())
+ return TGeoHMatrix();
+
+ if (m1.IsIdentity()) return Multiply(m2, m3);
+
+ if (m2.IsIdentity()) return Multiply(m1, m3);
+
+ if (m3.IsIdentity()) return Multiply(m1, m2);
+
+ return m1 * m2 * m3;
+}
- Fatal("AliMUONGeometryBuilder", "Copy constructor not provided.");
+//______________________________________________________________________________
+TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1,
+ const TGeoMatrix& m2,
+ const TGeoMatrix& m3,
+ const TGeoMatrix& m4)
+{
+/// Temporary fix for problem with matrix multiplication in Root 5.02/00
+
+ if (m1.IsIdentity() && m2.IsIdentity() & m3.IsIdentity() & m4.IsIdentity())
+ return TGeoHMatrix();
+
+ if (m1.IsIdentity()) return Multiply(m2, m3, m4);
+
+ if (m2.IsIdentity()) return Multiply(m1, m3, m4);
+
+ if (m3.IsIdentity()) return Multiply(m1, m2, m4);
+
+ if (m4.IsIdentity()) return Multiply(m1, m2, m3);
+
+ return m1 * m2 * m3 * m4;
}
+//
+// ctors, dtor
+//
+
//______________________________________________________________________________
-AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
+AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
+ : TObject(),
+ fModule(module),
+ fAlign(false),
+ fTransformFileName(GetDefaultTransformFileName()),
+ fSVMapFileName(GetDefaultSVMapFileName()),
+ fGlobalTransformation(),
+ fGeometryBuilders(0),
+ fGeometry(0)
{
-// Destructor
+/// Standard constructor
- delete fGlobalTransformation;
+ fGeometryBuilders = new TObjArray();
+ fGeometryBuilders->SetOwner(true);
+
+ fGeometry = new AliMUONGeometry(true);
- if (fGeometryBuilders){
- fGeometryBuilders->Delete();
- delete fGeometryBuilders;
- }
+ // Define the global transformation:
+ // Transformation from the old ALICE coordinate system to a new one:
+ // x->-x, z->-z
+ TGeoRotation* rotGlobal
+ = new TGeoRotation("rotGlobal", 90., 180., 90., 90., 180., 0.);
+ fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
}
//______________________________________________________________________________
-AliMUONGeometryBuilder&
-AliMUONGeometryBuilder::operator=(const AliMUONGeometryBuilder& right)
+AliMUONGeometryBuilder::AliMUONGeometryBuilder()
+ : TObject(),
+ fModule(0),
+ fAlign(false),
+ fTransformFileName(),
+ fSVMapFileName(),
+ fGlobalTransformation(),
+ fGeometryBuilders(0),
+ fGeometry(0)
{
- // assignement operator (not implemented)
-
- // check assignement to self
- if (this == &right) return *this;
+/// Default constructor
+}
- Fatal("operator =", "Assignement operator not provided.");
-
- return *this;
-}
+//______________________________________________________________________________
+AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
+{
+/// Destructor
+
+ delete fGeometryBuilders;
+ delete fGeometry;
+}
//
// private functions
//______________________________________________________________________________
void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mName,
Int_t copyNo, const TGeoHMatrix& matrix,
- Int_t npar, Double_t* param, const char* only) const
+ Int_t npar, Double_t* param, const char* only,
+ Bool_t makeAssembly) const
{
-// Place the volume specified by name with the given transformation matrix
-// ---
+/// Place the volume specified by name with the given transformation matrix
+
+ if (makeAssembly)
+ gGeoManager->MakeVolumeAssembly(name.Data());
- // Do not apply global transformation
- // if mother volume == DDIP
- // (as it is applied on this volume)
TGeoHMatrix transform(matrix);
- if (mName == TString("DDIP")) {
- transform = (*fGlobalTransformation) * transform;
- // To be changed to (*fGlobalTransformation).inverse()
- // when available in TGeo
- // To make this correct also for a general case when
- // (*fGlobalTransformation) * *fGlobalTransformation) != 1
- }
+ // Do not apply global transformation
+ // if mother volume was already placed in
+ // the new system of coordinates (that is MUON in negative Z)
+ // (as it is applied on the mother volume)
+ if (mName == TString("DDIP"))
+ transform = fGlobalTransformation.Inverse() * transform;
// Decompose transformation
const Double_t* xyz = transform.GetTranslation();
// << theta2 << " " << phi2 << " "
// << theta3 << " " << phi3 << endl;
- fMUON->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
+ fModule->AliMatrix(krot, theta1, phi1, theta2, phi2, theta3, phi3);
}
- // Place the volume in ALIC
+ // Place the volume
if (npar == 0)
- gMC->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
+ TVirtualMC::GetMC()->Gspos(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only);
else
- gMC->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
+ TVirtualMC::GetMC()->Gsposp(name, copyNo, mName, xyz[0], xyz[1], xyz[2] , krot, only,
param, npar);
-
}
-//
-// public functions
-//
-
//______________________________________________________________________________
-void AliMUONGeometryBuilder::CreateGeometry()
+void AliMUONGeometryBuilder::CreateGeometryWithTGeo()
{
-//
-// Construct geometry using geometry builders.
-//
-
+/// Construct geometry using geometry builders.
+/// Virtual modules/envelopes are placed as TGeoVolume assembly
+
+ if (fAlign) {
+ // Read transformations from ASCII data file
+ fGeometry->GetTransformer()
+ ->LoadGeometryData(fTransformFileName);
+ }
+
for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
// Get the builder
AliMUONVGeometryBuilder* builder
= (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
- // Create geometry with each builder
- if (builder) {
- if (fAlign) {
- builder->ReadTransformations();
- builder->CreateGeometry();
- }
- else {
- builder->CreateGeometry();
- builder->SetTransformations();
- }
- }
- }
-
- for (Int_t j=0; j<AliMUONConstants::NCh(); j++) {
+ // Create geometry + envelopes
+ //
+ builder->CreateGeometry();
+ builder->SetVolumes();
+ if (!fAlign) builder->SetTransformations();
+
+ // Place module volumes and envelopes
+ //
+ for (Int_t j=0; j<builder->NofGeometries(); j++) {
+
+ AliMUONGeometryModule* geometry = builder->Geometry(j);
+ AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
+ const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
+ TString volName = transformer->GetVolumeName();
+ TString motherVolName = transformer->GetMotherVolumeName();
+
+ // Place the module volume
+ PlaceVolume(volName, motherVolName,
+ 1, *kModuleTransform, 0, 0, "ONLY", geometry->IsVirtual());
+
+ TGeoCombiTrans appliedGlobalTransform;
+ if (builder->ApplyGlobalTransformation())
+ appliedGlobalTransform = fGlobalTransformation;
+
+ // Loop over envelopes
+ const TObjArray* kEnvelopes
+ = geometry->GetEnvelopeStore()->GetEnvelopes();
+ for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
+
+ // Get envelope
+ AliMUONGeometryEnvelope* env
+ = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
+
+ // Check consistency of detElemId and module Id
+ if ( env->GetUniqueID() > 0 &&
+ AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
+ != geometry->GetModuleId() ) {
+
+ AliErrorStream()
+ << "Detection element " << env->GetUniqueID()
+ << " is being placed in geometry module " << geometry->GetModuleId()
+ << " but should go in "
+ << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
+ << endl;
+ AliFatal("Inconsistent IDs");
+ }
+
+ const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
+ const char* only = "ONLY";
+ if (env->IsMANY()) only = "MANY";
+
+ if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
+ // virtual envelope + nof constituents = 0
+ // => not allowed;
+ // empty virtual envelope has no sense
+ AliFatal("Virtual envelope must have constituents.");
+ return;
+ }
- AliMUONChamberGeometry* geometry = fMUON->Chamber(j).GetGeometry();
+ if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
+ // non virtual envelope + nof constituents > 0
+ // => not allowed;
+ // use VMC to place constituents
+ AliFatal("Non virtual envelope cannot have constituents.");
+ return;
+ }
- if (!geometry) continue;
- // Skip chambers with not defined geometry
-
- // Loop over envelopes
- const TObjArray* kEnvelopes = geometry->GetEnvelopeStore()->GetEnvelopes();
- for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
-
- // Get envelope
- AliMUONGeometryEnvelope* env = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
- const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
- const char* only = "ONLY";
- if (env->IsMANY()) only = "MANY";
-
- if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
- // virtual envelope + nof constituents = 0
- // => not allowed;
- // empty virtual envelope has no sense
- Fatal("CreateGeometry", "Virtual envelope must have constituents.");
- return;
- }
-
- if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
- // non virtual envelope + nof constituents > 0
- // => not allowed;
- // use VMC to place constituents
- Fatal("CreateGeometry", "Non virtual envelope cannot have constituents.");
- return;
- }
-
- if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
- // non virtual envelope + nof constituents = 0
- // => place envelope in ALICE by composed transformation:
- // Tglobal * Tch * Tenv
-
- // Compound chamber transformation with the envelope one
+ // Place envelope in geometry module by composed transformation:
+ // [Tglobal] * Tenv
TGeoHMatrix total
- = (*fGlobalTransformation) *
- (*geometry->GetTransformation()) *
- (*kEnvTrans);
- PlaceVolume(env->GetName(), geometry->GetMotherVolume(),
- env->GetCopyNo(), total, 0, 0, only);
- }
-
- if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
- // virtual envelope + nof constituents > 0
- // => do not place envelope and place constituents
- // in ALICE by composed transformation:
- // Tglobal * Tch * Tenv * Tconst
-
- for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
- AliMUONGeometryConstituent* constituent
- = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
-
- // Compound chamber transformation with the envelope one + the constituent one
- TGeoHMatrix total
- = (*fGlobalTransformation) *
- (*geometry->GetTransformation()) *
- (*kEnvTrans) *
- (*constituent->GetTransformation());
-
- PlaceVolume(constituent->GetName(), geometry->GetMotherVolume(),
- constituent->GetCopyNo(), total,
- constituent->GetNpar(), constituent->GetParam(), only);
+ = Multiply( appliedGlobalTransform,
+ (*kEnvTrans) );
+ PlaceVolume(env->GetName(), volName,
+ env->GetCopyNo(), total, 0, 0, only, env->IsVirtual());
+
+ if ( env->IsVirtual() ) {
+ // Place constituents in the envelope
+ for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
+ AliMUONGeometryConstituent* constituent
+ = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
+
+ PlaceVolume(constituent->GetName(), env->GetName(),
+ constituent->GetCopyNo(),
+ *constituent->GetTransformation() ,
+ constituent->GetNpar(), constituent->GetParam(), only);
+ }
}
- }
- }
- }
+ } // end of loop over envelopes
+ } // end of loop over builder geometries
+ } // end of loop over builders
}
-//_____________________________________________________________________________
-void AliMUONGeometryBuilder::CreateMaterials()
+//______________________________________________________________________________
+void AliMUONGeometryBuilder::CreateGeometryWithoutTGeo()
{
-// Definition of common materials
-// --
+/// Construct geometry using geometry builders.
+/// Virtual modules/envelopes are not placed
- //
- // Ar-CO2 gas (80%+20%)
- Float_t ag1[3] = { 39.95,12.01,16. };
- Float_t zg1[3] = { 18.,6.,8. };
- Float_t wg1[3] = { .8,.0667,.13333 };
- Float_t dg1 = .001821;
- //
- // Ar-buthane-freon gas -- trigger chambers
- Float_t atr1[4] = { 39.95,12.01,1.01,19. };
- Float_t ztr1[4] = { 18.,6.,1.,9. };
- Float_t wtr1[4] = { .56,.1262857,.2857143,.028 };
- Float_t dtr1 = .002599;
- //
- // Ar-CO2 gas
- Float_t agas[3] = { 39.95,12.01,16. };
- Float_t zgas[3] = { 18.,6.,8. };
- Float_t wgas[3] = { .74,.086684,.173316 };
- Float_t dgas = .0018327;
- //
- // Ar-Isobutane gas (80%+20%) -- tracking
- Float_t ag[3] = { 39.95,12.01,1.01 };
- Float_t zg[3] = { 18.,6.,1. };
- Float_t wg[3] = { .8,.057,.143 };
- Float_t dg = .0019596;
- //
- // Ar-Isobutane-Forane-SF6 gas (49%+7%+40%+4%) -- trigger
- Float_t atrig[5] = { 39.95,12.01,1.01,19.,32.066 };
- Float_t ztrig[5] = { 18.,6.,1.,9.,16. };
- Float_t wtrig[5] = { .49,1.08,1.5,1.84,0.04 };
- Float_t dtrig = .0031463;
- //
- // bakelite
+ if (fAlign) {
+ // Read transformations from ASCII data file
+ fGeometry->GetTransformer()->LoadGeometryData(fTransformFileName);
+ }
- Float_t abak[3] = {12.01 , 1.01 , 16.};
- Float_t zbak[3] = {6. , 1. , 8.};
- Float_t wbak[3] = {6. , 6. , 1.};
- Float_t dbak = 1.4;
+ for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
- Int_t iSXFLD = gAlice->Field()->Integ();
- Float_t sXMGMX = gAlice->Field()->Max();
- //
- // --- Define the various materials for GEANT ---
- fMUON->AliMaterial(9, "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2);
- fMUON->AliMaterial(10, "ALUMINIUM$", 26.98, 13., 2.7, 8.9, 37.2);
- // Air
- Float_t aAir[4]={12.0107,14.0067,15.9994,39.948};
- Float_t zAir[4]={6.,7.,8.,18.};
- Float_t wAir[4]={0.000124,0.755267,0.231781,0.012827};
- Float_t dAir = 1.20479E-3;
- fMUON->AliMixture(15, "AIR$ ", aAir, zAir, dAir,4, wAir);
- // fMUON->AliMaterial(15, "AIR$ ", 14.61, 7.3, .001205, 30423.24, 67500);
- fMUON->AliMixture(19, "Bakelite$", abak, zbak, dbak, -3, wbak);
- fMUON->AliMixture(20, "ArC4H10 GAS$", ag, zg, dg, 3, wg);
- fMUON->AliMixture(21, "TRIG GAS$", atrig, ztrig, dtrig, -5, wtrig);
- fMUON->AliMixture(22, "ArCO2 80%$", ag1, zg1, dg1, 3, wg1);
- fMUON->AliMixture(23, "Ar-freon $", atr1, ztr1, dtr1, 4, wtr1);
- fMUON->AliMixture(24, "ArCO2 GAS$", agas, zgas, dgas, 3, wgas);
- // materials for slat:
- // Sensitive area: gas (already defined)
- // PCB: copper
- // insulating material and frame: vetronite
- // walls: carbon, rohacell, carbon
- Float_t aglass[5]={12.01, 28.09, 16., 10.8, 23.};
- Float_t zglass[5]={ 6., 14., 8., 5., 11.};
- Float_t wglass[5]={ 0.5, 0.105, 0.355, 0.03, 0.01};
- Float_t dglass=1.74;
-
- // rohacell: C9 H13 N1 O2
- Float_t arohac[4] = {12.01, 1.01, 14.010, 16.};
- Float_t zrohac[4] = { 6., 1., 7., 8.};
- Float_t wrohac[4] = { 9., 13., 1., 2.};
- Float_t drohac = 0.03;
-
- fMUON->AliMaterial(31, "COPPER$", 63.54, 29., 8.96, 1.4, 0.);
- fMUON->AliMixture(32, "Vetronite$",aglass, zglass, dglass, 5, wglass);
- fMUON->AliMaterial(33, "Carbon$", 12.01, 6., 2.265, 18.8, 49.9);
- fMUON->AliMixture(34, "Rohacell$", arohac, zrohac, drohac, -4, wrohac);
-
- Float_t epsil = .001; // Tracking precision,
- Float_t stemax = -1.; // Maximum displacement for multiple scat
- Float_t tmaxfd = -20.; // Maximum angle due to field deflection
- Float_t deemax = -.3; // Maximum fractional energy loss, DLS
- Float_t stmin = -.8;
- Float_t maxDestepAlu = fMUON->GetMaxDestepAlu();
- Float_t maxDestepGas = fMUON->GetMaxDestepGas();
- Float_t maxStepAlu = fMUON->GetMaxStepAlu();
- Float_t maxStepGas = fMUON->GetMaxStepGas();
+ // Get the builder
+ AliMUONVGeometryBuilder* builder
+ = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
+ // Create geometry + envelopes
//
- // Air
- fMUON->AliMedium(1, "AIR_CH_US ", 15, 1, iSXFLD, sXMGMX, tmaxfd, stemax, deemax, epsil, stmin);
- //
- // Aluminum
-
- fMUON->AliMedium(4, "ALU_CH_US ", 9, 0, iSXFLD, sXMGMX, tmaxfd, maxStepAlu,
- maxDestepAlu, epsil, stmin);
- fMUON->AliMedium(5, "ALU_CH_US ", 10, 0, iSXFLD, sXMGMX, tmaxfd, maxStepAlu,
- maxDestepAlu, epsil, stmin);
+ builder->CreateGeometry();
+ if (!fAlign) builder->SetTransformations();
+
+ // Place module volumes and envelopes
//
- // Ar-isoC4H10 gas
+ for (Int_t j=0; j<builder->NofGeometries(); j++) {
+
+ AliMUONGeometryModule* geometry = builder->Geometry(j);
+ AliMUONGeometryModuleTransformer* transformer= geometry->GetTransformer();
+ const TGeoHMatrix* kModuleTransform = transformer->GetTransformation();
+ TString volName = transformer->GetVolumeName();
+ TString motherVolName = transformer->GetMotherVolumeName();
+
+ // Place the module volume
+ if ( !geometry->IsVirtual() ) {
+ PlaceVolume(volName, motherVolName,
+ 1, *kModuleTransform, 0, 0, "ONLY");
+ }
+
+ TGeoCombiTrans appliedGlobalTransform;
+ if (builder->ApplyGlobalTransformation())
+ appliedGlobalTransform = fGlobalTransformation;
+
+ // Loop over envelopes
+ const TObjArray* kEnvelopes
+ = geometry->GetEnvelopeStore()->GetEnvelopes();
+ for (Int_t k=0; k<kEnvelopes->GetEntriesFast(); k++) {
+
+ // Get envelope
+ AliMUONGeometryEnvelope* env
+ = (AliMUONGeometryEnvelope*)kEnvelopes->At(k);
+
+ // Check consistency of detElemId and module Id
+ if ( env->GetUniqueID() > 0 &&
+ AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
+ != geometry->GetModuleId() ) {
+
+ AliErrorStream()
+ << "Detection element " << env->GetUniqueID()
+ << " is being placed in geometry module " << geometry->GetModuleId()
+ << " but should go in "
+ << AliMpDEManager::GetGeomModuleId(env->GetUniqueID())
+ << endl;
+ AliFatal("Inconsistent IDs");
+ }
+
+ const TGeoCombiTrans* kEnvTrans = env->GetTransformation();
+ const char* only = "ONLY";
+ if (env->IsMANY()) only = "MANY";
+
+ if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
+ // virtual envelope + nof constituents = 0
+ // => not allowed;
+ // empty virtual envelope has no sense
+ AliFatal("Virtual envelope must have constituents.");
+ return;
+ }
- fMUON->AliMedium(6, "AR_CH_US ", 20, 1, iSXFLD, sXMGMX, tmaxfd, maxStepGas,
- maxDestepGas, epsil, stmin);
-//
- // Ar-Isobuthane-Forane-SF6 gas
+ if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
+ // non virtual envelope + nof constituents > 0
+ // => not allowed;
+ // use VMC to place constituents
+ AliFatal("Non virtual envelope cannot have constituents.");
+ return;
+ }
- fMUON->AliMedium(7, "GAS_CH_TRIGGER ", 21, 1, iSXFLD, sXMGMX, tmaxfd, stemax, deemax, epsil, stmin);
+ if (!env->IsVirtual() && env->GetConstituents()->GetEntriesFast() == 0 ) {
+ // non virtual envelope + nof constituents = 0
+ // => place envelope by composed transformation:
+ // Tch * [Tglobal] * Tenv
+
+ // Compound chamber transformation with the envelope one
+ if (geometry->IsVirtual()) {
+ TGeoHMatrix total
+ = Multiply( (*kModuleTransform),
+ appliedGlobalTransform,
+ (*kEnvTrans) );
+ PlaceVolume(env->GetName(), motherVolName,
+ env->GetCopyNo(), total, 0, 0, only);
+ }
+ else {
+ TGeoHMatrix total
+ = Multiply( appliedGlobalTransform,
+ (*kEnvTrans) );
+ PlaceVolume(env->GetName(), volName,
+ env->GetCopyNo(), total, 0, 0, only);
+ }
+ }
- fMUON->AliMedium(8, "BAKE_CH_TRIGGER ", 19, 0, iSXFLD, sXMGMX, tmaxfd, maxStepAlu,
- maxDestepAlu, epsil, stmin);
+ if (env->IsVirtual() && env->GetConstituents()->GetEntriesFast() > 0 ) {
+ // virtual envelope + nof constituents > 0
+ // => do not place envelope and place constituents
+ // by composed transformation:
+ // Tch * [Tglobal] * Tenv * Tconst
- fMUON->AliMedium(9, "ARG_CO2 ", 22, 1, iSXFLD, sXMGMX, tmaxfd, maxStepGas,
- maxDestepAlu, epsil, stmin);
- // tracking media for slats: check the parameters!!
- fMUON->AliMedium(11, "PCB_COPPER ", 31, 0, iSXFLD, sXMGMX, tmaxfd,
- maxStepAlu, maxDestepAlu, epsil, stmin);
- fMUON->AliMedium(12, "VETRONITE ", 32, 0, iSXFLD, sXMGMX, tmaxfd,
- maxStepAlu, maxDestepAlu, epsil, stmin);
- fMUON->AliMedium(13, "CARBON ", 33, 0, iSXFLD, sXMGMX, tmaxfd,
- maxStepAlu, maxDestepAlu, epsil, stmin);
- fMUON->AliMedium(14, "Rohacell ", 34, 0, iSXFLD, sXMGMX, tmaxfd,
- maxStepAlu, maxDestepAlu, epsil, stmin);
+ for (Int_t l=0; l<env->GetConstituents()->GetEntriesFast(); l++) {
+ AliMUONGeometryConstituent* constituent
+ = (AliMUONGeometryConstituent*)env->GetConstituents()->At(l);
+
+ // Compound chamber transformation with the envelope one + the constituent one
+ if (geometry->IsVirtual()) {
+ TGeoHMatrix total
+ = Multiply ( (*kModuleTransform),
+ appliedGlobalTransform,
+ (*kEnvTrans),
+ (*constituent->GetTransformation()) );
+
+ PlaceVolume(constituent->GetName(), motherVolName,
+ constituent->GetCopyNo(), total,
+ constituent->GetNpar(), constituent->GetParam(), only);
+ }
+ else {
+ TGeoHMatrix total
+ = Multiply ( appliedGlobalTransform,
+ (*kEnvTrans),
+ (*constituent->GetTransformation()) );
+
+ PlaceVolume(constituent->GetName(), volName,
+ constituent->GetCopyNo(), total,
+ constituent->GetNpar(), constituent->GetParam(), only);
+ }
+ }
+ }
+ } // end of loop over envelopes
+ } // end of loop over builder geometries
+ } // end of loop over builders
+}
+//_____________________________________________________________________________
+void AliMUONGeometryBuilder::SetAlignToBuilder(AliMUONVGeometryBuilder* builder) const
+{
+/// Set align option to all geometry modules associated with the builder
+ for (Int_t j=0; j<builder->NofGeometries(); j++) {
- //.Materials specific to stations
- // created via builders
+ AliMUONGeometryModule* geometry = builder->Geometry(j);
- for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
+ geometry->SetAlign(fAlign);
+ }
+}
- // Get the builder
- AliMUONVGeometryBuilder* builder
- = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
+//
+// public functions
+//
- // Create materials with each builder
- if (builder) builder->CreateMaterials();
- }
+//_____________________________________________________________________________
+void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
+{
+/// Add the geometry builder to the list
+
+ fGeometryBuilders->Add(geomBuilder);
+
+ // Pass geometry modules created in the to the geometry parametrisation
+ for (Int_t i=0; i<geomBuilder->NofGeometries(); i++) {
+ fGeometry->AddModule(geomBuilder->Geometry(i));
+ }
+
+ if (geomBuilder->ApplyGlobalTransformation())
+ geomBuilder->SetReferenceFrame(fGlobalTransformation);
+
+ SetAlignToBuilder(geomBuilder);
}
//______________________________________________________________________________
-void AliMUONGeometryBuilder::InitGeometry()
+void AliMUONGeometryBuilder::CreateGeometry()
{
- // Initialize geometry
- // ---
+/// Construct geometry using geometry builders.
+
+ if ( TVirtualMC::GetMC()->IsRootGeometrySupported() ) {
+
+ CreateGeometryWithTGeo();
+ }
+ else
+ CreateGeometryWithoutTGeo();
- //
- // Set the chamber (sensitive region) GEANT identifier
- //
for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
// Get the builder
AliMUONVGeometryBuilder* builder
= (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
-
- // Set sesitive volumes with each builder
- builder->SetSensitiveVolumes();
-
- // Read sensitive volume map from a file
- builder->ReadSVMap();
- if (!fAlign) builder->FillTransformations();
+
+ // Update detection elements from built geometry
+ Bool_t create = ! fAlign;
+ builder->UpdateDetElements(create);
}
}
-//______________________________________________________________________________
-void AliMUONGeometryBuilder::WriteTransformations()
+//_____________________________________________________________________________
+void AliMUONGeometryBuilder::CreateMaterials()
{
- // Writes transformations into files per builder
- // ---
-
+/// Construct materials specific to modules via builders
+
for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
// Get the builder
AliMUONVGeometryBuilder* builder
= (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
- // Write transformations
- builder->WriteTransformations();
+ // Create materials with each builder
+ if (builder) builder->CreateMaterials();
}
}
//______________________________________________________________________________
-void AliMUONGeometryBuilder::WriteSVMaps(Bool_t rebuild)
+void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
{
- // Writes sensitive volume maps into files per builder
- // ---
+/// Initialize geometry
+
+ // Load alignement data from geometry if geometry is read from Root file
+ if ( AliSimulation::Instance()->IsGeometryFromFile() ) {
+ fAlign = true;
+ fGeometry->GetTransformer()->LoadGeometryData();
+ }
+ // Read sensitive volume map from a file
+ fGeometry->ReadSVMap(svmapFileName);
+
+ // Set the chamber (sensitive region) GEANT identifier
+ //
for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
// Get the builder
AliMUONVGeometryBuilder* builder
= (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
- // Write transformations
- builder->WriteSVMap(rebuild);
- }
+ // Set sensitive volumes with each builder
+ builder->SetSensitiveVolumes();
+ }
}
-//_____________________________________________________________________________
-void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
+//________________________________________________________________
+void AliMUONGeometryBuilder::UpdateInternalGeometry()
{
-// Adds the geometry builder to the list
-// ---
+/// Update geometry after applying mis-alignment:
+/// reload transformations in geometry builder.
- fGeometryBuilders->Add(geomBuilder);
+ fGeometry->GetTransformer()->LoadTransformations();
+}
+
+//______________________________________________________________________________
+void AliMUONGeometryBuilder::WriteSVMaps(const TString& fileName,
+ Bool_t rebuild, Bool_t writeEnvelopes)
+{
+/// Write sensitive volume maps into files per builder
+
+ // Rebuild sv maps
+ //
+ if (rebuild)
+ for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
+
+ AliMUONVGeometryBuilder* builder
+ = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
+
+ builder->RebuildSVMaps(writeEnvelopes);
+ }
+
+ // Write maps in file
+ fGeometry->WriteSVMap(fileName);
}
//_____________________________________________________________________________
void AliMUONGeometryBuilder::SetAlign(Bool_t align)
{
-// Sets the option for alignement
-// ---
+/// Set the option for alignement
fAlign = align;
- for (Int_t j=0; j<AliMUONConstants::NCh(); j++) {
-
- AliMUONChamberGeometry* geometry = fMUON->Chamber(j).GetGeometry();
+ for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
- if (!geometry) continue;
- // Skip chambers with not defined geometry
-
- geometry->SetAlign(align);
- }
+ AliMUONVGeometryBuilder* builder
+ = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
+
+ SetAlignToBuilder(builder);
+ }
}
+//_____________________________________________________________________________
+void AliMUONGeometryBuilder::SetAlign(const TString& fileName, Bool_t align)
+{
+/// Set the option for alignement and the transformations file name
+
+ fTransformFileName = fileName;
+ fAlign = align;
+
+ for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
+ AliMUONVGeometryBuilder* builder
+ = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
+
+ SetAlignToBuilder(builder);
+ }
+}