From ef5409ff5d1ef27df114c4e858a77a27db53a2e1 Mon Sep 17 00:00:00 2001
From: Christian Grefe <Christian.Grefe@cern.ch>
Date: Wed, 25 Sep 2013 16:54:49 +0000
Subject: [PATCH] Moved BitField64 to DDSegmentation, which is now stand-alone
 DDCore and other packages now depend on DDSegmentation Segmentation from
 DDCore now holds a DDSegmentation object that is created during XML parsing
 Readout interface extended to act like a full IDDecoder combining information
 from the volume manage and the DDSegmentation object TODO: Segmentation could
 be removed completely, if Readout simply holds a DDSegmentation object TODO:
 Missing DDSegmentation classes for cylinders

---
 CMakeLists.txt                                |  2 +-
 DDCore/CMakeLists.txt                         |  4 +-
 DDCore/include/DD4hep/IDDescriptor.h          | 14 +--
 DDCore/include/DD4hep/Readout.h               | 12 ++-
 DDCore/include/DD4hep/Segmentations.h         | 13 ++-
 DDCore/src/IDDescriptor.cpp                   |  9 +-
 DDCore/src/Readout.cpp                        | 37 +++++++
 DDCore/src/Segementations.cpp                 | 59 ++++-------
 DDCore/src/plugins/Compact2Objects.cpp        | 43 ++++----
 DDG4/src/Geant4TrackerSD.cpp                  |  2 +-
 DDSegmentation/CMakeLists.txt                 |  7 +-
 .../include/DDSegmentation}/BitField64.h      | 15 +--
 .../include/DDSegmentation/CartesianGrid.h    | 34 +++++++
 .../include/DDSegmentation/CartesianGridXY.h  | 99 +++++++++++++++++++
 .../include/DDSegmentation/CartesianGridXYZ.h | 71 +++++++++++++
 .../DDSegmentation/CartesianSegmentation.h    | 29 ------
 .../DDSegmentation/CartesianXYSegmentation.h  | 54 ----------
 .../DDSegmentation/CartesianXYZSegmentation.h | 43 --------
 .../DDSegmentation/CellIDDecoderFactory.h     |  4 +-
 .../include/DDSegmentation/Segmentation.h     | 51 +++++++---
 {DDCore => DDSegmentation}/src/BitField64.cpp |  8 +-
 DDSegmentation/src/CartesianGrid.cpp          | 60 +++++++++++
 DDSegmentation/src/CartesianGridXY.cpp        | 81 +++++++++++++++
 DDSegmentation/src/CartesianGridXYZ.cpp       | 83 ++++++++++++++++
 DDSegmentation/src/CartesianSegmentation.cpp  | 38 -------
 .../src/CartesianXYSegmentation.cpp           | 51 ----------
 .../src/CartesianXYZSegmentation.cpp          | 50 ----------
 DDSegmentation/src/Segmentation.cpp           | 53 +++++++++-
 DDSense/CMakeLists.txt                        |  1 +
 DDSense/src/DDSensitiveManager.cpp            |  4 +-
 UtilityApps/CMakeLists.txt                    |  3 +-
 31 files changed, 663 insertions(+), 371 deletions(-)
 rename {DDCore/include/DD4hep => DDSegmentation/include/DDSegmentation}/BitField64.h (96%)
 create mode 100644 DDSegmentation/include/DDSegmentation/CartesianGrid.h
 create mode 100644 DDSegmentation/include/DDSegmentation/CartesianGridXY.h
 create mode 100644 DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h
 delete mode 100644 DDSegmentation/include/DDSegmentation/CartesianSegmentation.h
 delete mode 100644 DDSegmentation/include/DDSegmentation/CartesianXYSegmentation.h
 delete mode 100644 DDSegmentation/include/DDSegmentation/CartesianXYZSegmentation.h
 rename {DDCore => DDSegmentation}/src/BitField64.cpp (98%)
 create mode 100644 DDSegmentation/src/CartesianGrid.cpp
 create mode 100644 DDSegmentation/src/CartesianGridXY.cpp
 create mode 100644 DDSegmentation/src/CartesianGridXYZ.cpp
 delete mode 100644 DDSegmentation/src/CartesianSegmentation.cpp
 delete mode 100644 DDSegmentation/src/CartesianXYSegmentation.cpp
 delete mode 100644 DDSegmentation/src/CartesianXYZSegmentation.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ea76225cb..c54d5a5b1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -57,8 +57,8 @@ ENDIF()
 
 
 #---Packages------------------------------------------------------------------------
-add_subdirectory(DDCore)
 add_subdirectory(DDSegmentation)
+add_subdirectory(DDCore)
 
 if(DD4HEP_WITH_GEANT4)
   add_subdirectory(DDG4)
diff --git a/DDCore/CMakeLists.txt b/DDCore/CMakeLists.txt
index a650e15cb..a99f7150a 100644
--- a/DDCore/CMakeLists.txt
+++ b/DDCore/CMakeLists.txt
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR)
 
 project(DDCore)
 
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${ROOT_INCLUDE_DIR})
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${ROOT_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/DDSegmentation/include )
 
 
 file(GLOB sources src/*.cpp src/Evaluator/*.cpp src/XML/*.cpp)
@@ -22,7 +22,7 @@ include(DD4hep_XML_setup)
 
 add_library(DD4hepCore SHARED ${sources} )
 
-target_link_libraries(DD4hepCore ${ROOT_LIBRARIES} ${XML_LIBRARIES} Geom Reflex ${libraries})
+target_link_libraries(DD4hepCore ${ROOT_LIBRARIES} ${XML_LIBRARIES} DDSegmentation Geom Reflex ${libraries})
 
 add_library(DD4hepPlugins SHARED ${plugin_sources})
 target_link_libraries(DD4hepPlugins ${ROOT_LIBRARIES} ${XML_LIBRARIES} DD4hepCore Geom Reflex ${libraries})
diff --git a/DDCore/include/DD4hep/IDDescriptor.h b/DDCore/include/DD4hep/IDDescriptor.h
index 78ff5b3d8..6ebb7ee74 100644
--- a/DDCore/include/DD4hep/IDDescriptor.h
+++ b/DDCore/include/DD4hep/IDDescriptor.h
@@ -13,7 +13,7 @@
 // Framework include files
 #include "DD4hep/Handle.h"
 #include "DD4hep/Primitives.h"
-#include "DD4hep/BitField64.h"
+#include "DDSegmentation/BitField64.h"
 
 // C++ include files
 #include <string>
@@ -39,7 +39,7 @@ namespace DD4hep {
     struct IDDescriptor : public Ref_t  {
     public:
       typedef std::pair<std::string,int> VolID;
-      typedef BitFieldValue* Field;
+      typedef DDSegmentation::BitFieldValue* Field;
       typedef std::vector<std::pair<std::string,Field> >  FieldMap;
       typedef std::vector<std::pair<size_t,std::string> > FieldIDs;
       typedef std::pair<Field,VolumeID>                   VolIDField;
@@ -51,7 +51,7 @@ namespace DD4hep {
        *  @version 1.0
        *  @date    2012/07/31
        */
-      struct Object : public TNamed, public BitField64 {
+      struct Object : public TNamed, public DDSegmentation::BitField64 {
 	FieldMap      fieldMap;
 	FieldIDs      fieldIDs;
 	std::string   description;
@@ -60,7 +60,7 @@ namespace DD4hep {
 	/// Default destructor
 	virtual ~Object();
 	/// Access to the field container of the BitField64
-	const std::vector<BitFieldValue*> fields() const  {
+	const std::vector<DDSegmentation::BitFieldValue*> fields() const  {
 	  return _fields;
 	}
       };
@@ -85,12 +85,14 @@ namespace DD4hep {
       size_t fieldID(const std::string& field_name)  const;
       /// Get the field descriptor of one field by its identifier
       Field field(size_t identifier)  const;
-      /// Encoede a set of volume identifiers (corresponding to this description of course!) to a volumeID.
+      /// Encode a set of volume identifiers (corresponding to this description of course!) to a volumeID.
       VolumeID encode(const std::vector<VolID>& ids)  const;
       /// Decode volume IDs and return filled descriptor with all fields
       void decodeFields(VolumeID vid, VolIDFields& fields);
-      /// Acces string representation
+      /// Access string representation
       std::string toString() const;
+      /// Access the BitField64 object
+      DDSegmentation::BitField64* decoder();
     };
   }       /* End namespace Geometry    */
 }         /* End namespace DD4hep      */
diff --git a/DDCore/include/DD4hep/Readout.h b/DDCore/include/DD4hep/Readout.h
index 2321408ad..e8c7d1da1 100644
--- a/DDCore/include/DD4hep/Readout.h
+++ b/DDCore/include/DD4hep/Readout.h
@@ -26,6 +26,8 @@ namespace DD4hep {
    */
   namespace Geometry  {
 
+  class DetElement;
+
     /** @class Readout  Readout.h DD4hep/Readout.h
       *
       * @author  M.Frank
@@ -43,7 +45,7 @@ namespace DD4hep {
 	/// Handle to the readout segmentation
         Segmentation segmentation;
 	/// Handle to the volume
-	Volume       readoutWorld;
+        Volume readoutWorld;
 	/// Handle to the field descriptor
         IDDescriptor id;
 	/// Standard constructor
@@ -66,6 +68,14 @@ namespace DD4hep {
       void setSegmentation(const Segmentation& segment) const;
       /// Access segmentation structure
       Segmentation segmentation()  const;
+
+      /// ID decoder interface
+      PlacedVolume getPlacement(const long64& cellID) const;
+      DetElement getSubDetector(const long64& cellID) const;
+      DetElement getDetectorElement(const long64& cellID) const;
+      Position getPosition(const long64& cellID) const;
+      Position getLocalPosition(const long64& cellID) const;
+      const TGeoMatrix& getWorldTransformation(const long64& cellID) const;
     };
 
     /** @class Alignment  Readoutn.h DD4hep/lcdd/Readout.h
diff --git a/DDCore/include/DD4hep/Segmentations.h b/DDCore/include/DD4hep/Segmentations.h
index 6ad3dc724..2af67d584 100644
--- a/DDCore/include/DD4hep/Segmentations.h
+++ b/DDCore/include/DD4hep/Segmentations.h
@@ -11,6 +11,9 @@
 
 // Framework include files
 #include "DD4hep/Handle.h"
+#include "DD4hep/IDDescriptor.h"
+
+#include "DDSegmentation/Segmentation.h"
 
 // C/C++ include files
 #include <cmath>
@@ -49,11 +52,13 @@ namespace DD4hep {
         unsigned char useForHitPosition;
         /// Spares to start 16 byte Byte aligned
         unsigned char _spare[6];
+        /// The segmentation object
+        DDSegmentation::Segmentation* segmentation;
         
         union Data {
-          /// Maximal size and data buffer for specialized user segentations
+          /// Maximal size and data buffer for specialized user segmentations
           double values[32];
-          /// Extension buffer for specialized user segentations, where above values are insufficient
+          /// Extension buffer for specialized user segmentations, where above values are insufficient
           struct Extension {
             const std::type_info* info;
             void (*destructor)(void*);
@@ -108,6 +113,10 @@ namespace DD4hep {
       bool useForHitPosition() const;
       /// Segmentation type
       const std::string type() const;
+      /// Assign segmentation object
+      void setSegmentation(DDSegmentation::Segmentation* segmentation);
+      /// Access segmentation object
+      DDSegmentation::Segmentation* segmentation();
       /// Extend the segmentation object with an arbitrary structure accessible by the type
       template<typename IFACE, typename CONCRETE> IFACE* setExtension(CONCRETE* c)
       {  return (IFACE*)i_setExtension(dynamic_cast<IFACE*>(c),typeid(IFACE),_delete<IFACE>);   }
diff --git a/DDCore/src/IDDescriptor.cpp b/DDCore/src/IDDescriptor.cpp
index a7ae2d2e3..6ad1307eb 100644
--- a/DDCore/src/IDDescriptor.cpp
+++ b/DDCore/src/IDDescriptor.cpp
@@ -15,6 +15,8 @@
 using namespace std;
 using namespace DD4hep;
 using namespace DD4hep::Geometry;
+using DDSegmentation::BitField64;
+using DDSegmentation::BitFieldValue;
 
 
 namespace  {
@@ -104,7 +106,7 @@ size_t IDDescriptor::fieldID(const string& field_name)  const   {
   throw runtime_error("DD4hep: "+string(name())+": This ID descriptor has no field with the name:"+field_name);
 }
 
-/// Encoede a set of volume identifiers (corresponding to this description of course!) to a volumeID.
+/// Encode a set of volume identifiers (corresponding to this description of course!) to a volumeID.
 VolumeID IDDescriptor::encode(const std::vector<VolID>& ids)  const   {
   typedef std::vector<VolID> VolIds;
   VolumeID id = 0;
@@ -126,3 +128,8 @@ void IDDescriptor::decodeFields(VolumeID vid, VolIDFields& fields)   {
   }
   throw runtime_error("DD4hep: Attempt to access an invalid IDDescriptor object.");
 }
+
+/// Access the BitField64 object
+BitField64* IDDescriptor::decoder() {
+	return data<Object>();
+}
diff --git a/DDCore/src/Readout.cpp b/DDCore/src/Readout.cpp
index b0945f9ff..e66580aa3 100644
--- a/DDCore/src/Readout.cpp
+++ b/DDCore/src/Readout.cpp
@@ -9,9 +9,13 @@
 
 #include "DD4hep/Readout.h"
 #include "DD4hep/InstanceCount.h"
+#include "DD4hep/TGeoUnits.h"
+#include "DD4hep/LCDD.h"
 
 using namespace std;
+using namespace DD4hep;
 using namespace DD4hep::Geometry;
+using tgeo::mm;
 
 /// Standard constructor
 Readout::Object::Object()  {
@@ -35,6 +39,11 @@ void Readout::setIDDescriptor(const Ref_t& new_descriptor)  const   {
   if ( isValid() )  {                    // Remember: segmentation is NOT owned by readout structure!
     if ( new_descriptor.isValid() )  {   // Do NOT delete!
       data<Object>()->id = new_descriptor;
+      Segmentation seg = data<Object>()->segmentation;
+      IDDescriptor id = new_descriptor;
+      if (seg.isValid()) {
+    	  seg.segmentation()->setDecoder(id.decoder());
+      }
       return;
     }
   }
@@ -67,6 +76,34 @@ Segmentation Readout::segmentation() const  {
   return object<Object>().segmentation;
 }
 
+/// full ID decoder interface
+PlacedVolume Readout::getPlacement(const long64& cellID) const {
+	VolumeManager volMan = LCDD::getInstance().volumeManager();
+	return volMan.lookupPlacement(cellID);
+}
+DetElement Readout::getSubDetector(const long64& cellID) const{
+	VolumeManager volMan = LCDD::getInstance().volumeManager();
+	return volMan.lookupDetector(cellID);
+}
+DetElement Readout::getDetectorElement(const long64& cellID) const {
+	VolumeManager volMan = LCDD::getInstance().volumeManager();
+	return volMan.lookupDetElement(cellID);
+}
+Position Readout::getPosition(const long64& cellID) const {
+	double global[3] = {0., 0., 0.};
+	VolumeManager volMan = LCDD::getInstance().volumeManager();
+	volMan.worldTransformation(cellID).LocalToMaster(&(segmentation().segmentation()->getLocalPosition(cellID))[0], global);
+	return Position(global[0]/tgeo::mm, global[1]/tgeo::mm, global[2]/tgeo::mm);
+}
+Position Readout::getLocalPosition(const long64& cellID) const {
+	std::vector<double> v = segmentation().segmentation()->getLocalPosition(cellID);
+	return Position(v[0], v[1], v[2]);
+}
+const TGeoMatrix& Readout::getWorldTransformation(const long64& cellID) const {
+	VolumeManager volMan = LCDD::getInstance().volumeManager();
+	return volMan.worldTransformation(cellID);
+}
+
 /// Standard constructor
 Alignment::Object::Object()  {
   InstanceCount::increment(this);
diff --git a/DDCore/src/Segementations.cpp b/DDCore/src/Segementations.cpp
index fed771b03..317efd6b0 100644
--- a/DDCore/src/Segementations.cpp
+++ b/DDCore/src/Segementations.cpp
@@ -18,6 +18,7 @@ using namespace DD4hep::Geometry;
 Segmentation::Object::Object() 
 : magic(magic_word()), type(REGULAR), useForHitPosition(0) 
 {
+  segmentation = 0;
   InstanceCount::increment(this);
   ::memset(data.values,0,sizeof(data.values));
   _spare[5]=_spare[4]=_spare[3]=_spare[2]=_spare[1]=_spare[0]=0;
@@ -33,6 +34,9 @@ Segmentation::Object::~Object() {
       data.extension.ptr = 0;
     }
   }
+  if (segmentation != 0) {
+	  delete segmentation;
+  }
   InstanceCount::decrement(this);
 }
 
@@ -46,7 +50,20 @@ bool Segmentation::useForHitPosition() const   {
 
 /// Segmentation type
 const string Segmentation::type() const   {
-  return m_element->GetTitle();
+  return object<Object>().segmentation->type();
+}
+
+/// Assign segmentation object
+void Segmentation::setSegmentation(DD4hep::DDSegmentation::Segmentation* segmentation) {
+	Object& o = object<Object>();
+	if (o.segmentation != 0) {
+		delete o.segmentation;
+	}
+	o.segmentation = segmentation;
+}
+/// Access segmentation object
+DD4hep::DDSegmentation::Segmentation* Segmentation::segmentation() {
+	return object<Object>().segmentation;
 }
 
 /// Add an extension object to the detector element
@@ -83,45 +100,7 @@ const string SegmentationParams::type() const   {
 
 /// Access to the parameters
 SegmentationParams::Parameters SegmentationParams::parameters() const  {
-  const string& typ = type();
-  const Object& obj = object<Object>();
-  const Object::Data& data = obj.data;
-  Parameters params;
-  //cout << "Segmentation:" << name() << " Type:" << typ << endl;
-  if ( typ == "projective_cylinder" )  {
-    params.push_back(make_pair("ntheta",data.cylindrical_binning.ntheta));
-    params.push_back(make_pair("nphi",data.cylindrical_binning.nphi));
-  }
-  else if ( typ == "nonprojective_cylinder" )  {
-    params.push_back(make_pair("grid_size_z",data.cylindrical_grid.grid_size_phi));
-    params.push_back(make_pair("grid_size_phi",data.cylindrical_grid.grid_size_phi));
-    params.push_back(make_pair("lunit",_toDouble("mm")));
-  }
-  else if ( typ == "projective_zplane" )  {
-    params.push_back(make_pair("ntheta",data.cylindrical_binning.ntheta));
-    params.push_back(make_pair("nphi",data.cylindrical_binning.nphi));
-  }
-  else if ( typ == "grid_xy"            ||
-	    typ == "cartesian_grid_xy"  ||
-            typ == "global_grid_xy"     
-	    )    {
-    params.push_back(make_pair("grid_size_x",data.cartesian_grid.grid_size_x));
-    params.push_back(make_pair("grid_size_y",data.cartesian_grid.grid_size_y));
-    params.push_back(make_pair("lunit",_toDouble("mm")));
-  }
-  else if ( typ == "grid_xyz"           || 
-	    typ == "cartesian_grid_xyz" ||
-	    typ == "global_grid_xyz"    
-	    )    {
-    params.push_back(make_pair("grid_size_x",data.cartesian_grid.grid_size_x));
-    params.push_back(make_pair("grid_size_y",data.cartesian_grid.grid_size_y));
-    params.push_back(make_pair("grid_size_z",data.cartesian_grid.grid_size_z));
-    params.push_back(make_pair("lunit",_toDouble("mm")));
-  }
-  else   {
-    throw runtime_error("DD4hep: The segmentation type "+typ+" is not supported by DD4hep.");
-  }
-  return params;
+  return object<Object>().segmentation->parameters();
 }
 
 ProjectiveCylinder::ProjectiveCylinder() : Segmentation("projective_cylinder")   
diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp
index dee18c47b..a2ab5752b 100644
--- a/DDCore/src/plugins/Compact2Objects.cpp
+++ b/DDCore/src/plugins/Compact2Objects.cpp
@@ -16,6 +16,9 @@
 #include "XML/DocumentHandler.h"
 #include "XML/Conversions.h"
 
+#include "DDSegmentation/CartesianGridXY.h"
+#include "DDSegmentation/CartesianGridXYZ.h"
+
 // Root/TGeo include files
 #include "TGeoManager.h"
 #include "TGeoMaterial.h"
@@ -67,39 +70,44 @@ namespace {
 
 static Ref_t create_GridXYZ(lcdd_t& /* lcdd */, xml_h e)  {
   GridXYZ obj;
-  if ( e.hasAttr(_U(gridSizeX)) ) obj.setGridSizeX(e.attr<float>(_U(gridSizeX)));
-  if ( e.hasAttr(_U(gridSizeY)) ) obj.setGridSizeY(e.attr<float>(_U(gridSizeY)));
-  if ( e.hasAttr(_U(gridSizeZ)) ) obj.setGridSizeZ(e.attr<float>(_U(gridSizeZ)));
+  DDSegmentation::CartesianGridXYZ* seg = new DDSegmentation::CartesianGridXYZ("");
+  obj.setSegmentation(seg);
+  if ( e.hasAttr(_U(gridSizeX)) ) seg->setGridSizeX(e.attr<float>(_U(gridSizeX)));
+  if ( e.hasAttr(_U(gridSizeY)) ) seg->setGridSizeY(e.attr<float>(_U(gridSizeY)));
+  if ( e.hasAttr(_U(gridSizeZ)) ) seg->setGridSizeZ(e.attr<float>(_U(gridSizeZ)));
   return obj;
 }
 DECLARE_XMLELEMENT(GridXYZ,create_GridXYZ);
 
-namespace DD4hep { namespace Geometry { typedef GridXYZ RegularNgonCartesianGridXY; }}
-DECLARE_XMLELEMENT(RegularNgonCartesianGridXY,create_GridXYZ);
-
 static Ref_t create_GlobalGridXY(lcdd_t& /* lcdd */, xml_h e)  {
   GlobalGridXY obj;
-  if ( e.hasAttr(_U(gridSizeX)) ) obj.setGridSizeX(e.attr<float>(_U(gridSizeX)));
-  if ( e.hasAttr(_U(gridSizeY)) ) obj.setGridSizeY(e.attr<float>(_U(gridSizeY)));
+  DDSegmentation::CartesianGridXY* seg = new DDSegmentation::CartesianGridXY("");
+    obj.setSegmentation(seg);
+  if ( e.hasAttr(_U(gridSizeX)) ) seg->setGridSizeX(e.attr<float>(_U(gridSizeX)));
+  if ( e.hasAttr(_U(gridSizeY)) ) seg->setGridSizeY(e.attr<float>(_U(gridSizeY)));
   return obj;
 }
 DECLARE_XMLELEMENT(GlobalGridXY,create_GlobalGridXY);
 
 static Ref_t create_CartesianGridXY(lcdd_t& /* lcdd */, xml_h e)  {
   CartesianGridXY obj;
-  if ( e.hasAttr(_U(gridSizeX)) ) obj.setGridSizeX(e.attr<double>(_U(gridSizeX)));
-  if ( e.hasAttr(_U(gridSizeY)) ) obj.setGridSizeY(e.attr<double>(_U(gridSizeY)));
+  DDSegmentation::CartesianGridXY* seg = new DDSegmentation::CartesianGridXY("");
+  obj.setSegmentation(seg);
+  if ( e.hasAttr(_U(gridSizeX)) ) seg->setGridSizeX(e.attr<double>(_U(gridSizeX)));
+  if ( e.hasAttr(_U(gridSizeY)) ) seg->setGridSizeY(e.attr<double>(_U(gridSizeY)));
   return obj;
 }
-
 DECLARE_XMLELEMENT(CartesianGridXY,create_CartesianGridXY);
 
+namespace DD4hep { namespace Geometry { typedef CartesianGridXY RegularNgonCartesianGridXY; }}
+DECLARE_XMLELEMENT(RegularNgonCartesianGridXY,create_CartesianGridXY);
+
 namespace DD4hep { namespace Geometry { 
-    typedef GridXYZ CartesianGridXYZ; 
-    typedef GridXYZ EcalBarrelCartesianGridXY; 
+    typedef GridXYZ CartesianGridXYZ;
+    typedef CartesianGridXY EcalBarrelCartesianGridXY;
 }}
-DECLARE_XMLELEMENT(CartesianGridXYZ,create_GridXYZ);
-DECLARE_XMLELEMENT(EcalBarrelCartesianGridXY,create_GridXYZ);
+DECLARE_XMLELEMENT(CartesianGridXYZ,create_CartesianGridXY);
+DECLARE_XMLELEMENT(EcalBarrelCartesianGridXY,create_CartesianGridXY);
   
 static Ref_t create_ProjectiveCylinder(lcdd_t& /* lcdd */, xml_h e)  {
   ProjectiveCylinder obj;
@@ -465,6 +473,7 @@ template <> void Converter<Readout>::operator()(xml_h e)  const {
   xml_h   seg  = e.child(_U(segmentation),false);
   string  name = e.attr<string>(_U(name));
   Readout ro(name);
+  Ref_t idSpec;
 
   if ( seg )  { // Segmentation is not mandatory!
     string type = seg.attr<string>(_U(type));
@@ -477,8 +486,8 @@ template <> void Converter<Readout>::operator()(xml_h e)  const {
     ro.setSegmentation(segment);
   }
   if ( id )  {
-    //  <id>system:6,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id> 
-    Ref_t idSpec = IDDescriptor(id.text());
+    //  <id>system:6,barrel:3,module:4,layer:8,slice:5,x:32:-16,y:-16</id>
+    idSpec = IDDescriptor(id.text());
     idSpec->SetName(ro.name());
     ro.setIDDescriptor(idSpec);
     lcdd.addIDSpecification(idSpec);
diff --git a/DDG4/src/Geant4TrackerSD.cpp b/DDG4/src/Geant4TrackerSD.cpp
index ca0908c31..a08849808 100644
--- a/DDG4/src/Geant4TrackerSD.cpp
+++ b/DDG4/src/Geant4TrackerSD.cpp
@@ -11,7 +11,7 @@
 #include "DDG4/Factories.h"
 #include "DDG4/Geant4StepHandler.h"
 #include "DDG4/Geant4Mapping.h"
-#include "DD4hep/BitField64.h"
+//#include "DDSegmentation/BitField64.h"
 
 /*
  *   DD4hep::Simulation namespace declaration
diff --git a/DDSegmentation/CMakeLists.txt b/DDSegmentation/CMakeLists.txt
index 4170a5e85..a35084a9c 100644
--- a/DDSegmentation/CMakeLists.txt
+++ b/DDSegmentation/CMakeLists.txt
@@ -1,15 +1,10 @@
 cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR)
 
-include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/include 
-                     ${CMAKE_SOURCE_DIR}/DDCore/include 
-                     ${ROOT_INCLUDE_DIR})
+include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/include )
 
 file(GLOB sources src/*.cpp)
-include(DD4hep_XML_setup)
 
 add_library(DDSegmentation SHARED ${sources})
-target_link_libraries(DDSegmentation DD4hepCore ${ROOT_LIBRARIES})
-#target_link_libraries(DDSegmentation ${DD4hep_LIBRARIES} ${ROOT_LIBRARIES})
 
 SET_TARGET_PROPERTIES( DDSegmentation PROPERTIES VERSION ${DD4hep_VERSION} SOVERSION ${DD4hep_SOVERSION})
 
diff --git a/DDCore/include/DD4hep/BitField64.h b/DDSegmentation/include/DDSegmentation/BitField64.h
similarity index 96%
rename from DDCore/include/DD4hep/BitField64.h
rename to DDSegmentation/include/DDSegmentation/BitField64.h
index 00a8c42a1..0a22af37a 100644
--- a/DDCore/include/DD4hep/BitField64.h
+++ b/DDSegmentation/include/DDSegmentation/BitField64.h
@@ -1,5 +1,5 @@
-#ifndef DD4hep_BitField64_H
-#define DD4hep_BitField64_H 1
+#ifndef DDSegmentation_BitField64_H
+#define DDSegmentation_BitField64_H 1
 
 #include <iostream>
 
@@ -10,11 +10,12 @@
 
 
 namespace DD4hep {
-  
-  //fixme: do  need to do this also for 32 bit machines ?
-  typedef long long64 ;
-  typedef unsigned long ulong64 ;
 
+//fixme: do  need to do this also for 32 bit machines ?
+typedef long long64 ;
+typedef unsigned long ulong64 ;
+
+namespace DDSegmentation {
 
   class BitFieldValue ;
   class StringTokenizer ; 
@@ -285,6 +286,8 @@ namespace DD4hep {
   }
 
 
+} // end namespace
+
 } // end namespace
 
 #endif
diff --git a/DDSegmentation/include/DDSegmentation/CartesianGrid.h b/DDSegmentation/include/DDSegmentation/CartesianGrid.h
new file mode 100644
index 000000000..1a3a13212
--- /dev/null
+++ b/DDSegmentation/include/DDSegmentation/CartesianGrid.h
@@ -0,0 +1,34 @@
+/*
+ * CartesianGrid.h
+ *
+ *  Created on: Jun 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef DDSegmentation_CARTESIANGRID_H_
+#define DDSegmentation_CARTESIANGRID_H_
+
+#include "DDSegmentation/Segmentation.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+class CartesianGrid: public Segmentation {
+public:
+	/// destructor
+	virtual ~CartesianGrid();
+protected:
+	/// default constructor using an arbitrary type
+	template <typename TYPE> CartesianGrid(TYPE cellEncoding);
+	/// default constructor using an existing decoder
+	CartesianGrid(BitField64* decoder);
+
+	/// helper method to convert a bin number to a 1D position
+	double binToPosition(long64 bin, double cellSize, double ofset) const;
+	/// helper method to convert a 1D position to a cell ID
+	int positionToBin(double position, double cellSize, double offset) const;
+};
+
+} /* namespace DDSegmentation */
+} /* namespace DD4hep */
+#endif /* DDSegmentation_CARTESIANGRID_H_ */
diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXY.h b/DDSegmentation/include/DDSegmentation/CartesianGridXY.h
new file mode 100644
index 000000000..42e1fd3ef
--- /dev/null
+++ b/DDSegmentation/include/DDSegmentation/CartesianGridXY.h
@@ -0,0 +1,99 @@
+/*
+ * CartesianGridXY.h
+ *
+ *  Created on: Jun 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef DDSegmentation_CARTESIANGRIDXY_H_
+#define DDSegmentation_CARTESIANGRIDXY_H_
+
+#include "DDSegmentation/CartesianGrid.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+class CartesianGridXY: public CartesianGrid {
+public:
+	/// default constructor using an arbitrary type
+	template <typename TYPE> CartesianGridXY(TYPE cellEncoding, double gridSizeX = 1., double gridSizeY = 1., double offsetX = 0.,
+			double offsetY = 0., std::string xField = "x", std::string yField = "y");
+	/// default constructor using an existing decoder
+	CartesianGridXY(BitField64* decoder, double gridSizeX = 1., double gridSizeY = 1., double offsetX = 0.,
+			double offsetY = 0., std::string xField = "x", std::string yField = "y");
+	/// destructor
+	virtual ~CartesianGridXY();
+
+	/// determine the local position based on the cell ID
+	virtual std::vector<double> getLocalPosition(const long64& cellID) const;
+	/// determine the cell ID based on the local position
+	virtual long64 getCellID(double x, double y, double z) const;
+	/// access the grid size in X
+	double getGridSizeX() const {
+		return _gridSizeX;
+	}
+	/// access the grid size in Y
+	double getGridSizeY() const {
+		return _gridSizeY;
+	}
+	/// access the coordinate offset in X
+	double getOffsetX() const {
+		return _offsetX;
+	}
+	/// access the coordinate offset in Y
+	double getOffsetY() const {
+		return _offsetY;
+	}
+	/// access the field name used for X
+	std::string getFieldNameX() const {
+		return _xId;
+	}
+	/// access the field name used for Y
+	std::string getFieldNameY() const {
+		return _yId;
+	}
+	/// set the grid size in X
+	void setGridSizeX(double cellSize) {
+		_gridSizeX = cellSize;
+	}
+	/// set the grid size in Y
+	void setGridSizeY(double cellSize) {
+		_gridSizeY = cellSize;
+	}
+	/// set the coordinate offset in X
+	void setOffsetX(double offset) {
+		_offsetX = offset;
+	}
+	/// set the coordinate offset in Y
+	void setOffsetY(double offset) {
+		_offsetY = offset;
+	}
+	/// set the field name used for X
+	void setFieldNameX(std::string name) {
+		_xId = name;
+	}
+	/// set the field name used for Y
+	void setFieldNameY(std::string name) {
+		_yId = name;
+	}
+	/// access the set of parameters for this segmentation
+	Parameters parameters() const;
+
+protected:
+	/// the grid size in X
+	double _gridSizeX;
+	/// the coordinate offset in X
+	double _offsetX;
+	/// the grid size in Y
+	double _gridSizeY;
+	/// the coordinate offset in Y
+	double _offsetY;
+	/// the field name used for X
+	std::string _xId;
+	/// the field name used for Y
+	std::string _yId;
+};
+
+} /* namespace DDSegmentation */
+} /* namespace DD4hep */
+#endif /* DDSegmentation_CARTESIANGRIDXY_H_ */
diff --git a/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h b/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h
new file mode 100644
index 000000000..8e9a3c2ed
--- /dev/null
+++ b/DDSegmentation/include/DDSegmentation/CartesianGridXYZ.h
@@ -0,0 +1,71 @@
+/*
+ * CartesianGridXYZ.h
+ *
+ *  Created on: Jun 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#ifndef DDSegmentation_CARTESIANGRIDXYZ_H_
+#define DDSegmentation_CARTESIANGRIDXYZ_H_
+
+#include "DDSegmentation/CartesianGridXY.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+class CartesianGridXYZ: public CartesianGridXY {
+public:
+	/// default constructor using an arbitrary type
+	template <typename TYPE> CartesianGridXYZ(TYPE cellEncoding, double gridSizeX = 1., double gridSizeY = 1., double gridSizeZ = 1.,
+			double offsetX = 0., double offsetY = 0., double offsetZ = 0., std::string xField = "x",
+			std::string yField = "y", std::string zField = "z");
+	/// default constructor using an existing decoder
+	CartesianGridXYZ(BitField64* decoder, double gridSizeX = 1., double gridSizeY = 1., double gridSizeZ = 1., double offsetX =
+			0., double offsetY = 0., double offsetZ = 0., std::string xField = "x", std::string yField = "y",
+			std::string zField = "z");
+	/// destructor
+	virtual ~CartesianGridXYZ();
+
+	/// determine the local position based on the cell ID
+	virtual std::vector<double> getLocalPosition(const long64& cellID) const;
+	/// determine the cell ID based on the local position
+	virtual long64 getCellID(double x, double y, double z) const;
+	/// access the grid size in Z
+	double getGridSizeZ() const {
+		return _gridSizeZ;
+	}
+	/// access the coordinate offset in Z
+	double getOffsetZ() const {
+		return _offsetZ;
+	}
+	/// access the field name used for Z
+	std::string getFieldNameZ() const {
+		return _zId;
+	}
+	/// set the grid size in Z
+	void setGridSizeZ(double cellSize) {
+		_gridSizeZ = cellSize;
+	}
+	/// set the coordinate offset in Z
+	void setOffsetZ(double offset) {
+		_offsetZ = offset;
+	}
+	/// set the field name used for Z
+	void setFieldNameZ(std::string name) {
+		_zId = name;
+	}
+	/// access the set of parameters for this segmentation
+	Parameters parameters() const;
+
+protected:
+	/// the grid size in Z
+	double _gridSizeZ;
+	/// the coordinate offset in Z
+	double _offsetZ;
+	/// the field name used for Z
+	std::string _zId;
+};
+
+} /* namespace DDSegmentation */
+} /* namespace DD4hep */
+#endif /* DDSegmentation_CARTESIANGRIDXYZ_H_ */
diff --git a/DDSegmentation/include/DDSegmentation/CartesianSegmentation.h b/DDSegmentation/include/DDSegmentation/CartesianSegmentation.h
deleted file mode 100644
index d52209eea..000000000
--- a/DDSegmentation/include/DDSegmentation/CartesianSegmentation.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * CartesianSegmentation.h
- *
- *  Created on: Jun 28, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef CARTESIANSEGMENTATION_H_
-#define CARTESIANSEGMENTATION_H_
-
-#include "DDSegmentation/Segmentation.h"
-
-namespace DD4hep {
-namespace DDSegmentation {
-
-class CartesianSegmentation: public Segmentation {
-public:
-	virtual ~CartesianSegmentation();
-protected:
-	CartesianSegmentation(const std::string& cellEncoding);
-	CartesianSegmentation(const BitField64& decoder);
-
-	double binToPosition(long64 bin, double cellSize, double offset) const;
-	int positionToBin(double position, double cellSize, double offset) const;
-};
-
-} /* namespace Segmentation */
-} /* namespace DD4hep */
-#endif /* CARTESIANSEGMENTATION_H_ */
diff --git a/DDSegmentation/include/DDSegmentation/CartesianXYSegmentation.h b/DDSegmentation/include/DDSegmentation/CartesianXYSegmentation.h
deleted file mode 100644
index 32e0bed4f..000000000
--- a/DDSegmentation/include/DDSegmentation/CartesianXYSegmentation.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * CartesianXYSegmentation.h
- *
- *  Created on: Jun 28, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef CARTESIANXYSEGMENTATION_H_
-#define CARTESIANXYSEGMENTATION_H_
-
-#include "DDSegmentation/CartesianSegmentation.h"
-
-namespace DD4hep {
-namespace DDSegmentation {
-
-class CartesianXYSegmentation: public CartesianSegmentation {
-public:
-	CartesianXYSegmentation(const std::string& cellEncoding, double cellSizeX, double cellSizeY, double offsetX = 0.,
-			double offsetY = 0.);
-	CartesianXYSegmentation(const BitField64& decoder, double cellSizeX, double cellSizeY, double offsetX = 0.,
-			double offsetY = 0.);
-	virtual ~CartesianXYSegmentation();
-
-
-	virtual std::vector<double> getLocalPosition(const long64& cellID) const;
-
-	virtual long64 getCellID(double x, double y, double z) const;
-
-	double getCellSizeX() const {
-		return _cellSizeX;
-	}
-
-	double getCellSizeY() const {
-		return _cellSizeY;
-	}
-
-	double getOffsetX() const {
-		return _offsetX;
-	}
-
-	double getOffsetY() const {
-		return _offsetY;
-	}
-
-protected:
-	double _cellSizeX;
-	double _offsetX;
-	double _cellSizeY;
-	double _offsetY;
-};
-
-} /* namespace Segmentation */
-} /* namespace DD4hep */
-#endif /* CARTESIANXYSEGMENTATION_H_ */
diff --git a/DDSegmentation/include/DDSegmentation/CartesianXYZSegmentation.h b/DDSegmentation/include/DDSegmentation/CartesianXYZSegmentation.h
deleted file mode 100644
index d0914f03b..000000000
--- a/DDSegmentation/include/DDSegmentation/CartesianXYZSegmentation.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * CartesianXYZSegmentation.h
- *
- *  Created on: Jun 28, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#ifndef CARTESIANXYZSEGMENTATION_H_
-#define CARTESIANXYZSEGMENTATION_H_
-
-#include "DDSegmentation/CartesianXYSegmentation.h"
-
-namespace DD4hep {
-namespace DDSegmentation {
-
-class CartesianXYZSegmentation: public CartesianXYSegmentation {
-public:
-	CartesianXYZSegmentation(const std::string& cellEncoding, double cellSizeX, double cellSizeY, double cellSizeZ,
-			double offsetX = 0., double offsetY = 0., double offsetZ = 0.);
-	CartesianXYZSegmentation(const BitField64& decoder, double cellSizeX, double cellSizeY, double cellSizeZ, double offsetX =
-			0., double offsetY = 0., double offsetZ = 0.);
-	virtual ~CartesianXYZSegmentation();
-
-	virtual std::vector<double> getLocalPosition(const long64& cellID) const;
-
-	virtual long64 getCellID(double x, double y, double z) const;
-
-	double getCellSizeZ() const {
-		return _cellSizeZ;
-	}
-
-	double getOffsetZ() const {
-		return _offsetZ;
-	}
-
-protected:
-	double _cellSizeZ;
-	double _offsetZ;
-};
-
-} /* namespace Segmentation */
-} /* namespace DD4hep */
-#endif /* CARTESIANXYZSEGMENTATION_H_ */
diff --git a/DDSegmentation/include/DDSegmentation/CellIDDecoderFactory.h b/DDSegmentation/include/DDSegmentation/CellIDDecoderFactory.h
index b242cb8a6..d796c6209 100644
--- a/DDSegmentation/include/DDSegmentation/CellIDDecoderFactory.h
+++ b/DDSegmentation/include/DDSegmentation/CellIDDecoderFactory.h
@@ -12,7 +12,7 @@
 
 #include "DD4hep/LCDD.h"
 #include "DD4hep/Segmentations.h"
-#include "DDSegmentation/CartesianXYSegmentation.h"
+#include "DDSegmentation/CartesianGridXY.h"
 
 #include <iostream>
 #include <string>
@@ -30,7 +30,7 @@ CellIDDecoder getCellIDDecoder(const std::string& collectionName) {
 	std::string type = s.type();
 	if (type == "grid_xyz") {
 		Geometry::GridXYZ g = (Geometry::GridXY) s;
-		segmentation = new CartesianXYSegmentation(readout.idSpec().fieldDescription(), g.getGridSizeX(), g.getGridSizeY());
+		segmentation = new CartesianGridXY(readout.idSpec().decoder(), g.getGridSizeX(), g.getGridSizeY());
 	} else {
 	    throw std::runtime_error("The segmentation type "+type+" is not supported by CellIDDecoderFactory.");
 	}
diff --git a/DDSegmentation/include/DDSegmentation/Segmentation.h b/DDSegmentation/include/DDSegmentation/Segmentation.h
index 140f9ab3e..3a1741204 100644
--- a/DDSegmentation/include/DDSegmentation/Segmentation.h
+++ b/DDSegmentation/include/DDSegmentation/Segmentation.h
@@ -5,37 +5,66 @@
  *      Author: Christian Grefe, CERN
  */
 
-#ifndef SEGMENTATION_H_
-#define SEGMENTATION_H_
+#ifndef DDSegmentation_SEGMENTATION_H_
+#define DDSegmentation_SEGMENTATION_H_
 
-#include "DD4hep/BitField64.h"
+#include "DDSegmentation/BitField64.h"
 
+#include <utility>
 #include <string>
 #include <vector>
 
 namespace DD4hep {
 namespace DDSegmentation {
 
+/// Segmentation parameter definition
+typedef std::pair<std::string,double> Parameter;
+/// Segmentation parameter container definition
+typedef std::vector<Parameter>        Parameters;
+
 class Segmentation {
 public:
-	Segmentation(const std::string& cellEncoding);
-	Segmentation(const BitField64& decoder);
+	/// default constructor using an arbitrary type
+	template <typename TYPE> Segmentation(TYPE cellEncoding);
+	/// default constructor using an existing decoder
+	Segmentation(BitField64* decoder);
+	/// destructor
 	virtual ~Segmentation();
 
+	/// determine the local position based on the cell ID
 	virtual std::vector<double> getLocalPosition(const long64& cellID) const = 0;
-
+	/// determine the cell ID based on the local position
 	virtual long64 getCellID(double x, double y, double z) const = 0;
+	/// determine the cell ID based on the local position
 	long64 getCellID(const std::vector<double>& localPosition) const;
+	/// determine the cell ID based on the local position
 	long64 getCellID(const double* localPosition) const;
-
+	/// access the encoding string
 	std::string fieldDescription() const {
-		return _decoder.fieldDescription();
+		return _decoder->fieldDescription();
+	}
+	/// access the segmentation type
+	std::string type() const {
+		return _type;
+	}
+	/// access the underlying decoder
+	BitField64* decoder() {
+		return _decoder;
 	}
+	/// set the underlying decoder
+	void setDecoder(BitField64* decoder);
+	/// access the set of parameters for this segmentation
+	Parameters parameters() const;
 
 protected:
-	mutable BitField64 _decoder;
+	/// the cell ID encoder and decoder
+	mutable BitField64* _decoder;
+	/// keeps track of the decoder ownership
+	bool _ownsDecoder;
+	/// the segmentation type
+	std::string _type;
 };
 
-} /* namespace Segmentation */
+} /* namespace DDSegmentation */
 } /* namespace DD4hep */
-#endif /* SEGMENTATION_H_ */
+#endif /* DDSegmentation_SEGMENTATION_H_ */
diff --git a/DDCore/src/BitField64.cpp b/DDSegmentation/src/BitField64.cpp
similarity index 98%
rename from DDCore/src/BitField64.cpp
rename to DDSegmentation/src/BitField64.cpp
index 268a92cd0..1deac192d 100644
--- a/DDCore/src/BitField64.cpp
+++ b/DDSegmentation/src/BitField64.cpp
@@ -1,11 +1,12 @@
-#include "DD4hep/BitField64.h"
+#include "DDSegmentation/BitField64.h"
 
 #include <cmath>
 #include <algorithm>
 #include <stdexcept>
 
 namespace DD4hep{
-  
+
+namespace DDSegmentation {
   
     BitFieldValue::BitFieldValue( long64& bitfield, const std::string& name, 
 				  unsigned offset, int signedWidth ) :
@@ -291,4 +292,5 @@ namespace DD4hep{
   } 
 
 } // namespace
- 
+
+} // namespace
diff --git a/DDSegmentation/src/CartesianGrid.cpp b/DDSegmentation/src/CartesianGrid.cpp
new file mode 100644
index 000000000..1c137444f
--- /dev/null
+++ b/DDSegmentation/src/CartesianGrid.cpp
@@ -0,0 +1,60 @@
+/*
+ * CartesianGrid.cpp
+ *
+ *  Created on: Jun 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#include "DDSegmentation/CartesianGrid.h"
+
+#include <stdexcept>
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+using std::string;
+
+/// default constructor using an encoding string
+template<> CartesianGrid::CartesianGrid(const string& cellEncoding) :
+		Segmentation(cellEncoding) {
+
+}
+
+/// default constructor using an encoding string
+template<> CartesianGrid::CartesianGrid(string cellEncoding) :
+		Segmentation(cellEncoding) {
+
+}
+
+/// default constructor using an encoding string
+template<> CartesianGrid::CartesianGrid(const char* cellEncoding) :
+		Segmentation(cellEncoding) {
+
+}
+
+/// default constructor using an existing decoder
+CartesianGrid::CartesianGrid(BitField64* decoder) :
+		Segmentation(decoder) {
+
+}
+
+/// destructor
+CartesianGrid::~CartesianGrid() {
+
+}
+
+/// helper method to convert a bin number to a 1D position
+double CartesianGrid::binToPosition(long64 bin, double cellSize, double offset) const {
+	return bin * cellSize + offset;
+}
+
+/// helper method to convert a 1D position to a cell ID
+int CartesianGrid::positionToBin(double position, double cellSize, double offset) const {
+	if (cellSize == 0.) {
+		throw std::runtime_error("Invalid cell size: 0.0");
+	}
+	return int((position + 0.5 * cellSize - offset)/cellSize);
+}
+
+} /* namespace DDSegmentation */
+} /* namespace DD4hep */
diff --git a/DDSegmentation/src/CartesianGridXY.cpp b/DDSegmentation/src/CartesianGridXY.cpp
new file mode 100644
index 000000000..33ab1d5f4
--- /dev/null
+++ b/DDSegmentation/src/CartesianGridXY.cpp
@@ -0,0 +1,81 @@
+/*
+ * CartesianGridXY.cpp
+ *
+ *  Created on: Jun 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#include "DDSegmentation/CartesianGridXY.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+using std::make_pair;
+using std::string;
+using std::vector;
+
+/// default constructor using an encoding string
+template<> CartesianGridXY::CartesianGridXY(const string& cellEncoding, double gridSizeX, double gridSizeY, double offsetX,
+		double offsetY, string xField, string yField) :
+		CartesianGrid(cellEncoding), _gridSizeX(gridSizeX), _gridSizeY(gridSizeY), _offsetX(offsetX), _offsetY(offsetY), _xId(
+				xField), _yId(yField) {
+	_type = "grid_xy";
+}
+
+/// default constructor using an encoding string
+template<> CartesianGridXY::CartesianGridXY(string cellEncoding, double gridSizeX, double gridSizeY, double offsetX,
+		double offsetY, string xField, string yField) :
+		CartesianGrid(cellEncoding), _gridSizeX(gridSizeX), _gridSizeY(gridSizeY), _offsetX(offsetX), _offsetY(offsetY), _xId(
+				xField), _yId(yField) {
+	_type = "grid_xy";
+}
+
+/// default constructor using an encoding string
+template<> CartesianGridXY::CartesianGridXY(const char* cellEncoding, double gridSizeX, double gridSizeY, double offsetX,
+		double offsetY, string xField, string yField) :
+		CartesianGrid(cellEncoding), _gridSizeX(gridSizeX), _gridSizeY(gridSizeY), _offsetX(offsetX), _offsetY(offsetY), _xId(
+				xField), _yId(yField) {
+	_type = "grid_xy";
+}
+
+/// default constructor using an existing decoder
+CartesianGridXY::CartesianGridXY(BitField64* decoder, double gridSizeX, double gridSizeY, double offsetX,
+		double offsetY, string xField, string yField) :
+		CartesianGrid(decoder), _gridSizeX(gridSizeX), _gridSizeY(gridSizeY), _offsetX(offsetX), _offsetY(offsetY), _xId(
+				xField), _yId(yField) {
+	_type = "grid_xy";
+}
+
+/// destructor
+CartesianGridXY::~CartesianGridXY() {
+
+}
+
+/// determine the local position based on the cell ID
+vector<double> CartesianGridXY::getLocalPosition(const long64& cellID) const {
+	_decoder->setValue(cellID);
+	vector<double> localPosition(3);
+	localPosition[0] = binToPosition((*_decoder)[_xId].value(), _gridSizeX, _offsetX);
+	localPosition[1] = binToPosition((*_decoder)[_yId].value(), _gridSizeY, _offsetY);
+	localPosition[2] = 0.;
+	return localPosition;
+}
+
+/// determine the cell ID based on the local position
+long64 CartesianGridXY::getCellID(double x, double y, double z) const {
+	_decoder->reset();
+	(*_decoder)[_xId] = positionToBin(x, _gridSizeX, _offsetX);
+	(*_decoder)[_yId] = positionToBin(y, _gridSizeY, _offsetY);
+	return _decoder->getValue();
+}
+
+/// access the set of parameters for this segmentation
+Parameters CartesianGridXY::parameters() const {
+	Parameters parameters;
+	parameters.push_back(make_pair("grid_size_x", _gridSizeX));
+	parameters.push_back(make_pair("grid_size_y", _gridSizeY));
+	return parameters;
+}
+
+} /* namespace DDSegmentation */
+} /* namespace DD4hep */
diff --git a/DDSegmentation/src/CartesianGridXYZ.cpp b/DDSegmentation/src/CartesianGridXYZ.cpp
new file mode 100644
index 000000000..4a21e554d
--- /dev/null
+++ b/DDSegmentation/src/CartesianGridXYZ.cpp
@@ -0,0 +1,83 @@
+/*
+ * CartesianGridXYZ.cpp
+ *
+ *  Created on: Jun 28, 2013
+ *      Author: Christian Grefe, CERN
+ */
+
+#include "DDSegmentation/CartesianGridXYZ.h"
+
+namespace DD4hep {
+namespace DDSegmentation {
+
+using std::make_pair;
+using std::string;
+using std::vector;
+
+/// default constructor using an encoding string
+template<> CartesianGridXYZ::CartesianGridXYZ(const string& cellEncoding, double gridSizeX, double gridSizeY, double gridSizeZ,
+		double offsetX, double offsetY, double offsetZ, string xField, string yField, string zField) :
+		CartesianGridXY(cellEncoding, gridSizeX, gridSizeY, offsetX, offsetY, xField, yField), _gridSizeZ(gridSizeZ), _offsetZ(
+				offsetZ), _zId(zField) {
+	_type = "grid_xyz";
+}
+
+/// default constructor using an encoding string
+template<> CartesianGridXYZ::CartesianGridXYZ(string cellEncoding, double gridSizeX, double gridSizeY, double gridSizeZ,
+		double offsetX, double offsetY, double offsetZ, string xField, string yField, string zField) :
+		CartesianGridXY(cellEncoding, gridSizeX, gridSizeY, offsetX, offsetY, xField, yField), _gridSizeZ(gridSizeZ), _offsetZ(
+				offsetZ), _zId(zField) {
+	_type = "grid_xyz";
+}
+
+/// default constructor using an encoding string
+template<> CartesianGridXYZ::CartesianGridXYZ(const char* cellEncoding, double gridSizeX, double gridSizeY, double gridSizeZ,
+		double offsetX, double offsetY, double offsetZ, string xField, string yField, string zField) :
+		CartesianGridXY(cellEncoding, gridSizeX, gridSizeY, offsetX, offsetY, xField, yField), _gridSizeZ(gridSizeZ), _offsetZ(
+				offsetZ), _zId(zField) {
+	_type = "grid_xyz";
+}
+
+/// default constructor using an existing decoder
+CartesianGridXYZ::CartesianGridXYZ(BitField64* decoder, double gridSizeX, double gridSizeY, double gridSizeZ,
+		double offsetX, double offsetY, double offsetZ, string xField, string yField, string zField) :
+		CartesianGridXY(decoder, gridSizeX, gridSizeY, offsetX, offsetY, xField, yField), _gridSizeZ(gridSizeZ), _offsetZ(
+				offsetZ), _zId(zField) {
+	_type = "grid_xyz";
+}
+
+/// destructor
+CartesianGridXYZ::~CartesianGridXYZ() {
+
+}
+
+/// determine the local position based on the cell ID
+vector<double> CartesianGridXYZ::getLocalPosition(const long64& cellID) const {
+	_decoder->setValue(cellID);
+	vector<double> localPosition(3);
+	localPosition[0] = binToPosition((*_decoder)[_xId].value(), _gridSizeX, _offsetX);
+	localPosition[1] = binToPosition((*_decoder)[_yId].value(), _gridSizeY, _offsetY);
+	localPosition[2] = binToPosition((*_decoder)[_zId].value(), _gridSizeZ, _offsetZ);
+	return localPosition;
+}
+
+/// determine the cell ID based on the local position
+long64 CartesianGridXYZ::getCellID(double x, double y, double z) const {
+	_decoder->reset();
+	(*_decoder)[_xId] = positionToBin(x, _gridSizeX, _offsetX);
+	(*_decoder)[_yId] = positionToBin(y, _gridSizeY, _offsetY);
+	(*_decoder)[_zId] = positionToBin(z, _gridSizeZ, _offsetZ);
+	return _decoder->getValue();
+}
+
+/// access the set of parameters for this segmentation
+Parameters CartesianGridXYZ::parameters() const {
+	Parameters parameters;
+	parameters.push_back(make_pair("grid_size_x", _gridSizeX));
+	parameters.push_back(make_pair("grid_size_y", _gridSizeY));
+	parameters.push_back(make_pair("grid_size_z", _gridSizeZ));
+	return parameters;
+}
+
+} /* namespace DDSegmentation */
+} /* namespace DD4hep */
diff --git a/DDSegmentation/src/CartesianSegmentation.cpp b/DDSegmentation/src/CartesianSegmentation.cpp
deleted file mode 100644
index c55b585e4..000000000
--- a/DDSegmentation/src/CartesianSegmentation.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * CartesianSegmentation.cpp
- *
- *  Created on: Jun 28, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#include "DDSegmentation/CartesianSegmentation.h"
-
-namespace DD4hep {
-namespace DDSegmentation {
-
-using std::string;
-
-CartesianSegmentation::CartesianSegmentation(const string& cellEncoding) :
-		Segmentation(cellEncoding) {
-
-}
-
-CartesianSegmentation::CartesianSegmentation(const BitField64& decoder) :
-		Segmentation(decoder) {
-
-}
-
-CartesianSegmentation::~CartesianSegmentation() {
-
-}
-
-double CartesianSegmentation::binToPosition(long64 bin, double cellSize, double offset) const {
-	return bin * cellSize + offset;
-}
-
-int CartesianSegmentation::positionToBin(double position, double cellSize, double offset) const {
-	return int((position + 0.5 * cellSize - offset)/cellSize);
-}
-
-} /* namespace Segmentation */
-} /* namespace DD4hep */
diff --git a/DDSegmentation/src/CartesianXYSegmentation.cpp b/DDSegmentation/src/CartesianXYSegmentation.cpp
deleted file mode 100644
index acbbcef20..000000000
--- a/DDSegmentation/src/CartesianXYSegmentation.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * CartesianXYSegmentation.cpp
- *
- *  Created on: Jun 28, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#include "DDSegmentation/CartesianXYSegmentation.h"
-
-namespace DD4hep {
-namespace DDSegmentation {
-
-using std::string;
-using std::vector;
-
-CartesianXYSegmentation::CartesianXYSegmentation(const string& cellEncoding, double cellSizeX, double cellSizeY,
-		double offsetX, double offsetY) :
-		CartesianSegmentation(cellEncoding), _cellSizeX(cellSizeX), _cellSizeY(cellSizeY), _offsetX(offsetX), _offsetY(
-				offsetY) {
-
-}
-
-CartesianXYSegmentation::CartesianXYSegmentation(const BitField64& decoder, double cellSizeX, double cellSizeY,
-		double offsetX, double offsetY) :
-		CartesianSegmentation(decoder), _cellSizeX(cellSizeX), _cellSizeY(cellSizeY), _offsetX(offsetX), _offsetY(
-				offsetY) {
-
-}
-
-CartesianXYSegmentation::~CartesianXYSegmentation() {
-
-}
-
-vector<double> CartesianXYSegmentation::getLocalPosition(const long64& cellID) const {
-	_decoder.setValue(cellID);
-	vector<double> localPosition(3);
-	localPosition[0] = binToPosition(_decoder["x"].value(), _cellSizeX, _offsetX);
-	localPosition[1] = binToPosition(_decoder["y"].value(), _cellSizeY, _offsetY);
-	localPosition[2] = 0.;
-	return localPosition;
-}
-
-long64 CartesianXYSegmentation::getCellID(double x, double y, double z) const {
-	_decoder.reset();
-	_decoder["x"] = positionToBin(x, _cellSizeX, _offsetX);
-	_decoder["y"] = positionToBin(y, _cellSizeY, _offsetY);
-	return _decoder.getValue();
-}
-
-} /* namespace Segmentation */
-} /* namespace DD4hep */
diff --git a/DDSegmentation/src/CartesianXYZSegmentation.cpp b/DDSegmentation/src/CartesianXYZSegmentation.cpp
deleted file mode 100644
index fbc8171bd..000000000
--- a/DDSegmentation/src/CartesianXYZSegmentation.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * CartesianXYZSegmentation.cpp
- *
- *  Created on: Jun 28, 2013
- *      Author: Christian Grefe, CERN
- */
-
-#include "DDSegmentation/CartesianXYZSegmentation.h"
-
-namespace DD4hep {
-namespace DDSegmentation {
-
-using std::string;
-using std::vector;
-
-CartesianXYZSegmentation::CartesianXYZSegmentation(const string& cellEncoding, double cellSizeX, double cellSizeY, double cellSizeZ,
-		double offsetX, double offsetY, double offsetZ) :
-		CartesianXYSegmentation(cellEncoding, cellSizeX, cellSizeY, offsetX, offsetY), _cellSizeZ(cellSizeZ), _offsetZ(offsetZ) {
-
-}
-
-CartesianXYZSegmentation::CartesianXYZSegmentation(const BitField64& decoder, double cellSizeX, double cellSizeY, double cellSizeZ,
-		double offsetX, double offsetY, double offsetZ) :
-		CartesianXYSegmentation(decoder, cellSizeX, cellSizeY, offsetX, offsetY), _cellSizeZ(cellSizeZ), _offsetZ(offsetZ) {
-
-}
-
-CartesianXYZSegmentation::~CartesianXYZSegmentation() {
-
-}
-
-vector<double> CartesianXYZSegmentation::getLocalPosition(const long64& cellID) const {
-	_decoder.setValue(cellID);
-	vector<double> localPosition;
-	localPosition[0] = binToPosition(_decoder["x"].value(), _cellSizeX, _offsetX);
-	localPosition[1] = binToPosition(_decoder["y"].value(), _cellSizeY, _offsetY);
-	localPosition[2] = binToPosition(_decoder["z"].value(), _cellSizeZ, _offsetZ);
-	return localPosition;
-}
-
-long64 CartesianXYZSegmentation::getCellID(double x, double y, double z) const {
-	_decoder.reset();
-	_decoder["x"] = positionToBin(x, _cellSizeX, _offsetX);
-	_decoder["y"] = positionToBin(y, _cellSizeY, _offsetY);
-	_decoder["z"] = positionToBin(z, _cellSizeZ, _offsetZ);
-	return _decoder.getValue();
-}
-
-} /* namespace Segmentation */
-} /* namespace DD4hep */
diff --git a/DDSegmentation/src/Segmentation.cpp b/DDSegmentation/src/Segmentation.cpp
index 37fa60419..5efba3ac6 100644
--- a/DDSegmentation/src/Segmentation.cpp
+++ b/DDSegmentation/src/Segmentation.cpp
@@ -7,30 +7,75 @@
 
 #include "DDSegmentation/Segmentation.h"
 
+#include <stdexcept>
+
 namespace DD4hep {
 namespace DDSegmentation {
 
 using std::string;
 using std::vector;
 
-Segmentation::Segmentation(const string& cellEncoding) : _decoder(cellEncoding) {
+/// default constructor using an encoding string
+template<> Segmentation::Segmentation(std::string cellEncoding) {
+	_decoder = new BitField64(cellEncoding);
+	_ownsDecoder = true;
+	_type = "segmentation";
 }
 
-Segmentation::Segmentation(const BitField64& decoder) : _decoder(decoder.fieldDescription()) {
+/// default constructor using an encoding string
+template<> Segmentation::Segmentation(const std::string& cellEncoding) {
+	_decoder = new BitField64(cellEncoding);
+	_ownsDecoder = true;
+	_type = "segmentation";
+}
 
+/// default constructor using an encoding string
+template<> Segmentation::Segmentation(const char* cellEncoding) {
+	_decoder = new BitField64(cellEncoding);
+	_ownsDecoder = true;
+	_type = "segmentation";
 }
 
-Segmentation::~Segmentation() {
+/// default constructor using an existing decoder
+Segmentation::Segmentation(BitField64* decoder) {
+	_decoder = decoder;
+	_ownsDecoder = false;
+	_type = "segmentation";
+}
 
+/// destructor
+Segmentation::~Segmentation() {
+	if (_ownsDecoder and _decoder != 0) {
+		delete _decoder;
+	}
 }
 
+/// determine the cell ID based on the local position
 long64 Segmentation::getCellID(const vector<double>& localPosition) const {
+	if (localPosition.size() != 3) {
+		throw std::runtime_error("Vector size has to be 3!");
+	}
 	return getCellID(localPosition[0], localPosition[1], localPosition[2]);
 }
 
+/// determine the cell ID based on the local position
 long64 Segmentation::getCellID(const double* localPosition) const {
 	return getCellID(localPosition[0], localPosition[1], localPosition[2]);
 }
 
-} /* namespace Segmentation */
+/// set the underlying decoder
+void Segmentation::setDecoder(BitField64* decoder) {
+	if (_ownsDecoder and _decoder != 0) {
+		delete _decoder;
+	}
+	_decoder = decoder;
+	_ownsDecoder = false;
+}
+
+/// access the set of parameters for this segmentation
+Parameters Segmentation::parameters() const {
+	return Parameters();
+}
+
+} /* namespace DDSegmentation */
 } /* namespace DD4hep */
diff --git a/DDSense/CMakeLists.txt b/DDSense/CMakeLists.txt
index e1c3c0f96..f13b154df 100644
--- a/DDSense/CMakeLists.txt
+++ b/DDSense/CMakeLists.txt
@@ -14,6 +14,7 @@ INCLUDE(${Geant4_USE_FILE})   # this also takes care of geant 4 definitions and
 
 #---Includedirs-------------------------------------------------------------------
 include_directories( ${CMAKE_SOURCE_DIR}/DDCore/include
+  ${CMAKE_SOURCE_DIR}/DDSegmentation/include
   ${CMAKE_CURRENT_SOURCE_DIR}/include 
   #${CLHEP_INCLUDE_DIR}
   ${Geant4_INCLUDE_DIRS}
diff --git a/DDSense/src/DDSensitiveManager.cpp b/DDSense/src/DDSensitiveManager.cpp
index 297b2112d..8726a3424 100644
--- a/DDSense/src/DDSensitiveManager.cpp
+++ b/DDSense/src/DDSensitiveManager.cpp
@@ -1,7 +1,7 @@
 #include "DDSense/DDSensitiveManager.h"
 #include "DDSense/G4SensitiveDetector.h"
 
-#include "DD4hep/BitField64.h"  // provides StringTokenizer
+#include "DDSegmentation/BitField64.h"  // provides StringTokenizer
 
 #include <dlfcn.h>
 #include <algorithm>
@@ -66,7 +66,7 @@ namespace DD4hep {
     void DDSensitiveManager::loadLibraries(){
       
       StringVec libs ;
-      StringTokenizer t( libs, ':' ) ;
+      DDSegmentation::StringTokenizer t( libs, ':' ) ;
       
       std::string sds("") ;
       
diff --git a/UtilityApps/CMakeLists.txt b/UtilityApps/CMakeLists.txt
index 6a98427b3..27e135b9c 100644
--- a/UtilityApps/CMakeLists.txt
+++ b/UtilityApps/CMakeLists.txt
@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 2.8.3 FATAL_ERROR)
 
 include_directories( ${CMAKE_SOURCE_DIR}/DDCore/include 
-                     ${ROOT_INCLUDE_DIR})
+                     ${ROOT_INCLUDE_DIR}
+                     ${CMAKE_SOURCE_DIR}/DDSegmentation/include)
 
 #-----------------------------------------------------------------------------------
 add_executable(geoDisplay src/display.cpp)
-- 
GitLab