diff --git a/Examples/options/LCIO_read_pan.py b/Examples/options/LCIO_read_pan.py
index 32292b36c7f0263841b7dc7663ebaea681b2dabf..c85a3cae511ceeb1cddb600fb5d05e5af0e5e484 100644
--- a/Examples/options/LCIO_read_pan.py
+++ b/Examples/options/LCIO_read_pan.py
@@ -52,6 +52,9 @@ gearSvc.GearXMLFile = "../Detector/DetCEPCv4/compact/FullDetGear.xml"
 from Configurables import PandoraPFAlg
 
 pandoralg = PandoraPFAlg("PandoraPFAlg")
+pandoralg.use_dd4hep_geo     = False
+pandoralg.use_dd4hep_decoder = False
+pandoralg.use_preshower      = False
 pandoralg.collections = [
         "MCParticle:MCParticle",
         "CalorimeterHit:ECALBarrel",
diff --git a/Examples/options/tut_detsim_pandora.py b/Examples/options/tut_detsim_pandora.py
index af80c1e6565ec12dc9cef76faa1bfa7b8fd62fd8..98fd9617dc55515a3e61249b520367d8354ceaf1 100644
--- a/Examples/options/tut_detsim_pandora.py
+++ b/Examples/options/tut_detsim_pandora.py
@@ -114,11 +114,14 @@ example_CaloDigiAlg.CaloAssociationCollection    = "RecoCaloAssociation_ECALBarr
 ##############################################################################
 from Configurables import GearSvc
 gearSvc  = GearSvc("GearSvc")
-gearSvc.GearXMLFile = "../Detector/DetCEPCv4/compact/FullDetGear.xml"
+gearSvc.GearXMLFile = "Detector/DetCEPCv4/compact/FullDetGear.xml"
 ##############################################################################
 from Configurables import PandoraPFAlg
 
 pandoralg = PandoraPFAlg("PandoraPFAlg")
+pandoralg.use_dd4hep_geo     = True
+pandoralg.use_dd4hep_decoder = True
+pandoralg.use_preshower      = False
 pandoralg.collections = [
         "MCParticle:MCParticle",
         "CalorimeterHit:ECALBarrel",
@@ -143,7 +146,7 @@ pandoralg.WriteReconstructedParticleCollection = "PandoraPFOs"
 pandoralg.WriteVertexCollection                = "PandoraPFANewStartVertices"               
 pandoralg.AnaOutput = "Ana.root"
 
-pandoralg.PandoraSettingsDefault_xml = "../Reconstruction/PFA/Pandora/PandoraSettingsDefault.xml"
+pandoralg.PandoraSettingsDefault_xml = "Reconstruction/PFA/Pandora/PandoraSettingsDefault.xml"
 #### Do not chage the collection name, only add or remove ###############
 pandoralg.TrackCollections      =  ["MarlinTrkTracks"]
 pandoralg.ECalCaloHitCollections=  ["ECALBarrel", "ECALEndcap", "ECALOther"]
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/CMakeLists.txt b/Reconstruction/PFA/Pandora/GaudiPandora/CMakeLists.txt
index be0c48674b7465d7ff1bfd607eff6b172439933c..3842a7aaf8e49e03f6a91de2a98ff5c24b66f71b 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/CMakeLists.txt
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/CMakeLists.txt
@@ -1,10 +1,10 @@
 gaudi_subdir(GaudiPandora v0r0)
 
 find_package(LCIO REQUIRED ) 
+find_package(DD4hep COMPONENTS DDG4 REQUIRED)
 find_package(GEAR REQUIRED)
 message("ENV GEAR: $ENV{GEAR}")
 
-find_package(CLHEP REQUIRED;CONFIG)
 find_package(EDM4HEP REQUIRED )
 include_directories(${EDM4HEP_INCLUDE_DIR})
 
@@ -16,14 +16,14 @@ include_directories(${LCContent_INCLUDE_DIRS})
 link_libraries(${LCContent_LIBRARIES})
 
 
-list(APPEND CMAKE_MODULE_PATH "$ENV{ROOTSYS}/etc/cmake/")
-find_package(ROOT 5.26.00 REQUIRED COMPONENTS Eve Geom RGL EG)
+find_package(ROOT COMPONENTS MathCore Physics GenVector Geom REQUIRED)
 
 
 gaudi_depends_on_subdirs(
     Service/EventSeeder
     Service/GearSvc
     Utilities/DataHelper
+    Detector/DetInterface
 )
 
 set(dir_srcs
@@ -33,12 +33,13 @@ set(dir_srcs
     src/CaloHitCreator.cpp
     src/TrackCreator.cpp
     src/PfoCreator.cpp
+    src/Utility.cpp
 )
 set(dir_include include)
 # Modules
 gaudi_add_module(GaudiPandora ${dir_srcs}
-    INCLUDE_DIRS ${dir_include} GaudiKernel FWCore ${CLHEP_INCLUDE_DIR}  ${LCIO_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} gear  
-    LINK_LIBRARIES GaudiKernel FWCore ${CLHEP_LIBRARIES} ROOT ${LCIO_LIBRARIES} ${GEAR_LIBRARIES} DataHelperLib 
+    INCLUDE_DIRS ${dir_include} GaudiKernel FWCore CLHEP  ${LCIO_INCLUDE_DIRS} ROOT gear DD4hep 
+    LINK_LIBRARIES GaudiKernel FWCore CLHEP ROOT ${LCIO_LIBRARIES} ${GEAR_LIBRARIES} DataHelperLib DD4hep ${DD4hep_COMPONENT_LIBRARIES} DDRec 
       -Wl,--no-as-needed 
       EDM4HEP::edm4hep EDM4HEP::edm4hepDict
       -Wl,--as-needed 
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/include/CaloHitCreator.h b/Reconstruction/PFA/Pandora/GaudiPandora/include/CaloHitCreator.h
index 91fd1ccd04f1de4ce7de89d83048171882564ab2..b947f49d25bf7e6147302d4c167e3bac7b026227 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/include/CaloHitCreator.h
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/include/CaloHitCreator.h
@@ -11,6 +11,14 @@
 #include "GaudiKernel/ISvcLocator.h"
 #include "edm4hep/CalorimeterHit.h"
 
+#include "DetInterface/IGeomSvc.h"
+#include "gear/LayerLayout.h"
+#include <DD4hep/DD4hepUnits.h>
+#include <DD4hep/DetType.h>
+#include <DD4hep/DetectorSelector.h>
+#include <DD4hep/Detector.h>
+
+#include "Utility.h"
 #include "gear/LayerLayout.h"
 
 #include "Api/PandoraApi.h"
@@ -89,6 +97,9 @@ public:
         float           m_eCalScToHadGeVBarrel;                 ///< The calibration from deposited Sc-layer energy on the endcaps to hadronic energy
         float           m_eCalSiToHadGeVEndCap;                 ///< The calibration from deposited Si-layer energy on the enecaps to hadronic energy
         float           m_eCalScToHadGeVEndCap;                 ///< The calibration from deposited Sc-layer energy on the endcaps to hadronic energy
+        bool            m_use_dd4hep_geo;                       /// 
+        bool            m_use_dd4hep_decoder;                       /// 
+        bool            m_use_preshower;                       /// 
     };
 
     /**
@@ -165,6 +176,8 @@ private:
      */
     void GetEndCapCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const gear::LayerLayout &layerLayout,
         PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const;
+    void GetEndCapCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer> &layers,
+    PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const;
 
     /**
      *  @brief  Get barrel specific calo hit properties: cell size, absorber radiation and interaction lengths, normal vector
@@ -173,6 +186,9 @@ private:
     void GetBarrelCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const gear::LayerLayout &layerLayout,
         unsigned int barrelSymmetryOrder, float barrelPhi0, unsigned int staveNumber, PandoraApi::CaloHit::Parameters &caloHitParameters,
         float &absorberCorrection) const;
+    void GetBarrelCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer> &layers,
+        unsigned int barrelSymmetryOrder, float barrelPhi0, unsigned int staveNumber, PandoraApi::CaloHit::Parameters &caloHitParameters,
+        float &absorberCorrection) const;
 
     /**
      *  @brief  Get number of active layers from position of a calo hit to the edge of the detector
@@ -235,6 +251,8 @@ private:
     std::string                         m_encoder_str_LCal ; 
     std::string                         m_encoder_str_LHCal; 
     gear::GearMgr* _GEAR;
+    IGeomSvc* m_geosvc;
+    dd4hep::DDSegmentation::BitFieldCoder* m_decoder;
 };
 
 //------------------------------------------------------------------------------------------------------------------------------------------
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/include/GeometryCreator.h b/Reconstruction/PFA/Pandora/GaudiPandora/include/GeometryCreator.h
index bb43d8a0f86a5211485a1e4cb301e3886da941a9..de894a78c27d288fc54028afa002d2beedd9a1cb 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/include/GeometryCreator.h
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/include/GeometryCreator.h
@@ -11,6 +11,11 @@
 #include "Api/PandoraApi.h"
 
 #include "GaudiKernel/ISvcLocator.h"
+#include "DD4hep/Detector.h"
+#include "DD4hep/DD4hepUnits.h"
+#include "DDRec/DetectorData.h"
+#include "DD4hep/DetType.h"
+#include "DD4hep/DetectorSelector.h"
 namespace gear { class CalorimeterParameters; class GearMgr; }
 
 //------------------------------------------------------------------------------------------------------------------------------------------
@@ -53,6 +58,7 @@ public:
         float           m_hCalRingInnerPhiCoordinate;           ///< HCal ring inner phi coordinate (missing from ILD gear files)
         int             m_hCalRingOuterSymmetryOrder;           ///< HCal ring outer symmetry order (missing from ILD gear files)
         float           m_hCalRingOuterPhiCoordinate;           ///< HCal ring outer phi coordinate (missing from ILD gear files)
+        bool            m_use_dd4hep_geo;           ///true to use dd4hep geo info
     };
 
     /**
@@ -102,6 +108,8 @@ private:
     void SetDefaultSubDetectorParameters(const gear::CalorimeterParameters &inputParameters, const std::string &subDetectorName,
         const pandora::SubDetectorType subDetectorType, PandoraApi::Geometry::SubDetector::Parameters &parameters) const;
 
+    void SetDefaultSubDetectorParameters(const dd4hep::rec::LayeredCalorimeterData &inputParameters, const std::string &subDetectorName,
+    const pandora::SubDetectorType subDetectorType, PandoraApi::Geometry::SubDetector::Parameters &parameters) const;
     /**
      *  @brief  Set positions of gaps in ILD detector and add information missing from GEAR parameters file
      * 
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/include/PandoraPFAlg.h b/Reconstruction/PFA/Pandora/GaudiPandora/include/PandoraPFAlg.h
index 8188fb965dab87b4a2cdefcae3be7c24d7bccea2..c3c2599e7d518082db1d1981f388341bef069e26 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/include/PandoraPFAlg.h
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/include/PandoraPFAlg.h
@@ -273,6 +273,9 @@ protected:
   std::vector<float> m_mc_charge;
   int m_hasConversion;
 
+  Gaudi::Property<bool> m_use_dd4hep_geo{this, "use_dd4hep_geo", false,"choose if use geo info from dd4hep"};
+  Gaudi::Property<bool> m_use_dd4hep_decoder {this, "use_dd4hep_decoder", true,"if use decoder from dd4hep"};
+  Gaudi::Property<bool> m_use_preshower {this, "use_preshower", false,"if use preshower layer for calorimeter"};
   Gaudi::Property< std::string >              m_AnaOutput{ this, "AnaOutput", "/junofs/users/wxfang/MyGit/CEPCSW/Reconstruction/PFA/Pandora/GaudiPandora/Ana.root" };
   //######################
   std::map< std::string, std::string > m_collections;
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/include/TrackCreator.h b/Reconstruction/PFA/Pandora/GaudiPandora/include/TrackCreator.h
index 134ff85bc5f08b7643155624e4e82910e7cbdce7..2b2c4011d2b24434816cd6bc94050dd540864a5e 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/include/TrackCreator.h
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/include/TrackCreator.h
@@ -104,6 +104,7 @@ public:
         float           m_maxTpcInnerRDistance;                 ///< Track cut on distance from tpc inner r to id whether track can form pfo
         float           m_minTpcHitFractionOfExpected;          ///< Minimum fraction of TPC hits compared to expected
         int             m_minFtdHitsForTpcHitFraction;          ///< Minimum number of FTD hits to ignore TPC hit fraction
+        bool            m_use_dd4hep_geo;          ///
     };
 
     /**
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/include/Utility.h b/Reconstruction/PFA/Pandora/GaudiPandora/include/Utility.h
index 0bd75b5d94f4725581e44176a02fbb94a99088fa..07ae48091b2be4ea02d2bd79b547afdf9f3f0912 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/include/Utility.h
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/include/Utility.h
@@ -2,5 +2,17 @@
 #define MYUTILITY 1
 
 #include <sstream>
+#include "DD4hep/Detector.h"
+#include "DD4hep/DD4hepUnits.h"
+#include "DD4hep/DetType.h"
+#include "DDRec/DetectorData.h"
+#include "DD4hep/DetectorSelector.h"
 std::string Convert (float number);
+dd4hep::rec::LayeredCalorimeterData * getExtension(unsigned int includeFlag, unsigned int excludeFlag) ;
+void line_a_b(float x1, float y1, float x2, float y2, float& a, float& b);
+float getPhi(float x, float y);
+int partition(float x, float y);
+int getLayer(float x, float y, float z, std::vector<float>& layers);
+int getLayer_v1(float x, float y, float z, std::vector<float>& layers);
+int getStave(float x, float y);
 #endif
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/src/CaloHitCreator.cpp b/Reconstruction/PFA/Pandora/GaudiPandora/src/CaloHitCreator.cpp
index e1c24b1e182b76ab503e007a0ec2d402424fe117..02009a5bdc83e9930e4f7b3642ddcdded49b300b 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/src/CaloHitCreator.cpp
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/src/CaloHitCreator.cpp
@@ -49,14 +49,25 @@ CaloHitCreator::CaloHitCreator(const Settings &settings, const pandora::Pandora
         throw "Failed to find GearSvc ...";
     }
     _GEAR = iSvc->getGearMgr();
+    if(m_settings.m_use_dd4hep_geo){
+        sc = svcloc->service("GeomSvc", m_geosvc, false);
+        if (!sc) throw "Failed to find GeomSvc.";
+        const dd4hep::rec::LayeredCalorimeterData * eCalBarrelExtension= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::BARREL),
+										     ( dd4hep::DetType::AUXILIARY  |  dd4hep::DetType::FORWARD ) );
+        m_eCalBarrelOuterZ        = eCalBarrelExtension->extent[3]/dd4hep::mm;
+        m_eCalBarrelInnerPhi0     = eCalBarrelExtension->inner_phi0/dd4hep::rad;
+        m_eCalBarrelInnerSymmetry = eCalBarrelExtension->inner_symmetry;
+    }
+    else{
+        m_eCalBarrelOuterZ        = (_GEAR->getEcalBarrelParameters().getExtent()[3]);
+        m_eCalBarrelInnerPhi0     = (_GEAR->getEcalBarrelParameters().getPhi0());
+        m_eCalBarrelInnerSymmetry = (_GEAR->getEcalBarrelParameters().getSymmetryOrder());
+    }
 
 
-    m_eCalBarrelOuterZ        = (_GEAR->getEcalBarrelParameters().getExtent()[3]);
     m_hCalBarrelOuterZ        = (_GEAR->getHcalBarrelParameters().getExtent()[3]);
     m_muonBarrelOuterZ        = (_GEAR->getYokeBarrelParameters().getExtent()[3]);
     m_coilOuterR              = (_GEAR->getGearParameters("CoilParameters").getDoubleVal("Coil_cryostat_outer_radius"));
-    m_eCalBarrelInnerPhi0     = (_GEAR->getEcalBarrelParameters().getPhi0());
-    m_eCalBarrelInnerSymmetry = (_GEAR->getEcalBarrelParameters().getSymmetryOrder());
     m_hCalBarrelInnerPhi0     = (_GEAR->getHcalBarrelParameters().getPhi0());
     m_hCalBarrelInnerSymmetry = (_GEAR->getHcalBarrelParameters().getSymmetryOrder());
     m_muonBarrelInnerPhi0     = (_GEAR->getYokeBarrelParameters().getPhi0());
@@ -129,6 +140,12 @@ pandora::StatusCode CaloHitCreator::CreateECalCaloHits(const CollectionMaps& col
             const std::string layerCodingString(m_encoder_str);
             const std::string layerCoding(this->GetLayerCoding(layerCodingString));
             const std::string staveCoding(this->GetStaveCoding(layerCodingString));
+            // get the DD4hep readout
+            const std::string name_readout = "EcalBarrelCollection";
+            if(m_settings.m_use_dd4hep_geo && m_settings.m_use_dd4hep_decoder ){
+                m_decoder = m_geosvc->getDecoder(name_readout);
+                if (!m_decoder) throw "Failed to get the decoder. ";
+            }
 
             for (int i = 0; i < nElements; ++i)
             {
@@ -173,7 +190,19 @@ pandora::StatusCode CaloHitCreator::CreateECalCaloHits(const CollectionMaps& col
                     PandoraApi::CaloHit::Parameters caloHitParameters;
                     caloHitParameters.m_hitType = pandora::ECAL;
                     caloHitParameters.m_isDigital = false;
-                    caloHitParameters.m_layer = cellIdDecoder(pCaloHit)[layerCoding.c_str()] + 1;
+                    caloHitParameters.m_layer = m_settings.m_use_dd4hep_decoder == false ? cellIdDecoder(pCaloHit)[layerCoding.c_str()] + 1 : m_decoder->get(pCaloHit->getCellID(), "layer");// from 0 to 29, 0 is preshower layer
+                    int Stave = 0 ; 
+                    if (m_settings.m_use_dd4hep_decoder == false){
+                        Stave = cellIdDecoder(pCaloHit)[ staveCoding];
+                    }
+                    else{
+                        Stave = m_decoder->get(pCaloHit->getCellID(), "stave");
+                        Stave = Stave <=2 ? Stave+5 : Stave-3 ;//change to correct style
+                    }
+                    //std::cout<<"0Stave="<<Stave<<",0layer="<<caloHitParameters.m_layer.Get()<<std::endl;
+                    if (Stave<0) throw "wrong Stave";
+                    if (m_settings.m_use_preshower==false && caloHitParameters.m_layer.Get()<1) continue;//don't use preshower layer 
+                    //std::cout<<"Stave="<<Stave<<",layer="<<caloHitParameters.m_layer.Get()<<std::endl;
                     caloHitParameters.m_isInOuterSamplingLayer = false;
                     this->GetCommonCaloHitProperties(pCaloHit, caloHitParameters);
 
@@ -181,14 +210,27 @@ pandora::StatusCode CaloHitCreator::CreateECalCaloHits(const CollectionMaps& col
 
                     if (std::fabs(pCaloHit->getPosition()[2]) < m_eCalBarrelOuterZ)
                     {
-                        this->GetBarrelCaloHitProperties(pCaloHit, barrelLayerLayout, m_eCalBarrelInnerSymmetry, m_eCalBarrelInnerPhi0,
-                            cellIdDecoder(pCaloHit)[ staveCoding], caloHitParameters, absorberCorrection);
+                        if(m_settings.m_use_dd4hep_geo){
+                            const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer>& barrelLayers= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::BARREL), ( dd4hep::DetType::AUXILIARY  |  dd4hep::DetType::FORWARD ) )->layers;
+                            this->GetBarrelCaloHitProperties(pCaloHit, barrelLayers, m_eCalBarrelInnerSymmetry, m_eCalBarrelInnerPhi0,
+                            Stave, caloHitParameters, absorberCorrection);
+                        }
+                        else{
+                            this->GetBarrelCaloHitProperties(pCaloHit, barrelLayerLayout, m_eCalBarrelInnerSymmetry, m_eCalBarrelInnerPhi0,
+                            Stave, caloHitParameters, absorberCorrection);
+                        }
 
                         caloHitParameters.m_hadronicEnergy = eCalToHadGeVBarrel * pCaloHit->getEnergy();
                     }
                     else
                     {
-                        this->GetEndCapCaloHitProperties(pCaloHit, endcapLayerLayout, caloHitParameters, absorberCorrection);
+                        if(m_settings.m_use_dd4hep_geo){
+                            const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer>& endcapLayers= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::ENDCAP), ( dd4hep::DetType::AUXILIARY  |  dd4hep::DetType::FORWARD ) )->layers;
+                            this->GetEndCapCaloHitProperties(pCaloHit, endcapLayers, caloHitParameters, absorberCorrection);
+                        }
+                        else{
+                            this->GetEndCapCaloHitProperties(pCaloHit, endcapLayerLayout, caloHitParameters, absorberCorrection);
+                        }
                         caloHitParameters.m_hadronicEnergy = eCalToHadGeVEndCap * pCaloHit->getEnergy();
                     }
 
@@ -623,6 +665,57 @@ void CaloHitCreator::GetEndCapCaloHitProperties(const edm4hep::CalorimeterHit *c
         pandora::CartesianVector(0, 0, -1);
 }
 
+//------------------------------------------------------------------------------------------------------------------------------------------
+void CaloHitCreator::GetEndCapCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer> &layers,
+    PandoraApi::CaloHit::Parameters &caloHitParameters, float &absorberCorrection) const
+{
+    caloHitParameters.m_hitRegion = pandora::ENDCAP;
+
+    const int physicalLayer(std::min(static_cast<int>(caloHitParameters.m_layer.Get()), static_cast<int>(layers.size()-1)));
+    caloHitParameters.m_cellSize0 = layers[physicalLayer].cellSize0/dd4hep::mm;
+    caloHitParameters.m_cellSize1 = layers[physicalLayer].cellSize1/dd4hep::mm;
+    //std::cout<<"Endcap m_cellSize0="<<caloHitParameters.m_cellSize0.Get()<<",m_cellSize1="<<caloHitParameters.m_cellSize1.Get()<<std::endl;
+    double thickness = (layers[physicalLayer].inner_thickness+layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm;
+    double nRadLengths = layers[physicalLayer].inner_nRadiationLengths;
+    double nIntLengths = layers[physicalLayer].inner_nInteractionLengths;
+    double layerAbsorberThickness = (layers[physicalLayer].inner_thickness-layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm;
+
+    if(physicalLayer>0){
+        thickness += (layers[physicalLayer-1].outer_thickness -layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm;
+        nRadLengths += layers[physicalLayer-1].outer_nRadiationLengths;
+        nIntLengths += layers[physicalLayer-1].outer_nInteractionLengths;
+        layerAbsorberThickness += (layers[physicalLayer-1].outer_thickness -layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm;
+
+    }
+    caloHitParameters.m_cellThickness = thickness;
+    caloHitParameters.m_nCellRadiationLengths = nRadLengths;
+    caloHitParameters.m_nCellInteractionLengths = nIntLengths;
+    if (caloHitParameters.m_nCellRadiationLengths.Get() < std::numeric_limits<float>::epsilon() || caloHitParameters.m_nCellInteractionLengths.Get() < std::numeric_limits<float>::epsilon())
+    {
+        std::cout<<"WARNING CaloHitCreator::GetEndCapCaloHitProperties Calo hit has 0 radiation length or interaction length: \
+            not creating a Pandora calo hit." << std::endl;
+        throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
+    }
+
+    absorberCorrection = 1.;
+    for (unsigned int i = 0, iMax = layers.size(); i < iMax; ++i)
+    {
+        float absorberThickness((layers[i].inner_thickness - layers[i].sensitive_thickness/2.0 )/dd4hep::mm);
+        
+        if (i>0)
+            absorberThickness += (layers[i-1].outer_thickness - layers[i-1].sensitive_thickness/2.0)/dd4hep::mm;
+
+        if (absorberThickness < std::numeric_limits<float>::epsilon())
+            continue;
+
+        if (layerAbsorberThickness > std::numeric_limits<float>::epsilon())
+            absorberCorrection = absorberThickness / layerAbsorberThickness;
+
+        break;
+    }
+    caloHitParameters.m_cellNormalVector = (pCaloHit->getPosition()[2] > 0) ? pandora::CartesianVector(0, 0, 1) :
+        pandora::CartesianVector(0, 0, -1);
+}
 //------------------------------------------------------------------------------------------------------------------------------------------
 
 void CaloHitCreator::GetBarrelCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const gear::LayerLayout &layerLayout,
@@ -688,6 +781,81 @@ void CaloHitCreator::GetBarrelCaloHitProperties(const edm4hep::CalorimeterHit *c
     }
 }
 
+void CaloHitCreator::GetBarrelCaloHitProperties(const edm4hep::CalorimeterHit *const pCaloHit, const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer> &layers,
+    unsigned int barrelSymmetryOrder, float barrelPhi0, unsigned int staveNumber, PandoraApi::CaloHit::Parameters &caloHitParameters,
+    float &absorberCorrection) const
+{
+    caloHitParameters.m_hitRegion = pandora::BARREL;
+    const int physicalLayer(std::min(static_cast<int>(caloHitParameters.m_layer.Get()), static_cast<int>(layers.size()-1)));
+    caloHitParameters.m_cellSize0 = layers[physicalLayer].cellSize0/dd4hep::mm;
+    caloHitParameters.m_cellSize1 = layers[physicalLayer].cellSize1/dd4hep::mm;
+    std::cout<<"DD m_cellSize0="<<caloHitParameters.m_cellSize0.Get()<<",m_cellSize1="<<caloHitParameters.m_cellSize1.Get()<<std::endl;
+    double thickness = (layers[physicalLayer].inner_thickness+layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm;
+    double nRadLengths = layers[physicalLayer].inner_nRadiationLengths;
+    double nIntLengths = layers[physicalLayer].inner_nInteractionLengths;
+
+    double layerAbsorberThickness = (layers[physicalLayer].inner_thickness-layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm;
+    if(physicalLayer>0){
+        thickness += (layers[physicalLayer-1].outer_thickness -layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm;
+        nRadLengths += layers[physicalLayer-1].outer_nRadiationLengths;
+        nIntLengths += layers[physicalLayer-1].outer_nInteractionLengths;
+        layerAbsorberThickness += (layers[physicalLayer-1].outer_thickness -layers[physicalLayer].sensitive_thickness/2.0)/dd4hep::mm;
+    }
+    
+    caloHitParameters.m_cellThickness = thickness;
+    caloHitParameters.m_nCellRadiationLengths = nRadLengths;
+    caloHitParameters.m_nCellInteractionLengths = nIntLengths;
+
+    if (caloHitParameters.m_nCellRadiationLengths.Get() < std::numeric_limits<float>::epsilon() || caloHitParameters.m_nCellInteractionLengths.Get() < std::numeric_limits<float>::epsilon())
+    {
+        std::cout<<"WARNIN CaloHitCreator::GetBarrelCaloHitProperties Calo hit has 0 radiation length or interaction length: \
+            not creating a Pandora calo hit." << std::endl;
+        throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
+    }
+    absorberCorrection = 1.;
+    float absorberThickness_0 = 0; 
+    for (unsigned int i = 0, iMax = layers.size(); i < iMax; ++i)
+    {
+        float absorberThickness((layers[i].inner_thickness - layers[i].sensitive_thickness/2.0 )/dd4hep::mm);
+        
+        if (i>0)
+            absorberThickness += (layers[i-1].outer_thickness - layers[i-1].sensitive_thickness/2.0)/dd4hep::mm;
+
+        if (absorberThickness < std::numeric_limits<float>::epsilon())
+            continue;
+
+        if (layerAbsorberThickness > std::numeric_limits<float>::epsilon())
+            absorberCorrection = absorberThickness / layerAbsorberThickness;
+        absorberThickness_0 = absorberThickness;
+        break;
+    }
+
+
+    //std::cout<<"DD m_cellSize0="<<caloHitParameters.m_cellSize0.Get()<<",m_cellSize1="<<caloHitParameters.m_cellSize1.Get()<<",physicalLayer="<<physicalLayer<<",layerAbsorberThickness="<<layerAbsorberThickness<<",absorberThickness_0="<<absorberThickness_0<<",m_cellThickness="<<caloHitParameters.m_cellThickness.Get()<<",m_nCellRadiationLengths="<<caloHitParameters.m_nCellRadiationLengths.Get()<<",m_nCellInteractionLengths="<<caloHitParameters.m_nCellInteractionLengths.Get()<<",absorberCorrection="<<absorberCorrection<<std::endl;
+
+
+    if (barrelSymmetryOrder > 2)
+    {
+        const float phi = barrelPhi0 + (2. * M_PI * static_cast<float>(staveNumber) / static_cast<float>(barrelSymmetryOrder));
+        caloHitParameters.m_cellNormalVector = pandora::CartesianVector(-std::sin(phi), std::cos(phi), 0);
+    }
+    else
+    {
+        const float pCaloHitPosition[3]={pCaloHit->getPosition()[0], pCaloHit->getPosition()[1], pCaloHit->getPosition()[2]};
+
+        if (pCaloHitPosition[1] != 0)
+        {
+            const float phi = barrelPhi0 + std::atan(pCaloHitPosition[0] / pCaloHitPosition[1]);
+            caloHitParameters.m_cellNormalVector = pandora::CartesianVector(std::sin(phi), std::cos(phi), 0);
+        }
+        else
+        {
+            caloHitParameters.m_cellNormalVector = (pCaloHitPosition[0] > 0) ? pandora::CartesianVector(1, 0, 0) :
+                pandora::CartesianVector(-1, 0, 0);
+        }
+    }
+}
+
 //------------------------------------------------------------------------------------------------------------------------------------------
 
 int CaloHitCreator::GetNLayersFromEdge(const edm4hep::CalorimeterHit *const pCaloHit) const
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/src/GeometryCreator.cpp b/Reconstruction/PFA/Pandora/GaudiPandora/src/GeometryCreator.cpp
index 4c88f7ba826fcf806b9a25f253cf51e06d1a92e2..4c3bcb3673d6c531060de032c9f9b943f12ede30 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/src/GeometryCreator.cpp
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/src/GeometryCreator.cpp
@@ -14,6 +14,7 @@
 #include "gear/PadRowLayout2D.h"
 #include "gear/LayerLayout.h"
 #include "GeometryCreator.h"
+#include "Utility.h"
 
 GeometryCreator::GeometryCreator(const Settings &settings, const pandora::Pandora *const pPandora) :
     m_settings(settings),
@@ -73,9 +74,16 @@ void GeometryCreator::SetMandatorySubDetectorParameters(SubDetectorTypeMap &subD
     std::cout << "Begin SetMandatorySubDetectorParameters:" << std::endl;
     PandoraApi::Geometry::SubDetector::Parameters eCalBarrelParameters, eCalEndCapParameters, hCalBarrelParameters, hCalEndCapParameters,
         muonBarrelParameters, muonEndCapParameters;
+    if(m_settings.m_use_dd4hep_geo){
+        std::cout << "Use dd4hep geo info for ECAL" << std::endl;
+        this->SetDefaultSubDetectorParameters(*const_cast<dd4hep::rec::LayeredCalorimeterData*>(getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::BARREL), ( dd4hep::DetType::AUXILIARY  |  dd4hep::DetType::FORWARD ) )), "ECalBarrel", pandora::ECAL_BARREL, eCalBarrelParameters);
+        this->SetDefaultSubDetectorParameters(*const_cast<dd4hep::rec::LayeredCalorimeterData*>(getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::ENDCAP), ( dd4hep::DetType::AUXILIARY  |  dd4hep::DetType::FORWARD ) )), "ECalEndCap", pandora::ECAL_ENDCAP, eCalEndCapParameters);
+    }
+    else{
+        this->SetDefaultSubDetectorParameters(_GEAR->getEcalBarrelParameters(), "ECalBarrel", pandora::ECAL_BARREL, eCalBarrelParameters);
+        this->SetDefaultSubDetectorParameters(_GEAR->getEcalEndcapParameters(), "ECalEndCap", pandora::ECAL_ENDCAP, eCalEndCapParameters);
+    }
 
-    this->SetDefaultSubDetectorParameters(_GEAR->getEcalBarrelParameters(), "ECalBarrel", pandora::ECAL_BARREL, eCalBarrelParameters);
-    this->SetDefaultSubDetectorParameters(_GEAR->getEcalEndcapParameters(), "ECalEndCap", pandora::ECAL_ENDCAP, eCalEndCapParameters);
     this->SetDefaultSubDetectorParameters(_GEAR->getHcalBarrelParameters(), "HCalBarrel", pandora::HCAL_BARREL, hCalBarrelParameters);
     this->SetDefaultSubDetectorParameters(_GEAR->getHcalEndcapParameters(), "HCalEndCap", pandora::HCAL_ENDCAP, hCalEndCapParameters);
     this->SetDefaultSubDetectorParameters(_GEAR->getYokeBarrelParameters(), "MuonBarrel", pandora::MUON_BARREL, muonBarrelParameters);
@@ -209,6 +217,48 @@ void GeometryCreator::SetDefaultSubDetectorParameters(const gear::CalorimeterPar
     }
 }
 
+void GeometryCreator::SetDefaultSubDetectorParameters(const dd4hep::rec::LayeredCalorimeterData &inputParameters, const std::string &subDetectorName,
+    const pandora::SubDetectorType subDetectorType, PandoraApi::Geometry::SubDetector::Parameters &parameters) const
+{
+  const std::vector<dd4hep::rec::LayeredCalorimeterStruct::Layer>& layers= inputParameters.layers;
+    parameters.m_subDetectorName = subDetectorName;
+    parameters.m_subDetectorType = subDetectorType;
+    parameters.m_innerRCoordinate = inputParameters.extent[0]/dd4hep::mm;
+    parameters.m_innerZCoordinate = inputParameters.extent[2]/dd4hep::mm;
+    parameters.m_innerPhiCoordinate = inputParameters.inner_phi0/dd4hep::rad;
+    parameters.m_innerSymmetryOrder = inputParameters.inner_symmetry;
+    parameters.m_outerRCoordinate = inputParameters.extent[1]/dd4hep::mm;
+    parameters.m_outerZCoordinate = inputParameters.extent[3]/dd4hep::mm;
+    parameters.m_outerPhiCoordinate = inputParameters.outer_phi0/dd4hep::rad;
+    parameters.m_outerSymmetryOrder = inputParameters.outer_symmetry;
+    parameters.m_isMirroredInZ = true;
+    parameters.m_nLayers = layers.size();
+
+    std::cout<<"DD m_subDetectorName="<<subDetectorName<<",m_subDetectorType="<<subDetectorType<<",m_innerRCoordinate="<<parameters.m_innerRCoordinate.Get()<<",m_innerZCoordinate="<<parameters.m_innerZCoordinate.Get()<<",m_innerPhiCoordinate="<<parameters.m_innerPhiCoordinate.Get()<<",m_innerSymmetryOrder="<<parameters.m_innerSymmetryOrder.Get()<<",m_outerRCoordinate="<<parameters.m_outerRCoordinate.Get()<<",m_outerZCoordinate="<<parameters.m_outerZCoordinate.Get()<<",m_outerPhiCoordinate="<<parameters.m_outerPhiCoordinate.Get()<<",m_outerSymmetryOrder="<<parameters.m_outerSymmetryOrder.Get()<<",m_nLayers="<<parameters.m_nLayers.Get()<<std::endl;
+    for (size_t i = 0; i< layers.size(); i++)
+    {
+        const dd4hep::rec::LayeredCalorimeterStruct::Layer & theLayer = layers.at(i);
+        
+        PandoraApi::Geometry::LayerParameters layerParameters;
+        
+        double totalNumberOfRadLengths = theLayer.inner_nRadiationLengths;
+        double totalNumberOfIntLengths = theLayer.inner_nInteractionLengths;
+        
+        if(i>0){
+           //Add the numbers from previous layer's outer side
+           totalNumberOfRadLengths += layers.at(i-1).outer_nRadiationLengths;
+            totalNumberOfIntLengths += layers.at(i-1).outer_nInteractionLengths;
+            
+        }
+        
+        layerParameters.m_closestDistanceToIp = (theLayer.distance+theLayer.inner_thickness)/dd4hep::mm; //Distance to center of sensitive element
+        layerParameters.m_nRadiationLengths = totalNumberOfRadLengths;
+        layerParameters.m_nInteractionLengths = totalNumberOfIntLengths;
+
+        parameters.m_layerParametersVector.push_back(layerParameters);
+        std::cout<<"layer="<<i<<",m_closestDistanceToIp="<<layerParameters.m_closestDistanceToIp.Get()<<",m_nRadiationLengths="<<layerParameters.m_nRadiationLengths.Get()<<",m_nInteractionLengths="<<layerParameters.m_nInteractionLengths.Get()<<",outer_thickness="<<theLayer.outer_thickness<<",inner_thickness="<<theLayer.inner_thickness<<",sensitive_thickness="<<theLayer.sensitive_thickness<<std::endl;
+    }
+}
 //------------------------------------------------------------------------------------------------------------------------------------------
 
 pandora::StatusCode GeometryCreator::SetILDSpecificGeometry(SubDetectorTypeMap &subDetectorTypeMap, SubDetectorNameMap &subDetectorNameMap) const
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/src/PandoraPFAlg.cpp b/Reconstruction/PFA/Pandora/GaudiPandora/src/PandoraPFAlg.cpp
index 14d4ee1a0e82b492706e30bba8cce509823bbbe0..6d458c6064b52536bdf0208c66167e1cdf11c00b 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/src/PandoraPFAlg.cpp
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/src/PandoraPFAlg.cpp
@@ -156,12 +156,16 @@ StatusCode PandoraPFAlg::initialize()
   m_trackCreatorSettings.m_prongVertexCollections = m_ProngVertexCollections;
   m_trackCreatorSettings.m_splitVertexCollections = m_SplitVertexCollections;
   m_trackCreatorSettings.m_v0VertexCollections = m_V0VertexCollections; 
+  m_trackCreatorSettings.m_use_dd4hep_geo      = m_use_dd4hep_geo; 
   
   m_caloHitCreatorSettings.m_eCalCaloHitCollections = m_ECalCaloHitCollections;
   m_caloHitCreatorSettings.m_hCalCaloHitCollections = m_HCalCaloHitCollections;
   m_caloHitCreatorSettings.m_lCalCaloHitCollections = m_LCalCaloHitCollections;
   m_caloHitCreatorSettings.m_lHCalCaloHitCollections = m_LHCalCaloHitCollections;
   m_caloHitCreatorSettings.m_muonCaloHitCollections = m_MuonCaloHitCollections; 
+  m_caloHitCreatorSettings.m_use_dd4hep_geo         = m_use_dd4hep_geo; 
+  m_caloHitCreatorSettings.m_use_dd4hep_decoder     = m_use_dd4hep_decoder ; 
+  m_caloHitCreatorSettings.m_use_preshower          = m_use_preshower  ; 
   m_mcParticleCreatorSettings.m_mcParticleCollections = m_MCParticleCollections;
   m_mcParticleCreatorSettings.m_CaloHitRelationCollections = m_RelCaloHitCollections; 
   m_mcParticleCreatorSettings.m_TrackRelationCollections = m_RelTrackCollections;
@@ -252,6 +256,7 @@ StatusCode PandoraPFAlg::initialize()
   m_geometryCreatorSettings.m_hCalRingInnerPhiCoordinate = m_HCalRingInnerPhiCoordinate;
   m_geometryCreatorSettings.m_hCalRingOuterSymmetryOrder = m_HCalRingOuterSymmetryOrder; 
   m_geometryCreatorSettings.m_hCalRingOuterPhiCoordinate = m_HCalRingOuterPhiCoordinate;
+  m_geometryCreatorSettings.m_use_dd4hep_geo             = m_use_dd4hep_geo;
   
   // For Strip Splitting method and also for hybrid ECAL
   m_caloHitCreatorSettings.m_stripSplittingOn = m_StripSplittingOn;
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/src/TrackCreator.cpp b/Reconstruction/PFA/Pandora/GaudiPandora/src/TrackCreator.cpp
index c3b83199123447b624bbafbe38ec0db9d2561080..c2c0757fd3f9df1c0eb1684d73a07c41a2d3430c 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/src/TrackCreator.cpp
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/src/TrackCreator.cpp
@@ -18,6 +18,13 @@
 #include "gear/FTDParameters.h"
 #include "gear/FTDLayerLayout.h"
 
+#include "DD4hep/Detector.h"
+#include "DD4hep/DD4hepUnits.h"
+#include "DD4hep/DetType.h"
+#include "DDRec/DetectorData.h"
+#include "DD4hep/DetectorSelector.h"
+#include "Utility.h"
+
 #include "GaudiKernel/IService.h"
 #include "GearSvc/IGearSvc.h"
 #include "PandoraPFAlg.h"
@@ -48,11 +55,23 @@ TrackCreator::TrackCreator(const Settings &settings, const pandora::Pandora *con
     m_tpcOuterR               = (_GEAR->getTPCParameters().getPadLayout().getPlaneExtent()[1]);
     m_tpcMaxRow               = (_GEAR->getTPCParameters().getPadLayout().getNRows());
     m_tpcZmax                 = (_GEAR->getTPCParameters().getMaxDriftLength());
-    m_eCalBarrelInnerSymmetry = (_GEAR->getEcalBarrelParameters().getSymmetryOrder());
-    m_eCalBarrelInnerPhi0     = (_GEAR->getEcalBarrelParameters().getPhi0());
-    m_eCalBarrelInnerR        = (_GEAR->getEcalBarrelParameters().getExtent()[0]);
-    m_eCalEndCapInnerZ        = (_GEAR->getEcalEndcapParameters().getExtent()[2]);
     // fg: FTD description in GEAR has changed ...
+    if(m_settings.m_use_dd4hep_geo){
+        const dd4hep::rec::LayeredCalorimeterData * eCalBarrelExtension= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::BARREL),
+            									     ( dd4hep::DetType::AUXILIARY  |  dd4hep::DetType::FORWARD ) );
+        const dd4hep::rec::LayeredCalorimeterData * eCalEndcapExtension= getExtension( ( dd4hep::DetType::CALORIMETER | dd4hep::DetType::ELECTROMAGNETIC | dd4hep::DetType::ENDCAP),
+            									     ( dd4hep::DetType::AUXILIARY |  dd4hep::DetType::FORWARD  ) );
+        m_eCalBarrelInnerPhi0     = eCalBarrelExtension->inner_phi0/dd4hep::rad;
+        m_eCalBarrelInnerSymmetry = eCalBarrelExtension->inner_symmetry;
+        m_eCalBarrelInnerR        = eCalBarrelExtension->extent[0]/dd4hep::mm;
+        m_eCalEndCapInnerZ        = eCalEndcapExtension->extent[2]/dd4hep::mm;
+    }
+    else{
+        m_eCalBarrelInnerSymmetry = (_GEAR->getEcalBarrelParameters().getSymmetryOrder());
+        m_eCalBarrelInnerPhi0     = (_GEAR->getEcalBarrelParameters().getPhi0());
+        m_eCalBarrelInnerR        = (_GEAR->getEcalBarrelParameters().getExtent()[0]);
+        m_eCalEndCapInnerZ        = (_GEAR->getEcalEndcapParameters().getExtent()[2]);
+    }
     try
     {
         m_ftdInnerRadii = _GEAR->getGearParameters("FTD").getDoubleVals("FTDInnerRadius");
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/src/Utility.cpp b/Reconstruction/PFA/Pandora/GaudiPandora/src/Utility.cpp
index 819fa15d4771c80d65e6437d22ebd46120d311de..697681ff616c9f9cbaecaf95a38c52b9e4aeaa0c 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/src/Utility.cpp
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/src/Utility.cpp
@@ -5,3 +5,153 @@ std::string Convert (float number){
     buff<<number;
     return buff.str();   
 }
+dd4hep::rec::LayeredCalorimeterData * getExtension(unsigned int includeFlag, unsigned int excludeFlag=0) {
+  
+  
+  dd4hep::rec::LayeredCalorimeterData * theExtension = 0;
+  
+  dd4hep::Detector & mainDetector = dd4hep::Detector::getInstance();
+  const std::vector< dd4hep::DetElement>& theDetectors = dd4hep::DetectorSelector(mainDetector).detectors(  includeFlag, excludeFlag );
+  
+  
+//  std::cout << " getExtension :  includeFlag: " << dd4hep::DetType( includeFlag ) << " excludeFlag: " << dd4hep::DetType( excludeFlag )
+//                          << "  found : " << theDetectors.size() << "  - first det: " << theDetectors.at(0).name() << std::endl ;
+  
+  if( theDetectors.size()  != 1 ){
+    
+    std::stringstream es ;
+    es << " getExtension: selection is not unique (or empty)  includeFlag: " << dd4hep::DetType( includeFlag ) << " excludeFlag: " << dd4hep::DetType( excludeFlag )
+       << " --- found detectors : " ;
+    for( unsigned i=0, N= theDetectors.size(); i<N ; ++i ){
+      es << theDetectors.at(i).name() << ", " ; 
+    }
+    throw std::runtime_error( es.str() ) ;
+  }
+  
+  theExtension = theDetectors.at(0).extension<dd4hep::rec::LayeredCalorimeterData>();
+  
+  return theExtension;
+}
+
+
+int partition(float x, float y)
+{
+    float a1, b1, a2, b2 ;
+    if (x>1850 && x < 2020){
+        line_a_b(1850, 750  , 2020, 600 , a1, b1);
+        line_a_b(1850, -1000, 2020, -850, a2, b2);
+        if ( (a1*x + b1*y) < 1 && (a2*x+b2*y) < 1 ) return 1 ;
+    }
+    if (y < 1850 && x < 2020){
+        line_a_b(750 , 1850,2020, 600, a1, b1);
+        line_a_b(1000, 1850,2020, 850, a2, b2);
+        if( (a1*x + b1*y) > 1 && (a2*x+b2*y) < 1 ) return 2;
+    }
+    if (y < 2020 && y > 1850){
+        line_a_b( -750, 1850 , -600, 2020 , a1, b1);
+        line_a_b( 1000, 1850 , 850 , 2020 , a2, b2);
+        if( (a1*x + b1*y) < 1 && (a2*x+b2*y) < 1 ) return 3;
+    }
+    if (y < 2020 && x > -1850){
+        line_a_b(  -1850, 750  , -600 , 2020 , a1, b1);
+        line_a_b(  -1850, 1000 , -850 , 2020 , a2, b2);
+        if( (a1*x + b1*y) > 1 && (a2*x+b2*y) < 1 ) return 4;
+    }
+    if (x > -2020 && x < -1850){
+        line_a_b( -1850, -750 ,  -2020, -600 , a1, b1);
+        line_a_b( -1850, 1000 ,  -2020,  850 , a2, b2);
+        if( (a1*x + b1*y) < 1 && (a2*x+b2*y) < 1 ) return 5;
+    }
+    if (x > -2020 && y > -1850){
+        line_a_b( -750 , -1850 , -2020, -600 , a1, b1);
+        line_a_b( -1000, -1850 , -2020, -850 , a2, b2);
+        if( (a1*x + b1*y) > 1 && (a2*x+b2*y) < 1) return 6;
+    }
+    if (y > -2020 && y < -1850){
+        line_a_b(  750 , -1850 ,  600, -2020 , a1, b1);
+        line_a_b( -1000, -1850 , -850, -2020 , a2, b2);
+        if( (a1*x + b1*y) < 1 && (a2*x+b2*y) < 1) return 7;
+    }
+    if (y > -2020 && x < 1850){
+        line_a_b(  1850, -750  ,  600, -2020 , a1, b1);
+        line_a_b(  1850, -1000 ,  850, -2020 , a2, b2);
+        if( (a1*x + b1*y) > 1 && (a2*x+b2*y) < 1) return 8;
+    }
+    return -1;
+}
+
+void line_a_b(float x1, float y1, float x2, float y2, float& a, float& b)
+{
+    a = (y2-y1)/(x1*y2-x2*y1);
+    b = (x1-x2)/(x1*y2-x2*y1);
+}
+
+float getPhi(float x, float y)
+{
+    if     (x==0 && y>0) return 90;
+    else if(x==0 && y<0) return 270;
+    else if(x==0 && y==0) return 0;
+    float phi = atan(y/x)*180/acos(-1);
+    if                 (x<0) phi = phi + 180;
+    else if     (x>0 && y<0) phi = phi + 360;
+    return phi;
+}
+
+int getStave(float x, float y){
+
+int part = partition(x, y);
+int Stave = part>=3 ? (part-2) : (part+6);// correct S is from 1 to 8, S-1 is from 0-7 
+return Stave-1;
+}
+
+int getLayer(float x, float y, float z, std::vector<float>& layers){
+if(abs(z) < 2400){
+    float phi = getPhi(x, y);
+    int part = partition(x, y);
+    float rotated = (part-1)*45;
+    float r = sqrt(x*x + y*y);
+    const float PI = acos(-1);
+    float new_x = r*cos((phi-rotated)*PI/180);
+    float new_y = r*sin((phi-rotated)*PI/180);
+    if(new_x <=layers.at(0)) return 0;
+    if(new_x >=layers.at(layers.size()-1)) return 29;
+    for(unsigned i=0; i<(layers.size()-1); i++){
+        if(new_x >layers.at(i) && new_x <=layers.at(i+1) ) return i+1;
+    }
+}
+else{
+    if(abs(z) <=layers.at(0)) return 0;
+    if(abs(z) >=layers.at(layers.size()-1)) return 29;
+    for(unsigned i=0; i<(layers.size()-1); i++){
+        if(abs(z) >layers.at(i) && abs(z) <=layers.at(i+1) ) return i+1;
+    }
+
+}
+return -1;
+}
+
+int getLayer_v1(float x, float y, float z, std::vector<float>& layers){
+if(abs(z) < 2400){
+    float phi = getPhi(x, y);
+    int part = partition(x, y);
+    float rotated = (part-1)*45;
+    float r = sqrt(x*x + y*y);
+    const float PI = acos(-1);
+    float new_x = r*cos((phi-rotated)*PI/180);
+    float new_y = r*sin((phi-rotated)*PI/180);
+    if(new_x <=layers.at(0)) return 1;
+    if(new_x >=layers.at(layers.size()-1)) return layers.size();
+    for(unsigned i=0; i<(layers.size()-1); i++){
+        if(new_x >layers.at(i) && new_x <=layers.at(i+1) ) return i+2;
+    }
+}
+else{
+    if(abs(z) <=layers.at(0)) return 1;
+    if(abs(z) >=layers.at(layers.size()-1)) return layers.size();
+    for(unsigned i=0; i<(layers.size()-1); i++){
+        if(abs(z) >layers.at(i) && abs(z) <=layers.at(i+1) ) return i+2;
+    }
+
+}
+return -1;
+}