]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONGeometryBuilder.cxx
- Revised comments and adapted them for Doxygen
[u/mrichter/AliRoot.git] / MUON / AliMUONGeometryBuilder.cxx
index 759547d356749211aba2fc4f9352c3f07ecce13e..e11326f69c2249e6ef828e3a1a5aeab34a48e3ff 100644 (file)
 
 // $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 "AliMUONGeometryStore.h"
+#include "AliMUONGeometryConstituent.h"
+
+#include "AliModule.h"
+#include "AliLog.h"
 #include "AliRun.h"
 
-ClassImp(AliMUONGeometryBuilder)
+#include <TObjArray.h>
+#include <TVirtualMC.h>
+#include <TGeoManager.h>
+
+// static data members
  
-//______________________________________________________________________________//___________________________________________
-AliMUONGeometryBuilder::AliMUONGeometryBuilder() 
-  : TObject(),
-    fMUON(0),
-    fAlign(false),
-    fGlobalTransformation(0),
-    fGeometryBuilders(0)
+const TString  AliMUONGeometryBuilder::fgkDefaultVolPathsFileName = "volpath.dat";   
+const TString  AliMUONGeometryBuilder::fgkDefaultTransformFileName = "transform.dat";   
+const TString  AliMUONGeometryBuilder::fgkDefaultSVMapFileName = "svmap.dat";    
+const TString  AliMUONGeometryBuilder::fgkOutFileNameExtension = ".out";    
+
+/// \cond CLASSIMP
+ClassImp(AliMUONGeometryBuilder)
+/// \endcond
+
+// static functions
+
+//______________________________________________________________________________
+TGeoHMatrix AliMUONGeometryBuilder::Multiply(const TGeoMatrix& m1, 
+                                             const TGeoMatrix& m2)
 {
-// Default constructor
-} 
+/// 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(AliMUON* muon)
+//______________________________________________________________________________
+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;
+}
+
+//______________________________________________________________________________
+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;
+}
+
+//______________________________________________________________________________
+AliMUONGeometryBuilder::AliMUONGeometryBuilder(AliModule* module)
   : TObject(),
-    fMUON(muon),
+    fModule(module),
     fAlign(false),
-    fGlobalTransformation(0), 
-    fGeometryBuilders(0)
+    fTransformFileName(fgkDefaultTransformFileName),
+    fSVMapFileName(fgkDefaultSVMapFileName),
+    fGlobalTransformation(), 
+    fGeometryBuilders(0),
+    fGeometry(0)
 {
-// Standars constructor
+/// Standard constructor
+
+  fGeometryBuilders = new TObjArray();
+  fGeometryBuilders->SetOwner(true);
+  
+  fGeometry = new AliMUONGeometry(true);
 
   // 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);
-
-  fGeometryBuilders = new TObjArray(AliMUONConstants::NCh());
+  fGlobalTransformation = TGeoCombiTrans(0., 0., 0., rotGlobal);
 }
 
 //______________________________________________________________________________
-AliMUONGeometryBuilder::AliMUONGeometryBuilder(const AliMUONGeometryBuilder& right) 
-  : TObject(right) 
-{  
-  // copy constructor (not implemented)
-
-  Fatal("AliMUONGeometryBuilder", "Copy constructor not provided.");
-}
+AliMUONGeometryBuilder::AliMUONGeometryBuilder() 
+  : TObject(),
+    fModule(0),
+    fAlign(false),
+    fTransformFileName(),
+    fSVMapFileName(),
+    fGlobalTransformation(),
+    fGeometryBuilders(0),
+    fGeometry(0)
+{
+/// Default constructor
+} 
 
 //______________________________________________________________________________
 AliMUONGeometryBuilder::~AliMUONGeometryBuilder()
 {
-// Destructor
-
-  delete fGlobalTransformation;
-
-  if (fGeometryBuilders){
-    fGeometryBuilders->Delete();
-    delete fGeometryBuilders;
-  }
+/// Destructor
+  
+  delete fGeometryBuilders;
+  delete fGeometry;
 }
 
-//______________________________________________________________________________
-AliMUONGeometryBuilder& 
-AliMUONGeometryBuilder::operator=(const AliMUONGeometryBuilder& right)
-{
-  // assignement operator (not implemented)
-
-  // check assignement to self
-  if (this == &right) return *this;
-
-  Fatal("operator =", "Assignement operator not provided.");
-    
-  return *this;  
-}    
-
 //
 // private functions
 //
@@ -114,22 +166,21 @@ AliMUONGeometryBuilder::operator=(const AliMUONGeometryBuilder& right)
 //______________________________________________________________________________
 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();
@@ -169,254 +220,299 @@ void AliMUONGeometryBuilder::PlaceVolume(const TString& name, const TString& mNa
     //     << 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);
   else 
     gMC->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()
+      ->ReadGeometryData(fgkDefaultVolPathsFileName, 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();
+    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);
+         
+        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()
+      ->ReadGeometryData(fgkDefaultVolPathsFileName, 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);
+    builder->CreateGeometry();
+    if (!fAlign) builder->SetTransformations();
+    
+    // Place module volumes and envelopes
     //
-    //    Aluminum 
+    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);
+         
+        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(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);
-    //
-    //    Ar-isoC4H10 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(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 
+          //        => 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(7, "GAS_CH_TRIGGER    ", 21, 1, iSXFLD, sXMGMX, tmaxfd, stemax, deemax, 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(8, "BAKE_CH_TRIGGER   ", 19, 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
+}
 
-    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);
+//_____________________________________________________________________________
+void AliMUONGeometryBuilder::SetAlign(AliMUONVGeometryBuilder* builder)
+{
+/// Set align option to all geometry modules associated with the builder
+
+  for (Int_t j=0; j<builder->NofGeometries(); j++) {
 
+    AliMUONGeometryModule* geometry = builder->Geometry(j);
+  
+    geometry->SetAlign(fAlign);
+  }      
+}           
 
+//
+// public functions
+//
+
+//_____________________________________________________________________________
+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);
+  
+  SetAlign(geomBuilder);
+}
+
+//______________________________________________________________________________
+void AliMUONGeometryBuilder::CreateGeometry()
+{
+/// Construct geometry using geometry builders.
+
+  if ( gMC->IsRootGeometrySupported() && 
+       TString(gMC->ClassName()) != "TGeant4" ) {
+       
+   CreateGeometryWithTGeo();
+  } 
+  else
+   CreateGeometryWithoutTGeo();
+}
 
-  //.Materials specific to stations
-  // created via builders
+//_____________________________________________________________________________
+void AliMUONGeometryBuilder::CreateMaterials()
+{
+/// Construct materials specific to modules via builders
   
   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
 
@@ -430,12 +526,21 @@ void AliMUONGeometryBuilder::CreateMaterials()
 }
 
 //______________________________________________________________________________
-void AliMUONGeometryBuilder::InitGeometry()
+void AliMUONGeometryBuilder::InitGeometry(const TString& svmapFileName)
 {
- // Initialize geometry
- // ---
+/// Initialize geometry
 
-  //
+  // Load alignement data from geometry if geometry is read from Root file
+  if ( gAlice->IsRootGeometry() ) {
+    fAlign = true;
+
+    fGeometry->GetTransformer()
+      ->ReadGeometryData(fgkDefaultVolPathsFileName, gGeoManager);
+  }    
+
+  // 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++) {
@@ -444,75 +549,70 @@ void AliMUONGeometryBuilder::InitGeometry()
     AliMUONVGeometryBuilder* builder
       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
 
-    // Set sesitive volumes with each builder
+    // Set sensitive volumes with each builder
     builder->SetSensitiveVolumes();
 
-    // Read sensitive volume map from a file
-    builder->ReadSVMap();
-    if (!fAlign)  builder->FillTransformations();
-  }
+    if (!fAlign)  {
+      // Create detection elements from built geometry
+      builder->CreateDetElements();
+    }  
+  }  
 }
 
 //______________________________________________________________________________
-void AliMUONGeometryBuilder::WriteTransformations()
+void AliMUONGeometryBuilder::WriteSVMaps(const TString& fileName, 
+                                         Bool_t rebuild)
 {
- // Writes transformations into files per builder
- // ---
+/// Write sensitive volume maps into files per builder
 
-  for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
+  // Rebuild sv maps
+  //
+  if (rebuild) 
+    for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
 
-    // Get the builder
-    AliMUONVGeometryBuilder* builder
-      = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
+      AliMUONVGeometryBuilder* builder
+        = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
 
-    // Write transformations
-    builder->WriteTransformations();
-  }
+      Bool_t writeEnvelopes = false;
+      if ( gMC->IsRootGeometrySupported() &&
+           TString(gMC->ClassName()) != "TGeant4") writeEnvelopes = true;
+
+      builder->RebuildSVMaps(writeEnvelopes);
+    }  
+    
+  // Write maps in file
+  fGeometry->WriteSVMap(fileName);
 }
 
-//______________________________________________________________________________
-void AliMUONGeometryBuilder::WriteSVMaps(Bool_t rebuild)
-{
- // Writes sensitive volume maps into files per builder
- // ---
+//_____________________________________________________________________________
+void AliMUONGeometryBuilder::SetAlign(Bool_t align)
+{ 
+/// Set the option for alignement
+
+  fAlign = align; 
 
   for (Int_t i=0; i<fGeometryBuilders->GetEntriesFast(); i++) {
 
-    // Get the builder
     AliMUONVGeometryBuilder* builder
       = (AliMUONVGeometryBuilder*)fGeometryBuilders->At(i);
-
-    // Write transformations      
-    builder->WriteSVMap(rebuild);
-  }
-}
-
-//_____________________________________________________________________________
-void AliMUONGeometryBuilder::AddBuilder(AliMUONVGeometryBuilder* geomBuilder)
-{
-// Adds the geometry builder to the list
-// ---
-
-  fGeometryBuilders->Add(geomBuilder);
+    
+    SetAlign(builder); 
+  }   
 }
 
 //_____________________________________________________________________________
-void AliMUONGeometryBuilder::SetAlign(Bool_t align)
+void AliMUONGeometryBuilder::SetAlign(const TString& fileName, Bool_t align)
 { 
-// Sets the option for alignement
-// ---
+/// Set the option for alignement and the transformations file name
 
+  fTransformFileName = fileName;
   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);
+    
+    SetAlign(builder); 
+  }   
 }
-
-