]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PHOS/AliPHOSv0.cxx
Overlaps and extrrusions in the volume PWTI are fixed
[u/mrichter/AliRoot.git] / PHOS / AliPHOSv0.cxx
index f77a423bb7f070e3c88762fd26ba1c77bd2851e8..27a2bdaeb2058927828c6d1b32389068d4f94765 100644 (file)
  * about the suitability of this software for any purpose. It is          *
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
+/* $Id$ */
+
+/* History of cvs commits:
+ *
+ * $Log$
+ * Revision 1.94  2007/10/18 08:40:02  kharlov
+ * Misalignment-related bug fixed
+ *
+ * Revision 1.93  2007/10/06 22:24:40  kharlov
+ * Bug in strip unit geometry is corrected
+ *
+ * Revision 1.92  2007/07/04 16:38:19  policheh
+ * Tracking2LocalCS matrices corrected for CPV.
+ *
+ * Revision 1.91  2007/07/02 14:50:49  policheh
+ * Tracking2LocalCS matrices corrected.
+ *
+ * Revision 1.90  2007/05/24 13:04:05  policheh
+ * AddAlignableVolumes: local to tracking CS transformation matrices creates for each
+ * PHOS supermodule
+ *
+ * Revision 1.89  2007/04/24 14:34:39  hristov
+ * Additional protection: do not search for alignable object if the CPV is not in the geometry
+ *
+ * Revision 1.88  2007/04/19 15:28:30  kharlov
+ * Modify strip unit geometry according to the final drawings (Timur)
+ *
+ * Revision 1.87  2007/04/01 07:37:10  kharlov
+ * TGeo RS to Local RS transf matr added
+ *
+ * Revision 1.86  2007/03/06 06:55:46  kharlov
+ * DP:Misalignment of CPV added
+ *
+ * Revision 1.85  2007/03/01 11:37:37  kharlov
+ * Strip units changed from 8x1 to 8x2 (T.Pocheptsov)
+ *
+ * Revision 1.84  2006/12/20 16:56:43  kharlov
+ * Optional geometry without CPV
+ *
+ * Revision 1.83  2006/11/14 17:11:15  hristov
+ * Removing inheritances from TAttLine, TAttMarker and AliRndm in AliModule. The copy constructor and assignment operators are moved to the private part of the class and not implemented. The corresponding changes are propagated to the detectors
+ *
+ * Revision 1.82  2006/09/27 19:55:57  kharlov
+ * Alignment object with symbolic volume names are introduced
+ *
+ * Revision 1.81  2006/03/04 20:25:56  kharlov
+ * Set geom parameters from CDB
+ *
+ * Revision 1.80  2005/06/17 07:39:07  hristov
+ * Removing GetDebug and SetDebug from AliRun and AliModule. Using AliLog for the messages
+ *
+ * Revision 1.79  2005/05/28 14:19:05  schutz
+ * Compilation warnings fixed by T.P.
+ *
+ */
 
 //_________________________________________________________________________
-// Manager class for PHOS version SUBATECH
-//*-- Author : Y. Schutz SUBATECH 
-//////////////////////////////////////////////////////////////////////////////
+// Implementation version v0 of PHOS Manager class 
+// An object of this class does not produce hits nor digits
+// It is the one to use if you do not want to produce outputs in TREEH or TREED
+//                  
+//*-- Author: Yves Schutz (SUBATECH) & Dmitri Peressounko (RRC KI & SUBATECH)
+
 
 // --- ROOT system ---
 
-#include "TBRIK.h"
-#include "TNode.h"
+#include <TBRIK.h>
+#include <TFolder.h>
+#include <TGeometry.h>
+#include <TNode.h>
+#include <TROOT.h>
+#include <TRandom.h>
+#include <TTRD1.h>
+#include <TTree.h>
+#include <TVirtualMC.h>
+#include <TGeoPhysicalNode.h>
+#include <TGeoManager.h>
+#include <TGeoMatrix.h>
+#include <TVector3.h>
 
 // --- Standard library ---
 
-#include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <strstream.h>
-#include <assert.h>
 
 // --- AliRoot header files ---
 
+#include "AliConst.h"
+#include "AliPHOSGeometry.h"
+#include "AliPHOSLoader.h"
 #include "AliPHOSv0.h"
-#include "AliPHOSHit.h"
-#include "AliPHOSDigit.h"
-#include "AliPHOSReconstructioner.h"
 #include "AliRun.h"
-#include "AliConst.h"
+#include "AliLog.h"
+#include "AliGeomManager.h"
 
 ClassImp(AliPHOSv0)
 
-//____________________________________________________________________________
-AliPHOSv0::AliPHOSv0()
-{
-  fNTmpHits = 0 ; 
-  fTmpHits  = 0 ; 
-}
-
 //____________________________________________________________________________
 AliPHOSv0::AliPHOSv0(const char *name, const char *title):
   AliPHOS(name,title)
 {
-  
-  // We use 2 arrays of hits :
-  //
-  //   - fHits (the "normal" one), which retains the hits associated with
-  //     the current primary particle being tracked
-  //     (this array is reset after each primary has been tracked).
-  //
-  //   - fTmpHits, which retains all the hits of the current event. It 
-  //     is used for the digitization part.
-
-  fHits   = new TClonesArray("AliPHOSHit",100) ;
-  fDigits = new TClonesArray("AliPHOSDigit",100) ;
-  fTmpHits= new TClonesArray("AliPHOSHit",100) ;
-
-  assert ( fHits != 0 ) ;
-  assert ( fDigits != 0 ) ;
-  assert ( fTmpHits != 0 ) ;
-
-  fNTmpHits = fNhits = 0 ;
-
-  fIshunt     =  1 ; // All hits are associated with primary particles
-  // gets an instance of the geometry parameters class  
-  fGeom =  AliPHOSGeometry::GetInstance(title, "") ; 
-
-  if (fGeom->IsInitialized() ) 
-    cout << "AliPHOSv0 : PHOS geometry intialized for " << fGeom->GetName() << endl ;
-  else
-   cout << "AliPHOSv0 : PHOS geometry initialization failed !" << endl ;   
-}
-//____________________________________________________________________________
-AliPHOSv0::AliPHOSv0(AliPHOSReconstructioner&  Reconstructioner, const char *name, const char *title):
-  AliPHOS(name,title)
-{
-  
-  // We use 2 arrays of hits :
-  //
-  //   - fHits (the "normal" one), which retains the hits associated with
-  //     the current primary particle being tracked
-  //     (this array is reset after each primary has been tracked).
-  //
-  //   - fTmpHits, which retains all the hits of the current event. It 
-  //     is used for the digitization part.
-
-  fHits   = new TClonesArray("AliPHOSHit",100) ;
-  fDigits = new TClonesArray("AliPHOSDigit",100) ;
-  fTmpHits= new TClonesArray("AliPHOSHit",100) ;
-
-  assert ( fHits != 0 ) ;
-  assert ( fDigits != 0 ) ;
-  assert ( fTmpHits != 0 ) ;
-
-  fNTmpHits = fNhits = 0 ;
-
-  fIshunt     =  1 ; // All hits are associated with primary particles
-  // gets an instance of the geometry parameters class  
-  fGeom =  AliPHOSGeometry::GetInstance(title, "") ; 
-
-  if (fGeom->IsInitialized() ) 
-    cout << "AliPHOSv0 : PHOS geometry intialized for " << fGeom->GetName() << endl ;
-  else
-   cout << "AliPHOSv0 : PHOS geometry initialization failed !" << endl ;   
-
-  // Defining the PHOS Reconstructioner
- fReconstructioner = &Reconstructioner;
-}
-
-//____________________________________________________________________________
-AliPHOSv0::~AliPHOSv0()
-{
-  delete fHits ;
-  delete fTmpHits ;
-  delete fDigits ;
-}
-
-//____________________________________________________________________________
-void AliPHOSv0::AddHit(Int_t track, Int_t Id, Float_t * hits)
-{
-  Int_t hitCounter ;
-  TClonesArray &ltmphits = *fTmpHits;
-  AliPHOSHit *newHit ;
-  AliPHOSHit *curHit;
-  bool already = false ;
-
-  // In any case, fills the fTmpHit TClonesArray (with "accumulated hits")
-
-  newHit = new AliPHOSHit(fIshunt, track, Id, hits) ;
-
-  for ( hitCounter = 0 ; hitCounter < fNTmpHits && !already ; hitCounter++ ) {
-    curHit = (AliPHOSHit*) ltmphits[hitCounter] ;
-    if( *curHit == *newHit ) {
-      *curHit = *curHit + *newHit ;
-      already = true ;
-    }
-  }
-       
-  if ( !already ) {
-    new(ltmphits[fNTmpHits]) AliPHOSHit(*newHit) ;
-    fNTmpHits++ ;
-  }
-
-  // Please note that the fTmpHits array must survive up to the
-  // end of the events, so it does not appear e.g. in ResetHits() (
-  // which is called at the end of each primary).  
-
-  //  if (IsTreeSelected('H')) {
-    // And, if we really want raw hits tree, have the fHits array filled also
-  //    TClonesArray &lhits = *fHits;
-  //    new(lhits[fNhits]) AliPHOSHit(*newHit) ;
-  //    fNhits++ ;
-  //  }
-
-   delete newHit;
-
+  // ctor : title is used to identify the layout
+  GetGeometry() ; 
 }
 
-
 //____________________________________________________________________________
 void AliPHOSv0::BuildGeometry()
 {
-
-  this->BuildGeometryforPHOS() ; 
-  if ( ( strcmp(fGeom->GetName(), "GPS2" ) == 0 ) ) 
-    this->BuildGeometryforPPSD() ;
-  else
-    cout << "AliPHOSv0::BuildGeometry : no charged particle identification system installed" << endl; 
-
+  // Build the PHOS geometry for the ROOT display
+  //BEGIN_HTML
+  /*
+    <H2>
+     PHOS in ALICE displayed by root
+    </H2>
+    <UL>
+    <LI> All Views
+    <P>
+    <CENTER>
+    <IMG Align=BOTTOM ALT="All Views" SRC="../images/AliPHOSv0AllViews.gif"> 
+    </CENTER></P></LI>
+    <LI> Front View
+    <P>
+    <CENTER>
+    <IMG Align=BOTTOM ALT="Front View" SRC="../images/AliPHOSv0FrontView.gif"> 
+    </CENTER></P></LI>
+     <LI> 3D View 1
+    <P>
+    <CENTER>
+    <IMG Align=BOTTOM ALT="3D View 1" SRC="../images/AliPHOSv03DView1.gif"> 
+    </CENTER></P></LI>
+    <LI> 3D View 2
+    <P>
+    <CENTER>
+    <IMG Align=BOTTOM ALT="3D View 2" SRC="../images/AliPHOSv03DView2.gif"> 
+    </CENTER></P></LI>
+    </UL>
+  */
+  //END_HTML  
+  
+  this->BuildGeometryforEMC() ; 
+  this->BuildGeometryforCPV() ;
+  
 }
 
 //____________________________________________________________________________
-void AliPHOSv0:: BuildGeometryforPHOS(void)
+void AliPHOSv0:: BuildGeometryforEMC(void)
 {
// Build the PHOS geometry for the ROOT display
-
 // Build the PHOS-EMC geometry for the ROOT display
+  
   const Int_t kColorPHOS = kRed ;
   const Int_t kColorXTAL = kBlue ;
-
-  Double_t const RADDEG = 180.0 / kPI ;
-  new TBRIK( "OuterBox", "PHOS box", "void", fGeom->GetOuterBoxSize(0)/2, 
-                                             fGeom->GetOuterBoxSize(1)/2, 
-                                             fGeom->GetOuterBoxSize(2)/2 );
-
-  // Textolit Wall box, position inside PHOS 
   
-  new TBRIK( "TextolitBox", "PHOS Textolit box ", "void", fGeom->GetTextolitBoxSize(0)/2, 
-                                                          fGeom->GetTextolitBoxSize(1)/2, 
-                                                          fGeom->GetTextolitBoxSize(2)/2);
-
-  // Polystyrene Foam Plate
-
-  new TBRIK( "UpperFoamPlate", "PHOS Upper foam plate", "void", fGeom->GetTextolitBoxSize(0)/2, 
-                                                                fGeom->GetSecondUpperPlateThickness()/2, 
-                                                                fGeom->GetTextolitBoxSize(2)/2 ) ; 
-
-  // Air Filled Box
-  new TBRIK( "AirFilledBox", "PHOS air filled box", "void", fGeom->GetAirFilledBoxSize(0)/2, 
-                                                            fGeom->GetAirFilledBoxSize(1)/2, 
-                                                            fGeom->GetAirFilledBoxSize(2)/2 );
+  Double_t const kRADDEG = 180.0 / TMath::Pi() ;
+  
+  AliPHOSGeometry * geom = GetGeometry() ; 
+  AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
+  Float_t * boxparams = emcg->GetEMCParams() ;
 
+  new TTRD1("OuterBox", "PHOS box", "void",boxparams[0],boxparams[1],boxparams[2], boxparams[3] );
+  
+  
   // Crystals Box
-
-  Float_t XTL_X = fGeom->GetCrystalSize(0) ; 
-  Float_t XTL_Y = fGeom->GetCrystalSize(1) ; 
-  Float_t XTL_Z = fGeom->GetCrystalSize(2) ; 
-
-  Float_t XL =  fGeom->GetNPhi() * ( XTL_X + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 + fGeom->GetModuleBoxThickness() ;
-  Float_t YL =  ( XTL_Y + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 
-             + fGeom->GetModuleBoxThickness() / 2.0 ;
-  Float_t ZL =  fGeom->GetNZ() * ( XTL_Z + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 +  fGeom->GetModuleBoxThickness() ;
   
-  new TBRIK( "CrystalsBox", "PHOS crystals box", "void", XL, YL, ZL ) ;
-
-// position PHOS into ALICE
-
-  Float_t R = fGeom->GetIPtoOuterCoverDistance() + fGeom->GetOuterBoxSize(1) / 2.0 ;
+  Float_t * cribox = emcg->GetInnerThermoHalfSize() ;  
+  new TBRIK( "CrystalsBox", "PHOS crystals box", "void", cribox[0], cribox[2], cribox[1] ) ;
+  
+  // position PHOS into ALICE
+  
+  Float_t r = geom->GetIPtoOuterCoverDistance() + boxparams[3] ;
   Int_t number = 988 ; 
-  Float_t pphi =  TMath::ATan( fGeom->GetOuterBoxSize(0)  / ( 2.0 * fGeom->GetIPtoOuterCoverDistance() ) ) ;
-  pphi *= RADDEG ;
-  TNode * Top = gAlice->GetGeometry()->GetNode("alice") ;
+  TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
+  
   char * nodename = new char[20] ;  
   char * rotname  = new char[20] ; 
 
-  for( Int_t i = 1; i <= fGeom->GetNModules(); i++ ) { 
-   Float_t angle = pphi * 2 * ( i - fGeom->GetNModules() / 2.0 - 0.5 ) ;
-   sprintf(rotname, "%s%d", "rot", number++) ;
-   new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
-   Top->cd();
-   sprintf(nodename,"%s%d", "Module", i) ;    
-   Float_t X =  R * TMath::Sin( angle / RADDEG ) ;
-   Float_t Y = -R * TMath::Cos( angle / RADDEG ) ;
-   TNode * OuterBoxNode = new TNode(nodename, nodename, "OuterBox", X, Y, 0, rotname ) ;
-   OuterBoxNode->SetLineColor(kColorPHOS) ;
-   fNodes->Add(OuterBoxNode) ;
-   OuterBoxNode->cd() ; 
-   // now inside the outer box the textolit box
-   Y = ( fGeom->GetOuterBoxThickness(1) -  fGeom->GetUpperPlateThickness() ) / 2.  ;
-   sprintf(nodename,"%s%d", "TexBox", i) ;  
-   TNode * TextolitBoxNode = new TNode(nodename, nodename, "TextolitBox", 0, Y, 0) ; 
-   TextolitBoxNode->SetLineColor(kColorPHOS) ;
-   fNodes->Add(TextolitBoxNode) ;
-   // upper foam plate inside outre box
-   OuterBoxNode->cd() ; 
-   sprintf(nodename, "%s%d", "UFPlate", i) ;
-   Y =  ( fGeom->GetTextolitBoxSize(1) - fGeom->GetSecondUpperPlateThickness() ) / 2.0 ;
-   TNode * UpperFoamPlateNode = new TNode(nodename, nodename, "UpperFoamPlate", 0, Y, 0) ; 
-   UpperFoamPlateNode->SetLineColor(kColorPHOS) ;
-   fNodes->Add(UpperFoamPlateNode) ;  
-   // air filled box inside textolit box (not drawn)
-   TextolitBoxNode->cd();
-   Y = ( fGeom->GetTextolitBoxSize(1) - fGeom->GetAirFilledBoxSize(1) ) / 2.0 -  fGeom->GetSecondUpperPlateThickness() ;
-   sprintf(nodename, "%s%d", "AFBox", i) ;
-   TNode * AirFilledBoxNode = new TNode(nodename, nodename, "AirFilledBox", 0, Y, 0) ; 
-   fNodes->Add(AirFilledBoxNode) ; 
-   // crystals box inside air filled box
-   AirFilledBoxNode->cd() ; 
-   Y = fGeom->GetAirFilledBoxSize(1) / 2.0 - YL 
-       - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetModuleBoxThickness() 
-       -  fGeom->GetUpperPlateThickness() -  fGeom->GetSecondUpperPlateThickness() ) ; 
-   sprintf(nodename, "%s%d", "XTBox", i) ; 
-   TNode * CrystalsBoxNode = new TNode(nodename, nodename, "CrystalsBox", 0, Y, 0) ;    
-   CrystalsBoxNode->SetLineColor(kColorXTAL) ; 
-   fNodes->Add(CrystalsBoxNode) ; 
+  new TRotMatrix("cribox", "cribox", 90, 0, 90, 90, 0, 0);  
+
+  for( Int_t i = 1; i <= geom->GetNModules(); i++ ) { 
+
+    Float_t angle = geom->GetPHOSAngle(i) ;
+    sprintf(rotname, "%s%d", "rot", number++) ;
+    new TRotMatrix(rotname, rotname, 90, angle, 0,  0,  90,  270 + angle);
+
+    top->cd();
+    sprintf(nodename,"%s%d", "Module", i) ;    
+    Float_t x =  r * TMath::Sin( angle / kRADDEG ) ;
+    Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
+    TNode * outerboxnode = new TNode(nodename, nodename, "OuterBox", x, y, 0, rotname ) ;
+    outerboxnode->SetLineColor(kColorPHOS) ;
+    fNodes->Add(outerboxnode) ;
+    outerboxnode->cd() ; 
+
+    Float_t z = -boxparams[3] - geom->GetIPtoOuterCoverDistance() + 
+                 cribox[1] +  geom->GetIPtoCrystalSurface() ;
+    TNode * crystalsboxnode = new TNode(nodename, nodename, "CrystalsBox", 0, 0, z) ;    
+    crystalsboxnode->SetLineColor(kColorXTAL) ; 
+    fNodes->Add(crystalsboxnode) ; 
   }
+
+  delete[] rotname ;  
+  delete[] nodename ;
 }
 
+
 //____________________________________________________________________________
-void AliPHOSv0:: BuildGeometryforPPSD(void)
+void AliPHOSv0:: BuildGeometryforCPV(void)
 {
- //  Build the PPSD geometry for the ROOT display
+  //  Build the PHOS-CPV geometry for the ROOT display
+  //  Author: Yuri Kharlov 11 September 2000
+  //
+  //BEGIN_HTML
+  /*
+    <H2>
+    CPV displayed by root
+    </H2>
+    <table width=700>
 
-  Double_t const RADDEG = 180.0 / kPI ;
+    <tr>
+         <td>CPV perspective view</td>
+         <td>CPV front view      </td>
+    </tr>
 
-  const Int_t kColorPHOS = kRed ;
-  const Int_t kColorPPSD = kGreen ;
-  const Int_t kColorGas  = kBlue ;  
-  const Int_t kColorAir  = kYellow ; 
+    <tr>
+         <td> <img height=300 width=290 src="../images/CPVRootPersp.gif"> </td>
+         <td> <img height=300 width=290 src="../images/CPVRootFront.gif"> </td>
+    </tr>
 
-  // Box for a full PHOS module
+    </table>
 
-  new TBRIK( "PPSDBox", "PPSD box", "void",  fGeom->GetPPSDBoxSize(0)/2, 
-                                             fGeom->GetPPSDBoxSize(1)/2, 
-                                            fGeom->GetPPSDBoxSize(2)/2 );
+  */
+  //END_HTML  
 
-  // Box containing one micromegas module 
+  const Double_t kRADDEG         = 180.0 / TMath::Pi() ;
+  const Int_t    kColorCPV       = kGreen ;
+  const Int_t    kColorFrame     = kYellow ;
+  const Int_t    kColorGassiplex = kRed;
+  const Int_t    kColorPCB       = kCyan;
 
-  new TBRIK( "PPSDModule", "PPSD module", "void",  fGeom->GetPPSDModuleSize(0)/2, 
-                                                   fGeom->GetPPSDModuleSize(1)/2, 
-                                                  fGeom->GetPPSDModuleSize(2)/2 );
- // top lid
+  AliPHOSGeometry * geom = GetGeometry() ; 
 
-  new TBRIK ( "TopLid", "Micromegas top lid", "void",  fGeom->GetPPSDModuleSize(0)/2,
-                                                       fGeom->GetLidThickness()/2,
-                                                       fGeom->GetPPSDModuleSize(2)/2 ) ; 
- // composite panel (top and bottom)
+  // Box for a full PHOS module
 
-  new TBRIK ( "TopPanel", "Composite top panel", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
-                                                            fGeom->GetCompositeThickness()/2,
-                                                          ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ;  
+  new TBRIK ("CPVBox", "CPV box", "void",                   geom->GetCPVBoxSize(0)/2,
+                                                            geom->GetCPVBoxSize(1)/2,
+                                                           geom->GetCPVBoxSize(2)/2 );
+  new TBRIK ("CPVFrameLR", "CPV frame Left-Right", "void",  geom->GetCPVFrameSize(0)/2,
+                                                            geom->GetCPVFrameSize(1)/2,
+                                                           geom->GetCPVBoxSize(2)/2 );
+  new TBRIK ("CPVFrameUD", "CPV frame Up-Down",    "void",  geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0),
+                                                            geom->GetCPVFrameSize(1)/2,
+                                                           geom->GetCPVFrameSize(2)/2);
+  new TBRIK ("CPVPCB",    "CPV PCB",               "void",  geom->GetCPVActiveSize(0)/2,
+                                                            geom->GetCPVTextoliteThickness()/2,
+                                                           geom->GetCPVActiveSize(1)/2);
+  new TBRIK ("CPVGassiplex", "CPV Gassiplex PCB",  "void",  geom->GetGassiplexChipSize(0)/2,
+                                                            geom->GetGassiplexChipSize(1)/2,
+                                                           geom->GetGassiplexChipSize(2)/2);
+
+  // position CPV into ALICE
+
+  char * nodename = new char[25] ;
+  char * rotname  = new char[25] ;
   
-  new TBRIK ( "BottomPanel", "Composite bottom panel", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
-                                                                  fGeom->GetCompositeThickness()/2,
-                                                                ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
- // gas gap (conversion and avalanche)
-
-  new TBRIK ( "GasGap", "gas gap", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
-                                           ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() )/2,
-                                            ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
-
- // anode and cathode 
-
-  new TBRIK ( "Anode", "Anode", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
-                                           fGeom->GetAnodeThickness()/2,
-                                         ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
-
-  new TBRIK ( "Cathode", "Cathode", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
-                                               fGeom->GetCathodeThickness()/2,
-                                             ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
- // PC  
-
-  new TBRIK ( "PCBoard", "Printed Circuit", "void",  ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() )/2,
-                                                       fGeom->GetPCThickness()/2,
-                                                     ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() )/2 ) ; 
- // Gap between Lead and top micromegas
-
-  new TBRIK ( "LeadToM", "Air Gap top", "void", fGeom->GetPPSDBoxSize(0)/2,
-                                                fGeom->GetMicro1ToLeadGap()/2,
-                                                fGeom->GetPPSDBoxSize(2)/2  ) ;  
-// Gap between Lead and bottom micromegas
+  Float_t r = geom->GetIPtoCPVDistance() + geom->GetCPVBoxSize(1) / 2.0 ;
+  Int_t number = 988 ; 
+  TNode * top = gAlice->GetGeometry()->GetNode("alice") ;
 
-  new TBRIK ( "MToLead", "Air Gap bottom", "void", fGeom->GetPPSDBoxSize(0)/2,
-                                                   fGeom->GetLeadToMicro2Gap()/2,
-                                                   fGeom->GetPPSDBoxSize(2)/2  ) ; 
- // Lead converter
-   
-  new TBRIK ( "Lead", "Lead converter", "void", fGeom->GetPPSDBoxSize(0)/2,
-                                                fGeom->GetLeadConverterThickness()/2,
-                                                fGeom->GetPPSDBoxSize(2)/2  ) ; 
+  Int_t lastModule = 0 ;
+  lastModule = geom->GetNModules();
+  
+  for( Int_t i = 1; i <= lastModule; i++ ) { // the number of PHOS modules
+    
+    // One CPV module
+    
+    Float_t angle = geom->GetPHOSAngle(i) ;
+    sprintf(rotname, "%s%d", "rotg", number+i) ;
+    new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
+    top->cd();
+    sprintf(nodename, "%s%d", "CPVModule", i) ;    
+    Float_t x =  r * TMath::Sin( angle / kRADDEG ) ;
+    Float_t y = -r * TMath::Cos( angle / kRADDEG ) ;
+    Float_t z;
+    TNode * cpvBoxNode = new TNode(nodename , nodename ,"CPVBox", x, y, 0, rotname ) ;
+    cpvBoxNode->SetLineColor(kColorCPV) ;
+    fNodes->Add(cpvBoxNode) ;
+    cpvBoxNode->cd() ;
+
+    // inside each CPV box:
+
+    // Frame around CPV
+    Int_t j;
+    for (j=0; j<=1; j++) {
+      sprintf(nodename, "CPVModule%d Frame%d", i, j+1) ;
+      x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
+      TNode * cpvFrameNode = new TNode(nodename , nodename ,"CPVFrameLR", x, 0, 0) ;
+      cpvFrameNode->SetLineColor(kColorFrame) ;
+      fNodes->Add(cpvFrameNode) ;
+
+      sprintf(nodename, "CPVModule%d Frame%d", i, j+3) ;
+      z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
+      cpvFrameNode = new TNode(nodename , nodename ,"CPVFrameUD", 0, 0, z) ;
+      cpvFrameNode->SetLineColor(kColorFrame) ;
+      fNodes->Add(cpvFrameNode) ;
+    }
 
-     // position PPSD into ALICE
+    // 4 printed circuit boards
+    for (j=0; j<4; j++) {
+      sprintf(nodename, "CPVModule%d PCB%d", i, j+1) ;
+      y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(j) + geom->GetCPVTextoliteThickness()/2;
+      TNode * cpvPCBNode = new TNode(nodename , nodename ,"CPVPCB", 0, y, 0) ;
+      cpvPCBNode->SetLineColor(kColorPCB) ;
+      fNodes->Add(cpvPCBNode) ;
+    }
 
-  char * nodename = new char[20] ;  
-  char * rotname  = new char[20] ; 
+    // Gassiplex chips
+    Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
+    Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ()   + 1);
+    y = geom->GetCPVFrameSize(1)/2           - geom->GetFTPosition(0) +
+        geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
+    for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
+      x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
+      for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
+       z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
+       sprintf(nodename, "CPVModule%d Chip(%dx%d)", i, ix+1,iz+1) ;
+       TNode * cpvGassiplexNode = new TNode(nodename , nodename ,"CPVGassiplex", x, y, z) ;
+       cpvGassiplexNode->SetLineColor(kColorGassiplex) ;
+       fNodes->Add(cpvGassiplexNode) ;
+      }
+    }
 
-  Float_t R = fGeom->GetIPtoTopLidDistance() + fGeom->GetPPSDBoxSize(1) / 2.0 ;
-  Int_t number = 988 ; 
-  TNode * Top = gAlice->GetGeometry()->GetNode("alice") ;
+  } // PHOS modules
  
-  for( Int_t i = 1; i <= fGeom->GetNModules(); i++ ) { // the number of PHOS modules
-    Float_t angle = fGeom->GetPHOSAngle(i) ;
-    sprintf(rotname, "%s%d", "rotg", number++) ;
-    new TRotMatrix(rotname, rotname, 90, angle, 90, 90 + angle, 0, 0);
-    Top->cd();
-    sprintf(nodename, "%s%d", "Moduleg", i) ;    
-    Float_t X =  R * TMath::Sin( angle / RADDEG ) ;
-    Float_t Y = -R * TMath::Cos( angle / RADDEG ) ;
-    TNode * PPSDBoxNode = new TNode(nodename , nodename ,"PPSDBox", X, Y, 0, rotname ) ;
-    PPSDBoxNode->SetLineColor(kColorPPSD) ;
-    fNodes->Add(PPSDBoxNode) ;
-    PPSDBoxNode->cd() ;
-    // inside the PPSD box: 
-    //   1.   fNumberOfModulesPhi x fNumberOfModulesZ top micromegas
-    X = ( fGeom->GetPPSDBoxSize(0) - fGeom->GetPPSDModuleSize(0) ) / 2. ;  
-    for ( Int_t iphi = 1; iphi <= fGeom->GetNumberOfModulesPhi(); iphi++ ) { // the number of micromegas modules in phi per PHOS module
-      Float_t Z = ( fGeom->GetPPSDBoxSize(2) - fGeom->GetPPSDModuleSize(2) ) / 2. ;
-      TNode * Micro1Node ; 
-      for ( Int_t iz = 1; iz <= fGeom->GetNumberOfModulesZ(); iz++ ) { // the number of micromegas modules in z per PHOS module
-       Y = ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas1Thickness() ) / 2. ; 
-       sprintf(nodename, "%s%d%d%d", "Mic1", i, iphi, iz) ;
-       Micro1Node  = new TNode(nodename, nodename, "PPSDModule", X, Y, Z) ;
-       Micro1Node->SetLineColor(kColorPPSD) ;  
-       fNodes->Add(Micro1Node) ; 
-       // inside top micromegas
-       Micro1Node->cd() ; 
-       //      a. top lid
-       Y = ( fGeom->GetMicromegas1Thickness() - fGeom->GetLidThickness() ) / 2. ; 
-       sprintf(nodename, "%s%d%d%d", "Lid", i, iphi, iz) ;
-       TNode * TopLidNode = new TNode(nodename, nodename, "TopLid", 0, Y, 0) ;
-       TopLidNode->SetLineColor(kColorPPSD) ;  
-       fNodes->Add(TopLidNode) ; 
-       //      b. composite panel
-       Y = Y - fGeom->GetLidThickness() / 2. - fGeom->GetCompositeThickness() / 2. ; 
-       sprintf(nodename, "%s%d%d%d", "CompU", i, iphi, iz) ;
-       TNode * CompUpNode = new TNode(nodename, nodename, "TopPanel", 0, Y, 0) ;
-       CompUpNode->SetLineColor(kColorPPSD) ;  
-       fNodes->Add(CompUpNode) ; 
-       //      c. anode
-       Y = Y - fGeom->GetCompositeThickness() / 2. - fGeom->GetAnodeThickness()  / 2. ; 
-       sprintf(nodename, "%s%d%d%d", "Ano", i, iphi, iz) ;
-       TNode * AnodeNode = new TNode(nodename, nodename, "Anode", 0, Y, 0) ;
-       AnodeNode->SetLineColor(kColorPHOS) ;  
-       fNodes->Add(AnodeNode) ; 
-       //      d.  gas 
-       Y = Y - fGeom->GetAnodeThickness() / 2. - ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() ) / 2. ; 
-       sprintf(nodename, "%s%d%d%d", "GGap", i, iphi, iz) ;
-       TNode * GGapNode = new TNode(nodename, nodename, "GasGap", 0, Y, 0) ;
-       GGapNode->SetLineColor(kColorGas) ;  
-       fNodes->Add(GGapNode) ;          
-         //      f. cathode
-       Y = Y - ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() ) / 2. - fGeom->GetCathodeThickness()  / 2. ; 
-       sprintf(nodename, "%s%d%d%d", "Cathode", i, iphi, iz) ;
-       TNode * CathodeNode = new TNode(nodename, nodename, "Cathode", 0, Y, 0) ;
-       CathodeNode->SetLineColor(kColorPHOS) ;  
-       fNodes->Add(CathodeNode) ;        
-       //      g. printed circuit
-       Y = Y - fGeom->GetCathodeThickness() / 2. - fGeom->GetPCThickness()  / 2. ; 
-       sprintf(nodename, "%s%d%d%d", "PC", i, iphi, iz) ;
-       TNode * PCNode = new TNode(nodename, nodename, "PCBoard", 0, Y, 0) ;
-       PCNode->SetLineColor(kColorPPSD) ;  
-       fNodes->Add(PCNode) ;        
-       //      h. composite panel
-       Y = Y - fGeom->GetPCThickness() / 2. - fGeom->GetCompositeThickness()  / 2. ; 
-       sprintf(nodename, "%s%d%d%d", "CompDown", i, iphi, iz) ;
-       TNode * CompDownNode = new TNode(nodename, nodename, "BottomPanel", 0, Y, 0) ;
-       CompDownNode->SetLineColor(kColorPPSD) ;  
-       fNodes->Add(CompDownNode) ;   
-       Z = Z - fGeom->GetPPSDModuleSize(2) ;
-       PPSDBoxNode->cd() ;
-      } // end of Z module loop     
-      X = X -  fGeom->GetPPSDModuleSize(0) ; 
-      PPSDBoxNode->cd() ;
-    } // end of phi module loop
-    //   2. air gap      
-    PPSDBoxNode->cd() ;
-    Y = ( fGeom->GetPPSDBoxSize(1) - 2 * fGeom->GetMicromegas1Thickness() - fGeom->GetMicro1ToLeadGap() ) / 2. ; 
-    sprintf(nodename, "%s%d", "GapUp", i) ;
-    TNode * GapUpNode = new TNode(nodename, nodename, "LeadToM", 0, Y, 0) ;
-    GapUpNode->SetLineColor(kColorAir) ;  
-    fNodes->Add(GapUpNode) ;        
-    //   3. lead converter
-    Y = Y - fGeom->GetMicro1ToLeadGap() / 2. - fGeom->GetLeadConverterThickness() / 2. ; 
-    sprintf(nodename, "%s%d", "LeadC", i) ;
-    TNode * LeadCNode = new TNode(nodename, nodename, "Lead", 0, Y, 0) ;
-    LeadCNode->SetLineColor(kColorPPSD) ;  
-    fNodes->Add(LeadCNode) ;        
-    //   4. air gap
-    Y = Y - fGeom->GetLeadConverterThickness() / 2. - fGeom->GetLeadToMicro2Gap()  / 2. ; 
-    sprintf(nodename, "%s%d", "GapDown", i) ;
-    TNode * GapDownNode = new TNode(nodename, nodename, "MToLead", 0, Y, 0) ;
-    GapDownNode->SetLineColor(kColorAir) ;  
-    fNodes->Add(GapDownNode) ;        
-    //    5.  fNumberOfModulesPhi x fNumberOfModulesZ bottom micromegas
-    X = ( fGeom->GetPPSDBoxSize(0) - fGeom->GetPPSDModuleSize(0) ) / 2. - fGeom->GetPhiDisplacement() ;  
-    for ( Int_t iphi = 1; iphi <= fGeom->GetNumberOfModulesPhi(); iphi++ ) { 
-      Float_t Z = ( fGeom->GetPPSDBoxSize(2) - fGeom->GetPPSDModuleSize(2) ) / 2.  - fGeom->GetZDisplacement() ;;
-      TNode * Micro2Node ; 
-      for ( Int_t iz = 1; iz <= fGeom->GetNumberOfModulesZ(); iz++ ) { 
-       Y = - ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas2Thickness() ) / 2. ; 
-       sprintf(nodename, "%s%d%d%d", "Mic2", i, iphi, iz) ;
-       Micro2Node  = new TNode(nodename, nodename, "PPSDModule", X, Y, Z) ;
-       Micro2Node->SetLineColor(kColorPPSD) ;  
-       fNodes->Add(Micro2Node) ; 
-       // inside bottom micromegas
-       Micro2Node->cd() ; 
-         //      a. top lid
-         Y = ( fGeom->GetMicromegas2Thickness() - fGeom->GetLidThickness() ) / 2. ; 
-         sprintf(nodename, "%s%d", "Lidb", i) ;
-         TNode * TopLidbNode = new TNode(nodename, nodename, "TopLid", 0, Y, 0) ;
-         TopLidbNode->SetLineColor(kColorPPSD) ;  
-         fNodes->Add(TopLidbNode) ; 
-         //      b. composite panel
-         Y = Y - fGeom->GetLidThickness() / 2. - fGeom->GetCompositeThickness() / 2. ; 
-         sprintf(nodename, "%s%d", "CompUb", i) ;
-         TNode * CompUpbNode = new TNode(nodename, nodename, "TopPanel", 0, Y, 0) ;
-         CompUpbNode->SetLineColor(kColorPPSD) ;  
-         fNodes->Add(CompUpbNode) ; 
-         //      c. anode
-         Y = Y - fGeom->GetCompositeThickness() / 2. - fGeom->GetAnodeThickness()  / 2. ; 
-         sprintf(nodename, "%s%d", "Anob", i) ;
-         TNode * AnodebNode = new TNode(nodename, nodename, "Anode", 0, Y, 0) ;
-         AnodebNode->SetLineColor(kColorPPSD) ;  
-         fNodes->Add(AnodebNode) ; 
-         //      d. conversion gas
-         Y = Y - fGeom->GetAnodeThickness() / 2. - ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() )  / 2. ; 
-         sprintf(nodename, "%s%d", "GGapb", i) ;
-         TNode * GGapbNode = new TNode(nodename, nodename, "GasGap", 0, Y, 0) ;
-         GGapbNode->SetLineColor(kColorGas) ;  
-         fNodes->Add(GGapbNode) ;           
-         //      f. cathode
-         Y = Y - ( fGeom->GetConversionGap() + fGeom->GetAvalancheGap() ) / 2. - fGeom->GetCathodeThickness()  / 2. ; 
-         sprintf(nodename, "%s%d", "Cathodeb", i) ;
-         TNode * CathodebNode = new TNode(nodename, nodename, "Cathode", 0, Y, 0) ;
-         CathodebNode->SetLineColor(kColorPPSD) ;  
-         fNodes->Add(CathodebNode) ;        
-         //      g. printed circuit
-         Y = Y - fGeom->GetCathodeThickness() / 2. - fGeom->GetPCThickness()  / 2. ; 
-         sprintf(nodename, "%s%d", "PCb", i) ;
-         TNode * PCbNode = new TNode(nodename, nodename, "PCBoard", 0, Y, 0) ;
-         PCbNode->SetLineColor(kColorPPSD) ;  
-         fNodes->Add(PCbNode) ;        
-         //      h. composite pane
-         Y = Y - fGeom->GetPCThickness() / 2. - fGeom->GetCompositeThickness()  / 2. ; 
-         sprintf(nodename, "%s%d", "CompDownb", i) ;
-         TNode * CompDownbNode = new TNode(nodename, nodename, "BottomPanel", 0, Y, 0) ;
-         CompDownbNode->SetLineColor(kColorPPSD) ;  
-         fNodes->Add(CompDownbNode) ;        
-                 Z = Z - fGeom->GetPPSDModuleSize(2) ;
-         PPSDBoxNode->cd() ;
-       } // end of Z module loop     
-       X = X -  fGeom->GetPPSDModuleSize(0) ; 
-       PPSDBoxNode->cd() ;
-       } // end of phi module loop
-     } // PHOS modules
- delete rotname ; 
- delete nodename ; 
+  delete[] rotname ;  
+  delete[] nodename ; 
 }
 
 //____________________________________________________________________________
 void AliPHOSv0::CreateGeometry()
 {
+  // Create the PHOS geometry for Geant
 
-  AliPHOSv0 *PHOS_tmp = (AliPHOSv0*)gAlice->GetModule("PHOS") ;
+  AliPHOSv0 *phostmp = dynamic_cast<AliPHOSv0*>(gAlice->GetModule("PHOS")) ;
 
-  if ( PHOS_tmp == NULL ) {
+  if ( phostmp == NULL ) {
     
     fprintf(stderr, "PHOS detector not found!\n") ;
     return;
     
   }
 
+  AliPHOSGeometry * geom = GetGeometry() ; 
+
   // Get pointer to the array containing media indeces
-  Int_t *IDTMED = fIdtmed->GetArray() - 699 ;
+  Int_t *idtmed = fIdtmed->GetArray() - 699 ;
 
-  Float_t BigBox[3] ; 
-  BigBox[0] =   fGeom->GetOuterBoxSize(0) / 2.0 ;
-  BigBox[1] = ( fGeom->GetOuterBoxSize(1) + fGeom->GetPPSDBoxSize(1) ) / 2.0 ;
-  BigBox[2] =   fGeom->GetOuterBoxSize(2) / 2.0 ;
+  // Create a PHOS module.
   
-  gMC->Gsvolu("PHOS", "BOX ", IDTMED[798], BigBox, 3) ;
+  gMC->Gsvolu("PHOS", "TRD1", idtmed[798], geom->GetPHOSParams(), 4) ;        
   
-  this->CreateGeometryforPHOS() ; 
-  if ( strcmp( fGeom->GetName(), "GPS2") == 0  ) 
-    this->CreateGeometryforPPSD() ;
-  else
-    cout << "AliPHOSv0::CreateGeometry : no charged particle identification system installed" << endl; 
-  
-  // --- Position  PHOS mdules in ALICE setup ---
+  this->CreateGeometryforEMC() ; 
+
+  if (strstr(fTitle.Data(),"noCPV") == 0) 
+    this->CreateGeometryforCPV() ;
   
-  Int_t IDROTM[99] ;
-  Double_t const RADDEG = 180.0 / kPI ;
+  this->CreateGeometryforSupport() ; 
   
-  for( Int_t i = 1; i <= fGeom->GetNModules(); i++ ) {
+  // --- Position  PHOS mdules in ALICE setup ---
+  Int_t idrotm[99] ;
+  Int_t iXYZ,iAngle;
+  char im[5] ;
+  Bool_t anyModuleCreated=0 ;
+  for (Int_t iModule = 0; iModule < 5 ; iModule++ ) {
+    sprintf(im,"%d",iModule+1) ;
+    if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
+      continue ;
+    anyModuleCreated=1 ;
+    Float_t angle[3][2];
+    for (iXYZ=0; iXYZ<3; iXYZ++)
+      for (iAngle=0; iAngle<2; iAngle++)
+       angle[iXYZ][iAngle] = geom->GetModuleAngle(iModule,iXYZ, iAngle);
+    AliMatrix(idrotm[iModule],
+             angle[0][0],angle[0][1],
+             angle[1][0],angle[1][1],
+             angle[2][0],angle[2][1]) ;
     
-    Float_t angle = fGeom->GetPHOSAngle(i) ;
-    AliMatrix(IDROTM[i-1], 90.0, angle, 90.0, 90.0+angle, 0.0, 0.0) ;
-    Float_t R = fGeom->GetIPtoOuterCoverDistance() + ( fGeom->GetOuterBoxSize(1) + fGeom->GetPPSDBoxSize(1) ) / 2.0 ;
-
-    Float_t XP1 = R * TMath::Sin( angle / RADDEG ) ;
-    Float_t YP1 = -R * TMath::Cos( angle / RADDEG ) ;
-
-    gMC->Gspos("PHOS", i, "ALIC", XP1, YP1, 0.0, IDROTM[i-1], "ONLY") ;
-  } // for GetNModules
-
+    Float_t pos[3];
+    for (iXYZ=0; iXYZ<3; iXYZ++)
+      pos[iXYZ] = geom->GetModuleCenter(iModule,iXYZ);
+    gMC->Gspos("PHOS", iModule+1, "ALIC", pos[0], pos[1], pos[2],
+              idrotm[iModule], "ONLY") ;
+  }
+  if(!anyModuleCreated)
+    AliError("No one PHOS module was created") ;
 }
 
 //____________________________________________________________________________
-void AliPHOSv0::CreateGeometryforPHOS()
+void AliPHOSv0::CreateGeometryforEMC()
 {
-  // Get pointer to the array containing media indeces
-  Int_t *IDTMED = fIdtmed->GetArray() - 699 ;
-
-  // ---
-  // --- Define PHOS box volume, fPUFPill with thermo insulating foam ---
-  // --- Foam Thermo Insulating outer cover dimensions ---
-  // --- Put it in BigBox = PHOS
+  // Create the PHOS-EMC geometry for GEANT
+  // Author: Dmitri Peressounko August 2001
+  // The used coordinate system: 
+  //   1. in Module: X along longer side, Y out of beam, Z along shorter side (along beam)
+  //   2. In Strip the same: X along longer side, Y out of beam, Z along shorter side (along beam)
+
+
+    //BEGIN_HTML
+  /*
+    <H2>
+    Geant3 geometry tree of PHOS-EMC in ALICE
+    </H2>
+    <P><CENTER>
+    <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/EMCinAlice.gif"> 
+    </CENTER><P>
+  */
+  //END_HTML  
+  
+  // Get pointer to the array containing media indexes
+  Int_t *idtmed = fIdtmed->GetArray() - 699 ;
 
-  Float_t DPHOS[3] ; 
-  DPHOS[0] =  fGeom->GetOuterBoxSize(0) / 2.0 ;
-  DPHOS[1] =  fGeom->GetOuterBoxSize(1) / 2.0 ;
-  DPHOS[2] =  fGeom->GetOuterBoxSize(2) / 2.0 ;
+  AliPHOSGeometry * geom = GetGeometry() ; 
+  AliPHOSEMCAGeometry * emcg = geom->GetEMCAGeometry() ;
 
-  gMC->Gsvolu("EMCA", "BOX ", IDTMED[706], DPHOS, 3) ;
+  // ======= Define the strip ===============
 
-  Float_t YO =  - fGeom->GetPPSDBoxSize(1)  / 2.0 ;
+  gMC->Gsvolu("PSTR", "BOX ", idtmed[716], emcg->GetStripHalfSize(), 3) ;  //Made of steel
+   
+      // --- define steel volume (cell of the strip unit)
+//       gMC->Gsvolu("PCEL", "BOX ", idtmed[798], emcg->GetSteelCellHalfSize(), 3);
+      gMC->Gsvolu("PCEL", "BOX ", idtmed[798], emcg->GetAirCellHalfSize(), 3);
 
-  gMC->Gspos("EMCA", 1, "PHOS", 0.0, YO, 0.0, 0, "ONLY") ; 
+      // --- define wrapped crystal and put it into steel cell
 
-  // ---
-  // --- Define Textolit Wall box, position inside EMCA ---
-  // --- Textolit Wall box dimentions ---
+      gMC->Gsvolu("PWRA", "BOX ", idtmed[702], emcg->GetWrappedHalfSize(), 3);
+      Float_t * pin = emcg->GetAPDHalfSize() ; 
+      Float_t * preamp = emcg->GetPreampHalfSize() ;
+      Float_t y = (emcg->GetAirGapLed()-2*pin[1]-2*preamp[1])/2;
+      gMC->Gspos("PWRA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
+    
+      // --- Define crystal and put it into wrapped crystall ---
+      gMC->Gsvolu("PXTL", "BOX ", idtmed[699], emcg->GetCrystalHalfSize(), 3) ;
+      gMC->Gspos("PXTL", 1, "PWRA", 0.0, 0.0, 0.0, 0, "ONLY") ;
+      
+      // --- define APD/PIN preamp and put it into AirCell
  
-  Float_t DPTXW[3];
-  DPTXW[0] = fGeom->GetTextolitBoxSize(0) / 2.0 ;
-  DPTXW[1] = fGeom->GetTextolitBoxSize(1) / 2.0 ;
-  DPTXW[2] = fGeom->GetTextolitBoxSize(2) / 2.0 ;
-
-  gMC->Gsvolu("PTXW", "BOX ", IDTMED[707], DPTXW, 3);
-
-  YO =   (  fGeom->GetOuterBoxThickness(1) -   fGeom->GetUpperPlateThickness() ) / 2.  ;
+      gMC->Gsvolu("PPIN", "BOX ", idtmed[705], emcg->GetAPDHalfSize(), 3) ;
+      Float_t * crystal = emcg->GetCrystalHalfSize() ;
+      y = crystal[1] + emcg->GetAirGapLed() /2 - preamp[1]; 
+      gMC->Gspos("PPIN", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;
+
+      gMC->Gsvolu("PREA", "BOX ", idtmed[711], emcg->GetPreampHalfSize(), 3) ;   // Here I assumed preamp
+                                                                                 // as a printed Circuit
+      y = crystal[1] + emcg->GetAirGapLed() /2 + pin[1]  ;                  // May it should be changed
+      gMC->Gspos("PREA", 1, "PCEL", 0.0, y, 0.0, 0, "ONLY") ;                    // to ceramics?
    
-  gMC->Gspos("PTXW", 1, "EMCA", 0.0, YO, 0.0, 0, "ONLY") ;
-
-  // --- 
-  // --- Define Upper Polystyrene Foam Plate, place inside PTXW ---
-  // --- immediately below Foam Thermo Insulation Upper plate ---
 
-  // --- Upper Polystyrene Foam plate thickness ---
+      // --- Fill strip with wrapped cristals in steel cells
+
+      Float_t* splate = emcg->GetSupportPlateHalfSize();  
+      y = -splate[1] ;
+//       Float_t* acel = emcg->GetSteelCellHalfSize() ;
+      Float_t* acel = emcg->GetAirCellHalfSize() ;
+
+      for(Int_t lev = 2, icel = 1; icel <= emcg->GetNCellsXInStrip()*emcg->GetNCellsZInStrip(); icel += 2, lev += 2){
+         Float_t x = (2*(lev / 2) - 1 - emcg->GetNCellsXInStrip())* acel[0] ;
+         Float_t z = acel[2];
+         gMC->Gspos("PCEL", icel, "PSTR", x, y, +z, 0, "ONLY") ;
+         gMC->Gspos("PCEL", icel + 1, "PSTR", x, y, -z, 0, "ONLY") ;
+      }
+
+      // --- define the support plate, hole in it and position it in strip ----
+      gMC->Gsvolu("PSUP", "BOX ", idtmed[701], emcg->GetSupportPlateHalfSize(), 3) ;
+
+      gMC->Gsvolu("PSHO", "BOX ", idtmed[798], emcg->GetSupportPlateInHalfSize(), 3) ;
+      Float_t z = emcg->GetSupportPlateThickness()/2 ;
+      gMC->Gspos("PSHO", 1, "PSUP", 0.0, 0.0, z, 0, "ONLY") ;
+
+      y = acel[1] ;
+      gMC->Gspos("PSUP", 1, "PSTR", 0.0, y, 0.0, 0, "ONLY") ;
+
+
+    // ========== Fill module with strips and put them into inner thermoinsulation=============
+      gMC->Gsvolu("PTII", "BOX ", idtmed[706], emcg->GetInnerThermoHalfSize(), 3) ;     
+
+      Float_t * inthermo = emcg->GetInnerThermoHalfSize() ;
+      Float_t * strip = emcg->GetStripHalfSize() ;
+      y = inthermo[1] - strip[1] ;
+      Int_t irow;
+      Int_t nr = 1 ;
+      Int_t icol ;
+
+      for(irow = 0; irow < emcg->GetNStripX(); irow ++){
+       Float_t x = (2*irow + 1 - emcg->GetNStripX())* strip[0] ;
+       for(icol = 0; icol < emcg->GetNStripZ(); icol ++){
+         z = (2*icol + 1 - emcg->GetNStripZ()) * strip[2] ;
+         gMC->Gspos("PSTR", nr, "PTII", x, y, z, 0, "ONLY") ;
+         nr++ ;
+       }
+      }
+         
+
+   // ------- define the air gap between thermoinsulation and cooler
+      gMC->Gsvolu("PAGA", "BOX ", idtmed[798], emcg->GetAirGapHalfSize(), 3) ;   
+      Float_t * agap = emcg->GetAirGapHalfSize() ;
+      y = agap[1] - inthermo[1]  ;
+      
+      gMC->Gspos("PTII", 1, "PAGA", 0.0, y, 0.0, 0, "ONLY") ;
+
+
+
+   // ------- define the Al passive cooler 
+      gMC->Gsvolu("PCOR", "BOX ", idtmed[701], emcg->GetCoolerHalfSize(), 3) ;   
+      Float_t * cooler = emcg->GetCoolerHalfSize() ;
+      y = cooler[1] - agap[1]  ;
+      
+      gMC->Gspos("PAGA", 1, "PCOR", 0.0, y, 0.0, 0, "ONLY") ;
+
+   // ------- define the outer thermoinsulating cover
+      gMC->Gsvolu("PTIO", "TRD1", idtmed[706], emcg->GetOuterThermoParams(), 4) ;        
+      Float_t * outparams = emcg->GetOuterThermoParams() ; 
+
+      Int_t idrotm[99] ;
+      AliMatrix(idrotm[1], 90.0, 0.0, 0.0, 0.0, 90.0, 270.0) ;
+      // Frame in outer thermoinsulation and so on: z out of beam, y along beam, x across beam
  
-  Float_t  DPUFP[3] ;
-  DPUFP[0] = fGeom->GetTextolitBoxSize(0) / 2.0 ; 
-  DPUFP[1] = fGeom->GetSecondUpperPlateThickness() / 2. ;
-  DPUFP[2] = fGeom->GetTextolitBoxSize(2) /2.0 ; 
+      z = outparams[3] - cooler[1] ;
+      gMC->Gspos("PCOR", 1, "PTIO", 0., 0.0, z, idrotm[1], "ONLY") ;
+       
+  // -------- Define the outer Aluminium cover -----
+      gMC->Gsvolu("PCOL", "TRD1", idtmed[701], emcg->GetAlCoverParams(), 4) ;        
+      Float_t * covparams = emcg->GetAlCoverParams() ; 
+      z = covparams[3] - outparams[3] ;
+      gMC->Gspos("PTIO", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
 
-  gMC->Gsvolu("PUFP", "BOX ", IDTMED[703], DPUFP, 3) ;
-  
-  YO = ( fGeom->GetTextolitBoxSize(1) -  fGeom->GetSecondUpperPlateThickness() ) / 2.0 ;
-  
-  gMC->Gspos("PUFP", 1, "PTXW", 0.0, YO, 0.0, 0, "ONLY") ;
-  
-  // ---
-  // --- Define air-filled box, place inside PTXW ---
-  // --- Inner AIR volume dimensions ---
+ // --------- Define front fiberglass cover -----------
+      gMC->Gsvolu("PFGC", "BOX ", idtmed[717], emcg->GetFiberGlassHalfSize(), 3) ;  
+      z = - outparams[3] ;
+      gMC->Gspos("PFGC", 1, "PCOL", 0., 0.0, z, 0, "ONLY") ;
 
-  Float_t  DPAIR[3] ;
-  DPAIR[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
-  DPAIR[1] = fGeom->GetAirFilledBoxSize(1) / 2.0 ;
-  DPAIR[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
+ //=============This is all with cold section==============
 
-  gMC->Gsvolu("PAIR", "BOX ", IDTMED[798], DPAIR, 3) ;
-  
-  YO = ( fGeom->GetTextolitBoxSize(1) -  fGeom->GetAirFilledBoxSize(1) ) / 2.0 -   fGeom->GetSecondUpperPlateThickness() ;
-  
-  gMC->Gspos("PAIR", 1, "PTXW", 0.0, YO, 0.0, 0, "ONLY") ;
 
-// --- Dimensions of PbWO4 crystal ---
+      //------ Warm Section --------------
+      gMC->Gsvolu("PWAR", "BOX ", idtmed[701], emcg->GetWarmAlCoverHalfSize(), 3) ; 
+      Float_t * warmcov = emcg->GetWarmAlCoverHalfSize() ;
 
-  Float_t XTL_X =  fGeom->GetCrystalSize(0) ; 
-  Float_t XTL_Y =  fGeom->GetCrystalSize(1) ; 
-  Float_t XTL_Z =  fGeom->GetCrystalSize(2) ; 
+      // --- Define the outer thermoinsulation ---
+      gMC->Gsvolu("PWTI", "BOX ", idtmed[706], emcg->GetWarmThermoHalfSize(), 3) ; 
+      Float_t * warmthermo = emcg->GetWarmThermoHalfSize() ;
+      z = -warmcov[2] + warmthermo[2] ;
 
-  Float_t DPTCB[3] ;  
-  DPTCB[0] =  fGeom->GetNPhi() * ( XTL_X + 2 *  fGeom->GetGapBetweenCrystals() ) / 2.0 + fGeom->GetModuleBoxThickness() ;
-  DPTCB[1] = ( XTL_Y +  fGeom->GetCrystalSupportHeight() +  fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 
-             + fGeom->GetModuleBoxThickness() / 2.0 ;
-  DPTCB[2] = fGeom->GetNZ() * ( XTL_Z + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 +  fGeom->GetModuleBoxThickness() ;
-  
-  gMC->Gsvolu("PTCB", "BOX ", IDTMED[706], DPTCB, 3) ;
+      gMC->Gspos("PWTI", 1, "PWAR", 0., 0.0, z, 0, "ONLY") ;     
 
-  YO =  fGeom->GetAirFilledBoxSize(1) / 2.0 - DPTCB[1] 
-       - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetModuleBoxThickness() 
-       -  fGeom->GetUpperPlateThickness() -  fGeom->GetSecondUpperPlateThickness() ) ;
-  
-  gMC->Gspos("PTCB", 1, "PAIR", 0.0, YO, 0.0, 0, "ONLY") ;
+      // --- Define cables area and put in it T-supports ---- 
+      gMC->Gsvolu("PCA1", "BOX ", idtmed[718], emcg->GetTCables1HalfSize(), 3) ; 
+      Float_t * cbox = emcg->GetTCables1HalfSize() ;
 
-  // ---
-  // --- Define Crystal BLock filled with air, position it inside PTCB ---
-  Float_t DPCBL[3] ; 
-  
-  DPCBL[0] = fGeom->GetNPhi() * ( XTL_X + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 ;
-  DPCBL[1] = ( XTL_Y + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 ;
-  DPCBL[2] = fGeom->GetNZ() * ( XTL_Z + 2 * fGeom->GetGapBetweenCrystals() ) / 2.0 ;
-  
-  gMC->Gsvolu("PCBL", "BOX ", IDTMED[798], DPCBL, 3) ;
-  
-  // --- Divide PCBL in X (phi) and Z directions --
-  gMC->Gsdvn("PROW", "PCBL", Int_t (fGeom->GetNPhi()), 1) ;
-  gMC->Gsdvn("PCEL", "PROW", Int_t (fGeom->GetNZ()), 3) ;
+      gMC->Gsvolu("PBE1", "BOX ", idtmed[701], emcg->GetTSupport1HalfSize(), 3) ;
+      Float_t * beams = emcg->GetTSupport1HalfSize() ;
+      Int_t isup ;
+      for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
+       Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
+       gMC->Gspos("PBE1", isup, "PCA1", x, 0.0, 0.0, 0, "ONLY") ;
+      }
 
-  YO = -fGeom->GetModuleBoxThickness() / 2.0 ;
-  
-  gMC->Gspos("PCBL", 1, "PTCB", 0.0, YO, 0.0, 0, "ONLY") ;
+      z = -warmthermo[2] + cbox[2];
+      gMC->Gspos("PCA1", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;     
 
-  // ---
-  // --- Define STeel (actually, it's titanium) Cover volume, place inside PCEL
-  Float_t  DPSTC[3] ; 
-  
-  DPSTC[0] = ( XTL_X + 2 * fGeom->GetCrystalWrapThickness() ) / 2.0 ;
-  DPSTC[1] = ( XTL_Y + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 ;
-  DPSTC[2] = ( XTL_Z + 2 * fGeom->GetCrystalWrapThickness()  + 2 *  fGeom->GetCrystalHolderThickness() ) / 2.0 ;
-  
-  gMC->Gsvolu("PSTC", "BOX ", IDTMED[704], DPSTC, 3) ;
+      gMC->Gsvolu("PCA2", "BOX ", idtmed[718], emcg->GetTCables2HalfSize(), 3) ; 
+      Float_t * cbox2 = emcg->GetTCables2HalfSize() ;
 
-  gMC->Gspos("PSTC", 1, "PCEL", 0.0, 0.0, 0.0, 0, "ONLY") ;
+      gMC->Gsvolu("PBE2", "BOX ", idtmed[701], emcg->GetTSupport2HalfSize(), 3) ;
+      for(isup = 0; isup < emcg->GetNTSuppots(); isup++){
+       Float_t x = -cbox[0] + beams[0] + (2*beams[0]+emcg->GetTSupportDist())*isup ;
+       gMC->Gspos("PBE2", isup, "PCA2", x, 0.0, 0.0, 0, "ONLY") ;
+      }
 
-  // ---
-  // --- Define Tyvek volume, place inside PSTC ---
-  Float_t  DPPAP[3] ;
+      z = -warmthermo[2] + 2*cbox[2] + cbox2[2];
+      gMC->Gspos("PCA2", 1, "PWTI", 0.0, 0.0, z, 0, "ONLY") ;     
 
-  DPPAP[0] = XTL_X / 2.0 + fGeom->GetCrystalWrapThickness() ;
-  DPPAP[1] = ( XTL_Y + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 ;
-  DPPAP[2] = XTL_Z / 2.0 + fGeom->GetCrystalWrapThickness() ;
-  
-  gMC->Gsvolu("PPAP", "BOX ", IDTMED[702], DPPAP, 3) ;
-  
-  YO = ( XTL_Y + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 
-              - ( XTL_Y +  fGeom->GetCrystalSupportHeight() +  fGeom->GetCrystalWrapThickness() + fGeom->GetCrystalHolderThickness() ) / 2.0 ;
-   
-  gMC->Gspos("PPAP", 1, "PSTC", 0.0, YO, 0.0, 0, "ONLY") ;
 
-  // ---
-  // --- Define PbWO4 crystal volume, place inside PPAP ---
-  Float_t  DPXTL[3] ; 
+  // --- Define frame ---
+      gMC->Gsvolu("PFRX", "BOX ", idtmed[716], emcg->GetFrameXHalfSize(), 3) ; 
+      Float_t * posit = emcg->GetFrameXPosition() ;
+      gMC->Gspos("PFRX", 1, "PWTI", posit[0],  posit[1], posit[2], 0, "ONLY") ;
+      gMC->Gspos("PFRX", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
 
-  DPXTL[0] = XTL_X / 2.0 ;
-  DPXTL[1] = XTL_Y / 2.0 ;
-  DPXTL[2] = XTL_Z / 2.0 ;
-  
-  gMC->Gsvolu("PXTL", "BOX ", IDTMED[699], DPXTL, 3) ;
+      gMC->Gsvolu("PFRZ", "BOX ", idtmed[716], emcg->GetFrameZHalfSize(), 3) ; 
+      posit = emcg->GetFrameZPosition() ;
+      gMC->Gspos("PFRZ", 1, "PWTI", posit[0], posit[1],  posit[2], 0, "ONLY") ;
+      gMC->Gspos("PFRZ", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
 
-  YO = ( XTL_Y + fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 - XTL_Y / 2.0 - fGeom->GetCrystalWrapThickness() ;
-  
-  gMC->Gspos("PXTL", 1, "PPAP", 0.0, YO, 0.0, 0, "ONLY") ;
+ // --- Define Fiber Glass support ---
+      gMC->Gsvolu("PFG1", "BOX ", idtmed[717], emcg->GetFGupXHalfSize(), 3) ; 
+      posit = emcg->GetFGupXPosition() ;
+      gMC->Gspos("PFG1", 1, "PWTI", posit[0],  posit[1], posit[2], 0, "ONLY") ;
+      gMC->Gspos("PFG1", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
 
-  // ---
-  // --- Define crystal support volume, place inside PPAP ---
-  Float_t DPSUP[3] ; 
+      gMC->Gsvolu("PFG2", "BOX ", idtmed[717], emcg->GetFGupZHalfSize(), 3) ; 
+      posit = emcg->GetFGupZPosition();
+      gMC->Gspos("PFG2", 1, "PWTI",  posit[0], posit[1], posit[2], 0, "ONLY") ;
+      gMC->Gspos("PFG2", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
 
-  DPSUP[0] = XTL_X / 2.0 + fGeom->GetCrystalWrapThickness()  ;
-  DPSUP[1] = fGeom->GetCrystalSupportHeight() / 2.0 ;
-  DPSUP[2] = XTL_Z / 2.0 +  fGeom->GetCrystalWrapThickness() ;
+      gMC->Gsvolu("PFG3", "BOX ", idtmed[717], emcg->GetFGlowXHalfSize(), 3) ; 
+      posit = emcg->GetFGlowXPosition() ;
+      gMC->Gspos("PFG3", 1, "PWTI", posit[0],  posit[1], posit[2], 0, "ONLY") ;
+      gMC->Gspos("PFG3", 2, "PWTI", posit[0], -posit[1], posit[2], 0, "ONLY") ;
 
-  gMC->Gsvolu("PSUP", "BOX ", IDTMED[798], DPSUP, 3) ;
+      gMC->Gsvolu("PFG4", "BOX ", idtmed[717], emcg->GetFGlowZHalfSize(), 3) ; 
+      posit = emcg->GetFGlowZPosition() ;
+      gMC->Gspos("PFG4", 1, "PWTI",  posit[0], posit[1], posit[2], 0, "ONLY") ;
+      gMC->Gspos("PFG4", 2, "PWTI", -posit[0], posit[1], posit[2], 0, "ONLY") ;
 
-  YO =  fGeom->GetCrystalSupportHeight() / 2.0 - ( XTL_Y +  fGeom->GetCrystalSupportHeight() + fGeom->GetCrystalWrapThickness() ) / 2.0 ;
+      // --- Define Air Gap for FEE electronics ----- 
 
-  gMC->Gspos("PSUP", 1, "PPAP", 0.0, YO, 0.0, 0, "ONLY") ;
+      gMC->Gsvolu("PAFE", "BOX ", idtmed[798], emcg->GetFEEAirHalfSize(), 3) ; 
+      posit = emcg->GetFEEAirPosition() ;
+      gMC->Gspos("PAFE", 1, "PWTI",  posit[0], posit[1], posit[2], 0, "ONLY") ;
 
-  // ---
-  // --- Define PIN-diode volume and position it inside crystal support ---
-  // --- right behind PbWO4 crystal
+      // Define the EMC module volume and combine Cool and Warm sections
 
-  // --- PIN-diode dimensions ---
+      gMC->Gsvolu("PEMC", "TRD1", idtmed[798], emcg->GetEMCParams(), 4) ;        
 
-  Float_t DPPIN[3] ;
-  DPPIN[0] = fGeom->GetPinDiodeSize(0) / 2.0 ;
-  DPPIN[1] = fGeom->GetPinDiodeSize(1) / 2.0 ;
-  DPPIN[2] = fGeom->GetPinDiodeSize(2) / 2.0 ;
-  gMC->Gsvolu("PPIN", "BOX ", IDTMED[705], DPPIN, 3) ;
-  YO = fGeom->GetCrystalSupportHeight() / 2.0 - fGeom->GetPinDiodeSize(1) / 2.0 ;
-  gMC->Gspos("PPIN", 1, "PSUP", 0.0, YO, 0.0, 0, "ONLY") ;
+      z =  - warmcov[2] ;
+      gMC->Gspos("PCOL", 1, "PEMC",  0., 0., z, 0, "ONLY") ;
+      z = covparams[3] ;
+      gMC->Gspos("PWAR", 1, "PEMC",  0., 0., z, 0, "ONLY") ;
 
-  // ---
-  // --- Define Upper Cooling Panel, place it on top of PTCB ---
-  Float_t DPUCP[3] ;
- // --- Upper Cooling Plate thickness ---
-  DPUCP[0] = DPTCB[0] ;
-  DPUCP[1] = fGeom->GetUpperCoolingPlateThickness() ;
-  DPUCP[2] = DPTCB[2] ;
-  
-  gMC->Gsvolu("PUCP", "BOX ", IDTMED[701], DPUCP,3) ;
-  
-  YO = (  fGeom->GetAirFilledBoxSize(1) -  fGeom->GetUpperCoolingPlateThickness() ) / 2. 
-       - ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetModuleBoxThickness()
-           - fGeom->GetUpperPlateThickness() - fGeom->GetSecondUpperPlateThickness() - fGeom->GetUpperCoolingPlateThickness() ) ; 
-  
-  gMC->Gspos("PUCP", 1, "PAIR", 0.0, YO, 0.0, 0, "ONLY") ;
 
-  // ---
-  // --- Define Al Support Plate, position it inside PAIR ---
-  // --- right beneath PTCB ---
- // --- Al Support Plate thickness ---
-  Float_t DPASP[3] ;
-  DPASP[0] =  fGeom->GetAirFilledBoxSize(0) / 2.0 ;
-  DPASP[1] = fGeom->GetSupportPlateThickness() / 2.0 ;
-  DPASP[2] =  fGeom->GetAirFilledBoxSize(2) / 2.0 ;
+      // Put created EMC geometry into PHOS volume
+      
+      z = geom->GetCPVBoxSize(1) / 2. ;
+      gMC->Gspos("PEMC", 1, "PHOS", 0., 0., z, 0, "ONLY") ; 
+            
+}
+
+//____________________________________________________________________________
+void AliPHOSv0::CreateGeometryforCPV()
+{
+  // Create the PHOS-CPV geometry for GEANT
+  // Author: Yuri Kharlov 11 September 2000
+  //BEGIN_HTML
+  /*
+    <H2>
+    Geant3 geometry of PHOS-CPV in ALICE
+    </H2>
+    <table width=700>
+
+    <tr>
+         <td>CPV perspective view</td>
+         <td>CPV front view      </td>
+    </tr>
+
+    <tr>
+         <td> <img height=300 width=290 src="../images/CPVallPersp.gif"> </td>
+         <td> <img height=300 width=290 src="../images/CPVallFront.gif"> </td>
+    </tr>
+
+    <tr>
+         <td>One CPV module, perspective view                            </td>
+         <td>One CPV module, front view (extended in vertical direction) </td>
+    </tr>
+
+    <tr>
+         <td><img height=300 width=290 src="../images/CPVmodulePers.gif"></td>
+         <td><img height=300 width=290 src="../images/CPVmoduleSide.gif"></td>
+    </tr>
+
+    </table>
+
+    <H2>
+    Geant3 geometry tree of PHOS-CPV in ALICE
+    </H2>
+    <center>
+    <img height=300 width=290 src="../images/CPVtree.gif">
+    </center>
+  */
+  //END_HTML  
+
+  Float_t par[3], x,y,z;
+
+  // Get pointer to the array containing media indexes
+  Int_t *idtmed = fIdtmed->GetArray() - 699 ;
+
+  AliPHOSGeometry * geom = GetGeometry() ; 
+
+  // The box containing all CPV for one PHOS module filled with air 
+  par[0] = geom->GetCPVBoxSize(0) / 2.0 ;  
+  par[1] = geom->GetCPVBoxSize(1) / 2.0 ; 
+  par[2] = geom->GetCPVBoxSize(2) / 2.0 ;
+  gMC->Gsvolu("PCPV", "BOX ", idtmed[798], par, 3) ;
+
+  Float_t * emcParams = geom->GetEMCAGeometry()->GetEMCParams() ;
+  z = - emcParams[3] ;
+  Int_t rotm ;
+  AliMatrix(rotm, 90.,0., 0., 0., 90., 90.) ;
+
+  gMC->Gspos("PCPV", 1, "PHOS", 0.0, 0.0, z, rotm, "ONLY") ; 
   
-  gMC->Gsvolu("PASP", "BOX ", IDTMED[701], DPASP, 3) ;
+  // Gassiplex board
   
-  YO = (  fGeom->GetAirFilledBoxSize(1) - fGeom->GetSupportPlateThickness() ) / 2. 
-       -  ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance()
-           - fGeom->GetUpperPlateThickness() - fGeom->GetSecondUpperPlateThickness() + DPCBL[1] * 2 ) ;
+  par[0] = geom->GetGassiplexChipSize(0)/2.;
+  par[1] = geom->GetGassiplexChipSize(1)/2.;
+  par[2] = geom->GetGassiplexChipSize(2)/2.;
+  gMC->Gsvolu("PCPC","BOX ",idtmed[707],par,3);
   
-  gMC->Gspos("PASP", 1, "PAIR", 0.0, YO, 0.0, 0, "ONLY") ;
+  // Cu+Ni foil covers Gassiplex board
+
+  par[1] = geom->GetCPVCuNiFoilThickness()/2;
+  gMC->Gsvolu("PCPD","BOX ",idtmed[710],par,3);
+  y      = -(geom->GetGassiplexChipSize(1)/2 - par[1]);
+  gMC->Gspos("PCPD",1,"PCPC",0,y,0,0,"ONLY");
+
+  // Position of the chip inside CPV
+
+  Float_t xStep = geom->GetCPVActiveSize(0) / (geom->GetNumberOfCPVChipsPhi() + 1);
+  Float_t zStep = geom->GetCPVActiveSize(1) / (geom->GetNumberOfCPVChipsZ()   + 1);
+  Int_t   copy  = 0;
+  y = geom->GetCPVFrameSize(1)/2           - geom->GetFTPosition(0) +
+    geom->GetCPVTextoliteThickness() / 2 + geom->GetGassiplexChipSize(1) / 2 + 0.1;
+  for (Int_t ix=0; ix<geom->GetNumberOfCPVChipsPhi(); ix++) {
+    x = xStep * (ix+1) - geom->GetCPVActiveSize(0)/2;
+    for (Int_t iz=0; iz<geom->GetNumberOfCPVChipsZ(); iz++) {
+      copy++;
+      z = zStep * (iz+1) - geom->GetCPVActiveSize(1)/2;
+      gMC->Gspos("PCPC",copy,"PCPV",x,y,z,0,"ONLY");
+    }
+  }
 
-  // ---
-  // --- Define Thermo Insulating Plate, position it inside PAIR ---
-  // --- right beneath PASP ---
-  // --- Lower Thermo Insulating Plate thickness ---
+  // Foiled textolite (1 mm of textolite + 50 mkm of Cu + 6 mkm of Ni)
   
-  Float_t DPTIP[3] ;
-  DPTIP[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
-  DPTIP[1] = fGeom->GetLowerThermoPlateThickness() / 2.0 ;
-  DPTIP[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
+  par[0] = geom->GetCPVActiveSize(0)        / 2;
+  par[1] = geom->GetCPVTextoliteThickness() / 2;
+  par[2] = geom->GetCPVActiveSize(1)        / 2;
+  gMC->Gsvolu("PCPF","BOX ",idtmed[707],par,3);
+
+  // Argon gas volume
+
+  par[1] = (geom->GetFTPosition(2) - geom->GetFTPosition(1) - geom->GetCPVTextoliteThickness()) / 2;
+  gMC->Gsvolu("PCPG","BOX ",idtmed[715],par,3);
+
+  for (Int_t i=0; i<4; i++) {
+    y = geom->GetCPVFrameSize(1) / 2 - geom->GetFTPosition(i) + geom->GetCPVTextoliteThickness()/2;
+    gMC->Gspos("PCPF",i+1,"PCPV",0,y,0,0,"ONLY");
+    if(i==1){
+      y-= (geom->GetFTPosition(2) - geom->GetFTPosition(1)) / 2;
+      gMC->Gspos("PCPG",1,"PCPV ",0,y,0,0,"ONLY");
+    }
+  }
 
-  gMC->Gsvolu("PTIP", "BOX ", IDTMED[706], DPTIP, 3) ;
+  // Dummy sensitive plane in the middle of argone gas volume
 
-  YO =  ( fGeom->GetAirFilledBoxSize(1) - fGeom->GetLowerThermoPlateThickness() ) / 2. 
-       -  ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetUpperPlateThickness() 
-            - fGeom->GetSecondUpperPlateThickness() + DPCBL[1] * 2 + fGeom->GetSupportPlateThickness() ) ;
+  par[1]=0.001;
+  gMC->Gsvolu("PCPQ","BOX ",idtmed[715],par,3);
+  gMC->Gspos ("PCPQ",1,"PCPG",0,0,0,0,"ONLY");
 
-  gMC->Gspos("PTIP", 1, "PAIR", 0.0, YO, 0.0, 0, "ONLY") ;
+  // Cu+Ni foil covers textolite
 
-  // ---
-  // --- Define Textolit Plate, position it inside PAIR ---
-  // --- right beneath PTIP ---
-  // --- Lower Textolit Plate thickness ---
-  Float_t DPTXP[3] ;
-  DPTXP[0] = fGeom->GetAirFilledBoxSize(0) / 2.0 ;
-  DPTXP[1] = fGeom->GetLowerTextolitPlateThickness() / 2.0 ;
-  DPTXP[2] = fGeom->GetAirFilledBoxSize(2) / 2.0 ;
+  par[1] = geom->GetCPVCuNiFoilThickness() / 2;
+  gMC->Gsvolu("PCP1","BOX ",idtmed[710],par,3);
+  y = geom->GetCPVTextoliteThickness()/2 - par[1];
+  gMC->Gspos ("PCP1",1,"PCPF",0,y,0,0,"ONLY");
 
-  gMC->Gsvolu("PTXP", "BOX ", IDTMED[707], DPTXP, 3) ;
+  // Aluminum frame around CPV
 
-  YO =  ( fGeom->GetAirFilledBoxSize(1) - fGeom->GetLowerTextolitPlateThickness() ) / 2. 
-       -  ( fGeom->GetIPtoCrystalSurface() - fGeom->GetIPtoOuterCoverDistance() - fGeom->GetUpperPlateThickness() 
-            - fGeom->GetSecondUpperPlateThickness() + DPCBL[1] * 2 + fGeom->GetSupportPlateThickness() 
-            +  fGeom->GetLowerThermoPlateThickness() ) ;
+  par[0] = geom->GetCPVFrameSize(0)/2;
+  par[1] = geom->GetCPVFrameSize(1)/2;
+  par[2] = geom->GetCPVBoxSize(2)  /2;
+  gMC->Gsvolu("PCF1","BOX ",idtmed[701],par,3);
 
-  gMC->Gspos("PTXP", 1, "PAIR", 0.0, YO, 0.0, 0, "ONLY") ;
+  par[0] = geom->GetCPVBoxSize(0)/2 - geom->GetCPVFrameSize(0);
+  par[1] = geom->GetCPVFrameSize(1)/2;
+  par[2] = geom->GetCPVFrameSize(2)/2;
+  gMC->Gsvolu("PCF2","BOX ",idtmed[701],par,3);
+
+  for (Int_t j=0; j<=1; j++) {
+    x = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(0) - geom->GetCPVFrameSize(0)) / 2;
+    gMC->Gspos("PCF1",j+1,"PCPV", x,0,0,0,"ONLY");
+    z = TMath::Sign(1,2*j-1) * (geom->GetCPVBoxSize(2) - geom->GetCPVFrameSize(2)) / 2;
+    gMC->Gspos("PCF2",j+1,"PCPV",0, 0,z,0,"ONLY");
+  }
 
 }
 
+
 //____________________________________________________________________________
-void AliPHOSv0::CreateGeometryforPPSD()
+void AliPHOSv0::CreateGeometryforSupport()
 {
-  // Get pointer to the array containing media indeces
-  Int_t *IDTMED = fIdtmed->GetArray() - 699 ;
+  // Create the PHOS' support geometry for GEANT
+    //BEGIN_HTML
+  /*
+    <H2>
+    Geant3 geometry of the PHOS's support
+    </H2>
+    <P><CENTER>
+    <IMG Align=BOTTOM ALT="EMC geant tree" SRC="../images/PHOS_support.gif"> 
+    </CENTER><P>
+  */
+  //END_HTML  
   
-  // The box containing all PPSD's for one PHOS module filled with air 
-  Float_t PPSD[3] ; 
-  PPSD[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;  
-  PPSD[1] = fGeom->GetPPSDBoxSize(1) / 2.0 ; 
-  PPSD[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
-
-  gMC->Gsvolu("PPSD", "BOX ", IDTMED[798], PPSD, 3) ;
-
-  Float_t YO =  fGeom->GetOuterBoxSize(1) / 2.0 ;
-
-  gMC->Gspos("PPSD", 1, "PHOS", 0.0, YO, 0.0, 0, "ONLY") ; 
+  Float_t par[5], x0,y0,z0 ; 
+  Int_t   i,j,copy;
 
-  // Now we build a micromegas module
-  // The box containing the whole module filled with epoxy (FR4)
+  // Get pointer to the array containing media indexes
+  Int_t *idtmed = fIdtmed->GetArray() - 699 ;
 
-  Float_t MPPSD[3] ;  
-  MPPSD[0] = fGeom->GetPPSDModuleSize(0) / 2.0 ;  
-  MPPSD[1] = fGeom->GetPPSDModuleSize(1) / 2.0 ;  
-  MPPSD[2] = fGeom->GetPPSDModuleSize(2) / 2.0 ;
+  AliPHOSGeometry * geom = GetGeometry() ; 
 
-  gMC->Gsvolu("MPPS", "BOX ", IDTMED[708], MPPSD, 3) ;  
-  // Inside MPPSD :
-  // 1. The Top Lid made of epoxy (FR4) 
-
-  Float_t TLPPSD[3] ; 
-  TLPPSD[0] = fGeom->GetPPSDModuleSize(0) / 2.0 ; 
-  TLPPSD[1] = fGeom->GetLidThickness() / 2.0 ;
-  TLPPSD[2] = fGeom->GetPPSDModuleSize(2) / 2.0 ;
-
-  gMC->Gsvolu("TLPS", "BOX ", IDTMED[708], TLPPSD, 3) ; 
-
-  Float_t  Y0 = ( fGeom->GetMicromegas1Thickness() - fGeom->GetLidThickness() ) / 2. ; 
+  // --- Dummy box containing two rails on which PHOS support moves
+  // --- Put these rails to the bottom of the L3 magnet
 
-  gMC->Gspos("TLPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
-  // 2. the upper panel made of composite material
+  par[0] =  geom->GetRailRoadSize(0) / 2.0 ;
+  par[1] =  geom->GetRailRoadSize(1) / 2.0 ;
+  par[2] =  geom->GetRailRoadSize(2) / 2.0 ;
+  gMC->Gsvolu("PRRD", "BOX ", idtmed[798], par, 3) ;
 
-  Float_t UPPPSD[3] ; 
-  UPPPSD[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
-  UPPPSD[1] = fGeom->GetCompositeThickness() / 2.0 ;
-  UPPPSD[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
-  gMC->Gsvolu("UPPS", "BOX ", IDTMED[709], UPPPSD, 3) ; 
-  
-  Y0 = Y0 - fGeom->GetLidThickness() / 2. - fGeom->GetCompositeThickness() / 2. ; 
+  y0     = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) / 2.0) ;
+  gMC->Gspos("PRRD", 1, "ALIC", 0.0, y0, 0.0, 0, "ONLY") ; 
 
-  gMC->Gspos("UPPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
+  // --- Dummy box containing one rail
 
-  // 3. the anode made of Copper
-  
-  Float_t ANPPSD[3] ; 
-  ANPPSD[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ; 
-  ANPPSD[1] = fGeom->GetAnodeThickness() / 2.0 ; 
-  ANPPSD[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0  ; 
+  par[0] =  geom->GetRailOuterSize(0) / 2.0 ;
+  par[1] =  geom->GetRailOuterSize(1) / 2.0 ;
+  par[2] =  geom->GetRailOuterSize(2) / 2.0 ;
+  gMC->Gsvolu("PRAI", "BOX ", idtmed[798], par, 3) ;
 
-  gMC->Gsvolu("ANPS", "BOX ", IDTMED[710], ANPPSD, 3) ; 
-  
-  Y0 = Y0 - fGeom->GetCompositeThickness() / 2. - fGeom->GetAnodeThickness()  / 2. ; 
-  
-  gMC->Gspos("ANPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
-
-  // 4. the conversion gap + avalanche gap filled with gas
-
-  Float_t GGPPSD[3] ; 
-  GGPPSD[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
-  GGPPSD[1] = ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() ) / 2.0 ; 
-  GGPPSD[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
+  for (i=0; i<2; i++) {
+    x0     = (2*i-1) * geom->GetDistanceBetwRails()  / 2.0 ;
+    gMC->Gspos("PRAI", i, "PRRD", x0, 0.0, 0.0, 0, "ONLY") ; 
+  }
 
-  gMC->Gsvolu("GGPS", "BOX ", IDTMED[715], GGPPSD, 3) ; 
-  
-  // --- Divide GGPP in X (phi) and Z directions --
-  gMC->Gsdvn("GROW", "GGPS", fGeom->GetNumberOfPadsPhi(), 1) ;
-  gMC->Gsdvn("GCEL", "GROW", fGeom->GetNumberOfPadsZ() , 3) ;
+  // --- Upper and bottom steel parts of the rail
 
-  Y0 = Y0 - fGeom->GetAnodeThickness() / 2.  - ( fGeom->GetConversionGap() +  fGeom->GetAvalancheGap() ) / 2. ; 
+  par[0] =  geom->GetRailPart1(0) / 2.0 ;
+  par[1] =  geom->GetRailPart1(1) / 2.0 ;
+  par[2] =  geom->GetRailPart1(2) / 2.0 ;
+  gMC->Gsvolu("PRP1", "BOX ", idtmed[716], par, 3) ;
 
-  gMC->Gspos("GGPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
+  y0     = - (geom->GetRailOuterSize(1) - geom->GetRailPart1(1))  / 2.0 ;
+  gMC->Gspos("PRP1", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
+  y0     =   (geom->GetRailOuterSize(1) - geom->GetRailPart1(1))  / 2.0 - geom->GetRailPart3(1);
+  gMC->Gspos("PRP1", 2, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ;
 
+  // --- The middle vertical steel parts of the rail
 
-  // 6. the cathode made of Copper
+  par[0] =  geom->GetRailPart2(0) / 2.0 ;
+  par[1] =  geom->GetRailPart2(1) / 2.0 ;
+  par[2] =  geom->GetRailPart2(2) / 2.0 ;
+  gMC->Gsvolu("PRP2", "BOX ", idtmed[716], par, 3) ;
 
-  Float_t CAPPSD[3] ;
-  CAPPSD[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
-  CAPPSD[1] = fGeom->GetCathodeThickness() / 2.0 ; 
-  CAPPSD[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0  ;
+  y0     =   - geom->GetRailPart3(1) / 2.0 ;
+  gMC->Gspos("PRP2", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ; 
 
-  gMC->Gsvolu("CAPS", "BOX ", IDTMED[710], CAPPSD, 3) ; 
+  // --- The most upper steel parts of the rail
 
-  Y0 = Y0 - ( fGeom->GetAvalancheGap() +  fGeom->GetAvalancheGap() ) / 2. - fGeom->GetCathodeThickness()  / 2. ; 
+  par[0] =  geom->GetRailPart3(0) / 2.0 ;
+  par[1] =  geom->GetRailPart3(1) / 2.0 ;
+  par[2] =  geom->GetRailPart3(2) / 2.0 ;
+  gMC->Gsvolu("PRP3", "BOX ", idtmed[716], par, 3) ;
 
-  gMC->Gspos("CAPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
+  y0     =   (geom->GetRailOuterSize(1) - geom->GetRailPart3(1))  / 2.0 ;
+  gMC->Gspos("PRP3", 1, "PRAI", 0.0, y0, 0.0, 0, "ONLY") ; 
 
-  // 7. the printed circuit made of G10       
+  // --- The wall of the cradle
+  // --- The wall is empty: steel thin walls and air inside
 
-  Float_t PCPPSD[3] ; 
-  PCPPSD[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2,.0 ; 
-  PCPPSD[1] = fGeom->GetPCThickness() / 2.0 ; 
-  PCPPSD[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
+  par[1] =  TMath::Sqrt(TMath::Power((geom->GetIPtoCPVDistance() + geom->GetOuterBoxSize(3)),2) +
+                       TMath::Power((geom->GetOuterBoxSize(1)/2),2))+10. ;
+  par[0] =  par[1] - geom->GetCradleWall(1) ;
+  par[2] =  geom->GetCradleWall(2) / 2.0 ;
+  par[3] =  geom->GetCradleWall(3) ;
+  par[4] =  geom->GetCradleWall(4) ;
+  gMC->Gsvolu("PCRA", "TUBS", idtmed[716], par, 5) ;
 
-  gMC->Gsvolu("PCPS", "BOX ", IDTMED[711], CAPPSD, 3) ; 
+  par[0] +=  geom->GetCradleWallThickness() ;
+  par[1] -=  geom->GetCradleWallThickness() ;
+  par[2] -=  geom->GetCradleWallThickness() ;
+  gMC->Gsvolu("PCRE", "TUBS", idtmed[798], par, 5) ;
+  gMC->Gspos ("PCRE", 1, "PCRA", 0.0, 0.0, 0.0, 0, "ONLY") ; 
 
-  Y0 = Y0 - fGeom->GetCathodeThickness() / 2. - fGeom->GetPCThickness()  / 2. ; 
+  for (i=0; i<2; i++) {
+    z0 = (2*i-1) * (geom->GetOuterBoxSize(2) + geom->GetCradleWall(2) )/ 2.0  ;
+        gMC->Gspos("PCRA", i, "ALIC", 0.0, 0.0, z0, 0, "ONLY") ; 
+  }
 
-  gMC->Gspos("PCPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
+  // --- The "wheels" of the cradle
+  
+  par[0] = geom->GetCradleWheel(0) / 2;
+  par[1] = geom->GetCradleWheel(1) / 2;
+  par[2] = geom->GetCradleWheel(2) / 2;
+  gMC->Gsvolu("PWHE", "BOX ", idtmed[716], par, 3) ;
+
+  y0 = -(geom->GetRailsDistanceFromIP() - geom->GetRailRoadSize(1) -
+        geom->GetCradleWheel(1)/2) ;
+  for (i=0; i<2; i++) {
+    z0 = (2*i-1) * ((geom->GetOuterBoxSize(2) + geom->GetCradleWheel(2))/ 2.0 +
+                    geom->GetCradleWall(2));
+    for (j=0; j<2; j++) {
+      copy = 2*i + j;
+      x0 = (2*j-1) * geom->GetDistanceBetwRails()  / 2.0 ;
+      gMC->Gspos("PWHE", copy, "ALIC", x0, y0, z0, 0, "ONLY") ; 
+    }
+  }
 
-  // 8. the lower panel made of composite material
-                                                   
-  Float_t LPPPSD[3] ; 
-  LPPPSD[0] = ( fGeom->GetPPSDModuleSize(0) - fGeom->GetMicromegasWallThickness() ) / 2.0 ; 
-  LPPPSD[1] = fGeom->GetCompositeThickness() / 2.0 ; 
-  LPPPSD[2] = ( fGeom->GetPPSDModuleSize(2) - fGeom->GetMicromegasWallThickness() ) / 2.0 ;
+}
 
-  gMC->Gsvolu("LPPS", "BOX ", IDTMED[709], LPPPSD, 3) ; 
+//_____________________________________________________________________________
+void AliPHOSv0::AddAlignableVolumes() const
+{
+  //
+  // Create entries for alignable volumes associating the symbolic volume
+  // name with the corresponding volume path. Needs to be syncronized with
+  // eventual changes in the geometry
+  // Alignable volumes are:
+  // 1) PHOS modules as a whole
+  // 2) Cradle
+  // 3) Cradle wheels
+  // 4) Strip units (group of 2x8 crystals)
+
+  TString volpath, symname;
+
+  // Alignable modules
+  // Volume path /ALIC_1/PHOS_<i> => symbolic name /PHOS/Module<i>, <i>=1,2,3,4,5
+  
+  AliGeomManager::ELayerID idPHOS1 = AliGeomManager::kPHOS1;
+  AliGeomManager::ELayerID idPHOS2 = AliGeomManager::kPHOS2;
+  Int_t modUID, modnum = 0;
+  TString physModulePath="/ALIC_1/PHOS_";
+  TString symbModuleName="PHOS/Module";
+  Int_t nModules = GetGeometry()->GetNModules();
+  
+  char im[5] ;
+  for(Int_t iModule=1; iModule<=nModules; iModule++){
+    sprintf(im,"%d",iModule) ;
+    if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
+      continue ;
+    modUID = AliGeomManager::LayerToVolUID(idPHOS1,modnum++);
+    volpath = physModulePath;
+    volpath += iModule;
+    //    volpath += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1";
  
-  Y0 = Y0 - fGeom->GetPCThickness() / 2. - fGeom->GetCompositeThickness()  / 2. ; 
-
-  gMC->Gspos("LPPS", 1, "MPPS", 0.0, Y0, 0.0, 0, "ONLY") ; 
-
-  // Position the  fNumberOfModulesPhi x fNumberOfModulesZ modules (MPPSD) inside PPSD to cover a PHOS module
-  // the top and bottom one's (which are assumed identical) :
-
-   Float_t Yt = ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas1Thickness() ) / 2. ; 
-   Float_t Yb = - ( fGeom->GetPPSDBoxSize(1) - fGeom->GetMicromegas2Thickness() ) / 2. ; 
+   // Check the volume path if not all 5 modules exist
+    if (!gGeoManager->CheckPath(volpath.Data())) {                                                                                         
+      AliError(Form("Volume path %s not valid!",volpath.Data()));                                                                          
+      continue;                                                                                                                            
+    }                                                                                                                                      
+    symname = symbModuleName;
+    symname += iModule;
+    if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
+      continue ;
+//      AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
+
+    // Creates the Tracking to Local transformation matrix for PHOS modules
+    TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
+
+    Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
+    TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
+
+    TGeoHMatrix *matTtoL = new TGeoHMatrix;
+    matTtoL->RotateZ(-90.+angle);
+    matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
+    alignableEntry->SetMatrix(matTtoL);
+  }
 
-   Int_t CopyNumbertop = 0 ; 
-   Int_t CopyNumberbot = fGeom->GetNumberOfModulesPhi() *  fGeom->GetNumberOfModulesZ() ; 
+  //Aligning of CPV should be done for volume PCPV_1
+  symbModuleName="PHOS/Module";
+  modnum=0;
+  for(Int_t iModule=1; iModule<=nModules; iModule++){
+    if(strstr(GetTitle(),"noCPV"))
+      continue ;
+    sprintf(im,"%d",iModule) ;
+    if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0)
+      continue ;
+    modUID = AliGeomManager::LayerToVolUID(idPHOS2,modnum++);
+    volpath = physModulePath;
+    volpath += iModule;
+    volpath += "/PCPV_1";
+    // Check the volume path
+    if (!gGeoManager->CheckPath(volpath.Data())) {
+      AliError(Form("Volume path %s not valid!",volpath.Data()));
+      continue;
+    }
 
-   Float_t X  = ( fGeom->GetPPSDBoxSize(0) - fGeom->GetPPSDModuleSize(0) ) / 2. ;  
+    symname = symbModuleName;
+    symname += iModule;
+    symname += "/CPV";
+    if(!gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data(),modUID))
+      AliFatal(Form("Alignable entry %s not created. Volume path %s not valid", symname.Data(),volpath.Data()));
+          
+    // Creates the TGeo Local to Tracking transformation matrix ...
+    TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntryByUID(modUID) ;
+
+    Float_t angle = GetGeometry()->GetPHOSAngle(iModule);
+    TGeoHMatrix* globMatrix = alignableEntry->GetGlobalOrig();
+
+    TGeoHMatrix *matTtoL = new TGeoHMatrix;
+    matTtoL->RotateZ(-90.+angle);
+    matTtoL->MultiplyLeft(&(globMatrix->Inverse()));
+    alignableEntry->SetMatrix(matTtoL);
+    
+  }
 
-   for ( Int_t iphi = 1; iphi <= fGeom->GetNumberOfModulesPhi(); iphi++ ) { // the number of micromegas modules in phi per PHOS module
-      Float_t Z = ( fGeom->GetPPSDBoxSize(2) - fGeom->GetPPSDModuleSize(2) ) / 2. ;
+  // Alignable cradle walls
+  // Volume path /ALIC_1/PCRA_<i> => symbolic name /PHOS/Cradle<i>, <i>=0,1
 
-      for ( Int_t iz = 1; iz <= fGeom->GetNumberOfModulesZ(); iz++ ) { // the number of micromegas modules in z per PHOS module
-       gMC->Gspos("MPPS", ++CopyNumbertop, "PPSD", X, Yt, Z, 0, "ONLY") ;
-       gMC->Gspos("MPPS", ++CopyNumberbot, "PPSD", X, Yb, Z, 0, "ONLY") ; 
-       Z = Z - fGeom->GetPPSDModuleSize(2) ;
-      } // end of Z module loop   
-      X = X -  fGeom->GetPPSDModuleSize(0) ; 
-    } // end of phi module loop
+  TString physCradlePath="/ALIC_1/PCRA_";
+  TString symbCradleName="PHOS/Cradle";
+  Int_t nCradles = 2;
 
-   // The Lead converter between two air gaps
-   // 1. Upper air gap
+  for(Int_t iCradle=0; iCradle<nCradles; iCradle++){
+    volpath = physCradlePath;
+    volpath += iCradle;
+    symname = symbCradleName;
+    symname += iCradle;
+    gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
+  }
 
-   Float_t UAPPSD[3] ;
-   UAPPSD[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;
-   UAPPSD[1] = fGeom->GetMicro1ToLeadGap() / 2.0 ; 
-   UAPPSD[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
+  // Alignable wheels
+  // Volume path /ALIC_1/PWHE_<i> => symbolic name /PHOS/Wheel<i>, i=0,1,2,3
 
-  gMC->Gsvolu("UAPPSD", "BOX ", IDTMED[798], UAPPSD, 3) ; 
+  TString physWheelPath="/ALIC_1/PWHE_";
+  TString symbWheelName="PHOS/Wheel";
+  Int_t nWheels = 4;
 
-  Y0 = ( fGeom->GetPPSDBoxSize(1) - 2 * fGeom->GetMicromegas1Thickness() - fGeom->GetMicro1ToLeadGap() ) / 2. ; 
+  for(Int_t iWheel=0; iWheel<nWheels; iWheel++){
+    volpath = physWheelPath;
+    volpath += iWheel;
+    symname = symbWheelName;
+    symname += iWheel;
+    gGeoManager->SetAlignableEntry(symname.Data(),volpath.Data());
+  }
 
-  gMC->Gspos("UAPPSD", 1, "PPSD", 0.0, Y0, 0.0, 0, "ONLY") ; 
+  //Physical strip path is a combination of: physModulePath + module number + 
+  //physStripPath + strip number == ALIC_1/PHOS_N/..../PSTR_M
+  const Int_t nStripsX = GetGeometry()->GetEMCAGeometry()->GetNStripX();
+  const Int_t nStripsZ = GetGeometry()->GetEMCAGeometry()->GetNStripZ();
+  TString partialPhysStripName(100);
+  TString fullPhysStripName(100);
+  TString partialSymbStripName(100);
+  TString fullSymbStripName(100);
+
+  for(Int_t module = 1; module <= nModules; ++module){
+
+    sprintf(im,"%d",module) ;
+    if(strstr(GetTitle(),im)==0 && strcmp(GetTitle(),"IHEP")!=0 && strcmp(GetTitle(),"noCPV")!=0)
+      continue ;
+
+    volpath = physModulePath;
+    volpath += module;
+    // Check the volume path if not all 5 modules exist
+    if (!gGeoManager->CheckPath(volpath.Data())) {
+      AliError(Form("Volume path %s does not exist",volpath.Data())) ;
+      continue;
+    }
 
-   // 2. Lead converter
+    partialPhysStripName  = physModulePath;
+    partialPhysStripName += module;
+    partialPhysStripName += "/PEMC_1/PCOL_1/PTIO_1/PCOR_1/PAGA_1/PTII_1/PSTR_";
+
+    partialSymbStripName  = symbModuleName;
+    partialSymbStripName += module;
+    partialSymbStripName += "/Strip_";
+
+    for(Int_t i = 0, ind1D = 1; i < nStripsX; ++i){//ind1D starts from 1 (PSTR_1...PSTR_224...)
+      for(Int_t j = 0; j < nStripsZ; ++j, ++ind1D){
+         fullPhysStripName = partialPhysStripName;
+         fullPhysStripName += ind1D;
+         
+         fullSymbStripName  = partialSymbStripName;
+         fullSymbStripName += i;//ind1D;
+         fullSymbStripName += '_';
+         fullSymbStripName += j;
+
+         gGeoManager->SetAlignableEntry(fullSymbStripName.Data(), fullPhysStripName.Data());
+
+         // Creates the TGeo Local to Tracking transformation matrix ...
+         TGeoPNEntry *alignableEntry = gGeoManager->GetAlignableEntry(fullSymbStripName.Data()) ;
+         const char *path = alignableEntry->GetTitle();
+         if (!gGeoManager->cd(path))
+           AliFatal(Form("Volume path %s not valid!",path));
+         TGeoHMatrix matLtoT = *gGeoManager->GetCurrentMatrix() ;
+         Double_t refl[3]={-1.,-1.,-1.} ;
+         matLtoT.SetScale(refl) ;
+         TGeoHMatrix *matTtoL = new TGeoHMatrix(matLtoT.Inverse());
  
-  Float_t LCPPSD[3] ; 
-  LCPPSD[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ;
-  LCPPSD[1] = fGeom->GetLeadConverterThickness() / 2.0 ; 
-  LCPPSD[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
+         char phosPath[50] ;
+         sprintf(phosPath,"/ALIC_1/PHOS_%d",module) ;
+         if (!gGeoManager->cd(phosPath)){
+            AliFatal("Geo manager can not find path \n");
+         }
+         TGeoHMatrix *mPHOS = gGeoManager->GetCurrentMatrix();
+         if (mPHOS) 
+           matTtoL->Multiply(mPHOS);
+         else{
+           AliFatal("Geo matrixes are not loaded \n") ;
+         }
+         //Switch y<->z
+         Double_t rot[9]={1.,0.,0.,  0.,1.,0., 0.,0.,1.} ;
+         matTtoL->SetRotation(rot) ;
+         alignableEntry->SetMatrix(matTtoL);
+
+/*
+  //Check poisition of corner cell of the strip
+  AliPHOSGeometry * geom = AliPHOSGeometry::GetInstance() ;
+  Int_t relid[4] ; 
+  relid[0] = module ;
+  relid[1] = 0 ;
+  Int_t iStrip=ind1D ;
+  Int_t icell=1 ;
+  Int_t raw = geom->GetEMCAGeometry()->GetNCellsXInStrip()*((iStrip-1)/geom->GetEMCAGeometry()->GetNStripZ()) +
+                1 + (icell-1)/geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
+  Int_t col = geom->GetEMCAGeometry()->GetNCellsZInStrip()*(1+(iStrip-1)%geom->GetEMCAGeometry()->GetNStripZ()) - 
+                (icell-1)%geom->GetEMCAGeometry()->GetNCellsZInStrip() ;
+  if(col==0) col=geom->GetNZ() ;
+  relid[2] = raw ;
+  relid[3] = col ;
+  Float_t xG,zG ; 
+  geom->RelPosInModule(relid, xG, zG) ;
+printf("============\n") ;
+printf("Geometry: x=%f, z=%f \n",xG,zG) ;
+  Int_t absid ; 
+  geom->RelToAbsNumbering(relid,absid) ;
+  Double_t pos[3]= {-2.2*3.5,0.0,1.1}; //Position incide the strip (Y coordinalte is not important)
+  Double_t posC[3]={0.0,0.0,0.}; //Global position
  
-  gMC->Gsvolu("LCPPSD", "BOX ", IDTMED[712], LCPPSD, 3) ; 
-  
-  Y0 = Y0 - fGeom->GetMicro1ToLeadGap() / 2. - fGeom->GetLeadConverterThickness() / 2. ; 
-
-  gMC->Gspos("LCPPSD", 1, "PPSD", 0.0, Y0, 0.0, 0, "ONLY") ; 
-
-  // 3. Lower air gap
-
-  Float_t LAPPSD[3] ; 
-  LAPPSD[0] = fGeom->GetPPSDBoxSize(0) / 2.0 ; 
-  LAPPSD[1] = fGeom->GetLeadToMicro2Gap() / 2.0 ; 
-  LAPPSD[2] = fGeom->GetPPSDBoxSize(2) / 2.0 ;
-
-  gMC->Gsvolu("LAPPSD", "BOX ", IDTMED[798], LAPPSD, 3) ; 
-    
-  Y0 = Y0 - fGeom->GetLeadConverterThickness() / 2. - fGeom->GetLeadToMicro2Gap()  / 2. ; 
-  
-  gMC->Gspos("LAPPSD", 1, "PPSD", 0.0, Y0, 0.0, 0, "ONLY") ; 
-   
-}
-
-//___________________________________________________________________________
-Int_t AliPHOSv0::Digitize(Float_t Energy){
-  Float_t fB = 10000000. ;
-  Float_t fA = 0. ;
-  Int_t chan = Int_t(fA + Energy*fB ) ;
-  return chan ;
-}
-//___________________________________________________________________________
-void AliPHOSv0::FinishEvent()
-{
-  cout << "//_____________________________________________________" << endl ;
-  cout << "<I> AliPHOSv0::FinishEvent() -- Starting digitalization" << endl ;
-  Int_t i ;
-  TClonesArray &lDigits = *fDigits ;
-  AliPHOSHit  * Hit ;
-  AliPHOSDigit * Digit ;
-
-  for ( i = 0 ; i < fNTmpHits ; i++ ) {
-    Hit = (AliPHOSHit*)fTmpHits->At(i) ;
-    assert (Hit!=0) ;
-    Digit = new AliPHOSDigit(Hit->GetId(),Digitize(Hit->GetEnergy())) ;
-    new(lDigits[fNdigits]) AliPHOSDigit(* Digit) ;
-    fNdigits++;  delete Digit ;    
+  matTtoL->MasterToLocal(pos,posC);
+printf("Matrix:   x=%f, z=%f, y=%f \n",posC[0],posC[2],posC[1]) ;
+*/
+      }
+    }
   }
-
-  // Reset the array of all the "accumulated hits" of this event.
-  fNTmpHits = 0 ;
-  fTmpHits->Delete();
 }
 
 //____________________________________________________________________________
-void AliPHOSv0::Init(void)
+Float_t AliPHOSv0::ZMin(void) const
 {
-  Int_t i;
+  // Overall dimension of the PHOS (min)
 
-  printf("\n");
-  for(i=0;i<35;i++) printf("*");
-  printf(" PHOS_INIT ");
-  for(i=0;i<35;i++) printf("*");
-  printf("\n");
+  AliPHOSGeometry * geom = GetGeometry() ; 
 
-  // Here the PHOS initialisation code (if any!)
-
-  for(i=0;i<80;i++) printf("*");
-  printf("\n");
-  
+  return -geom->GetOuterBoxSize(2)/2.;
 }
 
-//___________________________________________________________________________
-void AliPHOSv0::MakeBranch(Option_t* opt)
-{  
-  //
-  // Create a new branch in the current Root Tree
-  // The branch of fHits is automatically split
-  //
-  AliDetector::MakeBranch(opt) ;
-  
-  char branchname[10];
-  sprintf(branchname,"%s",GetName());
-  char *D = strstr(opt,"D");
-  
-  if (fDigits && gAlice->TreeD() && D) {
-    gAlice->TreeD()->Branch(branchname,&fDigits, fBufferSize);
-    printf("* AliPHOS::MakeBranch * Making Branch %s for digits\n",branchname);
-  }
-}
-//_____________________________________________________________________________
+//____________________________________________________________________________
+Float_t AliPHOSv0::ZMax(void) const
+{
+  // Overall dimension of the PHOS (max)
 
-void AliPHOSv0::Reconstruction(AliPHOSReconstructioner& Reconstructioner)
-{ 
-  fReconstructioner = &Reconstructioner;
-  if (fEmcClusters) 
-    { fEmcClusters->Delete();}
-  else
-    { fEmcClusters= new TClonesArray("AliPHOSEmcRecPoint", 100); } ;
-
-  if (fPpsdClusters)
-    { fPpsdClusters->Delete(); }
-  else
-    { fPpsdClusters = new TClonesArray("AliPHOSPpsdRecPoint", 100) ;}
-
-  if (fTrackSegments)
-    { fTrackSegments->Delete(); }
-  else
-    { fTrackSegments = new TObjArray(100) ;}
-  
-  fReconstructioner->Make(fDigits, fEmcClusters, fPpsdClusters, fTrackSegments);
-  
+  AliPHOSGeometry * geom = GetGeometry() ; 
+
+  return  geom->GetOuterBoxSize(2)/2.;
 }
 
 //____________________________________________________________________________
-void AliPHOSv0::StepManager(void)
+void AliPHOSv0::Init(void)
 {
-  Int_t          RelId[4] ;      // (box, layer, row, column) indices
-  Float_t        xyze[4] ;       // position wrt MRS and energy deposited
-  TLorentzVector pos ;
-  Int_t copy;
-
-  TString name = fGeom->GetName() ; 
-
-  if ( name == "GPS2" ) { // the CPV is a PPSD
-    if( gMC->CurrentVolID(copy) == gMC->VolId("GCEL") )
-    //     if( strcmp ( gMC->CurrentVolName(), "GCEL" ) == 0 )  // We are inside a gas cell 
-    {
-      gMC->TrackPosition(pos) ;
-      xyze[0] = pos[0] ;
-      xyze[1] = pos[1] ;
-      xyze[2] = pos[2] ;
-      xyze[3] = gMC->Edep() ; 
-
-      if ( xyze[3] != 0 ) { // there is deposited energy 
-               gMC->CurrentVolOffID(5, RelId[0]) ;  // get the PHOS Module number
-               gMC->CurrentVolOffID(3, RelId[1]) ;  // get the Micromegas Module number 
-      // 1-> Geom->GetNumberOfModulesPhi() *  fGeom->GetNumberOfModulesZ() upper                         
-      //  >  fGeom->GetNumberOfModulesPhi()  *  fGeom->GetNumberOfModulesZ() lower
-               gMC->CurrentVolOffID(1, RelId[2]) ;  // get the row number of the cell
-        gMC->CurrentVolID(RelId[3]) ;        // get the column number 
-
-       // get the absolute Id number
-
-       Int_t AbsId ; 
-               fGeom->RelToAbsNumbering(RelId,AbsId) ; 
-
-       // add current hit to the hit list      
-       AddHit(gAlice->CurrentTrack(), AbsId, xyze);
-
-      } // there is deposited energy 
-     } // We are inside the gas of the CPV  
-   } // GPS2 configuration
+  // Just prints an information message
   
-   if(gMC->CurrentVolID(copy) == gMC->VolId("PXTL") ) 
-  //      if( strcmp ( gMC->CurrentVolName(), "PXTL" ) == 0 ) { //  We are inside a PWO crystal
-     {
-       gMC->TrackPosition(pos) ;
-       xyze[0] = pos[0] ;
-       xyze[1] = pos[1] ;
-       xyze[2] = pos[2] ;
-       xyze[3] = gMC->Edep() ;
-
-       if ( xyze[3] != 0 ) {
-          gMC->CurrentVolOffID(10, RelId[0]) ; // get the PHOS module number ;
-          RelId[1] = 0   ;                    // means PW04
-          gMC->CurrentVolOffID(4, RelId[2]) ; // get the row number inside the module
-          gMC->CurrentVolOffID(3, RelId[3]) ; // get the cell number inside the module
-
-      // get the absolute Id number
-
-          Int_t AbsId ; 
-          fGeom->RelToAbsNumbering(RelId,AbsId) ; 
-      // add current hit to the hit list
+  Int_t i;
 
-          AddHit(gAlice->CurrentTrack(), AbsId, xyze);
+  if(AliLog::GetGlobalDebugLevel()>0) {
+    TString st ; 
+    for(i=0;i<35;i++) 
+      st += "*";
+    Info("Init", "%s", st.Data()) ;  
+    // Here the PHOS initialisation code (if any!)
     
-       } // there is deposited energy
-    } // we are inside a PHOS Xtal
-}
+    AliPHOSGeometry * geom = GetGeometry() ; 
 
+    if (geom!=0)  
+      Info("Init", "AliPHOS%s: PHOS geometry intialized for %s", Version().Data(), geom->GetName()) ;
+    else
+      Info("Init", "AliPHOS%s: PHOS geometry initialization failed !", Version().Data()) ;       
+
+    Info("Init", "%s", st.Data()) ;  
+  }
+}