From eb7a1417dde3ef00369db8ecb0132cc95870e64e Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Thu, 28 Oct 2021 14:27:53 +0800
Subject: [PATCH 01/27] Increase the diagonal wire version

---
 .../CRD_common_v01/DC_Simple_v01_01.xml       |  12 ++-
 .../CRD_common_v01/DC_Simple_v01_02.xml       |   8 +-
 .../CRD_o1_v01/CRD_Dimensions_v01_01.xml      |   4 +-
 .../CRD_o1_v01/CRD_o1_v01-onlyTracker.xml     |   2 +-
 .../CRD_o1_v02/CRD_Dimensions_v01_02.xml      |   4 +-
 .../CRD_o1_v02/CRD_o1_v02-onlyTracker.xml     |   2 +-
 Detector/DetDriftChamber/CMakeLists.txt       |   1 +
 Detector/DetDriftChamber/compact/det.xml      |  16 +--
 .../src/driftchamber/DriftChamber.cpp         |  20 +++-
 .../DetSegmentation/GridDriftChamber.h        |  64 ++++++++++-
 .../DetSegmentation/src/GridDriftChamber.cpp  | 101 +++++++++++++++++-
 11 files changed, 202 insertions(+), 32 deletions(-)

diff --git a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_01.xml b/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_01.xml
index a1da46679..73594f243 100644
--- a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_01.xml
+++ b/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_01.xml
@@ -28,7 +28,7 @@
 
     <constant name="SDT_chamber_layer_width" value="10*mm"/>
     <constant name="SDT_chamber_cell_width" value="10*mm"/>
-    <constant name="Epsilon" value="0*deg"/>
+    <constant name="Alpha" value="0*deg"/>
 
     <constant name="SDT_chamber_inner_wall_radius_min" value="SDT_chamber_radius_min-SDT_inner_wall_thickness"/>
     <constant name="SDT_chamber_inner_wall_radius_max" value="SDT_chamber_radius_min"/>
@@ -42,7 +42,7 @@
 
   <limits>
     <limitset name="DC_limits">
-      <limit name="step_length_max" particles="*" value="0.5" unit="mm" />
+      <limit name="step_length_max" particles="*" value="0.1" unit="mm" />
     </limitset>
   </limits>
 
@@ -53,8 +53,10 @@
 
   <detectors>
     <detector id="DetID_DC" name="DriftChamber" type="DriftChamber" readout="DriftChamberHitsCollection" vis="DCVis" sensitive="true" region="DriftChamberRegion" limits="DC_limits">
-      <chamber id="0"/>
-      <envelope>
+      <material name="Air"/>
+      <chamber id="0" material="GasHe_90Isob_10"/>
+      <side material="CarbonFiber"/>
+      <envelope vis="SeeThrough">
         <shape type="BooleanShape" operation="Union" material="Air">
           <shape type="Tube" rmin="SDT_radius_min" rmax="SDT_radius_max" dz="SDT_half_length" />
         </shape>
@@ -78,7 +80,7 @@
 
   <readouts>
     <readout name="DriftChamberHitsCollection">
-      <segmentation type="GridDriftChamber" cell_size="SDT_chamber_cell_width" epsilon0="Epsilon" detector_length="DC_length" identifier_phi="cellID" DC_rbegin="DC_chamber_layer_rbegin" DC_rend="DC_chamber_layer_rend" DC_rmin="SDT_chamber_radius_min" DC_rmax="SDT_chamber_radius_max" safe_distance="DC_safe_distance" layerID="layer" layer_width="SDT_chamber_layer_width"/>
+      <segmentation type="GridDriftChamber" cell_size="SDT_chamber_cell_width" detector_length="DC_length" identifier_phi="cellID" DC_rbegin="DC_chamber_layer_rbegin" DC_rend="DC_chamber_layer_rend" DC_rmin="SDT_chamber_radius_min" DC_rmax="SDT_chamber_radius_max" safe_distance="DC_safe_distance" layerID="layer" layer_width="SDT_chamber_layer_width"/>
 
       <!-- <id>system:8,chamber:1,layer:8,cellID:16</id> -->
       <id>system:5,layer:7:9,chamber:8,cellID:32:16</id>
diff --git a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_02.xml b/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_02.xml
index ae4ccbe02..0b6e8f67e 100644
--- a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_02.xml
+++ b/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_02.xml
@@ -28,7 +28,7 @@
 
     <constant name="SDT_chamber_layer_width" value="10*mm"/>
     <constant name="SDT_chamber_cell_width" value="10*mm"/>
-    <constant name="Epsilon" value="0*deg"/>
+    <constant name="Alpha" value="0*deg"/>
 
     <constant name="SDT_chamber_inner_wall_radius_min" value="SDT_chamber_radius_min-SDT_inner_wall_thickness"/>
     <constant name="SDT_chamber_inner_wall_radius_max" value="SDT_chamber_radius_min"/>
@@ -54,7 +54,9 @@
 
   <detectors>
     <detector id="DetID_DC" name="DriftChamber" type="DriftChamber" readout="DriftChamberHitsCollection" vis="DCVis" sensitive="true" insideTrackingVolume="true" limits="DC_limits">
-      <chamber id="0"/>
+      <material name="Air"/>
+      <chamber id="0" material="GasHe_90Isob_10"/>
+      <side material="CarbonFiber"/>
       <envelope>
         <shape type="BooleanShape" operation="Union" material="Air">
           <shape type="Tube" rmin="SDT_radius_min" rmax="SDT_radius_max" dz="SDT_half_length" />
@@ -79,7 +81,7 @@
 
   <readouts>
     <readout name="DriftChamberHitsCollection">
-      <segmentation type="GridDriftChamber" cell_size="SDT_chamber_cell_width" epsilon0="Epsilon" detector_length="DC_length" identifier_phi="cellID" DC_rbegin="DC_chamber_layer_rbegin" DC_rend="DC_chamber_layer_rend" DC_rmin="SDT_chamber_radius_min" DC_rmax="SDT_chamber_radius_max" safe_distance="DC_safe_distance" layerID="layer" layer_width="SDT_chamber_layer_width"/>
+      <segmentation type="GridDriftChamber" cell_size="SDT_chamber_cell_width" detector_length="DC_length" identifier_phi="cellID" DC_rbegin="DC_chamber_layer_rbegin" DC_rend="DC_chamber_layer_rend" DC_rmin="SDT_chamber_radius_min" DC_rmax="SDT_chamber_radius_max" safe_distance="DC_safe_distance" layerID="layer" layer_width="SDT_chamber_layer_width"/>
 
       <!-- <id>system:8,chamber:1,layer:8,cellID:16</id> -->
       <id>system:5,layer:7:9,chamber:8,cellID:32:16</id>
diff --git a/Detector/DetCRD/compact/CRD_o1_v01/CRD_Dimensions_v01_01.xml b/Detector/DetCRD/compact/CRD_o1_v01/CRD_Dimensions_v01_01.xml
index 4f631eb52..46959ebbe 100644
--- a/Detector/DetCRD/compact/CRD_o1_v01/CRD_Dimensions_v01_01.xml
+++ b/Detector/DetCRD/compact/CRD_o1_v01/CRD_Dimensions_v01_01.xml
@@ -102,8 +102,10 @@
     <constant name="DC_chamber_layer_rbegin" value="800*mm"/>
     <constant name="DC_chamber_layer_rend" value="1800*mm"/>
 
+    <constant name="DC_chamber_safe_distance" value="10*mm"/>
+
     <constant name="DC_inner_radius" value="DC_chamber_layer_rbegin-SDT_inner_wall_thickness-DC_safe_distance"/>
-    <constant name="DC_outer_radius" value="DC_chamber_layer_rend+SDT_outer_wall_thickness+DC_safe_distance"/>
+    <constant name="DC_outer_radius" value="DC_chamber_layer_rend+DC_chamber_safe_distance+SDT_outer_wall_thickness+DC_safe_distance"/>
 
     <constant name="SIT1_inner_radius"   value="230*mm"/>
     <constant name="SIT2_inner_radius"   value="410*mm"/>
diff --git a/Detector/DetCRD/compact/CRD_o1_v01/CRD_o1_v01-onlyTracker.xml b/Detector/DetCRD/compact/CRD_o1_v01/CRD_o1_v01-onlyTracker.xml
index 9ede81b79..d8c788d21 100644
--- a/Detector/DetCRD/compact/CRD_o1_v01/CRD_o1_v01-onlyTracker.xml
+++ b/Detector/DetCRD/compact/CRD_o1_v01/CRD_o1_v01-onlyTracker.xml
@@ -32,7 +32,7 @@
   <include ref="../CRD_common_v01/VXD_v01_01.xml"/>
   <include ref="../CRD_common_v01/FTD_SkewRing_v01_01.xml"/>
   <include ref="../CRD_common_v01/SIT_SimplePixel_v01_01.xml"/>
-  <include ref="../CRD_common_v01/DC_Simple_v01_02.xml"/>
+  <include ref="../CRD_common_v01/DC_Simple_v01_03.xml"/>
   <include ref="../CRD_common_v01/SET_SimplePixel_v01_01.xml"/>
   
   <fields>
diff --git a/Detector/DetCRD/compact/CRD_o1_v02/CRD_Dimensions_v01_02.xml b/Detector/DetCRD/compact/CRD_o1_v02/CRD_Dimensions_v01_02.xml
index 4f631eb52..46959ebbe 100644
--- a/Detector/DetCRD/compact/CRD_o1_v02/CRD_Dimensions_v01_02.xml
+++ b/Detector/DetCRD/compact/CRD_o1_v02/CRD_Dimensions_v01_02.xml
@@ -102,8 +102,10 @@
     <constant name="DC_chamber_layer_rbegin" value="800*mm"/>
     <constant name="DC_chamber_layer_rend" value="1800*mm"/>
 
+    <constant name="DC_chamber_safe_distance" value="10*mm"/>
+
     <constant name="DC_inner_radius" value="DC_chamber_layer_rbegin-SDT_inner_wall_thickness-DC_safe_distance"/>
-    <constant name="DC_outer_radius" value="DC_chamber_layer_rend+SDT_outer_wall_thickness+DC_safe_distance"/>
+    <constant name="DC_outer_radius" value="DC_chamber_layer_rend+DC_chamber_safe_distance+SDT_outer_wall_thickness+DC_safe_distance"/>
 
     <constant name="SIT1_inner_radius"   value="230*mm"/>
     <constant name="SIT2_inner_radius"   value="410*mm"/>
diff --git a/Detector/DetCRD/compact/CRD_o1_v02/CRD_o1_v02-onlyTracker.xml b/Detector/DetCRD/compact/CRD_o1_v02/CRD_o1_v02-onlyTracker.xml
index 2397761df..7f1a6986b 100644
--- a/Detector/DetCRD/compact/CRD_o1_v02/CRD_o1_v02-onlyTracker.xml
+++ b/Detector/DetCRD/compact/CRD_o1_v02/CRD_o1_v02-onlyTracker.xml
@@ -31,7 +31,7 @@
   <include ref="../CRD_common_v01/VXD_v01_01.xml"/>
   <include ref="../CRD_common_v01/FTD_SkewRing_v01_01.xml"/>
   <include ref="../CRD_common_v01/SIT_SimplePixel_v01_01.xml"/>
-  <include ref="../CRD_common_v01/DC_Simple_v01_01.xml"/>
+  <include ref="../CRD_common_v01/DC_Simple_v01_03.xml"/>
   <include ref="../CRD_common_v01/SET_SimplePlanar_v01_01.xml"/>
 
   <fields>
diff --git a/Detector/DetDriftChamber/CMakeLists.txt b/Detector/DetDriftChamber/CMakeLists.txt
index fbf8e01ce..7321b5e64 100644
--- a/Detector/DetDriftChamber/CMakeLists.txt
+++ b/Detector/DetDriftChamber/CMakeLists.txt
@@ -16,6 +16,7 @@ find_package(ROOT COMPONENTS MathCore GenVector Geom REQUIRED)
 
 gaudi_add_module(DetDriftChamber
                  SOURCES src/driftchamber/DriftChamber.cpp
+                 SOURCES src/driftchamber/DriftChamber_tile.cpp
 		 LINK DetSegmentation
                       ${DD4hep_COMPONENT_LIBRARIES} 
                   # ROOT Geant4
diff --git a/Detector/DetDriftChamber/compact/det.xml b/Detector/DetDriftChamber/compact/det.xml
index b62dd532d..08b29c928 100644
--- a/Detector/DetDriftChamber/compact/det.xml
+++ b/Detector/DetDriftChamber/compact/det.xml
@@ -19,7 +19,7 @@
 
 
   <define>
-    <constant name="world_size" value="2226*mm"/>
+    <constant name="world_size" value="2990*mm"/>
     <constant name="world_x" value="world_size"/>
     <constant name="world_y" value="world_size"/>
     <constant name="world_z" value="world_size"/>
@@ -40,8 +40,8 @@
 
     <constant name="DC_Endcap_dz" value="0.1*mm"/>
 
-    <constant name="SDT_half_length" value="2225*mm+DC_Endcap_dz"/>
-    <constant name="DC_half_length" value="2225*mm"/>
+    <constant name="SDT_half_length" value="2980*mm+DC_Endcap_dz"/>
+    <constant name="DC_half_length" value="2980*mm"/>
     <constant name="SDT_length" value="SDT_half_length*2"/>
     <constant name="DC_length" value="SDT_length-DC_Endcap_dz*2"/>
 
@@ -51,7 +51,7 @@
 
     <constant name="SDT_chamber_layer_width" value="10*mm"/>
     <constant name="SDT_chamber_cell_width" value="10*mm"/>
-    <constant name="Epsilon" value="0*deg"/>
+    <constant name="Alpha" value="0*deg"/>
 
     <constant name="SDT_chamber_inner_wall_radius_min" value="SDT_chamber_radius_min-SDT_inner_wall_thickness"/>
     <constant name="SDT_chamber_inner_wall_radius_max" value="SDT_chamber_radius_min"/>
@@ -74,7 +74,7 @@
 
   <limits>
     <limitset name="DC_limits">
-      <limit name="step_length_max" particles="*" value="0.1" unit="mm" />
+      <limit name="step_length_max" particles="*" value="0.5" unit="mm" />
     </limitset>
   </limits>
 
@@ -85,7 +85,9 @@
 
   <detectors>
     <detector id="DetID_DC" name="DriftChamber" type="DriftChamber" readout="DriftChamberHitsCollection" vis="VisibleBlue" sensitive="true" region="DriftChamberRegion" limits="DC_limits">
-      <chamber id="0"/>
+      <material name="Air"/>
+      <chamber id="0"  material="GasHe_90Isob_10"/>
+      <side material="CarbonFiber"/>
       <envelope vis="SeeThrough">
         <shape type="BooleanShape" operation="Union" material="Air">
           <shape type="Tube" rmin="SDT_radius_min" rmax="SDT_radius_max" dz="SDT_half_length" />
@@ -110,7 +112,7 @@
 
   <readouts>
     <readout name="DriftChamberHitsCollection">
-      <segmentation type="GridDriftChamber" cell_size="SDT_chamber_cell_width" epsilon0="Epsilon" detector_length="DC_length" identifier_phi="cellID" DC_rbegin="DC_chamber_layer_rbegin" DC_rend="DC_chamber_layer_rend" DC_rmin="SDT_chamber_radius_min" DC_rmax="SDT_chamber_radius_max" safe_distance="DC_safe_distance" layerID="layer" layer_width="SDT_chamber_layer_width"/>
+      <segmentation type="GridDriftChamber" cell_size="SDT_chamber_cell_width" detector_length="DC_length" identifier_phi="cellID" DC_rbegin="DC_chamber_layer_rbegin" DC_rend="DC_chamber_layer_rend" DC_rmin="SDT_chamber_radius_min" DC_rmax="SDT_chamber_radius_max" safe_distance="DC_safe_distance" layerID="layer" layer_width="SDT_chamber_layer_width"/>
 
 
       <id>system:5,layer:7:9,chamber:8,cellID:32:16</id>
diff --git a/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp b/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
index be98c1c14..02732bf5d 100644
--- a/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
+++ b/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
@@ -38,6 +38,9 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
     xml_coll_t c(x_det,_U(chamber));
     xml_comp_t x_chamber = c;
 
+    xml_coll_t cc(x_det,_U(side));
+    xml_comp_t x_side = cc;
+
     std::string det_name = x_det.nameStr();
     std::string det_type = x_det.typeStr();
 
@@ -45,6 +48,7 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
 
     // - global
     double chamber_half_length     = theDetector.constant<double>("DC_half_length");
+    double chamber_length  = theDetector.constant<double>("DC_length");
 
     // - chamber
     double chamber_radius_min = theDetector.constant<double>("SDT_chamber_radius_min");
@@ -60,7 +64,7 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
     int chamber_layer_number = floor((chamber_layer_rend-chamber_layer_rbegin)/chamber_layer_width);
 
     double safe_distance = theDetector.constant<double>("DC_safe_distance");
-    double epsilon = theDetector.constant<double>("Epsilon");
+    double alpha = theDetector.constant<double>("Alpha");
 
     // =======================================================================
     // Detector Construction
@@ -75,8 +79,10 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
     if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ;
 
 
-    dd4hep::Material det_mat(theDetector.material("Air"));
-    dd4hep::Material chamber_mat(theDetector.material("GasHe_90Isob_10"));
+//    dd4hep::Material det_mat(theDetector.material("Air"));
+    dd4hep::Material det_mat(theDetector.material(x_det.materialStr()));
+//    dd4hep::Material chamber_mat(theDetector.material("GasHe_90Isob_10"));
+    dd4hep::Material chamber_mat = theDetector.material(x_chamber.materialStr());
 
     // - global
     Assembly det_vol( det_name+"_assembly" ) ;
@@ -91,7 +97,8 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
     double chamber_outer_wall_rmin = theDetector.constant<double>("SDT_chamber_outer_wall_radius_min");
     double chamber_outer_wall_rmax = theDetector.constant<double>("SDT_chamber_outer_wall_radius_max");
 
-    dd4hep::Material wall_mat(theDetector.material("CarbonFiber"));
+//    dd4hep::Material wall_mat(theDetector.material("CarbonFiber"));
+    dd4hep::Material wall_mat(theDetector.material(x_side.materialStr()));
 
     double wall_rmin[2] = {chamber_inner_wall_rmin, chamber_outer_wall_rmin};
     double wall_rmax[2] = {chamber_inner_wall_rmax, chamber_outer_wall_rmax};
@@ -153,13 +160,14 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
     for(int layer_id = 0; layer_id < chamber_layer_number; layer_id++) {
         double rmin,rmax,offset=0;
         dd4hep::Volume* current_vol_ptr = nullptr;
-        current_vol_ptr = &det_chamber_vol;
+//        current_vol_ptr = &det_chamber_vol;
         rmin = chamber_layer_rbegin+(layer_id*chamber_layer_width);
         rmax = rmin+chamber_layer_width;
         layerIndex = layer_id;
 
         //Construction of drift chamber layers
         double rmid = delta_a_func(rmin,rmax);
+        double Rmid = rmid/std::cos(alpha/2);
         double ilayer_cir = 2 * M_PI * rmid;
         double ncell = ilayer_cir / chamber_layer_width;
         int ncell_layer = floor(ncell);
@@ -169,6 +177,8 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
         if(layer_id %2 ==0){ offset = 0.; }
         else { offset = 0.5 * layer_Phi; }
 
+        double epsilon = 0;
+
         DCHseg->setGeomParams(chamber_id, layerIndex, layer_Phi, rmid, epsilon, offset);
         DCHseg->setWiresInLayer(chamber_id, layerIndex, numWire);
 
diff --git a/Detector/DetSegmentation/include/DetSegmentation/GridDriftChamber.h b/Detector/DetSegmentation/include/DetSegmentation/GridDriftChamber.h
index 0233ccf82..ad9d03604 100644
--- a/Detector/DetSegmentation/include/DetSegmentation/GridDriftChamber.h
+++ b/Detector/DetSegmentation/include/DetSegmentation/GridDriftChamber.h
@@ -60,16 +60,19 @@ class GridDriftChamber : public Segmentation {
   virtual CellID cellID(const Vector3D& aLocalPosition, const Vector3D& aGlobalPosition,
                         const VolumeID& aVolumeID) const;
   virtual double distanceTrackWire(const CellID& cID, const TVector3& hit_start, const TVector3& hit_end) const;
+  virtual double distanceTrackWire2(const CellID& cID, const TVector3& hit_pos) const;
   virtual void cellposition(const CellID& cID, TVector3& Wstart, TVector3& Wend) const;
+  virtual void cellposition2(int chamber, int layer, int cell, TVector3& Wstart, TVector3& Wend) const;
   TVector3 LineLineIntersect(TVector3& p1, TVector3& p2, TVector3& p3, TVector3& p4) const;
   virtual TVector3 distanceClosestApproach(const CellID& cID, const TVector3& hitPos) const;
   virtual TVector3 Line_TrackWire(const CellID& cID, const TVector3& hit_start, const TVector3& hit_end) const;
   virtual TVector3 IntersectionTrackWire(const CellID& cID, const TVector3& hit_start, const TVector3& hit_end) const;
   virtual TVector3 wirePos_vs_z(const CellID& cID, const double& zpos) const;
+  virtual double Distance(const CellID& cID, const TVector3& pointIn, const TVector3& pointOut, TVector3& hitPosition) const;
 
 //  double phi(const CellID& cID) const;
   inline double cell_Size() const { return m_cellSize; }
-  inline double epsilon0() const { return m_epsilon0; }
+  inline double epsilon() const { return m_epsilon; }
   inline double detectorLength() const { return m_detectorLength; }
   inline double safe_distance() const { return m_safe_distance; }
   inline double layer_width() const { return m_layer_width; }
@@ -114,6 +117,52 @@ class GridDriftChamber : public Segmentation {
 
   inline auto returnAllWires() const { return m_wiresPositions; }
 
+//  TVector3 LineLineIntersect(TVector3 p1, TVector3 p2, TVector3 p3, TVector3 p4) const {
+//    TVector3 p13, p43, p21;
+//    double d1343, d4321, d1321, d4343, d2121;
+//    double numer, denom;
+//    double mua, mub;
+//    TVector3 pa, pb;
+//
+//    p13.SetX(p1.X() - p3.X());
+//    p13.SetY(p1.Y() - p3.Y());
+//    p13.SetZ(p1.Z() - p3.Z());
+//    p43.SetX(p4.X() - p3.X());
+//    p43.SetY(p4.Y() - p3.Y());
+//    p43.SetZ(p4.Z() - p3.Z());
+//    /* if (ABS(p43.X())  < EPS && ABS(p43.Y())  < EPS && ABS(p43.Z())  < EPS) */
+//    /*    return(FALSE); */
+//    p21.SetX(p2.X() - p1.X());
+//    p21.SetY(p2.Y() - p1.Y());
+//    p21.SetZ(p2.Z() - p1.Z());
+//    /* if (ABS(p21.X())  < EPS && ABS(p21.Y())  < EPS && ABS(p21.Z())  < EPS) */
+//    /*    return(FALSE); */
+//
+//    d1343 = p13.X() * p43.X() + p13.Y() * p43.Y() + p13.Z() * p43.Z();
+//    d4321 = p43.X() * p21.X() + p43.Y() * p21.Y() + p43.Z() * p21.Z();
+//    d1321 = p13.X() * p21.X() + p13.Y() * p21.Y() + p13.Z() * p21.Z();
+//    d4343 = p43.X() * p43.X() + p43.Y() * p43.Y() + p43.Z() * p43.Z();
+//    d2121 = p21.X() * p21.X() + p21.Y() * p21.Y() + p21.Z() * p21.Z();
+//
+//    denom = d2121 * d4343 - d4321 * d4321;
+//    /* if (ABS(denom) < EPS) */
+//    /*    return(FALSE); */
+//    numer = d1343 * d4321 - d1321 * d4343;
+//
+//    mua = numer / denom;
+//    mub = (d1343 + d4321 * (mua)) / d4343;
+//
+//    pa.SetX(p1.X() + mua * p21.X());
+//    pa.SetY(p1.Y() + mua * p21.Y());
+//    pa.SetZ(p1.Z() + mua * p21.Z());
+//    pb.SetX(p3.X() + mub * p43.X());
+//    pb.SetY(p3.Y() + mub * p43.Y());
+//    pb.SetZ(p3.Z() + mub * p43.Z());
+//
+//    return pb - pa;
+//  }
+
+
   void updateParams(int chamber, int layer)  const{
     auto it_end = layer_params.cend();
     --it_end;
@@ -136,6 +185,15 @@ class GridDriftChamber : public Segmentation {
     m_epsilon = Eps;
     m_offset = Offset;
  }
+   inline Vector3D returnPosWire0(double z) const {
+    double alpha = returnAlpha();
+    double t = 0.5 * (1 - 2.0 * z / m_detectorLength);
+    double x = _currentRadius * (1 + t * (std::cos(alpha) - 1));
+    double y = _currentRadius * t * std::sin(alpha);
+
+    Vector3D vec(x, y, z);
+    return vec;
+  }
 
 protected:
 
@@ -152,12 +210,12 @@ class GridDriftChamber : public Segmentation {
   }
 
   inline double returnAlpha() const {
-    double alpha = 2 * std::asin(m_detectorLength * std::tan(m_epsilon0)/(2 * _currentRadius));
+    double alpha = 2 * std::asin(m_detectorLength * std::tan(m_epsilon)/(2 * _currentRadius));
     return alpha;
  }
 
   double m_cellSize;
-  double m_epsilon0;
+//  double m_epsilon0;
   double m_detectorLength;
   double m_layer_width;
   double m_safe_distance;
diff --git a/Detector/DetSegmentation/src/GridDriftChamber.cpp b/Detector/DetSegmentation/src/GridDriftChamber.cpp
index a4302ebf5..a2d0029c2 100644
--- a/Detector/DetSegmentation/src/GridDriftChamber.cpp
+++ b/Detector/DetSegmentation/src/GridDriftChamber.cpp
@@ -22,7 +22,7 @@ GridDriftChamber::GridDriftChamber(const BitFieldCoder* decoder) : Segmentation(
   _description = "Drift chamber segmentation in the global coordinates";
 
   registerParameter("cell_size", "cell size", m_cellSize, 1., SegmentationParameter::LengthUnit);
-  registerParameter("epsilon0", "epsilon", m_epsilon0, 0., SegmentationParameter::AngleUnit, true);
+//  registerParameter("epsilon0", "epsilon", m_epsilon0, 0., SegmentationParameter::AngleUnit, true);
   registerParameter("detector_length", "Length of the wire", m_detectorLength, 1., SegmentationParameter::LengthUnit);
   registerIdentifier("identifier_phi", "Cell ID identifier for phi", m_phiID, "cellID");
   registerIdentifier("layerID", "layer id", layer_id, "layer");
@@ -48,6 +48,10 @@ CellID GridDriftChamber::cellID(const Vector3D& /*localPosition*/, const Vector3
 
   double posx = globalPosition.X;
   double posy = globalPosition.Y;
+  double posz = globalPosition.Z;
+  Vector3D wire0 = returnPosWire0(posz);
+  double phi_wire0 = phiFromXY(wire0);
+
   double radius = sqrt(posx*posx+posy*posy);
 
   int m_DC_layer_number = floor((m_DC_rend-m_DC_rbegin)/m_layer_width);
@@ -58,7 +62,7 @@ CellID GridDriftChamber::cellID(const Vector3D& /*localPosition*/, const Vector3
       layerid = floor((radius - m_DC_rbegin)/DC_layerdelta);
   } else if ( radius>= (m_DC_rmin-m_safe_distance) && radius < m_DC_rbegin) {
       layerid = 0;
-  } else if ( radius> m_DC_rend && radius <= (m_DC_rmax+m_safe_distance)) {
+  } else if ( radius> m_DC_rend ) {//&& radius <= (m_DC_rmax+m_safe_distance)) {
       layerid = m_DC_layer_number-1;
   }
 
@@ -68,14 +72,30 @@ CellID GridDriftChamber::cellID(const Vector3D& /*localPosition*/, const Vector3
   double offsetphi= m_offset;
   int _lphi;
 
-  if(phi_hit >= offsetphi) {
-    _lphi = (int) ((phi_hit - offsetphi)/ _currentLayerphi);
+  if(phi_hit >= (offsetphi+phi_wire0)) {
+    _lphi = (int) ((phi_hit - offsetphi - phi_wire0)/ _currentLayerphi);
   }
   else {
-    _lphi = (int) ((phi_hit - offsetphi + 2 * M_PI)/ _currentLayerphi);
+    _lphi = (int) ((phi_hit - offsetphi - phi_wire0 + 2 * M_PI)/ _currentLayerphi);
   }
 
   int lphi = _lphi;
+
+std::cout << "#######################################: "
+          << " posx= " << posx
+          << " posy= " << posy
+          << " posz= " << posz
+          << " phi_hit: " << phi_hit
+          << " phi_wire0: " << phi_wire0
+          << " _lphi: " << _lphi
+          <<  " offset : " << m_offset
+          << " offsetphi: " << offsetphi
+          << " layerID: " << layerid
+          << " r: " << _currentRadius
+          << " layerphi: " << _currentLayerphi
+          << std::endl;
+
+
   _decoder->set(cID, layer_id, layerid);
   _decoder->set(cID, m_phiID, lphi);
 
@@ -102,6 +122,17 @@ void GridDriftChamber::cellposition(const CellID& cID, TVector3& Wstart,
   Wend = returnWirePosition(phi_end, 1);
 }
 
+void GridDriftChamber::cellposition2(int chamber,int layer, int cell,
+                                    TVector3& Wstart, TVector3& Wend) const {
+     updateParams(chamber,layer);
+     double phi_start = binToPosition(cell, _currentLayerphi, m_offset);
+     double phi_mid = phi_start + _currentLayerphi/2.;
+     double phi_end = phi_mid + returnAlpha();
+
+     Wstart = returnWirePosition(phi_mid, -1);
+     Wend = returnWirePosition(phi_end, 1);
+}
+
 TVector3 GridDriftChamber::LineLineIntersect(TVector3& p1, TVector3& p2, TVector3& p3, TVector3& p4) const {
 
   TVector3 p13, p43, p21;
@@ -171,6 +202,20 @@ double GridDriftChamber::distanceTrackWire(const CellID& cID, const TVector3& hi
   return DCA;
 }
 
+double GridDriftChamber::distanceTrackWire2(const CellID& cID, const TVector3& hit_pos) const {
+
+    TVector3 Wstart = {0,0,0};
+    TVector3 Wend = {0,0,0};
+    cellposition(cID,Wstart,Wend);
+
+    TVector3 denominator = Wend - Wstart;
+    TVector3  numerator = denominator.Cross(Wstart-hit_pos);
+
+    double DCA = numerator.Mag()/denominator.Mag() ;
+
+    return DCA;
+}
+
 TVector3 GridDriftChamber::distanceClosestApproach(const CellID& cID, const TVector3& hitPos) const {
   // Distance of the closest approach between a single hit (point) and the closest wire
 
@@ -253,6 +298,52 @@ TVector3 GridDriftChamber::IntersectionTrackWire(const CellID& cID, const TVecto
   return intersect;
 }
 
+double GridDriftChamber::Distance(const CellID& cID, const TVector3& pointIn, const TVector3& pointOut, TVector3& hitPosition) const {
+
+ //For two lines r=r1+t1.v1 & r=r2+t2.v2
+  //the closest approach is d=|(r2-r1).(v1 x v2)|/|v1 x v2|
+  //the point where closest approach are
+  //t1=(v1 x v2).[(r2-r1) x v2]/[(v1 x v2).(v1 x v2)]
+  //t2=(v1 x v2).[(r2-r1) x v1]/[(v1 x v2).(v1 x v2)]
+  //if v1 x v2=0 means two lines are parallel
+  //d=|(r2-r1) x v1|/|v1|
+
+  double t1,distance,dInOut,dHitIn,dHitOut;
+  //Get wirepoint @ endplate
+   TVector3 west = {0,0,0};
+   TVector3 east = {0,0,0};
+   cellposition(cID,west,east);
+   TVector3 wireLine=east - west;
+   TVector3 hitLine=pointOut - pointIn;
+
+  TVector3 hitXwire=hitLine.Cross(wireLine);
+  TVector3 wire2hit=east-pointOut;
+  //Hitposition is the position on hit line where closest approach
+  //of two lines, but it may out the area from pointIn to pointOut
+  if(hitXwire.Mag()==0){
+    distance=wireLine.Cross(wire2hit).Mag()/wireLine.Mag();
+    hitPosition=pointIn;
+  }else{
+    t1=hitXwire.Dot(wire2hit.Cross(wireLine))/hitXwire.Mag2();
+    hitPosition=pointOut+t1*hitLine;
+
+    dInOut=(pointOut-pointIn).Mag();
+    dHitIn=(hitPosition-pointIn).Mag();
+    dHitOut=(hitPosition-pointOut).Mag();
+    if(dHitIn<=dInOut && dHitOut<=dInOut){ //Between point in & out
+      distance=fabs(wire2hit.Dot(hitXwire)/hitXwire.Mag());
+    }else if(dHitOut>dHitIn){ // out pointIn
+      distance=wireLine.Cross(pointIn-east).Mag()/wireLine.Mag();
+      hitPosition=pointIn;
+    }else{ // out pointOut
+      distance=wireLine.Cross(pointOut-east).Mag()/wireLine.Mag();
+      hitPosition=pointOut;
+    }
+  }
+
+  return distance;
+}
+
 
 }
 }

From 5b7f124ce93ae92d5a6d6e8ff9cca93ecc445217 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Thu, 28 Oct 2021 14:34:10 +0800
Subject: [PATCH 02/27]  Remove unimportant output information

---
 .../src/driftchamber/DriftChamber_tile.cpp    | 307 ++++++++++++++++++
 .../DetSegmentation/src/GridDriftChamber.cpp  |  15 -
 2 files changed, 307 insertions(+), 15 deletions(-)
 create mode 100644 Detector/DetDriftChamber/src/driftchamber/DriftChamber_tile.cpp

diff --git a/Detector/DetDriftChamber/src/driftchamber/DriftChamber_tile.cpp b/Detector/DetDriftChamber/src/driftchamber/DriftChamber_tile.cpp
new file mode 100644
index 000000000..9fc2da070
--- /dev/null
+++ b/Detector/DetDriftChamber/src/driftchamber/DriftChamber_tile.cpp
@@ -0,0 +1,307 @@
+//====================================================================
+//  Detector description implementation of the Drift Chamber
+//--------------------------------------------------------------------
+//
+//  Author: Tao Lin
+//          Mengyao Liu
+//
+//====================================================================
+
+#include "DD4hep/DetFactoryHelper.h"
+#include "DD4hep/Printout.h"
+#include "XML/Layering.h"
+#include "XML/Utilities.h"
+#include "XML/XMLElements.h"
+#include "DDRec/DetectorData.h"
+#include "DDSegmentation/Segmentation.h"
+#include "DetSegmentation/GridDriftChamber.h"
+
+using namespace dd4hep;
+using namespace dd4hep::detail;
+using namespace dd4hep::rec ;
+
+#define MYDEBUG(x) std::cout << __FILE__ << ":" << __LINE__ << ": " << x << std::endl;
+#define MYDEBUGVAL(x) std::cout << __FILE__ << ":" << __LINE__ << ": " << #x << ": " << x << std::endl;
+
+static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
+        xml_h e,
+        dd4hep::SensitiveDetector sens) {
+    // ------- Lambda functions ---- //
+    auto delta_a_func = [](auto x, auto y) { return 0.5 * ( x + y ); };
+    auto delta_b_func = [](auto x, auto y) { return 2 * std::sqrt((x + y) * (x - y)); };
+    auto epsilon_func = [](auto delta_a, auto L) { return std::atan(delta_a / L); };
+
+    // =======================================================================
+    // Parameter Definition
+    // =======================================================================
+
+    xml_det_t x_det = e;
+
+    xml_coll_t c(x_det,_U(chamber));
+    xml_comp_t x_chamber = c;
+
+    xml_coll_t cc(x_det,_U(side));
+    xml_comp_t x_side = cc;
+
+    std::string det_name = x_det.nameStr();
+    std::string det_type = x_det.typeStr();
+
+    dd4hep::SensitiveDetector sd = sens;
+
+    // - global
+    double chamber_half_length     = theDetector.constant<double>("DC_half_length");
+    double chamber_length     = theDetector.constant<double>("DC_length");
+
+    // - chamber
+    double chamber_radius_min = theDetector.constant<double>("SDT_chamber_radius_min");
+    double chamber_radius_max = theDetector.constant<double>("SDT_chamber_radius_max");
+    double SDT_half_length     = theDetector.constant<double>("SDT_chamber_half_length");
+    int chamberID = x_chamber.id();
+
+    // - layer
+    double chamber_layer_width  = theDetector.constant<double>("SDT_chamber_layer_width");
+    double chamber_cell_width  = theDetector.constant<double>("SDT_chamber_cell_width");
+    double chamber_layer_rbegin = theDetector.constant<double>("DC_chamber_layer_rbegin");
+    double chamber_layer_rend = theDetector.constant<double>("DC_chamber_layer_rend");
+    int chamber_layer_number = floor((chamber_layer_rend-chamber_layer_rbegin)/chamber_layer_width);
+
+    double cellsize = theDetector.constant<double>("SDT_chamber_cell_width");
+
+    double safe_distance = theDetector.constant<double>("DC_safe_distance");
+    double alpha = theDetector.constant<double>("Alpha");
+
+    // =======================================================================
+    // Detector Construction
+    // =======================================================================
+
+    dd4hep::DetElement sdet(det_name, x_det.id());
+
+    Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector,  e , sdet ) ;
+
+    dd4hep::xml::setDetectorTypeFlag( e, sdet ) ;
+
+    if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ;
+
+
+//    dd4hep::Material det_mat(theDetector.material("Air"));
+    dd4hep::Material det_mat(theDetector.material(x_det.materialStr()));
+//    dd4hep::Material chamber_mat(theDetector.material("GasHe_90Isob_10"));
+    dd4hep::Material chamber_mat = theDetector.material(x_chamber.materialStr());
+
+    // - global
+    Assembly det_vol( det_name+"_assembly" ) ;
+
+    // - chamber volume
+    dd4hep::Tube det_chamber_solid(chamber_radius_min, chamber_radius_max, chamber_half_length);
+    dd4hep::Volume det_chamber_vol(det_name+"_chamber_vol", det_chamber_solid, chamber_mat);
+
+    // - wall
+    double chamber_inner_wall_rmin = theDetector.constant<double>("SDT_chamber_inner_wall_radius_min");
+    double chamber_inner_wall_rmax = theDetector.constant<double>("SDT_chamber_inner_wall_radius_max");
+    double chamber_outer_wall_rmin = theDetector.constant<double>("SDT_chamber_outer_wall_radius_min");
+    double chamber_outer_wall_rmax = theDetector.constant<double>("SDT_chamber_outer_wall_radius_max");
+
+//    dd4hep::Material wall_mat(theDetector.material("CarbonFiber"));
+    dd4hep::Material wall_mat(theDetector.material(x_side.materialStr()));
+
+    double wall_rmin[2] = {chamber_inner_wall_rmin, chamber_outer_wall_rmin};
+    double wall_rmax[2] = {chamber_inner_wall_rmax, chamber_outer_wall_rmax};
+
+   // - wire
+    dd4hep::Volume module_vol;
+    dd4hep::Volume Module_vol;
+    for(xml_coll_t c(x_det,_U(module)); c; ++c) {
+      xml_comp_t x_module = c;
+      double  module_rmin = x_module.rmin();
+      double  module_rmax = x_module.rmax();
+      std::string module_name = x_module.nameStr();
+      dd4hep::Tube module_solid(module_rmin,module_rmax,chamber_half_length);
+      if(x_module.id()==0) {
+         module_vol = dd4hep::Volume(module_name,module_solid,det_mat);
+         module_vol.setVisAttributes(theDetector.visAttributes(x_module.visStr()));
+      } else {
+         Module_vol = dd4hep::Volume(module_name,module_solid,det_mat);
+         Module_vol.setVisAttributes(theDetector.visAttributes(x_module.visStr()));
+      }
+
+      for(xml_coll_t l(x_module,_U(tubs)); l; ++l) {
+         xml_comp_t x_tube =l;
+         double tube_rmin = x_tube.rmin();
+         double tube_rmax = x_tube.rmax();
+         std::string tube_name = x_tube.nameStr();
+         std::string wire_name= module_name + tube_name;
+         dd4hep::Material tube_mat = theDetector.material(x_tube.materialStr());
+         dd4hep::Tube wire_solid(tube_rmin,tube_rmax,chamber_half_length);
+         dd4hep::Volume wire_vol(wire_name,wire_solid,tube_mat);
+         dd4hep::Transform3D transform_wire(dd4hep::Rotation3D(),dd4hep::Position(0.,0.,0.));
+         dd4hep::PlacedVolume wire_phy;
+         if(x_module.id()==0) {
+            wire_phy = module_vol.placeVolume(wire_vol,transform_wire);
+         } else {
+            wire_phy = Module_vol.placeVolume(wire_vol,transform_wire);
+         }
+      }
+  }
+
+    // End cap
+    double Endcap_rmin = theDetector.constant<double>("DC_Endcap_rmin");
+    double Endcap_rmax = theDetector.constant<double>("DC_Endcap_rmax");
+    double Endcap_z = theDetector.constant<double>("DC_Endcap_dz");
+    dd4hep::Tube det_Endcap_solid(Endcap_rmin,Endcap_rmax,0.5*Endcap_z);
+    dd4hep::Volume det_Endcap_vol(det_name+"Endcap",det_Endcap_solid,det_mat);
+    det_Endcap_vol.setVisAttributes(theDetector,"YellowVis");
+
+    //Initialize the segmentation
+    dd4hep::Readout readout = sd.readout();
+    dd4hep::Segmentation geomseg = readout.segmentation();
+    dd4hep::Segmentation* _geoSeg = &geomseg;
+
+    auto DCHseg = dynamic_cast<dd4hep::DDSegmentation::GridDriftChamber*>(_geoSeg->segmentation());
+
+    // - layer
+    int chamber_id = 0;
+    int layerIndex = -1;
+    for(int layer_id = 0; layer_id < chamber_layer_number; layer_id++) {
+
+        double rmin,rmax,offset=0;
+
+        double sign_eps = 1;
+
+        dd4hep::Volume* current_vol_ptr = nullptr;
+//        current_vol_ptr = &det_chamber_vol;
+        rmin = chamber_layer_rbegin+(layer_id*chamber_layer_width);
+        rmax = rmin+chamber_layer_width;
+        layerIndex = layer_id;
+
+        //Construction of drift chamber layers
+        double rmid = delta_a_func(rmin,rmax);
+        double Rmid = rmid/std::cos(alpha/2);
+        double ilayer_cir = 2 * M_PI * rmid;
+        double ncell = ilayer_cir / chamber_layer_width;
+        int ncell_layer = floor(ncell);
+        int numWire = ncell_layer;
+        double layer_Phi = 2*M_PI / ncell_layer;
+
+        if(layer_id %2 ==0)
+        {
+             offset = 0.;
+             sign_eps = -1;
+        }
+        else { offset = 0.5 * layer_Phi; }
+
+
+        double epsilon = sign_eps*std::atan(2 * Rmid * std::tan(alpha / 2.0) / chamber_length);
+        double alpha0 = 2*std::asin(chamber_length * std::tan(epsilon)/(2*Rmid));
+
+        DCHseg->setGeomParams(chamber_id, layerIndex, layer_Phi, rmid, epsilon, offset);
+        DCHseg->setWiresInLayer(chamber_id, layerIndex, numWire);
+
+        double r_in_test = rmid*std::cos(alpha / 2.0);
+
+        double r_in0 = rmid - cellsize / 2.0;
+        double r_in = r_in0 / std::cos(alpha / 2.0);
+
+        double r_out0 = rmid + cellsize / 2.0;
+        double r_out = r_out0 / std::cos(alpha / 2.0);
+
+        double delta_a_in = delta_b_func(r_in, r_in0);
+        double delta_a_out = delta_b_func(r_out, r_out0);
+
+        double eps_in = epsilon_func(delta_a_in, chamber_length );
+        double eps_out = epsilon_func(delta_a_out, chamber_length );
+
+//        dd4hep::Tube layer_vol_solid(rmin,rmax,chamber_half_length);
+        dd4hep::Hyperboloid layer_vol_solid(r_in0, eps_in, r_out0, eps_out, chamber_half_length);
+        dd4hep::Volume layer_vol(det_name+"_layer_vol",layer_vol_solid,det_mat);
+        current_vol_ptr = &layer_vol;
+
+        if ( x_det.isSensitive() )   {
+            layer_vol.setRegion(theDetector,x_det.regionStr());
+            layer_vol.setLimitSet(theDetector,x_det.limitsStr());
+            layer_vol.setSensitiveDetector(sens);
+            sd.setType("tracker");
+        }
+
+        // - wire vol
+        //phi <-------------------> -phi
+        //    |   F8    F7   F6   F5|  Only on the outermost layer.
+        //    |                     |
+        //    |         S         F4|
+        //    |                     |
+        //    |   F0    F1   F2   F3|
+        //    -----------------------
+        for(int icell=0; icell< numWire; icell++) {
+            double wire_phi = (icell+0.5)*layer_Phi + offset;
+
+            // - signal wire
+            dd4hep::RotationZ rz(wire_phi);
+            dd4hep::RotationY ry(epsilon);
+            dd4hep::Position tr3D = Position(rmid*std::cos(0.5*M_PI+wire_phi),rmid*std::sin(0.5*M_PI+wire_phi),0.);
+            dd4hep::Transform3D transform_signal_wire(rz*ry,tr3D);
+
+            dd4hep::PlacedVolume module_phy = (*current_vol_ptr).placeVolume(module_vol,transform_signal_wire);
+           // - Field wire
+            dd4hep::PlacedVolume Module_phy;
+            double radius[5] = {rmid-chamber_layer_width*0.5+safe_distance,rmid-chamber_layer_width*0.5+safe_distance,rmid,rmid+chamber_layer_width*0.5-safe_distance,rmid+chamber_layer_width*0.5-safe_distance};
+            double phi[5] = {wire_phi,wire_phi-layer_Phi*0.5,wire_phi-layer_Phi*0.5,wire_phi-layer_Phi*0.5,wire_phi};
+            int num = 3;
+            if(layer_id==(chamber_layer_number-1)) {
+               num = 5;
+            }
+            for(int i=0; i<num ; i++) {
+                dd4hep::RotationZ rz_field(phi[i]);
+                dd4hep::RotationY ry_field(epsilon);
+                dd4hep::Position tr3D_field = Position(radius[i]*std::cos(0.5*M_PI+phi[i]),radius[i]*std::sin(0.5*M_PI+phi[i]),0.);
+                dd4hep::Transform3D transform_field_wire(rz_field*ry_field,tr3D_field);
+
+                Module_phy = (*current_vol_ptr).placeVolume(Module_vol,transform_field_wire);
+            }
+        }
+        dd4hep::Transform3D transform_layer(dd4hep::Rotation3D(),
+                dd4hep::Position(0,0,0));
+        dd4hep::PlacedVolume layer_phy = det_chamber_vol.placeVolume(layer_vol,transform_layer);
+        layer_phy.addPhysVolID("layer", layer_id);
+    }
+
+    // - place in det
+    // - chamber
+    dd4hep::Transform3D transform_chamber(dd4hep::Rotation3D(),
+            dd4hep::Position(0,0,0));
+    dd4hep::PlacedVolume det_chamber_phy = det_vol.placeVolume(det_chamber_vol,
+                 transform_chamber);
+
+    det_chamber_phy.addPhysVolID("chamber", chamberID);
+
+    // - place in world
+    dd4hep::Transform3D transform(dd4hep::Rotation3D(),
+            dd4hep::Position(0,0,0));
+    dd4hep::PlacedVolume phv = envelope.placeVolume(det_vol,transform);
+    // - place wall
+    dd4hep::PlacedVolume wall_phy;
+    for(int i=0; i<2; i++) {
+       dd4hep::Tube wall_solid(wall_rmin[i],wall_rmax[i],chamber_half_length);
+       dd4hep::Volume wall_vol(det_name+"_wall_vol",wall_solid,wall_mat);
+       wall_vol.setVisAttributes(theDetector,"VisibleGreen");
+       wall_phy = envelope.placeVolume(wall_vol,transform);
+    }
+
+    // - place Endcap
+    double endcap_pos[2] = {chamber_half_length+Endcap_z*0.5,-chamber_half_length-Endcap_z*0.5};
+    dd4hep::PlacedVolume endcap_phy;
+    for(int i=0; i<2; i++) {
+        dd4hep::Transform3D Endcap_transform(dd4hep::Rotation3D(),dd4hep::Position(0,0,endcap_pos[i]));
+        endcap_phy = envelope.placeVolume(det_Endcap_vol,Endcap_transform);
+   }
+
+    if ( x_det.hasAttr(_U(id)) )  {
+        phv.addPhysVolID("system",x_det.id());
+    }
+    DetElement assDE( sdet , det_name+"_assembly" , x_det.id() )  ;
+    assDE.setPlacement(phv);
+
+    MYDEBUG("Build Detector Drift Chamber successfully.");
+    return sdet;
+
+}
+
+DECLARE_DETELEMENT(DriftChamber_tile, create_detector);
diff --git a/Detector/DetSegmentation/src/GridDriftChamber.cpp b/Detector/DetSegmentation/src/GridDriftChamber.cpp
index a2d0029c2..b602315ba 100644
--- a/Detector/DetSegmentation/src/GridDriftChamber.cpp
+++ b/Detector/DetSegmentation/src/GridDriftChamber.cpp
@@ -81,21 +81,6 @@ CellID GridDriftChamber::cellID(const Vector3D& /*localPosition*/, const Vector3
 
   int lphi = _lphi;
 
-std::cout << "#######################################: "
-          << " posx= " << posx
-          << " posy= " << posy
-          << " posz= " << posz
-          << " phi_hit: " << phi_hit
-          << " phi_wire0: " << phi_wire0
-          << " _lphi: " << _lphi
-          <<  " offset : " << m_offset
-          << " offsetphi: " << offsetphi
-          << " layerID: " << layerid
-          << " r: " << _currentRadius
-          << " layerphi: " << _currentLayerphi
-          << std::endl;
-
-
   _decoder->set(cID, layer_id, layerid);
   _decoder->set(cID, m_phiID, lphi);
 

From 6a46894c2a312996122f8674fcc9dd55352b996d Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Thu, 28 Oct 2021 14:59:17 +0800
Subject: [PATCH 03/27] Slanted version of the XML file

---
 .../compact/det_inclined_wire.xml             | 129 ++++++++++++++++++
 1 file changed, 129 insertions(+)
 create mode 100644 Detector/DetDriftChamber/compact/det_inclined_wire.xml

diff --git a/Detector/DetDriftChamber/compact/det_inclined_wire.xml b/Detector/DetDriftChamber/compact/det_inclined_wire.xml
new file mode 100644
index 000000000..b3cbfd81c
--- /dev/null
+++ b/Detector/DetDriftChamber/compact/det_inclined_wire.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lccdd>
+
+  <info name="DriftChamber"
+    title="Test with Drift Chamber"
+    author="Tao Lin"
+    url="http://github.com/cepc/CEPCSW"
+    status="development"
+    version="v0">
+    <comment>Test with Drift Chamber</comment>
+  </info>
+
+  <includes>
+    <gdmlFile  ref="elements.xml"/>
+    <gdmlFile  ref="materials.xml"/>
+  </includes>
+
+  <define>
+    <constant name="world_size" value="2990*mm"/>
+    <constant name="world_x" value="world_size"/>
+    <constant name="world_y" value="world_size"/>
+    <constant name="world_z" value="world_size"/>
+
+    <!-- SDT -->
+    <constant name="DetID_DC"  value="7"/>
+
+    <constant name="DC_safe_distance" value="0.02*mm"/>
+
+    <constant name="SDT_inner_wall_thickness" value="0.2*mm"/>
+    <constant name="SDT_outer_wall_thickness" value="2.8*mm"/>
+
+    <constant name="DC_chamber_layer_rbegin" value="800*mm"/>
+    <constant name="DC_chamber_layer_rend" value="1800*mm"/>
+
+    <constant name="DC_chamber_safe_distance" value="10*mm"/>
+
+    <constant name="SDT_radius_min" value="DC_chamber_layer_rbegin-SDT_inner_wall_thickness-DC_safe_distance"/>
+    <constant name="SDT_radius_max" value="DC_chamber_layer_rend+DC_chamber_safe_distance+SDT_outer_wall_thickness+DC_safe_distance"/>
+
+    <constant name="DC_Endcap_dz" value="0.1*mm"/>
+
+    <constant name="SDT_half_length" value="2980*mm+DC_Endcap_dz+DC_safe_distance"/>
+    <constant name="DC_half_length" value="2980*mm"/>
+    <constant name="SDT_length" value="SDT_half_length*2"/>
+    <constant name="DC_length" value="SDT_length-DC_Endcap_dz*2"/>
+
+    <constant name="SDT_chamber_radius_min" value="DC_chamber_layer_rbegin-DC_safe_distance"/>
+    <constant name="SDT_chamber_radius_max" value="DC_chamber_layer_rend+DC_chamber_safe_distance+DC_safe_distance"/>
+    <constant name="SDT_chamber_half_length" value="DC_half_length"/>
+
+    <constant name="SDT_chamber_layer_width" value="10*mm"/>
+    <constant name="SDT_chamber_cell_width" value="10*mm"/>
+    <constant name="Alpha" value="12*deg"/>
+
+    <constant name="SDT_chamber_inner_wall_radius_min" value="SDT_chamber_radius_min-SDT_inner_wall_thickness"/>
+    <constant name="SDT_chamber_inner_wall_radius_max" value="SDT_chamber_radius_min"/>
+    <constant name="SDT_chamber_outer_wall_radius_min" value="SDT_chamber_radius_max"/>
+    <constant name="SDT_chamber_outer_wall_radius_max" value="SDT_chamber_radius_max+SDT_outer_wall_thickness"/>
+
+    <constant name="DC_Endcap_rmin" value="SDT_radius_min"/>
+    <constant name="DC_Endcap_rmax" value="SDT_radius_max"/>
+
+  </define>
+
+  <display>
+    <vis name="Invisible" showDaughters="false" visible="false"/>
+    <vis name="InvisibleWithChildren" showDaughters="true" visible="false"/>
+    <vis name="VisibleRed"  r="1.0" g="0.0" b="0.0" showDaughters="true" visible="true"/>
+    <vis name="VisibleBlue" r="0.0" g="0.0" b="1.0" showDaughters="true" visible="true"/>
+    <vis name="VisibleGreen" alpha="1.0" r="0.0" g="1.0" b="0.0" drawingStyle="solid" lineStyle="solid" showDaughters="true" visible="true"/>
+    <vis name="YellowVis" alpha="1.0" r="1.0" g="1.0"  b="0.0"   showDaughters="true"  visible="true"/>
+  </display>
+
+  <limits>
+    <limitset name="DC_limits">
+      <limit name="step_length_max" particles="*" value="0.5" unit="mm" />
+    </limitset>
+  </limits>
+
+  <regions>
+    <region name="DriftChamberRegion">
+    </region>
+  </regions>
+
+  <detectors>
+    <detector id="DetID_DC" name="DriftChamber_tile" type="DriftChamber_tile" readout="DriftChamberHitsCollection" vis="VisibleBlue" sensitive="true" region="DriftChamberRegion" limits="DC_limits">
+      <material name="Air"/>
+      <chamber id="0"  material="GasHe_90Isob_10"/>
+      <side material="CarbonFiber"/>
+      <envelope vis="SeeThrough">
+        <shape type="BooleanShape" operation="Union" material="Air">
+          <shape type="Tube" rmin="SDT_radius_min" rmax="SDT_radius_max" dz="SDT_half_length" />
+        </shape>
+      </envelope>
+
+      <module id="0" name="SignalWire" type="Tube" rmin="0*mm" rmax="0.01*mm" vis="VisibleRed">
+          <tubs name="W" type="Tube" rmin="0*mm" rmax="0.007*mm" material="Tungsten"/>
+          <tubs name="Au" type="Tube" rmin="0.007*mm" rmax="0.01*mm" material="Gold"/>
+      </module>
+
+      <module id="1" name="FieldWire" type="Tube" rmin="0*mm" rmax="0.02*mm" vis="VisibleGreen">
+          <tubs name="Al" type="Tube" rmin="0*mm" rmax="0.017*mm" material="Aluminum"/>
+          <tubs name="Ag" type="Tube" rmin="0.017*mm" rmax="0.02*mm" material="Silver"/>
+      </module>
+
+      <type_flags type="DetType_TRACKER + DetType_BARREL + DetType_GASEOUS + DetType_WIRE"/>
+      <!-- Use cm as unit if you want to use Pandora for reconstruction -->
+     <sensitive type="SimpleDriftChamber"/>
+     </detector>
+  </detectors>
+
+  <readouts>
+    <readout name="DriftChamberHitsCollection">
+      <segmentation type="GridDriftChamber" cell_size="SDT_chamber_cell_width" detector_length="DC_length" identifier_phi="cellID" DC_rbegin="DC_chamber_layer_rbegin" DC_rend="DC_chamber_layer_rend" DC_rmin="SDT_chamber_radius_min" DC_rmax="SDT_chamber_radius_max" safe_distance="DC_safe_distance" layerID="layer" layer_width="SDT_chamber_layer_width"/>
+
+
+      <id>system:5,layer:7:9,chamber:8,cellID:32:16</id>
+    </readout>
+  </readouts>
+
+  <fields>
+
+    <field name="MagnetFields_Constant" type="ConstantField" field="magnetic">
+      <strength x="0" y="0" z="3.0*tesla"/>
+    </field>
+
+  </fields>
+
+</lccdd>

From 7ce14446b3d8923896a6dbe26977dc5aadfddba3 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Thu, 28 Oct 2021 15:02:49 +0800
Subject: [PATCH 04/27] The diagonal wire version of the drift chamber in SDT

---
 .../CRD_common_v01/DC_Simple_v01_03.xml       | 88 +++++++++++++++++++
 1 file changed, 88 insertions(+)
 create mode 100644 Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_03.xml

diff --git a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_03.xml b/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_03.xml
new file mode 100644
index 000000000..801ad541c
--- /dev/null
+++ b/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_03.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lccdd>
+
+  <info name="DriftChamber"
+    title="Test with Drift Chamber"
+    author="Tao Lin"
+    url="http://github.com/cepc/CEPCSW"
+    status="development"
+    version="v0">
+    <comment>Test with Drift Chamber</comment>
+  </info>
+
+  <define>
+
+    <!-- SDT -->
+    <constant name="SDT_radius_min" value="DC_inner_radius"/>
+    <constant name="SDT_radius_max" value="DC_outer_radius"/>
+
+    <constant name="SDT_half_length" value="MainTracker_half_length"/>
+    <constant name="DC_length" value="DC_half_length*2"/>
+    <constant name="SDT_length" value="SDT_half_length*2"/>
+
+    <constant name="SDT_chamber_radius_min" value="DC_chamber_layer_rbegin-DC_safe_distance"/>
+    <constant name="SDT_chamber_radius_max" value="DC_chamber_layer_rend+DC_chamber_safe_distance+DC_safe_distance"/>
+    <constant name="SDT_chamber_half_length" value="DC_half_length"/>
+
+    <constant name="SDT_chamber_layer_width" value="10*mm"/>
+    <constant name="SDT_chamber_cell_width" value="10*mm"/>
+    <constant name="Alpha" value="12*deg"/>
+
+    <constant name="SDT_chamber_inner_wall_radius_min" value="SDT_chamber_radius_min-SDT_inner_wall_thickness"/>
+    <constant name="SDT_chamber_inner_wall_radius_max" value="SDT_chamber_radius_min"/>
+    <constant name="SDT_chamber_outer_wall_radius_min" value="SDT_chamber_radius_max"/>
+    <constant name="SDT_chamber_outer_wall_radius_max" value="SDT_chamber_radius_max+SDT_outer_wall_thickness"/>
+
+    <constant name="DC_Endcap_rmin" value="SDT_radius_min"/>
+    <constant name="DC_Endcap_rmax" value="SDT_radius_max"/>
+
+  </define>
+
+  <limits>
+    <limitset name="DC_limits">
+      <limit name="step_length_max" particles="*" value="0.1" unit="mm" />
+    </limitset>
+  </limits>
+
+  <regions>
+    <region name="DriftChamberRegion">
+    </region>
+  </regions>
+
+  <detectors>
+    <detector id="DetID_DC" name="DriftChamber_tile" type="DriftChamber_tile" readout="DriftChamberHitsCollection" vis="DCVis" sensitive="true" region="DriftChamberRegion" limits="DC_limits">
+      <material name="Air"/>
+      <chamber id="0" material="GasHe_90Isob_10"/>
+      <side material="CarbonFiber"/>
+      <envelope vis="SeeThrough">
+        <shape type="BooleanShape" operation="Union" material="Air">
+          <shape type="Tube" rmin="SDT_radius_min" rmax="SDT_radius_max" dz="SDT_half_length" />
+        </shape>
+      </envelope>
+
+      <module id="0" name="SignalWire" type="Tube" rmin="0*mm" rmax="0.01*mm" vis="RedVis">
+          <tubs name="W" type="Tube" rmin="0*mm" rmax="0.007*mm" material="Tungsten"/>
+          <tubs name="Au" type="Tube" rmin="0.007*mm" rmax="0.01*mm" material="Gold"/>
+      </module>
+
+      <module id="1" name="FieldWire" type="Tube" rmin="0*mm" rmax="0.02*mm" vis="GreenVis">
+          <tubs name="Al" type="Tube" rmin="0*mm" rmax="0.017*mm" material="Aluminum"/>
+          <tubs name="Ag" type="Tube" rmin="0.017*mm" rmax="0.02*mm" material="Silver"/>
+      </module>
+
+      <type_flags type="DetType_TRACKER + DetType_BARREL + DetType_GASEOUS + DetType_WIRE"/>
+      <!-- Use cm as unit if you want to use Pandora for reconstruction -->
+     <sensitive type="SimpleDriftChamber"/>
+     </detector>
+  </detectors>
+
+  <readouts>
+    <readout name="DriftChamberHitsCollection">
+      <segmentation type="GridDriftChamber" cell_size="SDT_chamber_cell_width" detector_length="DC_length" identifier_phi="cellID" DC_rbegin="DC_chamber_layer_rbegin" DC_rend="DC_chamber_layer_rend" DC_rmin="SDT_chamber_radius_min" DC_rmax="SDT_chamber_radius_max" safe_distance="DC_safe_distance" layerID="layer" layer_width="SDT_chamber_layer_width"/>
+
+
+      <id>system:5,layer:7:9,chamber:8,cellID:32:16</id>
+    </readout>
+  </readouts>
+
+</lccdd>

From bee3359587d8adf09f70ca22b5a7616bb6bdc3d8 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Sun, 31 Oct 2021 21:51:50 +0800
Subject: [PATCH 05/27] Modify the name of the DC's xml file

---
 .../{DC_Simple_v01_03.xml => DC_Stero_v01_01.xml}              | 3 ++-
 .../{DC_Simple_v01_01.xml => DC_Straight_v01_01.xml}           | 0
 .../{DC_Simple_v01_02.xml => DC_Straight_v01_02.xml}           | 0
 Detector/DetDriftChamber/CMakeLists.txt                        | 2 +-
 .../compact/{det_inclined_wire.xml => det_stero.xml}           | 2 +-
 .../{DriftChamber_tile.cpp => DriftChamber_stero.cpp}          | 2 +-
 6 files changed, 5 insertions(+), 4 deletions(-)
 rename Detector/DetCRD/compact/CRD_common_v01/{DC_Simple_v01_03.xml => DC_Stero_v01_01.xml} (93%)
 rename Detector/DetCRD/compact/CRD_common_v01/{DC_Simple_v01_01.xml => DC_Straight_v01_01.xml} (100%)
 rename Detector/DetCRD/compact/CRD_common_v01/{DC_Simple_v01_02.xml => DC_Straight_v01_02.xml} (100%)
 rename Detector/DetDriftChamber/compact/{det_inclined_wire.xml => det_stero.xml} (96%)
 rename Detector/DetDriftChamber/src/driftchamber/{DriftChamber_tile.cpp => DriftChamber_stero.cpp} (99%)

diff --git a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_03.xml b/Detector/DetCRD/compact/CRD_common_v01/DC_Stero_v01_01.xml
similarity index 93%
rename from Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_03.xml
rename to Detector/DetCRD/compact/CRD_common_v01/DC_Stero_v01_01.xml
index 801ad541c..fe303a521 100644
--- a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_03.xml
+++ b/Detector/DetCRD/compact/CRD_common_v01/DC_Stero_v01_01.xml
@@ -46,11 +46,12 @@
 
   <regions>
     <region name="DriftChamberRegion">
+      <limitsetref name="DC_limits"/>
     </region>
   </regions>
 
   <detectors>
-    <detector id="DetID_DC" name="DriftChamber_tile" type="DriftChamber_tile" readout="DriftChamberHitsCollection" vis="DCVis" sensitive="true" region="DriftChamberRegion" limits="DC_limits">
+    <detector id="DetID_DC" name="DriftChamber_Stero" type="DriftChamber_Stero" readout="DriftChamberHitsCollection" vis="DCVis" sensitive="true" insideTrackingVolume="true" limits="DC_limits">
       <material name="Air"/>
       <chamber id="0" material="GasHe_90Isob_10"/>
       <side material="CarbonFiber"/>
diff --git a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_01.xml b/Detector/DetCRD/compact/CRD_common_v01/DC_Straight_v01_01.xml
similarity index 100%
rename from Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_01.xml
rename to Detector/DetCRD/compact/CRD_common_v01/DC_Straight_v01_01.xml
diff --git a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_02.xml b/Detector/DetCRD/compact/CRD_common_v01/DC_Straight_v01_02.xml
similarity index 100%
rename from Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_02.xml
rename to Detector/DetCRD/compact/CRD_common_v01/DC_Straight_v01_02.xml
diff --git a/Detector/DetDriftChamber/CMakeLists.txt b/Detector/DetDriftChamber/CMakeLists.txt
index 7321b5e64..70a29ad77 100644
--- a/Detector/DetDriftChamber/CMakeLists.txt
+++ b/Detector/DetDriftChamber/CMakeLists.txt
@@ -16,7 +16,7 @@ find_package(ROOT COMPONENTS MathCore GenVector Geom REQUIRED)
 
 gaudi_add_module(DetDriftChamber
                  SOURCES src/driftchamber/DriftChamber.cpp
-                 SOURCES src/driftchamber/DriftChamber_tile.cpp
+                 SOURCES src/driftchamber/DriftChamber_stero.cpp
 		 LINK DetSegmentation
                       ${DD4hep_COMPONENT_LIBRARIES} 
                   # ROOT Geant4
diff --git a/Detector/DetDriftChamber/compact/det_inclined_wire.xml b/Detector/DetDriftChamber/compact/det_stero.xml
similarity index 96%
rename from Detector/DetDriftChamber/compact/det_inclined_wire.xml
rename to Detector/DetDriftChamber/compact/det_stero.xml
index b3cbfd81c..44e919087 100644
--- a/Detector/DetDriftChamber/compact/det_inclined_wire.xml
+++ b/Detector/DetDriftChamber/compact/det_stero.xml
@@ -83,7 +83,7 @@
   </regions>
 
   <detectors>
-    <detector id="DetID_DC" name="DriftChamber_tile" type="DriftChamber_tile" readout="DriftChamberHitsCollection" vis="VisibleBlue" sensitive="true" region="DriftChamberRegion" limits="DC_limits">
+    <detector id="DetID_DC" name="DriftChamber_Stero" type="DriftChamber_Stero" readout="DriftChamberHitsCollection" vis="VisibleBlue" sensitive="true" region="DriftChamberRegion" limits="DC_limits">
       <material name="Air"/>
       <chamber id="0"  material="GasHe_90Isob_10"/>
       <side material="CarbonFiber"/>
diff --git a/Detector/DetDriftChamber/src/driftchamber/DriftChamber_tile.cpp b/Detector/DetDriftChamber/src/driftchamber/DriftChamber_stero.cpp
similarity index 99%
rename from Detector/DetDriftChamber/src/driftchamber/DriftChamber_tile.cpp
rename to Detector/DetDriftChamber/src/driftchamber/DriftChamber_stero.cpp
index 9fc2da070..0b9061a9f 100644
--- a/Detector/DetDriftChamber/src/driftchamber/DriftChamber_tile.cpp
+++ b/Detector/DetDriftChamber/src/driftchamber/DriftChamber_stero.cpp
@@ -304,4 +304,4 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
 
 }
 
-DECLARE_DETELEMENT(DriftChamber_tile, create_detector);
+DECLARE_DETELEMENT(DriftChamber_Stero, create_detector);

From a466721423eacea00555bc75f53df7e6ee4f76c6 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Sun, 31 Oct 2021 22:49:55 +0800
Subject: [PATCH 06/27] Add a layer of protection to variables

---
 Digitisers/DCHDigi/src/DCHDigiAlg.cpp | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
index 4a68a1eaa..f9384dd89 100644
--- a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
+++ b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
@@ -92,7 +92,10 @@ StatusCode DCHDigiAlg::execute()
   m_start = clock();
 
   info() << "Processing " << _nEvt << " events " << endmsg;
-  m_evt = _nEvt;
+  if(m_WriteAna && (nullptr!=m_tuple))
+  {
+      m_evt = _nEvt;
+  }
   edm4hep::TrackerHitCollection* Vec   = w_DigiDCHCol.createAndPut();
   edm4hep::MCRecoTrackerAssociationCollection* AssoVec   = w_AssociationCol.createAndPut();
   const edm4hep::SimTrackerHitCollection* SimHitCol =  r_SimDCHCol.get();
@@ -227,15 +230,15 @@ StatusCode DCHDigiAlg::execute()
   debug()<<"output digi DCHhit size="<< Vec->size() <<endmsg;
   _nEvt ++ ;
 
+  m_end = clock();
   if(m_WriteAna && (nullptr!=m_tuple)){
+      m_time = (m_end - m_start);
       StatusCode status = m_tuple->write();
       if ( status.isFailure() ) {
         error() << "    Cannot fill N-tuple:" << long( m_tuple ) << endmsg;
         return StatusCode::FAILURE;
       }
   }
-  m_end = clock();
-  m_time = (m_end - m_start);
 
   return StatusCode::SUCCESS;
 }

From b0baa330d0d242501d7a71a329561c9aaae8d804 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Wed, 23 Feb 2022 22:38:06 +0800
Subject: [PATCH 07/27] fix simulation issues

---
 .../CRD_common_v01/DC_Simple_v01_05.xml       |  79 ++++
 .../CRD_o1_v01/CRD_Dimensions_v01_01.xml      |  19 +-
 .../CRD_o1_v02/CRD_Dimensions_v01_02.xml      |  19 +-
 Detector/DetDriftChamber/compact/det.xml      |  59 ++-
 .../src/driftchamber/DriftChamber.cpp         | 292 +++++++------
 .../DetSegmentation/GridDriftChamber.h        |  72 +---
 .../DetSegmentation/src/GridDriftChamber.cpp  | 398 +++++++++---------
 Digitisers/DCHDigi/src/DCHDigiAlg.cpp         |  77 ++--
 Digitisers/DCHDigi/src/DCHDigiAlg.h           |  16 +-
 9 files changed, 547 insertions(+), 484 deletions(-)
 create mode 100644 Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_05.xml

diff --git a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_05.xml b/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_05.xml
new file mode 100644
index 000000000..6c05c4fa0
--- /dev/null
+++ b/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_05.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lccdd>
+
+  <info name="DriftChamber"
+    title="Test with Drift Chamber"
+    author="Tao Lin"
+    url="http://github.com/cepc/CEPCSW"
+    status="development"
+    version="v0">
+    <comment>Test with Drift Chamber</comment>
+  </info>
+
+  <define>
+
+    <constant name="DC_layer_number" value="100"/>
+    <constant name="Alpha" value="12*deg"/>
+    <constant name="Gas_radius_min" value="DC_rbegin+DC_inner_wall_thickness+DC_safe_distance"/>
+    <constant name="Gas_half_length" value="DC_half_length-DC_Endcap_dz-DC_safe_distance"/>
+    <constant name="Gas_length" value="Gas_half_length*2"/>
+    <constant name="DC_cell_width" value="10*mm"/>
+    <constant name="DC_inner_wall_radius_min" value="DC_rbegin"/>
+    <constant name="DC_inner_wall_radius_max" value="DC_rbegin+DC_inner_wall_thickness"/>
+    <constant name="DC_Endcap_rmin" value="DC_rbegin"/>
+    <constant name="DC_Endcap_rmax" value="DC_rend"/>
+
+    <constant name="DC_construct_wire" value="0"/>
+
+    <constant name="DC_layer_width" value="9.57687*mm"/>
+
+  </define>
+
+  <limits>
+    <limitset name="DC_limits">
+      <limit name="step_length_max" particles="*" value="0.1" unit="mm" />
+    </limitset>
+  </limits>
+
+  <regions>
+    <region name="DriftChamberRegion">
+    </region>
+  </regions>
+
+  <detectors>
+    <detector id="DetID_DC" name="DriftChamber" type="DriftChamber" readout="DriftChamberHitsCollection" vis="DCVis" sensitive="true" limits="DC_limits">
+      <material name="Air"/>
+      <chamber id="0" material="GasHe_90Isob_10"/>
+      <side material="CarbonFiber"/>
+      <envelope vis="SeeThrough">
+        <shape type="BooleanShape" operation="Union" material="Air">
+          <shape type="Tube" rmin="DC_rbegin" rmax="DC_rend" dz="DC_half_length" />
+        </shape>
+      </envelope>
+
+      <module id="0" name="SignalWire" type="Tube" rmin="0*mm" rmax="0.01*mm" vis="RedVis">
+          <tubs name="W" type="Tube" rmin="0*mm" rmax="0.007*mm" material="Tungsten"/>
+          <tubs name="Au" type="Tube" rmin="0.007*mm" rmax="0.01*mm" material="Gold"/>
+      </module>
+
+      <module id="1" name="FieldWire" type="Tube" rmin="0*mm" rmax="0.02*mm" vis="GreenVis">
+          <tubs name="Al" type="Tube" rmin="0*mm" rmax="0.017*mm" material="Aluminum"/>
+          <tubs name="Ag" type="Tube" rmin="0.017*mm" rmax="0.02*mm" material="Silver"/>
+      </module>
+
+      <type_flags type="DetType_TRACKER + DetType_BARREL + DetType_GASEOUS + DetType_WIRE"/>
+      <!-- Use cm as unit if you want to use Pandora for reconstruction -->
+     <sensitive type="SimpleDriftChamber"/>
+     </detector>
+  </detectors>
+
+  <readouts>
+    <readout name="DriftChamberHitsCollection">
+      <segmentation type="GridDriftChamber" cell_size="DC_cell_width" detector_length="Gas_length" identifier_phi="cellID" layerID="layer" DC_rbegin="DC_rbegin" DC_rend="DC_rend" layer_width="DC_layer_width"/>
+
+
+      <id>system:5,layer:7:9,chamber:8,cellID:32:16</id>
+    </readout>
+  </readouts>
+
+</lccdd>
diff --git a/Detector/DetCRD/compact/CRD_o1_v01/CRD_Dimensions_v01_01.xml b/Detector/DetCRD/compact/CRD_o1_v01/CRD_Dimensions_v01_01.xml
index 46959ebbe..5c0950c2a 100644
--- a/Detector/DetCRD/compact/CRD_o1_v01/CRD_Dimensions_v01_01.xml
+++ b/Detector/DetCRD/compact/CRD_o1_v01/CRD_Dimensions_v01_01.xml
@@ -83,12 +83,16 @@
     <constant name="Vertex_outer_radius" value="101*mm"/>
     <constant name="Vertex_half_length"  value="200*mm"/>
 
+    <!-- Parameters of single drift chamber  -->
+    <constant name="DC_rbegin" value="800*mm"/>
+    <constant name="DC_rend" value="1800*mm"/>
+
     <constant name="DC_Endcap_dz" value="0.1*mm"/>
     <constant name="DC_half_length"  value="2980*mm" />
     <constant name="DC_safe_distance" value="0.02*mm"/>
-    <constant name="SDT_inner_wall_thickness" value="0.2*mm"/>
-    <constant name="SDT_outer_wall_thickness" value="2.8*mm"/>
-    <constant name="MainTracker_half_length"  value="DC_half_length+DC_Endcap_dz" />
+    <constant name="DC_inner_wall_thickness" value="0.2*mm"/>
+    <constant name="DC_outer_wall_thickness" value="2.8*mm"/>
+    <constant name="MainTracker_half_length"  value="DC_half_length"/>
 
     <!--obselete for single drift chamber-->
     <constant name="InnerTracker_half_length"  value="DC_half_length" />
@@ -98,15 +102,6 @@
     <constant name="OuterTracker_inner_radius" value="1082.18*mm"/>
     <constant name="OuterTracker_outer_radius" value="1723*mm"/>
 
-    <!-- Parameters of single drift chamber  -->
-    <constant name="DC_chamber_layer_rbegin" value="800*mm"/>
-    <constant name="DC_chamber_layer_rend" value="1800*mm"/>
-
-    <constant name="DC_chamber_safe_distance" value="10*mm"/>
-
-    <constant name="DC_inner_radius" value="DC_chamber_layer_rbegin-SDT_inner_wall_thickness-DC_safe_distance"/>
-    <constant name="DC_outer_radius" value="DC_chamber_layer_rend+DC_chamber_safe_distance+SDT_outer_wall_thickness+DC_safe_distance"/>
-
     <constant name="SIT1_inner_radius"   value="230*mm"/>
     <constant name="SIT2_inner_radius"   value="410*mm"/>
     <constant name="SIT3_inner_radius"   value="590*mm"/>
diff --git a/Detector/DetCRD/compact/CRD_o1_v02/CRD_Dimensions_v01_02.xml b/Detector/DetCRD/compact/CRD_o1_v02/CRD_Dimensions_v01_02.xml
index 46959ebbe..5c0950c2a 100644
--- a/Detector/DetCRD/compact/CRD_o1_v02/CRD_Dimensions_v01_02.xml
+++ b/Detector/DetCRD/compact/CRD_o1_v02/CRD_Dimensions_v01_02.xml
@@ -83,12 +83,16 @@
     <constant name="Vertex_outer_radius" value="101*mm"/>
     <constant name="Vertex_half_length"  value="200*mm"/>
 
+    <!-- Parameters of single drift chamber  -->
+    <constant name="DC_rbegin" value="800*mm"/>
+    <constant name="DC_rend" value="1800*mm"/>
+
     <constant name="DC_Endcap_dz" value="0.1*mm"/>
     <constant name="DC_half_length"  value="2980*mm" />
     <constant name="DC_safe_distance" value="0.02*mm"/>
-    <constant name="SDT_inner_wall_thickness" value="0.2*mm"/>
-    <constant name="SDT_outer_wall_thickness" value="2.8*mm"/>
-    <constant name="MainTracker_half_length"  value="DC_half_length+DC_Endcap_dz" />
+    <constant name="DC_inner_wall_thickness" value="0.2*mm"/>
+    <constant name="DC_outer_wall_thickness" value="2.8*mm"/>
+    <constant name="MainTracker_half_length"  value="DC_half_length"/>
 
     <!--obselete for single drift chamber-->
     <constant name="InnerTracker_half_length"  value="DC_half_length" />
@@ -98,15 +102,6 @@
     <constant name="OuterTracker_inner_radius" value="1082.18*mm"/>
     <constant name="OuterTracker_outer_radius" value="1723*mm"/>
 
-    <!-- Parameters of single drift chamber  -->
-    <constant name="DC_chamber_layer_rbegin" value="800*mm"/>
-    <constant name="DC_chamber_layer_rend" value="1800*mm"/>
-
-    <constant name="DC_chamber_safe_distance" value="10*mm"/>
-
-    <constant name="DC_inner_radius" value="DC_chamber_layer_rbegin-SDT_inner_wall_thickness-DC_safe_distance"/>
-    <constant name="DC_outer_radius" value="DC_chamber_layer_rend+DC_chamber_safe_distance+SDT_outer_wall_thickness+DC_safe_distance"/>
-
     <constant name="SIT1_inner_radius"   value="230*mm"/>
     <constant name="SIT2_inner_radius"   value="410*mm"/>
     <constant name="SIT3_inner_radius"   value="590*mm"/>
diff --git a/Detector/DetDriftChamber/compact/det.xml b/Detector/DetDriftChamber/compact/det.xml
index 08b29c928..3c86627d3 100644
--- a/Detector/DetDriftChamber/compact/det.xml
+++ b/Detector/DetDriftChamber/compact/det.xml
@@ -1,15 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<lccdd xmlns:compact="http://www.lcsim.org/schemas/compact/1.0"
-       xmlns:xs="http://www.w3.org/2001/XMLSchema"
-       xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/compact/1.0/compact.xsd">
+<lccdd>
 
   <info name="DriftChamber"
-    title="Test with Drift Chamber"
+    title="Drift Chamber"
     author="Tao Lin"
     url="http://github.com/cepc/CEPCSW"
     status="development"
-    version="v0">
-    <comment>Test with Drift Chamber</comment>
+    version="v2">
+    <comment>Drift Chamber</comment>
   </info>
 
   <includes>
@@ -17,7 +15,6 @@
     <gdmlFile  ref="materials.xml"/>
   </includes>
 
-
   <define>
     <constant name="world_size" value="2990*mm"/>
     <constant name="world_x" value="world_size"/>
@@ -25,41 +22,39 @@
     <constant name="world_z" value="world_size"/>
 
     <!-- SDT -->
-    <constant name="DetID_DC"  value="7"/>
+    <constant name="DetID_DC"  value="4"/>
 
     <constant name="DC_safe_distance" value="0.02*mm"/>
 
-    <constant name="SDT_inner_wall_thickness" value="0.2*mm"/>
-    <constant name="SDT_outer_wall_thickness" value="2.8*mm"/>
+    <constant name="DC_inner_wall_thickness" value="0.2*mm"/>
+    <constant name="DC_outer_wall_thickness" value="2.8*mm"/>
+
+    <constant name="DC_rbegin" value="800*mm"/>
+    <constant name="DC_rend" value="1800*mm"/>
 
-    <constant name="DC_chamber_layer_rbegin" value="800*mm"/>
-    <constant name="DC_chamber_layer_rend" value="1800*mm"/>
+    <constant name="DC_layer_number" value="100"/>
+    <constant name="Alpha" value="0*deg"/>
 
-    <constant name="SDT_radius_min" value="DC_chamber_layer_rbegin-SDT_inner_wall_thickness-DC_safe_distance"/>
-    <constant name="SDT_radius_max" value="DC_chamber_layer_rend+SDT_outer_wall_thickness+DC_safe_distance"/>
+    <constant name="Gas_radius_min" value="DC_rbegin+DC_inner_wall_thickness+DC_safe_distance"/>
 
     <constant name="DC_Endcap_dz" value="0.1*mm"/>
 
-    <constant name="SDT_half_length" value="2980*mm+DC_Endcap_dz"/>
     <constant name="DC_half_length" value="2980*mm"/>
-    <constant name="SDT_length" value="SDT_half_length*2"/>
-    <constant name="DC_length" value="SDT_length-DC_Endcap_dz*2"/>
 
-    <constant name="SDT_chamber_radius_min" value="DC_chamber_layer_rbegin-DC_safe_distance"/>
-    <constant name="SDT_chamber_radius_max" value="DC_chamber_layer_rend+DC_safe_distance"/>
-    <constant name="SDT_chamber_half_length" value="DC_half_length"/>
+    <constant name="Gas_half_length" value="DC_half_length-DC_Endcap_dz-DC_safe_distance"/>
+    <constant name="Gas_length" value="Gas_half_length*2"/>
 
-    <constant name="SDT_chamber_layer_width" value="10*mm"/>
-    <constant name="SDT_chamber_cell_width" value="10*mm"/>
-    <constant name="Alpha" value="0*deg"/>
+    <constant name="DC_cell_width" value="10*mm"/>
+
+    <constant name="DC_inner_wall_radius_min" value="DC_rbegin"/>
+    <constant name="DC_inner_wall_radius_max" value="DC_rbegin+DC_inner_wall_thickness"/>
+
+    <constant name="DC_Endcap_rmin" value="DC_rbegin"/>
+    <constant name="DC_Endcap_rmax" value="DC_rend"/>
 
-    <constant name="SDT_chamber_inner_wall_radius_min" value="SDT_chamber_radius_min-SDT_inner_wall_thickness"/>
-    <constant name="SDT_chamber_inner_wall_radius_max" value="SDT_chamber_radius_min"/>
-    <constant name="SDT_chamber_outer_wall_radius_min" value="SDT_chamber_radius_max"/>
-    <constant name="SDT_chamber_outer_wall_radius_max" value="SDT_chamber_radius_max+SDT_outer_wall_thickness"/>
+    <constant name="DC_layer_width" value="9.57687*mm"/>
+    <constant name="DC_construct_wire" value="0"/>
 
-    <constant name="DC_Endcap_rmin" value="SDT_radius_min"/>
-    <constant name="DC_Endcap_rmax" value="SDT_radius_max"/>
 
   </define>
 
@@ -84,13 +79,13 @@
   </regions>
 
   <detectors>
-    <detector id="DetID_DC" name="DriftChamber" type="DriftChamber" readout="DriftChamberHitsCollection" vis="VisibleBlue" sensitive="true" region="DriftChamberRegion" limits="DC_limits">
+    <detector id="DetID_DC" name="DriftChamber" type="DriftChamber" readout="DriftChamberHitsCollection" vis="VisibleBlue" sensitive="true" limits="DC_limits">
       <material name="Air"/>
       <chamber id="0"  material="GasHe_90Isob_10"/>
       <side material="CarbonFiber"/>
       <envelope vis="SeeThrough">
         <shape type="BooleanShape" operation="Union" material="Air">
-          <shape type="Tube" rmin="SDT_radius_min" rmax="SDT_radius_max" dz="SDT_half_length" />
+          <shape type="Tube" rmin="DC_rbegin" rmax="DC_rend" dz="DC_half_length" />
         </shape>
       </envelope>
 
@@ -112,7 +107,7 @@
 
   <readouts>
     <readout name="DriftChamberHitsCollection">
-      <segmentation type="GridDriftChamber" cell_size="SDT_chamber_cell_width" detector_length="DC_length" identifier_phi="cellID" DC_rbegin="DC_chamber_layer_rbegin" DC_rend="DC_chamber_layer_rend" DC_rmin="SDT_chamber_radius_min" DC_rmax="SDT_chamber_radius_max" safe_distance="DC_safe_distance" layerID="layer" layer_width="SDT_chamber_layer_width"/>
+      <segmentation type="GridDriftChamber" cell_size="DC_cell_width" detector_length="Gas_length" identifier_phi="cellID" layerID="layer" DC_rbegin="DC_rbegin" DC_rend="DC_rend" layer_width="DC_layer_width"/>
 
 
       <id>system:5,layer:7:9,chamber:8,cellID:32:16</id>
diff --git a/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp b/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
index 02732bf5d..67b36859b 100644
--- a/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
+++ b/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
@@ -1,12 +1,3 @@
-//====================================================================
-//  Detector description implementation of the Drift Chamber
-//--------------------------------------------------------------------
-//
-//  Author: Tao Lin
-//          Mengyao Liu
-//
-//====================================================================
-
 #include "DD4hep/DetFactoryHelper.h"
 #include "DD4hep/Printout.h"
 #include "XML/Layering.h"
@@ -16,6 +7,9 @@
 #include "DDSegmentation/Segmentation.h"
 #include "DetSegmentation/GridDriftChamber.h"
 
+#include <iostream>
+#include <chrono>
+
 using namespace dd4hep;
 using namespace dd4hep::detail;
 using namespace dd4hep::rec ;
@@ -27,12 +21,15 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
         xml_h e,
         dd4hep::SensitiveDetector sens) {
     // ------- Lambda functions ---- //
-    auto delta_a_func = [](auto x, auto y) { return 0.5 * ( x + y ); };
+    auto delta_b_func = [](auto x, auto y) { return 2 * std::sqrt((x + y) * (x - y)); };
+    auto epsilon_func = [](auto delta_a, auto L) { return std::atan(delta_a / L); };
 
     // =======================================================================
     // Parameter Definition
     // =======================================================================
 
+    auto start = std::chrono::steady_clock::now();
+
     xml_det_t x_det = e;
 
     xml_coll_t c(x_det,_U(chamber));
@@ -47,24 +44,34 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
     dd4hep::SensitiveDetector sd = sens;
 
     // - global
-    double chamber_half_length     = theDetector.constant<double>("DC_half_length");
-    double chamber_length  = theDetector.constant<double>("DC_length");
+    double chamber_half_length = theDetector.constant<double>("Gas_half_length");
+    double chamber_length = chamber_half_length*2;
 
-    // - chamber
-    double chamber_radius_min = theDetector.constant<double>("SDT_chamber_radius_min");
-    double chamber_radius_max = theDetector.constant<double>("SDT_chamber_radius_max");
-    double SDT_half_length     = theDetector.constant<double>("SDT_chamber_half_length");
+    double alpha = theDetector.constant<double>("Alpha");
+    double Pi = 0;
+    if(0!=alpha) Pi = 0.5*M_PI;
+
+    double safe_distance = theDetector.constant<double>("DC_safe_distance");
+
+    double DC_inner_wall_thickness = theDetector.constant<double>("DC_inner_wall_thickness");
+    double DC_outer_wall_thickness = theDetector.constant<double>("DC_outer_wall_thickness");
+
+    // - chamber gas
+    double DC_rend = theDetector.constant<double>("DC_rend");
+
+    double chamber_radius_min = theDetector.constant<double>("Gas_radius_min");
+    double chamber_radius_max = DC_rend-safe_distance-DC_outer_wall_thickness;
+    double layer_radius_max = chamber_radius_max*std::cos(alpha);
     int chamberID = x_chamber.id();
 
     // - layer
-    double chamber_layer_width  = theDetector.constant<double>("SDT_chamber_layer_width");
-    double chamber_cell_width  = theDetector.constant<double>("SDT_chamber_cell_width");
-    double chamber_layer_rbegin = theDetector.constant<double>("DC_chamber_layer_rbegin");
-    double chamber_layer_rend = theDetector.constant<double>("DC_chamber_layer_rend");
-    int chamber_layer_number = floor((chamber_layer_rend-chamber_layer_rbegin)/chamber_layer_width);
+    int DC_layer_number = theDetector.constant<int>("DC_layer_number");
 
-    double safe_distance = theDetector.constant<double>("DC_safe_distance");
-    double alpha = theDetector.constant<double>("Alpha");
+    double layer_width = (layer_radius_max-chamber_radius_min)/DC_layer_number;
+
+    double cell_width = theDetector.constant<double>("DC_cell_width");
+
+    int DC_construct_wire = theDetector.constant<int>("DC_construct_wire");
 
     // =======================================================================
     // Detector Construction
@@ -78,112 +85,113 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
 
     if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ;
 
-
-//    dd4hep::Material det_mat(theDetector.material("Air"));
     dd4hep::Material det_mat(theDetector.material(x_det.materialStr()));
-//    dd4hep::Material chamber_mat(theDetector.material("GasHe_90Isob_10"));
     dd4hep::Material chamber_mat = theDetector.material(x_chamber.materialStr());
 
-    // - global
+    /// - global
     Assembly det_vol( det_name+"_assembly" ) ;
 
-    // - chamber volume
+    /// - chamber volume
     dd4hep::Tube det_chamber_solid(chamber_radius_min, chamber_radius_max, chamber_half_length);
     dd4hep::Volume det_chamber_vol(det_name+"_chamber_vol", det_chamber_solid, chamber_mat);
 
-    // - wall
-    double chamber_inner_wall_rmin = theDetector.constant<double>("SDT_chamber_inner_wall_radius_min");
-    double chamber_inner_wall_rmax = theDetector.constant<double>("SDT_chamber_inner_wall_radius_max");
-    double chamber_outer_wall_rmin = theDetector.constant<double>("SDT_chamber_outer_wall_radius_min");
-    double chamber_outer_wall_rmax = theDetector.constant<double>("SDT_chamber_outer_wall_radius_max");
+    /// - wall
+    double chamber_inner_wall_rmin = theDetector.constant<double>("DC_inner_wall_radius_min");
+    double chamber_inner_wall_rmax = theDetector.constant<double>("DC_inner_wall_radius_max");
+    double chamber_outer_wall_rmin = chamber_radius_max+safe_distance;
+    double chamber_outer_wall_rmax = chamber_outer_wall_rmin+DC_outer_wall_thickness;
 
-//    dd4hep::Material wall_mat(theDetector.material("CarbonFiber"));
     dd4hep::Material wall_mat(theDetector.material(x_side.materialStr()));
 
     double wall_rmin[2] = {chamber_inner_wall_rmin, chamber_outer_wall_rmin};
     double wall_rmax[2] = {chamber_inner_wall_rmax, chamber_outer_wall_rmax};
 
-   // - wire
-    dd4hep::Volume module_vol;
-    dd4hep::Volume Module_vol;
-    for(xml_coll_t c(x_det,_U(module)); c; ++c) {
-      xml_comp_t x_module = c;
-      double  module_rmin = x_module.rmin();
-      double  module_rmax = x_module.rmax();
-      std::string module_name = x_module.nameStr();
-      dd4hep::Tube module_solid(module_rmin,module_rmax,chamber_half_length);
-      if(x_module.id()==0) {
-         module_vol = dd4hep::Volume(module_name,module_solid,det_mat);
-         module_vol.setVisAttributes(theDetector.visAttributes(x_module.visStr()));
-      } else {
-         Module_vol = dd4hep::Volume(module_name,module_solid,det_mat);
-         Module_vol.setVisAttributes(theDetector.visAttributes(x_module.visStr()));
-      }
-
-      for(xml_coll_t l(x_module,_U(tubs)); l; ++l) {
-         xml_comp_t x_tube =l;
-         double tube_rmin = x_tube.rmin();
-         double tube_rmax = x_tube.rmax();
-         std::string tube_name = x_tube.nameStr();
-         std::string wire_name= module_name + tube_name;
-         dd4hep::Material tube_mat = theDetector.material(x_tube.materialStr());
-         dd4hep::Tube wire_solid(tube_rmin,tube_rmax,chamber_half_length);
-         dd4hep::Volume wire_vol(wire_name,wire_solid,tube_mat);
-         dd4hep::Transform3D transform_wire(dd4hep::Rotation3D(),dd4hep::Position(0.,0.,0.));
-         dd4hep::PlacedVolume wire_phy;
-         if(x_module.id()==0) {
-            wire_phy = module_vol.placeVolume(wire_vol,transform_wire);
-         } else {
-            wire_phy = Module_vol.placeVolume(wire_vol,transform_wire);
-         }
-      }
-  }
-
-    // End cap
-    double Endcap_rmin = theDetector.constant<double>("DC_Endcap_rmin");
-    double Endcap_rmax = theDetector.constant<double>("DC_Endcap_rmax");
-    double Endcap_z = theDetector.constant<double>("DC_Endcap_dz");
-    dd4hep::Tube det_Endcap_solid(Endcap_rmin,Endcap_rmax,0.5*Endcap_z);
+    /// - construct wires
+    dd4hep::Volume signalWireVolume;
+    dd4hep::Volume fieldWireVolume;
+    for(xml_coll_t dcModule(x_det,_U(module)); dcModule; ++dcModule) {
+        xml_comp_t x_module = dcModule;
+        std::string module_name = x_module.nameStr();
+        dd4hep::Tube module_solid(x_module.rmin(),x_module.rmax(),chamber_half_length);
+        if(0==x_module.id()) {
+            signalWireVolume = dd4hep::Volume(module_name,module_solid,det_mat);
+            signalWireVolume.setVisAttributes(theDetector.visAttributes(x_module.visStr()));
+        } else {
+            fieldWireVolume = dd4hep::Volume(module_name,module_solid,det_mat);
+            fieldWireVolume.setVisAttributes(theDetector.visAttributes(x_module.visStr()));
+        }
+
+        /// construct wire tubes
+        for(xml_coll_t l(x_module,_U(tubs)); l; ++l) {
+            xml_comp_t x_tube =l;
+            std::string wire_name= module_name + x_tube.nameStr();
+            dd4hep::Material tube_mat = theDetector.material(x_tube.materialStr());
+            dd4hep::Tube wire_solid(x_tube.rmin(),x_tube.rmax(),chamber_half_length);
+            dd4hep::Volume wire_vol(wire_name,wire_solid,tube_mat);
+            dd4hep::Transform3D transform_wire(dd4hep::Rotation3D(),dd4hep::Position(0.,0.,0.));
+            if(0==x_module.id()) {
+                signalWireVolume.placeVolume(wire_vol,transform_wire);
+            } else {
+                fieldWireVolume.placeVolume(wire_vol,transform_wire);
+            }
+        }//end of construct tubes
+    }//end of construct wire
+
+    /// construct End cap
+    double endcap_rmin = theDetector.constant<double>("DC_Endcap_rmin");
+    double endcap_rmax = theDetector.constant<double>("DC_Endcap_rmax");
+    double endcap_z = theDetector.constant<double>("DC_Endcap_dz");
+    dd4hep::Tube det_Endcap_solid(endcap_rmin,endcap_rmax,0.5*endcap_z);
     dd4hep::Volume det_Endcap_vol(det_name+"Endcap",det_Endcap_solid,det_mat);
     det_Endcap_vol.setVisAttributes(theDetector,"YellowVis");
 
-    //Initialize the segmentation
-    dd4hep::Readout readout = sd.readout();
-    dd4hep::Segmentation geomseg = readout.segmentation();
-    dd4hep::Segmentation* _geoSeg = &geomseg;
-
-    auto DCHseg = dynamic_cast<dd4hep::DDSegmentation::GridDriftChamber*>(_geoSeg->segmentation());
+    ///Initialize the segmentation
+    auto segmentationDC =
+        dynamic_cast<dd4hep::DDSegmentation::GridDriftChamber*>
+        (sd.readout().segmentation().segmentation());
 
-    // - layer
+    /// - construct layers
     int chamber_id = 0;
-    int layerIndex = -1;
-    for(int layer_id = 0; layer_id < chamber_layer_number; layer_id++) {
-        double rmin,rmax,offset=0;
+    for(int layer_id = 0; layer_id < DC_layer_number; layer_id++) {
         dd4hep::Volume* current_vol_ptr = nullptr;
-//        current_vol_ptr = &det_chamber_vol;
-        rmin = chamber_layer_rbegin+(layer_id*chamber_layer_width);
-        rmax = rmin+chamber_layer_width;
-        layerIndex = layer_id;
+        double layer_rmin = chamber_radius_min+(layer_id*layer_width);
+        double layer_rmax = layer_rmin+layer_width;
+        double rmid_zZero = (layer_rmin+layer_rmax)/2.;  // z=0
+        double rmid_zEnd = rmid_zZero/std::cos(alpha/2);  //  z=endcap
+        int nCell = floor((2. * M_PI * rmid_zZero) / layer_width);
+        int nWire = nCell;
+        if(!DC_construct_wire) nWire =0;
+        double cell_phi = 2*M_PI / nCell;
+        double offset=0;//phi offset of first cell in each layer
+        double sign_eps = 1;// setero angle sign
+        if(0==(layer_id%2)) {
+            offset = 0.;
+            sign_eps = -1;
+        } else {
+            offset = 0.5 * cell_phi;
+        }
+        double epsilon = sign_eps*std::atan(rmid_zZero * std::tan(alpha / 2.0) / chamber_half_length);
+        //double alpha0 = 2*std::asin(chamber_length * std::tan(epsilon)/(2*rmid_zEnd));
 
-        //Construction of drift chamber layers
-        double rmid = delta_a_func(rmin,rmax);
-        double Rmid = rmid/std::cos(alpha/2);
-        double ilayer_cir = 2 * M_PI * rmid;
-        double ncell = ilayer_cir / chamber_layer_width;
-        int ncell_layer = floor(ncell);
-        int numWire = ncell_layer;
-        double layer_Phi = 2*M_PI / ncell_layer;
+        segmentationDC->setGeomParams(chamber_id, layer_id, cell_phi, rmid_zEnd , epsilon, offset);
+        segmentationDC->setWiresInLayer(chamber_id, layer_id, nCell);
 
-        if(layer_id %2 ==0){ offset = 0.; }
-        else { offset = 0.5 * layer_Phi; }
+        double r_in_test = rmid_zZero*std::cos(alpha / 2.0);
 
-        double epsilon = 0;
+        double r_in0 = rmid_zZero - layer_width / 2.0;//
+        double r_in = r_in0 / std::cos(alpha / 2.0);//layer min at z=half length
 
-        DCHseg->setGeomParams(chamber_id, layerIndex, layer_Phi, rmid, epsilon, offset);
-        DCHseg->setWiresInLayer(chamber_id, layerIndex, numWire);
+        double r_out0 = rmid_zZero + layer_width / 2.0;
+        double r_out = r_out0 / std::cos(alpha / 2.0);
 
+        double delta_a_in = delta_b_func(r_in, r_in0);
+        double delta_a_out = delta_b_func(r_out, r_out0);
 
-        dd4hep::Tube layer_vol_solid(rmin,rmax,chamber_half_length);
+        double eps_in = epsilon_func(delta_a_in, chamber_length );
+        double eps_out = epsilon_func(delta_a_out, chamber_length );
+
+        /// create hyper layer volume
+        dd4hep::Hyperboloid layer_vol_solid(r_in0, eps_in, r_out0, eps_out, chamber_half_length);
         dd4hep::Volume layer_vol(det_name+"_layer_vol",layer_vol_solid,det_mat);
         current_vol_ptr = &layer_vol;
 
@@ -194,46 +202,56 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
             sd.setType("tracker");
         }
 
-        // - wire vol
-        //phi <-------------------> -phi
-        //    |   F8    F7   F6   F5|  Only on the outermost layer.
-        //    |                     |
-        //    |         S         F4|
-        //    |                     |
-        //    |   F0    F1   F2   F3|
-        //    -----------------------
-        for(int icell=0; icell< numWire; icell++) {
-            double wire_phi = (icell+0.5)*layer_Phi + offset;
+        // - create wire volume
+        //phi <---------------> -phi
+        //    |    F4     F3|  Only on the outermost layer.
+        //    |             |
+        //    |    S      F2|
+        //    |             |
+        //    |    F0     F1|
+        //--------------------
+        // loop over cells
+        for(int icell=0; icell<nWire; icell++) {
+
+            double wire_phi = icell*cell_phi + offset;
+
             // - signal wire
-            dd4hep::Transform3D transform_module(dd4hep::Rotation3D(),dd4hep::Position(rmid*std::cos(wire_phi),rmid*std::sin(wire_phi),0.));
-            dd4hep::PlacedVolume module_phy = (*current_vol_ptr).placeVolume(module_vol,transform_module);
-           // - Field wire
-            dd4hep::PlacedVolume Module_phy;
-            double radius[9] = {rmid-chamber_layer_width*0.5+safe_distance,rmid-chamber_layer_width*0.5+safe_distance,rmid-chamber_layer_width*0.5+safe_distance,rmid-chamber_layer_width*0.5+safe_distance,rmid,rmid+chamber_layer_width*0.5-safe_distance,rmid+chamber_layer_width*0.5-safe_distance,rmid+chamber_layer_width*0.5-safe_distance,rmid+chamber_layer_width*0.5-safe_distance};
-            double phi[9] = {wire_phi+layer_Phi*0.25,wire_phi,wire_phi-layer_Phi*0.25,wire_phi-layer_Phi*0.5,wire_phi-layer_Phi*0.5,wire_phi-layer_Phi*0.5,wire_phi-layer_Phi*0.25,wire_phi,wire_phi+layer_Phi*0.25};
-            int num = 5;
-            if(layer_id==(chamber_layer_number-1)) {
-               num = 9;
+            dd4hep::RotationZ rz(wire_phi+Pi);
+            dd4hep::RotationY ry(epsilon);
+            dd4hep::Position tr3D = Position(rmid_zZero*std::cos(wire_phi),rmid_zZero*std::sin(wire_phi),0.);
+            dd4hep::Transform3D transform_signal_wire(rz*ry,tr3D);
+
+            (*current_vol_ptr).placeVolume(signalWireVolume,transform_signal_wire);
+            // - Field wire
+            double radius[5] = {rmid_zZero-layer_width*0.5+safe_distance,rmid_zZero-layer_width*0.5+safe_distance,rmid_zZero,rmid_zZero+layer_width*0.5-safe_distance,rmid_zZero+layer_width*0.5-safe_distance};
+            double phi[5] = {wire_phi,wire_phi-cell_phi*0.5,wire_phi-cell_phi*0.5,wire_phi-cell_phi*0.5,wire_phi};
+            int num = 3;
+            if(layer_id==(DC_layer_number-1)) {
+                num = 5;
             }
             for(int i=0; i<num ; i++) {
-                dd4hep::Position tr3D = Position(radius[i]*std::cos(phi[i]),radius[i]*std::sin(phi[i]),0.);
+                dd4hep::RotationZ rz_field(phi[i]+Pi);
+                dd4hep::RotationY ry_field(epsilon);
+                dd4hep::Position tr3D_field = Position(radius[i]*std::cos(phi[i]),radius[i]*std::sin(phi[i]),0.);
+
+                dd4hep::Transform3D transform_field_wire(rz_field*ry_field,tr3D_field);
 
-                dd4hep::Transform3D transform_Module(dd4hep::Rotation3D(),tr3D);
-                Module_phy = (*current_vol_ptr).placeVolume(Module_vol,transform_Module);
+                (*current_vol_ptr).placeVolume(fieldWireVolume,transform_field_wire);
             }
-        }
+        }//end of loop over cell
         dd4hep::Transform3D transform_layer(dd4hep::Rotation3D(),
                 dd4hep::Position(0,0,0));
-        dd4hep::PlacedVolume layer_phy = det_chamber_vol.placeVolume(layer_vol    ,transform_layer);
+        dd4hep::PlacedVolume layer_phy = det_chamber_vol.placeVolume(layer_vol,transform_layer);
         layer_phy.addPhysVolID("layer", layer_id);
-    }
+    }//end of loop over layers
+
 
     // - place in det
     // - chamber
     dd4hep::Transform3D transform_chamber(dd4hep::Rotation3D(),
             dd4hep::Position(0,0,0));
     dd4hep::PlacedVolume det_chamber_phy = det_vol.placeVolume(det_chamber_vol,
-                 transform_chamber);
+            transform_chamber);
 
     det_chamber_phy.addPhysVolID("chamber", chamberID);
 
@@ -244,19 +262,19 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
     // - place wall
     dd4hep::PlacedVolume wall_phy;
     for(int i=0; i<2; i++) {
-       dd4hep::Tube wall_solid(wall_rmin[i],wall_rmax[i],chamber_half_length);
-       dd4hep::Volume wall_vol(det_name+"_wall_vol",wall_solid,wall_mat);
-       wall_vol.setVisAttributes(theDetector,"VisibleGreen");
-       wall_phy = envelope.placeVolume(wall_vol,transform);
+        dd4hep::Tube wall_solid(wall_rmin[i],wall_rmax[i],chamber_half_length);
+        dd4hep::Volume wall_vol(det_name+"_wall_vol",wall_solid,wall_mat);
+        wall_vol.setVisAttributes(theDetector,"VisibleGreen");
+        wall_phy = envelope.placeVolume(wall_vol,transform);
     }
 
     // - place Endcap
-    double endcap_pos[2] = {chamber_half_length+Endcap_z*0.5,-chamber_half_length-Endcap_z*0.5};
+    double endcap_pos[2] = {chamber_half_length+endcap_z*0.5,-chamber_half_length-endcap_z*0.5};
     dd4hep::PlacedVolume endcap_phy;
     for(int i=0; i<2; i++) {
         dd4hep::Transform3D Endcap_transform(dd4hep::Rotation3D(),dd4hep::Position(0,0,endcap_pos[i]));
         endcap_phy = envelope.placeVolume(det_Endcap_vol,Endcap_transform);
-   }
+    }
 
     if ( x_det.hasAttr(_U(id)) )  {
         phv.addPhysVolID("system",x_det.id());
@@ -264,7 +282,11 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
     DetElement assDE( sdet , det_name+"_assembly" , x_det.id() )  ;
     assDE.setPlacement(phv);
 
+
     MYDEBUG("Build Detector Drift Chamber successfully.");
+    auto end = std::chrono::steady_clock::now();
+    std::chrono::duration<double> elapsed_seconds = end-start;
+    std::cout << "elapsed time: " << elapsed_seconds.count() << "s\n"; 
     return sdet;
 
 }
diff --git a/Detector/DetSegmentation/include/DetSegmentation/GridDriftChamber.h b/Detector/DetSegmentation/include/DetSegmentation/GridDriftChamber.h
index ad9d03604..911a6f4cb 100644
--- a/Detector/DetSegmentation/include/DetSegmentation/GridDriftChamber.h
+++ b/Detector/DetSegmentation/include/DetSegmentation/GridDriftChamber.h
@@ -64,22 +64,21 @@ class GridDriftChamber : public Segmentation {
   virtual void cellposition(const CellID& cID, TVector3& Wstart, TVector3& Wend) const;
   virtual void cellposition2(int chamber, int layer, int cell, TVector3& Wstart, TVector3& Wend) const;
   TVector3 LineLineIntersect(TVector3& p1, TVector3& p2, TVector3& p3, TVector3& p4) const;
-  virtual TVector3 distanceClosestApproach(const CellID& cID, const TVector3& hitPos) const;
+  virtual TVector3 distanceClosestApproach(const CellID& cID, const TVector3& hitPos, TVector3& PCA) const;
   virtual TVector3 Line_TrackWire(const CellID& cID, const TVector3& hit_start, const TVector3& hit_end) const;
   virtual TVector3 IntersectionTrackWire(const CellID& cID, const TVector3& hit_start, const TVector3& hit_end) const;
   virtual TVector3 wirePos_vs_z(const CellID& cID, const double& zpos) const;
-  virtual double Distance(const CellID& cID, const TVector3& pointIn, const TVector3& pointOut, TVector3& hitPosition) const;
+  virtual double Distance(const CellID& cID, const TVector3& pointIn, const TVector3& pointOut, TVector3& hitPosition, TVector3& PCA) const;
+  virtual TVector3 returnPhi0(int chamber,int layer, double z) const;
+
 
 //  double phi(const CellID& cID) const;
   inline double cell_Size() const { return m_cellSize; }
   inline double epsilon() const { return m_epsilon; }
   inline double detectorLength() const { return m_detectorLength; }
-  inline double safe_distance() const { return m_safe_distance; }
   inline double layer_width() const { return m_layer_width; }
   inline double DC_rbegin() const { return m_DC_rbegin; }
   inline double DC_rend() const { return m_DC_rend; }
-  inline double DC_rmax() const { return m_DC_rmax; }
-  inline double DC_rmin() const { return m_DC_rmin; }
   inline const std::string& fieldNamePhi() const { return m_phiID; }
   inline const std::string& Layerid() const { return layer_id; }
 
@@ -91,7 +90,13 @@ class GridDriftChamber : public Segmentation {
     return hit_phi;
   }
 
-  inline void setGeomParams(int chamberID, int layerID, double layerphi, double R, double eps, double offset) {
+ inline double phiFromXY2(const TVector3& aposition) const {
+    double hit_phi =  std::atan2(aposition.Y(), aposition.X()) ;
+    if( hit_phi < 0 ) { hit_phi += 2 * M_PI; }
+    return hit_phi;
+  }
+
+ inline void setGeomParams(int chamberID, int layerID, double layerphi, double R, double eps, double offset) {
 
     layer_params.insert(std::pair<vID,LAYER>(vID(chamberID,layerID),LAYER(layerphi,R,eps,offset)));
 
@@ -117,52 +122,6 @@ class GridDriftChamber : public Segmentation {
 
   inline auto returnAllWires() const { return m_wiresPositions; }
 
-//  TVector3 LineLineIntersect(TVector3 p1, TVector3 p2, TVector3 p3, TVector3 p4) const {
-//    TVector3 p13, p43, p21;
-//    double d1343, d4321, d1321, d4343, d2121;
-//    double numer, denom;
-//    double mua, mub;
-//    TVector3 pa, pb;
-//
-//    p13.SetX(p1.X() - p3.X());
-//    p13.SetY(p1.Y() - p3.Y());
-//    p13.SetZ(p1.Z() - p3.Z());
-//    p43.SetX(p4.X() - p3.X());
-//    p43.SetY(p4.Y() - p3.Y());
-//    p43.SetZ(p4.Z() - p3.Z());
-//    /* if (ABS(p43.X())  < EPS && ABS(p43.Y())  < EPS && ABS(p43.Z())  < EPS) */
-//    /*    return(FALSE); */
-//    p21.SetX(p2.X() - p1.X());
-//    p21.SetY(p2.Y() - p1.Y());
-//    p21.SetZ(p2.Z() - p1.Z());
-//    /* if (ABS(p21.X())  < EPS && ABS(p21.Y())  < EPS && ABS(p21.Z())  < EPS) */
-//    /*    return(FALSE); */
-//
-//    d1343 = p13.X() * p43.X() + p13.Y() * p43.Y() + p13.Z() * p43.Z();
-//    d4321 = p43.X() * p21.X() + p43.Y() * p21.Y() + p43.Z() * p21.Z();
-//    d1321 = p13.X() * p21.X() + p13.Y() * p21.Y() + p13.Z() * p21.Z();
-//    d4343 = p43.X() * p43.X() + p43.Y() * p43.Y() + p43.Z() * p43.Z();
-//    d2121 = p21.X() * p21.X() + p21.Y() * p21.Y() + p21.Z() * p21.Z();
-//
-//    denom = d2121 * d4343 - d4321 * d4321;
-//    /* if (ABS(denom) < EPS) */
-//    /*    return(FALSE); */
-//    numer = d1343 * d4321 - d1321 * d4343;
-//
-//    mua = numer / denom;
-//    mub = (d1343 + d4321 * (mua)) / d4343;
-//
-//    pa.SetX(p1.X() + mua * p21.X());
-//    pa.SetY(p1.Y() + mua * p21.Y());
-//    pa.SetZ(p1.Z() + mua * p21.Z());
-//    pb.SetX(p3.X() + mub * p43.X());
-//    pb.SetY(p3.Y() + mub * p43.Y());
-//    pb.SetZ(p3.Z() + mub * p43.Z());
-//
-//    return pb - pa;
-//  }
-
-
   void updateParams(int chamber, int layer)  const{
     auto it_end = layer_params.cend();
     --it_end;
@@ -184,8 +143,9 @@ class GridDriftChamber : public Segmentation {
     _currentRadius = Radius;
     m_epsilon = Eps;
     m_offset = Offset;
- }
-   inline Vector3D returnPosWire0(double z) const {
+  }
+
+  inline Vector3D returnPosWire0(double z) const {
     double alpha = returnAlpha();
     double t = 0.5 * (1 - 2.0 * z / m_detectorLength);
     double x = _currentRadius * (1 + t * (std::cos(alpha) - 1));
@@ -195,6 +155,7 @@ class GridDriftChamber : public Segmentation {
     return vec;
   }
 
+
 protected:
 
   double phi(const CellID& cID) const;
@@ -218,11 +179,8 @@ class GridDriftChamber : public Segmentation {
 //  double m_epsilon0;
   double m_detectorLength;
   double m_layer_width;
-  double m_safe_distance;
   double m_DC_rbegin;
   double m_DC_rend;
-  double m_DC_rmax;
-  double m_DC_rmin;
 
   std::string m_phiID;
   std::string layer_id;
diff --git a/Detector/DetSegmentation/src/GridDriftChamber.cpp b/Detector/DetSegmentation/src/GridDriftChamber.cpp
index b602315ba..b6cc05850 100644
--- a/Detector/DetSegmentation/src/GridDriftChamber.cpp
+++ b/Detector/DetSegmentation/src/GridDriftChamber.cpp
@@ -22,16 +22,12 @@ GridDriftChamber::GridDriftChamber(const BitFieldCoder* decoder) : Segmentation(
   _description = "Drift chamber segmentation in the global coordinates";
 
   registerParameter("cell_size", "cell size", m_cellSize, 1., SegmentationParameter::LengthUnit);
-//  registerParameter("epsilon0", "epsilon", m_epsilon0, 0., SegmentationParameter::AngleUnit, true);
   registerParameter("detector_length", "Length of the wire", m_detectorLength, 1., SegmentationParameter::LengthUnit);
   registerIdentifier("identifier_phi", "Cell ID identifier for phi", m_phiID, "cellID");
   registerIdentifier("layerID", "layer id", layer_id, "layer");
-  registerParameter("safe_distance", "safe_distance", m_safe_distance, 0., SegmentationParameter::LengthUnit);
   registerParameter("layer_width", "layer_width", m_layer_width, 0., SegmentationParameter::LengthUnit);
   registerParameter("DC_rbegin", "DC_rbegin", m_DC_rbegin, 0., SegmentationParameter::LengthUnit);
   registerParameter("DC_rend", "DC_rend", m_DC_rend, 0., SegmentationParameter::LengthUnit);
-  registerParameter("DC_rmin", "DC_rmin", m_DC_rmin, 0., SegmentationParameter::LengthUnit);
-  registerParameter("DC_rmax", "DC_rmax", m_DC_rmax, 0., SegmentationParameter::LengthUnit);
 }
 
 Vector3D GridDriftChamber::position(const CellID& /*cID*/) const {
@@ -45,146 +41,148 @@ CellID GridDriftChamber::cellID(const Vector3D& /*localPosition*/, const Vector3
   CellID cID = vID;
 
   int chamberID = _decoder->get(cID, "chamber");
+  int layerid = _decoder->get(cID, "layer");
 
   double posx = globalPosition.X;
   double posy = globalPosition.Y;
   double posz = globalPosition.Z;
-  Vector3D wire0 = returnPosWire0(posz);
-  double phi_wire0 = phiFromXY(wire0);
-
-  double radius = sqrt(posx*posx+posy*posy);
-
-  int m_DC_layer_number = floor((m_DC_rend-m_DC_rbegin)/m_layer_width);
-  double DC_layerdelta = m_layer_width;
-
-  int layerid;
-  if( radius<= m_DC_rend && radius>= m_DC_rbegin) {
-      layerid = floor((radius - m_DC_rbegin)/DC_layerdelta);
-  } else if ( radius>= (m_DC_rmin-m_safe_distance) && radius < m_DC_rbegin) {
-      layerid = 0;
-  } else if ( radius> m_DC_rend ) {//&& radius <= (m_DC_rmax+m_safe_distance)) {
-      layerid = m_DC_layer_number-1;
-  }
 
   updateParams(chamberID,layerid);
 
+  TVector3 Phi0 = returnPhi0(chamberID,layerid,posz);
+  double phi0 = phiFromXY2(Phi0);
+
   double phi_hit = phiFromXY(globalPosition);
   double offsetphi= m_offset;
-  int _lphi;
+  double _lphi;
 
-  if(phi_hit >= (offsetphi+phi_wire0)) {
-    _lphi = (int) ((phi_hit - offsetphi - phi_wire0)/ _currentLayerphi);
+  _lphi = phi_hit - phi0 + _currentLayerphi/2.;
+  if(_lphi<0.){
+      _lphi+=2*M_PI;
+  }else if(_lphi>2*M_PI){
+      _lphi=fmod(_lphi,2*M_PI);
   }
-  else {
-    _lphi = (int) ((phi_hit - offsetphi - phi_wire0 + 2 * M_PI)/ _currentLayerphi);
-  }
-
-  int lphi = _lphi;
+  int cellID=floor(_lphi/_currentLayerphi);
 
-  _decoder->set(cID, layer_id, layerid);
-  _decoder->set(cID, m_phiID, lphi);
+  _decoder->set(cID, m_phiID, cellID);
 
   return cID;
 }
 
 double GridDriftChamber::phi(const CellID& cID) const {
-  CellID phiValue = _decoder->get(cID, m_phiID);
-  return binToPosition(phiValue, _currentLayerphi, m_offset);
+    CellID phiValue = _decoder->get(cID, m_phiID);
+    return binToPosition(phiValue, _currentLayerphi, m_offset);
 }
 
 void GridDriftChamber::cellposition(const CellID& cID, TVector3& Wstart,
-                                    TVector3& Wend) const {
+        TVector3& Wend) const {
 
-  auto chamberIndex = _decoder->get(cID, "chamber");
-  auto layerIndex = _decoder->get(cID, "layer");
-  updateParams(chamberIndex,layerIndex);
+    auto chamberIndex = _decoder->get(cID, "chamber");
+    auto layerIndex = _decoder->get(cID, "layer");
+    updateParams(chamberIndex,layerIndex);
 
-  double phi_start = phi(cID);
-  double phi_mid = phi_start + _currentLayerphi/2.;
-  double phi_end = phi_mid + returnAlpha();
+    double phi_start = phi(cID);
+    double phi_end = phi_start + returnAlpha();
 
-  Wstart = returnWirePosition(phi_mid, -1);
-  Wend = returnWirePosition(phi_end, 1);
+    Wstart = returnWirePosition(phi_start, -1);
+    Wend = returnWirePosition(phi_end, 1);
 }
 
+TVector3 GridDriftChamber::returnPhi0(int chamber,int layer, double z) const
+{
+    updateParams(chamber,layer);
+
+    double phi_wire_start = binToPosition(0 , _currentLayerphi, m_offset);
+    double phi_wire_end = phi_wire_start + returnAlpha();
+
+    TVector3 wire_start = returnWirePosition(phi_wire_start, -1);
+    TVector3 wire_end = returnWirePosition(phi_wire_end, 1);
+
+    double ratio = fabs(z - wire_start.Z())/fabs(wire_end.Z() - wire_start.Z());
+    double x_pos = ratio * (wire_end.X() - wire_start.X()) + wire_start.X();
+    double y_pos = ratio * (wire_end.Y() - wire_start.Y()) + wire_start.Y();
+
+    return TVector3(x_pos,y_pos,z);
+}
+
+
 void GridDriftChamber::cellposition2(int chamber,int layer, int cell,
-                                    TVector3& Wstart, TVector3& Wend) const {
-     updateParams(chamber,layer);
-     double phi_start = binToPosition(cell, _currentLayerphi, m_offset);
-     double phi_mid = phi_start + _currentLayerphi/2.;
-     double phi_end = phi_mid + returnAlpha();
-
-     Wstart = returnWirePosition(phi_mid, -1);
-     Wend = returnWirePosition(phi_end, 1);
+        TVector3& Wstart, TVector3& Wend) const {
+    updateParams(chamber,layer);
+    double phi_start = binToPosition(cell, _currentLayerphi, m_offset);
+    double phi_end = phi_start + returnAlpha();
+
+    Wstart = returnWirePosition(phi_start, -1);
+    Wend = returnWirePosition(phi_end, 1);
 }
 
 TVector3 GridDriftChamber::LineLineIntersect(TVector3& p1, TVector3& p2, TVector3& p3, TVector3& p4) const {
 
-  TVector3 p13, p43, p21;
-  double d1343, d4321, d1321, d4343, d2121;
-  double numer, denom;
-  double mua, mub;
-  TVector3 pa, pb;
-
-  p13.SetX(p1.X() - p3.X());
-  p13.SetY(p1.Y() - p3.Y());
-  p13.SetZ(p1.Z() - p3.Z());
-  p43.SetX(p4.X() - p3.X());
-  p43.SetY(p4.Y() - p3.Y());
-  p43.SetZ(p4.Z() - p3.Z());
-  /* if (ABS(p43.X())  < EPS && ABS(p43.Y())  < EPS && ABS(p43.Z())  < EPS) */
-  /*    return(FALSE); */
-  p21.SetX(p2.X() - p1.X());
-  p21.SetY(p2.Y() - p1.Y());
-  p21.SetZ(p2.Z() - p1.Z());
-  /* if (ABS(p21.X())  < EPS && ABS(p21.Y())  < EPS && ABS(p21.Z())  < EPS) */
-  /*    return(FALSE); */
-
-  d1343 = p13.X() * p43.X() + p13.Y() * p43.Y() + p13.Z() * p43.Z();
-  d4321 = p43.X() * p21.X() + p43.Y() * p21.Y() + p43.Z() * p21.Z();
-  d1321 = p13.X() * p21.X() + p13.Y() * p21.Y() + p13.Z() * p21.Z();
-  d4343 = p43.X() * p43.X() + p43.Y() * p43.Y() + p43.Z() * p43.Z();
-  d2121 = p21.X() * p21.X() + p21.Y() * p21.Y() + p21.Z() * p21.Z();
-
-  denom = d2121 * d4343 - d4321 * d4321;
-  /* if (ABS(denom) < EPS) */
-  /*    return(FALSE); */
-  numer = d1343 * d4321 - d1321 * d4343;
-
-  mua = numer / denom;
-  mub = (d1343 + d4321 * (mua)) / d4343;
-
-  pa.SetX(p1.X() + mua * p21.X());
-  pa.SetY(p1.Y() + mua * p21.Y());
-  pa.SetZ(p1.Z() + mua * p21.Z());
-  pb.SetX(p3.X() + mub * p43.X());
-  pb.SetY(p3.Y() + mub * p43.Y());
-  pb.SetZ(p3.Z() + mub * p43.Z());
-
-  return pb - pa;
+    TVector3 p13, p43, p21;
+    double d1343, d4321, d1321, d4343, d2121;
+    double numer, denom;
+    double mua, mub;
+    TVector3 pa, pb;
+
+    p13.SetX(p1.X() - p3.X());
+    p13.SetY(p1.Y() - p3.Y());
+    p13.SetZ(p1.Z() - p3.Z());
+    p43.SetX(p4.X() - p3.X());
+    p43.SetY(p4.Y() - p3.Y());
+    p43.SetZ(p4.Z() - p3.Z());
+    /* if (ABS(p43.X())  < EPS && ABS(p43.Y())  < EPS && ABS(p43.Z())  < EPS) */
+    /*    return(FALSE); */
+    p21.SetX(p2.X() - p1.X());
+    p21.SetY(p2.Y() - p1.Y());
+    p21.SetZ(p2.Z() - p1.Z());
+    /* if (ABS(p21.X())  < EPS && ABS(p21.Y())  < EPS && ABS(p21.Z())  < EPS) */
+    /*    return(FALSE); */
+
+    d1343 = p13.X() * p43.X() + p13.Y() * p43.Y() + p13.Z() * p43.Z();
+    d4321 = p43.X() * p21.X() + p43.Y() * p21.Y() + p43.Z() * p21.Z();
+    d1321 = p13.X() * p21.X() + p13.Y() * p21.Y() + p13.Z() * p21.Z();
+    d4343 = p43.X() * p43.X() + p43.Y() * p43.Y() + p43.Z() * p43.Z();
+    d2121 = p21.X() * p21.X() + p21.Y() * p21.Y() + p21.Z() * p21.Z();
+
+    denom = d2121 * d4343 - d4321 * d4321;
+    /* if (ABS(denom) < EPS) */
+    /*    return(FALSE); */
+    numer = d1343 * d4321 - d1321 * d4343;
+
+    mua = numer / denom;
+    mub = (d1343 + d4321 * (mua)) / d4343;
+
+    pa.SetX(p1.X() + mua * p21.X());
+    pa.SetY(p1.Y() + mua * p21.Y());
+    pa.SetZ(p1.Z() + mua * p21.Z());
+    pb.SetX(p3.X() + mub * p43.X());
+    pb.SetY(p3.Y() + mub * p43.Y());
+    pb.SetZ(p3.Z() + mub * p43.Z());
+
+    return pb - pa;
 }
 
 double GridDriftChamber::distanceTrackWire(const CellID& cID, const TVector3& hit_start,
-                                           const TVector3& hit_end) const {
+        const TVector3& hit_end) const {
 
-  TVector3 Wstart = {0,0,0};
-  TVector3 Wend = {0,0,0};
-  cellposition(cID,Wstart,Wend);
+    TVector3 Wstart = {0,0,0};
+    TVector3 Wend = {0,0,0};
+    cellposition(cID,Wstart,Wend);
 
-  TVector3 a = (hit_end - hit_start).Unit();
-  TVector3 b = (Wend - Wstart).Unit();
-  TVector3 c = Wstart - hit_start;
+    TVector3 a = (hit_end - hit_start).Unit();
+    TVector3 b = (Wend - Wstart).Unit();
+    TVector3 c = Wstart - hit_start;
 
-  double num = std::abs(c.Dot(a.Cross(b)));
-  double denum = (a.Cross(b)).Mag();
+    double num = std::abs(c.Dot(a.Cross(b)));
+    double denum = (a.Cross(b)).Mag();
 
-  double DCA = 0;
+    double DCA = 0;
 
-  if (denum) {
-      DCA = num / denum;
-  }
+    if (denum) {
+        DCA = num / denum;
+    }
 
-  return DCA;
+    return DCA;
 }
 
 double GridDriftChamber::distanceTrackWire2(const CellID& cID, const TVector3& hit_pos) const {
@@ -201,132 +199,134 @@ double GridDriftChamber::distanceTrackWire2(const CellID& cID, const TVector3& h
     return DCA;
 }
 
-TVector3 GridDriftChamber::distanceClosestApproach(const CellID& cID, const TVector3& hitPos) const {
-  // Distance of the closest approach between a single hit (point) and the closest wire
+TVector3 GridDriftChamber::distanceClosestApproach(const CellID& cID, const TVector3& hitPos, TVector3& PCA) const {
+    // Distance of the closest approach between a single hit (point) and the closest wire
 
-   TVector3 Wstart = {0,0,0};
-   TVector3 Wend = {0,0,0};
-   cellposition(cID,Wstart,Wend);
+    TVector3 Wstart = {0,0,0};
+    TVector3 Wend = {0,0,0};
+    cellposition(cID,Wstart,Wend);
 
-   TVector3 temp = (Wend + Wstart);
-   TVector3 Wmid(temp.X() / 2.0, temp.Y() / 2.0, temp.Z() / 2.0);
+    TVector3 temp = (Wend + Wstart);
+    TVector3 Wmid(temp.X() / 2.0, temp.Y() / 2.0, temp.Z() / 2.0);
 
-   double hitPhi = hitPos.Phi();
-   if (hitPhi < 0) {
-       hitPhi = hitPhi + 2 * M_PI;
-   }
+    double hitPhi = hitPos.Phi();
+    if (hitPhi < 0) {
+        hitPhi = hitPhi + 2 * M_PI;
+    }
 
-   TVector3 PCA = Wstart + ((Wend - Wstart).Unit()).Dot((hitPos - Wstart)) * ((Wend - Wstart).Unit());
-   TVector3 dca = hitPos - PCA;
+    PCA = Wstart + ((Wend - Wstart).Unit()).Dot((hitPos - Wstart)) * ((Wend - Wstart).Unit());
+    TVector3 dca = hitPos - PCA;
 
-   return dca;
+    return dca;
 }
 
 TVector3 GridDriftChamber::Line_TrackWire(const CellID& cID, const TVector3& hit_start, const TVector3& hit_end) const {
-  // The line connecting a particle track to the closest wire
-  // Returns the vector connecting the both
-  TVector3 Wstart = {0,0,0};
-  TVector3 Wend = {0,0,0};
-  cellposition(cID,Wstart,Wend);
-
-  TVector3 P1 = hit_start;
-  TVector3 P2 = hit_end;
-  TVector3 P3 = Wstart;
-  TVector3 P4 = Wend;
-
-  TVector3 intersect = LineLineIntersect(P1, P2, P3, P4);
-  return intersect;
+    // The line connecting a particle track to the closest wire
+    // Returns the vector connecting the both
+    TVector3 Wstart = {0,0,0};
+    TVector3 Wend = {0,0,0};
+    cellposition(cID,Wstart,Wend);
+
+    TVector3 P1 = hit_start;
+    TVector3 P2 = hit_end;
+    TVector3 P3 = Wstart;
+    TVector3 P4 = Wend;
+
+    TVector3 intersect = LineLineIntersect(P1, P2, P3, P4);
+    return intersect;
 }
 
 // Get the wire position for a z
 TVector3 GridDriftChamber::wirePos_vs_z(const CellID& cID, const double& zpos) const {
 
-  TVector3 Wstart = {0,0,0};
-  TVector3 Wend = {0,0,0};
-  cellposition(cID,Wstart,Wend);
+    TVector3 Wstart = {0,0,0};
+    TVector3 Wend = {0,0,0};
+    cellposition(cID,Wstart,Wend);
 
-  double t = (zpos - Wstart.Z())/(Wend.Z()-Wstart.Z());
-  double x = Wstart.X()+t*(Wend.X()-Wstart.X());
-  double y = Wstart.Y()+t*(Wend.Y()-Wstart.Y());
+    double t = (zpos - Wstart.Z())/(Wend.Z()-Wstart.Z());
+    double x = Wstart.X()+t*(Wend.X()-Wstart.X());
+    double y = Wstart.Y()+t*(Wend.Y()-Wstart.Y());
 
-  TVector3 wireCoord(x, y, zpos);
-  return wireCoord;
+    TVector3 wireCoord(x, y, zpos);
+    return wireCoord;
 }
 
 TVector3 GridDriftChamber::IntersectionTrackWire(const CellID& cID, const TVector3& hit_start, const TVector3& hit_end) const {
-  // Intersection between the particle track and the wire assuming that the track between hit_start and hit_end is linear
+    // Intersection between the particle track and the wire assuming that the track between hit_start and hit_end is linear
 
-  TVector3 Wstart = {0,0,0};
-  TVector3 Wend = {0,0,0};
-  cellposition(cID,Wstart,Wend);
+    TVector3 Wstart = {0,0,0};
+    TVector3 Wend = {0,0,0};
+    cellposition(cID,Wstart,Wend);
 
-  TVector3 P1 = hit_start;
-  TVector3 V1 = hit_end-hit_start;
+    TVector3 P1 = hit_start;
+    TVector3 V1 = hit_end-hit_start;
 
-  TVector3 P2 = Wstart;
-  TVector3 V2 = Wend - Wstart;
+    TVector3 P2 = Wstart;
+    TVector3 V2 = Wend - Wstart;
 
-  TVector3 denom = V1.Cross(V2);
-  double mag_denom = denom.Mag();
+    TVector3 denom = V1.Cross(V2);
+    double mag_denom = denom.Mag();
 
-  TVector3 intersect(0, 0, 0);
+    TVector3 intersect(0, 0, 0);
 
-  if (mag_denom !=0)
+    if (mag_denom !=0)
     {
-      TVector3 num = ((P2-P1)).Cross(V2);
-      double mag_num = num.Mag();
-      double a = mag_num / mag_denom;
+        TVector3 num = ((P2-P1)).Cross(V2);
+        double mag_num = num.Mag();
+        double a = mag_num / mag_denom;
 
-      intersect = P1 + a * V1;
+        intersect = P1 + a * V1;
 
     }
-  return intersect;
+    return intersect;
 }
 
-double GridDriftChamber::Distance(const CellID& cID, const TVector3& pointIn, const TVector3& pointOut, TVector3& hitPosition) const {
-
- //For two lines r=r1+t1.v1 & r=r2+t2.v2
-  //the closest approach is d=|(r2-r1).(v1 x v2)|/|v1 x v2|
-  //the point where closest approach are
-  //t1=(v1 x v2).[(r2-r1) x v2]/[(v1 x v2).(v1 x v2)]
-  //t2=(v1 x v2).[(r2-r1) x v1]/[(v1 x v2).(v1 x v2)]
-  //if v1 x v2=0 means two lines are parallel
-  //d=|(r2-r1) x v1|/|v1|
-
-  double t1,distance,dInOut,dHitIn,dHitOut;
-  //Get wirepoint @ endplate
-   TVector3 west = {0,0,0};
-   TVector3 east = {0,0,0};
-   cellposition(cID,west,east);
-   TVector3 wireLine=east - west;
-   TVector3 hitLine=pointOut - pointIn;
-
-  TVector3 hitXwire=hitLine.Cross(wireLine);
-  TVector3 wire2hit=east-pointOut;
-  //Hitposition is the position on hit line where closest approach
-  //of two lines, but it may out the area from pointIn to pointOut
-  if(hitXwire.Mag()==0){
-    distance=wireLine.Cross(wire2hit).Mag()/wireLine.Mag();
-    hitPosition=pointIn;
-  }else{
-    t1=hitXwire.Dot(wire2hit.Cross(wireLine))/hitXwire.Mag2();
-    hitPosition=pointOut+t1*hitLine;
-
-    dInOut=(pointOut-pointIn).Mag();
-    dHitIn=(hitPosition-pointIn).Mag();
-    dHitOut=(hitPosition-pointOut).Mag();
-    if(dHitIn<=dInOut && dHitOut<=dInOut){ //Between point in & out
-      distance=fabs(wire2hit.Dot(hitXwire)/hitXwire.Mag());
-    }else if(dHitOut>dHitIn){ // out pointIn
-      distance=wireLine.Cross(pointIn-east).Mag()/wireLine.Mag();
-      hitPosition=pointIn;
-    }else{ // out pointOut
-      distance=wireLine.Cross(pointOut-east).Mag()/wireLine.Mag();
-      hitPosition=pointOut;
+double GridDriftChamber::Distance(const CellID& cID, const TVector3& pointIn, const TVector3& pointOut, TVector3& hitPosition, TVector3& PCA) const {
+
+    //For two lines r=r1+t1.v1 & r=r2+t2.v2
+    //the closest approach is d=|(r2-r1).(v1 x v2)|/|v1 x v2|
+    //the point where closest approach are
+    //t1=(v1 x v2).[(r2-r1) x v2]/[(v1 x v2).(v1 x v2)]
+    //t2=(v1 x v2).[(r2-r1) x v1]/[(v1 x v2).(v1 x v2)]
+    //if v1 x v2=0 means two lines are parallel
+    //d=|(r2-r1) x v1|/|v1|
+
+    double t1,distance,dInOut,dHitIn,dHitOut;
+    //Get wirepoint @ endplate
+    TVector3 west = {0,0,0};
+    TVector3 east = {0,0,0};
+    cellposition(cID,west,east);
+    TVector3 wireLine=east - west;
+    TVector3 hitLine=pointOut - pointIn;
+
+    TVector3 hitXwire=hitLine.Cross(wireLine);
+    TVector3 wire2hit=east-pointOut;
+    //Hitposition is the position on hit line where closest approach
+    //of two lines, but it may out the area from pointIn to pointOut
+    if(hitXwire.Mag()==0){
+        distance=wireLine.Cross(wire2hit).Mag()/wireLine.Mag();
+        hitPosition=pointIn;
+    }else{
+        t1=hitXwire.Dot(wire2hit.Cross(wireLine))/hitXwire.Mag2();
+        hitPosition=pointOut+t1*hitLine;
+
+        dInOut=(pointOut-pointIn).Mag();
+        dHitIn=(hitPosition-pointIn).Mag();
+        dHitOut=(hitPosition-pointOut).Mag();
+        if(dHitIn<=dInOut && dHitOut<=dInOut){ //Between point in & out
+            distance=fabs(wire2hit.Dot(hitXwire)/hitXwire.Mag());
+        }else if(dHitOut>dHitIn){ // out pointIn
+            distance=wireLine.Cross(pointIn-east).Mag()/wireLine.Mag();
+            hitPosition=pointIn;
+        }else{ // out pointOut
+            distance=wireLine.Cross(pointOut-east).Mag()/wireLine.Mag();
+            hitPosition=pointOut;
+        }
     }
-  }
 
-  return distance;
+    PCA = west + ((east - west).Unit()).Dot((hitPosition - west)) * ((east - west).Unit());
+
+    return distance;
 }
 
 
diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
index f9384dd89..661f59f60 100644
--- a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
+++ b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
@@ -1,4 +1,3 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 #include "DCHDigiAlg.h"
 
 
@@ -28,15 +27,15 @@ DCHDigiAlg::DCHDigiAlg(const std::string& name, ISvcLocator* svcLoc)
   : GaudiAlgorithm(name, svcLoc),
     _nEvt(0)
 {
-
+  
   // Input collections
   declareProperty("SimDCHitCollection", r_SimDCHCol, "Handle of the Input SimHit collection");
-
+  
   // Output collections
   declareProperty("DigiDCHitCollection", w_DigiDCHCol, "Handle of Digi DCHit collection");
-
+  
   declareProperty("AssociationCollection", w_AssociationCol, "Handle of Association collection");
-
+   
 }
 
 StatusCode DCHDigiAlg::initialize()
@@ -54,6 +53,7 @@ StatusCode DCHDigiAlg::initialize()
   }
 
   if(m_WriteAna){
+
       NTuplePtr nt( ntupleSvc(), "MyTuples/DCH_digi_evt" );
       if ( nt ) m_tuple = nt;
       else {
@@ -71,10 +71,16 @@ StatusCode DCHDigiAlg::initialize()
             m_tuple->addItem( "cell"    , m_n_digi, m_cell     ).ignore();
             m_tuple->addItem( "cell_x"  , m_n_digi, m_cell_x   ).ignore();
             m_tuple->addItem( "cell_y"  , m_n_digi, m_cell_y   ).ignore();
+            m_tuple->addItem( "cell1_x"  , m_n_digi, m_cell1_x   ).ignore();
+            m_tuple->addItem( "cell1_y"  , m_n_digi, m_cell1_y   ).ignore();
             m_tuple->addItem( "hit_x"    , m_n_digi,m_hit_x     ).ignore();
             m_tuple->addItem( "hit_y"    , m_n_digi,m_hit_y     ).ignore();
             m_tuple->addItem( "hit_z"    , m_n_digi,m_hit_z     ).ignore();
-            m_tuple->addItem( "dca"      , m_n_digi,m_dca       ).ignore();
+            m_tuple->addItem( "mom_x"    , m_n_digi,m_mom_x     ).ignore();
+            m_tuple->addItem( "mom_y"    , m_n_digi,m_mom_y     ).ignore();
+            m_tuple->addItem( "dca"      , m_n_digi, m_dca       ).ignore();
+            m_tuple->addItem( "poca_x"   , m_n_digi, m_poca_x    ).ignore();
+            m_tuple->addItem( "poca_y"   , m_n_digi, m_poca_y    ).ignore();
             m_tuple->addItem( "hit_dE"   , m_n_digi,m_hit_dE    ).ignore();
             m_tuple->addItem( "hit_dE_dx", m_n_digi,m_hit_dE_dx ).ignore();
           } else { // did not manage to book the N tuple....
@@ -92,10 +98,7 @@ StatusCode DCHDigiAlg::execute()
   m_start = clock();
 
   info() << "Processing " << _nEvt << " events " << endmsg;
-  if(m_WriteAna && (nullptr!=m_tuple))
-  {
-      m_evt = _nEvt;
-  }
+  if(m_WriteAna) m_evt = _nEvt;
   edm4hep::TrackerHitCollection* Vec   = w_DigiDCHCol.createAndPut();
   edm4hep::MCRecoTrackerAssociationCollection* AssoVec   = w_AssociationCol.createAndPut();
   const edm4hep::SimTrackerHitCollection* SimHitCol =  r_SimDCHCol.get();
@@ -105,8 +108,8 @@ StatusCode DCHDigiAlg::execute()
   debug()<<"input sim hit size="<< SimHitCol->size() <<endmsg;
 
   auto SimHit0 = SimHitCol->at(0);
-  std::map<unsigned long long, std::vector<decltype(SimHit0)> > id_hits_map;
-  //std::map<unsigned long long, std::vector<edm4hep::ConstSimTrackerhit> > id_hits_map;
+  std::map<unsigned long long, std::vector<decltype(SimHit0)>> id_hits_map;
+
 
   for( int i = 0; i < SimHitCol->size(); i++ ) 
   {
@@ -114,7 +117,8 @@ StatusCode DCHDigiAlg::execute()
       unsigned long long id = SimHit.getCellID();
       float sim_hit_mom = sqrt( SimHit.getMomentum()[0]*SimHit.getMomentum()[0] + SimHit.getMomentum()[1]*SimHit.getMomentum()[1] + SimHit.getMomentum()[2]*SimHit.getMomentum()[2] );//GeV
       if(sim_hit_mom < m_mom_threshold) continue; 
-      if(SimHit.getEDep() <= 0) continue;
+      if(sim_hit_mom > m_mom_threshold_high) continue; 
+      if(SimHit.getEDep() <= m_edep_threshold) continue;
 
       if ( id_hits_map.find(id) != id_hits_map.end()) id_hits_map[id].push_back(SimHit);
       else 
@@ -138,6 +142,7 @@ StatusCode DCHDigiAlg::execute()
     double pos_x = 0 ;
     double pos_y = 0 ;
     double pos_z = 0 ;
+    double momx,momy = 0;
     int simhit_size = iter->second.size();
     for(unsigned int i=0; i< simhit_size; i++)
     {
@@ -151,50 +156,48 @@ StatusCode DCHDigiAlg::execute()
     m_segmentation->cellposition(wcellid, Wstart, Wend);
     float dd4hep_mm = dd4hep::mm;
     //std::cout<<"dd4hep_mm="<<dd4hep_mm<<std::endl;
-//    Wstart =(1/dd4hep_mm)* Wstart;// from DD4HEP cm to mm
-//    Wend   =(1/dd4hep_mm)* Wend  ;
-    //std::cout<<"wcellid="<<wcellid<<",chamber="<<chamber<<",layer="<<layer<<",cellID="<<cellID<<",s_x="<<Wstart.x()<<",s_y="<<Wstart.y()<<",s_z="<<Wstart.z()<<",E_x="<<Wend.x()<<",E_y="<<Wend.y()<<",E_z="<<Wend.z()<<std::endl;
+    //    Wstart =(1/dd4hep_mm)* Wstart;// from DD4HEP cm to mm
+    //    Wend   =(1/dd4hep_mm)* Wend  ;
+    if(m_debug) std::cout<<"DCHDigi wcellid ="<<wcellid<< ",chamber="<<chamber<<",layer="<<layer<<",cellID="<<cellID<<",s_x="<<Wstart.x()<<",s_y="<<Wstart.y()<<",s_z="<<Wstart.z()<<",E_x="<<Wend.x()<<",E_y="<<Wend.y()<<",E_z="<<Wend.z()<<std::endl;
 
     TVector3  denominator = (Wend-Wstart) ;
     float min_distance = 999 ;
-    float min_line_distance = 999 ;
+    float min_SM_distance = 999 ;
+    float min_D_distance = 999 ;
     float tmp_distance =0;
+    float SMdca = 0;
+    float distance =0;
+    TVector3 hitPosition;
+    TVector3 PCA;
     for(unsigned int i=0; i< simhit_size; i++)
     {
         float sim_hit_mom = sqrt( iter->second.at(i).getMomentum()[0]*iter->second.at(i).getMomentum()[0] + iter->second.at(i).getMomentum()[1]*iter->second.at(i).getMomentum()[1] + iter->second.at(i).getMomentum()[2]*iter->second.at(i).getMomentum()[2] );//GeV
         float sim_hit_pt = sqrt( iter->second.at(i).getMomentum()[0]*iter->second.at(i).getMomentum()[0] + iter->second.at(i).getMomentum()[1]*iter->second.at(i).getMomentum()[1] );//GeV
         TVector3  pos(iter->second.at(i).getPosition()[0]*dd4hep_mm, iter->second.at(i).getPosition()[1]*dd4hep_mm, iter->second.at(i).getPosition()[2]*dd4hep_mm);
 
-//        TVector3  numerator = denominator.Cross(Wstart-pos) ;
-//        float tmp_distance = numerator.Mag()/denominator.Mag() ;
-
         TVector3 sim_mon(iter->second.at(i).getMomentum()[0],iter->second.at(i).getMomentum()[1],iter->second.at(i).getMomentum()[2]);
         float Steplength = iter->second.at(i).getPathLength();
         TVector3  pos_start = pos - 0.5 * Steplength * sim_mon.Unit();
         TVector3  pos_end = pos + 0.5 * Steplength * sim_mon.Unit();
-        if(m_Doca) {
-            tmp_distance = m_segmentation->distanceTrackWire(wcellid,pos_start,pos_end);
-            tmp_distance = tmp_distance/dd4hep_mm; //mm
-        } else {
-            tmp_distance = (m_segmentation->distanceClosestApproach(wcellid,pos)).Mag();
-            tmp_distance = tmp_distance/dd4hep_mm; //mm
-        }
-
+        tmp_distance = m_segmentation->Distance(wcellid,pos_start,pos_end,hitPosition,PCA);
+        tmp_distance = tmp_distance/dd4hep_mm; //mm
 
        // std::cout << " Steplength= " << Steplength << std::endl;
-       // std::cout<<"tmp_distance="<<tmp_distance<<",x="<<pos.x()<<",y="<<pos.y()<<",z="<<pos.z()<<",mom="<<sim_hit_mom<<",pt="<<sim_hit_pt<<std::endl;
 
         if(tmp_distance < min_distance){
             min_distance = tmp_distance;
-            pos_x = pos.x();
-            pos_y = pos.y();
+            pos_x = hitPosition.x();     //pos.x();
+            pos_y = hitPosition.y();     //pos.y();
             pos_z = pos.z();
+            momx = iter->second.at(i).getMomentum()[0];
+            momy = iter->second.at(i).getMomentum()[1];
         }
         tot_length += iter->second.at(i).getPathLength();//mm
         auto asso = AssoVec->create();
         asso.setRec(trkHit);
         asso.setSim(iter->second.at(i));
         asso.setWeight(iter->second.at(i).getEDep()/tot_edep);
+        //std::cout<<" asso setRec setSim "<<trkHit<<" "<<iter->second.at(i)<<std::endl;
 
         if(m_WriteAna && (nullptr!=m_tuple)) { // && min_distance <0.3){
             m_simhit_x[m_n_sim] = pos.x();
@@ -216,10 +219,16 @@ StatusCode DCHDigiAlg::execute()
         m_cell     [m_n_digi] = cellID;
         m_cell_x   [m_n_digi] = Wstart.x();
         m_cell_y   [m_n_digi] = Wstart.y();
+        m_cell1_x   [m_n_digi] = Wend.x();
+        m_cell1_y   [m_n_digi] = Wend.y();
         m_hit_x    [m_n_digi] = pos_x;
         m_hit_y    [m_n_digi] = pos_y;
         m_hit_z    [m_n_digi] = pos_z;
+        m_mom_x    [m_n_digi] = momx ;
+        m_mom_y    [m_n_digi] = momy ;
         m_dca      [m_n_digi] = min_distance;
+        m_poca_x   [m_n_digi] = PCA.x();
+        m_poca_y   [m_n_digi] = PCA.y();
         m_hit_dE   [m_n_digi] = trkHit.getEDep();
         m_hit_dE_dx[m_n_digi] = trkHit.getEdx() ;
         m_n_digi ++ ;
@@ -230,15 +239,17 @@ StatusCode DCHDigiAlg::execute()
   debug()<<"output digi DCHhit size="<< Vec->size() <<endmsg;
   _nEvt ++ ;
 
-  m_end = clock();
   if(m_WriteAna && (nullptr!=m_tuple)){
-      m_time = (m_end - m_start);
       StatusCode status = m_tuple->write();
       if ( status.isFailure() ) {
         error() << "    Cannot fill N-tuple:" << long( m_tuple ) << endmsg;
         return StatusCode::FAILURE;
       }
   }
+  m_end = clock();
+  if(m_WriteAna){
+      m_time = (m_end - m_start);
+  }
 
   return StatusCode::SUCCESS;
 }
diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.h b/Digitisers/DCHDigi/src/DCHDigiAlg.h
index d6a82961f..d674dc775 100644
--- a/Digitisers/DCHDigi/src/DCHDigiAlg.h
+++ b/Digitisers/DCHDigi/src/DCHDigiAlg.h
@@ -54,13 +54,19 @@ class DCHDigiAlg : public GaudiAlgorithm
   NTuple::Array<int  > m_cell      ;
   NTuple::Array<float> m_cell_x    ;
   NTuple::Array<float> m_cell_y    ;
+  NTuple::Array<float> m_cell1_x   ;
+  NTuple::Array<float> m_cell1_y   ;
   NTuple::Array<float> m_simhit_x  ;
   NTuple::Array<float> m_simhit_y  ;
   NTuple::Array<float> m_simhit_z  ;
   NTuple::Array<float> m_hit_x     ;
   NTuple::Array<float> m_hit_y     ;
   NTuple::Array<float> m_hit_z     ;
+  NTuple::Array<float> m_mom_x     ;
+  NTuple::Array<float> m_mom_y     ;
   NTuple::Array<float> m_dca       ;
+  NTuple::Array<float> m_poca_x    ;
+  NTuple::Array<float> m_poca_y    ;
   NTuple::Array<float> m_hit_dE    ;
   NTuple::Array<float> m_hit_dE_dx ;
 
@@ -69,16 +75,18 @@ class DCHDigiAlg : public GaudiAlgorithm
   dd4hep::rec::CellIDPositionConverter* m_cellIDConverter;
   dd4hep::DDSegmentation::GridDriftChamber* m_segmentation;
   dd4hep::DDSegmentation::BitFieldCoder* m_decoder;
-
+  
   Gaudi::Property<std::string> m_readout_name{ this, "readout", "DriftChamberHitsCollection"};//readout for getting segmentation
-
+ 
   Gaudi::Property<float> m_res_x     { this, "res_x", 0.11};//mm
   Gaudi::Property<float> m_res_y     { this, "res_y", 0.11};//mm
   Gaudi::Property<float> m_res_z     { this, "res_z", 1   };//mm
   Gaudi::Property<float> m_velocity  { this, "drift_velocity", 40};// um/ns
   Gaudi::Property<float> m_mom_threshold { this, "mom_threshold", 0};// GeV
+  Gaudi::Property<float> m_mom_threshold_high { this, "mom_threshold_high", 1e9};// GeV
+  Gaudi::Property<float> m_edep_threshold{ this, "edep_threshold", 0};// GeV
   Gaudi::Property<bool>  m_WriteAna { this, "WriteAna", false};
-  Gaudi::Property<bool>  m_Doca { this, "Doca", false};//1:line dca 0:point dca
+  Gaudi::Property<bool>  m_debug{ this, "debug", false};
 
 
   // Input collections
@@ -86,6 +94,6 @@ class DCHDigiAlg : public GaudiAlgorithm
   // Output collections
   DataHandle<edm4hep::TrackerHitCollection>    w_DigiDCHCol{"DigiDCHitCollection", Gaudi::DataHandle::Writer, this};
   DataHandle<edm4hep::MCRecoTrackerAssociationCollection>    w_AssociationCol{"DCHitAssociationCollection", Gaudi::DataHandle::Writer, this};
-
 };
+
 #endif

From 2a2999bd033b42a651d8f817ae5b83529ea372f9 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Thu, 24 Feb 2022 09:37:06 +0800
Subject: [PATCH 08/27] delete blank lines

---
 Digitisers/DCHDigi/src/DCHDigiAlg.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
index 661f59f60..41f70a4b9 100644
--- a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
+++ b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
@@ -110,7 +110,6 @@ StatusCode DCHDigiAlg::execute()
   auto SimHit0 = SimHitCol->at(0);
   std::map<unsigned long long, std::vector<decltype(SimHit0)>> id_hits_map;
 
-
   for( int i = 0; i < SimHitCol->size(); i++ ) 
   {
       auto SimHit = SimHitCol->at(i);

From a80dc6fb99686a0fad3b40bd72c548164eb7740c Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Sun, 5 Jun 2022 21:35:39 +0800
Subject: [PATCH 09/27] update 101

---
 Digitisers/DCHDigi/src/DCHDigiAlg.cpp         |  224 ++-
 Digitisers/DCHDigi/src/DCHDigiAlg.h           |   12 +-
 Reconstruction/RecGenfitAlg/CMakeLists.txt    |    6 +-
 .../RecGenfitAlg/src/GenfitField.cpp          |   26 +-
 .../RecGenfitAlg/src/GenfitFitter.cpp         |  236 +--
 .../RecGenfitAlg/src/GenfitFitter.h           |   52 +-
 .../src/GenfitMaterialInterface.cpp           |   47 +-
 .../src/GenfitMaterialInterface.h             |   11 +
 .../RecGenfitAlg/src/GenfitTrack.cpp          | 1765 ++++++++++++-----
 Reconstruction/RecGenfitAlg/src/GenfitTrack.h |  207 +-
 .../include/Tracking/TrackingHelper.h         |    1 -
 .../src/TruthTracker/TruthTrackerAlg.cpp      |  877 ++++++--
 .../src/TruthTracker/TruthTrackerAlg.h        |  179 +-
 Utilities/DataHelper/CMakeLists.txt           |    4 +-
 .../include/DataHelper/HelixClass.h           |   51 +-
 Utilities/DataHelper/src/HelixClass.cc        |   69 +
 Utilities/DataHelper/src/TrackerHitHelper.cpp |   43 +
 17 files changed, 2801 insertions(+), 1009 deletions(-)

diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
index 41f70a4b9..d516b50f4 100644
--- a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
+++ b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
@@ -1,3 +1,4 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 #include "DCHDigiAlg.h"
 
 
@@ -52,6 +53,8 @@ StatusCode DCHDigiAlg::initialize()
       return StatusCode::FAILURE;
   }
 
+  fRandom.SetSeed(105105);//FIXME: set by users
+
   if(m_WriteAna){
 
       NTuplePtr nt( ntupleSvc(), "MyTuples/DCH_digi_evt" );
@@ -66,6 +69,10 @@ StatusCode DCHDigiAlg::initialize()
             m_tuple->addItem( "simhit_x", m_n_sim, m_simhit_x).ignore();
             m_tuple->addItem( "simhit_y", m_n_sim, m_simhit_y).ignore();
             m_tuple->addItem( "simhit_z", m_n_sim, m_simhit_z).ignore();
+            m_tuple->addItem( "Simdca"      , m_n_sim, m_Simdca       ).ignore();
+            m_tuple->addItem( "simhitT", m_n_sim, m_simhitT    ).ignore();
+            m_tuple->addItem( "simhitmom", m_n_sim, m_simhitmom    ).ignore();
+            m_tuple->addItem( "simPDG", m_n_sim, m_simPDG    ).ignore();
             m_tuple->addItem( "chamber" , m_n_digi, m_chamber  ).ignore();
             m_tuple->addItem( "layer"   , m_n_digi, m_layer    ).ignore();
             m_tuple->addItem( "cell"    , m_n_digi, m_cell     ).ignore();
@@ -83,6 +90,7 @@ StatusCode DCHDigiAlg::initialize()
             m_tuple->addItem( "poca_y"   , m_n_digi, m_poca_y    ).ignore();
             m_tuple->addItem( "hit_dE"   , m_n_digi,m_hit_dE    ).ignore();
             m_tuple->addItem( "hit_dE_dx", m_n_digi,m_hit_dE_dx ).ignore();
+            m_tuple->addItem( "truthlength", m_n_digi,m_truthlength).ignore();
           } else { // did not manage to book the N tuple....
             info() << "    Cannot book N-tuple:" << long( m_tuple ) << endmsg;
           }
@@ -110,6 +118,7 @@ StatusCode DCHDigiAlg::execute()
   auto SimHit0 = SimHitCol->at(0);
   std::map<unsigned long long, std::vector<decltype(SimHit0)>> id_hits_map;
 
+
   for( int i = 0; i < SimHitCol->size(); i++ ) 
   {
       auto SimHit = SimHitCol->at(i);
@@ -119,6 +128,10 @@ StatusCode DCHDigiAlg::execute()
       if(sim_hit_mom > m_mom_threshold_high) continue; 
       if(SimHit.getEDep() <= m_edep_threshold) continue;
 
+      //Wire efficiency
+      double hitProb = fRandom.Uniform(1.);
+      if(hitProb > m_wireEff) continue;
+
       if ( id_hits_map.find(id) != id_hits_map.end()) id_hits_map[id].push_back(SimHit);
       else 
       {
@@ -133,116 +146,119 @@ StatusCode DCHDigiAlg::execute()
   }
   for(auto iter = id_hits_map.begin(); iter != id_hits_map.end(); iter++)
   {
-    unsigned long long wcellid = iter->first;
-    auto trkHit = Vec->create();
-    trkHit.setCellID(wcellid);
-    double tot_edep   = 0 ;
-    double tot_length = 0 ;
-    double pos_x = 0 ;
-    double pos_y = 0 ;
-    double pos_z = 0 ;
-    double momx,momy = 0;
-    int simhit_size = iter->second.size();
-    for(unsigned int i=0; i< simhit_size; i++)
-    {
-        tot_edep += iter->second.at(i).getEDep();//GeV
-    }
-    int chamber = m_decoder->get(wcellid, "chamber");
-    int layer   = m_decoder->get(wcellid, "layer"  );
-    int cellID  = m_decoder->get(wcellid, "cellID" );
-    TVector3 Wstart(0,0,0);
-    TVector3 Wend  (0,0,0);
-    m_segmentation->cellposition(wcellid, Wstart, Wend);
-    float dd4hep_mm = dd4hep::mm;
-    //std::cout<<"dd4hep_mm="<<dd4hep_mm<<std::endl;
-    //    Wstart =(1/dd4hep_mm)* Wstart;// from DD4HEP cm to mm
-    //    Wend   =(1/dd4hep_mm)* Wend  ;
-    if(m_debug) std::cout<<"DCHDigi wcellid ="<<wcellid<< ",chamber="<<chamber<<",layer="<<layer<<",cellID="<<cellID<<",s_x="<<Wstart.x()<<",s_y="<<Wstart.y()<<",s_z="<<Wstart.z()<<",E_x="<<Wend.x()<<",E_y="<<Wend.y()<<",E_z="<<Wend.z()<<std::endl;
-
-    TVector3  denominator = (Wend-Wstart) ;
-    float min_distance = 999 ;
-    float min_SM_distance = 999 ;
-    float min_D_distance = 999 ;
-    float tmp_distance =0;
-    float SMdca = 0;
-    float distance =0;
-    TVector3 hitPosition;
-    TVector3 PCA;
-    for(unsigned int i=0; i< simhit_size; i++)
-    {
-        float sim_hit_mom = sqrt( iter->second.at(i).getMomentum()[0]*iter->second.at(i).getMomentum()[0] + iter->second.at(i).getMomentum()[1]*iter->second.at(i).getMomentum()[1] + iter->second.at(i).getMomentum()[2]*iter->second.at(i).getMomentum()[2] );//GeV
-        float sim_hit_pt = sqrt( iter->second.at(i).getMomentum()[0]*iter->second.at(i).getMomentum()[0] + iter->second.at(i).getMomentum()[1]*iter->second.at(i).getMomentum()[1] );//GeV
-        TVector3  pos(iter->second.at(i).getPosition()[0]*dd4hep_mm, iter->second.at(i).getPosition()[1]*dd4hep_mm, iter->second.at(i).getPosition()[2]*dd4hep_mm);
-
-        TVector3 sim_mon(iter->second.at(i).getMomentum()[0],iter->second.at(i).getMomentum()[1],iter->second.at(i).getMomentum()[2]);
-        float Steplength = iter->second.at(i).getPathLength();
-        TVector3  pos_start = pos - 0.5 * Steplength * sim_mon.Unit();
-        TVector3  pos_end = pos + 0.5 * Steplength * sim_mon.Unit();
-        tmp_distance = m_segmentation->Distance(wcellid,pos_start,pos_end,hitPosition,PCA);
-        tmp_distance = tmp_distance/dd4hep_mm; //mm
-
-       // std::cout << " Steplength= " << Steplength << std::endl;
-
-        if(tmp_distance < min_distance){
-            min_distance = tmp_distance;
-            pos_x = hitPosition.x();     //pos.x();
-            pos_y = hitPosition.y();     //pos.y();
-            pos_z = pos.z();
-            momx = iter->second.at(i).getMomentum()[0];
-            momy = iter->second.at(i).getMomentum()[1];
-        }
-        tot_length += iter->second.at(i).getPathLength();//mm
-        auto asso = AssoVec->create();
-        asso.setRec(trkHit);
-        asso.setSim(iter->second.at(i));
-        asso.setWeight(iter->second.at(i).getEDep()/tot_edep);
-        //std::cout<<" asso setRec setSim "<<trkHit<<" "<<iter->second.at(i)<<std::endl;
-
-        if(m_WriteAna && (nullptr!=m_tuple)) { // && min_distance <0.3){
-            m_simhit_x[m_n_sim] = pos.x();
-            m_simhit_y[m_n_sim] = pos.y();
-            m_simhit_z[m_n_sim] = pos.z();
-            m_n_sim ++ ;
-        }
-    }
-
-    trkHit.setTime(min_distance*1e3/m_velocity);//m_velocity is um/ns, drift time in ns
-    trkHit.setEDep(tot_edep);// GeV
-    trkHit.setEdx (tot_edep/tot_length); // GeV/mm
-    trkHit.setPosition (edm4hep::Vector3d(pos_x, pos_y, pos_z));//position of closest sim hit
-    trkHit.setCovMatrix(std::array<float, 6>{m_res_x, 0, m_res_y, 0, 0, m_res_z});//cov(x,x) , cov(y,x) , cov(y,y) , cov(z,x) , cov(z,y) , cov(z,z) in mm
-
-    if(m_WriteAna && (nullptr!=m_tuple)) { // && min_distance <0.3){
-        m_chamber  [m_n_digi] = chamber;
-        m_layer    [m_n_digi] = layer  ;
-        m_cell     [m_n_digi] = cellID;
-        m_cell_x   [m_n_digi] = Wstart.x();
-        m_cell_y   [m_n_digi] = Wstart.y();
-        m_cell1_x   [m_n_digi] = Wend.x();
-        m_cell1_y   [m_n_digi] = Wend.y();
-        m_hit_x    [m_n_digi] = pos_x;
-        m_hit_y    [m_n_digi] = pos_y;
-        m_hit_z    [m_n_digi] = pos_z;
-        m_mom_x    [m_n_digi] = momx ;
-        m_mom_y    [m_n_digi] = momy ;
-        m_dca      [m_n_digi] = min_distance;
-        m_poca_x   [m_n_digi] = PCA.x();
-        m_poca_y   [m_n_digi] = PCA.y();
-        m_hit_dE   [m_n_digi] = trkHit.getEDep();
-        m_hit_dE_dx[m_n_digi] = trkHit.getEdx() ;
-        m_n_digi ++ ;
-    }
-  }
+      unsigned long long wcellid = iter->first;
+      auto trkHit = Vec->create();
+      trkHit.setCellID(wcellid);
+      double tot_edep   = 0 ;
+      double tot_length = 0 ;
+      double pos_x = 0 ;
+      double pos_y = 0 ;
+      double pos_z = 0 ;
+      double momx,momy = 0;
+      int simhit_size = iter->second.size();
+      for(unsigned int i=0; i< simhit_size; i++)
+      {
+          tot_edep += iter->second.at(i).getEDep();//GeV
+      }
+      int chamber = m_decoder->get(wcellid, "chamber");
+      int layer   = m_decoder->get(wcellid, "layer"  );
+      int cellID  = m_decoder->get(wcellid, "cellID" );
+      TVector3 Wstart(0,0,0);
+      TVector3 Wend  (0,0,0);
+      m_segmentation->cellposition(wcellid, Wstart, Wend);
+      float dd4hep_mm = dd4hep::mm;
+      //std::cout<<"dd4hep_mm="<<dd4hep_mm<<std::endl;
+      //    Wstart =(1/dd4hep_mm)* Wstart;// from DD4HEP cm to mm
+      //    Wend   =(1/dd4hep_mm)* Wend  ;
+      if(m_debug) std::cout<<"DCHDigi wcellid ="<<wcellid<< ",chamber="<<chamber<<",layer="<<layer<<",cellID="<<cellID<<",s_x="<<Wstart.x()<<",s_y="<<Wstart.y()<<",s_z="<<Wstart.z()<<",E_x="<<Wend.x()<<",E_y="<<Wend.y()<<",E_z="<<Wend.z()<<std::endl;
+
+      TVector3  denominator = (Wend-Wstart) ;
+      float min_distance = 999 ;
+      float sim_distance = 999 ;
+      float tmp_distance =0;
+      float SMdca = 0;
+      float distance =0;
+      TVector3 hitPosition;
+      TVector3 PCA;
+      for(unsigned int i=0; i< simhit_size; i++)
+      {
+          float sim_hit_mom = sqrt( iter->second.at(i).getMomentum()[0]*iter->second.at(i).getMomentum()[0] + iter->second.at(i).getMomentum()[1]*iter->second.at(i).getMomentum()[1] + iter->second.at(i).getMomentum()[2]*iter->second.at(i).getMomentum()[2] );//GeV
+          float sim_hit_pt = sqrt( iter->second.at(i).getMomentum()[0]*iter->second.at(i).getMomentum()[0] + iter->second.at(i).getMomentum()[1]*iter->second.at(i).getMomentum()[1] );//GeV
+          TVector3  pos(iter->second.at(i).getPosition()[0]*dd4hep_mm, iter->second.at(i).getPosition()[1]*dd4hep_mm, iter->second.at(i).getPosition()[2]*dd4hep_mm);
+
+          TVector3 sim_mon(iter->second.at(i).getMomentum()[0],iter->second.at(i).getMomentum()[1],iter->second.at(i).getMomentum()[2]);
+          float Steplength = iter->second.at(i).getPathLength();
+          TVector3  pos_start = pos - 0.5 * Steplength * sim_mon.Unit();
+          TVector3  pos_end = pos + 0.5 * Steplength * sim_mon.Unit();
+          tmp_distance = m_segmentation->Distance(wcellid,pos_start,pos_end,hitPosition,PCA);
+          tmp_distance = tmp_distance/dd4hep_mm; //mm
+          sim_distance = tmp_distance;
 
 
+          if(tmp_distance < min_distance){
+              min_distance = tmp_distance;
+              pos_x = hitPosition.x();     //pos.x();
+              pos_y = hitPosition.y();     //pos.y();
+              pos_z = pos.z();
+              momx = iter->second.at(i).getMomentum()[0];
+              momy = iter->second.at(i).getMomentum()[1];
+          }
+          tot_length += iter->second.at(i).getPathLength();//mm
+          auto asso = AssoVec->create();
+          asso.setRec(trkHit);
+          asso.setSim(iter->second.at(i));
+          asso.setWeight(iter->second.at(i).getEDep()/tot_edep);
+          //std::cout<<" asso setRec setSim "<<trkHit<<" "<<iter->second.at(i)<<std::endl;
+
+          if(m_WriteAna && (nullptr!=m_tuple)) {
+              m_simhit_x[m_n_sim] = pos.x();
+              m_simhit_y[m_n_sim] = pos.y();
+              m_simhit_z[m_n_sim] = pos.z();
+              m_Simdca[m_n_sim] = sim_distance;
+              m_simhitT[m_n_sim] = iter->second.at(i).getTime();
+              m_simhitmom[m_n_sim] = sim_hit_mom;
+              m_simPDG[m_n_sim] = iter->second.at(i).getMCParticle().getPDG();
+              m_n_sim ++ ;
+          }
+      }
+
+      trkHit.setTime(min_distance*1e3/m_velocity);//m_velocity is um/ns, drift time in ns
+      trkHit.setEDep(tot_edep);// GeV
+      trkHit.setEdx (tot_edep/tot_length); // GeV/mm
+      trkHit.setPosition (edm4hep::Vector3d(pos_x, pos_y, pos_z));//position of closest sim hit
+      trkHit.setCovMatrix(std::array<float, 6>{m_res_x, 0, m_res_y, 0, 0, m_res_z});//cov(x,x) , cov(y,x) , cov(y,y) , cov(z,x) , cov(z,y) , cov(z,z) in mm
+
+      if(m_WriteAna && (nullptr!=m_tuple)) {
+          m_chamber  [m_n_digi] = chamber;
+          m_layer    [m_n_digi] = layer  ;
+          m_cell     [m_n_digi] = cellID;
+          m_cell_x   [m_n_digi] = Wstart.x();
+          m_cell_y   [m_n_digi] = Wstart.y();
+          m_cell1_x   [m_n_digi] = Wend.x();
+          m_cell1_y   [m_n_digi] = Wend.y();
+          m_hit_x    [m_n_digi] = pos_x;
+          m_hit_y    [m_n_digi] = pos_y;
+          m_hit_z    [m_n_digi] = pos_z;
+          m_mom_x    [m_n_digi] = momx ;
+          m_mom_y    [m_n_digi] = momy ;
+          m_dca      [m_n_digi] = min_distance;
+          m_poca_x   [m_n_digi] = PCA.x();
+          m_poca_y   [m_n_digi] = PCA.y();
+          m_hit_dE   [m_n_digi] = trkHit.getEDep();
+          m_hit_dE_dx[m_n_digi] = trkHit.getEdx() ;
+          m_truthlength[m_n_digi] = tot_length ;
+          m_n_digi ++ ;
+      }
+
+  }
   debug()<<"output digi DCHhit size="<< Vec->size() <<endmsg;
   _nEvt ++ ;
 
   if(m_WriteAna && (nullptr!=m_tuple)){
       StatusCode status = m_tuple->write();
       if ( status.isFailure() ) {
-        error() << "    Cannot fill N-tuple:" << long( m_tuple ) << endmsg;
-        return StatusCode::FAILURE;
+          error() << "    Cannot fill N-tuple:" << long( m_tuple ) << endmsg;
+          return StatusCode::FAILURE;
       }
   }
   m_end = clock();
@@ -255,6 +271,6 @@ StatusCode DCHDigiAlg::execute()
 
 StatusCode DCHDigiAlg::finalize()
 {
-  info() << "Processed " << _nEvt << " events " << endmsg;
-  return GaudiAlgorithm::finalize();
+    info() << "Processed " << _nEvt << " events " << endmsg;
+    return GaudiAlgorithm::finalize();
 }
diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.h b/Digitisers/DCHDigi/src/DCHDigiAlg.h
index d674dc775..4dcf76944 100644
--- a/Digitisers/DCHDigi/src/DCHDigiAlg.h
+++ b/Digitisers/DCHDigi/src/DCHDigiAlg.h
@@ -7,6 +7,7 @@
 #include "edm4hep/SimTrackerHitCollection.h"
 #include "edm4hep/TrackerHitCollection.h"
 #include "edm4hep/MCRecoTrackerAssociationCollection.h"
+#include "edm4hep/MCParticleConst.h"
 
 #include <DDRec/DetectorData.h>
 #include <DDRec/CellIDPositionConverter.h>
@@ -15,8 +16,7 @@
 #include "DetSegmentation/GridDriftChamber.h"
 
 #include "TVector3.h"
-
-
+#include "TRandom3.h"
 
 class DCHDigiAlg : public GaudiAlgorithm
 {
@@ -44,6 +44,8 @@ class DCHDigiAlg : public GaudiAlgorithm
   typedef std::vector<float> FloatVec;
   int _nEvt ;
 
+  TRandom3 fRandom;
+
   NTuple::Tuple* m_tuple = nullptr ;
   NTuple::Item<int> m_evt;
   NTuple::Item<long>   m_n_sim;
@@ -59,16 +61,21 @@ class DCHDigiAlg : public GaudiAlgorithm
   NTuple::Array<float> m_simhit_x  ;
   NTuple::Array<float> m_simhit_y  ;
   NTuple::Array<float> m_simhit_z  ;
+  NTuple::Array<float> m_simhitT ;
+  NTuple::Array<float> m_simhitmom  ;
+  NTuple::Array<int> m_simPDG  ;
   NTuple::Array<float> m_hit_x     ;
   NTuple::Array<float> m_hit_y     ;
   NTuple::Array<float> m_hit_z     ;
   NTuple::Array<float> m_mom_x     ;
   NTuple::Array<float> m_mom_y     ;
   NTuple::Array<float> m_dca       ;
+  NTuple::Array<float> m_Simdca       ;
   NTuple::Array<float> m_poca_x    ;
   NTuple::Array<float> m_poca_y    ;
   NTuple::Array<float> m_hit_dE    ;
   NTuple::Array<float> m_hit_dE_dx ;
+  NTuple::Array<double> m_truthlength ;
 
   clock_t m_start,m_end;
 
@@ -87,6 +94,7 @@ class DCHDigiAlg : public GaudiAlgorithm
   Gaudi::Property<float> m_edep_threshold{ this, "edep_threshold", 0};// GeV
   Gaudi::Property<bool>  m_WriteAna { this, "WriteAna", false};
   Gaudi::Property<bool>  m_debug{ this, "debug", false};
+  Gaudi::Property<double>  m_wireEff{ this, "wireEff", 1.0};
 
 
   // Input collections
diff --git a/Reconstruction/RecGenfitAlg/CMakeLists.txt b/Reconstruction/RecGenfitAlg/CMakeLists.txt
index 566801d15..6136171a0 100644
--- a/Reconstruction/RecGenfitAlg/CMakeLists.txt
+++ b/Reconstruction/RecGenfitAlg/CMakeLists.txt
@@ -2,11 +2,15 @@
 
 if (GenFit_FOUND)
 gaudi_add_module(RecGenfitAlg
-        SOURCES src/RecGenfitAlgDC.cpp
+       SOURCES src/RecGenfitAlgSDT.cpp
                 src/GenfitTrack.cpp
+                src/GenfitHit.cpp
                 src/GenfitField.cpp
                 src/GenfitFitter.cpp
                 src/GenfitMaterialInterface.cpp
+                src/LSFitting.cpp
+                src/WireMeasurementDC.cpp
+                src/PlanarMeasurementSDT.cpp
         LINK GearSvc
              Gaudi::GaudiAlgLib
              Gaudi::GaudiKernel
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitField.cpp b/Reconstruction/RecGenfitAlg/src/GenfitField.cpp
index 744084254..e0b8e3548 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitField.cpp
+++ b/Reconstruction/RecGenfitAlg/src/GenfitField.cpp
@@ -1,4 +1,5 @@
 #include "GenfitField.h"
+#include "GenfitUnit.h"
 
 //External
 #include "DD4hep/DD4hepUnits.h"
@@ -39,16 +40,21 @@ GenfitField::get(const double& posX, const double& posY, const double& posZ,
 {
     /// get field from dd4hepField
     const dd4hep::Direction& field=m_dd4hepField.magneticField(
-            dd4hep::Position(posX/dd4hep::cm,posY/dd4hep::cm,posZ/dd4hep::cm));
-    //m_dd4hepField.magneticField(pos,B);
-
-    Bx=field.X()/dd4hep::kilogauss;
-    By=field.Y()/dd4hep::kilogauss;
-    Bz=field.Z()/dd4hep::kilogauss;
-
-//    std::cout<<"GenfitField "
-//      <<Form("xyz(%f,%f,%f)cm B(%f,%f,%f)kilogauss",posX,posY,posZ,Bx,By,Bz)
-//      <<std::endl;
+            dd4hep::Position(
+              posX/GenfitUnit::cm*dd4hep::cm,
+              posY/GenfitUnit::cm*dd4hep::cm,
+              posZ/GenfitUnit::cm*dd4hep::cm));
+
+    Bx=field.X()/dd4hep::kilogauss*GenfitUnit::kilogauss;
+    By=field.Y()/dd4hep::kilogauss*GenfitUnit::kilogauss;
+    Bz=field.Z()/dd4hep::kilogauss*GenfitUnit::kilogauss;
+
+    //std::cout<<"GenfitField "
+    //  <<Form("xyz(%f,%f,%f)cm B(%f,%f,%f)kilogauss",
+    //      posX/GenfitUnit::cm*dd4hep::cm,
+    //      posY/GenfitUnit::cm*dd4hep::cm,
+    //      posZ/GenfitUnit::cm*dd4hep::cm,Bx,By,Bz)
+    //  <<std::endl;
 }
 
 double GenfitField::getBz(const TVector3& pos) const
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitFitter.cpp b/Reconstruction/RecGenfitAlg/src/GenfitFitter.cpp
index 4850cf4d3..501b5af33 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitFitter.cpp
+++ b/Reconstruction/RecGenfitAlg/src/GenfitFitter.cpp
@@ -1,8 +1,15 @@
+
+#undef GENFIT_MY_DEBUG
+//#define GENFIT_MY_DEBUG 1
 #include "GenfitFitter.h"
 #include "GenfitTrack.h"
 #include "GenfitField.h"
 #include "GenfitMaterialInterface.h"
 
+#ifdef GENFIT_MY_DEBUG
+#include "GenfitHist.h"
+#endif
+
 //Gaudi
 #include "GaudiKernel/StatusCode.h"
 #include "GaudiKernel/ISvcLocator.h"
@@ -33,13 +40,15 @@
 //STL
 #include <iostream>
 #include <string>
+#include <string.h>
 
+//#define GENFIT_MY_DEBUG 1
 
 GenfitFitter::~GenfitFitter(){
     delete m_absKalman;
 }
 
-GenfitFitter::GenfitFitter(const char* type, const char* name):
+GenfitFitter::GenfitFitter(const char* type,int debug,const char* name):
     m_absKalman(nullptr)
     ,m_genfitField(nullptr)
     ,m_geoMaterial(nullptr)
@@ -49,7 +58,7 @@ GenfitFitter::GenfitFitter(const char* type, const char* name):
     ,m_maxIterations(10)
     ,m_deltaPval(1e-3)
     ,m_relChi2Change(0.2)
-    ,m_blowUpFactor(1e3)
+    ,m_blowUpFactor(500)
     ,m_resetOffDiagonals(true)
     ,m_blowUpMaxVal(1.e6)
     ,m_multipleMeasurementHandling(genfit::unweightedClosestToPredictionWire)
@@ -66,9 +75,10 @@ GenfitFitter::GenfitFitter(const char* type, const char* name):
     ,m_noiseBrems(false)
     ,m_ignoreBoundariesBetweenEqualMaterials(true)
     ,m_mscModelName("GEANE")
-    ,m_debug(0)
+    //,m_debug(0)
     ,m_hist(0)
 {
+    m_debug=debug;
     /// Initialize genfit fitter
     init();
 }
@@ -78,15 +88,20 @@ void GenfitFitter::setField(const GenfitField* field)
     if(nullptr==m_genfitField) m_genfitField=field;
 }
 
+
 /// Set geometry for material, use geometry from IOADatabase
-void GenfitFitter::setGeoMaterial(const dd4hep::Detector* dd4hepGeo)
+void GenfitFitter::setGeoMaterial(const dd4hep::Detector* dd4hepGeo,
+        double extDistCut, bool skipWireMaterial)
 {
     if(nullptr==m_geoMaterial){
         m_geoMaterial=GenfitMaterialInterface::getInstance(dd4hepGeo);
     }
+    m_geoMaterial->setMinSafetyDistanceCut(extDistCut);
+    m_geoMaterial->setSkipWireMaterial(skipWireMaterial);
+    m_geoMaterial->setDebugLvl(m_debug);
 }
 
-/// initialize genfit fitter
+/// initialize genfit fitter, old fitter will be deleted
 int GenfitFitter::init(bool deleteOldFitter)
 {
     if(deleteOldFitter && m_absKalman) delete m_absKalman;
@@ -95,17 +110,21 @@ int GenfitFitter::init(bool deleteOldFitter)
         <<m_fitterType<<std::endl;
 
     if (m_fitterType=="DAFRef") {
+        if(m_debug>=2)std::cout<<" m_fitterType==DAFRef "<<std::endl;
         m_absKalman = new genfit::DAF(true,getDeltaPval(),
                 getConvergenceDeltaWeight());
     }
     else if (m_fitterType=="DAF") {
+        if(m_debug>=2)std::cout<<" m_fitterType==DAF"<<std::endl;
         m_absKalman = new genfit::DAF(false,getDeltaPval(),
                 getConvergenceDeltaWeight());
     }
     else if (m_fitterType=="KalmanFitter") {
+        if(m_debug>=2)std::cout<<" m_fitterType==KalmanFitter"<<std::endl;
         m_absKalman = new genfit::KalmanFitter(getMaxIterations());
     }
     else if (m_fitterType=="KalmanFitterRefTrack") {
+        if(m_debug>=2)std::cout<<" m_fitterType==KalmanFitterRefTrack"<<std::endl;
         m_absKalman = new genfit::KalmanFitterRefTrack(getMaxIterations());
     }
     else {
@@ -116,6 +135,9 @@ int GenfitFitter::init(bool deleteOldFitter)
     }
     if(m_debug>=2)std::cout<<"Fitter type is "<<m_fitterType<<std::endl;
     m_absKalman->setDebugLvl(m_debug);
+#ifdef GENFIT_MY_DEBUG
+    //m_absKalman->setDebugLvlLocal(m_debugLocal);
+#endif
 
     return 0;
 }
@@ -125,6 +147,10 @@ int GenfitFitter::processTrackWithRep(GenfitTrack* track,int repID,bool resort)
 {
     if(m_debug>=2)std::cout<< "In ProcessTrackWithRep rep "<<repID<<std::endl;
     if(getDebug()>2) print("");
+    if(track->getNumPoints()<=0){
+        if(m_debug>=2)std::cout<<"skip track w.o. hit"<<std::endl;
+        return false;
+    }
 
     if(getDebug()>0){
         if(m_debug>=2)std::cout<<"Print track seed "<<std::endl;
@@ -147,6 +173,10 @@ int GenfitFitter::processTrackWithRep(GenfitTrack* track,int repID,bool resort)
 int GenfitFitter::processTrack(GenfitTrack* track, bool resort)
 {
     if(m_debug>=2)std::cout<<"In ProcessTrack"<<std::endl;
+    if(track->getNumPoints()<=0){
+        if(m_debug>=2)std::cout<<"skip track w.o. hit"<<std::endl;
+        return false;
+    }
     if(getDebug()>2) print("");
 
     /// Do the fitting
@@ -170,142 +200,6 @@ void GenfitFitter::setFitterType(const char* val)
     init(oldFitterType==val);
 }
 
-/// Extrapolate track to the cloest point of approach(POCA) to the wire of hit,
-/// return StateOnPlane of this POCA
-/// inputs
-///  pos,mom ... position & momentum at starting point, unit= [mm]&[GeV/c]
-///              (converted to [cm]&[GeV/c] inside this function)
-///  hit ... destination
-/// outputs poca [mm] (converted from [cm] in this function) ,global
-double GenfitFitter::extrapolateToHit( TVector3& poca, TVector3& pocaDir,
-        TVector3& pocaOnWire, double& doca, const GenfitTrack* track,
-        TVector3 pos, TVector3 mom,
-        TVector3 end0,//one end of the hit wire
-        TVector3 end1,//the orhter end of the hit wire
-        int debug,
-        int repID,
-        bool stopAtBoundary,
-        bool calcJacobianNoise)
-{
-
-    return track->extrapolateToHit(poca,pocaDir,pocaOnWire,doca,pos,mom,end0,
-            end1,debug,repID,stopAtBoundary,calcJacobianNoise);
-}//end of ExtrapolateToHit
-
-
-/// Extrapolate the track to the cyliner at fixed raidus
-/// position & momentum as starting point
-/// position and momentum at global coordinate in dd4hepUnit
-/// return trackLength in dd4hepUnit
-    double
-GenfitFitter::extrapolateToCylinder(TVector3& pos, TVector3& mom,
-        GenfitTrack* track, double radius, const TVector3 linePoint,
-        const TVector3 lineDirection, int hitID, int repID,
-        bool stopAtBoundary, bool calcJacobianNoise)
-{
-    double trackLength(1e9*dd4hep::cm);
-    if(!track->getFitStatus(repID)->isFitted()) return trackLength;
-    try{
-        // get track rep
-        genfit::AbsTrackRep* rep = track->getRep(repID);
-        if(nullptr == rep) {
-            if(m_debug>=2)std::cout<<"In ExtrapolateToCylinder rep is null"
-                <<std::endl;
-            return trackLength*dd4hep::cm;
-        }
-
-        // get track point with fitter info
-        genfit::TrackPoint* tp =
-            track->getTrack()->getPointWithFitterInfo(hitID,rep);
-        if(nullptr == tp) {
-            if(m_debug>=2)std::cout<<
-                "In ExtrapolateToCylinder TrackPoint is null"<<std::endl;
-            return trackLength*dd4hep::cm;
-        }
-
-        // get fitted state on plane of this track point
-        genfit::KalmanFittedStateOnPlane* state =
-            static_cast<genfit::KalmanFitterInfo*>(
-                    tp->getFitterInfo(rep))->getBackwardUpdate();
-
-        if(nullptr == state){
-            if(m_debug>=2)std::cout<<"In ExtrapolateToCylinder "
-                <<"no KalmanFittedStateOnPlane in backwardUpdate"<<std::endl;
-            return trackLength*dd4hep::cm;
-        }
-        rep->setPosMom(*state, pos*(1/dd4hep::cm), mom*(1/dd4hep::GeV));
-
-        /// extrapolate
-        trackLength = rep->extrapolateToCylinder(*state,
-                radius/dd4hep::cm, linePoint*(1/dd4hep::cm), lineDirection,
-                stopAtBoundary, calcJacobianNoise);
-        // get pos&mom at extrapolated point on the cylinder
-        rep->getPosMom(*state,pos,mom);//FIXME exception exist
-        pos = pos*dd4hep::cm;
-        mom = mom*dd4hep::GeV;
-    } catch(genfit::Exception& e){
-        if(m_debug>=3)std::cout
-            <<"Exception in GenfitFitter::extrapolateToCylinder "
-            << e.what()<<std::endl;
-        trackLength = 1e9*dd4hep::cm;
-    }
-    return trackLength*dd4hep::cm;
-}
-
-double GenfitFitter::extrapolateToPoint(TVector3& pos, TVector3& mom,
-        const GenfitTrack* track,
-        const TVector3& point,
-        int repID,// same with pidType
-        bool stopAtBoundary,
-        bool calcJacobianNoise) const
-{
-    double trackLength(1e9*dd4hep::cm);
-    if(!track->getFitStatus(repID)->isFitted()) return trackLength;
-    try{
-        // get track rep
-        genfit::AbsTrackRep* rep = track->getRep(repID);
-        if(nullptr == rep) {
-            if(m_debug>=2)std::cout<<"In ExtrapolateToPoint rep "
-                <<repID<<" not exist!"<<std::endl;
-            return trackLength*dd4hep::cm;
-        }
-
-        /// extrapolate to point
-        //genfit::StateOnPlane state(*(&(track->getTrack()->getFittedState(0,rep))));
-
-        // get track point with fitter info
-        genfit::TrackPoint* tp =
-            track->getTrack()->getPointWithFitterInfo(0,rep);
-        if(nullptr == tp) {
-            if(m_debug>=2)std::cout<<
-                "In ExtrapolateToPoint TrackPoint is null"<<std::endl;
-            return trackLength*dd4hep::cm;
-        }
-
-        // get fitted state on plane of this track point
-        genfit::KalmanFittedStateOnPlane* state =
-            static_cast<genfit::KalmanFitterInfo*>(
-                    tp->getFitterInfo(rep))->getBackwardUpdate();
-
-        if(nullptr == state) {
-            if(m_debug>=2)std::cout<<
-                "In ExtrapolateToPoint KalmanFittedStateOnPlane is null"<<std::endl;
-            return trackLength*dd4hep::cm;
-        }
-        trackLength = rep->extrapolateToPoint(*state,
-                point*(1/dd4hep::cm),stopAtBoundary, calcJacobianNoise);
-        rep->getPosMom(*state,pos,mom);//FIXME exception exist
-        pos = pos*dd4hep::cm;
-        mom = mom*dd4hep::GeV;
-    } catch(genfit::Exception& e){
-        if(m_debug>=3)std::cout
-            <<"Exception in GenfitFitter::extrapolateToPoint"
-            << e.what()<<std::endl;
-        trackLength = 1e9*dd4hep::cm;
-    }
-    return trackLength*dd4hep::cm;
-}//end of ExtrapolateToPoint
-
 GenfitFitter& GenfitFitter::operator=(
         const GenfitFitter& r)
 {
@@ -370,7 +264,7 @@ void GenfitFitter::print(const char* name)
         <<" m_noiseBrems          = " << m_noiseBrems<<std::endl;
     if(m_debug>=2)std::cout<<name
         <<" m_ignoreBoundariesBetweenEqualMaterials= "
-        << m_ignoreBoundariesBetweenEqualMaterials<<std::endl;
+            << m_ignoreBoundariesBetweenEqualMaterials<<std::endl;
     if(m_debug>=2)std::cout<<name
         <<" m_mscModelName        = " << m_mscModelName<<std::endl;
     if(m_debug>=2)std::cout<<name
@@ -458,18 +352,27 @@ void GenfitFitter::setBlowUpFactor(double val)
 {
     m_absKalman->setBlowUpFactor(val);
     m_blowUpFactor = val;
+    if (m_fitterType=="DAFRef" || m_fitterType=="DAF") {
+        getDAF()->getKalman()->setBlowUpFactor(m_blowUpFactor);
+    }
 }
 
 void GenfitFitter::setResetOffDiagonals(bool val)
 {
     m_absKalman->setResetOffDiagonals(val);
     m_resetOffDiagonals = val;
+    if (m_fitterType=="DAFRef" || m_fitterType=="DAF") {
+        getDAF()->getKalman()->setResetOffDiagonals(m_resetOffDiagonals);
+    }
 }
 
 void GenfitFitter::setBlowUpMaxVal(double val)
 {
     m_absKalman->setBlowUpMaxVal(val);
     m_blowUpMaxVal = val;
+    if (m_fitterType=="DAFRef" || m_fitterType=="DAF") {
+        getDAF()->getKalman()->setBlowUpMaxVal(m_blowUpMaxVal);
+    }
 }
 
 void GenfitFitter::setMultipleMeasurementHandling(
@@ -558,16 +461,33 @@ void GenfitFitter::setMaterialDebugLvl(unsigned int val)
     genfit::MaterialEffects::getInstance()->setDebugLvl(val);
 }
 
-///Set GenfitFitter parameters
 void GenfitFitter::setDebug(unsigned int val)
 {
-    if(m_debug>=2)std::cout<<"set fitter debugLvl "<<val<<std::endl;
-    m_absKalman->setDebugLvl(val);
-    if(nullptr!=getDAF()) getDAF()->setDebugLvl(val);
-    if(val>10) genfit::MaterialEffects::getInstance()->setDebugLvl(val);
     m_debug = val;
 }
 
+void GenfitFitter::setDebugGenfit(unsigned int val)
+{
+    //std::cout<<"set fitter debugGenfit "<<val<<std::endl;
+    m_debugGenfit=val;
+    m_absKalman->setDebugLvl(val);
+}
+
+void GenfitFitter::setDebugLocal(unsigned int val)
+{
+    //std::cout<<"set fitter debugLvlLocal "<<val<<std::endl;
+    m_debugLocal=val;
+#ifdef GENFIT_MY_DEBUG
+    ////std::cout<<" GenfitFitter::setDebugLvlLocal "<<val<<std::endl;
+    //m_absKalman->setDebugLvlLocal(val);
+    //if(0==strncmp(m_fitterType.c_str(),"DAF",3)){
+    //std::cout<<" GenfitFitter::setDebugLvlLocal DAF "<<val<<std::endl;
+    //    getDAF()->setDebugLvlLocal(val+1);
+    //}
+    //getDAF()->setDebugLvlLocal();
+#endif
+}
+
 void GenfitFitter::setHist(unsigned int val) {m_hist = val;}
 
 genfit::DAF* GenfitFitter::getDAF()
@@ -591,21 +511,33 @@ genfit::KalmanFitterRefTrack* GenfitFitter::getKalRef()
     }catch(...){
         if(m_debug>=3)std::cout
             << "dynamic_cast m_rom AbsFitter to KalmanFitterRefTrack m_ailed!"
-            <<std::endl;
+                <<std::endl;
     }
     return ref;
 }
 
 void GenfitFitter::initHist(std::string name)
 {
-    if(m_debug>=2)std::cout<<"GenfitFitter::initHist "<<name<<std::endl;
-    //getDAF()->initHist(name);
+    if(m_debug)std::cout<<"GenfitFitter::initHist "<<name<<std::endl;
+#ifdef GENFIT_MY_DEBUG
+    genfit::GenfitHist::instance()->initHist(name);
+#endif
 }
 
 void GenfitFitter::writeHist()
 {
-    if(m_debug>=2)std::cout<<"GenfitFitter::writeHist "<<std::endl;
-    //getDAF()->writeHist();
+    if(m_debug)std::cout<<"GenfitFitter::writeHist "<<std::endl;
+#ifdef GENFIT_MY_DEBUG
+    if(genfit::GenfitHist::instance()->initialized()){
+        genfit::GenfitHist::instance()->writeHist();
+    }
+#endif
 }
 
 
+void GenfitFitter::SetRunEvent(int event){
+#ifdef GENFIT_MY_DEBUG
+    m_absKalman->SetRunEvent(event);
+#endif
+}
+
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitFitter.h b/Reconstruction/RecGenfitAlg/src/GenfitFitter.h
index 9ca466445..7b3363e6a 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitFitter.h
+++ b/Reconstruction/RecGenfitAlg/src/GenfitFitter.h
@@ -18,6 +18,7 @@
 
 #include "AbsKalmanFitter.h"
 #include <string>
+#include "MaterialEffects.h"
 
 class GenfitField;
 class GenfitMaterialInterface;
@@ -29,6 +30,7 @@ namespace genfit{
     class AbsKalmanFitter;
     class KalmanFitterRefTrack;
     class DAF;
+    class MaterialEffects;
 }
 namespace dd4hep{
     class OverlayedField;
@@ -40,49 +42,22 @@ namespace dd4hep{
 class GenfitFitter{
     public:
         /// Type of fitters are :DAFRef,DAF,KalmanFitter,KalmanFitterRefTrack
-        GenfitFitter(const char* type="DAFRef",const char* name="GenfitFitter");
+        GenfitFitter(const char* type="DAFRef",int debug=0,const char* name="GenfitFitter");
         virtual ~GenfitFitter();
 
         /// Magnetic field and geometry for material effect in genfit
         /// please SET before use !!!!
         void setField(const GenfitField* field);
         /// please SET before use !!!!
-        void setGeoMaterial(const dd4hep::Detector* dd4hepGeo);
+        void setGeoMaterial(const dd4hep::Detector* dd4hepGeo,
+            double extDistCut=1e-4, bool skipWireMaterial=false);
 
         /// Main fitting function
-        int processTrack(GenfitTrack* track, bool resort=false);
+        int processTrack(GenfitTrack* track, bool resort=true);
 
         /// fitting with rep
         int processTrackWithRep(GenfitTrack* track,int repID=0,
-                bool resort=false);
-
-        /// Extrapolate the track to the CDC hit
-        /// Output: poca pos and dir and poca distance to the hit wire
-        /// Input: genfit track, pos and mom, two ends of a wire
-        ///        pos, and mom are position & momentum at starting point
-        double extrapolateToHit(TVector3& poca, TVector3& pocaDir,
-                TVector3& pocaOnWire, double& doca, const GenfitTrack* track,
-                TVector3 pos, TVector3 mom, TVector3 end0, TVector3 end1,
-                int debug=0, int repID=0, bool stopAtBoundary=false,
-                bool calcJacobianNoise=false);
-
-        /// Extrapolate the track to the cyliner at fixed raidus
-        /// Output: pos and mom at fixed radius
-        /// Input: genfitTrack, radius of cylinder at center of the origin,
-        ///        repID, stopAtBoundary and calcAverageState
-        double extrapolateToCylinder(TVector3& pos, TVector3& mom,
-                GenfitTrack* track, double radius, const TVector3 linePoint,
-                const TVector3 lineDirection, int hitID =0, int repID=0,
-                bool stopAtBoundary=false, bool calcJacobianNoise=false);
-
-        /// Extrapolate the track to the point
-        /// Output: pos and mom of POCA point to point
-        /// Input: genfitTrack,point,repID,stopAtBoundary and calcAverageState
-        /// repID same with pidType
-        double extrapolateToPoint(TVector3& pos, TVector3& mom,
-                const GenfitTrack* genfitTrack, const TVector3& point,
-                int repID=0, bool stopAtBoundary = false,
-                bool calcJacobianNoise = false) const;
+                bool resort=true);
 
         /// setters of fitter properties
         void setFitterType(const char* val);
@@ -110,10 +85,16 @@ class GenfitFitter{
         void setMscModelName(std::string val);
         void setMaterialDebugLvl(unsigned int val);
         void setDebug(unsigned int val);
+        void setDebugGenfit(unsigned int val);
+        void setDebugLocal(unsigned int val);
         void setHist(unsigned int val);
 
         /// getters of fitter properties
         std::string getFitterType() const {return m_fitterType;}
+        GenfitMaterialInterface* getGeoMaterial() const {return m_geoMaterial;}
+        genfit::MaterialEffects* getMaterialEffects() const {
+            return genfit::MaterialEffects::getInstance();
+        }
         unsigned int getMinIterations() const { return m_minIterations; }
         unsigned int getMaxIterations() const { return m_maxIterations; }
         double getDeltaPval() const { return m_deltaPval; }
@@ -137,7 +118,10 @@ class GenfitFitter{
         {return m_ignoreBoundariesBetweenEqualMaterials;}
         std::string getMscModelName(){return m_mscModelName;}
         int  getDebug() const {return m_debug;}
+        int  getDebugGenfit() const {return m_debugGenfit;}
+        int  getDebugLocal() const {return m_debugLocal;}
         int  getHist() const {return m_hist;}
+        void SetRunEvent(int event);
 
         /// Printer
         void print(const char* name="");
@@ -194,7 +178,9 @@ class GenfitFitter{
         std::string  m_mscModelName;
 
         int          m_debug;             /// debug
-        int          m_hist;             /// hist
+        int          m_debugGenfit;       /// debug
+        int          m_debugLocal;        /// debug
+        int          m_hist;              /// hist
 };
 
 #endif
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.cpp b/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.cpp
index 73a59316e..031cd7bfa 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.cpp
+++ b/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.cpp
@@ -1,8 +1,8 @@
 ///
 ///   Authors: ZHANG Yao (zhangyao@ihep.ac.cn)
 ///
-
 #include "GenfitMaterialInterface.h"
+#include "GenfitUnit.h"
 //Gaudi
 #include "GaudiKernel/Bootstrap.h"
 #include "GaudiKernel/SmartIF.h"
@@ -21,7 +21,7 @@
 #include "TGeoMaterial.h"
 #include "TGeoManager.h"
 #include "MaterialEffects.h"
-#include "Material.h"
+//#include "Material.h"
 //STL
 #include <assert.h>
 #include <math.h>
@@ -39,6 +39,8 @@ GenfitMaterialInterface::GenfitMaterialInterface(
     assert(nullptr!=dd4hepGeo);
     m_geoManager=&(dd4hepGeo->manager());
     assert(nullptr!=m_geoManager);
+    m_skipWireMaterial=false;
+    debugLvl_=0;
 }
 
 GenfitMaterialInterface* GenfitMaterialInterface::getInstance(
@@ -64,7 +66,6 @@ TGeoManager* GenfitMaterialInterface::getGeoManager()
 GenfitMaterialInterface::initTrack(double posX, double posY,
         double posZ, double dirX, double dirY, double dirZ)
 {
-    //debugLvl_ = 1;
 #ifdef DEBUG_GENFITGEO
     std::cout << "GenfitMaterialInterface::initTrack. \n";
     std::cout << "Pos    "; TVector3(posX, posY, posZ).Print();
@@ -77,11 +78,13 @@ GenfitMaterialInterface::initTrack(double posX, double posY,
     // Set the intended direction.
     setCurrentDirection(dirX, dirY, dirZ);
 
+#ifdef DEBUG_GENFITGEO
     if (debugLvl_ > 0) {
         std::cout << "      GenfitMaterialInterface::initTrack at \n";
         std::cout << "      position:  "; TVector3(posX, posY, posZ).Print();
         std::cout << "      direction: "; TVector3(dirX, dirY, dirZ).Print();
     }
+#endif
 
     return result;
 }
@@ -91,6 +94,9 @@ genfit::Material GenfitMaterialInterface::getMaterialParameters()
 {
     TGeoMaterial* mat =
         getGeoManager()->GetCurrentVolume()->GetMedium()->GetMaterial();
+#ifdef DEBUG_GENFITGEO
+    getGeoManager()->GetCurrentVolume()->Print();
+#endif
     //Scalar density;  /// Density in g / cm^3
     //Scalar Z;  /// Atomic number
     //Scalar A;  /// Mass number in g / mol
@@ -98,6 +104,17 @@ genfit::Material GenfitMaterialInterface::getMaterialParameters()
     //Scalar mEE;  /// Mean excitaiton energy in eV
     //Material from CEPCSW is NOT follow the dd4hep?FIXME
 
+    //getGeoManager()->GetCurrentVolume()->Print();
+    if(m_skipWireMaterial){//FIXME
+        if((strncmp(getGeoManager()->GetCurrentVolume()->GetName(),"FieldWire",9) == 0) ||
+                (strncmp(getGeoManager()->GetCurrentVolume()->GetName(),"SenseWire",9) == 0)){
+            //Air: den 0.0012 radlen 30528.8 Z 7.366 A 14.7844
+            std::cout<<" skipWireMateria "<<std::endl;
+            std::cout<<"CurrentVolume "<<getGeoManager()->GetCurrentVolume()->GetName()<<std::endl;
+            return genfit::Material(0.0012,7.366,14.8744,30528.8,MeanExcEnergy_get(mat));
+        }
+    }
+
     //std::cout<<__FILE__<<" "<<__LINE__<<" yzhang debug material "<<std::endl;
     //mat->Print();
     return genfit::Material(mat->GetDensity(), mat->GetZ(), mat->GetA(),
@@ -110,7 +127,6 @@ GenfitMaterialInterface::findNextBoundary(const genfit::RKTrackRep* rep,
         double sMax, // signed
         bool varField)
 {
-    //debugLvl_ = 1;
     // cm, distance limit beneath which straight-line steps are taken.
     const double delta(1.E-2);
     const double epsilon(1.E-1); // cm, allowed upper bound on arch
@@ -131,6 +147,8 @@ GenfitMaterialInterface::findNextBoundary(const genfit::RKTrackRep* rep,
     findNextBoundary(fabs(sMax) - s);
     double safety = getSafeDistance(); // >= 0
     double slDist = getStep();
+    if (debugLvl_ > 0)
+        std::cout << "   slDist=getStep()= " << slDist<< "; safety=getSafeDistance()=" << safety<< "\n";
 
     // this should not happen, but it happens sometimes.
     // The reason are probably overlaps in the geometry.
@@ -175,6 +193,11 @@ GenfitMaterialInterface::findNextBoundary(const genfit::RKTrackRep* rep,
         state7 = stateOrig;
         rep->RKPropagate(state7, nullptr, SA, stepSign*(s + step), varField);
 
+        if(debugLvl_){
+            std::cout<<" RKTrackRep at state "<<state7[0]<<" "<<state7[1]
+                <<" "<<state7[2] <<" "<<state7[3] <<" "<<state7[4]
+                <<" "<<state7[5] <<" "<<state7[6]<<std::endl;
+        }
         // Straight line distance² between extrapolation finish and
         // the end of the previously determined safe segment.
         double dist2 = (pow(state7[0] - oldState7[0], 2)
@@ -321,12 +344,12 @@ MeanExcEnergy_get(TGeoMaterial* mat) {
 
 double GenfitMaterialInterface::getSafeDistance()
 {
-    return getGeoManager()->GetSafeDistance();
+    return getGeoManager()->GetSafeDistance();//yzhang debug FIXME
 }
 
 double GenfitMaterialInterface::getStep()
 {
-    return getGeoManager()->GetSafeDistance();
+    return getGeoManager()->GetStep();//yzhang debug FIXME
 }
 
 TGeoNode* GenfitMaterialInterface::findNextBoundary(double stepmax,
@@ -340,8 +363,16 @@ bool GenfitMaterialInterface::isSameLocation(double posX, double posY,
 {
     //std::cout<<" MatInt  "<<__LINE__<<" posXYZ*dd4hep::cm "<<posX*dd4hep::cm
     //<<" posY "<<posY*dd4hep::cm<<" posZ "<<posZ*dd4hep::cm<<std::endl;
-    return getGeoManager()->IsSameLocation(posX,posY,
-            posZ,change);
+#ifdef DEBUG_GENFITGEO
+    std::cout<<" MatInt  "<<" posXYZ "<<posX<<" "<<posY<<" "<<posZ<<std::endl;
+#endif
+
+    double rootUnitCM=1.;//FIXME
+    //std::cout<<" MatInt  "<<" posXYZ cm "<<posX/rootUnitCM<<" "<<posY/rootUnitCM<<" "<<posZ/rootUnitCM<<std::endl;
+    return getGeoManager()->IsSameLocation(
+        posX/GenfitUnit::cm*rootUnitCM,
+        posY/GenfitUnit::cm*rootUnitCM,
+        posZ/GenfitUnit::cm*rootUnitCM,change);
 }
 
 void GenfitMaterialInterface::setCurrentDirection(double nx, double ny,
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.h b/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.h
index 83da9fc1e..dbf602610 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.h
+++ b/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.h
@@ -11,6 +11,7 @@
 #define RECGENFITALG_GENFITMATERIALINTERFACE_H
 
 #include "AbsMaterialInterface.h"
+//#include "MaterialProperties.h"
 
 class RKTrackRep;
 class TGeoManager;
@@ -33,6 +34,9 @@ class GenfitMaterialInterface : public genfit::AbsMaterialInterface{
         //Set Detector pointer of dd4hep
         void setDetector(dd4hep::Detector*);
 
+        //void getMaterialParameters(double& density,double& Z,double& A,
+        //        double& radiationLength, double& mEE) {return;}
+        //void getMaterialParameters(genfit::MaterialProperties& parameters) {return;}
         /** @brief Initialize the navigator at given position and with given
           direction.  Returns true if the volume changed.
           */
@@ -54,6 +58,11 @@ class GenfitMaterialInterface : public genfit::AbsMaterialInterface{
                 bool varField = true) override;
 
         // ClassDef(GenfitMaterialInterface, 1);
+        void setMinSafetyDistanceCut(double safeDistCut=1e-7)
+        {m_safeDistCut=safeDistCut;}
+        void setSkipWireMaterial(bool skipWireMateria)
+        {m_skipWireMaterial=skipWireMateria;}
+        virtual void setDebugLvl(unsigned int lvl = 1) {debugLvl_ = lvl;}
 
     private:
         static GenfitMaterialInterface* m_instance;
@@ -66,6 +75,8 @@ class GenfitMaterialInterface : public genfit::AbsMaterialInterface{
         bool isSameLocation(double posX, double posY, double posZ,
                 bool change=false);
         void setCurrentDirection(double nx, double ny, double nz);
+        double m_safeDistCut;
+        bool m_skipWireMaterial;
 
 };
 
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp b/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp
index 7209847b8..5f2c9475f 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp
+++ b/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp
@@ -1,120 +1,142 @@
 #include "GenfitTrack.h"
+#include "GenfitHit.h"
 #include "GenfitField.h"
 
 //CEPCSW
 #include "DataHelper/HelixClass.h"
+#include "DataHelper/TrackHelper.h"
+#include "DataHelper/TrackerHitHelper.h"
+#include "DetInterface/IGeomSvc.h"
+#include "GenfitUnit.h"
 #include "UTIL/ILDConf.h"
+#include "WireMeasurementDC.h"
 
 //Externals
 #include "DD4hep/DD4hepUnits.h"
-#include "edm4hep/MCParticle.h"
+#include "DD4hep/Detector.h"
+#include "DD4hep/DetElement.h"
+#include "DD4hep/Segmentations.h"
+#include "DDRec/ISurface.h"
+#include "DDRec/SurfaceManager.h"
+#include "DDRec/Vector3D.h"
+#include "DetSegmentation/GridDriftChamber.h"
+#include "edm4hep/MutableReconstructedParticle.h"
+#include "edm4hep/SimTrackerHit.h"
 #include "edm4hep/Track.h"
 #include "edm4hep/MutableTrack.h"
 #include "edm4hep/TrackerHit.h"
-#include "edm4hep/SimTrackerHit.h"
-#include "edm4hep/ReconstructedParticle.h"
-#include "edm4hep/MutableReconstructedParticle.h"
 #include "edm4hep/TrackerHitCollection.h"
+#include "edm4hep/MCParticle.h"
 #include "edm4hep/MCRecoTrackerAssociationCollection.h"
 #include "edm4hep/Vector3d.h"
-#include "DetSegmentation/GridDriftChamber.h"
+#include "GaudiKernel/SmartIF.h"
 
 //genfit
-#include "Track.h"
-#include "MeasuredStateOnPlane.h"
-#include "RKTrackRep.h"
-#include "TrackPoint.h"
-#include "StateOnPlane.h"
-#include "KalmanFitterInfo.h"
-#include "KalmanFittedStateOnPlane.h"
+#include "AbsMeasurement.h"
 #include "AbsTrackRep.h"
 #include "FitStatus.h"
+#include "KalmanFitterInfo.h"
+#include "KalmanFittedStateOnPlane.h"
+#include "RKTrackRep.h"
+//#include "PlanarMeasurement.h"
+#include "PlanarMeasurementSDT.h"
 #include "SpacepointMeasurement.h"
+#include "StateOnPlane.h"
+#include "RectangularFinitePlane.h"
+#include "Track.h"
+#include "TrackPoint.h"
+#include "MeasuredStateOnPlane.h"
 #include "WireMeasurementNew.h"
+#include "AbsMeasurement.h"
+#include "TrackPoint.h"
 
 //ROOT
-#include "TRandom.h"
-#include "TVector3.h"
 #include "TLorentzVector.h"
 #include "TMatrixDSym.h"
+#include "TRandom.h"
+#include "TVector3.h"
 
 //cpp
 #include <cfloat>
 
+#undef GENFIT_MY_DEBUG
+//#define GENFIT_MY_DEBUG 1
+
 const int GenfitTrack::s_PDG[2][5]
 ={{-11,-13,211,321,2212},{11,13,-211,-321,-2212}};
 
     bool
-sortDCHit(edm4hep::SimTrackerHit hit1,edm4hep::SimTrackerHit hit2)
+sortDCSimHit(edm4hep::SimTrackerHit hit1,edm4hep::SimTrackerHit hit2)
 {
     //std::cout<<"hit1"<<hit1<<std::endl;
     //std::cout<<"hit2"<<hit2<<std::endl;
     bool isEarly=hit1.getTime()<hit2.getTime();
     return isEarly;
 }
-
-    GenfitTrack::GenfitTrack(const GenfitField* genfitField, const dd4hep::DDSegmentation::GridDriftChamber* seg, const char* name)
-:m_name(name),m_track(nullptr),m_reps(),m_debug(0),
-m_genfitField(genfitField),m_gridDriftChamber(seg)
+    bool
+sortDCDigi(std::pair<double,edm4hep::TrackerHit*> hitPair1,std::pair<double,edm4hep::TrackerHit*> hitPair2)
+{
+    bool isEarly=hitPair1.first<hitPair2.first;
+    return isEarly;
+}
+//bool sortDCDigiLayer(std::pair<int,edm4hep::TrackerHit> hitPair1,std::pair<int,edm4hep::TrackerHit> hitPair2)
+//{
+//    bool isEarly=hitPair1.first<hitPair2.first;
+//    return isEarly;
+//}
+
+
+GenfitTrack::GenfitTrack(const GenfitField* genfitField,
+        const dd4hep::DDSegmentation::GridDriftChamber* seg,
+        SmartIF<IGeomSvc> geom, const char* name)
+:m_name(name),m_track(nullptr),m_debug(0),m_debugLocal(0),m_geomSvc(geom),
+    m_genfitField(genfitField),m_gridDriftChamber(seg),
+    m_decoderDC(geom->getDecoder("DriftChamberHitsCollection"))
 {
-
 }
 
 GenfitTrack::~GenfitTrack()
 {
+    clearGenfitHitVec();
     ///Note: track reps and points will be deleted in the destructor of track
     ///implemented in genfit::Track::Clear()
     delete m_track;
 }
 
-/// create a Genfit track from track state, without trackRep
-/// Initialize track with seed states
-/// NO unit conversion here
+void GenfitTrack::clearGenfitHitVec(){
+    for(auto h:m_genfitHitVec){delete h;}
+    m_genfitHitVec.clear();
+    std::vector<GenfitHit*>().swap(m_genfitHitVec);
+}
+
+/// create a Genfit track from track state
+/// Initialize track with seed state and cov
+/// unit conversion here!!!
 bool GenfitTrack::createGenfitTrack(int pdgType,int charge,
-        TLorentzVector posInit, TVector3 momInit, TMatrixDSym covMInit)
+        TVectorD trackParam, TMatrixDSym covMInit_6)
 {
-    TVectorD seedState(6);
-    TMatrixDSym seedCov(6);
-
-    //for(int i = 0; i < 6; ++i) {
-    //  for(int j = 0; j < 6; ++j) {
-    //    seedCov(i,j)=covMInit(i,j);
-    //  }
-    //}
-    //yzhang FIXME
-    //seed position
-    for(int i = 0; i < 3; ++i) {
-        seedState(i)=posInit[i];
-        //yzhang TODO from covMInit to seedCov
-        double resolution = 0.1;//*dd4hep::mm/dd4hep::cm;
-        seedCov(i,i)=resolution*resolution;
-        if(i==2) seedCov(i,i)=0.5*0.5;
-    }
-    //seed momentum
-    for(int i = 3; i < 6; ++i){
-        //seedState(i)=momInit[i-3]*(dd4hep::GeV);
-        seedState(i)=momInit[i-3];
-        //yzhang TODO from covMInit to seedCov
-        seedCov(i,i)=0.01;//pow(resolution / sqrt(3),2);
-    }
-
-    if(nullptr==m_track) m_track=new genfit::Track();
-    m_track->setStateSeed(seedState);
-    m_track->setCovSeed(seedCov);
-
-    /// new a track representation and add to the track
-    int chargeId=0;
-    charge>0 ? chargeId=0 : chargeId=1;
+    if(m_debug){
+        std::cout<<"createGenfitTrack pdgType "<<pdgType<<" charge "<<charge
+          <<" trackParam "<<std::endl; trackParam.Print();
+        std::cout<<"Cov"<<std::endl; covMInit_6.Print();
+    }
+    ///new a track and set seed state and cov
+    if(nullptr!=m_track) {
+        delete m_track;
+        clearGenfitHitVec();
+    }
+    m_track=new genfit::Track();
+    m_track->setStateSeed(trackParam);
+    m_track->setCovSeed(covMInit_6);
 
-    if(m_debug>=2)std::cout<<m_name<<" CreateGenfitTrack seed pos("
-        <<seedState[0]<<" "<<seedState[1]<<" "<<seedState[2]<<")cm ("
-        <<seedState[3]<<" "<<seedState[4]<<" "<<seedState[5]<<")GeV charge "
-        <<charge<<" pdg "<<s_PDG[chargeId][pdgType]<<std::endl;
-    if(m_debug>=2)std::cout<<"seedCov "<<std::endl;
+#ifdef GENFIT_MY_DEBUG
+    //m_track->setDebugLvlLocal(m_debugLocal);
+#endif
 
-    addTrackRep(s_PDG[chargeId][pdgType]);
+    ///new a track representation and add to the track
+    addTrackRep(pdgType,charge);
 
-    if(m_debug>0) seedCov.Print();
+    if(m_debug>0) printSeed();
     return true;
 }
 
@@ -122,227 +144,292 @@ bool GenfitTrack::createGenfitTrack(int pdgType,int charge,
 bool GenfitTrack::createGenfitTrackFromMCParticle(int pidType,
         const edm4hep::MCParticle& mcParticle, double eventStartTime)
 {
-    ///get track parameters from McParticle
-    edm4hep::Vector3d mcPocaPos = mcParticle.getVertex();//mm
-    edm4hep::Vector3f mcPocaMom = mcParticle.getMomentum();//GeV
-    if(m_debug>=2)std::cout<<"seedPos poca "<< mcPocaPos.x
-        <<" "<<mcPocaPos.y<<" "<<mcPocaPos.z<<" mm "<<std::endl;
-    if(m_debug>=2)std::cout<<"seedMom poca "<< mcPocaMom.x
-        <<" "<<mcPocaMom.y<<" "<<mcPocaMom.z<<" GeV "<<std::endl;
-
-    ///Pivot to first layer to avoid correction of beam pipe
-    edm4hep::Vector3d firstLayerPos(1e9,1e9,1e9);
-    edm4hep::Vector3f firstLayerMom(1e9,1e9,1e9);
-    pivotToFirstLayer(mcPocaPos,mcPocaMom,firstLayerPos,firstLayerMom);
-
-    //TODO convert unit
-    ///Get seed position and momentum
-    TLorentzVector seedPos(firstLayerPos.x,firstLayerPos.y,firstLayerPos.z,
-            eventStartTime);
-    TVector3 seedMom(firstLayerMom.x,firstLayerMom.y,firstLayerMom.z);
-    if(m_debug>=2)std::cout<<"seedPos "<< firstLayerPos.x
-        <<" "<<firstLayerPos.y<<" "<<firstLayerPos.z<<std::endl;
-    if(m_debug>=2)std::cout<<"seedMom "<< firstLayerMom.x
-        <<" "<<firstLayerMom.y<<" "<<firstLayerMom.z<<std::endl;
-
     ///Get error matrix of seed track
-    TMatrixDSym covM(5);//FIXME, TODO
-
-    ///Create a genfit track with seed
-    if(m_debug>=2)std::cout<<"createGenfitTrack " ;
-    if(!GenfitTrack::createGenfitTrack(pidType,mcParticle.getCharge(),
-                seedPos,seedMom,covM)){
-        if(m_debug>=2)std::cout<<"GenfitTrack"
-            <<" Error in createGenfitTrack" <<std::endl;
-        return false;
-    }else{
-        if(m_debug>=2)std::cout<<"GenfitTrack "
-            <<"createGenfitTrackFromMCParticle track created" <<std::endl;
-    }
-    return true;
+    TMatrixDSym covMInit_6(6);
+    getSeedCov(covMInit_6);
+    TVectorD seedState(6);
+    getTrackFromMCPartile(mcParticle,seedState,covMInit_6);
+
+    return createGenfitTrack(pidType,mcParticle.getCharge(),seedState,covMInit_6);
 }//end of createGenfitTrackFromMCParticle
 
-///Create a Genfit track with MCParticle, unit conversion here
+///Create a Genfit track with edm4hep Track
 bool GenfitTrack::createGenfitTrackFromEDM4HepTrack(int pidType,
-        edm4hep::Track track, double eventStartTime)
+        const edm4hep::Track& track, double eventStartTime, bool isUseCovTrack)
 {
-    //std::cout<<__FILE__<<"   "<<__LINE__<<" bz kilogauss "<<m_genfitField->getBz({0.,0.,0.})/dd4hep::kilogauss<<std::endl;
-    //std::cout<<__FILE__<<"   "<<__LINE__<<" bz tesla "<<m_genfitField->getBz({0.,0.,0.})/dd4hep::tesla<<std::endl;
-    //std::cout<<__FILE__<<"   "<<__LINE__<<" bz "<<m_genfitField->getBz({0.,0.,0.})<< dd4hep::kilogauss <<" "<<dd4hep::tesla<<std::endl;
-    //TODO
-    //pivotToFirstLayer(mcPocaPos,mcPocaMom,firstLayerPos,firstLayerMom);
-    //Get track parameters
-    edm4hep::TrackState trackStat=track.getTrackStates(0);//FIXME?
-    HelixClass helixClass;
-    helixClass.Initialize_Canonical(trackStat.phi,trackStat.D0,
-            trackStat.Z0,trackStat.omega,trackStat.tanLambda,
-            m_genfitField->getBz({0.,0.,0.})*dd4hep::kilogauss/dd4hep::tesla);
-    TLorentzVector posInit(helixClass.getReferencePoint()[0],
-            helixClass.getReferencePoint()[1],
-            helixClass.getReferencePoint()[2],eventStartTime);
-    posInit.SetX(posInit.X()*dd4hep::mm);
-    posInit.SetY(posInit.Y()*dd4hep::mm);
-    posInit.SetZ(posInit.Z()*dd4hep::mm);
-    TVector3 momInit(helixClass.getMomentum()[0],
-            helixClass.getMomentum()[1],helixClass.getMomentum()[2]);
-    momInit.SetX(momInit.x()*dd4hep::GeV);
-    momInit.SetY(momInit.y()*dd4hep::GeV);
-    momInit.SetZ(momInit.z()*dd4hep::GeV);
-    TMatrixDSym covMInit;
-    if(!createGenfitTrack(pidType,
-                int(trackStat.omega/fabs(trackStat.omega)),//charge,FIXME?
-                posInit,momInit,covMInit)){
+
+    ///Skip track w.o. hit
+    if(track.trackerHits_size()<=0) {
+        std::cout << " track.trackerHits_size = " << track.trackerHits_size() << std::endl;
+        if(m_debug){
+          std::cout<<"createGenfitTrackFromEDM4HepTrack skip track w/o hit"<<std::endl;
+        }
         return false;
     }
-    return true;
+
+    //pivotToFirstLayer(mcPocaPos,mcPocaMom,firstLayerPos,firstLayerMom);
+    ///Get track parameters
+    double charge=0;
+    TVectorD seedState(6);
+    TMatrixDSym covMInit_6(6);
+
+    getTrackFromEDMTrack(track,charge,seedState,covMInit_6);///unit conversion
+    if(!isUseCovTrack) getSeedCov(covMInit_6);
+
+    bool status=createGenfitTrack(pidType,charge,seedState,covMInit_6);
+    return status;
 }
 
-/// Add a 3d SpacepointMeasurement on TrackerHit
-bool GenfitTrack::addSpacePointTrakerHit(edm4hep::TrackerHit hit,
-        int hitID)
+/// Add a 3d SpacepointMeasurement
+bool GenfitTrack::addSpacePointMeasurement(const TVector3& pos,
+        std::vector<float> sigmaUVec,std::vector<float> sigmaVVec,int cellID,int hitID)
 {
-    edm4hep::Vector3d pos=hit.getPosition();
-    TVectorD p(3);
-    p[0]=pos.x*dd4hep::mm;
-    p[1]=pos.y*dd4hep::mm;
-    p[2]=pos.z*dd4hep::mm;
+    TVectorD pos_smeared(3);
+    for(int i=0;i<3;i++) pos_smeared[i]=pos(i)*GenfitUnit::mm;
 
-    if(m_debug>=2)std::cout<<m_name<<" addSpacePointTrakerHit"<<hitID
-        <<"pos "<<p[0]<<" "<<p[1]<<" "<<p[2]<<" cm"<<std::endl;
     /// New a SpacepointMeasurement
-    double cov[6];
-    for(int i=0;i<6;i++) {
-        cov[i]=hit.getCovMatrix(i);
-        if(m_debug>=2)std::cout<<"cov "<<cov[i]<<std::endl;
-    }
-    TMatrixDSym hitCov(3);//FIXME?
-    //in SimpleDigi/src/PlanarDigiAlg.cpp
-    //cov[0] = u_direction[0];
-    //cov[1] = u_direction[1];
-    //cov[2] = resU;
-    //cov[3] = v_direction[0];
-    //cov[4] = v_direction[1];
-    //cov[5] = resV;
-    hitCov(0,0)=cov[2]*dd4hep::mm*dd4hep::mm;
-    hitCov(1,1)=cov[2]*dd4hep::mm*dd4hep::mm;
-    hitCov(2,2)=cov[2]*dd4hep::mm*dd4hep::mm;
-
-    genfit::SpacepointMeasurement* sMeas =
-        new genfit::SpacepointMeasurement(p,hitCov,(int) hit.getCellID(),hitID,
-                nullptr);
-    genfit::TrackPoint* trackPoint = new genfit::TrackPoint(sMeas,m_track);
-    m_track->insertPoint(trackPoint);
+    /// space point error matrix and smear, unit cm
+    TMatrixDSym hitCov(3);
+    hitCov.Zero();
+
+    //get sigmas
+    float sigmaU,sigmaV;
+    getSigmas(cellID,sigmaUVec,sigmaVVec,sigmaU,sigmaV);
+    float sigmaX=sigmaU;//sigmaU*cos(atan2(pos_smeared[1],pos_smeared[0]));
+    float sigmaY=sigmaU;//*sin(atan2(pos_smeared[1],pos_smeared[0]));
+    float sigmaZ=sigmaV;
+
+    //smear 3d track position
+    bool smear=(sigmaUVec[0]>0);
+    if(smear){
+        pos_smeared[0]+=gRandom->Gaus(0,sigmaX);
+        pos_smeared[1]+=gRandom->Gaus(0,sigmaX);
+        pos_smeared[2]+=gRandom->Gaus(0,sigmaX);
+    }
+    hitCov(0,0)=sigmaX*sigmaX;//FIXME
+    hitCov(1,1)=sigmaX*sigmaX;
+    hitCov(2,2)=sigmaX*sigmaX;
+
+    if(m_debug>=2){
+        std::cout<<" addSpacePointMeasurement pos "<<std::endl;
+        pos.Print();
+        std::cout<<m_name<<" hit "<<hitID
+            <<" pos_smeared "<<pos_smeared[0]<<" "<<pos_smeared[1]
+            <<" "<<pos_smeared[2]<<" "<<" hitCov (0,0) "<<hitCov(0,0)<<" cm"<<std::endl;
+        hitCov.Print();
+    }
 
-    if(m_debug>=2)std::cout<<"end of addSpacePointTrakerHit"<<std::endl;
+    /// new space point and TrackPoint, unit in cm
+    genfit::TrackPoint* trackPoint = new genfit::TrackPoint(
+            new genfit::SpacepointMeasurement(pos_smeared,hitCov,
+                cellID ,hitID, nullptr), m_track);
+    if(m_debug>=2){
+        std::cout<<m_name<<" add TrackPoint \n";
+        trackPoint->Print();
+    }
+    m_track->insertPoint(trackPoint);
     return true;
+}//end of addSpacePointMeasurement
+
+/// Return isurface of a silicon hit
+const dd4hep::rec::ISurface*
+GenfitTrack::getISurface(edm4hep::TrackerHit* hit){
+    dd4hep::rec::SurfaceManager surfaceManager(*m_geomSvc->lcdd());
+
+    std::string detectorName;
+    unsigned long long cellID=hit->getCellID();
+    int detTypeID=getDetTypeID(hit->getCellID());
+    if(detTypeID==lcio::ILDDetID::VXD){
+        detectorName="VXD";
+        if(hit->getPosition().z>0){
+            cellID+=0x100000000;
+        }else{
+            cellID+=0x300000000;
+        }
+    }else if(detTypeID==lcio::ILDDetID::SIT){
+        detectorName="SIT";
+    }else if(detTypeID==lcio::ILDDetID::SET){
+        detectorName="SET";
+    }else if(detTypeID==lcio::ILDDetID::FTD){
+        detectorName="FTD";
+    }else{
+        std::cout << "ERROR:getISurface  iSurface = NULL!" << std::endl;
+        return nullptr;
+    }
+    if(m_debug>2) std::cout<<m_name<<" detectorName  "<<detectorName
+        <<" hit position mm "<<hit->getPosition()<<" hit.cellID "<<hit->getCellID()
+            <<" cellId "<<cellID<<" detTypeID "<<detTypeID<<std::endl;
+    const dd4hep::rec::SurfaceMap* surfaceMap=surfaceManager.map(detectorName);
+    auto iter=surfaceMap->find(cellID);
+    dd4hep::rec::ISurface* iSurface=nullptr;
+    if(iter!=surfaceMap->end()){iSurface=(*iter).second;}
+
+    //std::multimap< unsigned long, dd4hep::rec::ISurface*>::const_iterator it,itend;
+    //it=surfaceMap->begin();
+    //itend= surfaceMap->end();
+    //std::cout<<" print map "<<detectorName<<std::endl;
+    //for(; it!=itend; it++){
+    //    dd4hep::rec::ISurface* surf = it->second;
+    //    dd4hep::rec::Vector3D origin = surf->origin();
+    //    std::cout <<"surf id "<< surf->id() << " origin xyz " << origin.x()
+    //        << " " << origin.y() << " " << origin.z() << std::endl;
+    //}
+    return iSurface;
 }
 
-/// Add a 3d SpacepointMeasurement with MC truth position smeared by sigma
-bool GenfitTrack::addSpacePointMeasurement(const TVectorD& pos,
-        double sigma, int detID, int hitID, bool smear)
+/// Add a 1d strip or 2d pixel smeared by sigma
+    bool
+GenfitTrack::addSiliconMeasurement(edm4hep::TrackerHit* hit,
+        float sigmaU,float sigmaV,int cellID,int hitID)
 {
-    double sigma_t=sigma*dd4hep::mm;
-    /// Convert from CEPCSW unit to genfit unit, cm
-    TVectorD pos_t(3);
-    pos_t(0)=pos(0)*dd4hep::mm;
-    pos_t(1)=pos(1)*dd4hep::mm;
-    pos_t(2)=pos(2)*dd4hep::mm;
+    if(m_debug>0) std::cout<<"addSiliconMeasurement "<<*hit<<std::endl;
 
-    /// smear hit position with same weight
-    TVectorD pos_smeared(3);
-    for (int i=0;i<3;i++){
-        pos_smeared[i]=pos_t(i);
-        if(smear) pos_smeared[i]+=gRandom->Gaus(0,sigma_t/TMath::Sqrt(3.));
+    ///get surface by cellID
+    const dd4hep::rec::ISurface* iSurface = getISurface(hit);
+    if(nullptr==iSurface){
+        std::cout<<m_name<<" addSiliconMeasurement get surface ERROR!"<<std::endl;
+        return false;
     }
+    TVector3 o,u,v;
+    double lengthU,lengthV;
+    getISurfaceOUV(iSurface,o,u,v,lengthU,lengthV);
 
-    /// New a SpacepointMeasurement
-    TMatrixDSym hitCov(3);
-    hitCov(0,0)=sigma_t*sigma_t;
-    hitCov(1,1)=sigma_t*sigma_t;
-    hitCov(2,2)=sigma_t*sigma_t;
-
-    if(m_debug>=2)std::cout<<m_name<<" addSpacePointMeasurement detID "
-        <<detID<<" hitId "<<hitID<<" " <<pos_t[0]<<" "<<pos_t[1]<<" "<<pos_t[2]
-        <<" cm smeared "<<pos_smeared[0]<<" "<<pos_smeared[1]<<" "
-        <<pos_smeared[2]<<" sigma_t "<<sigma_t<<" cm"<<std::endl;
-
-    genfit::SpacepointMeasurement* sMeas =
-        new genfit::SpacepointMeasurement(pos_smeared,hitCov,detID,hitID,nullptr);
-    genfit::TrackPoint* trackPoint = new genfit::TrackPoint(sMeas,m_track);
-    m_track->insertPoint(trackPoint);
+    ///Get detector plane parameter
+    //VXD
+    //SIT
+    //SET
+
+    ///Get measurement and cov
+    TVectorD hitCoords(2);
+    TVector3 p;
+    TMatrixDSym hitCov(2);
+    getMeasurementAndCov(hit,p,hitCov);
+    hitCoords(0)=(p-o).Dot(u);
+    hitCoords(1)=(p-o).Dot(v);
+    if(m_debug) std::cout<<"yzhang debug hitCoords cm "<<hitCoords(0)<<" "<<hitCoords(1)<<std::endl;
+    hitCov.Zero();
+    hitCov(0,0)=sigmaU*sigmaU;
+    hitCov(1,1)=sigmaV*sigmaV;
+
+    ///Create planer finite detector plane, measurement and TrackPoint
+    genfit::RectangularFinitePlane* pixelOrStripPlane=
+        new genfit::RectangularFinitePlane(
+                -lengthU/2.,lengthU/2.,-lengthV/2.,lengthV/2.);
+    genfit::SharedPlanePtr plane(new genfit::DetPlane(o,u,v));
+    plane->setFinitePlane(pixelOrStripPlane);
+    genfit::PlanarMeasurementSDT* planarMeasurement=new genfit::PlanarMeasurementSDT(
+            hitCoords,hitCov,cellID,hitID,nullptr);
+    planarMeasurement->setTrackerHit(hit);
+    //genfit::PlanarMeasurement* planarMeasurement=new genfit::PlanarMeasurement(
+    //        hitCoords,hitCov,cellID,hitID,nullptr);
+    planarMeasurement->setPlane(plane);
+    m_track->insertPoint(new genfit::TrackPoint(planarMeasurement,m_track));
+
+    if(m_debug>2){
+        std::cout<<"hitID "<<hitID<<" unit cm"<<std::endl;
+        std::cout<<"sigmaU "<<sigmaU<<" sigmaV "<<sigmaV<<std::endl;
+        std::cout<<"lengthU "<<lengthU<<" lengthV "<<lengthV<<std::endl;
+        std::cout<<"u "<<u.x()<<" "<<u.y()<<" "<<u.z()<<std::endl;
+        std::cout<<"v "<<v.x()<<" "<<v.y()<<" "<<v.z()<<std::endl;
+        std::cout<<"o "<<o.x()<<" "<<o.y()<<" "<<o.z()<<std::endl;
+        std::cout<<"p "<<p.x()<<" "<<p.y()<<" "<<p.z()<<std::endl;
+        std::cout<<"hitCoords "<<hitCoords(0)<<" "<<hitCoords(1)<<std::endl;
+        std::cout<<"hitCov "<<hitCov(0,0)<<" "<<hitCov(1,1)<<std::endl;
+    }
 
     return true;
 }
 
+int GenfitTrack::addSiliconMeasurements(edm4hep::Track& track,
+        std::vector<float> sigmaUVec,std::vector<float> sigmaVVec)
+{
+    ///Get TrackerHit on Track
+    int nHitAdd=0;
+    for(unsigned int iHit=0;iHit<track.trackerHits_size();iHit++){
+        edm4hep::TrackerHit* trackerHit=
+          new edm4hep::TrackerHit(track.getTrackerHits(iHit));
+        unsigned long long cellID=trackerHit->getCellID();
+        float sigmaU,sigmaV;
+        int sigmaUID=getSigmas(cellID,sigmaUVec,sigmaVVec,sigmaU,sigmaV);
+        if(0==sigmaUID) continue;//skip DC track
+        addSiliconMeasurement(trackerHit,sigmaU,sigmaV,cellID,nHitAdd++);
+        GenfitHit* genfitHit=
+            new GenfitHit(trackerHit,nullptr,nullptr,
+            nullptr,0.,0.);
+        if(nullptr==genfitHit) continue;
+        m_genfitHitVec.push_back(genfitHit);
+    }
+    return nHitAdd;
+}
 
-/// Add a WireMeasurement, no Unit conversion here
-void GenfitTrack::addWireMeasurement(double driftDistance,
-        double driftDistanceError, const TVector3& endPoint1,
-        const TVector3& endPoint2, int lrAmbig, int detID, int hitID)
+//Add wire measurement on wire, unit conversion here
+//int GenfitTrack::addWireMeasurementsFromList(podio::RelationRange<edm4hep::TrackerHit> hits,float sigma,
+int GenfitTrack::addWireMeasurementsFromList(std::vector<edm4hep::TrackerHit*>& hits,float sigma,
+        const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
+        int sortMethod, bool truthAmbig,float skipCorner,float skipNear)
 {
-    try{
-        /// New a WireMeasurement
-        genfit::WireMeasurementNew* wireMeas = new genfit::WireMeasurementNew(
-                driftDistance, driftDistanceError, endPoint1, endPoint2, detID,
-                hitID, nullptr);
-        wireMeas->setMaxDistance(0.5);//0.5 cm FIXME
-        wireMeas->setLeftRightResolution(lrAmbig);
-
-        if(m_debug>=2)std::cout<<m_name<<" Add wire measurement(cm) "<<hitID
-            <<" ep1("<<endPoint1[0]<<" "<<endPoint1[1]<<" "<<endPoint1[2]
-            <<") ep2("<<endPoint2[0]<<" "<<endPoint2[1]<<" "<<endPoint2[2]
-            <<") drift "<<driftDistance<<" driftErr "<<driftDistanceError
-            <<" lr "<<lrAmbig<<" detId "<<detID << " hitId "<< hitID
-            <<std::endl;
+    if(m_debug>0){ std::cout<<"addWireMeasurementsFromList"<<std::endl; }
+    //podio::RelationRange<edm4hep::TrackerHit> hits_t=track.getTrackerHits();
+    std::vector<edm4hep::TrackerHit*> sortedTrackerHits;
+//    sortedTrackerHits.reserve(100);
+    getSortedTrackerHits(hits,assoHits,sortedTrackerHits,sortMethod);
+
+    if(m_debug>0){
+      std::cout<<"n sortedTrackerHits "<<sortedTrackerHits.size()<<std::endl;
+    }
+    int nHitAdd=0;
+    for(auto trackerHit : sortedTrackerHits){
+        edm4hep::SimTrackerHit simTrackerHitAsso;
+        getAssoSimTrackerHit(assoHits,trackerHit,simTrackerHitAsso);
+        //FIXME driftVelocity
+        GenfitHit* genfitHit=
+            makeAGenfitHit(trackerHit,&simTrackerHitAsso,sigma,truthAmbig,
+                    skipCorner,skipNear);
+        if(nullptr==genfitHit) continue;
+        m_genfitHitVec.push_back(genfitHit);
 
         ///New a TrackPoint,create connection between meas. and trackPoint
-        genfit::TrackPoint* trackPoint=new genfit::TrackPoint(wireMeas,m_track);
-        wireMeas->setTrackPoint(trackPoint);
-
-        m_track->insertPoint(trackPoint);
-
-    }catch(genfit::Exception& e){
-        if(m_debug>=2)std::cout<<m_name
-            <<"Add wire measurement exception"<<std::endl;
-        e.what();
-    }
-}//end of addWireMeasurementOnTrack
+        WireMeasurementDC* wireMeasurementDC=
+            new WireMeasurementDC(genfitHit,nHitAdd++);
+        m_track->insertPoint(new genfit::TrackPoint(wireMeasurementDC,m_track));
+        if(m_debug>=2){ std::cout<<nHitAdd-1; wireMeasurementDC->Print(); }
+    }//end of loop over sotred hits
+    return nHitAdd;
+}//end of addWireMeasurementsFromList
 
 //Add wire measurement on wire, unit conversion here
-bool GenfitTrack::addWireMeasurementOnTrack(edm4hep::Track track,double sigma)
+int GenfitTrack::addWireMeasurementsOnTrack(edm4hep::Track& track,float sigma,
+        const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
+        int sortMethod, bool truthAmbig,float skipCorner,float skipNear)
 {
-    for(unsigned int iHit=0;iHit<track.trackerHits_size();iHit++){
-        edm4hep::TrackerHit hit=track.getTrackerHits(iHit);
+    if(m_debug>0){ std::cout<<"addWireMeasurementsOnTrack"<<std::endl; }
 
-        double driftVelocity=40;//FIXME, TODO, um/ns
-        double driftDistance=hit.getTime()*driftVelocity*dd4hep::um;
-        TVector3 endPointStart(0,0,0);
-        TVector3 endPointEnd(0,0,0);
-        m_gridDriftChamber->cellposition(hit.getCellID(),endPointStart,
-                endPointEnd);
-        int lrAmbig=0;
-        if(m_debug>=2)std::cout<<m_name<<" time "<<hit.getTime()
-            <<" driftVelocity " <<driftVelocity<<std::endl;
-        if(m_debug>=2)std::cout<<m_name<<" wire pos " <<endPointStart.X()
-            <<" "<<endPointStart.Y()<<" " <<endPointStart.Z()<<" "
-            <<endPointEnd.X()<<" " <<endPointEnd.Y()<<" "
-            <<endPointEnd.Z()<<" " <<std::endl;
-        endPointStart.SetX(endPointStart.x()*dd4hep::cm);
-        endPointStart.SetY(endPointStart.y()*dd4hep::cm);
-        endPointStart.SetZ(endPointStart.z()*dd4hep::cm);
-        endPointEnd.SetX(endPointEnd.x()*dd4hep::cm);
-        endPointEnd.SetY(endPointEnd.y()*dd4hep::cm);
-        endPointEnd.SetZ(endPointEnd.z()*dd4hep::cm);
-        addWireMeasurement(driftDistance,sigma*dd4hep::cm,endPointStart,
-                endPointEnd,lrAmbig,hit.getCellID(),iHit);
+    if(m_debug>0){
+      std::cout<<"n trackerHits size"<<track.trackerHits_size()<<std::endl;
     }
-    return true;
-}//end of addWireMeasurementOnTrack of Track
+    int nHitAdd=0;
+    if(0==track.trackerHits_size()){
+        if(m_debug>0) std::cout<<"No hit on track"<<std::endl;
+        return nHitAdd;
+    }
+
+    podio::RelationRange<edm4hep::TrackerHit> hits_t=track.getTrackerHits();
+    std::vector<edm4hep::TrackerHit*> hits;
+    //hits.reserve(1000);
+    for(auto &h:hits_t){
+        edm4hep::TrackerHit* hit = const_cast<edm4hep::TrackerHit*>(&h);
+        hits.push_back(hit); 
+    }
+    nHitAdd=addWireMeasurementsFromList(hits,sigma,assoHits,sortMethod,truthAmbig,skipCorner,skipNear);
+
+    return nHitAdd;
+}//end of addWireMeasurements
 
 /// Get MOP
-bool GenfitTrack::getMOP(int hitID,
-        genfit::MeasuredStateOnPlane& mop, genfit::AbsTrackRep* trackRep) const
+bool GenfitTrack::getMOP(int hitID,genfit::MeasuredStateOnPlane& mop,
+        genfit::AbsTrackRep* trackRep) const
 {
+
     if(nullptr == trackRep) trackRep = getRep();
     try{
         mop = m_track->getFittedState(hitID,trackRep);
@@ -354,30 +441,22 @@ bool GenfitTrack::getMOP(int hitID,
 }
 
 /// New and add a track representation to track
-genfit::RKTrackRep* GenfitTrack::addTrackRep(int pdg)
+genfit::RKTrackRep* GenfitTrack::addTrackRep(int pdgType,int charge)
 {
-    /// create a new track representation
-    genfit::RKTrackRep* rep = new genfit::RKTrackRep(pdg);
-    m_reps.push_back(rep);
+    int chargeId=0;
+    charge>0 ? chargeId=0 : chargeId=1;//s_PDG[0]: positive particle
+
+    genfit::RKTrackRep* rep=new genfit::RKTrackRep(s_PDG[chargeId][pdgType]);
     m_track->addTrackRep(rep);
-    //try{
-    //  genfit::MeasuredStateOnPlane stateInit(rep);
-    //  rep->setPosMomCov(stateInit, pos, mom, covM);
-    //}catch(genfit::Exception e){
-    //  if(m_debug>=2)std::cout<<m_name<<" Exception in set track status"
-    //  <<std::endl     ;
-    //  std::cout<<e.what()<<std::endl;
-    //  return false;
-    //}
     return rep;
 }
 
 /// Get the position from genfit::Track::getStateSeed
 const TLorentzVector GenfitTrack::getSeedStatePos()const
 {
-    TVectorD seedStat(6);
-    seedStat = m_track->getStateSeed();
-    TVector3 p(seedStat[0],seedStat[1],seedStat[2]);
+    TVectorD seedState(6);
+    seedState = m_track->getStateSeed();
+    TVector3 p(seedState[0],seedState[1],seedState[2]);
     p = p*dd4hep::cm;
     TLorentzVector pos(p[0],p[1],p[2],9999);//FIXME
     return pos;
@@ -386,18 +465,18 @@ const TLorentzVector GenfitTrack::getSeedStatePos()const
 /// Get the momentum from genfit::Track::getStateSeed
 const TVector3 GenfitTrack::getSeedStateMom() const
 {
-    TVectorD seedStat(6); seedStat = m_track->getStateSeed();
-    TVector3 mom(seedStat[3],seedStat[4],seedStat[5]);
+    TVectorD seedState(6); seedState = m_track->getStateSeed();
+    TVector3 mom(seedState[3],seedState[4],seedState[5]);
     return mom*dd4hep::GeV;
 }
 
 /// Get the seed states of momentum and position
 void GenfitTrack::getSeedStateMom(TLorentzVector& pos, TVector3& mom) const
 {
-    TVectorD seedStat(6); seedStat = m_track->getStateSeed();
-    mom = TVector3(seedStat[3],seedStat[4],seedStat[5])*dd4hep::GeV;
-    seedStat = m_track->getStateSeed();
-    TVector3 p = TVector3(seedStat[0],seedStat[1],seedStat[2])*dd4hep::cm;
+    TVectorD seedState(6); seedState = m_track->getStateSeed();
+    mom = TVector3(seedState[3],seedState[4],seedState[5])*dd4hep::GeV;
+    seedState = m_track->getStateSeed();
+    TVector3 p = TVector3(seedState[0],seedState[1],seedState[2])*dd4hep::cm;
     pos.SetXYZT(p[0],p[1],p[2],9999);//FIXME time
 }
 
@@ -406,6 +485,23 @@ unsigned int GenfitTrack::getNumPoints() const
     return m_track->getNumPoints();
 }
 
+GenfitHit* GenfitTrack::GetHit(long unsigned int i) const {
+  if(i>=m_genfitHitVec.size())return nullptr;
+  return m_genfitHitVec[i];
+}
+
+unsigned int GenfitTrack::getNumPointsDet(int detTypeID) const
+{
+    unsigned int nHit=0;
+    const std::vector<genfit::TrackPoint*> tps=m_track->getPoints();
+    for(auto tp:tps){
+        const genfit::AbsMeasurement* m=nullptr;
+        if(tp->hasRawMeasurements()) m=tp->getRawMeasurement();
+        if(nullptr!=m && detTypeID==getDetTypeID(m->getDetId())) nHit++;
+    }
+    return nHit;
+}
+
 /// Test the fit result FIXME
 bool GenfitTrack::fitSuccess(int repID) const
 {
@@ -417,8 +513,8 @@ bool GenfitTrack::fitSuccess(int repID) const
             ||fitStatus->isFitConvergedFully()) {
         if(m_debug>=2)std::cout<<m_name<< "Fitting is failed... isFitted"
             <<fitStatus->isFitted()<<" , isFitConverged "
-            <<fitStatus->isFitConverged()<<", isFitConvergedFully "
-            <<fitStatus->isFitConvergedFully()<<std::endl;
+                <<fitStatus->isFitConverged()<<", isFitConvergedFully "
+                <<fitStatus->isFitConvergedFully()<<std::endl;
         return false;
     }
 
@@ -436,18 +532,40 @@ bool GenfitTrack::fitSuccess(int repID) const
     return true;
 }
 
-void GenfitTrack::setDebug(int debug)
+void GenfitTrack::setDebugGenfit(int debug)
 {
-    m_debug = debug;
-    for(unsigned int i=0;i<m_reps.size();i++){ m_reps[i]->setDebugLvl(debug); }
+    if(m_track){
+        for(unsigned int i=0;i<m_track->getNumReps();i++){
+            m_track->getTrackRep(i)->setDebugLvl(debug);
+        }
+    }
+}
+void GenfitTrack::setDebugLocal(int debug){
+#ifdef GENFIT_MY_DEBUG
+    if(m_track){
+        for(unsigned int i=0;i<m_track->getNumReps();i++){
+            //m_track->getTrackRep(i)->setDebugLvlLocal(debug);
+        }
+    }
+    m_debugLocal=debug;
+#endif
+    if(m_debug)std::cout<<"GenfitTrack:setDebugLvlLocal "<<debug<<std::endl;
 }
 
 void GenfitTrack::printSeed() const
 {
     TLorentzVector pos = getSeedStatePos();
     TVector3 mom = getSeedStateMom();
+    std::cout << " Seed pos "  << std::endl;
+    pos.Print();
+    std::cout << " Seed Mom =  " << std::endl;
+    mom.Print();
     print(pos,mom);
-    if(m_debug>=2)std::cout<<m_name<<" NumPoints "<<getNumPoints()<<std::endl;
+    TMatrixDSym covSeed=m_track->getCovSeed();
+    //if(m_debug>1)
+    std::cout << " covSeed = " << std::endl;
+    covSeed.Print();
+    //std::cout<<" pdg "<<0<<getRep(0)<<std::endl;//FIXME
 }
 
 void GenfitTrack::printFitted(int repID) const
@@ -479,7 +597,9 @@ void GenfitTrack::print( TLorentzVector pos, TVector3 mom,
     if(m_debug>=2)std::cout<<m_name<<" "<<comment<<std::endl;
 
     if(m_debug>1){
-        for(unsigned int i=0;i<m_reps.size();i++){ m_reps[i]->Print(); }
+        for(unsigned int i=0;i<m_track->getNumReps();i++){
+            m_track->getTrackRep(i)->Print();
+        }
     }
     //for(unsigned int i=0; i<m_track->getNumPoints(); i++){
     //  m_track->getPoint(i)->print();
@@ -488,7 +608,7 @@ void GenfitTrack::print( TLorentzVector pos, TVector3 mom,
 
 /// Get position, momentum, cov on plane of hitID-th hit
 bool GenfitTrack::getPosMomCovMOP(int hitID, TLorentzVector& pos,
-        TVector3& mom, TMatrixDSym& cov, int repID) const
+        TVector3& mom, TMatrixDSym& cov,int repID) const
 {
     TVector3 p;
     genfit::MeasuredStateOnPlane mop;
@@ -505,7 +625,9 @@ bool GenfitTrack::getPosMomCovMOP(int hitID, TLorentzVector& pos,
 int GenfitTrack::getNumPointsWithFittedInfo(int repID) const
 {
     int nHitWithFittedInfo = 0;
+    //check number of hit with fitter info
     int nHit = m_track->getNumPointsWithMeasurement();
+    //check number of hit with fitter info
     for(int i=0; i<nHit; i++){
         if(nullptr != m_track->getPointWithFitterInfo(i,getRep(repID))){
             nHitWithFittedInfo++;
@@ -515,7 +637,7 @@ int GenfitTrack::getNumPointsWithFittedInfo(int repID) const
 }
 
 int GenfitTrack::getFittedState(TLorentzVector& pos, TVector3& mom,
-        TMatrixDSym& cov, int repID, bool biased) const
+        TMatrixDSym& cov, int trackPointId, int repID, bool biased) const
 {
     //check number of hit with fitter info
     if(getNumPointsWithFittedInfo(repID)<=2) return 1;
@@ -527,14 +649,13 @@ int GenfitTrack::getFittedState(TLorentzVector& pos, TVector3& mom,
     //get first or last measured state on plane
     genfit::MeasuredStateOnPlane mop;
     try{
-        mop = m_track->getFittedState(biased);
+        mop = m_track->getFittedState(trackPointId,rep,biased);
     }catch(genfit::Exception& e){
-        std::cout<<" getNumPointsWithFittedInfo "
+        std::cout<<" getNumPointsWithFittedInfo="
             <<getNumPointsWithFittedInfo(repID)
             <<" no TrackPoint with fitted info "<<std::endl;
         if(m_debug>=2)std::cout<<m_name
             <<"Exception in getFittedState"<<std::endl;
-        std::cout<<e.what()<<std::endl;
         return 3;
     }
 
@@ -557,12 +678,12 @@ int GenfitTrack::getDetIDWithFitterInfo(int hitID, int idRaw) const
 
 int GenfitTrack::getPDG(int id) const
 {
-    return m_reps[id]->getPDG();
+    return m_track->getTrackRep(id)->getPDG();
 }
 
 int GenfitTrack::getPDGCharge(int id) const
 {
-    return m_reps[id]->getPDGCharge();
+    return m_track->getTrackRep(id)->getPDGCharge();
 }
 
 const genfit::FitStatus*
@@ -572,264 +693,701 @@ GenfitTrack::getFitStatus(int repID) const
 }
 
 /// Extrapolate track to the cloest point of approach(POCA) to the wire of hit,
-/// return StateOnPlane of this POCA
-/// inputs
-///  pos,mom ... position & momentum at starting point, unit= [mm]&[GeV/c]
-///              (converted to [cm]&[GeV/c] inside this function)
-///  hit ... destination
-/// outputs poca [mm] (converted from [cm] in this function) ,global
-double GenfitTrack::extrapolateToHit( TVector3& poca, TVector3& pocaDir,
-        TVector3& pocaOnWire, double& doca, TVector3 pos, TVector3 mom,
-        TVector3 end0,//one end of the hit wire
-        TVector3 end1,//the orhter end of the hit wire
-        int debug,
-        int repID,
-        bool stopAtBoundary,
-        bool calcJacobianNoise)const
+/// return doca, poca on wire and track
+/// outputs poca [cm]
+/// unit conversion here
+double GenfitTrack::extrapolateToHit(TVector3& poca, TVector3& pocaDir,
+        TVector3& pocaOnWire, double& doca,edm4hep::MCParticle mcParticle,
+        int cellID, int repID, bool stopAtBoundary, bool calcJacobianNoise)const
 {
-
-    //genfit::MeasuredStateOnPlane state = getMOP(iPoint); // better?
-    //genfit::MeasuredStateOnPlane state = getMOP(0);      // better?
-    //To do the extrapolation without IHitSelection,above 2 lines are not used.
-    pos = pos*dd4hep::cm;//FIXME
-    mom = mom*dd4hep::GeV;
-
-    //std::cout<<__LINE__<<" extrapolate to Hit pos and mom"<<std::endl;
-    //pos.Print();
-    //mom.Print();
-
-    genfit::AbsTrackRep* rep = new genfit::RKTrackRep(getRep(repID)->getPDG());
-    rep->setDebugLvl(debug);
-    genfit::MeasuredStateOnPlane state(rep);
+    ///Get MCParticle and convert unit
+    TVector3 pos;
+    TVector3 mom;
+    getPosMomFromMCPartile(mcParticle,pos,mom);
+
+    TVector3 end0(0,0,0);
+    TVector3 end1(0,0,0);
+    getEndPointsOfWire(cellID,end0,end1);
+
+    int chargeId;
+    mcParticle.getCharge() >0 ? chargeId=0 : chargeId=1;//s_PDG[0]: positive particle
+    genfit::RKTrackRep* rep = new genfit::RKTrackRep(s_PDG[chargeId][repID]);
+    //genfit::MeasuredStateOnPlane state(rep);
+    genfit::StateOnPlane state(rep);
     rep->setPosMom(state, pos, mom);
 
-
-    //genfit::MeasuredStateOnPlane state(m_track->getRep(repID));
-    //m_track->getRep(repID)->setPosMom(state, pos, mom);
-
-    //m_track->PrintSeed();
-    double extrapoLen(0);
-    //std::cout<<" wire1 "<<std::endl;
-    //end0.Print();
-    //std::cout<<" wire0 "<<std::endl;
-    //end1.Print();
-    //std::cout<<" state "<<std::endl;
-    //state.Print();
+    if(m_debug){
+        std::cout<<"GenfitterTrack::extrapolateToHit before pos and mom "
+            <<" charge "<<(int)mcParticle.getCharge()<<" repID "<<repID
+            <<" pdg "<<s_PDG[chargeId][repID]<<std::endl;
+        pos.Print();
+        mom.Print();
+        std::cout<<" end point"<<std::endl;
+        end0.Print();
+        end1.Print();
+        std::cout<<" state "<<std::endl;
+        state.Print();
+        std::cout<<" stopAtBoundary "<<stopAtBoundary<<std::endl;
+        std::cout<<" calcJacobianNoise "<<calcJacobianNoise<<std::endl;
+    }
 
 
-    // forth
+    double extrapoLen=0.;
     try {
-        //genfit::RKTrackRep* rkRep =
-        //  dynamic_cast<genfit::RKTrackRep*> (m_track->getRep(repID));
-        //extrapoLen = rkRep->extrapolateToLine(state, end0, end1, poca,
-        //    pocaDir, pocaOnWire, stopAtBoundary, calcJacobianNoise);
-        extrapoLen = rep->extrapolateToLine(state, end0, end1, poca,
-                pocaDir, pocaOnWire, stopAtBoundary, calcJacobianNoise);
+        extrapoLen = rep->extrapolateToLine(state,end0,end0-end1,
+                poca,pocaDir,pocaOnWire,stopAtBoundary,calcJacobianNoise);
     }catch(genfit::Exception& e) {
         if(m_debug>=3)std::cout<<
-            "Exception in GenfigFitter::ExtrapolateToHit"<<e.what()<<std::endl;
-        return extrapoLen;
+            "Exception in GenfitterTrack::extrapolateToHit"<<e.what()<<std::endl;
+        return extrapoLen/GenfitUnit::mm*dd4hep::mm;
     }
 
-    //poca = poca*(dd4hep::cm);
-    //pocaOnWire = pocaOnWire*(dd4hep::cm);
-    pocaOnWire = pocaOnWire;
     doca = (pocaOnWire-poca).Mag();
-    //TODO: debug pocaOnWire
-    if(m_debug>=2)std::cout<< " poca "<<poca.x()<<","<<poca.y()
-        <<" "<<poca.z()<<" doca "<<doca<<std::endl;
-    if(m_debug>=2)std::cout<< " pocaOnWire "<<pocaOnWire.x()
-        <<","<<pocaOnWire.y()<<" "<<pocaOnWire.z()<<" doca "<<doca<<std::endl;
+    if(m_debug>=2){
+        std::cout<< " poca "<<poca.x()<<","<<poca.y()<<" "<<poca.z()
+            <<" pocaDir "<<pocaDir.x()<<","<<pocaDir.y()<<" "<<pocaDir.z()
+            <<" pocaOnWire "<<pocaOnWire.x()<<","<<pocaOnWire.y()<<" "<<pocaOnWire.z()
+            <<" doca "<<doca<<" cm"<<std::endl;
+    }
 
-    return extrapoLen*(dd4hep::cm);
-}//end of ExtrapolateToHit
+    delete rep;
+    return extrapoLen/GenfitUnit::mm*dd4hep::mm;
+}//end of extrapolateToHit
+
+/////Add space point measurement from edm4hep::Track to genfit track
+//int GenfitTrack::addHitsOnEdm4HepTrack(const edm4hep::Track& track,
+//        const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
+//        std::vector<float> sigma,bool smear,
+//        bool measurementTypeSi, bool measurementTypeDC){
+//    ///Get TrackerHit on Track
+//    int hitID=0;
+//    for(unsigned int iHit=0;iHit<track.trackerHits_size();iHit++){
+//        edm4hep::TrackerHit hit=track.getTrackerHits(iHit);
+//        ///Get hit type
+//        int detTypeID=getDetTypeID(hit.getCellID());
+//        if(m_debug>=2)std::cout<<"addHitsOnEdm4HepTrack "<<iHit<<" hit "<<hit
+//            <<" detTypeID "<<detTypeID<<" type "<<hit.getType()<<std::endl;
+//
+//        bool hitIsSpapcePoint=UTIL::BitSet32(hit.getType())[
+//                              UTIL::ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT];
+//        bool hitIsPlanar=UTIL::BitSet32(hit.getType())[
+//                         UTIL::ILDTrkHitTypeBit::ONE_DIMENSIONAL];
+//        if(m_debug>2){
+//            std::cout<<detTypeID<<" COMPOSITE_SPACEPOINT "<<hitIsSpapcePoint
+//                <<std::endl;
+//            std::cout<<detTypeID<<" ONE_DIMENSIONAL "<<hitIsPlanar<<std::endl;
+//        }
+//
+//    }
+//
+//    return 1;
+//}
+
+///Add space point measurement of silicon from edm4hep::Track to genfit track
+int GenfitTrack::addSpacePointsSi(const edm4hep::Track& track,
+        std::vector<float> sigmaU,std::vector<float> sigmaV)
+{
+    ///Get TrackerHit on Track
+    int nHitAdd=0;
+    for(unsigned int iHit=0;iHit<track.trackerHits_size();iHit++){
+        int detTypeID=getDetTypeID(track.getTrackerHits(iHit).getCellID());
+        if(m_geomSvc->lcdd()->constant<int>("DetID_DC")==detTypeID) continue;
+        edm4hep::TrackerHit hit=track.getTrackerHits(iHit);
+        edm4hep::Vector3d pos=hit.getPosition();
+
+        //edm4hep::Vector3d pos=simTrackerHitAsso.getPosition();
+
+        TVector3 p(pos.x,pos.y,pos.z);
 
+        p.Print();
+        unsigned long long cellID = hit.getCellID();
+        if(addSpacePointMeasurement(p,sigmaU,sigmaV,cellID,nHitAdd)){
+            if(m_debug>=2)std::cout<<"add silicon space point"<<std::endl;
+            nHitAdd++;
+        }else{
+            if(m_debug>=2)std::cout<<"addSpacePointMeasurement"
+                <<cellID<<" faieled" <<std::endl;
+        }
+    }
+    if(m_debug>=2) std::cout<<m_name<<" Si addHitAdd="<<nHitAdd<<std::endl;
+    return nHitAdd;
+}//end of addSpacePointsSi
 
-///Add space point measurement from edm4hep::Track to genfit track
-int GenfitTrack::addSimTrackerHits(edm4hep::Track track,
+///Add drift chamber space point from edm4hep::track
+int GenfitTrack::addSpacePointsDC(const edm4hep::Track& track,
         const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
-        float sigma,bool smear){
-    //A TrakerHit collection
-    std::vector<edm4hep::SimTrackerHit> sortedDCTrackHitCol;
+        std::vector<float> sigmaU,std::vector<float> sigmaV)
+{
+    if(m_debug>=2){
+    std::cout<<m_name<<" 5. addSpacePointsDC nTrackerHit="
+        <<track.trackerHits_size()<<std::endl;
+    }
 
-    if(m_debug>=2)std::cout<<m_name<<" VXD "
-        <<lcio::ILDDetID::VXD<<" SIT "
-        <<lcio::ILDDetID::SIT<<" SET "
-        <<lcio::ILDDetID::SET<<" FTD "
-        <<lcio::ILDDetID::FTD<<" "<<std::endl;
-    ///Get TrackerHit on Track
-    int hitID=0;
+    ///Get TrackerHit with min. time in Cell
+    std::vector<edm4hep::SimTrackerHit> sortedDCTrackHitCol;
     for(unsigned int iHit=0;iHit<track.trackerHits_size();iHit++){
         edm4hep::TrackerHit hit=track.getTrackerHits(iHit);
-
-        UTIL::BitField64 encoder(lcio::ILDCellID0::encoder_string);
-        encoder.setValue(hit.getCellID());
-        int detID=encoder[lcio::ILDCellID0::subdet];
-        if(m_debug>=2)std::cout<<m_name<<" "<<iHit<<" hit "<<hit
-            <<" detID "<<detID<<std::endl;
-
-        if(detID==lcio::ILDDetID::VXD || detID==lcio::ILDDetID::SIT ||
-                detID==lcio::ILDDetID::SET || detID==lcio::ILDDetID::FTD){
-            if(addSpacePointTrakerHit(hit,hitID)){
-                if(m_debug>=2)std::cout<<"add slicon space point"<<std::endl;
-                hitID++;
-            }else{
-                if(m_debug>=2)std::cout<<"silicon addSpacePointTrakerHit"
-                    <<detID<<" "<<hit.getCellID()<<" faieled"<<std::endl;
-            }
-        }else if(detID==7){
-            //if(addSpacePointMeasurement(p,sigma,hit.getCellID(),hitID)){
-            //    if(m_debug>=2)std::cout<<"add DC space point"<<std::endl;
-            //    hitID++;
-            //}else{
-            //    if(m_debug>=2)std::cout<<"addSpacePointMeasurement"
-            //        <<detID<<" faieled" <<std::endl;
-            //}
-            float minTime=FLT_MAX;
-            edm4hep::SimTrackerHit minTimeSimHit;
-            //Select the SimTrakerHit with least time
-            for(int iSimHit=0;iSimHit<(int) assoHits->size();iSimHit++){
-                if(assoHits->at(iSimHit).getRec()==hit &&
-                        assoHits->at(iSimHit).getSim().getTime()<minTime){
-                    minTimeSimHit=assoHits->at(iSimHit).getSim();
-                    minTime=assoHits->at(iSimHit).getSim().getTime();
-                }
+        int detTypeID=getDetTypeID(track.getTrackerHits(iHit).getCellID());
+        if(m_geomSvc->lcdd()->constant<int>("DetID_DC")!=detTypeID) continue;
+
+        ///Select the SimTrakerHit with least time
+        float minTime=FLT_MAX;
+        edm4hep::SimTrackerHit minTimeSimHit;
+        for(int iSimHit=0;iSimHit<(int) assoHits->size();iSimHit++){
+            if(assoHits->at(iSimHit).getRec()==hit &&
+                    assoHits->at(iSimHit).getSim().getTime()<minTime){
+                minTimeSimHit=assoHits->at(iSimHit).getSim();
+                minTime=assoHits->at(iSimHit).getSim().getTime();
             }
-            //std::cout<<"minTimeSimHit "<<minTimeSimHit<<std::endl;
+        }
+        if(!minTimeSimHit.isProducedBySecondary()){
             sortedDCTrackHitCol.push_back(minTimeSimHit);
-        }else{
-            if(m_debug>=2)std::cout<<" Skip add this hit!"<<std::endl;
         }
-    }//end loop over hit on track
+    }//end loop over TrackerHit
 
-    if(m_debug>=2)std::cout<<" addSimTrakerHits trackerHits_size="
-        <<track.trackerHits_size()<<std::endl;
+    ///Sort DC SimTrackerHit by time
+    std::sort(sortedDCTrackHitCol.begin(),sortedDCTrackHitCol.end(),sortDCSimHit);
 
     ///Add DC hits to track
-    //Sort sim DC hits by time
-    //std::sort(sortedDCTrackHitCol.begin(),sortedDCTrackHitCol.end(),sortDCHit);
+    int nHitAdd=0;
     for(auto dCTrackerHit: sortedDCTrackHitCol){
         edm4hep::Vector3d pos=dCTrackerHit.getPosition();
-        TVectorD p(3);
-        p[0]=pos.x;
-        p[1]=pos.y;
-        p[2]=pos.z;
-        unsigned long long detID = dCTrackerHit.getCellID();
-        if(addSpacePointMeasurement(p,sigma,detID,hitID,smear)){
+        TVector3 p(pos.x,pos.y,pos.z);
+
+        if(m_debug) std::cout<<"6. addSpacePointsDC hit "<<dCTrackerHit<<std::endl;
+        unsigned long long cellID=dCTrackerHit.getCellID();
+        if(addSpacePointMeasurement(p,sigmaU,sigmaV,dCTrackerHit.getCellID()
+                    ,nHitAdd)){
             if(m_debug>=2)std::cout<<"add DC space point"<<std::endl;
-            hitID++;
+            nHitAdd++;
         }else{
             if(m_debug>=2)std::cout<<"addSpacePointMeasurement"
-                <<detID<<" faieled" <<std::endl;
+                <<cellID<<" faieled" <<std::endl;
+        }
+    }
+
+    if(m_debug>=2) std::cout<<m_name<<" DC addHitAdd="<<nHitAdd<<std::endl;
+    return nHitAdd;
+}//end of addSpacePointsDC
+
+//double GenfitTrack::extrapolateToPoint(TVector3& pos, TVector3& mom,
+//        TMatrixDSym& cov,
+//        const TVector3& point,
+//        int repID,// same with pidType
+//        bool stopAtBoundary,
+//        bool calcJacobianNoise) const
+//{
+//    return extrapolateToPoint(pos,mom,cov,point,repID,stopAtBoundary,
+//            calcJacobianNoise);
+//
+//}//end of extrapolateToPoint
+
+double GenfitTrack::extrapolateToPoint(TVector3& pos, TVector3& mom,
+        TMatrixDSym& cov, const TVector3& point,
+        int repID,// same with pidType
+        bool stopAtBoundary,
+        bool calcJacobianNoise) const
+{
+    double trackLength(1e9*dd4hep::cm);
+    if(!getFitStatus(repID)->isFitted()) return trackLength;
+    try{
+        // get track rep
+        genfit::AbsTrackRep* rep = getRep(repID);
+        if(nullptr == rep) {
+            if(m_debug>=2)std::cout<<"In extrapolateToPoint rep "
+                <<repID<<" not exist!"<<std::endl;
+            return trackLength*dd4hep::cm;
+        }
+
+        /// extrapolate to point
+        //genfit::StateOnPlane state(*(&(track->getTrack()->getFittedState(0,rep))));
+
+        // get track point with fitter info
+        genfit::TrackPoint* tp = getTrack()->getPointWithFitterInfo(0,rep);
+        if(nullptr == tp) {
+            if(m_debug>=2)std::cout<<
+                "In extrapolateToPoint TrackPoint is null"<<std::endl;
+            return trackLength*dd4hep::cm;//FIXME unit
+        }
+
+        // get fitted state on plane of this track point
+        genfit::KalmanFittedStateOnPlane* state =
+            static_cast<genfit::KalmanFitterInfo*>(
+                    tp->getFitterInfo(rep))->getBackwardUpdate();
+        genfit::StateOnPlane orignalState(*state);
+        if(m_debug>3){
+            tp->Print();
+            std::cout<<" original state before extrapolate "<<std::endl;
+            state->Print();
+        }
+
+        if(nullptr == state) {
+            if(m_debug>=2)std::cout<<
+                "In extrapolateToPoint KalmanFittedStateOnPlane is null"<<std::endl;
+            return trackLength*dd4hep::cm;//FIXME unit
+        }
+        //rep->setDebugLvl(10);
+        trackLength = rep->extrapolateToPoint(*state,
+                point*(1/dd4hep::cm),stopAtBoundary, calcJacobianNoise);
+
+        rep->getPosMomCov(*state,pos,mom,cov);//FIXME exception exist
+
+        pos = pos*dd4hep::cm;//FIXME unit
+        mom = mom*dd4hep::GeV;//FIXME unit
+        if(m_debug>3){
+            std::cout<<" original state before extrapolate "<<std::endl;
+            orignalState.Print();
+            std::cout<<" extrapolated state "<<std::endl;
+            state->Print();
         }
+
+    } catch(genfit::Exception& e){
+        if(m_debug>=3)std::cout
+            <<"Exception in GenfitTrack::extrapolateToPoint"
+                << e.what()<<std::endl;
+        trackLength = 1e9*dd4hep::cm;
     }
+    return trackLength*dd4hep::cm;
+}//end of extrapolateToPoint
+
+/// Extrapolate the track to the cyliner at fixed raidus
+/// position & momentum as starting point
+/// position and momentum at global coordinate in dd4hepUnit
+/// return trackLength in dd4hepUnit
+    double
+GenfitTrack::extrapolateToCylinder(TVector3& pos, TVector3& mom,
+        double radius, const TVector3 linePoint,
+        const TVector3 lineDirection, int hitID, int repID,
+        bool stopAtBoundary, bool calcJacobianNoise)
+{
+    double trackLength(1e9*dd4hep::cm);//FIXME unit
+    if(!getFitStatus(repID)->isFitted()) return trackLength;
+    try{
+        // get track rep
+        genfit::AbsTrackRep* rep = getRep(repID);
+        if(nullptr == rep) {
+            if(m_debug>=2)std::cout<<"In extrapolateToCylinder rep is null"
+                <<std::endl;
+            return trackLength*dd4hep::cm;//FIXME unit
+        }
 
-    if(m_debug>=2)std::cout<<"GenfitTrack nHitAdded "<<hitID<<std::endl;
-    return hitID;
+        // get track point with fitter info
+        genfit::TrackPoint* tp =
+            getTrack()->getPointWithFitterInfo(hitID,rep);
+        if(nullptr == tp) {
+            if(m_debug>=2)std::cout<<
+                "In extrapolateToCylinder TrackPoint is null"<<std::endl;
+            return trackLength*dd4hep::cm;//FIXME unit
+        }
+
+        // get fitted state on plane of this track point
+        genfit::KalmanFittedStateOnPlane* state =
+            static_cast<genfit::KalmanFitterInfo*>(
+                    tp->getFitterInfo(rep))->getBackwardUpdate();
+
+        if(nullptr == state){
+            if(m_debug>=2)std::cout<<"In extrapolateToCylinder "
+                <<"no KalmanFittedStateOnPlane in backwardUpdate"<<std::endl;
+            return trackLength*dd4hep::cm;
+        }
+        rep->setPosMom(*state, pos*(1/dd4hep::cm), mom*(1/dd4hep::GeV));//FIXME unit
+
+        /// extrapolate
+        trackLength = rep->extrapolateToCylinder(*state,
+                radius/dd4hep::cm, linePoint*(1/dd4hep::cm), lineDirection,
+                stopAtBoundary, calcJacobianNoise);
+        // get pos&mom at extrapolated point on the cylinder
+        rep->getPosMom(*state,pos,mom);//FIXME exception exist
+        pos = pos*dd4hep::cm;
+        mom = mom*dd4hep::GeV;
+    } catch(genfit::Exception& e){
+        if(m_debug>=3)std::cout
+            <<"Exception in GenfitTrack::extrapolateToCylinder "
+                << e.what()<<std::endl;
+        trackLength = 1e9*dd4hep::cm;
+    }
+    return trackLength*dd4hep::cm;
+}
+
+bool GenfitTrack::debugDistance(const edm4hep::TrackerHitCollection* dCDigiCol,
+        int& nFittedDC,int& nFittedSDT,int& ngenfitHit,
+        std::vector<double>& smearDistance,
+        std::vector<double>& truthDistance,double driftVelocity)
+{
+
+    int DCHit = 0;
+    int SDTHit = 0;
+    unsigned int nPoints = m_track->getNumPoints();
+    for(unsigned int i = 0; i<nPoints; i++){
+      genfit::TrackPoint* point = m_track->getPoint(i);
+      genfit::AbsMeasurement* absMea = point->getRawMeasurement();
+      genfit::PlanarMeasurementSDT* sdtMea =
+          dynamic_cast<genfit::PlanarMeasurementSDT*>(absMea);
+      if(sdtMea){
+        const edm4hep::TrackerHit* TrackerHit_ = sdtMea->getTrackerHit();
+        SDTHit++;
+      }else{
+        WireMeasurementDC* dcMea =
+            dynamic_cast<WireMeasurementDC*>(absMea);
+        if(dcMea){
+          const edm4hep::TrackerHit* TrackerHit_ = dcMea->getTrackerHit();
+          smearDistance.push_back(1e-3*driftVelocity*TrackerHit_->getTime());
+          DCHit++;
+          for(auto dcDigi: *dCDigiCol){
+            if(dcDigi.getCellID() == TrackerHit_->getCellID())
+            {
+                truthDistance.push_back(1e-3*driftVelocity*(dcDigi.getTime()));
+            }
+          }
+        }
+      }
+    }
+
+    DCHit = nFittedDC;
+    SDTHit = nFittedSDT;
+    ngenfitHit = nFittedDC+nFittedDC;
+
+    return true;
+}
+
+/// Get doca on plane of hitID-th hit
+bool GenfitTrack::GetDocaRes(int hitID, double& DriftDis,double& fittedDoca,
+        double& res, int repID, bool biased) const
+{
+    genfit::TrackPoint* trackPoint = m_track->getPointWithFitterInfo(hitID, getRep(repID));
+    if(!trackPoint)return false;
+    genfit::AbsMeasurement* thismea = trackPoint->getRawMeasurement(0);
+    const TVectorD measereddoca = thismea->getRawHitCoords();
+    DriftDis = abs(measereddoca[0]);
+    genfit::MeasuredStateOnPlane mop;
+    if(!getMOP(hitID,mop,getRep(repID))) return false;
+    TVectorD state = mop.getState();
+    if(state.GetNrows() != 5)return false;
+    fittedDoca = abs(state[3]);
+    res = 10*(fittedDoca - DriftDis);
+    return true;
 }
 
 bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
-        int pidType, int ndfCut, double chi2Cut)
+        edm4hep::MutableTrack& track,TVector3& pocaToOrigin_pos,
+        TVector3& pocaToOrigin_mom,TMatrixDSym& pocaToOrigin_cov,
+        // edm4hep::TrackState& trackState,
+        int pidType, int ndfCut, double chi2Cut,
+        int& nFittedDC, int& nFittedSDT, int& ngenfitHit,
+        std::vector<double>& trackL, std::vector<double>& hitMom,
+        std::vector<float>& truthMomEdep,
+        const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
+        std::vector<double>& driftDis,
+        std::vector<double>& FittedDoca,
+        std::vector<double>& Res)
 {
 
+    int id = 0;
+    int fitid = 0;
+    int DCHit = 0;
+    int dcFit = 0;
+    int sdtFit = 0;
+    int SDTHit = 0;
+
+    //  getNumRawMeasurements
+    unsigned int nPoints = m_track->getNumPoints();
+    std::cout << " nPoints =  " << nPoints << std::endl;
+
+    std::vector<double> hitMomMag;
+
+    while(1){
+        genfit::TrackPoint* point = m_track->getPointWithFitterInfo(id);
+        if(!point)break;
+        id++;
+        genfit::AbsMeasurement* absMea = point->getRawMeasurement();
+
+        // getPoint FitterInfo
+        genfit::AbsFitterInfo* FitterInfo = point->getFitterInfo();
+        genfit::KalmanFitterInfo *KalmanfitterInfo =
+            dynamic_cast<genfit::KalmanFitterInfo*>(FitterInfo);
+
+        unsigned int nNumMea = KalmanfitterInfo->getNumMeasurements();
+
+        bool flag = false;
+        for(int i=0;i<nNumMea;i++)
+        {
+            genfit::MeasurementOnPlane* MeaOnPlane =
+                KalmanfitterInfo->getMeasurementOnPlane(i);
+            double weight = MeaOnPlane->getWeight();
+            if(weight>0.8) flag = true;
+        }
+        if(flag) fitid++;
+
+        genfit::MeasurementOnPlane * Mea =
+            KalmanfitterInfo->getMeasurementOnPlane();
+
+        genfit::PlanarMeasurementSDT* sdtMea =
+            dynamic_cast<genfit::PlanarMeasurementSDT*>(absMea);
+        if(sdtMea){
+            SDTHit++;
+            if(flag) sdtFit++;
+            const edm4hep::TrackerHit* TrackerHit_ = sdtMea->getTrackerHit();
+            track.addToTrackerHits(*TrackerHit_);
+        }else{
+            WireMeasurementDC* dcMea =
+                dynamic_cast<WireMeasurementDC*>(absMea);
+            if(dcMea){
+                const edm4hep::TrackerHit* TrackerHit_ = dcMea->getTrackerHit();
+                track.addToTrackerHits(*TrackerHit_);
+
+
+                DCHit++;
+                if(flag)
+                {
+
+                    truthMomEdep.push_back(TrackerHit_->getEDep());
+                    double DriftDis,fittedDoca,res = 0;
+                    GetDocaRes(dcFit,DriftDis,fittedDoca,res);
+                    driftDis.push_back(DriftDis);
+                    FittedDoca.push_back(fittedDoca);
+                    Res.push_back(res);
+
+                    //                    TMatrixDSym fittedHitCov(6);//cm, GeV
+                    //                    TLorentzVector fittedHitPos;
+                    //                    TVector3 fittedHitMom;
+                    //                    int fittedState=getFittedState(fittedHitPos,fittedHitMom,fittedHitCov,dcFit);
+                    //                    hitMomMag.push_back(fittedHitMom.Mag());
+                    //
+                    //                    for(int iSim=0;iSim<assoHits->size();iSim++)
+                    //                    {
+                    //                        //if(*TrackerHit_ == assoHits->at(iSim).getRec())
+                    //                        if(TrackerHit_->getCellID() == assoHits->at(iSim).getRec().getCellID())
+                    //                        {
+                    //                           // std::cout << " if  TrackerHit_ = " << TrackerHit_->getCellID() << std::endl;
+                    //                           // std::cout << " if assoHits->at(iSim).getRec() = " << assoHits->at(iSim).getRec().getCellID() << std::endl;
+                    //                           // std::cout << " Sim Mom = " << assoHits->at(iSim).getSim().getMomentum() << std::endl;
+                    //                           // std::cout << " Sim MomMag = " << sqrt(assoHits->at(iSim).getSim().getMomentum()[0]*assoHits->at(iSim).getSim().getMomentum()[0]+assoHits->at(iSim).getSim().getMomentum()[1]*assoHits->at(iSim).getSim().getMomentum()[1]+assoHits->at(iSim).getSim().getMomentum()[2]*assoHits->at(iSim).getSim().getMomentum()[2]) << std::endl;
+                    //
+                    //                            break;
+                    //                        }
+                    //                    }
+
+                    //std::cout << " i = " << dcFit << "fittedMom = " << fittedHitMom.X() << " " << fittedHitMom.Y() << " " << fittedHitMom.Z() << std::endl;
+                    //std::cout << " i = " << dcFit << "fittedMomMag = " << fittedHitMom.Mag() << std::endl;
+                    dcFit++;
+                }
+            }
+        }
+    }
+
+    std::cout << " id = " << id << std::endl;
+    std::cout << " fitid = " << fitid << std::endl;
+
+    nFittedDC = dcFit;
+    nFittedSDT = SDTHit;
+
+    std::cout<<"nDC: "<<nFittedDC<<", nSDT: "<<nFittedSDT<<std::endl;
+    std::cout<<"nFittedDC: "<<dcFit<<", nFittedSDT: "<<sdtFit<<std::endl;
+    if(m_debug>0)std::cout<<m_name<<" store track ndfCut "<<ndfCut<<" chi2Cut "
+        <<chi2Cut<<std::endl;
+
     /// Get fit status
-    const genfit::FitStatus* fitState = m_track->getFitStatus();
+    const genfit::FitStatus* fitState = getFitStatus();
     double ndf = fitState->getNdf();
-    if(ndf>ndfCut) return false;
+    if(ndf>ndfCut){
+        if(m_debug>0){
+            std::cout<<m_name<<" cut by ndf="<<ndf<<">"<<ndfCut<<std::endl;
+        }
+        return false;
+    }
     double chi2 = fitState->getChi2();
-    if(chi2>chi2Cut) return false;
+    if(chi2>chi2Cut){
+        if(m_debug>0){
+            std::cout<<m_name<<" cut by chi2="<<chi2<<">"<<chi2Cut<<std::endl;
+        }
+        return false;
+    }
     double charge = fitState->getCharge();
     int isFitted = fitState->isFitted();
     int isConverged = fitState->isFitConverged();
     int isConvergedFully = fitState->isFitConvergedFully();
-    TMatrixDSym fittedCov;
+
+    TMatrixDSym fittedCov(6);//cm, GeV
     TLorentzVector fittedPos;
     TVector3 fittedMom;
     int fittedState=getFittedState(fittedPos,fittedMom,fittedCov);
-    if(m_debug>=2)std::cout<<"fit result: get status OK? pidType "
-        <<pidType<<" fittedState==0 " <<(0==fittedState)<<" isFitted "<<isFitted
-        <<" isConverged "<<isConverged<<" ndf "<<ndf<<std::endl;
-    if((0!=fittedState) || (!isFitted) || !isConvergedFully || (ndf<ndfCut)){
-        if(m_debug>=2)std::cout<<" fitting failed"<<std::endl;
+
+    //get dx
+    TVector3 pos;
+    TVector3 mom;
+    pos.SetXYZ(fittedPos.X(),fittedPos.Y(),fittedPos.Z());
+    mom.SetXYZ(fittedMom.X(),fittedMom.Y(),fittedMom.Z());
+    //std::cout << "fitted momx = " << mom.X() << "momy = " << mom.Y() << "momz = " << mom.Z() << " mom.Mag = " << mom.Mag() << std::endl;
+    //std::cout << "fitted posx = " << pos.X() << "posy = " << pos.Y() << "posz = " << pos.Z() << std::endl;
+    double radius = 80.022;  // cm
+    const TVector3 linePoint(0,0,0);
+    const TVector3 lineDirection(0,0,1);
+
+    for(int i = 0;i<fitid;i++){
+        int repID=1;
+        radius+=1.741321;
+        double tracklength =
+            extrapolateToCylinder(pos,mom,radius,linePoint,lineDirection,repID);
+        hitMomMag.push_back(mom.Mag());
+        //std::cout << "momx = " << mom.X() << "momy = " << mom.Y() << "momz = " << mom.Z() << " mom.Mag = " << mom.Mag() << std::endl;
+        //std::cout << "posx = " << pos.X() << "posy = " << pos.Y() << "posz = " << pos.Z() << std::endl;
+        trackL.push_back(tracklength);
+    }
+
+    for(int j=0;j<hitMomMag.size()-1;j++)
+    {
+        hitMom.push_back(hitMomMag[j]-hitMomMag[j+1]);
+        //std::cout << " Error Dep = " << hitMomMag[j]-hitMomMag[j+1] << std::endl;
+    }
+
+    if(m_debug>0)std::cout<<m_name<<" fit result: get status OK? pidType "
+        <<pidType<<" fittedState"<<fittedState<<"==0? "<<(0==fittedState)
+            <<" isFitted "<<isFitted
+            <<" isConverged "<<isConverged<<" ndf "<<ndf<<std::endl;
+    if((0!=fittedState)||(!isFitted)||(!isConvergedFully)||(ndf>ndfCut)){
+        if(m_debug>0)std::cout<<m_name<<" fitting FAILED!=========="<<std::endl;
     }else{
-        if(m_debug>=2)std::cout<<"fit result: Pos("<<
-            fittedPos.X()<<" "<<
-            fittedPos.Y()<<" "<<
-            fittedPos.Z()<<") mom("<<
-            fittedMom.X()<<" "<<
-            fittedMom.Y()<<" "<<
-            fittedMom.Z()<<") p_tot "<<
-            fittedMom.Mag()<<" pt "<<
-            fittedMom.Perp()<<
-            " chi2 "<<chi2<<
-            " ndf "<<ndf
-            <<std::endl;
-    }
-    float pos[3]={float(fittedPos.X()),float(fittedPos.Y()),float(fittedPos.Z())};
-    float mom[3]={float(fittedMom.X()),float(fittedMom.Y()),float(fittedMom.Z())};
-    HelixClass helix;
-    helix.Initialize_VP(pos,mom,charge,m_genfitField->getBz(fittedPos.Vect()));
-
-
-    /////track status at POCA to origin
-    //TVector3 origin(pivot);
-    //TVector3 pocaToOrigin_pos(1e9*dd4hep::cm,1e9*dd4hep::cm,1e9*dd4hep::cm);
-    //TVector3 pocaToOrigin_mom(1e9*dd4hep::GeV,1e9*dd4hep::GeV,1e9*dd4hep::GeV);
-
-    //if(ExtrapolateToPoint(pocaToOrigin_pos,pocaToOrigin_mom,
-    //            m_track,origin) > 1e6*dd4hep::cm){
-    //    log<<"extrapolate to origin failed";
-    //    return false;
-    //}
+        if(m_debug>0){
+            const TLorentzVector seedPos=getSeedStatePos();
+            const TVector3 seedMom=getSeedStateMom();
+            std::cout<<m_name<<"===fit-seed:delta pos("
+                <<fittedPos.X()-seedPos.X()<<","
+                <<fittedPos.Y()-seedPos.Y()<<","
+                <<fittedPos.Z()-seedPos.Z()<<") delta mom("
+                <<fittedMom.X()-seedMom.X()<<","
+                <<fittedMom.Y()-seedMom.Y()<<","
+                <<fittedMom.Z()-seedMom.Z()<<")"<<" delta mag "<<fittedMom.Mag()-seedMom.Mag()<<std::endl;
+            std::cout<<m_name<<" seed pos("
+                <<seedPos.X()<<","
+                <<seedPos.Y()<<","
+                <<seedPos.Z()<<") seed mom("
+                <<seedMom.X()<<","
+                <<seedMom.Y()<<","
+                <<seedMom.Z()<<std::endl;
+            std::cout<<m_name<<" fit result: Pos("<<
+                fittedPos.X()<<" "<<
+                fittedPos.Y()<<" "<<
+                fittedPos.Z()<<") mom("<<
+                fittedMom.X()<<" "<<
+                fittedMom.Y()<<" "<<
+                fittedMom.Z()<<") p_tot "<<
+                fittedMom.Mag()<<" pt "<<
+                fittedMom.Perp()<<
+                " chi2 "<<chi2<<
+                " ndf "<<ndf
+                <<std::endl;
+            std::cout<<"fittedCov "<<std::endl;
+            fittedCov.Print();
+        }
+    }
 
 
-    //new TrackState
-    edm4hep::TrackState* trackState = new edm4hep::TrackState();
-    trackState->location=0;//edm4hep::AtIP;
-    trackState->D0=helix.getD0();
-    trackState->phi=helix.getPhi0();
-    trackState->omega=helix.getOmega();
-    trackState->Z0=helix.getZ0();
-    trackState->tanLambda=helix.getTanLambda();
-    trackState->referencePoint=helix.getReferencePoint();
-
-    //    std::array<float,15> covMatrix;
-    //    int k=0;
-    //    for(int i=0;i<5;i++){
-    //        for(int j=0;j<5;j++){
-    //            if(i<=j) covMatrix[k]=;//FIXME
-    //        }
-    //    }
-    //    trackState.covMatrix=
+    //TVectorD seedState5(5);
+    //getSeedState5(seedState5);
+
+    ///track status at POCA to referencePoint: origin
+    const TVector3 referencePoint(0,0,0);
+    //TVector3 
+    pocaToOrigin_pos.SetXYZ(1e9*dd4hep::cm,1e9*dd4hep::cm,1e9*dd4hep::cm);
+    //TVector3 
+    pocaToOrigin_mom.SetXYZ(1e9*dd4hep::GeV,1e9*dd4hep::GeV,1e9*dd4hep::GeV);
+    //TMatrixDSym pocaToOrigin_cov;
+    if(extrapolateToPoint(pocaToOrigin_pos,pocaToOrigin_mom,pocaToOrigin_cov,
+                referencePoint) > 1e6*dd4hep::cm){
+        if(m_debug>0)std::cout<<m_name<<" extrapolate to origin failed"<<std::endl;
+        return false;
+    }
 
-    //new Track
-    edm4hep::MutableTrack* track = new edm4hep::MutableTrack();
-    //track->setType();
-    track->setChi2(fitState->getChi2());
-    track->setNdf(fitState->getNdf());
-    //track->setDEdx();
-    //track->setRadiusOfInnermostHit();//FIXME
-    //track->addToTrackerHits();
+    //Unit conversion of position and momentum cm->mm
+    pocaToOrigin_pos.SetXYZ(pocaToOrigin_pos.X()/dd4hep::mm,
+            pocaToOrigin_pos.Y()/dd4hep::mm,
+            pocaToOrigin_pos.Z()/dd4hep::mm);
+    pocaToOrigin_mom.SetXYZ(pocaToOrigin_mom.X(),
+            pocaToOrigin_mom.Y(),
+            pocaToOrigin_mom.Z());
+
+    //unit conversion of error matrix
+    TMatrixDSym covMatrix_6=fittedCov;
+    for(int i=0;i<5;i++){
+        covMatrix_6[0][i]=fittedCov[0][i]/dd4hep::mm;//d0 column
+        covMatrix_6[2][i]=fittedCov[1][i]/dd4hep::mm;//omega column
+        covMatrix_6[3][i]=fittedCov[2][i]/dd4hep::mm;//z0 column
+        covMatrix_6[i][0]=fittedCov[i][0]/dd4hep::mm;//d0 row
+        covMatrix_6[i][2]=fittedCov[i][1]/dd4hep::mm;//omega row
+        covMatrix_6[i][3]=fittedCov[i][2]/dd4hep::mm;//z0 row
+        //covMatrix_6[0][i]=fittedCov[0][i]/GenfitUnit::cm*dd4hep::cm;//d0 column
+        //covMatrix_6[2][i]=fittedCov[2][i]*GenfitUnit::cm/dd4hep::cm;//omega column
+        //covMatrix_6[3][i]=fittedCov[3][i]/GenfitUnit::cm*dd4hep::cm;//z0 column
+        //covMatrix_6[i][0]=fittedCov[i][0]/GenfitUnit::cm*dd4hep::cm;//d0 row
+        //covMatrix_6[i][2]=fittedCov[i][2]*GenfitUnit::cm/dd4hep::cm;//omega row
+        //covMatrix_6[i][3]=fittedCov[i][3]/GenfitUnit::cm*dd4hep::cm;//z0 row
+    }
+
+    double Bz=m_genfitField->getBz(referencePoint)/GenfitUnit::tesla;
+
+    if(m_debug>0){
+        std::cout<<m_name<<" fit result poca: Pos"<<std::endl;
+        pocaToOrigin_pos.Print();
+        pocaToOrigin_mom.Print();
+        std::cout<<" chi2 "<<chi2<< " ndf "<<ndf <<std::endl;
+        std::cout<<"fittedCov "<<std::endl;
+        fittedCov.Print();
+        std::cout<<"covMatrix_6 "<<std::endl;
+        covMatrix_6.Print();
+        std::cout<<__LINE__<<" debug Bz tesla"<<Bz<<std::endl;
+    }
+
+    edm4hep::TrackState trackState;
+    CEPC::getTrackStateFromPosMom(trackState,Bz,pocaToOrigin_pos,
+            pocaToOrigin_mom,charge,covMatrix_6);
+
+    trackState.location=0;//edm4hep::AtIP;//FIXME
+    if(m_debug>2){
+        std::cout<<m_name<<" trackState "<<trackState<<std::endl;
+    }
+    track.addToTrackStates(trackState);
+
+    //ngenfitHit = m_genfitHitVec.size();
+    ngenfitHit = nPoints;
+    std::cout << " m_genfitHitVec size = " << m_genfitHitVec.size() << std::endl;
+    //    for(long unsigned int i=0; i<m_genfitHitVec.size();i++)
+    //    {
+    //        GenfitHit * genfitHit = GetHit(i);
+    //        edm4hep::TrackerHit* trackHit =
+    //            const_cast<edm4hep::TrackerHit*>(genfitHit->getTrackerHit());
+    //
+    //        track.addToTrackerHits(*trackHit);
+    //    }
+    //track.setType();
+    track.setChi2(chi2);
+    track.setNdf(ndf);
+    //track.setDEdx();
+    //track.setRadiusOfInnermostHit();//FIXME
+    //track.addToTrackerHits();
 
     //new ReconstructedParticle
     //recParticle->setType();
     //dcRecParticle->setEnergy();
 
-    edm4hep::Vector3f momVec3(helix.getMomentum()[0],
-            helix.getMomentum()[1],helix.getMomentum()[2]);
-    recParticle.setMomentum(momVec3);
-    //recParticle->setReferencePoint(referencePoint);
-    recParticle.setCharge(helix.getCharge());
-    //    recParticle->setMass();
-    //    recParticle->setCovMatrix();
-    //    rcRecParticle->setStartVertex();
-    //recParticle->addToTracks(track);
+    recParticle.setMomentum(edm4hep::Vector3f(pocaToOrigin_mom.X(),
+                pocaToOrigin_mom.Y(),pocaToOrigin_mom.Z()));
+    recParticle.setReferencePoint(edm4hep::Vector3f(referencePoint.X(),
+                referencePoint.Y(),referencePoint.Z()));
+    recParticle.setCharge(charge);
+    //recParticle->setMass();
+    //recParticle.setCovMatrix(trackState->covMatrix);
+    //recParticle->setStartVertex();
+    recParticle.addToTracks(track);
+    if(m_debug>2){
+        std::cout<<m_name<<" storeTrack trackState "<<trackState<<std::endl;
+        std::cout<<m_name<<" storeTrack track "<<track<<std::endl;
+    }
 
     return true;
 }
 
-void GenfitTrack::pivotToFirstLayer(edm4hep::Vector3d& pos,
-        edm4hep::Vector3f& mom, edm4hep::Vector3d& firstPos,
+void GenfitTrack::pivotToFirstLayer(const edm4hep::Vector3d& pos,
+        const edm4hep::Vector3f& mom, edm4hep::Vector3d& firstPos,
         edm4hep::Vector3f& firstMom)
 {
     //FIXME, TODO
@@ -837,3 +1395,246 @@ void GenfitTrack::pivotToFirstLayer(edm4hep::Vector3d& pos,
     firstMom=mom;
 }
 
+int GenfitTrack::getDetTypeID(unsigned long long cellID) const
+{
+    UTIL::BitField64 encoder(lcio::ILDCellID0::encoder_string);
+    encoder.setValue(cellID);
+    return encoder[lcio::ILDCellID0::subdet];
+}
+
+void GenfitTrack::getAssoSimTrackerHit(
+        const edm4hep::MCRecoTrackerAssociationCollection*& assoHits,
+        edm4hep::TrackerHit* trackerHit,
+        edm4hep::SimTrackerHit& simTrackerHit) const
+{
+    for(auto assoHit: *assoHits){
+        if(assoHit.getRec()==*trackerHit)
+        {
+            simTrackerHit=assoHit.getSim();
+
+        }
+    }
+}
+
+genfit::AbsTrackRep* GenfitTrack::getRep(int id) const
+{
+    return m_track->getTrackRep(id);
+}
+
+void GenfitTrack::getSeedCov(TMatrixDSym& cov){
+    cov.Zero();
+    for(int i=0;i<3;i++) {
+        double posResolusion=1.;
+        cov(i,i)=posResolusion*posResolusion; //seed position
+        double momResolusion=5.;
+        cov(i+3,i+3)=momResolusion*momResolusion; //seed momentum
+    }
+}
+
+//unit conversion here
+void GenfitTrack::getEndPointsOfWire(int cellID,TVector3& end0,TVector3& end1) const{
+    m_gridDriftChamber->cellposition(cellID,end0,end1);//dd4hep unit
+    end0*=(1./dd4hep::cm*GenfitUnit::cm);
+    end1*=(1./dd4hep::cm*GenfitUnit::cm);
+}
+//unit conversion here
+void GenfitTrack::getTrackFromMCPartile(const edm4hep::MCParticle mcParticle,
+        TVectorD& trackParam, TMatrixDSym& cov) const{
+    TVector3 pos;
+    TVector3 mom;
+    getPosMomFromMCPartile(mcParticle,pos,mom);
+    trackParam[0]=pos[0];
+    trackParam[1]=pos[1];
+    trackParam[2]=pos[2];
+    trackParam[3]=mom[0];
+    trackParam[4]=mom[1];
+    trackParam[5]=mom[2];
+    //cov TODO
+}
+//unit conversion here
+void GenfitTrack::getPosMomFromMCPartile(const edm4hep::MCParticle mcParticle,
+        TVector3& pos,TVector3& mom) const{
+    const edm4hep::Vector3d mcParticleVertex=mcParticle.getVertex();//mm
+    const edm4hep::Vector3f mcParticleMom=mcParticle.getMomentum();//GeV
+    pos[0]=mcParticleVertex.x*GenfitUnit::mm;
+    pos[1]=mcParticleVertex.y*GenfitUnit::mm;
+    pos[2]=mcParticleVertex.z*GenfitUnit::mm;
+    mom[0]=mcParticleMom.x*GenfitUnit::GeV;
+    mom[1]=mcParticleMom.y*GenfitUnit::GeV;
+    mom[2]=mcParticleMom.z*GenfitUnit::GeV;
+    if(m_debug>2){
+        std::cout<<"getPosMomFromTrackState pos("<<pos.X()<<" "<<pos.Y()
+            <<" "<<pos.Z();
+        std::cout<<") "<<" ("<<mom.X()<<" "<<mom.Y()<<" "<<mom.Z()<<")"
+            <<" mom "<<mom.Mag()<<" pt "<<mom.Perp()<<std::endl;
+    }
+}
+
+//unit conversion here
+void GenfitTrack::getTrackFromEDMTrack(const edm4hep::Track& edm4HepTrack,
+        double& charge, TVectorD& trackParam, TMatrixDSym& cov) const{
+    TVector3 pos;
+    TVector3 mom;
+    double Bz=m_genfitField->getBz(TVector3{0.,0.,0.})/GenfitUnit::tesla;
+    double charge_double;
+    CEPC::getPosMomFromTrackState(edm4HepTrack.getTrackStates(0),Bz,pos,mom,charge_double,cov);
+
+    //std::cout<<__LINE__<<" Bz "<<Bz<<" charge "<<charge_double<<std::endl;
+    //pos.Print();
+    //mom.Print();
+    charge=(int) charge_double;
+    trackParam[0]=pos[0]*GenfitUnit::mm;
+    trackParam[1]=pos[1]*GenfitUnit::mm;
+    trackParam[2]=pos[2]*GenfitUnit::mm;
+    trackParam[3]=mom[0]*GenfitUnit::GeV;
+    trackParam[4]=mom[1]*GenfitUnit::GeV;
+    trackParam[5]=mom[2]*GenfitUnit::GeV;
+
+    //cov unit conversion
+    for(int i=0;i<6;i++){
+        for(int j=0;j<6;j++){
+            cov(i,j) = cov(i,j)*GenfitUnit::mm;
+        }
+    }
+}
+
+//to genfit unit
+void GenfitTrack::getISurfaceOUV(const dd4hep::rec::ISurface* iSurface,TVector3& o,
+        TVector3& u,TVector3& v, double& lengthU,double& lengthV){
+    o.SetXYZ(iSurface->origin().x()/dd4hep::mm*GenfitUnit::mm,
+            iSurface->origin().y()/dd4hep::mm*GenfitUnit::mm,
+            iSurface->origin().z()/dd4hep::mm*GenfitUnit::mm);
+    u.SetXYZ(iSurface->u().x()/dd4hep::mm*GenfitUnit::mm,
+            iSurface->u().y()/dd4hep::mm*GenfitUnit::mm,
+            iSurface->u().z()/dd4hep::mm*GenfitUnit::mm);
+    v.SetXYZ(iSurface->v().x()/dd4hep::mm*GenfitUnit::mm,
+            iSurface->v().y()/dd4hep::mm*GenfitUnit::mm,
+            iSurface->v().z()/dd4hep::mm*GenfitUnit::mm);
+
+    lengthU=iSurface->length_along_u();
+    lengthV=iSurface->length_along_v();
+}
+
+void GenfitTrack::getMeasurementAndCov(edm4hep::TrackerHit* hit,TVector3& pos,TMatrixDSym& cov){
+
+    pos.SetXYZ(hit->getPosition().x*GenfitUnit::mm,
+            hit->getPosition().y*GenfitUnit::mm,
+            hit->getPosition().z*GenfitUnit::mm);
+}
+
+
+int GenfitTrack::getSigmas(int cellID,std::vector<float> sigmaUVec,
+        std::vector<float> sigmaVVec,float& sigmaU,float& sigmaV)const{
+    int detTypeID=getDetTypeID(cellID);
+    int sigmaUID=0;
+    int sigmaVID=0;
+    int layer=0;
+    dd4hep::DDSegmentation::BitFieldCoder* decoder;
+    if(m_geomSvc->lcdd()->constant<int>("DetID_DC")==detTypeID){
+        sigmaUID=0;
+        sigmaVID=0;
+    }else if(detTypeID==lcio::ILDDetID::VXD){
+        decoder=m_geomSvc->getDecoder("VXDCollection");//FIXME
+        layer=decoder->get(cellID,"layer");//FIXME
+        sigmaUID=layer+1;
+        sigmaVID=layer+1;
+    }else if(detTypeID==lcio::ILDDetID::SIT){
+        sigmaUID=7;
+        sigmaVID=7;
+    }else if(detTypeID==lcio::ILDDetID::SET){
+        sigmaUID=8;
+        sigmaVID=8;
+    }else if(detTypeID==lcio::ILDDetID::FTD){
+        decoder=m_geomSvc->getDecoder("FTDCollection");//FIXME
+        layer=decoder->get(cellID,"layer");//FIXME
+        sigmaUID=layer+9;
+        sigmaVID=layer+9;
+    }else{
+        if(m_debug>=0) std::cout<<m_name<<" Error: no detType!"<<std::endl;
+    }
+    if(m_debug){
+        std::cout<<"sigmaUID "<<sigmaUID<<" sigmaVID "<<sigmaVID<<std::endl;
+        //std::cout<<"pos "<<pos_smeared[0]<<" "<<pos_smeared[1]<<" "<<pos_smeared[2]<<std::endl;
+        //std::cout<<"angle "<<atan2(pos_smeared[1],pos_smeared[0])<<std::endl;
+        std::cout<<"sigmaU "<<sigmaUVec[sigmaUID]*GenfitUnit::mm
+            <<" sigmaV "<<sigmaVVec[sigmaVID]*GenfitUnit::mm<<std::endl;
+    }
+    sigmaU=sigmaUVec[sigmaUID]*GenfitUnit::mm;
+    sigmaV=sigmaVVec[sigmaVID]*GenfitUnit::mm;
+    return sigmaUID;
+}
+
+bool GenfitTrack::isCDCHit(edm4hep::TrackerHit* hit){
+    return m_geomSvc->lcdd()->constant<int>("DetID_DC")==
+        getDetTypeID(hit->getCellID());
+}
+
+void GenfitTrack::getSortedTrackerHits(
+        std::vector<edm4hep::TrackerHit*>& trackerHits,
+        const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
+        std::vector<edm4hep::TrackerHit*>& sortedDCTrackerHits,
+        int sortMethod){
+
+    std::vector<std::pair<double,edm4hep::TrackerHit*> > sortedDCTrackerHitPair;
+    for(auto trackerHit : trackerHits){
+        edm4hep::TrackerHit* thisHit = trackerHit;
+        if(!isCDCHit(thisHit))continue;//skip non-DC trackerHit
+
+        edm4hep::SimTrackerHit simTrackerHitAsso;
+        getAssoSimTrackerHit(assoHits,trackerHit,simTrackerHitAsso);
+        double time=simTrackerHitAsso.getTime();
+        if(0==sortMethod){
+            //by time
+            sortedDCTrackerHitPair.push_back(std::make_pair(time,trackerHit));
+            if(m_debug>0){ std::cout<<"sorted DC digi by time"<<std::endl;}
+        }else if(1==sortMethod){
+            //by layer
+            sortedDCTrackerHitPair.push_back(std::make_pair(
+                        m_decoderDC->get(trackerHit->getCellID(),"layer"),trackerHit));
+            if(m_debug>0){ std::cout<<"sorted DC digi by layer"<<std::endl;}
+        }else{
+            sortedDCTrackerHits.push_back(trackerHit);
+        }
+    }
+    if(0==sortMethod || 1==sortMethod){
+        std::sort(sortedDCTrackerHitPair.begin(),sortedDCTrackerHitPair.end(),
+                sortDCDigi);
+        for(auto trackerHit:sortedDCTrackerHitPair){
+            sortedDCTrackerHits.push_back(trackerHit.second);
+        }
+    }
+    if(m_debug>0){
+        std::cout<<"trackerHits on track after sort\n";
+        for(auto trackerHit:sortedDCTrackerHits){
+            std::cout<<trackerHit->getCellID()<<"("<<std::setw(2)
+                <<m_decoderDC->get(trackerHit->getCellID(),"layer")
+                <<","<<std::setw(3)
+                <<m_decoderDC->get(trackerHit->getCellID(),"cellID")<<")\n";
+        }
+        std::cout<<"\n"; std::cout.unsetf(std::ios_base::floatfield);
+    }
+    return;
+}//end of getSortedTrackerHits
+
+//make a genfit hit and do hits selection
+GenfitHit* GenfitTrack::makeAGenfitHit(edm4hep::TrackerHit* trackerHit,
+        edm4hep::SimTrackerHit* simTrackerHitAsso,
+        double sigma,bool truthAmbig,double skipCorner,double skipNear){
+
+    //TODO truthAmbig
+    double driftVelocity=40.;//FIXME
+    GenfitHit* genfitHit=new GenfitHit(trackerHit,simTrackerHitAsso,m_decoderDC,
+            m_gridDriftChamber,driftVelocity,sigma*GenfitUnit::mm);
+    //skip corner hit
+    if(fabs(genfitHit->getDriftDistance())>skipCorner){
+        if(m_debug) std::cout<<" skip hit dd > skipCorner"<<std::endl;
+        delete genfitHit;
+        return nullptr;
+    }
+    if(genfitHit->getDriftDistance()<skipNear){
+        if(m_debug) std::cout<<" skip hit dd < skipCorner"<<std::endl;
+        delete genfitHit;
+        return nullptr;
+    }
+    return genfitHit;
+}
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitTrack.h b/Reconstruction/RecGenfitAlg/src/GenfitTrack.h
index bcff94794..bfcb7a995 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitTrack.h
+++ b/Reconstruction/RecGenfitAlg/src/GenfitTrack.h
@@ -11,8 +11,6 @@
 ///
 /// Authors:
 ///   Zhang Yao (zhangyao@ihep.ac.cn)
-///   Y.Fujii (yfujii@ihep.ac.cn)
-///   Yohei Nakatsugawa (yohei@ihep.ac.cn)
 ///
 //////////////////////////////////////////////////////////////////
 
@@ -20,15 +18,23 @@
 #define RECGENFITALG_GENFITTRACK_H
 
 #include "GenfitFitter.h"
+#include "GenfitHit.h"
 
 //ROOT
+#include "TVector3.h"
 #include "TVectorD.h"
 #include "TMatrixDSym.h"
+#include "TLorentzVector.h"
+
+//Gaudi
+#include "GaudiKernel/SmartIF.h"
 
 //STL
 #include <vector>
 
 class TLorentzVector;
+class IGeomSvc;
+class WireMeasurementDC;
 
 namespace genfit{
     class Track;
@@ -44,101 +50,132 @@ namespace edm4hep{
     class MutableReconstructedParticle;
     class MCRecoTrackerAssociationCollection;
     class Track;
-    class Track;
+    class MutableTrack;
+    class TrackCollection;
     class TrackerHit;
+    class SimTrackerHit;
     class Vector3d;
     class Vector3f;
+    class TrackerHitCollection;
 }
 namespace dd4hep {
     namespace DDSegmentation{
         class GridDriftChamber;
+        class BitFieldCoder;
+    }
+    namespace rec{
+        class ISurface;
     }
 }
 
 class GenfitTrack {
     friend int GenfitFitter::processTrack(
-            GenfitTrack* track, bool resort);
+            GenfitTrack* track, bool resort=true);
 
     friend int GenfitFitter::processTrackWithRep(
-            GenfitTrack* track, int repID, bool resort);
-
-    friend double GenfitFitter::extrapolateToHit(TVector3& poca,
-            TVector3& pocaDir,
-            TVector3& pocaOnWire, double& doca, const GenfitTrack* track,
-            TVector3 pos, TVector3 mom, TVector3 end0, TVector3 end1, int debug,
-            int repID, bool stopAtBoundary, bool calcJacobianNoise);
-
-    friend double GenfitFitter::extrapolateToCylinder(TVector3& pos,
-            TVector3& mom,
-            GenfitTrack* track, double radius, const TVector3 linePoint,
-            const TVector3 lineDirection, int hitID, int repID,
-            bool stopAtBoundary, bool calcJacobianNoise);
-
-    friend double GenfitFitter::extrapolateToPoint(TVector3& pos, TVector3& mom,
-            const GenfitTrack* genfitTrack, const TVector3& point, int repID,
-            bool stopAtBoundary, bool calcJacobianNoise) const;
+            GenfitTrack* track, int repID, bool resort=true);
 
     public:
     GenfitTrack(const GenfitField* field,
             const dd4hep::DDSegmentation::GridDriftChamber* seg,
+            SmartIF<IGeomSvc> geom,
             const char* name="GenfitTrack");
     virtual ~GenfitTrack();
 
-    /// Add a Genfit track
-    virtual bool createGenfitTrack(int pdgType,int charge,TLorentzVector pos, TVector3 mom,
-            TMatrixDSym covM);
-    //virtual bool createGenfitTrack(TLorentzVector posInit,TVector3 momInit,
-            //TMatrixDSym covMInit);
-
     ///Create genfit track from MCParticle
     bool createGenfitTrackFromMCParticle(int pidTyep,const edm4hep::MCParticle&
             mcParticle, double eventStartTime=0.);
-    bool createGenfitTrackFromEDM4HepTrack(int pidType, edm4hep::Track track,
-            double eventStartTime);
+    bool createGenfitTrackFromEDM4HepTrack(int pidType,const edm4hep::Track& track,
+            double eventStartTime,bool isUseCovTrack);
 
-    //  /// Prepare a hit list, return number of hits on track
-    //  int PrepareHits();//TODO
+    /// ---------Add measurements---------
+    ///Add one space point measurement, return number of hits on track
+    virtual bool addSpacePointMeasurement(const TVector3&,std::vector<float>
+        sigmaU,std::vector<float> sigmaV,int cellID,int hitID);
 
-    /// Add a space point measurement, return number of hits on track
-    bool addSpacePointTrakerHit(edm4hep::TrackerHit hit, int hitID);
+    ///Add silicon space points from edm4hep::track
+    int addSpacePointsSi(const edm4hep::Track& track,
+            std::vector<float> sigmaU,std::vector<float> sigmaV);
 
-    /// Add a space point measurement, return number of hits on track
-    virtual bool addSpacePointMeasurement(const TVectorD&, double,
-            int detID=-1, int hitID=-1, bool smear=false);
+    ///Add drift chamber space points from edm4hep::track
+    int addSpacePointsDC(const edm4hep::Track& track,
+            const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
+        std::vector<float> sigmaU,std::vector<float> sigmaV);
 
-    /// Add a WireMeasurement with MC truth position smeared by sigma
-    virtual void addWireMeasurement(double driftDistance,
-            double driftDistanceError, const TVector3& endPoint1,
-            const TVector3& endPoint2, int lrAmbig, int detID, int hitID);
 
-    /// Add a WireMeasurement with DC digi
-    virtual bool addWireMeasurementOnTrack(edm4hep::Track track, double sigma);
+    ///Add WireMeasurements of hits on track
+    virtual int addWireMeasurementsOnTrack(edm4hep::Track& track,float sigma,
+            const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
+            int sortMethod,bool truthAmbig,float skipCorner, float skipNear);
 
-    ///Add space point from truth to track
-    int addSimTrackerHits( edm4hep::Track track,
-        const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
-        float sigma,bool smear=false);// float nSigmaSelection
+    ///Add WireMeasurements of hits on track from hit selection
+    virtual int addWireMeasurementsFromList(std::vector<edm4hep::TrackerHit*>& hits,float sigma,
+            const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
+            int sortMethod,bool truthAmbig,float skipCorner, float skipNear);
+
+    ///Add one silicon hits
+    bool addSiliconMeasurement(edm4hep::TrackerHit* hit,
+            float sigmaU,float sigmaV,int cellID,int hitID);
+
+    ///Add silicon measurements, return number of hits on track
+    int addSiliconMeasurements(edm4hep::Track& track,
+            std::vector<float> sigmaU,std::vector<float> sigmaV);
+
+    bool debugDistance(const edm4hep::TrackerHitCollection* dCDigiCol,
+            int& nFittedDC,int& nFittedSDT,int& ngenfitHit,
+            std::vector<double>& smearDistance,
+            std::vector<double>& truthDistance,double driftVelocity);
+    bool GetDocaRes(int hitID,  double& DriftDis,double& fittedDoca,
+            double& res,int repID=0, bool biased=true) const;
 
     ///Store track to ReconstructedParticle
-    bool storeTrack(edm4hep::MutableReconstructedParticle& dcRecParticle,int pidType,
-            int ndfCut=1e9, double chi2Cut=1.e9);
+    bool storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
+            edm4hep::MutableTrack& track,
+            TVector3& pocaToOrigin_pos,
+            TVector3& pocaToOrigin_mom,
+            TMatrixDSym& pocaToOrigin_cov,
+            int pidType, int ndfCut, double chi2Cut,
+            int& nFittedDC, int& nFittedSDT,int& ngenfitHit,
+            std::vector<double>& trackL, std::vector<double>& hitMom,
+            std::vector<float>& truthMomEdep,
+            const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
+            std::vector<double>& driftDis,
+            std::vector<double>& FittedDoca,
+            std::vector<double>& Res);
 
     ///A tool to convert track to the first layer of DC
-    void pivotToFirstLayer(edm4hep::Vector3d& pos,edm4hep::Vector3f& mom,
-            edm4hep::Vector3d& firstPos, edm4hep::Vector3f& firstMom);
+    void pivotToFirstLayer(const edm4hep::Vector3d& pos,
+            const edm4hep::Vector3f& mom, edm4hep::Vector3d& firstPos,
+            edm4hep::Vector3f& firstMom);
 
     /// Copy a track to event
     //void CopyATrack()const;
 
-    ///Extrapolate to Hit
-    double extrapolateToHit( TVector3& poca, TVector3& pocaDir,
-            TVector3& pocaOnWire, double& doca, TVector3 pos, TVector3 mom,
-            TVector3 end0,//one end of the hit wire
-            TVector3 end1,//the orhter end of the hit wire
-            int debug,
-            int repID,
-            bool stopAtBoundary,
-            bool calcJacobianNoise) const;
+    //return dd4hep unit
+    double extrapolateToHit(TVector3& poca, TVector3& pocaDir,
+            TVector3& pocaOnWire, double& doca,edm4hep::MCParticle mcParticle,
+            int cellID, int repID, bool stopAtBoundary, bool calcJacobianNoise)const;
+    /// Extrapolate the track to the point
+    /// Output: pos and mom of POCA point to point
+    /// Input: genfitTrack,point,repID,stopAtBoundary and calcAverageState
+    /// repID same with pidType
+//    double extrapolateToPoint(TVector3& pos, TVector3& mom,TMatrixDSym& cov,
+//            const TVector3& point, int repID=0, bool stopAtBoundary = false,
+//            bool calcJacobianNoise = true) const;
+
+    double extrapolateToPoint(TVector3& pos, TVector3& mom, TMatrixDSym& cov,
+            const TVector3& point, int repID=0,
+            bool stopAtBoundary = false, bool calcJacobianNoise = true) const;
+
+    /// Extrapolate the track to the cyliner at fixed raidus
+    /// Output: pos and mom at fixed radius
+    /// Input: genfitTrack, radius of cylinder at center of the origin,
+    ///        repID, stopAtBoundary and calcAverageState
+    double extrapolateToCylinder(TVector3& pos, TVector3& mom,
+            double radius, const TVector3 linePoint,
+            const TVector3 lineDirection, int hitID =0, int repID=0,
+            bool stopAtBoundary=false, bool calcJacobianNoise=true);
+
 
     bool getPosMomCovMOP(int hitID, TLorentzVector& pos, TVector3& mom,
             TMatrixDSym& cov, int repID=0) const;
@@ -148,11 +185,12 @@ class GenfitTrack {
     const TVector3 getSeedStateMom() const;
     void getSeedStateMom(TLorentzVector& pos, TVector3& mom) const;
     unsigned int getNumPoints() const;
+    unsigned int getNumPointsDet(int cellID) const;
 
     /// get the fitted track status
     const genfit::FitStatus* getFitStatus(int repID=0) const;
     int getFittedState(TLorentzVector& pos, TVector3& mom, TMatrixDSym& cov,
-            int repID=0, bool biased=true) const;
+            int trackPointId=0, int repID=0, bool biased=true) const;
     int getNumPointsWithFittedInfo(int repID=0) const;
     bool getFirstPointWithFittedInfo(int repID=0) const;
     bool fitSuccess(int repID) const;
@@ -169,7 +207,9 @@ class GenfitTrack {
     void print(TLorentzVector pos, TVector3 mom, const char* comment="") const;
 
     /// set and get debug level
-    void setDebug(int debug);
+    void setDebug(int debug){m_debug=debug;}
+    void setDebugGenfit(int debug);
+    void setDebugLocal(int debug);
     int getDebug(void) const { return m_debug;}
 
     /// get name of this object
@@ -177,30 +217,67 @@ class GenfitTrack {
     genfit::Track* getTrack() const{return m_track;}
 
     /// Add a track representation
-    genfit::RKTrackRep* addTrackRep(int pdg);
+    genfit::RKTrackRep* addTrackRep(int pdgType,int charge);
 
+    /// Get a hit according to index
+    GenfitHit* GetHit(long unsigned int i) const;
     protected:
     //genfit::Track* getTrack() {return m_track;}
 
     private:
 
+    /// ---------Add a Genfit track-------
+    bool createGenfitTrack(int pdgType,int charge,
+            TVectorD trackParam, TMatrixDSym covMInit_6);
+
+    int getDetTypeID(unsigned long long cellID) const;
     const char* m_name;
 
     ///Note! private functions are using genfit unit, cm and MeV
 
-    genfit::AbsTrackRep* getRep(int id=0) const {return m_reps[id];}
+    genfit::AbsTrackRep* getRep(int id=0) const;
     bool getMOP(int hitID, genfit::MeasuredStateOnPlane& mop,
             genfit::AbsTrackRep* trackRep=nullptr) const;
+    const dd4hep::rec::ISurface* getISurface(edm4hep::TrackerHit* hit);
+    void getSeedCov(TMatrixDSym& cov);
+    void getAssoSimTrackerHit(
+            const edm4hep::MCRecoTrackerAssociationCollection*& assoHits,
+            edm4hep::TrackerHit* trackerHit,
+            edm4hep::SimTrackerHit& simTrackerHit) const;
+    void getEndPointsOfWire(int cellID,TVector3& end0,TVector3& end1)const;
+    void getTrackFromEDMTrack(const edm4hep::Track& edm4HepTrack,
+            double& charge, TVectorD& trackParam, TMatrixDSym& cov) const;
+    void getTrackFromMCPartile(const edm4hep::MCParticle mcParticle,
+            TVectorD& trackParam, TMatrixDSym& cov) const;
+    void getPosMomFromMCPartile(const edm4hep::MCParticle mcParticle,
+            TVector3& pos,TVector3& mom) const;
+    void clearGenfitHitVec();
+    void getISurfaceOUV(const dd4hep::rec::ISurface* iSurface,TVector3& o,
+            TVector3& u,TVector3& v,double& lengthU,double& lengthV);
+    void getMeasurementAndCov(edm4hep::TrackerHit* hit,TVector3& pos,TMatrixDSym& cov);
+    int getSigmas(int cellID,std::vector<float> sigmaUVec,
+        std::vector<float> sigmaVVec,float& sigmaU,float& sigmaV)const;
+    bool isCDCHit(edm4hep::TrackerHit* hit);
+    GenfitHit* makeAGenfitHit(edm4hep::TrackerHit* trackerHit,
+            edm4hep::SimTrackerHit* simTrackerHitAsso,
+            double sigma,bool truthAmbig,double skipCorner,double skipNear);
+    void getSortedTrackerHits(std::vector<edm4hep::TrackerHit*>& hits,
+            const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
+            std::vector<edm4hep::TrackerHit*>& sortedDCTrackerHits,
+            int sortMethod);
 
     genfit::Track* m_track;/// track
-    std::vector<genfit::AbsTrackRep*> m_reps;/// track repesentations
     int m_debug;/// debug level
+    int m_debugLocal;/// debug level local
 
+    SmartIF<IGeomSvc> m_geomSvc;
     const GenfitField* m_genfitField;//pointer to genfit field
     const dd4hep::DDSegmentation::GridDriftChamber* m_gridDriftChamber;
+    const dd4hep::DDSegmentation::BitFieldCoder* m_decoderDC;
 
     static const int s_PDG[2][5];
 
-};
+    std::vector<GenfitHit*> m_genfitHitVec;
 
+};
 #endif
diff --git a/Reconstruction/Tracking/include/Tracking/TrackingHelper.h b/Reconstruction/Tracking/include/Tracking/TrackingHelper.h
index beed38e62..c12f55174 100644
--- a/Reconstruction/Tracking/include/Tracking/TrackingHelper.h
+++ b/Reconstruction/Tracking/include/Tracking/TrackingHelper.h
@@ -62,5 +62,4 @@ inline int getLayer(const edm4hep::TrackerHit hit) {
     return layer;
 }
 
-
 #endif
diff --git a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp
index 29e714e3b..c87ebc39a 100644
--- a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp
+++ b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp
@@ -7,6 +7,7 @@
 #include "DD4hep/IDDescriptor.h"
 #include "DD4hep/Plugins.h"
 #include "DD4hep/DD4hepUnits.h"
+#include "UTIL/ILDConf.h"
 
 //external
 #include "CLHEP/Random/RandGauss.h"
@@ -25,37 +26,71 @@ TruthTrackerAlg::TruthTrackerAlg(const std::string& name, ISvcLocator* svcLoc)
 : GaudiAlgorithm(name, svcLoc),m_dd4hep(nullptr),m_gridDriftChamber(nullptr),
     m_decoder(nullptr)
 {
+    declareProperty("NoiseSimHitsCollection", w_SimNoiseHCol,
+            "Handle of the output simulation  DC Noise hits collection");
+    declareProperty("NoiseDCHitsCollection", w_NoiseHitCol,
+            "Handle of the input DC Noise hits collection");
+    declareProperty("NoiseDCHitAssociationCollection", w_NoiseAssociationCol,
+            "Handle of the simNoiseDCHit and noiseDC Noise hits collection");
     declareProperty("MCParticle", m_mcParticleCol,
             "Handle of the input MCParticle collection");
+    declareProperty("DriftChamberHitsCollection", m_DCSimTrackerHitCol,
+            "Handle of DC SimTrackerHit collection");
     declareProperty("DigiDCHitCollection", m_DCDigiCol,
             "Handle of DC digi(TrackerHit) collection");
     declareProperty("DCHitAssociationCollection", m_DCHitAssociationCol,
             "Handle of association collection");
     declareProperty("DCTrackCollection", m_DCTrackCol,
             "Handle of DC track collection");
-    declareProperty("SiSubsetTrackCollection", m_siSubsetTrackCol,
+    declareProperty("SubsetTracks", m_siSubsetTrackCol,
             "Handle of silicon subset track collection");
     declareProperty("SDTTrackCollection", m_SDTTrackCol,
             "Handle of SDT track collection");
-    declareProperty("DCRecParticleCollection", m_DCRecParticleCol,
-            "Handle of drift chamber reconstructed particle collection");
-    declareProperty("DCRecParticleAssociationCollection",
-            m_DCRecParticleAssociationCol,
-            "Handle of drift chamber reconstructed particle collection");
+    declareProperty("VXDTrackerHits", m_VXDTrackerHits,
+            "Handle of input VXD tracker hit collection");
+    declareProperty("SITTrackerHits", m_SITTrackerHits,
+            "Handle of input SIT tracker hit collection");
+    declareProperty("SETTrackerHits", m_SETTrackerHits,
+            "Handle of input SET tracker hit collection");
+    declareProperty("FTDTrackerHits", m_FTDTrackerHits,
+            "Handle of input FTD tracker hit collection");
+    declareProperty("SITSpacePoints", m_SITSpacePointCol,
+            "Handle of input SIT hit collection");
+//    declareProperty("SETSpacePoints", m_SETSpacePointCol,
+//            "Handle of input SET hit collection");
+    declareProperty("FTDSpacePoints", m_FTDSpacePointCol,
+            "Handle of input FTD hit collection");
+    declareProperty("VXDCollection", m_VXDCollection,
+            "Handle of input VXD hit collection");
+    declareProperty("SITCollection", m_SITCollection,
+            "Handle of input SIT hit collection");
+    declareProperty("SETCollection", m_SETCollection,
+            "Handle of input SET hit collection");
+    declareProperty("FTDCollection", m_FTDCollection,
+            "Handle of input FTD hit collection");
+    declareProperty("TruthTrackerHitCollection", m_truthTrackerHitCol,
+            "Handle of output truth TrackerHit collection");
+    declareProperty("SmearTrackerHitCollection", m_SmeartruthTrackerHitCol,
+            "Handle of output smear truth TrackerHit collection");
+    declareProperty("SmearSimHitsCollection", w_SimSmearHCol,
+            "Handle of output smear SimTrackerHit collection");
+    declareProperty("SmearDCHitAssociationCollection", w_SmearAssociationCol,
+            "Handle of output smear simulationhit and TrackerHit collection");
 }
 
+
 StatusCode TruthTrackerAlg::initialize()
 {
     ///Get geometry
     m_geomSvc=service<IGeomSvc>("GeomSvc");
     if (!m_geomSvc) {
-        error() << "Failed to get GeomSvc." << endmsg;
+        error()<<"Failed to get GeomSvc."<<endmsg;
         return StatusCode::FAILURE;
     }
     ///Get Detector
     m_dd4hep=m_geomSvc->lcdd();
     if (nullptr==m_dd4hep) {
-        error() << "Failed to get dd4hep::Detector." << endmsg;
+        error()<<"Failed to get dd4hep::Detector."<<endmsg;
         return StatusCode::FAILURE;
     }
     //Get Field
@@ -66,44 +101,125 @@ StatusCode TruthTrackerAlg::initialize()
     m_gridDriftChamber=dynamic_cast<dd4hep::DDSegmentation::GridDriftChamber*>
         (readout.segmentation().segmentation());
     if(nullptr==m_gridDriftChamber){
-        error() << "Failed to get the GridDriftChamber" << endmsg;
+        error()<<"Failed to get the GridDriftChamber"<<endmsg;
         return StatusCode::FAILURE;
     }
     ///Get Decoder
     m_decoder = m_geomSvc->getDecoder(m_readout_name);
     if (nullptr==m_decoder) {
-        error() << "Failed to get the decoder" << endmsg;
+        error()<<"Failed to get the decoder"<<endmsg;
         return StatusCode::FAILURE;
     }
 
+    m_tuple=nullptr;
+    ///book tuple
+    if(m_hist){
+        NTuplePtr nt(ntupleSvc(), "TruthTrackerAlg/truthTrackerAlg");
+        if(nt){
+            m_tuple=nt;
+        }else{
+            m_tuple=ntupleSvc()->book("TruthTrackerAlg/truthTrackerAlg",
+                    CLID_ColumnWiseTuple,"TruthTrackerAlg");
+            if(m_tuple){
+                StatusCode sc;
+                sc=m_tuple->addItem("run",m_run);
+                sc=m_tuple->addItem("evt",m_evt);
+                sc=m_tuple->addItem("siMom",3,m_siMom);
+                sc=m_tuple->addItem("siPos",3,m_siPos);
+                sc=m_tuple->addItem("mcMom",3,m_mcMom);
+
+                sc=m_tuple->addItem("mcPos",3,m_mcPos);
+                sc=m_tuple->addItem("nDCTrackHit",m_nDCTrackHit,0,100000);
+                sc=m_tuple->addItem("DriftDistance",m_nDCTrackHit,m_DriftDistance);
+                sc=m_tuple->addItem("nSmearDCTrackHit",m_nSmearDCTrackHit,0,100000);
+                sc=m_tuple->addItem("SmearDriftDistance",m_nSmearDCTrackHit,m_SmearDriftDistance);
+                sc=m_tuple->addItem("nNoiseDCTrackHit",m_nNoiseDCTrackHit,0,100000);
+                sc=m_tuple->addItem("NoiseDriftDistance",m_nNoiseDCTrackHit,m_NoiseDriftDistance);
+
+                sc=m_tuple->addItem("nSimTrackerHitVXD",m_nSimTrackerHitVXD);
+                sc=m_tuple->addItem("nSimTrackerHitSIT",m_nSimTrackerHitSIT);
+                sc=m_tuple->addItem("nSimTrackerHitSET",m_nSimTrackerHitSET);
+                sc=m_tuple->addItem("nSimTrackerHitFTD",m_nSimTrackerHitFTD);
+                sc=m_tuple->addItem("nSimTrackerHitDC",m_nSimTrackerHitDC);
+                sc=m_tuple->addItem("nTrackerHitVXD",m_nTrackerHitVXD);
+                sc=m_tuple->addItem("nTrackerHitSIT",m_nTrackerHitSIT);
+                sc=m_tuple->addItem("nTrackerHitSET",m_nTrackerHitSET);
+                sc=m_tuple->addItem("nTrackerHitFTD",m_nTrackerHitFTD);
+                sc=m_tuple->addItem("nTrackerHitDC",m_nTrackerHitDC);
+                sc=m_tuple->addItem("nSpacePointSIT",m_nSpacePointSIT);
+                sc=m_tuple->addItem("nSpacePointSET",m_nSpacePointSET);
+                sc=m_tuple->addItem("nSpacePointFTD",m_nSpacePointFTD);
+                sc=m_tuple->addItem("nHitOnSiTkXVD",m_nHitOnSiTkVXD);
+                sc=m_tuple->addItem("nHitOnSiTkSIT",m_nHitOnSiTkSIT);
+                sc=m_tuple->addItem("nHitOnSiTkSET",m_nHitOnSiTkSET);
+                sc=m_tuple->addItem("nHitOnSiTkFTD",m_nHitOnSiTkFTD);
+                sc=m_tuple->addItem("nHitOnSdtTkVXD",m_nHitOnSdtTkVXD);
+                sc=m_tuple->addItem("nHitOnSdtTkSIT",m_nHitOnSdtTkSIT);
+                sc=m_tuple->addItem("nHitOnSdtTkSET",m_nHitOnSdtTkSET);
+                sc=m_tuple->addItem("nHitOnSdtTkFTD",m_nHitOnSdtTkFTD);
+                sc=m_tuple->addItem("nHitOnSdtTkDC",m_nHitOnSdtTkDC);
+                sc=m_tuple->addItem("nHitSdt",m_nHitOnSdtTk);
+                sc=m_tuple->addItem("nNoiseOnSdt",m_nNoiseOnSdtTk);
+            }
+        }
+    }
     return GaudiAlgorithm::initialize();
 }
 
 StatusCode TruthTrackerAlg::execute()
 {
+    info()<<"In execute()"<<endmsg;
+
+    ///Output DC Track collection
+    edm4hep::TrackCollection* dcTrackCol=m_DCTrackCol.createAndPut();
+
+    ///Output SDT Track collection
+    edm4hep::TrackCollection* sdtTkCol=m_SDTTrackCol.createAndPut();
+
+    ///Output Hit collection
+    auto truthTrackerHitCol=m_truthTrackerHitCol.createAndPut();
+
     ///Retrieve MC particle(s)
     const edm4hep::MCParticleCollection* mcParticleCol=nullptr;
     mcParticleCol=m_mcParticleCol.get();
+    //if(m_mcParticleCol.exist()){mcParticleCol=m_mcParticleCol.get();}
     if(nullptr==mcParticleCol){
         debug()<<"MCParticleCollection not found"<<endmsg;
         return StatusCode::SUCCESS;
     }
     ///Retrieve DC digi
     const edm4hep::TrackerHitCollection* digiDCHitsCol=nullptr;
-    digiDCHitsCol=m_DCDigiCol.get();//FIXME DEBUG
-    if(nullptr==digiDCHitsCol){
-        debug()<<"TrackerHitCollection not found"<<endmsg;
-        //return StatusCode::SUCCESS;//FIXME return when no hits in DC + silicon
+    const edm4hep::SimTrackerHitCollection* dcSimHitCol
+        =m_DCSimTrackerHitCol.get();
+    const edm4hep::MCRecoTrackerAssociationCollection* assoHits
+        = m_DCHitAssociationCol.get();
+    if(m_useDC){
+        if(nullptr==dcSimHitCol){
+            debug()<<"DC SimTrackerHitCollection not found"<<endmsg;
+        }else{
+            debug()<<"DriftChamberHitsCollection size "
+                <<dcSimHitCol->size()<<endmsg;
+            if(m_tuple)m_nSimTrackerHitDC=dcSimHitCol->size();
+        }
+        digiDCHitsCol=m_DCDigiCol.get();
+        m_nDCTrackHit = digiDCHitsCol->size();
+        if(nullptr==digiDCHitsCol){
+            debug()<<"TrackerHitCollection not found"<<endmsg;
+        }else{
+            debug()<<"digiDCHitsCol size "<<digiDCHitsCol->size()<<endmsg;
+            if((int) digiDCHitsCol->size()>m_maxDCDigiCut){
+                debug()<<"Track cut by m_maxDCDigiCut "<<m_maxDCDigiCut<<endmsg;
+                return StatusCode::SUCCESS;
+            }
+        }
     }
-    if((int) digiDCHitsCol->size()>m_maxDCDigiCut) return StatusCode::SUCCESS;
 
-    ///Output Track collection
-    edm4hep::TrackCollection* dcTrackCol=m_DCTrackCol.createAndPut();
-    edm4hep::TrackCollection* sdtTrackCol=m_SDTTrackCol.createAndPut();
-    edm4hep::ReconstructedParticleCollection* dcRecParticleCol(nullptr);
-    if(m_writeRecParticle){
-        dcRecParticleCol=m_DCRecParticleCol.createAndPut();
-    }
+    // make noise
+    edm4hep::SimTrackerHitCollection* SimVec = w_SimNoiseHCol.createAndPut();
+    edm4hep::MCRecoTrackerAssociationCollection* AssoVec = 
+        w_NoiseAssociationCol.createAndPut();
+    edm4hep::TrackerHitCollection* Vec = w_NoiseHitCol.createAndPut();
+
     ////TODO
     //Output MCRecoTrackerAssociationCollection collection
     //const edm4hep::MCRecoTrackerAssociationCollection*
@@ -115,50 +231,184 @@ StatusCode TruthTrackerAlg::execute()
     //}
     //mcRecoTrackerAssociationCol=m_mcRecoParticleAssociation.get();
 
-    ///Retrieve silicon Track
-    const edm4hep::TrackCollection* siTrackCol=nullptr;
-    if(m_siSubsetTrackCol.exist()) siTrackCol=m_siSubsetTrackCol.get();
-    if(nullptr!=siTrackCol) {
-        ///New SDT track
-        for(auto siTrack:*siTrackCol){
-            auto sdtTrack=sdtTrackCol->create();
-            edm4hep::TrackState sdtTrackState;
-            edm4hep::TrackState siTrackStat=siTrack.getTrackStates(0);//FIXME?
-            sdtTrackState.location=siTrackStat.location;
-            sdtTrackState.D0=siTrackStat.D0;
-            sdtTrackState.phi=siTrackStat.phi;
-            sdtTrackState.omega=siTrackStat.omega;
-            sdtTrackState.Z0=siTrackStat.Z0;
-            sdtTrackState.tanLambda=siTrackStat.tanLambda;
-            sdtTrackState.referencePoint=siTrackStat.referencePoint;
-            for(int k=0;k<15;k++){
-                sdtTrackState.covMatrix[k]=siTrackStat.covMatrix[k];
-            }
-            sdtTrack.addToTrackStates(sdtTrackState);
-            sdtTrack.setType(siTrack.getType());
-            sdtTrack.setChi2(siTrack.getChi2());
-            sdtTrack.setNdf(siTrack.getNdf());
-            sdtTrack.setDEdx(siTrack.getDEdx());
-            sdtTrack.setDEdxError(siTrack.getDEdxError());
-            sdtTrack.setRadiusOfInnermostHit(siTrack.getRadiusOfInnermostHit());
-            debug()<<"siTrack trackerHits_size="<<siTrack.trackerHits_size()<<endmsg;
-            for(unsigned int iSiTackerHit=0;iSiTackerHit<siTrack.trackerHits_size();
-                    iSiTackerHit++){
-                sdtTrack.addToTrackerHits(siTrack.getTrackerHits(iSiTackerHit));
+    ///New SDT track
+    edm4hep::MutableTrack sdtTk=sdtTkCol->create();
+
+    int nVXDHit=0;
+    int nSITHit=0;
+    int nSETHit=0;
+    int nFTDHit=0;
+    int nDCHitDCTk=0;
+    int nDCHitSDTTk=0;
+
+    ///Create track with mcParticle
+    edm4hep::TrackState trackStateMc;
+    getTrackStateFromMcParticle(mcParticleCol,trackStateMc);
+    if(m_useTruthTrack.value()||!m_useSi){sdtTk.addToTrackStates(trackStateMc);}
+
+    if(m_useSi){
+        ///Retrieve silicon Track
+        const edm4hep::TrackCollection* siTrackCol=nullptr;
+        //if(m_siSubsetTrackCol.exist()){
+        siTrackCol=m_siSubsetTrackCol.get();
+        if(nullptr==siTrackCol){
+            debug()<<"SDTTrackCollection is empty"<<endmsg;
+            if(!m_useTruthTrack.value()) return StatusCode::SUCCESS;
+        }else{
+            debug()<<"SiSubsetTrackCol size "<<siTrackCol->size()<<endmsg;
+            if(!m_useTruthTrack.value()&&0==siTrackCol->size()){
+                return StatusCode::SUCCESS;
             }
-            //TODO tracks
-            for(auto digiDC:*digiDCHitsCol){
-                //if(Sim->MCParti!=current) continue;//TODO
-                sdtTrack.addToTrackerHits(digiDC);
+        }
+        //}
+
+        for(auto siTk:*siTrackCol){
+            if(!m_useTruthTrack.value()){
+                debug()<<"siTk: "<<siTk<<endmsg;
+                edm4hep::TrackState siTrackStat=siTk.getTrackStates(0);//FIXME?
+                sdtTk.addToTrackStates(siTrackStat);
+                sdtTk.setType(siTk.getType());
+                sdtTk.setChi2(siTk.getChi2());
+                sdtTk.setNdf(siTk.getNdf());
+                sdtTk.setDEdx(siTk.getDEdx());
+                sdtTk.setDEdxError(siTk.getDEdxError());
+                sdtTk.setRadiusOfInnermostHit(
+                        siTk.getRadiusOfInnermostHit());
             }
+            if(!m_useSiTruthHit){
+                debug()<<"use Si hit on track"<<endmsg;
+                nVXDHit=addHotsToTk(siTk,sdtTk,lcio::ILDDetID::VXD,"VXD",nVXDHit);
+                nSITHit=addHotsToTk(siTk,sdtTk,lcio::ILDDetID::SIT,"SIT",nSITHit);
+                nSETHit=addHotsToTk(siTk,sdtTk,lcio::ILDDetID::SET,"SET",nSETHit);
+                nFTDHit=addHotsToTk(siTk,sdtTk,lcio::ILDDetID::FTD,"FTD",nFTDHit);
+            }//end of loop over hits on siTk
+        }//end of loop over siTk
+
+        if(m_useSiTruthHit){
+            ///Add silicon SimTrackerHit
+            debug()<<"Add silicon SimTrackerHit"<<endmsg;
+            nVXDHit=addSimHitsToTk(m_VXDCollection,truthTrackerHitCol,sdtTk,"VXD",nVXDHit);
+            nSITHit=addSimHitsToTk(m_SITCollection,truthTrackerHitCol,sdtTk,"SIT",nSITHit);
+            nSETHit=addSimHitsToTk(m_SETCollection,truthTrackerHitCol,sdtTk,"SET",nSETHit);
+            nFTDHit=addSimHitsToTk(m_FTDCollection,truthTrackerHitCol,sdtTk,"FTD",nFTDHit);
+        }else{
+            ///Add reconstructed hit or digi
+            debug()<<"Add VXD TrackerHit"<<endmsg;
+            nVXDHit=addHitsToTk(m_VXDTrackerHits,sdtTk,"VXD digi",nVXDHit);
+            nSITHit=addHitsToTk(m_SITTrackerHits,sdtTk,"SIT digi",nSITHit);
+            if(m_useSiSpacePoint.value()){
+                ///Add silicon SpacePoint
+                debug()<<"Add silicon SpacePoint"<<endmsg;
+                if(m_useSiSpacePoint){
+                    nSITHit=addHitsToTk(m_SITSpacePointCol,sdtTk,"SIT sp",nSITHit);
+                }
+               // nSETHit=addHitsToTk(m_SETSpacePointCol,sdtTk,"SET sp",nSETHit);
+                nFTDHit=addHitsToTk(m_FTDSpacePointCol,sdtTk,"FTD sp",nFTDHit);
+            }else{
+                ///Add silicon TrackerHit
+                debug()<<"Add silicon TrackerHit"<<endmsg;
+                nSITHit=addHitsToTk(m_SITTrackerHits,sdtTk,"SIT digi",nSITHit);
+                nSETHit=addHitsToTk(m_SETTrackerHits,sdtTk,"SET digi",nSETHit);
+                nFTDHit=addHitsToTk(m_FTDTrackerHits,sdtTk,"FTD digi",nFTDHit);
+            }//end of use space point
+        }
+    }//end of use silicon
+
+    if(m_useDC){
+        ///Create DC Track
+        edm4hep::MutableTrack dcTrack=dcTrackCol->create();
+
+        //Create TrackState
+        edm4hep::TrackState trackStateFirstDCHit;
+        float charge=trackStateMc.omega/fabs(trackStateMc.omega);
+        if(m_useFirstHitForDC&&getTrackStateFirstHit(m_DCSimTrackerHitCol,
+                    charge,trackStateFirstDCHit)){
+            dcTrack.addToTrackStates(trackStateFirstDCHit);
+            dcTrack.addToTrackStates(trackStateMc);
+        }else{
+            dcTrack.addToTrackStates(trackStateMc);
+            dcTrack.addToTrackStates(trackStateFirstDCHit);
+        }
+        //sdtTk.addToTrackStates(trackStateFirstDCHit);
+
+        ///Add other track properties
+        dcTrack.setNdf(dcTrack.trackerHits_size()-5);
+
+        ///Add DC hits to tracks after track state set
+        if(m_useIdealHit){
+            nDCHitDCTk=addIdealHitsToTk(m_DCDigiCol,truthTrackerHitCol,dcTrack,
+                    "DC digi",nDCHitDCTk);
+        }else{
+            nDCHitDCTk=addHitsToTk(m_DCDigiCol,dcTrack,"DC digi",nDCHitDCTk);
+        }
+//        if(m_useSi) nDCHitSDTTk=addHitsToTk(m_DCDigiCol,sdtTk,"DC digi",nDCHitSDTTk);
+       // if(m_useSi)
+       // {
+        if(m_smearHits){
+            m_nSmearDCTrackHit = smearDCTkhit(m_DCDigiCol,
+                    m_SmeartruthTrackerHitCol,m_DCSimTrackerHitCol,
+                    w_SimSmearHCol,m_DCHitAssociationCol,
+                    w_SmearAssociationCol,m_resX,m_resY,m_resZ);
         }
+
+        if(!m_useNoiseHits)
+        {
+            //nDCHitSDTTk=addHitsToTk(m_DCDigiCol,sdtTk,"DC digi",nDCHitSDTTk);
+            nDCHitSDTTk=addHitsToTk(m_SmeartruthTrackerHitCol,sdtTk,"DC digi",nDCHitSDTTk);
+        } else {
+            m_nNoiseOnSdtTk = makeNoiseHit(SimVec,Vec,AssoVec,
+                    m_SmeartruthTrackerHitCol.get(),w_SmearAssociationCol.get());
+            if(debugNoiseHitsCol(Vec))std::cout << " Make noise hits successfully!" << std::endl;
+            nDCHitSDTTk=addHitsToTk(w_NoiseHitCol,sdtTk,
+                    "DC digi",nDCHitSDTTk);
+        } 
+        //}
+
+        //track.setType();//TODO
+        //track.setChi2(gauss(digiDCHitsCol->size-5(),1));//FIXME
+        //track.setDEdx();//TODO
+
+        debug()<<"dcTrack nHit "<<dcTrack.trackerHits_size()<<dcTrack<<endmsg;
+    }
+
+    ///Set other track parameters
+    //sdtTk.setNdf(sdtTk.trackerHits_size()-5);
+    //double radiusOfInnermostHit=1e9;
+    //edm4hep::Vector3d digiPos=digiDC.getPosition();
+    //double r=sqrt(digiPos.x*digiPos.x+digiPos.y*digiPos.y);
+    //if(r<radiusOfInnermostHit) radiusOfInnermostHit=r;
+
+    debug()<<"sdtTk nHit "<<sdtTk.trackerHits_size()<<sdtTk<<endmsg;
+    debug()<<"nVXDHit "<<nVXDHit<<" nSITHit "<<nSITHit<<" nSETHit "<<nSETHit
+        <<" nFTDHit "<<nFTDHit<<" nDCHitSDTTk "<<nDCHitSDTTk<<endmsg;
+
+    if(m_tuple){
+        m_nHitOnSdtTkVXD=nVXDHit;
+        m_nHitOnSdtTkSIT=nSITHit;
+        m_nHitOnSdtTkSET=nSETHit;
+        m_nHitOnSdtTkFTD=nFTDHit;
+        m_nHitOnSdtTkDC=nDCHitSDTTk;
+        //m_nHitOnSdtTk=sdtTk.trackerHits_size();
+        debugEvent();
+        StatusCode sc=m_tuple->write();
     }
 
-    ///Convert MCParticle to Track and ReconstructedParticle
+    return StatusCode::SUCCESS;
+}
+
+StatusCode TruthTrackerAlg::finalize()
+{
+    return GaudiAlgorithm::finalize();
+}
+
+void TruthTrackerAlg::getTrackStateFromMcParticle(
+        const edm4hep::MCParticleCollection* mcParticleCol,
+        edm4hep::TrackState& trackState)
+{
+    ///Convert MCParticle to DC Track and ReconstructedParticle
     debug()<<"MCParticleCol size="<<mcParticleCol->size()<<endmsg;
     for(auto mcParticle : *mcParticleCol){
         /// skip mcParticleVertex do not have enough associated hits TODO
-
         ///Vertex
         const edm4hep::Vector3d mcParticleVertex=mcParticle.getVertex();//mm
         edm4hep::Vector3f mcParticleVertexSmeared;//mm
@@ -169,7 +419,7 @@ StatusCode TruthTrackerAlg::execute()
         mcParticleVertexSmeared.z=
             CLHEP::RandGauss::shoot(mcParticleVertex.z,m_resVertexZ);
         ///Momentum
-        edm4hep::Vector3f mcParticleMom=mcParticle.getMomentum();//GeV
+        const edm4hep::Vector3f mcParticleMom=mcParticle.getMomentum();//GeV
         double mcParticlePt=sqrt(mcParticleMom.x*mcParticleMom.x+
                 mcParticleMom.y*mcParticleMom.y);
         //double mcParticlePtSmeared=
@@ -180,8 +430,7 @@ StatusCode TruthTrackerAlg::execute()
         edm4hep::Vector3f mcParticleMomSmeared;
         mcParticleMomSmeared.x=mcParticlePt*cos(mcParticleMomPhiSmeared);
         mcParticleMomSmeared.y=mcParticlePt*sin(mcParticleMomPhiSmeared);
-        mcParticleMomSmeared.z=
-            CLHEP::RandGauss::shoot(mcParticleMom.z,m_resPz);
+        mcParticleMomSmeared.z=CLHEP::RandGauss::shoot(mcParticleMom.z,m_resPz);
 
         ///Converted to Helix
         double B[3]={1e9,1e9,1e9};
@@ -192,15 +441,17 @@ StatusCode TruthTrackerAlg::execute()
         //float mom[3]={mcParticleMomSmeared.x,mcParticleMomSmeared.y,
         //    mcParticleMomSmeared.z};
         ////FIXME DEBUG
-        float pos[3]={(float)mcParticleVertex.x,
-            (float)mcParticleVertex.y,(float)mcParticleVertex.z};
-        float mom[3]={(float)mcParticleMom.x,(float)mcParticleMom.y,
-            (float)mcParticleMom.z};
+        double pos[3]={mcParticleVertex.x,mcParticleVertex.y,mcParticleVertex.z};//mm
+        double mom[3]={mcParticleMom.x,mcParticleMom.y,mcParticleMom.z};//mm
         helix.Initialize_VP(pos,mom,mcParticle.getCharge(),B[2]/dd4hep::tesla);
+        if(m_tuple) {
+            for(int ii=0;ii<3;ii++) {
+                m_mcMom[ii]=mom[ii];//GeV
+                m_mcPos[ii]=pos[ii];//mm
+            }
+        }
 
         ///new Track
-        auto dcTrack=dcTrackCol->create();
-        edm4hep::TrackState trackState;
         trackState.D0=helix.getD0();
         trackState.phi=helix.getPhi0();
         trackState.omega=helix.getOmega();
@@ -208,49 +459,19 @@ StatusCode TruthTrackerAlg::execute()
         trackState.tanLambda=helix.getTanLambda();
         trackState.referencePoint=helix.getReferencePoint();
         std::array<float,15> covMatrix;
-        for(int i=0;i<15;i++){covMatrix[i]=999.;}//FIXME
+        for(int i=0;i<15;i++){covMatrix[i]=1.;}//FIXME
         trackState.covMatrix=covMatrix;
-        dcTrack.addToTrackStates(trackState);
-        //dcTrack.setType();//TODO
-        //dcTrack.setChi2(gauss(digiDCHitsCol->size-5(),1));//FIXME
-        dcTrack.setNdf(digiDCHitsCol->size()-5);
-        //dcTrack.setDEdx();//TODO
-        //set hits
-        double radiusOfInnermostHit=1e9;
-        debug()<<"digiDCHitsCol size"<<digiDCHitsCol->size()<<endmsg;
-        for(auto digiDC : *digiDCHitsCol){
-            //if(Sim->MCParti!=current) continue;//TODO
-            edm4hep::Vector3d digiPos=digiDC.getPosition();
-            double r=sqrt(digiPos.x*digiPos.x+digiPos.y*digiPos.y);
-            if(r<radiusOfInnermostHit) radiusOfInnermostHit=r;
-            dcTrack.addToTrackerHits(digiDC);
-        }
-        dcTrack.setRadiusOfInnermostHit(radiusOfInnermostHit);//TODO
-
-        edm4hep::MutableReconstructedParticle dcRecParticle;
-        if(m_writeRecParticle){
-            dcRecParticle=dcRecParticleCol->create();
-            ///new ReconstructedParticle
-            //dcRecParticle.setType();//TODO
-            double mass=mcParticle.getMass();
-            double p=sqrt(mcParticleMomSmeared.x*mcParticleMomSmeared.x+
-                    mcParticleMomSmeared.y*mcParticleMomSmeared.y+
-                    mcParticleMomSmeared.z*mcParticleMomSmeared.z);
-            dcRecParticle.setEnergy(sqrt(mass*mass+p*p));
-            dcRecParticle.setMomentum(mcParticleMomSmeared);
-            dcRecParticle.setReferencePoint(mcParticleVertexSmeared);
-            dcRecParticle.setCharge(mcParticle.getCharge());
-            dcRecParticle.setMass(mass);
-            //dcRecParticle.setGoodnessOfPID();//TODO
-            //std::array<float>,10> covMat=?;//TODO
-            //dcRecParticle.setCovMatrix(covMat);//TODO
-            //dcRecParticle.setStartVertex();//TODO
-            edm4hep::ParticleID particleID(0,mcParticle.getPDG(),0,1);//FIXME
-            dcRecParticle.setParticleIDUsed(particleID);
-            dcRecParticle.addToTracks(dcTrack);
-        }//end of write RecParticle
 
+        getCircleFromPosMom(pos,mom,B[2]/dd4hep::tesla,mcParticle.getCharge(),m_helixRadius,m_helixXC,m_helixYC);
+
+        debug()<<"dd4hep::mm "<<dd4hep::mm<<" dd4hep::cm "<<dd4hep::cm<<endmsg;
         debug()<<"mcParticle "<<mcParticle
+            <<" helix radius "<<helix.getRadius()<<" "<<helix.getXC()<<" "
+            <<helix.getYC()<<" mm "
+            <<" myhelix radius "<<m_helixRadius<<" "<<m_helixXC<<" "
+            <<m_helixYC<<" mm "
+            <<" momMC "<<mom[0]<<" "<<mom[1]<<" "<<mom[2]<<"GeV"
+            <<" posMC "<<pos[0]<<" "<<pos[1]<<" "<<pos[2]<<"mm"
             <<" momPhi "<<mcParticleMomPhi
             <<" mcParticleVertex("<<mcParticleVertex<<")mm "
             <<" mcParticleVertexSmeared("<<mcParticleVertexSmeared<<")mm "
@@ -258,17 +479,443 @@ StatusCode TruthTrackerAlg::execute()
             <<" mcParticleMomSmeared("<<mcParticleMomSmeared<<")GeV "
             <<" Bxyz "<<B[0]/dd4hep::tesla<<" "<<B[1]/dd4hep::tesla
             <<" "<<B[2]/dd4hep::tesla<<" tesla"<<endmsg;
-        debug()<<"trackState:location,D0,phi,omega,Z0,tanLambda"
-            <<",referencePoint,cov"<<std::endl<<trackState<<std::endl;
-        debug()<<"dcTrack"<<dcTrack<<endmsg;
-        if(m_writeRecParticle) debug()<<"dcRecParticle"<<dcRecParticle<<endmsg;
     }//end loop over MCParticleCol
+}//end of getTrackStateFromMcParticle
 
-    debug()<<"Output DCTrack size="<<dcTrackCol->size()<<endmsg;
-    return StatusCode::SUCCESS;
+bool TruthTrackerAlg::getTrackStateFirstHit(
+        DataHandle<edm4hep::SimTrackerHitCollection>& dcSimTrackerHitCol,
+        float charge,edm4hep::TrackState& trackState)
+{
+
+    const edm4hep::SimTrackerHitCollection* col=nullptr;
+    col=dcSimTrackerHitCol.get();
+    debug()<<"TruthTrackerAlg::getTrackStateFirstHit"<<endmsg;
+    debug()<<"simTrackerHitCol size "<<col->size()<<endmsg;
+    float minHitTime=1e9;
+    if(nullptr!=col||0==col->size()){
+        edm4hep::SimTrackerHit firstHit;
+        for(auto dcSimTrackerHit:*col){
+            const edm4hep::Vector3f mom=dcSimTrackerHit.getMomentum();
+            if(abs(sqrt(mom[0]*mom[0]+mom[1]*mom[1]))<m_momentumCut)continue;//yzhang TEMP skip hits with momentum <0.5GeV/c
+            if(dcSimTrackerHit.getTime()<minHitTime) {
+                minHitTime=dcSimTrackerHit.getTime();
+                firstHit=dcSimTrackerHit;
+            }
+            //debug()<<"simTrackerHit time "<<dcSimTrackerHit.getTime()
+            //    <<" pos "<<dcSimTrackerHit.getPosition()
+            //    <<" mom "<<dcSimTrackerHit.getMomentum()<<endmsg;
+        }
+        const edm4hep::Vector3d pos=firstHit.getPosition();
+        const edm4hep::Vector3f mom=firstHit.getMomentum();
+        debug()<<"first Hit pos "<<pos<<" mom "<<mom<<" time "<<minHitTime<<endmsg;
+        float pos_t[3]={(float)pos[0],(float)pos[1],(float)pos[2]};
+        float mom_t[3]={(float)mom[0],(float)mom[1],(float)mom[2]};
+        ///Converted to Helix
+        double B[3]={1e9,1e9,1e9};
+        m_dd4hepField.magneticField({0.,0.,0.},B);
+        HelixClass helix;
+        helix.Initialize_VP(pos_t,mom_t,charge,B[2]/dd4hep::tesla);
+        m_helixRadiusFirst=helix.getRadius();
+        m_helixXCFirst=helix.getXC();
+        m_helixYCFirst=helix.getYC();
+
+        ///new Track
+        trackState.D0=helix.getD0();
+        trackState.phi=helix.getPhi0();
+        trackState.omega=helix.getOmega();
+        trackState.Z0=helix.getZ0();
+        trackState.tanLambda=helix.getTanLambda();
+        trackState.referencePoint=helix.getReferencePoint();
+        std::array<float,15> covMatrix;
+        for(int i=0;i<15;i++){covMatrix[i]=100.;}//FIXME
+        trackState.covMatrix=covMatrix;
+        debug()<<"first hit trackState "<<trackState<<endmsg;
+        return true;
+    }
+    return false;
+}//end of getTrackStateFirstHit
+
+void TruthTrackerAlg::debugEvent()
+{
+    if(m_useSi){
+        ///Retrieve silicon Track
+        const edm4hep::TrackCollection* siTrackCol=nullptr;
+        siTrackCol=m_siSubsetTrackCol.get();
+        if(nullptr!=siTrackCol){
+            for(auto siTk:*siTrackCol){
+                debug()<<"siTk: "<<siTk<<endmsg;
+                edm4hep::TrackState trackStat=siTk.getTrackStates(0);//FIXME?
+                double B[3]={1e9,1e9,1e9};
+                m_dd4hepField.magneticField({0.,0.,0.},B);
+                HelixClass helix;
+                helix.Initialize_Canonical(trackStat.phi, trackStat.D0, trackStat.Z0,
+                        trackStat.omega, trackStat.tanLambda, B[2]/dd4hep::tesla);
+
+                if(m_tuple){
+                    m_siMom[0]=helix.getMomentum()[0];
+                    m_siMom[1]=helix.getMomentum()[1];
+                    m_siMom[2]=helix.getMomentum()[2];
+                    m_siPos[0]=helix.getReferencePoint()[0];
+                    m_siPos[1]=helix.getReferencePoint()[1];
+                    m_siPos[2]=helix.getReferencePoint()[2];
+                    m_nHitOnSiTkVXD=nHotsOnTrack(siTk,lcio::ILDDetID::VXD);
+                    m_nHitOnSiTkSIT=nHotsOnTrack(siTk,lcio::ILDDetID::SIT);
+                    m_nHitOnSiTkSET=nHotsOnTrack(siTk,lcio::ILDDetID::SET);
+                    m_nHitOnSiTkFTD=nHotsOnTrack(siTk,lcio::ILDDetID::FTD);
+                }
+            }//end of loop over siTk
+        }
+        if(m_tuple){
+            //SimTrackerHits
+            m_nSimTrackerHitVXD=simTrackerHitColSize(m_VXDCollection);
+            m_nSimTrackerHitSIT=simTrackerHitColSize(m_SITCollection);
+            m_nSimTrackerHitSET=simTrackerHitColSize(m_SETCollection);
+            m_nSimTrackerHitFTD=simTrackerHitColSize(m_FTDCollection);
+
+            //TrackerHits
+            m_nTrackerHitVXD=trackerHitColSize(m_VXDTrackerHits);
+            m_nTrackerHitSIT=trackerHitColSize(m_SITTrackerHits);
+            m_nTrackerHitSET=trackerHitColSize(m_SETTrackerHits);
+            m_nTrackerHitFTD=trackerHitColSize(m_FTDTrackerHits);
+            m_nTrackerHitDC=trackerHitColSize(m_DCDigiCol);
+
+            //SpacePoints
+            if(m_useSiSpacePoint){
+                m_nSpacePointSIT=trackerHitColSize(m_SITSpacePointCol);
+            }
+            //m_nSpacePointSET=trackerHitColSize(m_SETSpacePointCol);
+            m_nSpacePointFTD=trackerHitColSize(m_FTDSpacePointCol);
+        }
+    }
 }
 
-StatusCode TruthTrackerAlg::finalize()
+int TruthTrackerAlg::addIdealHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
+        colHandle, edm4hep::TrackerHitCollection*& truthTrackerHitCol,
+        edm4hep::MutableTrack& track, const char* msg,int nHitAdded)
 {
-    return GaudiAlgorithm::finalize();
+    if(nHitAdded>0) return nHitAdded;
+    int nHit=0;
+    const edm4hep::TrackerHitCollection* col=colHandle.get();
+    debug()<<"add "<<msg<<" "<<col->size()<<" trackerHit"<<endmsg;
+    debug()<<track<<endmsg;
+    for(auto hit:*col){
+        //get end point of this wire
+        TVector3 endPointStart(0,0,0);
+        TVector3 endPointEnd(0,0,0);
+        m_gridDriftChamber->cellposition(hit.getCellID(),endPointStart,
+                endPointEnd);//cm
+
+        //calc. doca of helix to wire
+        TVector3 wire(endPointStart.X()/dd4hep::mm,endPointStart.Y()/dd4hep::mm,0);//to mm
+        TVector3 center(m_helixXC,m_helixYC,0);//mm
+        double docaIdeal=(center-wire).Mag()-m_helixRadius;//mm
+        TVector3 centerFirst(m_helixXCFirst,m_helixYCFirst,0);//mm
+        double docaIdealFirst=(centerFirst-wire).Mag()-m_helixRadiusFirst;//mm
+
+        //add modified hit
+        auto tmpHit = truthTrackerHitCol->create();
+        tmpHit=hit.clone();
+        tmpHit.setTime(fabs(docaIdeal)*1e3/40.);//40#um/ns, drift time in ns
+        track.addToTrackerHits(tmpHit);
+
+        long long int detID=hit.getCellID();
+        debug()<<" addIdealHitsToTk "<<m_helixRadius<<" center "<<m_helixXC
+            <<" "<<m_helixYC<<" mm wire("<<m_decoder->get(detID,"layer")<<","
+            <<m_decoder->get(detID,"cellID")<<") "<<wire.X()<<" "<<wire.Y()
+            <<"mm docaIdeal "<<docaIdeal<<" docaIdealFirst "<<docaIdealFirst<<"mm "
+            <<"hit.Time orignal "<<hit.getTime()<<" new Time "
+            <<fabs(docaIdeal)*1e3/40.<<endmsg;
+        ++nHit;
+    }
+    return nHit;
+}
+
+bool TruthTrackerAlg::debugNoiseHitsCol(edm4hep::TrackerHitCollection* Vec)
+{
+    m_nNoiseDCTrackHit = Vec->size();
+std::cout << "  m_nNoiseDCTrackHit = " <<  m_nNoiseDCTrackHit << std::endl;
+    int ihit=0;
+    for(auto Vechit: *Vec)
+    {
+        m_NoiseDriftDistance[ihit] = (Vechit.getTime())*m_driftVelocity*1e-3;
+        ihit++;
+    }
+
+    return true;
+}
+
+int TruthTrackerAlg::makeNoiseHit(edm4hep::SimTrackerHitCollection* SimVec,
+        edm4hep::TrackerHitCollection* Vec,
+        edm4hep::MCRecoTrackerAssociationCollection* AssoVec,
+        const edm4hep::TrackerHitCollection* digiDCHitsCol,
+        const edm4hep::MCRecoTrackerAssociationCollection* assoHits)
+{
+    int nNoise = 0;
+    //loop all hits
+    for(unsigned int i = 0; i<(digiDCHitsCol->size()); i++)
+    {
+        edm4hep::TrackerHit mcHit = digiDCHitsCol->at(i);
+        unsigned long long wcellid = mcHit.getCellID();
+
+        float pocaTime = mcHit.getTime();
+
+        // store trackHit
+        auto trkHit = Vec->create();
+
+        trkHit.setCellID(wcellid);
+        trkHit.setTime(pocaTime);
+        trkHit.setEDep(mcHit.getEDep());
+        trkHit.setEdx(mcHit.getEdx());
+        trkHit.setPosition(mcHit.getPosition());
+        trkHit.setCovMatrix(mcHit.getCovMatrix());
+        for(int iAsso=0;iAsso<(int) assoHits->size();iAsso++)
+        {
+
+            if(assoHits->at(iAsso).getRec().getCellID()==wcellid )
+            {
+                auto SimtrkHit = SimVec->create();
+
+                SimtrkHit.setCellID(assoHits->at(iAsso).getSim().getCellID());
+                SimtrkHit.setEDep(assoHits->at(iAsso).getSim().getEDep());
+                SimtrkHit.setTime(assoHits->at(iAsso).getSim().getTime());
+                SimtrkHit.setPathLength(assoHits->at(iAsso).getSim().getPathLength());
+                SimtrkHit.setQuality(assoHits->at(iAsso).getSim().getQuality());
+                SimtrkHit.setPosition(assoHits->at(iAsso).getSim().getPosition());
+                SimtrkHit.setMomentum(assoHits->at(iAsso).getSim().getMomentum());
+                SimtrkHit.setMCParticle(assoHits->at(iAsso).getSim().getMCParticle());
+
+                auto asso = AssoVec->create();
+                asso.setRec(trkHit);
+                asso.setSim(SimtrkHit);
+                asso.setWeight(SimtrkHit.getEDep()/trkHit.getEDep());
+            }
+        }
+
+        double prob1 = fRandom.Uniform(1.);
+        if(prob1 > m_fHitPurity) continue;
+
+        float noiseTime = m_pocaTime*fRandom.Uniform(1.);
+        if(noiseTime>pocaTime) continue;
+        nNoise++;
+        trkHit.setTime(noiseTime);
+
+        for(int iAsso=0;iAsso<(int) assoHits->size();iAsso++)
+        {
+
+            if(assoHits->at(iAsso).getRec().getCellID()==wcellid )
+            {
+
+                AssoVec->at(iAsso).setRec(trkHit);
+
+            }
+
+        }
+
+    }
+
+std::cout << " Truth Noise number = " << nNoise << std::endl;
+    return nNoise;
+}
+
+int TruthTrackerAlg::smearDCTkhit(DataHandle<edm4hep::TrackerHitCollection>&
+        colHandle,DataHandle<edm4hep::TrackerHitCollection>& smearCol,
+        DataHandle<edm4hep::SimTrackerHitCollection>& SimDCHitCol,
+        DataHandle<edm4hep::SimTrackerHitCollection>& SimSmearDCHitCol,
+        DataHandle<edm4hep::MCRecoTrackerAssociationCollection>& AssoDCHitCol,
+        DataHandle<edm4hep::MCRecoTrackerAssociationCollection>& AssoSmearDCHitCol,
+        double resX, double resY, double resZ)
+{
+    int nHit=0;
+    const edm4hep::TrackerHitCollection* col=colHandle.get();
+    auto smearTrackerHitCol = smearCol.createAndPut();
+
+    auto simDCCol = SimDCHitCol.get();
+    auto SimVec = SimSmearDCHitCol.createAndPut();
+
+    auto assoHits = AssoDCHitCol.get();
+    auto AssoVec = AssoSmearDCHitCol.createAndPut();
+
+    //sort,FIXME
+    for(auto hit:*col){
+
+        auto smearHit=smearTrackerHitCol->create();
+
+        float truthD = (hit.getTime())*m_driftVelocity*1e-3;
+        m_DriftDistance[nHit] = truthD;
+
+        truthD+=gRandom->Gaus(0,fabs(m_resX));
+        m_SmearDriftDistance[nHit] = truthD;
+        float smearT = (truthD*1e3)/m_driftVelocity;
+
+        smearHit.setTime(smearT);
+        smearHit.setCellID(hit.getCellID());
+        smearHit.setType(hit.getCellID());
+        smearHit.setQuality(hit.getQuality());
+        smearHit.setEDep(hit.getEDep());
+        smearHit.setEDepError(hit.getEDepError());
+        smearHit.setEdx(hit.getEdx());
+        smearHit.setPosition(hit.getPosition());
+        smearHit.setCovMatrix(hit.getCovMatrix());
+        smearHit.addToRawHits(hit.getObjectID());
+
+        ++nHit;
+        for(int iAsso=0;iAsso<(int) assoHits->size();iAsso++)
+        {
+
+            if(assoHits->at(iAsso).getRec().getCellID()== smearHit.getCellID())
+            {
+                auto SimtrkHit = SimVec->create();
+
+                SimtrkHit.setCellID(assoHits->at(iAsso).getSim().getCellID());
+                SimtrkHit.setEDep(assoHits->at(iAsso).getSim().getEDep());
+                SimtrkHit.setTime(assoHits->at(iAsso).getSim().getTime());
+                SimtrkHit.setPathLength(assoHits->at(iAsso).getSim().getPathLength());
+                SimtrkHit.setQuality(assoHits->at(iAsso).getSim().getQuality());
+                SimtrkHit.setPosition(assoHits->at(iAsso).getSim().getPosition());
+                SimtrkHit.setMomentum(assoHits->at(iAsso).getSim().getMomentum());
+                SimtrkHit.setMCParticle(assoHits->at(iAsso).getSim().getMCParticle());
+
+                auto asso = AssoVec->create();
+                asso.setRec(smearHit);
+                asso.setSim(SimtrkHit);
+                asso.setWeight(SimtrkHit.getEDep()/smearHit.getEDep());
+            }
+        }
+    }
+    std::cout << " SimSmear size = " <<  SimVec->size() << " Asso size = " << AssoVec->size() << std::endl;
+    std::cout << " Sim size = " <<  simDCCol->size() << " Asso size = " << assoHits->size() << std::endl;
+
+    return nHit;
+}
+
+int TruthTrackerAlg::addHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
+        colHandle, edm4hep::MutableTrack& track, const char* msg,int nHitAdded)
+{
+    if(nHitAdded>0) return nHitAdded;
+    int nHit=0;
+    const edm4hep::TrackerHitCollection* col=colHandle.get();
+    debug()<<"add "<<msg<<" "<<col->size()<<" trackerHit"<<endmsg;
+    //sort,FIXME
+    for(auto hit:*col){
+        track.addToTrackerHits(hit);
+        ++nHit;
+    }
+    return nHit;
+}
+
+int TruthTrackerAlg::addSimHitsToTk(
+        DataHandle<edm4hep::SimTrackerHitCollection>& colHandle,
+        edm4hep::TrackerHitCollection*& truthTrackerHitCol,
+        edm4hep::MutableTrack& track, const char* msg,int nHitAdded)
+{
+    if(nHitAdded>0) return nHitAdded;
+    int nHit=0;
+    const edm4hep::SimTrackerHitCollection* col=colHandle.get();
+    for(auto simTrackerHit:*col){
+        auto trackerHit=truthTrackerHitCol->create();
+        if(m_skipSecondaryHit&&simTrackerHit.isProducedBySecondary()) {
+            debug()<<"skip secondary simTrackerHit "<<msg<<endmsg;
+            continue;
+        }
+        auto& pos = simTrackerHit.getPosition();
+        debug()<<" addSimHitsToTk "<<msg<<" "<<sqrt(pos.x*pos.x+pos.y*pos.y)<<endmsg;
+        UTIL::BitField64 encoder(lcio::ILDCellID0::encoder_string) ;
+        int detID=encoder[lcio::ILDCellID0::subdet] ;
+        double resolution[3];
+        if(lcio::ILDDetID::VXD==detID){
+            for(int i=0;i<3;i++)resolution[i]=m_resVXD[i];
+        }else if(lcio::ILDDetID::SIT==detID){
+            for(int i=0;i<3;i++)resolution[i]=m_resSIT[i];
+        }else if(lcio::ILDDetID::SET==detID){
+            for(int i=0;i<3;i++)resolution[i]=m_resSET[i];
+        }else if(lcio::ILDDetID::FTD==detID){
+            for(int i=0;i<3;i++)resolution[i]=m_resFTDPixel[i];//FIXME
+        }else{
+            for(int i=0;i<3;i++)resolution[i]=0.003;
+        }
+        edm4hep::Vector3d posSmeared;//mm
+        posSmeared.x=CLHEP::RandGauss::shoot(pos.x,resolution[0]);
+        posSmeared.y=CLHEP::RandGauss::shoot(pos.y,resolution[1]);
+        posSmeared.z=CLHEP::RandGauss::shoot(pos.z,resolution[2]);
+        trackerHit.setPosition(posSmeared) ;
+        encoder.setValue(simTrackerHit.getCellID()) ;
+        trackerHit.setCellID(encoder.lowWord());//?FIXME
+        std::array<float, 6> cov;
+        cov[0]=resolution[0]*resolution[0];
+        cov[1]=0.;
+        cov[2]=resolution[1]*resolution[1];
+        cov[3]=0.;
+        cov[4]=0.;
+        cov[5]=resolution[2]*resolution[2];
+        trackerHit.setCovMatrix(cov);
+        debug()<<"add simTrackerHit "<<msg<<" trackerHit "<<trackerHit<<endmsg;
+        ///Add hit to track
+        track.addToTrackerHits(trackerHit);
+        trackerHit.setEDep(simTrackerHit.getEDep());
+        trackerHit.addToRawHits(simTrackerHit.getObjectID());
+        trackerHit.setType(-8);//FIXME?
+        ++nHit;
+    }
+    debug()<<"add simTrackerHit "<<msg<<" "<<nHit<<endmsg;
+    return nHit;
+}
+
+int TruthTrackerAlg::addHotsToTk(edm4hep::Track& sourceTrack,
+        edm4hep::MutableTrack& targetTrack, int hitType,const char* msg,int nHitAdded)
+{
+    if(nHitAdded>0) return nHitAdded;
+    int nHit=0;
+    for(unsigned int iHit=0;iHit<sourceTrack.trackerHits_size();iHit++){
+        edm4hep::TrackerHit hit=sourceTrack.getTrackerHits(iHit);
+        UTIL::BitField64 encoder(lcio::ILDCellID0::encoder_string);
+        encoder.setValue(hit.getCellID());
+        if(encoder[lcio::ILDCellID0::subdet]==hitType){
+            targetTrack.addToTrackerHits(hit);
+            debug()<<endmsg<<" add siHit "<<msg<<" "<<iHit<<" "<<hit
+                <<" pos "<<hit.getPosition().x<<" "<<hit.getPosition().y<<" "
+                <<hit.getPosition().z<<" " <<endmsg;
+            ++nHit;
+        }
+    }
+    debug()<<endmsg<<" "<<nHit<<" "<<msg<<" hits add on track"<<endmsg;
+    return nHit;
+}
+
+int TruthTrackerAlg::nHotsOnTrack(edm4hep::Track& track, int hitType)
+{
+    int nHit=0;
+    for(unsigned int iHit=0;iHit<track.trackerHits_size();iHit++){
+        edm4hep::TrackerHit hit=track.getTrackerHits(iHit);
+        UTIL::BitField64 encoder(lcio::ILDCellID0::encoder_string);
+        encoder.setValue(hit.getCellID());
+        if(encoder[lcio::ILDCellID0::subdet]==hitType){
+            ++nHit;
+        }
+    }
+    return nHit;
+}
+
+int TruthTrackerAlg::trackerHitColSize(DataHandle<edm4hep::TrackerHitCollection>& col)
+{
+    const edm4hep::TrackerHitCollection* c=col.get();
+    if(nullptr!=c) return c->size();
+    return 0;
+}
+
+int TruthTrackerAlg::simTrackerHitColSize(DataHandle<edm4hep::SimTrackerHitCollection>& col)
+{
+    const edm4hep::SimTrackerHitCollection* c=col.get();
+    if(nullptr!=c) return c->size();
+    return 0;
+}
+//unit length is mm
+void TruthTrackerAlg::getCircleFromPosMom(double pos[3],double mom[3],
+        double Bz,double q,double& helixRadius,double& helixXC,double& helixYC)
+{
+    double FCT = 2.99792458E-4;//mm
+    double pxy = sqrt(mom[0]*mom[0]+mom[1]*mom[1]);
+    helixRadius = pxy / (FCT*Bz);
+    double phiMomRefPoint = atan2(mom[1],mom[0]);
+    helixXC= pos[0] + helixRadius*cos(phiMomRefPoint-M_PI*0.5*q);
+    helixYC= pos[1] + helixRadius*sin(phiMomRefPoint-M_PI*0.5*q);
 }
diff --git a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h
index 30efd0a8a..563d98543 100644
--- a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h
+++ b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h
@@ -4,6 +4,9 @@
 #include "GaudiAlg/GaudiAlgorithm.h"
 #include "k4FWCore/DataHandle.h"
 #include "DD4hep/Fields.h"
+#include "GaudiKernel/NTuple.h"
+
+#include "TRandom3.h"
 
 class IGeomSvc;
 namespace dd4hep {
@@ -15,10 +18,14 @@ namespace dd4hep {
 }
 namespace edm4hep {
     class MCParticleCollection;
+    class SimTrackerHitCollection;
     class TrackerHitCollection;
     class TrackCollection;
-    class MCRecoTrackerAssociationCollection;
+    class Track;
+    class MutableTrack;
+    class TrackState;
     class ReconstructedParticleCollection;
+    class MCRecoTrackerAssociationCollection;
     class MCRecoParticleAssociationCollection;
 }
 
@@ -32,47 +39,199 @@ class TruthTrackerAlg: public GaudiAlgorithm
         virtual StatusCode finalize() override;
 
     private:
+        void getTrackStateFromMcParticle(const edm4hep::MCParticleCollection*
+                mcParticleCol, edm4hep::TrackState& stat);
+        int addSimHitsToTk(DataHandle<edm4hep::SimTrackerHitCollection>&
+                colHandle, edm4hep::TrackerHitCollection*& truthTrackerHitCol,
+                edm4hep::MutableTrack& track, const char* msg,int nHitAdded);
+        int smearDCTkhit(DataHandle<edm4hep::TrackerHitCollection>&
+                colHandle,DataHandle<edm4hep::TrackerHitCollection>& smearCol,
+                DataHandle<edm4hep::SimTrackerHitCollection>& SimDCHitCol,
+                DataHandle<edm4hep::SimTrackerHitCollection>& SimSmearDCHitCol,
+                DataHandle<edm4hep::MCRecoTrackerAssociationCollection>& AssoDCHitCol,
+                DataHandle<edm4hep::MCRecoTrackerAssociationCollection>& AssoSmearDCHitCol,
+                double resX, double resY, double resZ);
+        int addHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
+                colHandle, edm4hep::MutableTrack& track, const char* msg,int nHitAdded);
+        int addIdealHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
+                colHandle, edm4hep::TrackerHitCollection*& truthTrackerHitCol,
+                edm4hep::MutableTrack& track, const char* msg,int nHitAdded);
+
+        int addHotsToTk(edm4hep::Track& sourceTrack,edm4hep::MutableTrack&
+                targetTrack, int hitType,const char* msg,int nHitAdded);
+        int nHotsOnTrack(edm4hep::Track& track, int hitType);
+        int trackerHitColSize(DataHandle<edm4hep::TrackerHitCollection>& hitCol);
+        int simTrackerHitColSize(DataHandle<edm4hep::SimTrackerHitCollection>& hitCol);
+        bool getTrackStateFirstHit(
+                DataHandle<edm4hep::SimTrackerHitCollection>& dcSimTrackerHitCol,
+                float charge,edm4hep::TrackState& trackState);
         SmartIF<IGeomSvc> m_geomSvc;
         dd4hep::Detector* m_dd4hep;
         dd4hep::OverlayedField m_dd4hepField;
         dd4hep::DDSegmentation::GridDriftChamber* m_gridDriftChamber;
         dd4hep::DDSegmentation::BitFieldCoder* m_decoder;
+        void debugEvent();
+        //unit length is mm
+        void getCircleFromPosMom(double pos[3],double mom[3],
+                double Bz,double q,double& helixRadius,double& helixXC,double& helixYC);
+        int makeNoiseHit(edm4hep::SimTrackerHitCollection* SimVec,
+                edm4hep::TrackerHitCollection* Vec,
+                edm4hep::MCRecoTrackerAssociationCollection* AssoVec,
+                const edm4hep::TrackerHitCollection* digiDCHitsCol,
+                const edm4hep::MCRecoTrackerAssociationCollection* assoHits);
+        bool debugNoiseHitsCol(edm4hep::TrackerHitCollection* Vec);
 
-        //reader
+            //reader
+            //        DataHandle<edm4hep::TrackerHitCollection> m_NoiseHitCol{
+            //            "NoiseDCHitsCollection", Gaudi::DataHandle::Reader, this};
         DataHandle<edm4hep::MCParticleCollection> m_mcParticleCol{
             "MCParticle", Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::SimTrackerHitCollection> m_DCSimTrackerHitCol{
+            "DriftChamberHitsCollection", Gaudi::DataHandle::Reader, this};
         DataHandle<edm4hep::TrackerHitCollection> m_DCDigiCol{
             "DigiDCHitCollection", Gaudi::DataHandle::Reader, this};
         DataHandle<edm4hep::MCRecoTrackerAssociationCollection>
             m_DCHitAssociationCol{ "DCHitAssociationCollection",
                 Gaudi::DataHandle::Reader, this};
         DataHandle<edm4hep::TrackCollection>
-            m_siSubsetTrackCol{ "SiSubsetTrackCollection",
+            m_siSubsetTrackCol{ "SubsetTracks",
                 Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::TrackerHitCollection> m_SITSpacePointCol{
+            "SITSpacePoints" , Gaudi::DataHandle::Reader, this};
+        //        DataHandle<edm4hep::TrackerHitCollection> m_SETSpacePointCol{
+        //            "SETSpacePoints" , Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::TrackerHitCollection> m_FTDSpacePointCol{
+            "FTDSpacePoints" , Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::TrackerHitCollection> m_VXDTrackerHits{
+            "VXDTrackerHits" , Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::TrackerHitCollection> m_SETTrackerHits{
+            "SETTrackerHits" , Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::TrackerHitCollection> m_SITTrackerHits{
+            "SITTrackerHits" , Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::TrackerHitCollection> m_FTDTrackerHits{
+            "FTDTrackerHits" , Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::SimTrackerHitCollection> m_VXDCollection{
+            "VXDCollection" , Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::SimTrackerHitCollection> m_SETCollection{
+            "SETCollection" , Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::SimTrackerHitCollection> m_SITCollection{
+            "SITCollection" , Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::SimTrackerHitCollection> m_FTDCollection{
+            "FTDCollection" , Gaudi::DataHandle::Reader, this};
         //writer
         DataHandle<edm4hep::TrackCollection> m_DCTrackCol{
             "DCTrackCollection", Gaudi::DataHandle::Writer, this};
         DataHandle<edm4hep::TrackCollection> m_SDTTrackCol{
             "SDTTrackCollection", Gaudi::DataHandle::Writer, this};
-        DataHandle<edm4hep::ReconstructedParticleCollection> m_DCRecParticleCol{
-            "DCRecParticleCollection", Gaudi::DataHandle::Writer, this};
-        DataHandle<edm4hep::MCRecoParticleAssociationCollection>
-            m_DCRecParticleAssociationCol{
-                "DCRecMCRecoParticleAssociationCollection",
-                Gaudi::DataHandle::Writer, this};
+        DataHandle<edm4hep::TrackerHitCollection> m_truthTrackerHitCol{
+            "TruthTrackerHitCollection", Gaudi::DataHandle::Writer, this};
+
+        // Smear hit
+        DataHandle<edm4hep::SimTrackerHitCollection> w_SimSmearHCol{
+            "SmearSimHitsCollection", Gaudi::DataHandle::Writer, this};
+        DataHandle<edm4hep::TrackerHitCollection> m_SmeartruthTrackerHitCol{
+            "SmearTrackerHitCollection", Gaudi::DataHandle::Writer, this};
+        DataHandle<edm4hep::MCRecoTrackerAssociationCollection> w_SmearAssociationCol{
+            "SmearDCHitAssociationCollection", Gaudi::DataHandle::Writer, this};
+        // make noise hit
+        DataHandle<edm4hep::SimTrackerHitCollection> w_SimNoiseHCol{
+            "NoiseSimHitsCollection", Gaudi::DataHandle::Writer, this};
+        DataHandle<edm4hep::TrackerHitCollection> w_NoiseHitCol{
+            "NoiseDCHitsCollection", Gaudi::DataHandle::Writer, this};
+        DataHandle<edm4hep::MCRecoTrackerAssociationCollection> w_NoiseAssociationCol{
+            "NoiseDCHitAssociationCollection", Gaudi::DataHandle::Writer, this};
+
 
         //readout for getting segmentation
         Gaudi::Property<std::string> m_readout_name{this, "readout",
             "DriftChamberHitsCollection"};
-        Gaudi::Property<bool> m_writeRecParticle{this,"writeRecParticle",false};
+        Gaudi::Property<bool> m_hist{this,"hist",false};
+        Gaudi::Property<bool> m_useDC{this,"useDC",true};
+        Gaudi::Property<bool> m_useSi{this,"useSi",true};
+        Gaudi::Property<bool> m_useTruthTrack{this,"useTruthTrack",false};
+        Gaudi::Property<bool> m_useSiTruthHit{this,"useSiTruthHit",false};
+        Gaudi::Property<bool> m_skipSecondaryHit{this,"skipSecondaryHit",true};
+        Gaudi::Property<bool> m_useFirstHitForDC{this,"useFirstHitForDC",false};
+        Gaudi::Property<bool> m_useSiSpacePoint{this,"useSiSpacePoint",false};
+        Gaudi::Property<bool> m_useIdealHit{this,"useIdealHit",false};
+
+        Gaudi::Property<bool> m_useNoiseHits{this,"useNoiseHits",false};
+        Gaudi::Property<bool> m_smearHits{this,"smearHits",false};
+
+        Gaudi::Property<float> m_momentumCut{this,"momentumCut",0.1};//momentum cut for the first hit
         Gaudi::Property<float> m_resPT{this,"resPT",0};//ratio
         Gaudi::Property<float> m_resPz{this,"resPz",0};//ratio
+        Gaudi::Property<float> m_resX{this,"resX",0.11};//mm
+        Gaudi::Property<float> m_resY{this,"resY",0.11};//mm
+        Gaudi::Property<float> m_resZ{this,"resZ",0.11};//mm
+        Gaudi::Property<float> m_driftVelocity{this,"driftVelocity",40};// um/us
         Gaudi::Property<float> m_resMomPhi{this,"resMomPhi",0};//radian
         Gaudi::Property<float> m_resMomTheta{this,"resMomTheta",0};//radian
         Gaudi::Property<float> m_resVertexX{this,"resVertexX",0.003};//3um
         Gaudi::Property<float> m_resVertexY{this,"resVertexY",0.003};//3um
         Gaudi::Property<float> m_resVertexZ{this,"resVertexZ",0.003};//3um
         Gaudi::Property<int> m_maxDCDigiCut{this,"maxDigiCut",1e6};
+        Gaudi::Property<std::vector<float> > m_resVXD{this,"resVXD",{0.003,0.003,0.003}};//mm
+        Gaudi::Property<std::vector<float> > m_resSIT{this,"resSIT",{0.003,0.003,0.003}};//mm
+        Gaudi::Property<std::vector<float> > m_resSET{this,"resSET",{0.003,0.003,0.003}};//mm
+        Gaudi::Property<std::vector<float> > m_resFTDPixel{this,"resFTDPixel",{0.003,0.003,0.003}};//mm
+        Gaudi::Property<std::vector<float> > m_resFTDStrip{this,"resFTDStrip",{0.003,0.003,0.003}};//mm
+
+        Gaudi::Property<double> m_fHitPurity{this,"fHitPurity",0.1};
+        Gaudi::Property<float> m_pocaTime  { this, "pocaTime", 225};// ns
+
+        double m_helixRadius,m_helixXC,m_helixYC;
+        double m_helixRadiusFirst,m_helixXCFirst,m_helixYCFirst;
+
+        NTuple::Tuple*  m_tuple;
+        NTuple::Item<int> m_run;
+        NTuple::Item<int> m_evt;
+        NTuple::Array<double> m_siMom;
+        NTuple::Array<double> m_siPos;
+        NTuple::Array<double> m_mcMom;
+        NTuple::Array<double> m_mcPos;
+
+        NTuple::Item<int> m_nDCTrackHit;
+        NTuple::Item<int> m_nSmearDCTrackHit;
+        NTuple::Item<int> m_nNoiseDCTrackHit;
+        NTuple::Array<float> m_DriftDistance;
+        NTuple::Array<float> m_SmearDriftDistance;
+        NTuple::Array<float> m_NoiseDriftDistance;
+
+        NTuple::Item<int> m_nSimTrackerHitVXD;
+        NTuple::Item<int> m_nSimTrackerHitSIT;
+        NTuple::Item<int> m_nSimTrackerHitSET;
+        NTuple::Item<int> m_nSimTrackerHitFTD;
+        NTuple::Item<int> m_nSimTrackerHitDC;
+        NTuple::Item<int> m_nTrackerHitVXD;
+        NTuple::Item<int> m_nTrackerHitSIT;
+        NTuple::Item<int> m_nTrackerHitSET;
+        NTuple::Item<int> m_nTrackerHitFTD;
+        NTuple::Item<int> m_nTrackerHitDC;
+        NTuple::Item<int> m_nTrackerHitErrVXD;
+        NTuple::Item<int> m_nTrackerHitErrSIT;
+        NTuple::Item<int> m_nTrackerHitErrSET;
+        NTuple::Item<int> m_nTrackerHitErrFTD;
+        NTuple::Item<int> m_nSpacePointSIT;
+        NTuple::Item<int> m_nSpacePointSET;
+        NTuple::Item<int> m_nSpacePointFTD;
+        NTuple::Item<int> m_nSpacePointErrVXD;
+        NTuple::Item<int> m_nSpacePointErrSIT;
+        NTuple::Item<int> m_nSpacePointErrSET;
+        NTuple::Item<int> m_nSpacePointErrFTD;
+        NTuple::Item<int> m_nHitOnSiTkVXD;
+        NTuple::Item<int> m_nHitOnSiTkSIT;
+        NTuple::Item<int> m_nHitOnSiTkSET;
+        NTuple::Item<int> m_nHitOnSiTkFTD;
+        NTuple::Item<int> m_nHitOnSdtTkVXD;
+        NTuple::Item<int> m_nHitOnSdtTkSIT;
+        NTuple::Item<int> m_nHitOnSdtTkSET;
+        NTuple::Item<int> m_nHitOnSdtTkFTD;
+        NTuple::Item<int> m_nHitOnSdtTkDC;
+        NTuple::Item<int> m_nHitOnSdtTk;
+        NTuple::Item<int> m_nNoiseOnSdtTk;
+
+        TRandom3 fRandom;
 };
 
 #endif
diff --git a/Utilities/DataHelper/CMakeLists.txt b/Utilities/DataHelper/CMakeLists.txt
index 8398a6557..74ec620fb 100644
--- a/Utilities/DataHelper/CMakeLists.txt
+++ b/Utilities/DataHelper/CMakeLists.txt
@@ -15,9 +15,11 @@ gaudi_add_library(DataHelperLib
                           src/TrackerHitExtended.cc
                           src/TrackExtended.cc
                           src/TrackHitPair.cc
-			  src/TrackerHitHelper.cpp
+                          src/TrackerHitHelper.cpp
+                          src/TrackHelper.cc
                   LINK EDM4HEP::edm4hep
                        EDM4HEP::edm4hepDict
+                       DetSegmentation
                        GSL::gsl
                        ${CLHEP_LIBRARIES}
 		       Identifier
diff --git a/Utilities/DataHelper/include/DataHelper/HelixClass.h b/Utilities/DataHelper/include/DataHelper/HelixClass.h
index 794f81586..f573ee9d5 100644
--- a/Utilities/DataHelper/include/DataHelper/HelixClass.h
+++ b/Utilities/DataHelper/include/DataHelper/HelixClass.h
@@ -69,6 +69,7 @@ class HelixClass {
  *     - particle charge : q;<br>
  *     - magnetic field (in Tesla) : B<br>
  */  
+    void Initialize_VP(double * pos, double * mom, double q, double B);
     void Initialize_VP(float * pos, float * mom, float q, float B);
 
 /**
@@ -266,35 +267,35 @@ class HelixClass {
     float getCharge();
 
  private:    
-    float _momentum[3]; // momentum @ ref point 
+    float  _momentum[3]; // momentum @ ref point 
     float _referencePoint[3]; // coordinates @ ref point
-    float _phi0; // phi0 in canonical parameterization 
-    float _d0;   // d0 in canonical parameterisation
-    float _z0;   // z0 in canonical parameterisation
-    float _omega; // signed curvuture in canonical parameterisation
-    float _tanLambda; // TanLambda 
-    float _pxy; // Transverse momentum
-    float _charge; // Particle Charge
-    float _bField; // Magnetic field (assumed to point to Z>0)
-    float _radius; // radius of circle in XY plane
-    float _xCentre; // X of circle centre
-    float _yCentre; // Y of circle centre
-    float _phiRefPoint; // Phi w.r.t. (X0,Y0) of circle @ ref point
-    float _phiAtPCA; // Phi w.r.t. (X0,Y0) of circle @ PCA 
-    float _xAtPCA; // X @ PCA
-    float _yAtPCA; // Y @ PCA
-    float _pxAtPCA; // PX @ PCA
-    float _pyAtPCA; // PY @ PCA
-    float _phiMomRefPoint; // Phi of Momentum vector @ ref point
-    float _const_pi; // PI
-    float _const_2pi; // 2*PI
-    float _const_pi2; // PI/2    
-    float _FCT; // 2.99792458E-4
+    double  _phi0; // phi0 in canonical parameterization 
+    double  _d0;   // d0 in canonical parameterisation
+    double  _z0;   // z0 in canonical parameterisation
+    double  _omega; // signed curvuture in canonical parameterisation
+    double  _tanLambda; // TanLambda 
+    double  _pxy; // Transverse momentum
+    double  _charge; // Particle Charge
+    double  _bField; // Magnetic field (assumed to point to Z>0)
+    double  _radius; // radius of circle in XY plane
+    double  _xCentre; // X of circle centre
+    double  _yCentre; // Y of circle centre
+    double  _phiRefPoint; // Phi w.r.t. (X0,Y0) of circle @ ref point
+    double  _phiAtPCA; // Phi w.r.t. (X0,Y0) of circle @ PCA 
+    double  _xAtPCA; // X @ PCA
+    double  _yAtPCA; // Y @ PCA
+    double  _pxAtPCA; // PX @ PCA
+    double  _pyAtPCA; // PY @ PCA
+    double  _phiMomRefPoint; // Phi of Momentum vector @ ref point
+    double  _const_pi; // PI
+    double  _const_2pi; // 2*PI
+    double  _const_pi2; // PI/2    
+    double  _FCT; // 2.99792458E-4
     float _xStart[3]; // Starting point of track segment
     float _xEnd[3]; // Ending point of track segment
 
-    float _bZ;
-    float _phiZ;
+    double  _bZ;
+    double  _phiZ;
 
 };
 
diff --git a/Utilities/DataHelper/src/HelixClass.cc b/Utilities/DataHelper/src/HelixClass.cc
index 591acc514..a9ef6ca70 100644
--- a/Utilities/DataHelper/src/HelixClass.cc
+++ b/Utilities/DataHelper/src/HelixClass.cc
@@ -12,6 +12,75 @@ HelixClass::HelixClass() {
 
 HelixClass::~HelixClass() {}
 
+void HelixClass::Initialize_VP(double * pos, double * mom, double q, double B) {
+    _referencePoint[0] = (float) pos[0];
+    _referencePoint[1] = (float) pos[1];
+    _referencePoint[2] = (float) pos[2];
+    _momentum[0] = (float) mom[0];
+    _momentum[1] = (float) mom[1];
+    _momentum[2] = (float) mom[2];
+    _charge = q;
+    _bField = B;
+    _pxy = sqrt(mom[0]*mom[0]+mom[1]*mom[1]);
+    _radius = _pxy / (_FCT*B);
+    _omega = q/_radius;
+    _tanLambda = mom[2]/_pxy;
+    _phiMomRefPoint = atan2(mom[1],mom[0]);
+    _xCentre = pos[0] + _radius*cos(_phiMomRefPoint-_const_pi2*q);
+    _yCentre = pos[1] + _radius*sin(_phiMomRefPoint-_const_pi2*q);
+    _phiRefPoint = atan2(pos[1]-_yCentre,pos[0]-_xCentre);
+    _phiAtPCA = atan2(-_yCentre,-_xCentre);
+    _phi0 = -_const_pi2*q + _phiAtPCA;
+    while (_phi0<0) _phi0+=_const_2pi;
+    while (_phi0>=_const_2pi) _phi0-=_const_2pi;
+    _xAtPCA = _xCentre + _radius*cos(_phiAtPCA);
+    _yAtPCA = _yCentre + _radius*sin(_phiAtPCA);
+    //    _d0 = -_xAtPCA*sin(_phi0) + _yAtPCA*cos(_phi0);
+    
+    if (q>0) {
+      _d0 = double(q)*_radius - double(sqrt(_xCentre*_xCentre+_yCentre*_yCentre));
+    }
+    else {
+      _d0 = double(q)*_radius + double(sqrt(_xCentre*_xCentre+_yCentre*_yCentre));
+    }
+
+//     if (fabs(_d0)>0.001 ) {
+//       std::cout << "New helix : " << std::endl;
+//       std::cout << " Position : " << pos[0] 
+// 		<< " " << pos[1]
+// 		<< " " << pos[2] << std::endl;
+//       std::cout << " Radius = " << _radius << std::endl;
+//       std::cout << " RC = " << sqrt(_xCentre*_xCentre+_yCentre*_yCentre) << std::endl;  
+//       std::cout << " D0 = " << _d0 << std::endl;
+//     }
+
+    _pxAtPCA = _pxy*cos(_phi0);
+    _pyAtPCA = _pxy*sin(_phi0);
+    float deltaPhi = _phiRefPoint - _phiAtPCA;    
+    float xCircles = -pos[2]*q/(_radius*_tanLambda) - deltaPhi;
+    xCircles = xCircles/_const_2pi;
+    int nCircles;
+    int n1,n2;
+
+    if (xCircles >= 0.) {
+	n1 = int(xCircles);
+	n2 = n1 + 1;
+    }
+    else {
+	n1 = int(xCircles) - 1;
+	n2 = n1 + 1;
+    }
+    
+    if (fabs(n1-xCircles) < fabs(n2-xCircles)) {
+	nCircles = n1;
+    }
+    else {
+	nCircles = n2;
+    }
+    _z0 = pos[2] + _radius*_tanLambda*q*(deltaPhi + _const_2pi*nCircles);
+
+}
+
 void HelixClass::Initialize_VP(float * pos, float * mom, float q, float B) {
     _referencePoint[0] = pos[0];
     _referencePoint[1] = pos[1];
diff --git a/Utilities/DataHelper/src/TrackerHitHelper.cpp b/Utilities/DataHelper/src/TrackerHitHelper.cpp
index e12eb886c..f12b16873 100644
--- a/Utilities/DataHelper/src/TrackerHitHelper.cpp
+++ b/Utilities/DataHelper/src/TrackerHitHelper.cpp
@@ -7,6 +7,8 @@
 #include "CLHEP/Vector/ThreeVector.h"
 #include "CLHEP/Vector/Rotation.h"
 #include <bitset>
+#include "TVector3.h"
+#include "DD4hep/DD4hepUnits.h"
 
 std::array<float,6> CEPC::GetCovMatrix(edm4hep::TrackerHit& hit, bool useSpacePointBuilderMethod){
   if(hit.isAvailable()){
@@ -115,3 +117,44 @@ std::array<float, 6> CEPC::ConvertToCovXYZ(float dU, float thetaU, float phiU, f
   }
   return cov;
 }
+
+const edm4hep::SimTrackerHit CEPC::getAssoClosestSimTrackerHit(
+        const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
+        const edm4hep::TrackerHit trackerHit,
+        const dd4hep::DDSegmentation::GridDriftChamber* segmentation,
+        int docaMehtod)
+{
+  std::vector<edm4hep::SimTrackerHit> hits;
+  for(auto assoHit: *assoHits){
+    if(assoHit.getRec()==trackerHit){
+      hits.push_back(assoHit.getSim());
+    }
+  }
+  edm4hep::SimTrackerHit minSimTrackerHit;
+  double min_distance = 999 ;
+  double tmp_distance =0.;
+  for(auto hit:hits){
+    unsigned long long wcellid=hit.getCellID();
+    TVector3  pos(hit.getPosition()[0]*dd4hep::mm, hit.getPosition()[1]*dd4hep::mm, hit.getPosition()[2]*dd4hep::mm);
+
+    TVector3 sim_mon(hit.getMomentum()[0],hit.getMomentum()[1],hit.getMomentum()[2]);
+    float Steplength = hit.getPathLength();
+    TVector3  pos_start=pos - 0.5 * Steplength * sim_mon.Unit();
+    TVector3  pos_end=pos + 0.5 * Steplength * sim_mon.Unit();
+    TVector3 hitPosition;
+    TVector3 PCA;
+    tmp_distance = segmentation->Distance(wcellid,pos_start,pos_end,hitPosition,PCA);
+    tmp_distance = tmp_distance/dd4hep::mm; //mm
+
+    if(tmp_distance < min_distance){
+      min_distance = tmp_distance;
+      //pos_x = hitPosition.x();     //pos.x();
+      //pos_y = hitPosition.y();     //pos.y();
+      //pos_z = pos.z();
+      //momx = hit.getMomentum()[0];
+      //momy = hit.getMomentum()[1];
+      minSimTrackerHit=hit;
+    }
+  }
+  return minSimTrackerHit;
+}

From f0fd6257ced3ee0facfb5e6277a915c17304584a Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Sun, 5 Jun 2022 21:36:42 +0800
Subject: [PATCH 10/27] update 101 -2

---
 .../include/DataHelper/TrackerHitHelper.h        | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Utilities/DataHelper/include/DataHelper/TrackerHitHelper.h b/Utilities/DataHelper/include/DataHelper/TrackerHitHelper.h
index fcd9dd146..319bbebf6 100644
--- a/Utilities/DataHelper/include/DataHelper/TrackerHitHelper.h
+++ b/Utilities/DataHelper/include/DataHelper/TrackerHitHelper.h
@@ -2,13 +2,29 @@
 #define TrackerHitHelper_H
 
 #include "edm4hep/TrackerHit.h"
+#include "edm4hep/SimTrackerHit.h"
+#include "edm4hep/MCRecoTrackerAssociationCollection.h"
+#include "DDSegmentation/Segmentation.h"
+#include "DetSegmentation/GridDriftChamber.h"
 #include <array>
 
+//namespace dd4hep {
+//         class Detector;
+//         namespace DDSegmentation{
+//             class GridDriftChamber;
+//         }
+//}
+
 namespace CEPC{
   std::array<float, 6> GetCovMatrix(edm4hep::TrackerHit& hit, bool useSpacePointerBuilderMethod = false);
   float                GetResolutionRPhi(edm4hep::TrackerHit& hit);
   float                GetResolutionZ(edm4hep::TrackerHit& hit);
   std::array<float, 6> ConvertToCovXYZ(float dU, float thetaU, float phiU, float dV, float thetaV, float phiV, bool useSpacePointBuilderMethod = false);
+  const edm4hep::SimTrackerHit getAssoClosestSimTrackerHit(
+          const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
+          const edm4hep::TrackerHit trackerHit,
+          const dd4hep::DDSegmentation::GridDriftChamber* segmentation,
+          int docaMehtod);
 }
 
 #endif

From 712b6bb1cdb5fa8006b2a88387abda93c1b6e424 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Sun, 5 Jun 2022 21:38:28 +0800
Subject: [PATCH 11/27] update 101 -3

---
 build.sh | 2 +-
 run.sh   | 2 +-
 setup.sh | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/build.sh b/build.sh
index 718e78011..8f8ad7e8c 100755
--- a/build.sh
+++ b/build.sh
@@ -92,7 +92,7 @@ function run-make() {
 
 # The current default platform
 lcg_platform=x86_64-centos7-gcc8-opt
-lcg_version=98.0.0
+lcg_version=101.0.0
 
 bldtool=${CEPCSW_BLDTOOL} # make, ninja # set in env var
 
diff --git a/run.sh b/run.sh
index dba9c8c81..97f7f2150 100755
--- a/run.sh
+++ b/run.sh
@@ -67,7 +67,7 @@ function run-job() {
 
 # The current default platform
 lcg_platform=x86_64-centos7-gcc8-opt
-lcg_version=98.0.0
+lcg_version=101.0.0
 
 bldtool=${CEPCSW_BLDTOOL} # make, ninja # set in env var
 
diff --git a/setup.sh b/setup.sh
index 44ff6369a..6b973779f 100644
--- a/setup.sh
+++ b/setup.sh
@@ -49,7 +49,7 @@ function setup-external() {
 # CEPCSW_LCG_VERSION=${1}; shift
 
 if [ -z "$CEPCSW_LCG_VERSION" ]; then
-    CEPCSW_LCG_VERSION=98.0.0
+    CEPCSW_LCG_VERSION=101.0.0
 fi
 export CEPCSW_LCG_VERSION
 

From 2f734f7ca414867aa99c36f26da0e7555b12321f Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Mon, 6 Jun 2022 10:55:04 +0800
Subject: [PATCH 12/27] Add TrackHelper head file and PlanarMeasurementSDT and
 WireMeasurementDC

---
 Reconstruction/RecGenfitAlg/src/GenfitHit.cpp |   94 ++
 Reconstruction/RecGenfitAlg/src/GenfitHit.h   |   65 +
 Reconstruction/RecGenfitAlg/src/GenfitUnit.h  |   13 +
 Reconstruction/RecGenfitAlg/src/LSFitting.cpp |   92 ++
 Reconstruction/RecGenfitAlg/src/LSFitting.h   |   18 +
 .../RecGenfitAlg/src/PlanarMeasurementSDT.cpp |  127 ++
 .../RecGenfitAlg/src/PlanarMeasurementSDT.h   |   94 ++
 .../RecGenfitAlg/src/RecGenfitAlgSDT.cpp      | 1069 +++++++++++++++++
 .../RecGenfitAlg/src/RecGenfitAlgSDT.h        |  372 ++++++
 .../RecGenfitAlg/src/WireMeasurementDC.cpp    |  194 +++
 .../RecGenfitAlg/src/WireMeasurementDC.h      |  144 +++
 .../include/DataHelper/TrackHelper.h          |   19 +
 Utilities/DataHelper/src/TrackHelper.cc       |  130 ++
 13 files changed, 2431 insertions(+)
 create mode 100644 Reconstruction/RecGenfitAlg/src/GenfitHit.cpp
 create mode 100644 Reconstruction/RecGenfitAlg/src/GenfitHit.h
 create mode 100644 Reconstruction/RecGenfitAlg/src/GenfitUnit.h
 create mode 100644 Reconstruction/RecGenfitAlg/src/LSFitting.cpp
 create mode 100644 Reconstruction/RecGenfitAlg/src/LSFitting.h
 create mode 100644 Reconstruction/RecGenfitAlg/src/PlanarMeasurementSDT.cpp
 create mode 100644 Reconstruction/RecGenfitAlg/src/PlanarMeasurementSDT.h
 create mode 100644 Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
 create mode 100644 Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.h
 create mode 100644 Reconstruction/RecGenfitAlg/src/WireMeasurementDC.cpp
 create mode 100644 Reconstruction/RecGenfitAlg/src/WireMeasurementDC.h
 create mode 100644 Utilities/DataHelper/include/DataHelper/TrackHelper.h
 create mode 100644 Utilities/DataHelper/src/TrackHelper.cc

diff --git a/Reconstruction/RecGenfitAlg/src/GenfitHit.cpp b/Reconstruction/RecGenfitAlg/src/GenfitHit.cpp
new file mode 100644
index 000000000..85af21fec
--- /dev/null
+++ b/Reconstruction/RecGenfitAlg/src/GenfitHit.cpp
@@ -0,0 +1,94 @@
+#include "GenfitHit.h"
+#include "DataHelper/TrackerHitHelper.h"
+#include "DetSegmentation/GridDriftChamber.h"
+#include "GenfitUnit.h"
+
+#include "DD4hep/Detector.h"
+#include "DD4hep/DetElement.h"
+#include "DD4hep/Segmentations.h"
+#include "DD4hep/DD4hepUnits.h"
+#include "edm4hep/TrackerHit.h"
+#include "edm4hep/SimTrackerHit.h"
+#include "TRandom.h"
+
+#include <iostream>
+
+GenfitHit::GenfitHit(const edm4hep::TrackerHit* trackerHit,
+        const edm4hep::SimTrackerHit* simTrackerHit,
+        const dd4hep::DDSegmentation::BitFieldCoder* decoder,
+        const dd4hep::DDSegmentation::GridDriftChamber* gridDriftChamber,
+        double driftVelocity,double driftDistanceErr){
+    m_trackerHit=trackerHit;
+    m_simTrackerHit=simTrackerHit;
+    m_decoder=decoder;
+    m_gridDriftChamber=gridDriftChamber;
+    m_driftVelocity=driftVelocity;
+    m_driftDistanceErr=driftDistanceErr*GenfitUnit::cm;
+    //driftVelocity um/ns
+    m_driftDistanceTruth=m_trackerHit->getTime()*driftVelocity*GenfitUnit::um;
+    m_driftDistance=m_driftDistanceTruth*GenfitUnit::cm;
+//    if(driftDistanceErr>0) m_driftDistance+=gRandom->Gaus(0,fabs(driftDistanceErr*GenfitUnit::cm));//FIXME
+}
+
+unsigned long long GenfitHit::getCellID() const {
+    return m_trackerHit->getCellID();
+}
+
+int GenfitHit::getLayer() const {
+    return m_decoder->get(getCellID(),"layer");
+}
+
+int GenfitHit::getCell() const {
+    return m_decoder->get(getCellID(),"cellID");
+}
+
+int GenfitHit::getLeftRightAmbig() const {
+    TVector3 momTruth=getTruthMom();
+    TVector3 pocaOnTrack=getTruthPos();//FIXME, not poca on track
+    TVector3 trackDir=momTruth.Unit();
+    TVector3 wireDir=(getEnd1()-getEnd0()).Unit();
+    TVector3 pocaOnWire=
+        m_gridDriftChamber->wirePos_vs_z(getCellID(),pocaOnTrack.Z());
+    TVector3 pocaDir=(pocaOnWire-pocaOnTrack).Unit();
+    //TVector3 a=pocaDir.Cross(trackDir);
+    int lrAmbig=(pocaDir.Cross(trackDir))*wireDir;
+    return fabs(lrAmbig)/lrAmbig;
+}
+
+TVector3 GenfitHit::getEnd0() const {
+    TVector3 end0;
+    TVector3 end1;
+    m_gridDriftChamber->cellposition(m_trackerHit->getCellID(),end0,end1);//dd4hep unit
+    end0*=(1./dd4hep::cm)*GenfitUnit::cm;
+    return end0;
+}
+
+TVector3 GenfitHit::getEnd1() const {
+    TVector3 end0;
+    TVector3 end1;
+    m_gridDriftChamber->cellposition(m_trackerHit->getCellID(),end0,end1);//dd4hep unit
+    end1*=(1./dd4hep::cm)*GenfitUnit::cm;
+    return end1;
+}
+
+TVector3 GenfitHit::getTruthPos()const{
+    edm4hep::Vector3d pos=m_simTrackerHit->getPosition();
+    return TVector3(pos.x/dd4hep::cm*GenfitUnit::cm,
+            pos.y/dd4hep::cm*GenfitUnit::cm,
+            pos.z/dd4hep::cm*GenfitUnit::cm);
+}
+
+TVector3 GenfitHit::getTruthMom()const{
+    edm4hep::Vector3f mom=m_simTrackerHit->getMomentum();
+    return TVector3(mom.x/dd4hep::GeV*GenfitUnit::GeV,
+            mom.y/dd4hep::GeV*GenfitUnit::GeV,
+            mom.z/dd4hep::GeV*GenfitUnit::GeV);
+}
+
+void GenfitHit::print()const{
+    //TODO
+    std::cout<<"driftDistanceTruth cm "<<m_driftDistanceTruth;
+    std::cout<<"driftDistance cm "<<m_driftDistance;
+    std::cout<<"driftDistanceErr cm "<<m_driftDistanceErr<<std::endl;
+}
+
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitHit.h b/Reconstruction/RecGenfitAlg/src/GenfitHit.h
new file mode 100644
index 000000000..2f23d6485
--- /dev/null
+++ b/Reconstruction/RecGenfitAlg/src/GenfitHit.h
@@ -0,0 +1,65 @@
+//////////////////////////////////////////////////////////////////
+///
+/// This is an interface of to call genfit
+/// A genfit hit can be created
+///
+/// In this file, including:
+///   a genfit hit class
+///
+///   Units are following GenfitUnit
+#ifndef RECGENFITALG_GENFITHIT_H
+#define RECGENFITALG_GENFITHIT_H
+#include "TVector3.h"
+
+namespace edm4hep{
+    class SimTrackerHit;
+    class TrackerHit;
+}
+namespace dd4hep {
+    namespace DDSegmentation{
+        class GridDriftChamber;
+        class BitFieldCoder;
+    }
+}
+
+
+class GenfitHit{
+    public:
+        GenfitHit(const edm4hep::TrackerHit* trackerHit,
+                const edm4hep::SimTrackerHit* simTrackerHit,
+                const dd4hep::DDSegmentation::BitFieldCoder* decoder,
+                const dd4hep::DDSegmentation::GridDriftChamber* gridDriftChamber,
+                double driftVelocity,double driftDistanceErr);
+        ~GenfitHit(){;}
+        unsigned long long getCellID()const;
+        int getLayer()const;
+        int getCell()const;
+        double getDriftDistance()const{return m_driftDistance;}
+        double getDriftDistanceErr()const{return m_driftDistanceErr;}
+        double getDriftDistanceTruth()const{return m_driftDistanceTruth;}
+        const edm4hep::SimTrackerHit* getSimTrackerHit()const{return m_simTrackerHit;}
+        const edm4hep::TrackerHit* getTrackerHit()const{return m_trackerHit;}
+        TVector3 getEnd0()const;
+        TVector3 getEnd1()const;
+        TVector3 getTruthPos()const;
+        TVector3 getTruthMom()const;
+        double getMaxDistance()const{return 0.6*1.4;}//FIXME
+        int getLeftRightAmbig()const;
+
+        void setDriftDistance(double d){m_driftDistance=d;}
+        void setDriftDistanceErr(double de){m_driftDistanceErr=de;}
+        void setDriftDistanceTruth(double dt){m_driftDistanceTruth=dt;}
+        void print()const;
+
+    private:
+        const dd4hep::DDSegmentation::BitFieldCoder* m_decoder;
+        const dd4hep::DDSegmentation::GridDriftChamber* m_gridDriftChamber;
+        const edm4hep::TrackerHit* m_trackerHit;
+        const edm4hep::SimTrackerHit* m_simTrackerHit;
+        double m_driftDistance;
+        double m_driftDistanceErr;
+        double m_driftDistanceTruth;
+        double m_driftVelocity;
+};
+
+#endif
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitUnit.h b/Reconstruction/RecGenfitAlg/src/GenfitUnit.h
new file mode 100644
index 000000000..5601fcc28
--- /dev/null
+++ b/Reconstruction/RecGenfitAlg/src/GenfitUnit.h
@@ -0,0 +1,13 @@
+#ifndef GENFITUNIT_H
+#define GENFITUNIT_H
+
+namespace GenfitUnit{
+  static constexpr double cm=1.;
+  static constexpr double mm=0.1;
+  static constexpr double um=mm*1e-3;
+  static constexpr double GeV=1.;
+  static constexpr double kilogauss=1.;
+  static constexpr double tesla = 10.*kilogauss;
+}
+
+#endif
diff --git a/Reconstruction/RecGenfitAlg/src/LSFitting.cpp b/Reconstruction/RecGenfitAlg/src/LSFitting.cpp
new file mode 100644
index 000000000..6763e4233
--- /dev/null
+++ b/Reconstruction/RecGenfitAlg/src/LSFitting.cpp
@@ -0,0 +1,92 @@
+#include "LSFitting.h"
+#include <iostream>
+#include <TMinuit.h>
+
+
+std::vector<double> LSFitting::m_wireX;
+std::vector<double> LSFitting::m_wireY;
+std::vector<double> LSFitting::m_driftDist;
+
+void LSFitting::Fitting(double& fitXc, double& fitYc, double& fitRadius)
+{
+    TMinuit* tMinuit = new TMinuit(3);  //initialize TMinuit with a maximum of 3 params
+    tMinuit->SetFCN(FCN);
+    double arglist[2];
+    arglist[0] = 0;
+    int ierflg = 0;
+    tMinuit->SetPrintLevel(-1); // no print
+    tMinuit->mnexcm("SET NOW",  arglist,1,ierflg); // no warning
+    arglist[0] = 1;
+    tMinuit->mnexcm("SET ERR", arglist ,1,ierflg);
+    double xcErr= 1;
+    double ycErr= 1;
+    double radiusErr= 5;
+    //fitXc=0;
+    //fitYc=0;
+    //fitRadius=1000;
+    //std::cout<<" test Fitting---------------"<<fitXc<<" "<<fitYc<<" "<<fitRadius<<std::endl;
+    tMinuit->mnparm(0,"xc",fitXc,xcErr/1.e4,fitXc-xcErr,fitXc+xcErr,ierflg);
+    tMinuit->mnparm(1,"yc",fitYc,ycErr/1.e4,fitYc-ycErr,fitYc+ycErr,ierflg);
+    tMinuit->mnparm(2,"r",fitRadius,radiusErr/1.e4,fitRadius-radiusErr,fitRadius+radiusErr,ierflg);
+    arglist[0] = 0.0;
+    arglist[1] = 1.0;
+    tMinuit->mnexcm("MIGRAD", arglist ,2,ierflg);
+    double temp;
+    tMinuit->GetParameter(0, fitXc,temp);
+    tMinuit->GetParameter(1, fitYc,temp);
+    tMinuit->GetParameter(2, fitRadius,temp);
+    //std::cout<<" test Fitting---------------"<<fitXc<<" "<<fitYc<<" "<<fitRadius<<std::endl;
+
+    delete tMinuit;
+    return;
+}
+
+void LSFitting::FCN(int &npar, double *gin, double &f, double *par, int iflag)
+{
+    double fitXc=par[0];
+    double fitYc=par[1];
+    double fitRadius=par[2];
+    f = 0.0;
+    double hitChi2=0;
+
+    for(unsigned int i=0;i<m_wireX.size();i++) {
+        double fitDoca=fabs(sqrt((fitXc-m_wireX[i])*(fitXc-m_wireX[i])+
+                    (fitYc-m_wireY[i])*(fitYc-m_wireY[i]))-fitRadius);
+        double err=0.11;//mm
+        hitChi2=(fitDoca-m_driftDist[i])*(fitDoca-m_driftDist[i])/(err*err);
+        //std::cout<<"No."<<i<<" fitXY "<<fitXc<<" "<<fitYc<<" "<<fitRadius<<" wire "<<m_wireX[i]
+        //    <<" "<<m_wireY[i]<<" hit, drift: "<<m_driftDist[i]<<", doca: "
+            //<<fitDoca<<", hitchi: "<<hitChi2<<std::endl;
+        f+= hitChi2;
+        //std::cout<<"f: "<<f<<std::endl;
+    }
+    f = f/m_wireX.size();
+    //std::cout<<"This fit has "<<m_wireX.size()<<" hits, chisq: "<<f<<std::endl;
+}
+
+void LSFitting::clear(){
+    m_wireX.clear();
+    m_wireY.clear();
+    m_driftDist.clear();
+    std::vector<double> tmp1;
+    m_wireX.swap(tmp1);
+    std::vector<double> tmp2;
+    m_wireY.swap(tmp2);
+    std::vector<double> tmp3;
+    m_driftDist.swap(tmp3);
+}
+
+void LSFitting::setWire(double x,double y){
+    m_wireX.push_back(x);
+    m_wireY.push_back(y);
+}
+void LSFitting::setDrift(double driftDist){
+    m_driftDist.push_back(driftDist);
+}
+
+void LSFitting::print(){
+    std::cout<<" nHit "<<m_wireX.size()<<std::endl;
+    for(unsigned int i=0;i<m_wireX.size();i++) {
+        std::cout<<" wireX "<<m_wireX[i]<<" wireY "<<m_wireY[i]<<" drift "<<m_driftDist[i]<<std::endl;
+    }
+}
diff --git a/Reconstruction/RecGenfitAlg/src/LSFitting.h b/Reconstruction/RecGenfitAlg/src/LSFitting.h
new file mode 100644
index 000000000..e660fa3cb
--- /dev/null
+++ b/Reconstruction/RecGenfitAlg/src/LSFitting.h
@@ -0,0 +1,18 @@
+#ifndef RECONSTRUCTION_RECGENFITALG_LSFITTING_H
+#define RECONSTRUCTION_RECGENFITALG_LSFITTING_H
+#include <vector>
+#include <cmath>
+
+class LSFitting{
+public:
+    void Fitting(double& fitXc, double& fitYc, double& fitRadisu);
+    static void FCN(int &npar, double *gin, double &f, double *par, int iflag);
+    void setWire(double x,double y);
+    void setDrift(double driftDist);
+    void print();
+    void clear();
+    static std::vector<double> m_wireX;
+    static std::vector<double> m_wireY;
+    static std::vector<double> m_driftDist;
+};
+#endif
diff --git a/Reconstruction/RecGenfitAlg/src/PlanarMeasurementSDT.cpp b/Reconstruction/RecGenfitAlg/src/PlanarMeasurementSDT.cpp
new file mode 100644
index 000000000..cfa03ce9d
--- /dev/null
+++ b/Reconstruction/RecGenfitAlg/src/PlanarMeasurementSDT.cpp
@@ -0,0 +1,127 @@
+/* Copyright 2008-2010, Technische Universitaet Muenchen,
+   Authors: Christian Hoeppner & Sebastian Neubert & Johannes Rauch
+
+   This file is part of GENFIT.
+
+   GENFIT is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published
+   by the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   GENFIT is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with GENFIT.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "PlanarMeasurementSDT.h"
+
+#include <Exception.h>
+#include <RKTrackRep.h>
+#include <HMatrixU.h>
+#include <HMatrixV.h>
+#include <HMatrixUV.h>
+
+#include <cassert>
+#include <TBuffer.h>
+
+namespace genfit {
+
+PlanarMeasurementSDT::PlanarMeasurementSDT(int nDim)
+  : AbsMeasurement(nDim), physicalPlane_(), planeId_(-1), stripV_(false)
+{
+  assert(nDim >= 1);
+}
+
+PlanarMeasurementSDT::PlanarMeasurementSDT(const TVectorD& rawHitCoords, const TMatrixDSym& rawHitCov, int detId, int hitId, TrackPoint* trackPoint)
+  : AbsMeasurement(rawHitCoords, rawHitCov, detId, hitId, trackPoint), physicalPlane_(), planeId_(-1), stripV_(false)
+{
+  assert(rawHitCoords_.GetNrows() >= 1);
+}
+
+
+SharedPlanePtr PlanarMeasurementSDT::constructPlane(const StateOnPlane&) const {
+  if (!physicalPlane_) {
+    Exception exc("PlanarMeasurementSDT::constructPlane(): No plane has been set!", __LINE__,__FILE__);
+    throw exc;
+  }
+  return physicalPlane_;
+}
+
+
+std::vector<MeasurementOnPlane*> PlanarMeasurementSDT::constructMeasurementsOnPlane(const StateOnPlane& state) const {
+
+  MeasurementOnPlane* mop = new MeasurementOnPlane(rawHitCoords_,
+       rawHitCov_,
+       state.getPlane(), state.getRep(), constructHMatrix(state.getRep()));
+
+  std::vector<MeasurementOnPlane*> retVal;
+  retVal.push_back(mop);
+  return retVal;
+}
+
+
+const AbsHMatrix* PlanarMeasurementSDT::constructHMatrix(const AbsTrackRep* rep) const {
+
+  if (dynamic_cast<const RKTrackRep*>(rep) == nullptr) {
+    Exception exc("SpacepointMeasurement default implementation can only handle state vectors of type RKTrackRep!", __LINE__,__FILE__);
+    throw exc;
+  }
+
+  switch(rawHitCoords_.GetNrows()) {
+  case 1:
+    if (stripV_)
+      return new HMatrixV();
+    return new HMatrixU();
+
+  case 2:
+    return new HMatrixUV();
+
+  default:
+    Exception exc("PlanarMeasurementSDT default implementation can only handle 1D (strip) or 2D (pixel) measurements!", __LINE__,__FILE__);
+    throw exc;
+  }
+
+}
+
+void PlanarMeasurementSDT::Streamer(TBuffer &R__b)
+{
+   // Stream an object of class genfit::PlanarMeasurementSDT.
+
+   //This works around a msvc bug and should be harmless on other platforms
+   typedef ::genfit::PlanarMeasurementSDT thisClass;
+   UInt_t R__s, R__c;
+   if (R__b.IsReading()) {
+      Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
+      //This works around a msvc bug and should be harmless on other platforms
+      typedef genfit::AbsMeasurement baseClass0;
+      baseClass0::Streamer(R__b);
+      char flag;
+      R__b >> flag;
+      physicalPlane_.reset();
+      if (flag) {
+        physicalPlane_.reset(new DetPlane());
+        physicalPlane_->Streamer(R__b);
+      }
+      R__b >> planeId_;
+      R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
+   } else {
+      R__c = R__b.WriteVersion(thisClass::IsA(), kTRUE);
+      //This works around a msvc bug and should be harmless on other platforms
+      typedef genfit::AbsMeasurement baseClass0;
+      baseClass0::Streamer(R__b);
+      if (physicalPlane_) {
+        R__b << (char)1;
+        physicalPlane_->Streamer(R__b);
+      } else {
+        R__b << (char)0;
+      }
+      R__b << planeId_;
+      R__b.SetByteCount(R__c, kTRUE);
+   }
+}
+
+} /* End of namespace genfit */
diff --git a/Reconstruction/RecGenfitAlg/src/PlanarMeasurementSDT.h b/Reconstruction/RecGenfitAlg/src/PlanarMeasurementSDT.h
new file mode 100644
index 000000000..27867a9fa
--- /dev/null
+++ b/Reconstruction/RecGenfitAlg/src/PlanarMeasurementSDT.h
@@ -0,0 +1,94 @@
+/* Copyright 2008-2010, Technische Universitaet Muenchen,
+   Authors: Christian Hoeppner & Sebastian Neubert & Johannes Rauch
+
+   This file is part of GENFIT.
+
+   GENFIT is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published
+   by the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   GENFIT is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with GENFIT.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @addtogroup genfit
+ * @{
+ */
+
+#ifndef genfit_PlanarMeasurementSDT_h
+#define genfit_PlanarMeasurementSDT_h
+
+#include "AbsMeasurement.h"
+#include "AbsHMatrix.h"
+#include "MeasurementOnPlane.h"
+
+namespace edm4hep{
+    class TrackerHit;
+    class SimTrackerHit;
+}
+
+namespace genfit {
+
+class AbsTrackRep;
+
+/** @brief Measurement class implementing a planar hit geometry (1 or 2D).
+ *
+ *  @author Christian H&ouml;ppner (Technische Universit&auml;t M&uuml;nchen, original author)
+ *  @author Sebastian Neubert  (Technische Universit&auml;t M&uuml;nchen, original author)
+ *  @author Johannes Rauch  (Technische Universit&auml;t M&uuml;nchen, original author)
+ *
+ * The main feature of this type of hit is, that the detector plane
+ * is defined by the detector hardware. 
+ */
+class PlanarMeasurementSDT : public AbsMeasurement {
+
+ public:
+  PlanarMeasurementSDT(int nDim = 1);
+  PlanarMeasurementSDT(const TVectorD& rawHitCoords, const TMatrixDSym& rawHitCov, int detId, int hitId, TrackPoint* trackPoint);
+
+  virtual ~PlanarMeasurementSDT() {;}
+
+  virtual AbsMeasurement* clone() const override {return new PlanarMeasurementSDT(*this);}
+
+  int getPlaneId() const {return planeId_;}
+
+  virtual SharedPlanePtr constructPlane(const StateOnPlane& state) const override;
+
+  virtual std::vector<MeasurementOnPlane*> constructMeasurementsOnPlane(const StateOnPlane& state) const override;
+
+  virtual const AbsHMatrix* constructHMatrix(const AbsTrackRep*) const override;
+
+  virtual void setPlane(const SharedPlanePtr& physicalPlane, int planeId = -1) {physicalPlane_ = physicalPlane; planeId_ = planeId;}
+
+  /** @brief Use if the coordinate for 1D hits measured in V direction.
+   *
+   * Per default for 1D planar hits, the coordinate is measured in U direction.
+   * With this function you can set it to be measured in V direction.
+   * This affects the outcoe of constructHMatrix().
+   */
+  void setStripV(bool v = true) {stripV_ = v;}
+
+  void setTrackerHit(const edm4hep::TrackerHit* hit){trackerHit_=hit;}
+  const edm4hep::TrackerHit* getTrackerHit(){return trackerHit_;}
+
+ protected:
+  SharedPlanePtr physicalPlane_;   //! This is persistent, but '!' makes ROOT shut up.
+  int planeId_; // planeId id is -1 per default
+  bool stripV_;
+  const edm4hep::SimTrackerHit* simTrackerHit_;
+  const edm4hep::TrackerHit* trackerHit_;
+
+ public:
+
+  ClassDefOverride(PlanarMeasurementSDT,1)
+};
+
+} /* End of namespace genfit */
+/** @} */
+
+#endif // genfit_PlanarMeasurementSDT_h
diff --git a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
new file mode 100644
index 000000000..f9292e375
--- /dev/null
+++ b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
@@ -0,0 +1,1069 @@
+#include "RecGenfitAlgSDT.h"
+#include "GenfitTrack.h"
+#include "GenfitFitter.h"
+#include "GenfitField.h"
+#include "GenfitUnit.h"
+
+//genfit
+#include "EventDisplay.h"
+#include "ReferenceStateOnPlane.h"
+
+//cepcsw
+#include "DetInterface/IGeomSvc.h"
+#include "DataHelper/HelixClass.h"
+#include "DataHelper/TrackHelper.h"
+#include "DataHelper/TrackerHitHelper.h"
+#include "DetSegmentation/GridDriftChamber.h"
+#include "UTIL/ILDConf.h"
+
+//externals
+#include "edm4hep/EventHeaderCollection.h"
+#include "edm4hep/MCParticle.h"
+#include "edm4hep/MCParticleCollection.h"
+#include "edm4hep/SimTrackerHitCollection.h"
+#include "edm4hep/TrackerHitCollection.h"
+#include "edm4hep/TrackCollection.h"
+#include "edm4hep/MCRecoTrackerAssociationCollection.h"
+#include "edm4hep/ReconstructedParticle.h"
+#include "edm4hep/ReconstructedParticleCollection.h"
+#include "edm4hep/Track.h"
+#include "edm4hep/TrackCollection.h"
+#include "DD4hep/DD4hepUnits.h"
+#include "DD4hep/Detector.h"
+#include "UTIL/BitField64.h"
+#include "DDSegmentation/Segmentation.h"
+#include "TRandom.h"
+#include "TLorentzVector.h"
+
+//stl
+#include <chrono>
+#include "time.h"
+#include <stdlib.h>
+#include <thread>
+#include <iostream>
+
+#include <TTimeStamp.h>
+
+#include <ctime>
+#include <cstdlib>
+
+#include "map"
+
+DECLARE_COMPONENT( RecGenfitAlgSDT )
+
+    /////////////////////////////////////////////////////////////////////
+    RecGenfitAlgSDT::RecGenfitAlgSDT(const std::string& name,
+            ISvcLocator* pSvcLocator):
+        GaudiAlgorithm(name, pSvcLocator),m_nPDG(5),m_dd4hepDetector(nullptr),
+        m_gridDriftChamber(nullptr),m_decoder(nullptr)
+{
+    declareProperty("EventHeaderCollection", m_headerCol);
+    declareProperty("MCParticleCollection", m_mcParticleCol,
+            "Handle of the input MCParticle collection");
+    declareProperty("DigiDCHitCollection", m_DCDigiCol,
+            "Handle of DC digi(TrakerHit) collection");
+    declareProperty("DCHitAssociationCollection", m_DCHitAssociationCol,
+            "Handle of DCsimTrackerHit and DCTrackerHit association collection");
+    declareProperty("SDTTrackCollection", m_SDTTrackCol,
+            "Handle of input silicon track collection");
+    declareProperty("SDTRecTrackCollection",m_SDTRecTrackCol,
+            "Handle of input silicon rec. track collection");
+    declareProperty("DCTrackCollection", m_dcTrackCol,
+            "Handle of DC track collection");
+    declareProperty("SDTRecParticleCollection", m_SDTRecParticleCol,
+            "Handle of silicon+drift chamber rec. particle collection");
+
+    declareProperty("SimTrackerHitCollection",m_simVXDHitCol,
+             "Handle of the VXDsimTrackerHit collection");
+    declareProperty("SimTrackerHitCollection",m_simSETHitCol,
+             "Handle of the SETsimTrackerHit collection");
+    declareProperty("SimTrackerHitCollection",m_simSITHitCol,
+             "Handle of the SITsimTrackerHit collection");
+    declareProperty("SimTrackerHitCollection",m_simFTDHitCol,
+             "Handle of the FTDsimTrackerHit collection");
+    declareProperty("SimTrackerHitCollection",m_simDCHitCol,
+             "Handle of the DCsimTrackerHit collection");
+    declareProperty("SimTrackerHitCollection",m_simVXDHitCol,
+             "Handle of the VXDsimTrackerHit collection");
+    declareProperty("NoiseDCHitAssociationCollection",r_NoiseAssociationCol,
+             "Handle of the DCSimTrackerHits and Noise TrackerHit collection");
+
+    declareProperty("SmearDCHitAssociationCollection", r_SmearAssociationCol,
+            "Handle of output smear simulationhit and TrackerHit collection");
+
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+StatusCode RecGenfitAlgSDT::initialize()
+{
+    MsgStream log(msgSvc(), name());
+    info()<<" RecGenfitAlgSDT initialize()"<<endmsg;
+
+//    time_t timep;
+//    time(&timep);
+//    std::cout << "Myliu say: the time is "
+//              << ctime(&timep)
+//              << "at the begin of RecGenfitAlgSDT::initialize()"
+//              << std::endl;
+//    system("/scratchfs/bes/myliu/script/memory_rec.sh");
+
+    m_eventNo=0;
+
+    ///Get GeomSvc
+    m_geomSvc=Gaudi::svcLocator()->service("GeomSvc");
+    if (nullptr==m_geomSvc) {
+        std::cout<<"Failed to find GeomSvc"<<std::endl;
+        return StatusCode::FAILURE;
+    }
+    ///Get Detector
+    m_dd4hepDetector=m_geomSvc->lcdd();
+
+    ///Get Field
+    m_dd4hepField=m_geomSvc->lcdd()->field();
+
+    /// New a genfit fitter
+    m_genfitFitter=new GenfitFitter(m_fitterType.toString().c_str());
+    m_genfitField=new GenfitField(m_dd4hepField);
+    m_genfitFitter->setField(m_genfitField);
+    m_genfitFitter->setGeoMaterial(m_geomSvc->lcdd(),m_extMinDistCut,
+            m_skipWireMaterial);
+    m_genfitFitter->setEnergyLossBrems(m_correctBremsstrahlung);
+    m_genfitFitter->setNoiseBrems(m_correctBremsstrahlung);
+    //m_genfitFitter->setMultipleMeasurementHandling(
+            //genfit::eMultipleMeasurementHandling(m_multipleMeasurementHandling.value()));
+    if(m_debug>10) m_genfitFitter->setDebug(m_debug-10);
+    if(m_noMaterialEffects) m_genfitFitter->setNoEffects(true);
+    if(-1==m_debugPid) m_genfitFitter->setNoEffects(true);
+    if(-1==m_debugPid) m_debugPid=0;//charged geantino with electron pid
+    if(m_fitterType=="DAF"||m_fitterType=="DafRef"){
+        m_genfitFitter->setMaxIterationsBetas(m_bStart,m_bFinal,m_maxIteration);
+    } else {
+        m_genfitFitter->setMaxIterations(m_maxIteration);
+    }
+    //print genfit parameters
+    if(m_debug) m_genfitFitter->print();
+    if(""!=m_genfitHistRootName) m_genfitFitter->initHist(m_genfitHistRootName);
+
+    //initialize member vairables
+    for(int i=0;i<5;i++) m_fitSuccess[i]=0;
+    m_nRecTrack=0;
+    ///Get Readout
+    dd4hep::Readout readout=m_dd4hepDetector->readout(m_readout_name);
+    ///Get Segmentation
+    m_gridDriftChamber=dynamic_cast<dd4hep::DDSegmentation::GridDriftChamber*>
+        (readout.segmentation().segmentation());
+    if(nullptr==m_gridDriftChamber){
+        error() << "Failed to get the GridDriftChamber" << endmsg;
+        return StatusCode::FAILURE;
+    }
+
+    m_cell_width = 0.5*(m_gridDriftChamber->cell_Size()); //dd4hep::cm
+    debug() << " m_cell_width = " << m_cell_width << " dd4hep::cm"<< endmsg;
+    m_skipCorner = m_cell_width/dd4hep::cm;
+
+    ///Get Decoder
+    m_decoder = m_geomSvc->getDecoder(m_readout_name);
+    if (nullptr==m_decoder) {
+        error() << "Failed to get the decoder" << endmsg;
+        return StatusCode::FAILURE;
+    }
+
+
+    ///book tuple
+    NTuplePtr nt(ntupleSvc(), "RecGenfitAlgSDT/recGenfitAlgSDT");
+    if(nt){
+        m_tuple=nt;
+    }else{
+        m_tuple=ntupleSvc()->book("RecGenfitAlgSDT/recGenfitAlgSDT",
+                CLID_ColumnWiseTuple,"RecGenfitAlgSDT");
+        if(m_tuple){
+            StatusCode sc;
+            sc=m_tuple->addItem("run",m_run);
+            sc=m_tuple->addItem("evt",m_evt);
+            sc=m_tuple->addItem("tkId",m_tkId);
+            sc=m_tuple->addItem("nStdTrack",m_nSdtTrack);
+            sc=m_tuple->addItem("nStdTrackHit",m_nSdtTrackHit,0,1000);
+
+            sc=m_tuple->addItem("nSdtRecTrack",m_nSdtRecTrack);
+
+
+            sc=m_tuple->addItem("mcIndex",m_mcIndex,0,100);//max. 100 particles
+            sc=m_tuple->addItem("seedMomP",m_mcIndex,m_seedMomP);//for some track debug
+            sc=m_tuple->addItem("seedMomPt",m_mcIndex,m_seedMomPt);
+            sc=m_tuple->addItem("seedMomQ",m_mcIndex,m_seedMomQ);
+            sc=m_tuple->addItem("seedPos",m_mcIndex,m_seedPos,3);
+            sc=m_tuple->addItem("seedMom",m_mcIndex,m_seedMom,3);
+            sc=m_tuple->addItem("truthPocaMc",m_mcIndex,m_truthPocaMc,3);
+            sc=m_tuple->addItem("pocaPosMc",m_mcIndex,m_pocaPosMc,3);
+            sc=m_tuple->addItem("pocaMomMc",m_mcIndex,m_pocaMomMc,3);
+            sc=m_tuple->addItem("pocaMomMcP",m_mcIndex,m_pocaMomMcP);
+            sc=m_tuple->addItem("pocaMomMcPt",m_mcIndex,m_pocaMomMcPt);
+            sc=m_tuple->addItem("pocaPosMdc",m_mcIndex,m_pocaPosMdc,3);
+            sc=m_tuple->addItem("pocaMomMdc",m_mcIndex,m_pocaMomMdc,3);
+            sc=m_tuple->addItem("index",m_pidIndex, 0, 5);
+            //sc=m_tuple->addItem("firstPosKalP",5,3,m_firstPosKal);
+            //sc=m_tuple->addItem("firstMomKalP",5,m_firstMomKalP);
+            //sc=m_tuple->addItem("firstMomKalPt",5,m_firstMomKalPt);
+
+            sc=m_tuple->addItem("ErrorcovMatrix6",m_mcIndex,m_ErrorcovMatrix6,6);
+            sc=m_tuple->addItem("McErrCov",m_mcIndex,m_McErrCov,6);
+            sc=m_tuple->addItem("posx",m_mcIndex,m_posx);
+            sc=m_tuple->addItem("posy",m_mcIndex,m_posy);
+            sc=m_tuple->addItem("posz",m_mcIndex,m_posz);
+
+            sc=m_tuple->addItem("momx",m_mcIndex,m_momx);
+            sc=m_tuple->addItem("momy",m_mcIndex,m_momy);
+            sc=m_tuple->addItem("momz",m_mcIndex,m_momz);
+
+            sc=m_tuple->addItem("PosMcX",m_mcIndex,m_PosMcX);
+            sc=m_tuple->addItem("PosMcY",m_mcIndex,m_PosMcY);
+            sc=m_tuple->addItem("PosMcZ",m_mcIndex,m_PosMcZ);
+
+            sc=m_tuple->addItem("MomMcX",m_mcIndex,m_MomMcX);
+            sc=m_tuple->addItem("MomMcY",m_mcIndex,m_MomMcY);
+            sc=m_tuple->addItem("MomMcZ",m_mcIndex,m_MomMcZ);
+
+            sc=m_tuple->addItem("PocaPosX",m_mcIndex,m_PocaPosX);
+            sc=m_tuple->addItem("PocaPosY",m_mcIndex,m_PocaPosY);
+            sc=m_tuple->addItem("PocaPosZ",m_mcIndex,m_PocaPosZ);
+
+            sc=m_tuple->addItem("PocaMomX",m_mcIndex,m_PocaMomX);
+            sc=m_tuple->addItem("PocaMomY",m_mcIndex,m_PocaMomY);
+            sc=m_tuple->addItem("PocaMomZ",m_mcIndex,m_PocaMomZ);
+
+            sc=m_tuple->addItem("PocaErrCov",m_mcIndex,m_PocaErrCov,6);
+            
+            sc=m_tuple->addItem("ErrorcovMatrix",m_mcIndex,m_ErrorcovMatrix,15);
+            sc=m_tuple->addItem("D0",m_mcIndex,m_D0);
+            sc=m_tuple->addItem("phi",m_mcIndex,m_phi);
+            sc=m_tuple->addItem("omega",m_mcIndex,m_omega);
+            sc=m_tuple->addItem("Z0",m_mcIndex,m_Z0);
+            sc=m_tuple->addItem("tanLambda",m_mcIndex,m_tanLambda);
+
+            sc=m_tuple->addItem("ErrorcovMatrix_Origin",m_mcIndex,m_ErrorcovMatrix_Origin,15);
+            sc=m_tuple->addItem("D0_Origin",m_mcIndex,m_D0_Origin);
+            sc=m_tuple->addItem("phi_Origin",m_mcIndex,m_phi_Origin);
+            sc=m_tuple->addItem("omega_Origin",m_mcIndex,m_omega_Origin);
+            sc=m_tuple->addItem("Z0_Origin",m_mcIndex,m_Z0_Origin);
+            sc=m_tuple->addItem("tanLambda_Origin",m_mcIndex,m_tanLambda_Origin);
+
+            sc=m_tuple->addItem("mcP_D0",m_mcIndex,mcP_D0);
+            sc=m_tuple->addItem("mcP_phi",m_mcIndex,mcP_phi);
+            sc=m_tuple->addItem("mcP_omega",m_mcIndex,mcP_omega);
+            sc=m_tuple->addItem("mcP_Z0",m_mcIndex,mcP_Z0);
+            sc=m_tuple->addItem("mcP_tanLambda",m_mcIndex,mcP_tanLambda);
+
+            sc=m_tuple->addItem("pocaPosKal",5,3,m_pocaPosKal);
+            sc=m_tuple->addItem("pocaMomKal",5,3,m_pocaMomKal);
+            sc=m_tuple->addItem("pocaMomKalP",m_mcIndex,m_pocaMomKalP,5);
+            sc=m_tuple->addItem("pocaMomKalPt",m_mcIndex,m_pocaMomKalPt,5);
+            sc=m_tuple->addItem("chargeKal",m_mcIndex,m_chargeKal,5);
+            sc=m_tuple->addItem("nDofKal",m_mcIndex,m_nDofKal,5);
+            sc=m_tuple->addItem("chi2Kal",m_mcIndex,m_chi2Kal,5);
+            sc=m_tuple->addItem("isFitted",m_mcIndex,m_isFitted,5);
+            sc=m_tuple->addItem("isFitConverged",m_mcIndex,m_isFitConverged,5);
+            sc=m_tuple->addItem("isFitConvergedFully",m_mcIndex,
+                    m_isFitConvergedFully,5);
+            sc=m_tuple->addItem("fittedState",m_mcIndex,m_fittedState,5);
+            sc=m_tuple->addItem("nHitFailedKal",m_mcIndex,m_nHitFailedKal,5);
+            sc=m_tuple->addItem("nHitFitted",m_mcIndex,m_nHitFitted,5);
+            sc=m_tuple->addItem("nDCDigi",m_nDCDigi,0,50000);
+            sc=m_tuple->addItem("nHitKalInput",m_nHitKalInput,0,300000);
+            //10 is greater than # of tracking detectors
+            sc=m_tuple->addItem("hitDetID",10,m_nHitDetType);
+            sc=m_tuple->addItem("nHitWithFitInfo",m_mcIndex,m_nHitWithFitInfo,5);
+            sc=m_tuple->addItem("nSimDCHit",m_nSimDCHit,0,500000);
+            sc=m_tuple->addItem("mdcHitDriftT",m_nSimDCHit,m_mdcHitDriftT);
+            sc=m_tuple->addItem("mdcHitDriftDl",m_nSimDCHit,m_mdcHitDriftDl);
+            sc=m_tuple->addItem("mdcHitDriftDr",m_nSimDCHit,m_mdcHitDriftDr);
+            sc=m_tuple->addItem("mdcHitLr",m_nSimDCHit,m_mdcHitLr);
+            sc=m_tuple->addItem("mdcHitLayer",m_nSimDCHit,m_mdcHitLayer);
+            sc=m_tuple->addItem("mdcHitWire",m_nSimDCHit,m_mdcHitWire);
+            sc=m_tuple->addItem("mdcHitExpDoca",m_nSimDCHit,m_mdcHitExpDoca);
+            sc=m_tuple->addItem("mdcHitExpMcDoca",m_nSimDCHit,m_mdcHitExpMcDoca);
+            sc=m_tuple->addItem("mdcHitErr",m_nSimDCHit,m_mdcHitErr);
+            sc=m_tuple->addItem("exeTime",m_exeTime);
+            sc=m_tuple->addItem("mdcHitMcTkId",m_nSimDCHit,m_mdcHitMcTkId);
+            sc=m_tuple->addItem("mdcHitMcLr",m_nSimDCHit,m_mdcHitMcLr);
+            sc=m_tuple->addItem("mdcHitMcDrift",m_nSimDCHit,m_mdcHitMcDrift);
+            sc=m_tuple->addItem("mdcHitMcX",m_nSimDCHit,m_mdcHitMcX);
+            sc=m_tuple->addItem("mdcHitMcY",m_nSimDCHit,m_mdcHitMcY);
+            sc=m_tuple->addItem("mdcHitMcZ",m_nSimDCHit,m_mdcHitMcZ);
+            sc=m_tuple->addItem("mcPocaX",m_nSimDCHit,m_mdcHitExpMcPocaX);
+            sc=m_tuple->addItem("mcPocaY",m_nSimDCHit,m_mdcHitExpMcPocaY);
+            sc=m_tuple->addItem("mcPocaZ",m_nSimDCHit,m_mdcHitExpMcPocaZ);
+            sc=m_tuple->addItem("mcPocaWireY",m_nSimDCHit,m_mdcHitExpMcPocaWireY);
+            sc=m_tuple->addItem("mcPocaWireZ",m_nSimDCHit,m_mdcHitExpMcPocaWireZ);
+
+            sc=m_tuple->addItem("dcDigiChamber",m_nDCDigi,m_dcDigiChamber);
+            sc=m_tuple->addItem("dcDigiLayer",m_nDCDigi,m_dcDigiLayer);
+            sc=m_tuple->addItem("dcDigiCell",m_nDCDigi,m_dcDigiCell);
+            sc=m_tuple->addItem("dcDigiTime",m_nDCDigi,m_dcDigiTime);
+            sc=m_tuple->addItem("dcDigiDrift",m_nDCDigi,m_dcDigiDrift);
+            sc=m_tuple->addItem("dcDigiDocaMC",m_nDCDigi,m_dcDigiDocaMC);
+            sc=m_tuple->addItem("dcDigiPocaOnWireMCX",m_nDCDigi,m_dcDigiPocaOnWireMCX);
+            sc=m_tuple->addItem("dcDigiPocaOnWireMCY",m_nDCDigi,m_dcDigiPocaOnWireMCY);
+            sc=m_tuple->addItem("dcDigiWireStartX",m_nDCDigi,m_dcDigiWireStartX);
+            sc=m_tuple->addItem("dcDigiWireStartY",m_nDCDigi,m_dcDigiWireStartY);
+            sc=m_tuple->addItem("dcDigiWireStartZ",m_nDCDigi,m_dcDigiWireStartZ);
+            sc=m_tuple->addItem("dcDigiWireEndX",m_nDCDigi,m_dcDigiWireEndX);
+            sc=m_tuple->addItem("dcDigiWireEndY",m_nDCDigi,m_dcDigiWireEndY);
+            sc=m_tuple->addItem("dcDigiWireEndZ",m_nDCDigi,m_dcDigiWireEndZ);
+            sc=m_tuple->addItem("dcDigiMcMomX",m_nDCDigi,m_dcDigiMcMomX);
+            sc=m_tuple->addItem("dcDigiMcMomY",m_nDCDigi,m_dcDigiMcMomY);
+            sc=m_tuple->addItem("dcDigiMcMomZ",m_nDCDigi,m_dcDigiMcMomZ);
+            sc=m_tuple->addItem("dcDigiMcPosX",m_nDCDigi,m_dcDigiMcPosX);
+            sc=m_tuple->addItem("dcDigiMcPosY",m_nDCDigi,m_dcDigiMcPosY);
+            sc=m_tuple->addItem("dcDigiMcPosZ",m_nDCDigi,m_dcDigiMcPosZ);
+            sc=m_tuple->addItem("firstMomMc",m_firstMomMc);
+
+            sc=m_tuple->addItem("dcDigiDocaExt",m_nDCDigi,m_dcDigiDocaExt);
+            sc=m_tuple->addItem("dcDigiPocaExtX",m_nDCDigi,m_dcDigiPocaExtX);
+            sc=m_tuple->addItem("dcDigiPocaExtY",m_nDCDigi,m_dcDigiPocaExtY);
+            sc=m_tuple->addItem("dcDigiPocaExtZ",m_nDCDigi,m_dcDigiPocaExtZ);
+
+            sc=m_tuple->addItem("nTrackerHitDC",m_nTrackerHitDC,0,1000);
+            sc=m_tuple->addItem("trackLength",m_nTrackerHitDC,m_trackLength);
+            sc=m_tuple->addItem("hitMomEdep",m_nTrackerHitDC,m_hitMomEdep);
+            sc=m_tuple->addItem("truthMomedep",m_nTrackerHitDC,m_truthMomEdep);
+            sc=m_tuple->addItem("driftDis",m_nTrackerHitDC,m_driftDis);
+            sc=m_tuple->addItem("FittedDoca",m_nTrackerHitDC,m_FittedDoca);
+            sc=m_tuple->addItem("Res",m_nTrackerHitDC,m_Res);
+            sc=m_tuple->addItem("nTrackerHitSDT",m_nTrackerHitSDT);
+            sc=m_tuple->addItem("nGenFitTrackerHit",m_nGenFitTrackerHit);
+            debug()<< "Book tuple RecGenfitAlgSDT/recGenfitAlgSDT" << endmsg;
+        }else{
+            warning()<<"Tuple RecGenfitAlgSDT/recGenfitAlgSDT not booked"<<endmsg;
+        }
+    }//end of book tuple
+
+    //init genfit event display
+    if(m_showDisplay) m_genfitDisplay = genfit::EventDisplay::getInstance();
+//    time(&timep);
+//    std::cout << "Myliu say: the time is "
+//              << ctime(&timep)
+//              << "at the end of RecGenfitAlgSDT::initialize()"
+//              << std::endl;
+//    system("/scratchfs/bes/myliu/script/memory_rec.sh");
+
+    return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+StatusCode RecGenfitAlgSDT::execute()
+{
+    info()<<"RecGenfitAlgSDT in execute()"<<endmsg;
+//    time_t timep;
+//    time(&timep);
+//    std::cout << "Myliu say: the time is "
+//              << ctime(&timep)
+//              << "at the begin of RecGenfitAlgSDT::execute()"
+//              << std::endl;
+//    system("/scratchfs/bes/myliu/script/memory_rec.sh");
+
+    edm4hep::ReconstructedParticleCollection* sdtRecParticleCol=
+        m_SDTRecParticleCol.createAndPut();
+
+    edm4hep::TrackCollection* sdtRecTrackCol=
+        m_SDTRecTrackCol.createAndPut();
+
+    StatusCode sc=StatusCode::SUCCESS;
+
+    std::cout<<" RecGenfitAlgSDT execute eventNo  "<<m_eventNo<<std::endl;
+    if(m_debug&&(abs(m_eventNoSelection)<1e8)&&m_eventNo!=m_eventNoSelection){
+        ++m_eventNo;
+        return sc;
+    }
+    ++m_eventNo;
+
+    std::chrono::time_point<std::chrono::high_resolution_clock> start;
+    if(m_tuple) start=std::chrono::high_resolution_clock::now();
+
+    /////retrieve EventHeader
+    //auto header = _headerCol.get()->at(0);
+    //int evtNo = header.getEventNumber();
+    //int runNo = header.getRunNumber();
+    //info()<<"run "<<header.getEventNumber()
+    //  <<" "<<header.getRunNumber()<<std::endl;
+
+    ///retrieve silicon Track and TrackHits
+    const edm4hep::TrackCollection* sdtTrackCol=nullptr;
+    if(m_SDTTrackCol.exist())sdtTrackCol=m_SDTTrackCol.get();
+    if(nullptr==sdtTrackCol || sdtTrackCol->size()<=0) {
+        debug()<<"TrackCollection not found or sdtTrackCol size=0"<<endmsg;
+        return StatusCode::SUCCESS;
+    }
+
+    auto assoDCHitsCol=m_DCHitAssociationCol.get();
+    double eventStartTime=0;
+
+    const edm4hep::TrackerHitCollection* dCDigiCol=nullptr;
+    dCDigiCol=m_DCDigiCol.get();
+
+    const edm4hep::TrackCollection* dcTrackCol=nullptr;
+    if(m_dcTrackCol.exist()) dcTrackCol=m_dcTrackCol.get();
+    if(nullptr==dcTrackCol) {
+        debug()<<"TrackCollection not found"<<endmsg;
+        return StatusCode::SUCCESS;
+    }
+    const edm4hep::MCParticleCollection* mcParticleCol=nullptr;
+    mcParticleCol=m_mcParticleCol.get();//FIXME get error when call exist()
+    std::cout << " MCParticleCol size = " << mcParticleCol->size() << std::endl;
+    if(nullptr==mcParticleCol){
+        debug()<<"MCParticleCollection not found"<<endmsg;
+        return StatusCode::SUCCESS;
+    }
+    ///----------------------------------------------------
+    ///Loop over Track and do fitting for each track
+    ///----------------------------------------------------
+    m_firstTuple=true;
+    debug()<<"SDTTrackCol size="<<sdtTrackCol->size()<<endmsg;
+    int iSdtTrack = 0;
+    int nFittedSDT,nFittedDC,ngenfitHit;
+    std::vector<double> trackL;
+    std::vector<double> hitMom;
+    std::vector<float> truthMomEdep;
+    std::vector<double> driftDis;
+    std::vector<double> FittedDoca;
+    std::vector<double> Res;
+    for(auto sdtTrack: *sdtTrackCol)
+    {
+        ///Loop over 5 particle hypothesis(0-4): e,mu,pi,K,p
+        ///-1 for chargedgeantino
+        for(unsigned int pidType=0;pidType<m_nPDG;pidType++)
+        {
+            if((m_debugPid>=0) && (m_debugPid!=pidType)) continue;
+            debug()<<"processing pidType "<<pidType<<endmsg;
+            std::cout<<"processing pidType "<<pidType<<std::endl;
+            ///-----------------------------------
+            ///Create a GenFit track
+            ///-----------------------------------
+            GenfitTrack* genfitTrack=new GenfitTrack(m_genfitField,
+                    m_gridDriftChamber,m_geomSvc);
+            genfitTrack->setDebug(m_debug);
+            //if(m_useTruthTrack){
+            //    //single track only FIXME
+            //    if(!genfitTrack->createGenfitTrackFromMCParticle(pidType,
+            //                *(mcParticleCol->begin()), eventStartTime)){
+            //        debug()<<"createGenfitTrackFromMCParticle failed!"<<endmsg;
+            //        return StatusCode::SUCCESS;
+            //    }
+            //}else{
+std::cout << " sdtTrack size = " << sdtTrack.trackerHits_size() << std::endl;
+            if(!genfitTrack->createGenfitTrackFromEDM4HepTrack(pidType,
+                        sdtTrack, eventStartTime,m_isUseCovTrack)){
+                debug()<<"createGenfitTrackFromEDM4HepTrack from SDT track failed!"<<endmsg;
+                return StatusCode::SUCCESS;
+            }
+            //}
+
+            ///-----------------------------------
+            ///Add hits on track
+            ///-----------------------------------
+            if(m_debug) std::cout<<" m_measurementTypeSi "<<m_measurementTypeSi<<" "<<m_measurementTypeDC<<" "<<std::endl;
+            int nHitAdded=0;
+            //add silicon hits
+            if(0==m_measurementTypeSi.value()){
+                nHitAdded+=genfitTrack->addSpacePointsSi(sdtTrack,
+                        m_sigmaHitU,m_sigmaHitV);
+            }else if(1==m_measurementTypeSi.value()){
+                nHitAdded+=genfitTrack->addSiliconMeasurements(sdtTrack,
+                        m_sigmaHitU,m_sigmaHitV);
+            }
+
+            //add DC hits
+            if(0==m_measurementTypeDC.value()){
+                nHitAdded+=genfitTrack->addSpacePointsDC(sdtTrack,
+                        assoDCHitsCol,m_sigmaHitU,m_sigmaHitV);
+            }else if(1==m_measurementTypeDC.value()){
+                if(m_selectDCHit){
+                    std::vector<edm4hep::TrackerHit*> selectedHits;
+                    selectHits(sdtTrack,selectedHits);
+                    nHitAdded+=genfitTrack->addWireMeasurementsFromList(selectedHits,
+                            m_sigmaHitU[0],assoDCHitsCol,m_sortMethod,m_truthAmbig,
+                            m_skipCorner,m_skipNear);//mm
+                    std::vector<edm4hep::TrackerHit*> tmp;
+                    selectedHits.swap(tmp);
+                }else{
+                    if(m_useNoiseDCHit){
+                        nHitAdded+=genfitTrack->addWireMeasurementsOnTrack(sdtTrack,
+                                m_sigmaHitU[0],r_NoiseAssociationCol.get(),m_sortMethod,m_truthAmbig,
+                                m_skipCorner,m_skipNear);//mm
+                     } else {
+                        //nHitAdded+=genfitTrack->addWireMeasurementsOnTrack(sdtTrack,
+                        //        m_sigmaHitU[0],assoDCHitsCol,m_sortMethod,m_truthAmbig,
+                        //        m_skipCorner,m_skipNear);//mm
+                        nHitAdded+=genfitTrack->addWireMeasurementsOnTrack(sdtTrack,
+                                m_sigmaHitU[0],r_SmearAssociationCol.get(),m_sortMethod,m_truthAmbig,
+                                m_skipCorner,m_skipNear);//mm
+                     }
+                }
+            }
+
+
+            // skip events w.o hits
+            if(0==nHitAdded){
+                debug()<<m_eventNo<<" No hit added to track!"<<endmsg;
+                return StatusCode::SUCCESS;
+            }
+            if(m_debug) genfitTrack->printSeed();
+
+            ///-----------------------------------
+            ///call genfit fitting procedure
+            ///-----------------------------------
+            m_genfitFitter->setDebug(m_debug);
+            m_genfitFitter->setDebugGenfit(m_debugGenfit);
+            m_genfitFitter->processTrack(genfitTrack,m_resortHits.value());
+
+            ///----------------------------------
+            ///Get TrackLength
+            ///---------------------------------
+            //TVector3 pos, TVector3 mom;
+            //double tracklength = genfitTrack->extrapolateToCylinder();
+
+            ///-----------------------------------
+            ///Store track
+            ///-----------------------------------
+            auto dcRecParticle=sdtRecParticleCol->create();
+            auto dcRecTrack=sdtRecTrackCol->create();
+
+            TVector3 pocaToOrigin_pos,pocaToOrigin_mom;
+            TMatrixDSym pocaToOrigin_cov;
+            edm4hep::TrackState pocaToOrigin_trackState;
+            if(!genfitTrack->storeTrack(dcRecParticle,dcRecTrack,
+                        pocaToOrigin_pos,pocaToOrigin_mom,pocaToOrigin_cov,
+                        pidType,m_ndfCut,m_chi2Cut,nFittedDC,nFittedSDT,
+                        ngenfitHit,trackL,hitMom,truthMomEdep,assoDCHitsCol,
+                        driftDis,FittedDoca,Res)){
+                debug()<<"Fitting failed!"<<std::endl;
+            }else{
+                ++m_fitSuccess[pidType];
+            }
+
+            if(m_tuple) debugTrack(iSdtTrack,pidType,genfitTrack,pocaToOrigin_pos,
+                    pocaToOrigin_mom,pocaToOrigin_cov);
+            if(m_showDisplay) {
+                m_genfitDisplay->addEvent(genfitTrack->getTrack());
+                m_genfitDisplay->open();
+
+                using namespace std::chrono_literals;
+                std::this_thread::sleep_for(1000000000ms);
+                system("pause");
+            }else{
+                delete genfitTrack;
+            }
+        }//end loop over particle type
+        ++iSdtTrack;
+    }//end loop over a track
+    m_nRecTrack++;
+
+    if(m_tuple) {
+        m_nTrackerHitDC = nFittedDC;
+        m_nTrackerHitSDT = nFittedSDT;
+        m_nGenFitTrackerHit = ngenfitHit;
+        for(int i=0;i<trackL.size();i++) m_trackLength[i] = trackL[i];
+        for(int i=0;i<hitMom.size();i++) m_hitMomEdep[i] = hitMom[i];
+        for(int i=0;i<truthMomEdep.size();i++) m_truthMomEdep[i] = truthMomEdep[i];
+        for(int i=0;i<driftDis.size();i++) m_driftDis[i] = driftDis[i];
+        for(int i=0;i<FittedDoca.size();i++) m_FittedDoca[i] = FittedDoca[i];
+        for(int i=0;i<Res.size();i++) m_Res[i] = Res[i];
+        auto finish = std::chrono::high_resolution_clock::now();
+        std::chrono::duration<double> elapsed = finish - start;
+        debug() << "Elapsed time: " << elapsed.count() << " s"<<endmsg;
+        m_exeTime=elapsed.count();
+        debugEvent(sdtTrackCol,sdtRecTrackCol,eventStartTime,nFittedSDT);
+    }
+
+
+
+    //if(m_genfitDisplay) while(1){
+    //    std::cout<<"Press any key to finish..."<<std::endl;
+    //    //system ("pause");
+    //}
+
+
+    if(m_tuple) sc=m_tuple->write();
+
+    //    time(&timep);
+    //    std::cout << "Myliu say: the time is "
+    //              << ctime(&timep)
+    //              << "at the end of RecGenfitAlgSDT::execute()"
+    //              << std::endl;
+    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
+
+    return StatusCode::SUCCESS;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+StatusCode RecGenfitAlgSDT::finalize()
+{
+    MsgStream log(msgSvc(), name());
+    info()<< " RecGenfitAlgSDT in finalize()" << endmsg;
+
+    m_genfitFitter->writeHist();
+    delete m_genfitFitter;
+    info()<<"RecGenfitAlgSDT nRecTrack="<<m_nRecTrack<<" success e "
+        <<m_fitSuccess[0]<<" mu "<<m_fitSuccess[1]<<" pi "<<m_fitSuccess[2]
+        <<" K "<<m_fitSuccess[3]<<" p "<<m_fitSuccess[4]<<std::endl;
+    if(m_nRecTrack>0){
+        std::cout<<"RecGenfitAlgSDT Success rate = "<<std::endl;
+        for (int i=0;i<5;i++){
+            std::cout<<Form("%d: %d/%d= %2.2f",i,m_fitSuccess[i],m_nRecTrack,
+                    ((float) m_fitSuccess[i])/m_nRecTrack)<<std::endl;
+        }
+    }
+    return StatusCode::SUCCESS;
+}
+
+void RecGenfitAlgSDT::debugTrack(int iStrack,int pidType,const GenfitTrack* genfitTrack,
+        TVector3 pocaToOrigin_pos,TVector3 pocaToOrigin_mom,
+        TMatrixDSym pocaToOrigin_cov)
+{
+
+    //    time_t timep;
+    //    time(&timep);
+    //    std::cout << "Myliu say: the time is "
+    //              << ctime(&timep)
+    //              << "at the begin of debugTrack()"
+    //              << std::endl;
+    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
+
+    /// Get fit status
+    const genfit::FitStatus* fitState = genfitTrack->getFitStatus();
+    int charge= fitState->getCharge();
+
+    if(m_firstTuple){
+        m_nHitKalInput=genfitTrack->getNumPoints();
+        debug()<<"m_nHitKalInput "<<m_nHitKalInput<<endmsg;
+        //FIXME read from config file
+        if(m_debug) {
+            debug()<<"detType nHot: ";
+        }
+        int detIDs[5]={1,2,3,4,5};//VXD=1,SIT=2,SET=5;FTD=3,
+        for(int i=0;i<5;i++){
+            m_nHitDetType[detIDs[i]]=genfitTrack->getNumPointsDet(detIDs[i]);
+            if(m_debug){
+                debug()<<" "<<detIDs[i]<<"="<<m_nHitDetType[detIDs[i]]<<", ";
+            }
+        }
+        if(m_debug) { debug()<<endmsg; }
+        m_firstTuple=false;
+    }
+    m_chargeKal[iStrack][pidType]= charge;
+    m_nHitWithFitInfo[iStrack][pidType]=genfitTrack->getNumPointsWithFittedInfo();
+    m_chi2Kal[iStrack][pidType]=fitState->getChi2();
+    m_nDofKal[iStrack][pidType]=fitState->getNdf();
+    m_isFitted[iStrack][pidType]=(int)fitState->isFitted();
+    m_isFitConverged[iStrack][pidType]=(int) fitState->isFitConverged();
+    m_isFitConvergedFully[iStrack][pidType]=(int) fitState->isFitConvergedFully();
+
+    ///get fitted state of track
+    TMatrixDSym fittedCov;
+    TLorentzVector fittedPos;
+    TVector3 fittedMom;
+    int fittedState=genfitTrack->getFittedState(fittedPos,fittedMom,fittedCov);
+    const TLorentzVector seedPos=genfitTrack->getSeedStatePos();
+    const TVector3 seedMom=genfitTrack->getSeedStateMom();
+    m_fittedState[iStrack][pidType]=fittedState;
+    HelixClass helix;//mm and GeV
+    HelixClass helix_origin;//mm and GeV
+
+
+    double pos[3]={(fittedPos.X()/dd4hep::mm),(fittedPos.Y()/dd4hep::mm),
+        (fittedPos.Z()/dd4hep::mm)};
+    double mom[3]={(fittedMom.X()),(fittedMom.Y()),(fittedMom.Z())};
+
+    m_posx[iStrack] = fittedPos.X();
+    m_posy[iStrack] = fittedPos.Y();
+    m_posz[iStrack] = fittedPos.Z();
+
+    m_momx[iStrack] = fittedMom.X();
+    m_momy[iStrack] = fittedMom.Y();
+    m_momz[iStrack] = fittedMom.Z();
+
+    m_PosMcX[iStrack] = seedPos.X();
+    m_PosMcY[iStrack] = seedPos.Y();
+    m_PosMcZ[iStrack] = seedPos.Z();
+
+    m_MomMcX[iStrack] = seedMom.X();
+    m_MomMcY[iStrack] = seedMom.Y();
+    m_MomMcZ[iStrack] = seedMom.Z();
+
+    m_PocaPosX[iStrack] = pocaToOrigin_pos.X()*dd4hep::mm;
+    m_PocaPosY[iStrack] = pocaToOrigin_pos.Y()*dd4hep::mm;
+    m_PocaPosZ[iStrack] = pocaToOrigin_pos.Z()*dd4hep::mm;
+
+    m_PocaMomX[iStrack] = pocaToOrigin_mom.X();
+    m_PocaMomY[iStrack] = pocaToOrigin_mom.Y();
+    m_PocaMomZ[iStrack] = pocaToOrigin_mom.Z();
+
+    for(int i=0;i<6;i++)
+    {
+        m_ErrorcovMatrix6[iStrack][i] = fittedCov(i,i);
+        m_PocaErrCov[iStrack][i] = pocaToOrigin_cov(i,i);
+    }
+
+    double pocaToOrigin_Pos[3] = {pocaToOrigin_pos.X(),pocaToOrigin_pos.Y(),pocaToOrigin_pos.Z()};
+    double pocaToOrigin_Mom[3] = {pocaToOrigin_mom.X(),pocaToOrigin_mom.Y(),pocaToOrigin_mom.Z()};
+    TLorentzVector pocaToOrigin_POS;
+    pocaToOrigin_POS.SetXYZT(pocaToOrigin_pos.X()*dd4hep::mm,pocaToOrigin_pos.Y()*dd4hep::mm,
+            pocaToOrigin_pos.Z()*dd4hep::mm,999);
+    helix.Initialize_VP(pos,mom,charge,m_genfitField->getBz(fittedPos.Vect())/GenfitUnit::tesla);
+    helix_origin.Initialize_VP(pocaToOrigin_Pos,pocaToOrigin_Mom,charge,m_genfitField->getBz(pocaToOrigin_POS.Vect())/GenfitUnit::tesla);
+    m_pocaMomKalP[iStrack][pidType]=fittedMom.Mag();
+
+    TMatrixDSym covMatrix_6=pocaToOrigin_cov;
+    for(int i=0;i<5;i++){
+        covMatrix_6[0][i]=pocaToOrigin_cov[0][i]/dd4hep::mm;//d0 column
+        covMatrix_6[1][i]=pocaToOrigin_cov[1][i]/dd4hep::mm;//omega column
+        covMatrix_6[2][i]=pocaToOrigin_cov[2][i]/dd4hep::mm;//z0 column
+        covMatrix_6[i][0]=pocaToOrigin_cov[i][0]/dd4hep::mm;//d0 row
+        covMatrix_6[i][1]=pocaToOrigin_cov[i][1]/dd4hep::mm;//omega row
+        covMatrix_6[i][2]=pocaToOrigin_cov[i][2]/dd4hep::mm;//z0 row
+    }
+    edm4hep::TrackState trackState_Origin;
+    CEPC::getTrackStateFromPosMom(trackState_Origin,m_genfitField->getBz(pocaToOrigin_POS.Vect())/GenfitUnit::tesla,pocaToOrigin_pos,
+            pocaToOrigin_mom,charge,covMatrix_6);
+    std::array<float,15> errorCov_Origin;
+    errorCov_Origin = trackState_Origin.covMatrix;
+    for(int j=0; j<15; j++) {
+        m_ErrorcovMatrix_Origin[iStrack][j] = errorCov_Origin[j];
+    }
+    m_D0_Origin[iStrack] = helix_origin.getD0();
+    m_phi_Origin[iStrack] = helix_origin.getPhi0();
+    m_omega_Origin[iStrack] = helix_origin.getOmega();
+    m_Z0_Origin[iStrack] = helix_origin.getZ0();
+    m_tanLambda_Origin[iStrack] = helix_origin.getTanLambda();
+
+    m_evt=m_eventNo;
+    /// Get fit status
+    if((0!=fittedState)||(!m_isFitted[pidType])||(m_nDofKal[iStrack][pidType]>m_ndfCut)){
+        debug()<<"evt "<<m_evt<<" fit FAILED !!"
+            <<pidType<<" fittedState "<<fittedState<<" isFitted "
+            <<m_isFitted[pidType]<<" isConverged "<<m_isFitConverged[pidType]
+            <<" isFitConvergedFully "<<m_isFitConvergedFully[pidType]<<endmsg;
+    }else{
+        debug()<<"==fit result evt "<<m_evt<<" pidType "<<pidType<<" pos("<<
+            fittedPos.X()<<" "<<
+            fittedPos.Y()<<" "<<
+            fittedPos.Z()<<")cm mom("<<
+            fittedMom.X()<<" "<<
+            fittedMom.Y()<<" "<<
+            fittedMom.Z()<<") p_tot "<<
+            fittedMom.Mag()<<" pt "<<
+            fittedMom.Perp()
+            <<" fittedState "<<fittedState<<" isFitted "
+            <<m_isFitted[pidType]<<" isConverged "<<m_isFitConverged[pidType]
+            <<" isFitConvergedFully "<<m_isFitConvergedFully[pidType]
+            <<" ndf "<<m_nDofKal[iStrack][pidType]
+            <<" chi2 "<<m_chi2Kal[pidType]<<endmsg;
+    }
+    //    time(&timep);
+    //    std::cout << "Myliu say: the time is "
+    //              << ctime(&timep)
+    //              << "at the end of debugTrack()"
+    //              << std::endl;
+    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
+}
+
+void RecGenfitAlgSDT::debugEvent(const edm4hep::TrackCollection* sdtTrackCol,
+        const edm4hep::TrackCollection* sdtRecTrackCol,
+        double eventStartTime,int nFittedSDT)
+{
+
+    //    time_t timep;
+    //    time(&timep);
+    //    std::cout << "Myliu say: the time is "
+    //              << ctime(&timep)
+    //              << "at the begin of debugEvent()"
+    //              << std::endl;
+    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
+
+
+    int iSdtTrack=0;
+    m_nSdtTrack=sdtTrackCol->size();
+    for(auto sdtTrack: *sdtTrackCol){
+        m_nSdtTrackHit = sdtTrack.trackerHits_size();
+        for(int ihit=0;ihit<sdtTrack.trackerHits_size();ihit++){
+            edm4hep::TrackerHit sdtTrackHit = sdtTrack.getTrackerHits(ihit);
+        }
+
+        //if(iSdtTrack>0) break;//TODO debug for some track only
+        edm4hep::TrackState trackStat=sdtTrack.getTrackStates(0);//FIXME?
+        HelixClass helixClass;
+        helixClass.Initialize_Canonical(trackStat.phi,trackStat.D0,
+                trackStat.Z0,trackStat.omega,trackStat.tanLambda,
+                m_genfitField->getBz({0.,0.,0.})/GenfitUnit::tesla);
+
+        TLorentzVector posInit(helixClass.getReferencePoint()[0],
+                helixClass.getReferencePoint()[1],
+                helixClass.getReferencePoint()[2],eventStartTime);
+        m_seedPos[iSdtTrack][0]=posInit.X();
+        m_seedPos[iSdtTrack][1]=posInit.Y();
+        m_seedPos[iSdtTrack][2]=posInit.Z();
+        TVector3 momInit(helixClass.getMomentum()[0],
+                helixClass.getMomentum()[1],helixClass.getMomentum()[2]);
+        m_seedMomP[iSdtTrack]=momInit.Mag();
+        m_seedMomPt[iSdtTrack]=momInit.Perp();
+        m_seedMom[iSdtTrack][0]=momInit.X();
+        m_seedMom[iSdtTrack][1]=momInit.Y();
+        m_seedMom[iSdtTrack][2]=momInit.Z();
+        TVector3 pos,mom;
+        TMatrixDSym cov(6);
+        double charge;
+        CEPC::getPosMomFromTrackState(trackStat,
+                m_genfitField->getBz({0.,0.,0.})/GenfitUnit::tesla,pos,mom,charge,cov);
+        for(int i =0;i<6;i++)
+        {
+            m_McErrCov[iSdtTrack][i] = cov(i,i);
+        }
+        m_seedMomQ[iSdtTrack]=charge;
+        iSdtTrack++;
+    }
+
+    const edm4hep::MCParticleCollection* mcParticleCol = nullptr;
+    const edm4hep::SimTrackerHitCollection* simHitCol=nullptr;
+
+    m_pidIndex=5;
+
+    mcParticleCol=m_mcParticleCol.get();
+    int iMcParticle=0;
+    HelixClass helix_mcP;
+    for(auto mcParticle : *mcParticleCol){
+        edm4hep::Vector3f mcPocaMom = mcParticle.getMomentum();//GeV
+        edm4hep::Vector3d mcPocaPos = mcParticle.getVertex();
+
+        double mcPos[3]={(mcPocaPos.x),(mcPocaPos.y),(mcPocaPos.z)};
+        double mcMom[3]={(mcPocaMom.x),(mcPocaMom.y),(mcPocaMom.z)};
+        //for(int i=0;i<3;i++){debug()<<"mcPos "<<mcPos[i]<<endmsg;}
+        //for(int i=0;i<3;i++){debug()<<"mcMom "<<mcMom[i]<<endmsg;}
+        float mcCharge = mcParticle.getCharge();
+        helix_mcP.Initialize_VP(mcPos,mcMom,mcCharge,
+                m_genfitField->getBz(mcPos)/GenfitUnit::tesla);
+
+        mcP_D0[iMcParticle] = helix_mcP.getD0();
+        mcP_phi[iMcParticle] = helix_mcP.getPhi0();
+        mcP_omega[iMcParticle] = helix_mcP.getOmega();
+        mcP_Z0[iMcParticle] = helix_mcP.getZ0();
+        mcP_tanLambda[iMcParticle] = helix_mcP.getTanLambda();
+
+        debug()<< "debugEvent Bz " << m_genfitField->getBz(mcPos)/GenfitUnit::tesla
+            << "Tesla mc d0= " << mcP_D0
+            << " phi0= " << mcP_phi
+            << " omega= " << mcP_omega
+            << " Z0= " << mcP_Z0
+            << " tanLambda= " << mcP_tanLambda << endmsg;
+
+        float px=mcPocaMom.x;
+        float py=mcPocaMom.y;
+        float pz=mcPocaMom.z;
+        debug()<<"mc pos("<<mcPos[0]<<","<<mcPos[1]<<","<<mcPos[2]
+            <<") pxyz("<<px<<","<<py<<","<<pz<<") p"<<sqrt(px*px+py*py+pz*pz)
+            <<endmsg;
+        m_pocaMomMcP[iMcParticle]=sqrt(px*px+py*py+pz*pz);
+        m_pocaMomMcPt[iMcParticle]=sqrt(px*px+py*py);
+        m_pocaMomMc[iMcParticle][0]=px;
+        m_pocaMomMc[iMcParticle][1]=py;
+        m_pocaMomMc[iMcParticle][2]=pz;
+        iMcParticle++;
+    }
+    m_mcIndex=iMcParticle;
+
+    int iHit=0;
+    simHitCol=m_simDCHitCol.get();
+    for(auto simHit: *simHitCol){
+        edm4hep::Vector3d pos=simHit.getPosition();
+        TVectorD p(3);
+        p[0]=pos.x;//no unit conversion here
+        p[1]=pos.y;
+        p[2]=pos.z;
+        m_mdcHitMcX[iHit]=pos.x;
+        m_mdcHitMcY[iHit]=pos.y;
+        m_mdcHitMcZ[iHit]=pos.z;
+        iHit++;
+    }
+    m_nSimDCHit=simHitCol->size();
+
+    m_nSdtRecTrack=sdtRecTrackCol->size();
+    int isdttrack=0;
+    for(auto sdtRecTrack: *sdtRecTrackCol){
+        std::cout << " sdtRecTrack.trackerHits_size() = " << sdtRecTrack.trackerHits_size() << std::endl;
+        for(int iHit=0;iHit<sdtRecTrack.trackerHits_size();iHit++)
+        {
+            edm4hep::TrackerHit sdtRecTrackHit = sdtRecTrack.getTrackerHits(iHit);
+            //std::cout << " sdtRecTrackHit eDep = " << sdtRecTrackHit.getEDep() << std::endl;
+
+        }
+        for(unsigned int i=0; i<sdtRecTrack.trackStates_size(); i++) {
+            edm4hep::TrackState trackStat=sdtRecTrack.getTrackStates(i);
+            std::array<float,15> errorCov;
+            errorCov = trackStat.covMatrix;
+            for(int j=0; j<15; j++) {
+                m_ErrorcovMatrix[isdttrack][j] = errorCov[j];
+                if(m_debug)debug()<<"errorCov "<<j<<" "<<errorCov[j]<<endmsg;
+            }
+            m_D0[isdttrack] = trackStat.D0;
+            m_phi[isdttrack] = trackStat.phi;
+            m_omega[isdttrack] = trackStat.omega;
+            m_Z0[isdttrack] = trackStat.Z0;
+            m_tanLambda[isdttrack] = trackStat.tanLambda;
+        }
+        ++isdttrack;
+    }
+
+    //debug digi
+    const edm4hep::TrackerHitCollection* dCDigiCol=nullptr;
+    dCDigiCol=m_DCDigiCol.get();
+    if(nullptr!=dCDigiCol){ m_nDCDigi=dCDigiCol->size(); }
+    int iDCDigi=0;
+    for(auto dcDigi: *dCDigiCol){
+        m_dcDigiChamber[iDCDigi]=m_decoder->get(dcDigi.getCellID(),"chamber");
+        m_dcDigiLayer[iDCDigi]=m_decoder->get(dcDigi.getCellID(),"layer");
+        m_dcDigiCell[iDCDigi]=m_decoder->get(dcDigi.getCellID(),"cellID");
+        m_dcDigiTime[iDCDigi]=dcDigi.getTime();
+        m_dcDigiDrift[iDCDigi]=dcDigi.getTime()*m_driftVelocity.value()/10000.; //cm
+        TVector3 endPointStart(0,0,0);
+        TVector3 endPointEnd(0,0,0);
+        m_gridDriftChamber->cellposition(dcDigi.getCellID(),endPointStart,
+                endPointEnd);
+        m_dcDigiWireStartX[iDCDigi]=endPointStart.X();
+        m_dcDigiWireStartY[iDCDigi]=endPointStart.Y();
+        m_dcDigiWireStartZ[iDCDigi]=endPointStart.Z();
+        m_dcDigiWireEndX[iDCDigi]=endPointEnd.X();
+        m_dcDigiWireEndY[iDCDigi]=endPointEnd.Y();
+        m_dcDigiWireEndZ[iDCDigi]=endPointEnd.Z();
+
+
+
+        //get information from associated simTrackerHit
+        //edm4hep::SimTrackerHit dcSimTrackerHit;
+        auto dcSimTrackerHit=CEPC::getAssoClosestSimTrackerHit(m_DCHitAssociationCol.get(),dcDigi,m_gridDriftChamber,0);
+        //const edm4hep::MCRecoTrackerAssociationCollection* assoHits=m_DCHitAssociationCol.get();
+        m_dcDigiMcMomX[iDCDigi]=dcSimTrackerHit.getMomentum().x*GenfitUnit::GeV;
+        m_dcDigiMcMomY[iDCDigi]=dcSimTrackerHit.getMomentum().y*GenfitUnit::GeV;
+        m_dcDigiMcMomZ[iDCDigi]=dcSimTrackerHit.getMomentum().z*GenfitUnit::GeV;
+        m_dcDigiMcPosX[iDCDigi]=dcSimTrackerHit.getPosition().x*GenfitUnit::mm;
+        m_dcDigiMcPosY[iDCDigi]=dcSimTrackerHit.getPosition().y*GenfitUnit::mm;
+        m_dcDigiMcPosZ[iDCDigi]=dcSimTrackerHit.getPosition().z*GenfitUnit::mm;
+        m_dcDigiDocaMC[iDCDigi]=dcDigi.getTime()*m_driftVelocity.value()/10000.;//cm
+        TVector3 pocaOnWire=m_gridDriftChamber->wirePos_vs_z(dcDigi.getCellID(),
+                dcSimTrackerHit.getPosition().z*dd4hep::mm);
+        m_dcDigiPocaOnWireMCX[iDCDigi]=pocaOnWire.X();
+        m_dcDigiPocaOnWireMCY[iDCDigi]=pocaOnWire.Y();
+        double firstMom=sqrt(dcSimTrackerHit.getMomentum().x*
+                dcSimTrackerHit.getMomentum().x+dcSimTrackerHit.getMomentum().y
+                *dcSimTrackerHit.getMomentum().y+dcSimTrackerHit.getMomentum().z
+                *dcSimTrackerHit.getMomentum().z);
+        if(0==m_decoder->get(dcDigi.getCellID(),"layer")){
+            m_firstMomMc=firstMom;
+            if(m_debug.value()>0){
+                std::cout<<" firstMomMc "<<firstMom<<" ("
+                    <<dcSimTrackerHit.getMomentum().x<<","
+                    <<dcSimTrackerHit.getMomentum().y
+                    <<","<<dcSimTrackerHit.getMomentum().z<<")"<<std::endl;
+            }
+        }
+        if(m_debug) std::cout<<"digi "<<iDCDigi<<" ("
+            <<m_decoder->get(dcDigi.getCellID(),"layer")<<","
+                <<m_decoder->get(dcDigi.getCellID(),"cellID")<<") truth mom GeV"
+                <<firstMom<<" "<<dcSimTrackerHit.getMomentum().x<<" "
+                <<dcSimTrackerHit.getMomentum().y<<" "
+                <<dcSimTrackerHit.getMomentum().z<<" truth pos "
+                <<dcSimTrackerHit.getPosition().x*GenfitUnit::mm<<" "
+                <<dcSimTrackerHit.getPosition().y*GenfitUnit::mm<<" "
+                <<dcSimTrackerHit.getPosition().z*GenfitUnit::mm<<"cm truth doca "
+                <<dcDigi.getTime()*m_driftVelocity.value()/10000.<<" cm"
+                <<std::endl;//yzhang debug
+
+        iDCDigi++;
+    }
+    //    time(&timep);
+    //    std::cout << "Myliu say: the time is "
+    //              << ctime(&timep)
+    //              << "at the end of debugEvent()"
+    //              << std::endl;
+    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
+}
+
+void RecGenfitAlgSDT::selectHits(const edm4hep::Track&,
+        std::vector<edm4hep::TrackerHit*>& dcDigiSelected)
+{
+
+    //    time_t timep;
+    //    time(&timep);
+    //    std::cout << "Myliu say: the time is "
+    //              << ctime(&timep)
+    //              << "at the begin of selectHits()"
+    //              << std::endl;
+    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
+
+
+    //for single track only, FIXME
+    double eventStartTime=0;
+    unsigned int pidType=1;//mu
+    GenfitTrack* genfitTrack=new GenfitTrack(m_genfitField,
+            m_gridDriftChamber,m_geomSvc);
+    genfitTrack->setDebug(m_debug);
+    const edm4hep::MCParticleCollection* mcParticleCol=nullptr;
+    mcParticleCol=m_mcParticleCol.get();//FIXME get error when call exist()
+    if(genfitTrack->createGenfitTrackFromMCParticle(
+                pidType,*(mcParticleCol->begin()),
+                eventStartTime)){
+        const edm4hep::TrackerHitCollection* dCDigiCol=nullptr;
+        dCDigiCol=m_DCDigiCol.get();
+        int iDCDigi=0;
+        for(auto dcDigi:*dCDigiCol){
+            TVector3 poca,pocaDir,pocaOnWire;
+
+            double docaExt=1e9;
+            bool stopAtBoundary=false;
+            bool calcJacobianNoise=true;
+            //for(auto mcParticle : *mcParticleCol){
+            //}
+            edm4hep::MCParticle mcParticle=*(mcParticleCol->begin());//FIXME single track only
+
+            genfitTrack->extrapolateToHit(poca,pocaDir,pocaOnWire,docaExt,
+                    mcParticle,dcDigi.getCellID(),pidType,stopAtBoundary,calcJacobianNoise);
+            m_dcDigiDocaExt[iDCDigi]=docaExt;
+            m_dcDigiPocaExtX[iDCDigi]=poca.X();
+            m_dcDigiPocaExtY[iDCDigi]=poca.Y();
+            m_dcDigiPocaExtZ[iDCDigi]=poca.Z();
+            double docaMC=dcDigi.getTime()*m_driftVelocity.value()/10000.;//cm
+            auto dcSimTrackerHit=CEPC::getAssoClosestSimTrackerHit(
+                    m_DCHitAssociationCol.get(),dcDigi,m_gridDriftChamber,0);
+
+            debug()<<" CellID "<<dcDigi.getCellID()<<"select hit ("
+                <<m_decoder->get(dcDigi.getCellID(),"layer")
+                <<","<<m_decoder->get(dcDigi.getCellID(),"cellID")
+                <<") by extdoca:"<<docaExt<<"- docaMC:"<<docaMC<<" deltaDoca "
+                <<fabs(docaExt-docaMC)<<" cut "<<m_docaCut
+                <<" pocaOnWire ("<<pocaOnWire.X()<<","<<pocaOnWire.Y()
+                <<","<<pocaOnWire.Z()<<") truthPos("
+                <<dcSimTrackerHit.getPosition().x/10.<<","
+                <<dcSimTrackerHit.getPosition().y/10.<<","
+                <<dcSimTrackerHit.getPosition().z/10.<<") diffZ "
+                <<dcSimTrackerHit.getPosition().z/10.-pocaOnWire.Z()<<endmsg;
+            if(fabs(docaExt-docaMC)>m_docaCut*GenfitUnit::mm){
+                debug()<<"Skip hit delta doca "<<fabs(docaExt-docaMC)<<endmsg;
+                continue;
+            }
+            edm4hep::TrackerHit* thisDigi = new edm4hep::TrackerHit(dcDigi);
+            dcDigiSelected.push_back(thisDigi);
+            iDCDigi++;
+        }//end loop over digi
+        if(m_debug>0){
+            std::cout<<"selectHits "<<dCDigiCol->size()
+                <<" after "<<iDCDigi<<std::endl;
+        }
+    }//end loop over track
+    delete genfitTrack;
+    //    time(&timep);
+    //    std::cout << "Myliu say: the time is "
+    //              << ctime(&timep)
+    //              << "at the end of selectHits()"
+    //              << std::endl;
+    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
+}//end of select hit
diff --git a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.h b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.h
new file mode 100644
index 000000000..7387ea870
--- /dev/null
+++ b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.h
@@ -0,0 +1,372 @@
+//////////////////////////////////////////////////////////////////////
+///
+/// This is an algorithm for track fitting for CEPC track with genfit.
+///
+/// In this file, including:
+///   An algorithm for combined silicon and drift chamber track fitting
+///   with genfit for 5 particle hypothesis
+///
+///   Units are following DD4hepUnits
+///
+/// Authors:
+///   Yao ZHANG(zhangyao@ihep.ac.cn)
+///
+/////////////////////////////////////////////////////////////////////
+
+#ifndef RECGENFITALG_RECGENFITALGSDT_H
+#define RECGENFITALG_RECGENFITALGSDT_H
+
+#include "GaudiAlg/GaudiAlgorithm.h"
+#include "GaudiKernel/NTuple.h"
+#include "k4FWCore/DataHandle.h"
+#include "DD4hep/Fields.h"
+#include <string>
+#include <vector>
+#include "AbsKalmanFitter.h"
+
+class GenfitFitter;
+class GenfitField;
+class GenfitTrack;
+class IGeomSvc;
+class time;
+namespace genfit{
+    class EventDisplay;
+}
+namespace dd4hep {
+    class Detector;
+    //class rec::CellIDPositionConverter;
+    namespace DDSegmentation{
+        class GridDriftChamber;
+        class BitFieldCoder;
+    }
+}
+namespace edm4hep{
+    class EventHeaderCollection;
+    class MCParticleCollection;
+    class SimTrackerHitCollection;
+    class TrackCollection;
+    class TrackerHitCollection;
+    class MCRecoTrackerAssociationCollection;
+    class ReconstructedParticle;
+    class MutableReconstructedParticle;
+    class ReconstructedParticleCollection;
+    class MutableReconstructedParticleCollection;
+    class TrackerHit;
+    class Track;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+class RecGenfitAlgSDT:public GaudiAlgorithm {
+    public:
+        RecGenfitAlgSDT (const std::string& name, ISvcLocator* pSvcLocator);
+        StatusCode initialize() override; StatusCode execute() override; StatusCode finalize() override;
+
+    private:
+        GenfitFitter* m_genfitFitter;//The pointer to a GenfitFitter
+        const GenfitField* m_genfitField;//The pointer to a GenfitField
+
+        void debugTrack(int iStrack,int pidType,const GenfitTrack* genfitTrack,
+                        TVector3 pocaToOrigin_pos,TVector3 pocaToOrigin_mom,
+                        TMatrixDSym pocaToOrigin_cov);
+        void debugEvent(const edm4hep::TrackCollection* sdtTrackCol,
+                const edm4hep::TrackCollection* sdtRecTrackCol,
+                double eventStartTime,int nFittedSDT);
+
+        void selectHits(const edm4hep::Track&, std::vector<edm4hep::TrackerHit*>& dcDigiSelected);
+
+        DataHandle<edm4hep::EventHeaderCollection> m_headerCol{
+            "EventHeaderCol", Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::TrackerHitCollection> m_DCDigiCol{
+            "DigiDCHitCollection", Gaudi::DataHandle::Reader, this};
+        //Mc truth
+        DataHandle<edm4hep::SimTrackerHitCollection> m_simVXDHitCol{
+            "VXDCollection", Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::SimTrackerHitCollection> m_simSETHitCol{
+            "SETCollection", Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::SimTrackerHitCollection> m_simSITHitCol{
+            "SITCollection", Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::SimTrackerHitCollection> m_simFTDHitCol{
+            "FTDCollection", Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::MCParticleCollection> m_mcParticleCol{
+            "MCParticle", Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::SimTrackerHitCollection> m_simDCHitCol{
+            "DriftChamberHitsCollection" , Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::MCRecoTrackerAssociationCollection>
+            m_DCHitAssociationCol{"DCHitAssociationCollection",
+                Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::TrackCollection> m_dcTrackCol{
+            "DCTrackCollection", Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::MCRecoTrackerAssociationCollection>
+            m_VXDHitAssociationCol{"VXDTrackerHitAssociation",
+                Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::MCRecoTrackerAssociationCollection>
+            m_SITHitAssociationCol{"SITTrackerHitAssociation",
+                Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::MCRecoTrackerAssociationCollection>
+            m_SETHitAssociationCol{"SETTrackerHitAssociation",
+                Gaudi::DataHandle::Reader, this};
+        DataHandle<edm4hep::MCRecoTrackerAssociationCollection>
+            m_FTDHitAssociationCol{"FTDTrackerHitAssociation",
+                Gaudi::DataHandle::Reader, this};
+
+        //Track from silicon detectors
+        DataHandle<edm4hep::TrackCollection> m_SDTTrackCol{"SDTTrackCollection",
+            Gaudi::DataHandle::Writer, this};
+        DataHandle<edm4hep::TrackCollection> m_SDTRecTrackCol{"SDTRecTrackCollection",
+            Gaudi::DataHandle::Writer, this};
+        DataHandle<edm4hep::TrackCollection> m_SDTDebugRecTrackCol{"SDTDebugRecTrackCollection",
+            Gaudi::DataHandle::Writer, this};
+
+        //Smear
+        DataHandle<edm4hep::MCRecoTrackerAssociationCollection> r_SmearAssociationCol{
+            "SmearDCHitAssociationCollection", Gaudi::DataHandle::Reader, this};
+
+
+        //Noise
+        DataHandle<edm4hep::MCRecoTrackerAssociationCollection> r_NoiseAssociationCol{
+            "NoiseDCHitAssociationCollection", Gaudi::DataHandle::Reader, this};
+
+        //Output hits and particles
+        DataHandle<edm4hep::ReconstructedParticleCollection> m_SDTRecParticleCol{
+            "SDTRecParticleCollection", Gaudi::DataHandle::Writer, this};
+
+        const unsigned int m_nPDG;//5:e,mu,pi,K,proton
+        int m_eventNo;
+        SmartIF<IGeomSvc> m_geomSvc;
+        dd4hep::OverlayedField m_dd4hepField;
+        dd4hep::Detector* m_dd4hepDetector;
+        double m_cell_width;
+        dd4hep::DDSegmentation::GridDriftChamber* m_gridDriftChamber;
+        dd4hep::DDSegmentation::BitFieldCoder* m_decoder;
+        Gaudi::Property<std::string> m_readout_name{this,
+            "readout", "DriftChamberHitsCollection"};
+        Gaudi::Property<int> m_debug{this,"debug",0};
+        Gaudi::Property<int> m_debugGenfit{this,"debugGenfit",0};
+        Gaudi::Property<int> m_debugPid{this,"debugPid",-99};
+        Gaudi::Property<int> m_eventNoSelection{this,"eventNoSelection",1e9};
+        Gaudi::Property<std::vector<float> > m_sigmaHitU{this,
+            "sigmaHitU",{0.11, // DC z mm
+                0.0028,0.006,0.004,0.004,0.004,0.004, //VXD U
+                    0.0072, //SIT U 4 layers same resolusion
+                    0.0072, //SET U
+                    0.003,0.003,0.0072,0.0072,0.0072,0.0072,0.0072}};//FTD V
+        //mm, 0:DC, 1~7:VXD, 8:SIT, 9:SET, FTD:10~16
+        Gaudi::Property<std::vector<float> > m_sigmaHitV{this,
+            "sigmaHitV",{0.11, // DC z mm
+                0.0028,0.006,0.004,0.004,0.004,0.004, //VXD V
+                    0.086, //SIT V
+                    0.086, //SET V
+                    0.003,0.003,0.0072,0.0072,0.0072,0.0072,0.0072}};//FTD V
+        Gaudi::Property<int> m_measurementTypeSi{this,"measurementTypeSi",0};
+        //-1: not use, 0, space point, 1, pixel or planer measurement
+        Gaudi::Property<int> m_measurementTypeDC{this,"measurementTypeDC",0};
+        //-1: not use, 0, space point, 1, wire measurement
+        //Gaudi::Property<bool> m_smearHit{this,"smearHit",true};
+        //Gaudi::Property<float> m_nSigmaHit{this,"nSigmaHit",5};
+        Gaudi::Property<int> m_sortMethod{this,"sortMethod",0};
+        Gaudi::Property<bool> m_truthAmbig{this,"truthAmbig",true};
+        Gaudi::Property<float> m_skipCorner{this,"skipCorner",999.};
+        Gaudi::Property<float> m_skipNear{this,"skipNear",0.};
+        //Gaudi::Property<double> m_initCovResPos{this,"initCovResPos",1};
+        //Gaudi::Property<double> m_initCovResMom{this,"initCovResMom",0.1};
+        Gaudi::Property<bool> m_isUseCovTrack{this,"isUseCovTrack",false};
+        //Fitter type default is DAFRef.
+        //Candidates are DAF,DAFRef,KalmanFitter and KalmanFitterRefTrack.
+        Gaudi::Property<std::string> m_fitterType{this,"fitterType","DAF"};
+        Gaudi::Property<bool> m_correctBremsstrahlung{this,
+            "correctBremsstrahlung",false};
+        Gaudi::Property<bool> m_noMaterialEffects{this,
+            "noMaterialEffects",false};
+        Gaudi::Property<bool> m_skipWireMaterial{this,
+            "skipWireMaterial",true};
+        Gaudi::Property<int> m_maxIteration{this,"maxIteration",20};
+        Gaudi::Property<int> m_resortHits{this,"resortHits",true};
+        Gaudi::Property<double> m_bStart{this,"bStart",100};
+        Gaudi::Property<double> m_bFinal{this,"bFinal",0.01};
+        Gaudi::Property<double> m_DCCornerCuts{this,"dcCornerCuts",-999};
+        Gaudi::Property<double> m_ndfCut{this,"ndfCut",1e9};
+        Gaudi::Property<double> m_chi2Cut{this,"chi2Cut",1e9};
+        //-1,chargedGeantino;0,1,2,3,4:e,mu,pi,K,proton
+        Gaudi::Property<bool> m_useTruthTrack{this,"useTruthTrack",false};
+        Gaudi::Property<std::string> m_genfitHistRootName{this,
+            "genfitHistRootName",""};
+        Gaudi::Property<bool> m_showDisplay{this,"showDisplay",false};
+        Gaudi::Property<bool> m_fitSiliconOnly{this,"fitSiliconOnly",false};
+        Gaudi::Property<bool> m_isUseFixedSiHitError{this,"isUseFixedSiHitError",false};
+        Gaudi::Property<std::vector<float> > m_hitError{this,"hitError",
+            {0.007,0.007,0.03}};
+        Gaudi::Property<double> m_extMinDistCut{this,"extMinDistCut",1e-4};
+        Gaudi::Property<int> m_multipleMeasurementHandling{this,
+            "multipleMeasurementHandling",
+            (int) genfit::eMultipleMeasurementHandling::unweightedClosestToPredictionWire};
+        Gaudi::Property<double> m_driftVelocity{this,"drift_velocity",40};//um/ns
+        Gaudi::Property<bool> m_selectDCHit{this,"selectDCHit",false};
+        Gaudi::Property<bool> m_useNoiseDCHit{this,"useNoiseDCHit",false};
+        Gaudi::Property<double> m_docaCut{this,"docaCut",3.3};//mm
+        int m_fitSuccess[5];
+        int m_nRecTrack;
+        bool m_firstTuple;
+        //bool m_useRecLRAmbig;
+
+        genfit::EventDisplay* m_genfitDisplay;
+
+        /// tuples
+        NTuple::Tuple*  m_tuple;
+        NTuple::Item<int> m_run;
+        NTuple::Item<int> m_evt;
+        NTuple::Item<int> m_tkId;
+        NTuple::Item<int> m_mcIndex;//number of navigated mcParicle
+        NTuple::Matrix<double> m_truthPocaMc;//2 dim matched particle and 3 pos.
+        NTuple::Array<double> m_seedMomP;//for some track
+        NTuple::Array<double> m_seedMomPt;
+        NTuple::Array<int> m_seedMomQ;
+        NTuple::Matrix<double> m_seedMom;
+        NTuple::Matrix<double> m_seedPos;
+        NTuple::Matrix<double> m_pocaPosMc;//2 dim matched particle and 3 pos.
+        NTuple::Matrix<double> m_pocaMomMc;//2 dim matched particle and 3 mom.
+        NTuple::Array<double> m_pocaMomMcP;//2 dim matched particle and p
+        NTuple::Array<double> m_pocaMomMcPt;//2 dim matched particle and pt
+        NTuple::Matrix<double> m_pocaPosMdc;//pos 0:x,1:y,2:z
+        NTuple::Matrix<double> m_pocaMomMdc;//mom. 0:px,1:py,2:pz
+        NTuple::Item<int> m_pidIndex;
+        NTuple::Matrix<double> m_firstPosKal;//5 hyposis and pos. at first
+        NTuple::Array<double> m_firstMomKalP;//5 hyposis and mom. at first
+        NTuple::Array<double> m_firstMomKalPt;//5 hyposis and mom. at first
+
+        NTuple::Matrix<double> m_ErrorcovMatrix6;
+        NTuple::Array<double> m_posx;
+        NTuple::Array<double> m_posy;
+        NTuple::Array<double> m_posz;
+
+        NTuple::Array<double> m_momx;
+        NTuple::Array<double> m_momy;
+        NTuple::Array<double> m_momz;
+
+        NTuple::Array<double> m_PosMcX;
+        NTuple::Array<double> m_PosMcY;
+        NTuple::Array<double> m_PosMcZ;
+
+        NTuple::Array<double> m_MomMcX;
+        NTuple::Array<double> m_MomMcY;
+        NTuple::Array<double> m_MomMcZ;
+
+        
+        NTuple::Array<double> m_PocaPosX;
+        NTuple::Array<double> m_PocaPosY;
+        NTuple::Array<double> m_PocaPosZ;
+
+        NTuple::Array<double> m_PocaMomX;
+        NTuple::Array<double> m_PocaMomY;
+        NTuple::Array<double> m_PocaMomZ;
+
+        NTuple::Matrix<double> m_McErrCov;
+        NTuple::Matrix<double> m_PocaErrCov;
+
+        NTuple::Matrix<double> m_ErrorcovMatrix;
+        NTuple::Array<double> m_D0;
+        NTuple::Array<double> m_phi;
+        NTuple::Array<double> m_omega;
+        NTuple::Array<double> m_Z0;
+        NTuple::Array<double> m_tanLambda;
+
+        NTuple::Matrix<double> m_ErrorcovMatrix_Origin;
+        NTuple::Array<double> m_D0_Origin;
+        NTuple::Array<double> m_phi_Origin;
+        NTuple::Array<double> m_omega_Origin;
+        NTuple::Array<double> m_Z0_Origin;
+        NTuple::Array<double> m_tanLambda_Origin;
+
+        NTuple::Array<double> mcP_D0;
+        NTuple::Array<double> mcP_phi;
+        NTuple::Array<double> mcP_omega;
+        NTuple::Array<double> mcP_Z0;
+        NTuple::Array<double> mcP_tanLambda;
+
+        NTuple::Matrix<double> m_pocaPosKal;//5 hyposis and 3 mom.
+        NTuple::Matrix<double> m_pocaMomKal;//5 hyposis and 3 mom.
+        NTuple::Matrix<double> m_pocaMomKalP;//5 hyposis and p
+        NTuple::Matrix<double> m_pocaMomKalPt;//5 hyposis and pt
+        NTuple::Matrix<int> m_chargeKal;
+        NTuple::Matrix<double> m_chi2Kal;
+        NTuple::Matrix<double> m_nDofKal;
+        NTuple::Matrix<int> m_isFitConverged;
+        NTuple::Matrix<int> m_isFitConvergedFully;
+        NTuple::Matrix<int> m_isFitted;
+        NTuple::Matrix<int> m_fittedState;
+        NTuple::Item<int> m_nDCDigi;
+        NTuple::Item<int> m_nHitMc;
+        NTuple::Item<int> m_nSdtTrack;
+        NTuple::Item<int> m_nSdtTrackHit;
+
+        NTuple::Item<int> m_nSdtRecTrack;
+
+        NTuple::Item<int> m_nSimDCHit;
+        NTuple::Matrix<int> m_nHitWithFitInfo;
+        NTuple::Item<int> m_nHitKalInput;
+        NTuple::Array<int> m_nHitDetType;
+        NTuple::Array<double> m_mdcHitDriftT;
+        NTuple::Array<double> m_mdcHitDriftDl;
+        NTuple::Array<double> m_mdcHitDriftDr;
+        NTuple::Array<int> m_mdcHitLr;
+        NTuple::Array<int> m_mdcHitLayer;
+        NTuple::Array<int> m_mdcHitWire;
+        NTuple::Array<double> m_mdcHitExpDoca;
+        NTuple::Array<double> m_mdcHitExpMcDoca;
+        NTuple::Array<double> m_mdcHitErr;
+        NTuple::Matrix<int> m_nHitFailedKal;
+        NTuple::Matrix<int> m_nHitFitted;
+        NTuple::Item<double> m_exeTime;
+        //truth
+        NTuple::Array<int> m_mdcHitMcLr;
+        NTuple::Array<int> m_mdcHitMcTkId;
+        NTuple::Array<double> m_mdcHitMcDrift;
+        NTuple::Array<double> m_mdcHitMcX;
+        NTuple::Array<double> m_mdcHitMcY;
+        NTuple::Array<double> m_mdcHitMcZ;
+        NTuple::Array<double> m_mdcHitExpMcPocaX;
+        NTuple::Array<double> m_mdcHitExpMcPocaY;
+        NTuple::Array<double> m_mdcHitExpMcPocaZ;
+        NTuple::Array<double> m_mdcHitExpMcPocaWireX;
+        NTuple::Array<double> m_mdcHitExpMcPocaWireY;
+        NTuple::Array<double> m_mdcHitExpMcPocaWireZ;
+
+        NTuple::Array<double> m_dcDigiChamber;
+        NTuple::Array<double> m_dcDigiLayer;
+        NTuple::Array<double> m_dcDigiCell;
+        NTuple::Array<double> m_dcDigiTime;
+        NTuple::Array<double> m_dcDigiDrift;
+        NTuple::Array<double> m_dcDigiDocaMC;
+        NTuple::Array<double> m_dcDigiPocaOnWireMCX;
+        NTuple::Array<double> m_dcDigiPocaOnWireMCY;
+        NTuple::Array<double> m_dcDigiWireStartX;
+        NTuple::Array<double> m_dcDigiWireStartY;
+        NTuple::Array<double> m_dcDigiWireStartZ;
+        NTuple::Array<double> m_dcDigiWireEndX;
+        NTuple::Array<double> m_dcDigiWireEndY;
+        NTuple::Array<double> m_dcDigiWireEndZ;
+        NTuple::Array<double> m_dcDigiMcPosX;
+        NTuple::Array<double> m_dcDigiMcPosY;
+        NTuple::Array<double> m_dcDigiMcPosZ;
+        NTuple::Array<double> m_dcDigiMcMomX;
+        NTuple::Array<double> m_dcDigiMcMomY;
+        NTuple::Array<double> m_dcDigiMcMomZ;
+        NTuple::Array<double> m_dcDigiDocaExt;
+        NTuple::Array<double> m_dcDigiPocaExtX;
+        NTuple::Array<double> m_dcDigiPocaExtY;
+        NTuple::Array<double> m_dcDigiPocaExtZ;
+        NTuple::Item<double> m_firstMomMc;
+
+        NTuple::Item<int> m_nTrackerHitSDT;
+        NTuple::Item<int> m_nTrackerHitDC;
+        NTuple::Item<int> m_nGenFitTrackerHit;
+
+        NTuple::Array<double> m_trackLength;
+        NTuple::Array<double> m_hitMomEdep;
+        NTuple::Array<float> m_truthMomEdep;
+        NTuple::Array<float> m_FittedDoca;
+        NTuple::Array<float> m_driftDis;
+        NTuple::Array<float> m_Res;
+
+};
+#endif
diff --git a/Reconstruction/RecGenfitAlg/src/WireMeasurementDC.cpp b/Reconstruction/RecGenfitAlg/src/WireMeasurementDC.cpp
new file mode 100644
index 000000000..0070d7ff0
--- /dev/null
+++ b/Reconstruction/RecGenfitAlg/src/WireMeasurementDC.cpp
@@ -0,0 +1,194 @@
+/* Copyright 2008-2010, Technische Universitaet Muenchen,
+             2014, Ludwig-Maximilians-Universität München
+   Authors: Tobias Schlüter
+
+   This file is part of GENFIT.
+
+   GENFIT is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published
+   by the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   GENFIT is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with GENFIT.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @addtogroup genfit
+ * @{
+ */
+
+#include "WireMeasurementDC.h"
+#include "edm4hep/SimTrackerHit.h"
+#include "edm4hep/TrackerHit.h"
+
+#include <iostream>
+#include <algorithm>
+
+#include <Exception.h>
+#include <RKTrackRep.h>
+#include <HMatrixU.h>
+
+#include <cassert>
+
+
+
+
+WireMeasurementDC::WireMeasurementDC()
+  : AbsMeasurement(1), maxDistance_(2), leftRight_(0)
+{
+  memset(wireEndPoint1_, 0, 3*sizeof(double));
+  memset(wireEndPoint2_, 0, 3*sizeof(double));
+}
+
+WireMeasurementDC::WireMeasurementDC(double driftDistance, double driftDistanceError, const TVector3& endPoint1, const TVector3& endPoint2, int detId, int hitId, TrackPoint* trackPoint)
+  : AbsMeasurement(1), maxDistance_(2), leftRight_(0)
+{
+  TVectorD coords(1);
+  coords[0] = driftDistance;
+  this->setRawHitCoords(coords);
+
+  TMatrixDSym cov(1);
+  cov(0,0) = driftDistanceError*driftDistanceError;
+  this->setRawHitCov(cov);
+
+  this->setWireEndPoints(endPoint1, endPoint2);
+
+  this->setDetId(detId);
+  this->setHitId(hitId);
+  this->setTrackPoint(trackPoint);
+}
+
+SharedPlanePtr WireMeasurementDC::constructPlane(const StateOnPlane& state) const {
+
+  // copy state. Neglect covariance.
+  StateOnPlane st(state);
+
+  TVector3 wire1(wireEndPoint1_);
+  TVector3 wire2(wireEndPoint2_);
+
+  // unit vector along the wire (V)
+  TVector3 wireDirection = wire2 - wire1; 
+  wireDirection.SetMag(1.);
+
+  // point of closest approach
+  const AbsTrackRep* rep = state.getRep();
+  rep->extrapolateToLine(st, wire1, wireDirection);
+  const TVector3& poca = rep->getPos(st);
+  TVector3 dirInPoca = rep->getMom(st);
+  dirInPoca.SetMag(1.);
+  const TVector3& pocaOnWire = wire1 + wireDirection.Dot(poca - wire1)*wireDirection;
+
+  // check if direction is parallel to wire
+  if (fabs(wireDirection.Angle(dirInPoca)) < 0.01){
+    Exception exc("WireMeasurementDC::detPlane(): Cannot construct detector plane, direction is parallel to wire", __LINE__,__FILE__);
+    throw exc;
+  }
+
+  // construct orthogonal vector
+  TVector3 U = wireDirection.Cross(dirInPoca);
+  // U.SetMag(1.); automatically assured
+
+  return SharedPlanePtr(new DetPlane(pocaOnWire, U, wireDirection));
+}
+
+
+std::vector<MeasurementOnPlane*> WireMeasurementDC::constructMeasurementsOnPlane(const StateOnPlane& state) const
+{
+  double mR = getRawHitCoords()(0);
+  double mL = -mR;
+
+  MeasurementOnPlane* mopL = new MeasurementOnPlane(TVectorD(1, &mL),
+      getRawHitCov(),
+      state.getPlane(), state.getRep(), constructHMatrix(state.getRep()));
+
+  MeasurementOnPlane* mopR = new MeasurementOnPlane(TVectorD(1, &mR),
+      getRawHitCov(),
+      state.getPlane(), state.getRep(), constructHMatrix(state.getRep()));
+
+  // set left/right weights
+  if (leftRight_ < 0) {
+    mopL->setWeight(1);
+    mopR->setWeight(0);
+  }
+  else if (leftRight_ > 0) {
+    mopL->setWeight(0);
+    mopR->setWeight(1);
+  }
+  else {
+    double val = 0.5 * pow(std::max(0., 1 - mR/maxDistance_), 2.);
+    mopL->setWeight(val);
+    mopR->setWeight(val);
+  }
+
+  std::vector<MeasurementOnPlane*> retVal;
+  retVal.push_back(mopL);
+  retVal.push_back(mopR);
+  return retVal;
+}
+
+const AbsHMatrix* WireMeasurementDC::constructHMatrix(const AbsTrackRep* rep) const {
+  if (dynamic_cast<const RKTrackRep*>(rep) == nullptr) {
+    Exception exc("WireMeasurementDC default implementation can only handle state vectors of type RKTrackRep!", __LINE__,__FILE__);
+    throw exc;
+  }
+
+  return new HMatrixU();
+}
+
+void WireMeasurementDC::setWireEndPoints(const TVector3& endPoint1, const TVector3& endPoint2)
+{
+  wireEndPoint1_[0] = endPoint1.X();
+  wireEndPoint1_[1] = endPoint1.Y();
+  wireEndPoint1_[2] = endPoint1.Z();
+
+  wireEndPoint2_[0] = endPoint2.X();
+  wireEndPoint2_[1] = endPoint2.Y();
+  wireEndPoint2_[2] = endPoint2.Z();
+}
+
+void WireMeasurementDC::setLeftRightResolution(int lr){
+  if (lr==0) leftRight_ = 0;
+  else if (lr<0) leftRight_ = -1;
+  else leftRight_ = 1;
+}
+
+void WireMeasurementDC::print(){
+  std::cout<<"("<<layer_<<","<<cell_
+    <<") wire(" <<wireEndPoint1_[0] <<wireEndPoint1_[1] <<wireEndPoint1_[2]
+    <<wireEndPoint2_[0] <<wireEndPoint2_[1] <<wireEndPoint2_[2]
+    <<")cm dt "<<trackerHit_->getTime()
+    <<"ns time "<<simTrackerHit_->getTime()
+    <<"ns dd "<<getRawHitCoords()[0]
+    <<"cm dd err "<< getRawHitCov()(0,0)
+    <<"cm lr "<<leftRight_;
+  //<<std::endl;
+  //<<" ddSm "<<driftDistanceSmeared
+}
+
+
+WireMeasurementDC::WireMeasurementDC(const GenfitHit* genfitHit,int iHit):
+    maxDistance_(genfitHit->getMaxDistance()),
+    leftRight_(genfitHit->getLeftRightAmbig()),
+    trackerHit_(genfitHit->getTrackerHit()),
+    simTrackerHit_(genfitHit->getSimTrackerHit()),
+    layer_(genfitHit->getLayer()),
+    cell_(genfitHit->getCell())
+{
+    /// New a WireMeasurement
+    try{
+        new (this)WireMeasurementDC(
+                genfitHit->getDriftDistance(),
+                genfitHit->getDriftDistanceErr(),
+                genfitHit->getEnd0(),genfitHit->getEnd1(),
+                genfitHit->getCellID(),iHit,nullptr);
+    }catch(genfit::Exception& e){
+        std::cout<<"New WireMeasurementDC exception"<<std::endl;
+        e.what();
+    }
+}
+
+/** @} */
diff --git a/Reconstruction/RecGenfitAlg/src/WireMeasurementDC.h b/Reconstruction/RecGenfitAlg/src/WireMeasurementDC.h
new file mode 100644
index 000000000..024ee704f
--- /dev/null
+++ b/Reconstruction/RecGenfitAlg/src/WireMeasurementDC.h
@@ -0,0 +1,144 @@
+/* Copyright 2008-2010, Technische Universitaet Muenchen,
+             2014 Ludwig-Maximimilians-Universität München
+   Authors: Tobias Schlüter
+
+   This file is part of GENFIT.
+
+   GENFIT is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published
+   by the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   GENFIT is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with GENFIT.  If not, see <http://www.gnu.org/licenses/>.
+*/
+/** @addtogroup genfit
+ * @{
+ */
+
+#ifndef WireMeasurementDC_h
+#define WireMeasurementDC_h
+
+#include "AbsMeasurement.h"
+#include "TrackPoint.h"
+#include "SharedPlanePtr.h"
+#include "MeasurementOnPlane.h"
+#include "StateOnPlane.h"
+#include "AbsHMatrix.h"
+#include "GenfitHit.h"
+
+namespace edm4hep{
+    class TrackerHit;
+    class SimTrackerHit;
+}
+
+
+
+/** @brief Class for measurements in wire detectors (Straw tubes and drift chambers)
+ *  which do not measure the coordinate along the wire.
+ *
+ *  @author Tobias Schlüter
+ *
+ * This is similar to WireMeasurement, but since WireMeasurement
+ * stores a 7x7 covariance matrix for what is a one-dimensional
+ * measurement, this class is preferable.  Protected inheritance of
+ * rawHitCoords_ and rawHitCov_ makes it impossible to rewrite
+ * WireMeasurement, as subclasses will access these members.
+ *
+ * This hit class is not valid for arbitrary choices of plane
+ * orientation: to use it you MUST choose a plane described by u
+ * and v axes with v coincident with the wire (and u orthogonal
+ * to it, obviously).
+ * The hit will be described by 7 coordinates:
+ * w_x1, w_y1, w_z1, w_x2, w_y2, w_z2, rdrift
+ * where w_ji (with j = x, y, z and i = 1, 2) are the wire
+ * extremities coordinates; rdrift = distance from the wire (u
+ * coordinate in the plane)
+ *
+ */
+using namespace genfit;
+class WireMeasurementDC : public genfit::AbsMeasurement{
+
+ public:
+  WireMeasurementDC();
+  WireMeasurementDC(double driftDistance, double driftDistanceError, const TVector3& endPoint1, const TVector3& endPoint2, int detId, int hitId, TrackPoint* trackPoint);
+  WireMeasurementDC(const GenfitHit* genfitHit,int iHit);
+
+  virtual ~WireMeasurementDC() {;}
+
+  virtual WireMeasurementDC* clone() const override {return new WireMeasurementDC(*this);}
+
+  virtual SharedPlanePtr constructPlane(const StateOnPlane& state) const override;
+
+  /**  Hits with a small drift distance get a higher weight, whereas hits with
+    * big drift distances become weighted down.
+    * When these initial weights are used by the DAF, the smoothed track will be closer to the real
+    * trajectory than if both sides are weighted with 0.5 regardless of the drift distance.
+    * This helps a lot when resolving l/r ambiguities with the DAF.
+    * The idea is that for the first iteration of the DAF, the wire positions are taken.
+    * For small drift radii, the wire position does not bend the fit away from the
+    * trajectory, whereas the wire position for hits with large drift radii is further away
+    * from the trajectory and will therefore bias the fit if not weighted down.
+    */
+  virtual std::vector<MeasurementOnPlane*> constructMeasurementsOnPlane(const StateOnPlane& state) const override;
+
+  virtual const AbsHMatrix* constructHMatrix(const AbsTrackRep*) const override;
+
+  /** Reset the wire end points.
+   */
+  void setWireEndPoints(const TVector3& endPoint1, const TVector3& endPoint2);
+
+  /** Set maximum drift distance. This is used to calculate the start weights of the two
+   * measurementsOnPlane.
+   */
+  void setMaxDistance(double d){maxDistance_ = d;}
+  /**
+   * select how to resolve the left/right ambiguity:
+   * -1: negative (left) side on vector (wire direction) x (track direction)
+   * 0: mirrors enter with same weight, DAF will decide.
+   * 1: positive (right) side on vector (wire direction) x (track direction)
+   * where the wire direction is pointing from endPoint1 to endPoint2
+   */
+  void setLeftRightResolution(int lr);
+
+  virtual bool isLeftRigthMeasurement() const {return true;}
+  double getMaxDistance(){return maxDistance_;}
+  int getLeftRightResolution() const override {return leftRight_;}
+  void setTrackerHit(const edm4hep::TrackerHit& trackerHit,int l,int c){
+      trackerHit_=&trackerHit;
+      layer_=l;
+      cell_=c;
+  }
+  void setSimTrackerHit(const edm4hep::SimTrackerHit& simTrackerHit){
+      simTrackerHit_=&simTrackerHit;
+  }
+  void print();
+
+  const edm4hep::TrackerHit* getTrackerHit(){return trackerHit_;}
+
+ protected:
+
+  double wireEndPoint1_[3]; //! Wire end point 1 (X, Y, Z)
+  double wireEndPoint2_[3]; //! Wire end point 2 (X, Y, Z)
+  double maxDistance_;
+  double leftRight_;
+
+  int layer_;
+  int cell_;
+  const edm4hep::SimTrackerHit* simTrackerHit_;
+  const edm4hep::TrackerHit* trackerHit_;
+
+ public:
+
+  //ClassDefOverride(WireMeasurementDC, 1)
+
+};
+
+/** @} */
+
+#endif // WireMeasurementDC_h
diff --git a/Utilities/DataHelper/include/DataHelper/TrackHelper.h b/Utilities/DataHelper/include/DataHelper/TrackHelper.h
new file mode 100644
index 000000000..cb76b6bea
--- /dev/null
+++ b/Utilities/DataHelper/include/DataHelper/TrackHelper.h
@@ -0,0 +1,19 @@
+#ifndef TRACKHELPER_H
+#define TRACKHELPER_H
+#include "edm4hep/TrackState.h"
+#include "TMatrixDSym.h"
+#include "TVector3.h"
+
+namespace CEPC{
+    //get track position and momentum from TrackState
+    void getPosMomFromTrackState(const edm4hep::TrackState& trackState,
+            double Bz, TVector3& pos,TVector3& mom,double& charge,
+            TMatrixDSym& covMatrix_6);
+
+    //Set track state from position, momentum and charge
+    void getTrackStateFromPosMom(edm4hep::TrackState& trackState,double Bz,
+            TVector3 pos,TVector3 mom,double charge,TMatrixDSym covMatrix_6);
+
+}
+
+#endif
diff --git a/Utilities/DataHelper/src/TrackHelper.cc b/Utilities/DataHelper/src/TrackHelper.cc
new file mode 100644
index 000000000..61153e857
--- /dev/null
+++ b/Utilities/DataHelper/src/TrackHelper.cc
@@ -0,0 +1,130 @@
+#include "DataHelper/TrackHelper.h"
+#include "DD4hep/DD4hepUnits.h"
+#include "DataHelper/HelixClass.h"
+#include "TVector3.h"
+#include "TLorentzVector.h"
+#include <iostream>
+
+//get track position and momentum from TrackState
+void CEPC::getPosMomFromTrackState(const edm4hep::TrackState& trackState,
+        double Bz, TVector3& pos,TVector3& mom,double& charge,
+        TMatrixDSym& covMatrix_6){
+    double D0=trackState.D0;
+    double phi=trackState.phi;
+    double omega=trackState.omega;
+    double Z0=trackState.Z0;
+    double tanLambda=trackState.tanLambda;
+
+    ::edm4hep::Vector3f referencePoint=trackState.referencePoint;
+    charge=omega/fabs(omega);
+    const double FCT = 2.99792458E-4;
+    double radius = 1./fabs(omega);
+    double pxy = FCT*Bz*radius;
+    for(int i=0;i<3;i++){
+        pos[i]=referencePoint[i];
+    }
+    mom[0]=pxy*cos(phi);
+    mom[1]=pxy*sin(phi);
+    mom[2]=pxy*tanLambda;
+    TMatrixDSym covMatrix_5(5);
+    ///< lower triangular covariance matrix of the track parameters.
+    ///  the order of parameters is  d0, phi, omega, z0, tan(lambda).
+    std::array<float,15> covMatrix=trackState.covMatrix;
+    int k=0;
+    for(int i=0;i<5;i++){
+        for(int j=0;j<5;j++){
+            if(i>=j) { covMatrix_5(i,j)=covMatrix[k++]; }
+        }
+    }
+
+    ///Error propagation
+    //V(Y)=S * V(X) * ST , mS = S , mVy = V(Y) , helix.covariance() = V(X)
+    TMatrix mS(covMatrix_6.GetNrows(),covMatrix_5.GetNrows());
+    mS.Zero();
+    mS[0][0]=-sin(phi);
+    mS[0][1]=-1*D0*cos(phi);
+    mS[1][0]=cos(phi);
+    mS[1][1]=-1*D0*sin(phi);
+    mS[2][3]=1;
+    mS[3][1]=FCT*Bz*(1/omega)*sin(phi);
+    mS[3][2]=charge*FCT*Bz*(1/(omega*omega))*cos(phi);
+    mS[4][1]=-1*FCT*Bz*(1/omega)*cos(phi);
+    mS[4][2]=charge*FCT*Bz*(1/(omega*omega))*sin(phi);
+    mS[5][2]=charge*tanLambda*Bz*(1/(omega*omega));
+    mS[5][4]=-FCT*Bz/omega*(1+tanLambda*tanLambda);
+
+    covMatrix_6= covMatrix_5.Similarity(mS);
+
+    const char* m_name="TrackHelper";
+    int m_debug=0;
+    if(m_debug>=2){
+        //std::cout<<m_name<<" covMatrix_5 " <<std::endl;
+        //covMatrix_5.Print();
+        //std::cout<<m_name<<" mS " <<std::endl;
+        //mS.Print();
+        std::cout<<m_name<<" covMatrix_6 " <<std::endl;
+        covMatrix_6.Print();
+        std::cout<<m_name<<" pos " <<std::endl;
+        pos.Print();
+        std::cout<<m_name<<" mom " <<std::endl;
+        mom.Print();
+    }
+}
+
+//Set track state from position, momentum and charge
+void CEPC::getTrackStateFromPosMom(edm4hep::TrackState& trackState,double Bz,
+        TVector3 pos,TVector3 mom,double charge,TMatrixDSym covMatrix_6){
+    HelixClass helix;
+    double pos_t[3]={pos.X(),pos.Y(),pos.Z()};
+    double mom_t[3]={mom.X(),mom.Y(),mom.Z()};
+    helix.Initialize_VP(pos_t,mom_t,charge,Bz); //mm GeV
+
+    trackState.D0=helix.getD0();
+    trackState.phi=helix.getPhi0();
+    trackState.omega=helix.getOmega();
+    trackState.Z0=helix.getZ0();
+    trackState.tanLambda=helix.getTanLambda();
+    trackState.referencePoint=helix.getReferencePoint();
+    int m_debug=1;
+    if(m_debug>=2){
+        std::cout<<__FILE__<<" pos mom"<<std::endl;
+        pos.Print();
+        mom.Print();
+        std::cout<<__FILE__<<" getTrackStateFromPosMom trackState  "<<trackState<<std::endl;
+        std::cout<<__FILE__<<" getTrackStateFromPosMom cov6"<<std::endl;
+        covMatrix_6.Print();
+    }
+
+    TMatrix Jacobian_matrix(5,6);
+    Jacobian_matrix.Zero();
+
+    const double FCT = 2.99792458E-4;
+    double pt=sqrt(mom.X()*mom.X()+mom.Y()*mom.Y());
+    Jacobian_matrix[0][0] = pos.X()/(sqrt(pos.X()*pos.X()+pos.Y()*pos.Y()));
+    Jacobian_matrix[0][1] = pos.Y()/(sqrt(pos.X()*pos.X()+pos.Y()*pos.Y()));
+    Jacobian_matrix[1][3] = -1*mom.Y()/(pt*pt);
+    Jacobian_matrix[1][4] = mom.X()/(pt*pt);
+    Jacobian_matrix[2][3] = -1*charge*mom.X()*Bz*FCT/(pt*pt*pt); //FIXME
+    Jacobian_matrix[2][4] = -1*charge*mom.Y()*Bz*FCT/(pt*pt*pt); //FIXME
+    Jacobian_matrix[3][2] = 1.;
+    Jacobian_matrix[4][3] = -1*mom.Z()*mom.X()/(pt*pt*pt); //FIXME
+    Jacobian_matrix[4][4] = -1*mom.Z()*mom.Y()/(pt*pt*pt); //FIXME
+    Jacobian_matrix[4][5] = 1./pt;
+
+    TMatrixDSym covMatrix_5 = covMatrix_6.Similarity(Jacobian_matrix);
+
+    std::array<float,15> covMatrix;
+    int k=0;
+    int k1;
+    for(int i=0;i<5;i++){
+        for(int j=0;j<5;j++){
+            if(i>=j) { 
+                k1=k++;
+                //covMatrix[k++]=covMatrix_5(i,j);
+                covMatrix[k1]=covMatrix_5(i,j);
+            }
+        }
+    }
+
+    trackState.covMatrix = covMatrix;
+}

From 23666a4dfe64bda059ce3c9b1fc765aced073290 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Tue, 5 Jul 2022 14:12:15 +0800
Subject: [PATCH 13/27] TrackState add time

---
 Digitisers/DCHDigi/src/DCHDigiAlg.cpp                    | 4 ++--
 Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp      | 4 ++--
 .../Tracking/src/TruthTracker/TruthTrackerAlg.cpp        | 8 ++++----
 Utilities/DataHelper/src/TrackHelper.cc                  | 9 +++++----
 4 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
index d516b50f4..927c7b27d 100644
--- a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
+++ b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
@@ -224,7 +224,7 @@ StatusCode DCHDigiAlg::execute()
 
       trkHit.setTime(min_distance*1e3/m_velocity);//m_velocity is um/ns, drift time in ns
       trkHit.setEDep(tot_edep);// GeV
-      trkHit.setEdx (tot_edep/tot_length); // GeV/mm
+      //trkHit.setEdx (tot_edep/tot_length); // GeV/mm
       trkHit.setPosition (edm4hep::Vector3d(pos_x, pos_y, pos_z));//position of closest sim hit
       trkHit.setCovMatrix(std::array<float, 6>{m_res_x, 0, m_res_y, 0, 0, m_res_z});//cov(x,x) , cov(y,x) , cov(y,y) , cov(z,x) , cov(z,y) , cov(z,z) in mm
 
@@ -245,7 +245,7 @@ StatusCode DCHDigiAlg::execute()
           m_poca_x   [m_n_digi] = PCA.x();
           m_poca_y   [m_n_digi] = PCA.y();
           m_hit_dE   [m_n_digi] = trkHit.getEDep();
-          m_hit_dE_dx[m_n_digi] = trkHit.getEdx() ;
+          //m_hit_dE_dx[m_n_digi] = trkHit.getEdx() ;
           m_truthlength[m_n_digi] = tot_length ;
           m_n_digi ++ ;
       }
diff --git a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
index f9292e375..ee56ab6e5 100644
--- a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
+++ b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
@@ -727,7 +727,7 @@ void RecGenfitAlgSDT::debugTrack(int iStrack,int pidType,const GenfitTrack* genf
     edm4hep::TrackState trackState_Origin;
     CEPC::getTrackStateFromPosMom(trackState_Origin,m_genfitField->getBz(pocaToOrigin_POS.Vect())/GenfitUnit::tesla,pocaToOrigin_pos,
             pocaToOrigin_mom,charge,covMatrix_6);
-    std::array<float,15> errorCov_Origin;
+    std::array<float,21> errorCov_Origin;
     errorCov_Origin = trackState_Origin.covMatrix;
     for(int j=0; j<15; j++) {
         m_ErrorcovMatrix_Origin[iStrack][j] = errorCov_Origin[j];
@@ -899,7 +899,7 @@ void RecGenfitAlgSDT::debugEvent(const edm4hep::TrackCollection* sdtTrackCol,
         }
         for(unsigned int i=0; i<sdtRecTrack.trackStates_size(); i++) {
             edm4hep::TrackState trackStat=sdtRecTrack.getTrackStates(i);
-            std::array<float,15> errorCov;
+            std::array<float,21> errorCov;
             errorCov = trackStat.covMatrix;
             for(int j=0; j<15; j++) {
                 m_ErrorcovMatrix[isdttrack][j] = errorCov[j];
diff --git a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp
index afe625ae4..7b2b7afe2 100644
--- a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp
+++ b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp
@@ -528,8 +528,8 @@ bool TruthTrackerAlg::getTrackStateFirstHit(
         trackState.Z0=helix.getZ0();
         trackState.tanLambda=helix.getTanLambda();
         trackState.referencePoint=helix.getReferencePoint();
-        std::array<float,15> covMatrix;
-        for(int i=0;i<15;i++){covMatrix[i]=100.;}//FIXME
+        std::array<float,21> covMatrix;
+        for(int i=0;i<21;i++){covMatrix[i]=100.;}//FIXME
         trackState.covMatrix=covMatrix;
         debug()<<"first hit trackState "<<trackState<<endmsg;
         return true;
@@ -667,7 +667,7 @@ int TruthTrackerAlg::makeNoiseHit(edm4hep::SimTrackerHitCollection* SimVec,
         trkHit.setCellID(wcellid);
         trkHit.setTime(pocaTime);
         trkHit.setEDep(mcHit.getEDep());
-        trkHit.setEdx(mcHit.getEdx());
+        //trkHit.setEdx(mcHit.getEdx());
         trkHit.setPosition(mcHit.getPosition());
         trkHit.setCovMatrix(mcHit.getCovMatrix());
         for(int iAsso=0;iAsso<(int) assoHits->size();iAsso++)
@@ -755,7 +755,7 @@ int TruthTrackerAlg::smearDCTkhit(DataHandle<edm4hep::TrackerHitCollection>&
         smearHit.setQuality(hit.getQuality());
         smearHit.setEDep(hit.getEDep());
         smearHit.setEDepError(hit.getEDepError());
-        smearHit.setEdx(hit.getEdx());
+        //smearHit.setEdx(hit.getEdx());
         smearHit.setPosition(hit.getPosition());
         smearHit.setCovMatrix(hit.getCovMatrix());
         smearHit.addToRawHits(hit.getObjectID());
diff --git a/Utilities/DataHelper/src/TrackHelper.cc b/Utilities/DataHelper/src/TrackHelper.cc
index 61153e857..6f5db4cef 100644
--- a/Utilities/DataHelper/src/TrackHelper.cc
+++ b/Utilities/DataHelper/src/TrackHelper.cc
@@ -29,7 +29,7 @@ void CEPC::getPosMomFromTrackState(const edm4hep::TrackState& trackState,
     TMatrixDSym covMatrix_5(5);
     ///< lower triangular covariance matrix of the track parameters.
     ///  the order of parameters is  d0, phi, omega, z0, tan(lambda).
-    std::array<float,15> covMatrix=trackState.covMatrix;
+    std::array<float,21> covMatrix=trackState.covMatrix;
     int k=0;
     for(int i=0;i<5;i++){
         for(int j=0;j<5;j++){
@@ -113,15 +113,16 @@ void CEPC::getTrackStateFromPosMom(edm4hep::TrackState& trackState,double Bz,
 
     TMatrixDSym covMatrix_5 = covMatrix_6.Similarity(Jacobian_matrix);
 
-    std::array<float,15> covMatrix;
+    std::array<float,21> covMatrix;
     int k=0;
     int k1;
-    for(int i=0;i<5;i++){
-        for(int j=0;j<5;j++){
+    for(int i=0;i<6;i++){
+        for(int j=0;j<6;j++){
             if(i>=j) { 
                 k1=k++;
                 //covMatrix[k++]=covMatrix_5(i,j);
                 covMatrix[k1]=covMatrix_5(i,j);
+                if(5==i) covMatrix[k1]=-999;
             }
         }
     }

From b71b0002b2b784b6588f88c8cda8e3a14119b236 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Tue, 5 Jul 2022 18:40:39 +0800
Subject: [PATCH 14/27] Fix Compile Error

---
 Digitisers/DCHDigi/src/DCHDigiAlg.h           | 2 +-
 Reconstruction/RecGenfitAlg/src/GenfitTrack.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.h b/Digitisers/DCHDigi/src/DCHDigiAlg.h
index 4dcf76944..6effe0a29 100644
--- a/Digitisers/DCHDigi/src/DCHDigiAlg.h
+++ b/Digitisers/DCHDigi/src/DCHDigiAlg.h
@@ -7,7 +7,7 @@
 #include "edm4hep/SimTrackerHitCollection.h"
 #include "edm4hep/TrackerHitCollection.h"
 #include "edm4hep/MCRecoTrackerAssociationCollection.h"
-#include "edm4hep/MCParticleConst.h"
+#include "edm4hep/MCParticle.h"
 
 #include <DDRec/DetectorData.h>
 #include <DDRec/CellIDPositionConverter.h>
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitTrack.h b/Reconstruction/RecGenfitAlg/src/GenfitTrack.h
index bfcb7a995..27ef200b6 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitTrack.h
+++ b/Reconstruction/RecGenfitAlg/src/GenfitTrack.h
@@ -70,10 +70,10 @@ namespace dd4hep {
 
 class GenfitTrack {
     friend int GenfitFitter::processTrack(
-            GenfitTrack* track, bool resort=true);
+            GenfitTrack* track, bool resort);
 
     friend int GenfitFitter::processTrackWithRep(
-            GenfitTrack* track, int repID, bool resort=true);
+            GenfitTrack* track, int repID, bool resort);
 
     public:
     GenfitTrack(const GenfitField* field,

From c71bd59a328fc4a49cdab87a5134417c28042148 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Wed, 4 Jan 2023 11:21:08 +0800
Subject: [PATCH 15/27] Add DC_Simple_v01_03.xml

---
 .../CRD_common_v01/DC_Simple_v01_03.xml       | 79 +++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_03.xml

diff --git a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_03.xml b/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_03.xml
new file mode 100644
index 000000000..e3c372fdd
--- /dev/null
+++ b/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_03.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lccdd>
+
+  <info name="DriftChamber"
+    title="Test with Drift Chamber"
+    author="Tao Lin"
+    url="http://github.com/cepc/CEPCSW"
+    status="development"
+    version="v0">
+    <comment>Test with Drift Chamber</comment>
+  </info>
+
+  <define>
+
+    <constant name="DC_layer_number" value="100"/>
+    <constant name="Alpha" value="12*deg"/>
+    <constant name="Gas_radius_min" value="DC_rbegin+DC_inner_wall_thickness+DC_safe_distance"/>
+    <constant name="Gas_half_length" value="DC_half_length-DC_Endcap_dz-DC_safe_distance"/>
+    <constant name="Gas_length" value="Gas_half_length*2"/>
+    <constant name="DC_cell_width" value="10*mm"/>
+    <constant name="DC_inner_wall_radius_min" value="DC_rbegin"/>
+    <constant name="DC_inner_wall_radius_max" value="DC_rbegin+DC_inner_wall_thickness"/>
+    <constant name="DC_Endcap_rmin" value="DC_rbegin"/>
+    <constant name="DC_Endcap_rmax" value="DC_rend"/>
+
+    <constant name="DC_construct_wire" value="1"/>
+
+    <constant name="DC_layer_width" value="9.57687*mm"/>
+
+  </define>
+
+  <limits>
+    <limitset name="DC_limits">
+      <limit name="step_length_max" particles="*" value="0.1" unit="mm" />
+    </limitset>
+  </limits>
+
+  <regions>
+    <region name="DriftChamberRegion">
+    </region>
+  </regions>
+
+  <detectors>
+    <detector id="DetID_DC" name="DriftChamber" type="DriftChamber" readout="DriftChamberHitsCollection" vis="DCVis" sensitive="true" region="DriftChamberRegion" limits="DC_limits">
+      <material name="Air"/>
+      <chamber id="0" material="GasHe_90Isob_10"/>
+      <side material="CarbonFiber"/>
+      <envelope vis="SeeThrough">
+        <shape type="BooleanShape" operation="Union" material="Air">
+          <shape type="Tube" rmin="DC_rbegin" rmax="DC_rend" dz="DC_half_length" />
+        </shape>
+      </envelope>
+
+      <module id="0" name="SignalWire" type="Tube" rmin="0*mm" rmax="0.01*mm" vis="RedVis">
+          <tubs name="W" type="Tube" rmin="0*mm" rmax="0.007*mm" material="Tungsten"/>
+          <tubs name="Au" type="Tube" rmin="0.007*mm" rmax="0.01*mm" material="Gold"/>
+      </module>
+
+      <module id="1" name="FieldWire" type="Tube" rmin="0*mm" rmax="0.02*mm" vis="GreenVis">
+          <tubs name="Al" type="Tube" rmin="0*mm" rmax="0.017*mm" material="Aluminum"/>
+          <tubs name="Ag" type="Tube" rmin="0.017*mm" rmax="0.02*mm" material="Silver"/>
+      </module>
+
+      <type_flags type="DetType_TRACKER + DetType_BARREL + DetType_GASEOUS + DetType_WIRE"/>
+      <!-- Use cm as unit if you want to use Pandora for reconstruction -->
+     <sensitive type="SimpleDriftChamber"/>
+     </detector>
+  </detectors>
+
+  <readouts>
+    <readout name="DriftChamberHitsCollection">
+      <segmentation type="GridDriftChamber" cell_size="DC_cell_width" detector_length="Gas_length" identifier_phi="cellID" layerID="layer" DC_rbegin="DC_rbegin" DC_rend="DC_rend" layer_width="DC_layer_width"/>
+
+
+      <id>system:5,layer:7:9,chamber:8,cellID:32:16</id>
+    </readout>
+  </readouts>
+
+</lccdd>

From 9a4b4744a25fa00ef0d56cf6350034dd03bdf051 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Wed, 4 Jan 2023 16:32:12 +0800
Subject: [PATCH 16/27] Resolve conflicts

---
 Detector/DetCRD/compact/CRD_o1_v02/CRD_o1_v02-onlyTracker.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Detector/DetCRD/compact/CRD_o1_v02/CRD_o1_v02-onlyTracker.xml b/Detector/DetCRD/compact/CRD_o1_v02/CRD_o1_v02-onlyTracker.xml
index 7f1a6986b..e0a91d171 100644
--- a/Detector/DetCRD/compact/CRD_o1_v02/CRD_o1_v02-onlyTracker.xml
+++ b/Detector/DetCRD/compact/CRD_o1_v02/CRD_o1_v02-onlyTracker.xml
@@ -31,7 +31,7 @@
   <include ref="../CRD_common_v01/VXD_v01_01.xml"/>
   <include ref="../CRD_common_v01/FTD_SkewRing_v01_01.xml"/>
   <include ref="../CRD_common_v01/SIT_SimplePixel_v01_01.xml"/>
-  <include ref="../CRD_common_v01/DC_Simple_v01_03.xml"/>
+  <include ref="../CRD_common_v01/DC_Simple_v01_02.xml"/>
   <include ref="../CRD_common_v01/SET_SimplePlanar_v01_01.xml"/>
 
   <fields>

From 658f043f1c8b861da4fdbe724755669d7b66b408 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Thu, 5 Jan 2023 22:59:48 +0800
Subject: [PATCH 17/27] Add a script to run the RecGenfitAlgSDT

---
 Examples/options/tut_detsim_rec_SDT.py        | 322 ++++++++++++++++++
 .../src/TruthTracker/TruthTrackerAlg.cpp      |  32 +-
 .../src/TruthTracker/TruthTrackerAlg.h        |   9 +-
 3 files changed, 341 insertions(+), 22 deletions(-)
 create mode 100644 Examples/options/tut_detsim_rec_SDT.py

diff --git a/Examples/options/tut_detsim_rec_SDT.py b/Examples/options/tut_detsim_rec_SDT.py
new file mode 100644
index 000000000..02ac7612f
--- /dev/null
+++ b/Examples/options/tut_detsim_rec_SDT.py
@@ -0,0 +1,322 @@
+#!/usr/bin/env python
+from Gaudi.Configuration import *
+
+from Configurables import k4DataSvc
+dsvc = k4DataSvc("EventDataSvc")
+
+from Configurables import RndmGenSvc, HepRndm__Engine_CLHEP__RanluxEngine_
+seed = [10]
+# rndmengine = HepRndm__Engine_CLHEP__RanluxEngine_() # The default engine in Gaudi
+rndmengine = HepRndm__Engine_CLHEP__HepJamesRandom_("RndmGenSvc.Engine") # The default engine in Geant4
+rndmengine.SetSingleton = True
+rndmengine.Seeds = seed
+
+rndmgensvc = RndmGenSvc("RndmGenSvc")
+rndmgensvc.Engine = rndmengine.name()
+
+##############################################################################
+# Event Data Svc
+##############################################################################
+from Configurables import k4DataSvc
+dsvc = k4DataSvc("EventDataSvc")
+
+
+# option for standalone tracker study
+geometry_option = "CRD_o1_v01/CRD_o1_v01-onlyTracker.xml"
+#geometry_option = "CRD_o1_v01/CRD_o1_v01-onlyTracker_noWire_18.xml"
+#geometry_option = "CRD_o1_v01/CRD_o1_v01.xml"
+
+if not os.getenv("DETCRDROOT"):
+    print("Can't find the geometry. Please setup envvar DETCRDROOT." )
+    sys.exit(-1)
+
+geometry_path = os.path.join(os.getenv("DETCRDROOT"), "compact", geometry_option)
+if not os.path.exists(geometry_path):
+    print("Can't find the compact geometry file: %s"%geometry_path)
+    sys.exit(-1)
+
+from Configurables import GeomSvc
+geosvc = GeomSvc("GeomSvc")
+geosvc.compact = geometry_path
+
+##############################################################################
+# Physics Generator
+##############################################################################
+from Configurables import GenAlgo
+from Configurables import GtGunTool
+from Configurables import StdHepRdr
+from Configurables import SLCIORdr
+from Configurables import HepMCRdr
+from Configurables import GenPrinter
+gun = GtGunTool("GtGunTool")
+gun.Particles = ["mu-"]
+gun.EnergyMins = [40] # GeV
+gun.EnergyMaxs = [40] # GeV
+gun.ThetaMins  = [85]    # deg
+gun.ThetaMaxs  = [85]  # deg
+gun.PhiMins    = [0]    # deg
+gun.PhiMaxs    = [360]  # deg
+# stdheprdr = StdHepRdr("StdHepRdr")
+# stdheprdr.Input = "/cefs/data/stdhep/CEPC250/2fermions/E250.Pbhabha.e0.p0.whizard195/bhabha.e0.p0.00001.stdhep"
+# lciordr = SLCIORdr("SLCIORdr")
+# lciordr.Input = "/cefs/data/stdhep/lcio250/signal/Higgs/E250.Pbbh.whizard195/E250.Pbbh_X.e0.p0.whizard195/Pbbh_X.e0.p0.00001.slcio"
+# hepmcrdr = HepMCRdr("HepMCRdr")
+# hepmcrdr.Input = "example_UsingIterators.txt"
+
+genprinter = GenPrinter("GenPrinter")
+
+genalg = GenAlgo("GenAlgo")
+genalg.GenTools = ["GtGunTool"]
+#genalg.GenTools = ["StdHepRdr"]
+# genalg.GenTools = ["StdHepRdr", "GenPrinter"]
+# genalg.GenTools = ["SLCIORdr", "GenPrinter"]
+# genalg.GenTools = ["HepMCRdr", "GenPrinter"]
+
+##############################################################################
+# Detector Simulation
+##############################################################################
+from Configurables import DetSimSvc
+detsimsvc = DetSimSvc("DetSimSvc")
+
+from Configurables import DetSimAlg
+detsimalg = DetSimAlg("DetSimAlg")
+detsimalg.RandomSeeds = seed
+# detsimalg.VisMacs = ["vis.mac"]
+detsimalg.RunCmds = [
+    #"/tracking/verbose 1",
+]
+detsimalg.AnaElems = [
+    # example_anatool.name()
+    # "ExampleAnaElemTool"
+    "Edm4hepWriterAnaElemTool"
+]
+detsimalg.RootDetElem = "WorldDetElemTool"
+
+from Configurables import AnExampleDetElemTool
+example_dettool = AnExampleDetElemTool("AnExampleDetElemTool")
+
+dedxoption = "BetheBlochEquationDedxSimTool"
+from Configurables import DriftChamberSensDetTool
+dc_sensdettool = DriftChamberSensDetTool("DriftChamberSensDetTool")
+dc_sensdettool.DedxSimTool = dedxoption
+
+from Configurables import DummyDedxSimTool
+from Configurables import BetheBlochEquationDedxSimTool
+
+if dedxoption == "DummyDedxSimTool":
+    dedx_simtool = DummyDedxSimTool("DummyDedxSimTool")
+elif dedxoption == "BetheBlochEquationDedxSimTool":
+    dedx_simtool = BetheBlochEquationDedxSimTool("BetheBlochEquationDedxSimTool")
+    dedx_simtool.material_Z = 2
+    dedx_simtool.material_A = 4
+    dedx_simtool.scale = 10
+    dedx_simtool.resolution = 0.0001
+    
+from Configurables import MarlinEvtSeeder
+evtseeder = MarlinEvtSeeder("EventSeeder")
+
+from Configurables import GearSvc
+gearsvc = GearSvc("GearSvc")
+
+from Configurables import TrackSystemSvc
+tracksystemsvc = TrackSystemSvc("TrackSystemSvc")
+
+# digitization
+vxdhitname  = "VXDTrackerHits"
+sithitname  = "SITTrackerHits"
+dchitname   = "DCTrackerHits"
+sethitname  = "SETTrackerHits"
+setspname   = "SETSpacePoints"
+ftdhitname  = "FTDTrackerHits"
+ftdspname   = "FTDSpacePoints"
+from Configurables import PlanarDigiAlg
+digiVXD = PlanarDigiAlg("VXDDigi")
+digiVXD.SimTrackHitCollection = "VXDCollection"
+digiVXD.TrackerHitCollection = vxdhitname
+digiVXD.ResolutionU = [0.0028, 0.006, 0.004, 0.004, 0.004, 0.004]
+digiVXD.ResolutionV = [0.0028, 0.006, 0.004, 0.004, 0.004, 0.004]
+digiVXD.UsePlanarTag = True
+#digiVXD.OutputLevel = DEBUG
+
+digiSIT = PlanarDigiAlg("SITDigi")
+digiSIT.IsStrip = False
+digiSIT.SimTrackHitCollection = "SITCollection"
+digiSIT.TrackerHitCollection = sithitname
+digiSIT.TrackerHitAssociationCollection = "SITTrackerHitAssociation"
+digiSIT.ResolutionU = [0.0072]
+digiSIT.ResolutionV = [0.086]
+digiSIT.UsePlanarTag = True
+#digiSIT.OutputLevel = DEBUG
+
+digiSET = PlanarDigiAlg("SETDigi")
+digiSET.IsStrip = False
+digiSET.SimTrackHitCollection = "SETCollection"
+digiSET.TrackerHitCollection = sethitname
+digiSET.TrackerHitAssociationCollection = "SETTrackerHitAssociation"
+digiSET.ResolutionU = [0.0072]
+digiSET.ResolutionV = [0.086]
+digiSET.UsePlanarTag = True
+#digiSET.OutputLevel = DEBUG
+
+digiFTD = PlanarDigiAlg("FTDDigi")
+digiFTD.IsStrip = False
+digiFTD.SimTrackHitCollection = "FTDCollection"
+digiFTD.TrackerHitCollection = ftdhitname
+digiFTD.TrackerHitAssociationCollection = "FTDTrackerHitAssociation"
+digiFTD.ResolutionU = [0.003, 0.003, 0.0072, 0.0072, 0.0072, 0.0072, 0.0072]
+digiFTD.ResolutionV = [0.003, 0.003, 0.0072, 0.0072, 0.0072, 0.0072, 0.0072]
+digiFTD.UsePlanarTag = True
+#digiFTD.OutputLevel = DEBUG
+
+from Configurables import DCHDigiAlg
+digiDC = DCHDigiAlg("DCHDigi")
+digiDC.DigiDCHitCollection = dchitname
+digiDC.WriteAna = True
+#digiDC.mom_threshold=98.
+#digiDC.mom_threshold_high=102.
+#digiDC.OutputLevel = DEBUG
+
+# two strip tracker hits -> one space point
+from Configurables import SpacePointBuilderAlg
+spFTD = SpacePointBuilderAlg("FTDBuilder")
+spFTD.TrackerHitCollection = ftdhitname
+spFTD.TrackerHitAssociationCollection = "FTDTrackerHitAssociation"
+spFTD.SpacePointCollection = ftdspname
+spFTD.SpacePointAssociationCollection = "FTDSpacePointAssociation"
+#spFTD.OutputLevel = DEBUG
+
+# tracking
+from Configurables import SiliconTrackingAlg
+tracking = SiliconTrackingAlg("SiliconTracking")
+tracking.HeaderCol = "EventHeader"
+tracking.VTXHitCollection = vxdhitname
+tracking.SITHitCollection = sithitname
+tracking.FTDPixelHitCollection = ftdhitname
+tracking.FTDSpacePointCollection = ftdspname
+tracking.SITRawHitCollection = "NotNeedForPixelSIT"
+tracking.FTDRawHitCollection = ftdhitname
+tracking.UseSIT = True
+tracking.SmoothOn = False
+#tracking.OutputLevel = DEBUG
+
+from Configurables import ForwardTrackingAlg
+forward = ForwardTrackingAlg("ForwardTracking")
+forward.FTDPixelHitCollection = ftdhitname
+forward.FTDSpacePointCollection = ftdspname
+forward.FTDRawHitCollection = ftdhitname
+forward.Chi2ProbCut = 0.0
+forward.HitsPerTrackMin = 3
+forward.BestSubsetFinder = "SubsetSimple"
+forward.Criteria = ["Crit2_DeltaPhi","Crit2_StraightTrackRatio","Crit3_3DAngle","Crit3_ChangeRZRatio","Crit3_IPCircleDist","Crit4_3DAngleChange","Crit4_DistToExtrapolation",
+                    "Crit2_DeltaRho","Crit2_RZRatio","Crit3_PT"]
+forward.CriteriaMin = [0,  0.9,  0,  0.995, 0,  0.8, 0,   20,  1.002, 0.1,      0,   0.99, 0,    0.999, 0,   0.99, 0]
+forward.CriteriaMax = [30, 1.02, 10, 1.015, 20, 1.3, 1.0, 150, 1.08,  99999999, 0.8, 1.01, 0.35, 1.001, 1.5, 1.01, 0.05]
+#forward.OutputLevel = DEBUG
+
+from Configurables import TrackSubsetAlg
+subset = TrackSubsetAlg("TrackSubset")
+subset.TrackInputCollections = ["ForwardTracks", "SiTracks"]
+subset.RawTrackerHitCollections = [vxdhitname, sithitname, ftdhitname, ftdspname]
+subset.TrackSubsetCollection = "SubsetTracks"
+#subset.OutputLevel = DEBUG
+
+##TODO: DC reconstruction, as preliminary, use Clupatra like as TPC
+#from Configurables import ClupatraAlg
+#clupatra = ClupatraAlg("Clupatra")
+#clupatra.TPCHitCollection = dchitname
+#clupatra.DistanceCut = 100.
+#clupatra.MaxDeltaChi2 = 100.
+#clupatra.Chi2Cut = 150.
+##clupatra.OutputLevel = DEBUG
+#
+#from Configurables import FullLDCTrackingAlg
+#full = FullLDCTrackingAlg("FullTracking")
+#full.VTXTrackerHits = vxdhitname
+#full.SITTrackerHits = sithitname
+#full.TPCTrackerHits = dchitname # add TPC or DC tracker hit here, if TPC or DC track is set by full.TPCTracks
+#full.SETTrackerHits = sethitname
+#full.FTDPixelTrackerHits = ftdhitname
+#full.FTDSpacePoints = ftdspname
+#full.SITRawHits     = "NotNeedForPixelSIT"
+#full.SETRawHits     = "NotNeedForPixelSET"
+#full.FTDRawHits     = ftdhitname
+#full.TPCTracks = "ClupatraTracks" # add standalone TPC or DC track here
+#full.SiTracks  = "SubsetTracks"
+#full.OutputTracks  = "MarlinTrkTracks"
+#full.SITHitToTrackDistance = 3.
+#full.SETHitToTrackDistance = 5.
+##full.OutputLevel = DEBUG
+#
+##TODO: more reconstruction, PFA etc.
+
+from Configurables import TruthTrackerAlg
+truthTrackerAlg = TruthTrackerAlg("TruthTrackerAlg")
+truthTrackerAlg.maxDigiCut=500
+truthTrackerAlg.useSi=True
+truthTrackerAlg.hist=True
+#truthTrackerAlg.useNoiseHits=True
+truthTrackerAlg.smearHits=True
+#truthTrackerAlg.useFirstHitForDC=True
+#truthTrackerAlg.useIdealHit=False
+truthTrackerAlg.DigiDCHitCollection="DCTrackerHits"
+#truthTrackerAlg.OutputLevel=DEBUG
+##############################################################################
+# GenfitAlg
+##############################################################################
+from Configurables import RecGenfitAlgSDT
+recGenfitAlgSDT = RecGenfitAlgSDT("RecGenfitAlgSDT")
+recGenfitAlgSDT.debugPid=1
+#recGenfitAlgSDT.debug=10
+#recGenfitAlgSDT.debugGenfit=10000
+recGenfitAlgSDT.DigiDCHitCollection="DCTrackerHits"
+recGenfitAlgSDT.SmearDCHitAssociationCollection = "SmearDCHitAssociationCollection"
+#recGenfitAlgSDT.OutputLevel=DEBUG
+recGenfitAlgSDT.measurementTypeSi=1 # -1: not use, 0:use space point, 1:use detector measurment
+recGenfitAlgSDT.measurementTypeDC=1 # -1: not use, 0:use space point, 1:use detector measurment
+#recGenfitAlgSDT.sigmaHitU=[0.11, 0.0028, 0.006, 0.004, 0.004, 0.004, 0.004]
+#recGenfitAlgSDT.sigmaHitV=[0.2, 0.0028, 0.006, 0.004, 0.004, 0.004, 0.004]
+
+from Configurables import NTupleSvc
+ntsvc = NTupleSvc("NTupleSvc")
+ntsvc.Output = ["MyTuples DATAFILE='DCH_digi.root' OPT='NEW' TYP='ROOT'",
+    "TruthTrackerAlg DATAFILE='truthTracker.root' OPT='NEW' TYP='ROOT'",
+    "RecGenfitAlgSDT DATAFILE='fit.root' OPT='NEW' TYP='ROOT'"
+]
+
+###############################################################################
+## Event service
+###############################################################################
+#from Configurables import k4DataSvc
+#dsvc = k4DataSvc("EventDataSvc",
+#    #input = "CRD-o1-v01-SimDigi00_1k.root"
+#    input = "test-detsim10.root"
+#)
+#from Configurables import PodioInput
+#podioinput = PodioInput("PodioReader", collections=[
+#        #"EventHeader",
+#        "MCParticle",
+#        "DriftChamberHitsCollection",
+#        "VXDCollection",
+#        "SITCollection",
+#        "SETCollection",
+#        #"DCHitAssociationCollection",
+#])
+
+# output
+from Configurables import PodioOutput
+out = PodioOutput("outputalg")
+out.filename = "CRD-o1-v01-onlyTracker.root"
+out.outputCommands = ["keep *"]
+
+# ApplicationMgr
+from Configurables import ApplicationMgr
+ApplicationMgr(
+    #TopAlg = [ genalg, detsimalg, digiVXD, digiSIT, digiSET, digiFTD, spFTD, digiDC, tracking, forward, subset, out],
+    #TopAlg = [podioinput,  digiVXD, digiSIT, digiSET, digiFTD, spFTD, digiDC, tracking, forward, subset, truthTrackerAlg, recGenfitAlgSDT, out],
+    TopAlg = [genalg, detsimalg, digiVXD, digiSIT, digiSET, digiFTD, spFTD, digiDC, tracking, forward, subset, truthTrackerAlg, recGenfitAlgSDT, out],
+    EvtSel = 'NONE',
+    EvtMax = 10,
+    ExtSvc = [rndmengine, rndmgensvc, dsvc, evtseeder, geosvc, gearsvc, ntsvc],
+    HistogramPersistency = 'ROOT',
+    OutputLevel = ERROR
+)
diff --git a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp
index 7b2b7afe2..0d5100b62 100644
--- a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp
+++ b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp
@@ -232,7 +232,7 @@ StatusCode TruthTrackerAlg::execute()
     //mcRecoTrackerAssociationCol=m_mcRecoParticleAssociation.get();
 
     ///New SDT track
-    edm4hep::MutableTrack sdtTk=sdtTkCol->create();
+    edm4hep::Track sdtTk=sdtTkCol->create();
 
     int nVXDHit=0;
     int nSITHit=0;
@@ -316,7 +316,7 @@ StatusCode TruthTrackerAlg::execute()
 
     if(m_useDC){
         ///Create DC Track
-        edm4hep::MutableTrack dcTrack=dcTrackCol->create();
+        edm4hep::Track dcTrack=dcTrackCol->create();
 
         //Create TrackState
         edm4hep::TrackState trackStateFirstDCHit;
@@ -458,10 +458,8 @@ void TruthTrackerAlg::getTrackStateFromMcParticle(
         trackState.Z0=helix.getZ0();
         trackState.tanLambda=helix.getTanLambda();
         trackState.referencePoint=helix.getReferencePoint();
-
-        decltype(trackState.covMatrix) covMatrix;
-        for(int i=0;i<covMatrix.size();i++){covMatrix[i]=999.;}//FIXME
-
+        std::array<float,15> covMatrix;
+        for(int i=0;i<15;i++){covMatrix[i]=1.;}//FIXME
         trackState.covMatrix=covMatrix;
 
         getCircleFromPosMom(pos,mom,B[2]/dd4hep::tesla,mcParticle.getCharge(),m_helixRadius,m_helixXC,m_helixYC);
@@ -528,8 +526,8 @@ bool TruthTrackerAlg::getTrackStateFirstHit(
         trackState.Z0=helix.getZ0();
         trackState.tanLambda=helix.getTanLambda();
         trackState.referencePoint=helix.getReferencePoint();
-        std::array<float,21> covMatrix;
-        for(int i=0;i<21;i++){covMatrix[i]=100.;}//FIXME
+        std::array<float,15> covMatrix;
+        for(int i=0;i<15;i++){covMatrix[i]=100.;}//FIXME
         trackState.covMatrix=covMatrix;
         debug()<<"first hit trackState "<<trackState<<endmsg;
         return true;
@@ -593,7 +591,7 @@ void TruthTrackerAlg::debugEvent()
 
 int TruthTrackerAlg::addIdealHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
         colHandle, edm4hep::TrackerHitCollection*& truthTrackerHitCol,
-        edm4hep::MutableTrack& track, const char* msg,int nHitAdded)
+        edm4hep::Track& track, const char* msg,int nHitAdded)
 {
     if(nHitAdded>0) return nHitAdded;
     int nHit=0;
@@ -616,7 +614,7 @@ int TruthTrackerAlg::addIdealHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
 
         //add modified hit
         auto tmpHit = truthTrackerHitCol->create();
-        tmpHit=hit.clone();
+        tmpHit=hit;
         tmpHit.setTime(fabs(docaIdeal)*1e3/40.);//40#um/ns, drift time in ns
         track.addToTrackerHits(tmpHit);
 
@@ -667,7 +665,7 @@ int TruthTrackerAlg::makeNoiseHit(edm4hep::SimTrackerHitCollection* SimVec,
         trkHit.setCellID(wcellid);
         trkHit.setTime(pocaTime);
         trkHit.setEDep(mcHit.getEDep());
-        //trkHit.setEdx(mcHit.getEdx());
+        trkHit.setEdx(mcHit.getEdx());
         trkHit.setPosition(mcHit.getPosition());
         trkHit.setCovMatrix(mcHit.getCovMatrix());
         for(int iAsso=0;iAsso<(int) assoHits->size();iAsso++)
@@ -755,7 +753,7 @@ int TruthTrackerAlg::smearDCTkhit(DataHandle<edm4hep::TrackerHitCollection>&
         smearHit.setQuality(hit.getQuality());
         smearHit.setEDep(hit.getEDep());
         smearHit.setEDepError(hit.getEDepError());
-        //smearHit.setEdx(hit.getEdx());
+        smearHit.setEdx(hit.getEdx());
         smearHit.setPosition(hit.getPosition());
         smearHit.setCovMatrix(hit.getCovMatrix());
         smearHit.addToRawHits(hit.getObjectID());
@@ -791,7 +789,7 @@ int TruthTrackerAlg::smearDCTkhit(DataHandle<edm4hep::TrackerHitCollection>&
 }
 
 int TruthTrackerAlg::addHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
-        colHandle, edm4hep::MutableTrack& track, const char* msg,int nHitAdded)
+        colHandle, edm4hep::Track& track, const char* msg,int nHitAdded)
 {
     if(nHitAdded>0) return nHitAdded;
     int nHit=0;
@@ -808,7 +806,7 @@ int TruthTrackerAlg::addHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
 int TruthTrackerAlg::addSimHitsToTk(
         DataHandle<edm4hep::SimTrackerHitCollection>& colHandle,
         edm4hep::TrackerHitCollection*& truthTrackerHitCol,
-        edm4hep::MutableTrack& track, const char* msg,int nHitAdded)
+        edm4hep::Track& track, const char* msg,int nHitAdded)
 {
     if(nHitAdded>0) return nHitAdded;
     int nHit=0;
@@ -863,12 +861,12 @@ int TruthTrackerAlg::addSimHitsToTk(
 }
 
 int TruthTrackerAlg::addHotsToTk(edm4hep::Track& sourceTrack,
-        edm4hep::MutableTrack& targetTrack, int hitType,const char* msg,int nHitAdded)
+        edm4hep::Track& targetTrack, int hitType,const char* msg,int nHitAdded)
 {
     if(nHitAdded>0) return nHitAdded;
     int nHit=0;
     for(unsigned int iHit=0;iHit<sourceTrack.trackerHits_size();iHit++){
-        edm4hep::TrackerHit hit=sourceTrack.getTrackerHits(iHit);
+        edm4hep::ConstTrackerHit hit=sourceTrack.getTrackerHits(iHit);
         UTIL::BitField64 encoder(lcio::ILDCellID0::encoder_string);
         encoder.setValue(hit.getCellID());
         if(encoder[lcio::ILDCellID0::subdet]==hitType){
@@ -887,7 +885,7 @@ int TruthTrackerAlg::nHotsOnTrack(edm4hep::Track& track, int hitType)
 {
     int nHit=0;
     for(unsigned int iHit=0;iHit<track.trackerHits_size();iHit++){
-        edm4hep::TrackerHit hit=track.getTrackerHits(iHit);
+        edm4hep::ConstTrackerHit hit=track.getTrackerHits(iHit);
         UTIL::BitField64 encoder(lcio::ILDCellID0::encoder_string);
         encoder.setValue(hit.getCellID());
         if(encoder[lcio::ILDCellID0::subdet]==hitType){
diff --git a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h
index 563d98543..32136cd4c 100644
--- a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h
+++ b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h
@@ -22,7 +22,6 @@ namespace edm4hep {
     class TrackerHitCollection;
     class TrackCollection;
     class Track;
-    class MutableTrack;
     class TrackState;
     class ReconstructedParticleCollection;
     class MCRecoTrackerAssociationCollection;
@@ -43,7 +42,7 @@ class TruthTrackerAlg: public GaudiAlgorithm
                 mcParticleCol, edm4hep::TrackState& stat);
         int addSimHitsToTk(DataHandle<edm4hep::SimTrackerHitCollection>&
                 colHandle, edm4hep::TrackerHitCollection*& truthTrackerHitCol,
-                edm4hep::MutableTrack& track, const char* msg,int nHitAdded);
+                edm4hep::Track& track, const char* msg,int nHitAdded);
         int smearDCTkhit(DataHandle<edm4hep::TrackerHitCollection>&
                 colHandle,DataHandle<edm4hep::TrackerHitCollection>& smearCol,
                 DataHandle<edm4hep::SimTrackerHitCollection>& SimDCHitCol,
@@ -52,12 +51,12 @@ class TruthTrackerAlg: public GaudiAlgorithm
                 DataHandle<edm4hep::MCRecoTrackerAssociationCollection>& AssoSmearDCHitCol,
                 double resX, double resY, double resZ);
         int addHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
-                colHandle, edm4hep::MutableTrack& track, const char* msg,int nHitAdded);
+                colHandle, edm4hep::Track& track, const char* msg,int nHitAdded);
         int addIdealHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
                 colHandle, edm4hep::TrackerHitCollection*& truthTrackerHitCol,
-                edm4hep::MutableTrack& track, const char* msg,int nHitAdded);
+                edm4hep::Track& track, const char* msg,int nHitAdded);
 
-        int addHotsToTk(edm4hep::Track& sourceTrack,edm4hep::MutableTrack&
+        int addHotsToTk(edm4hep::Track& sourceTrack,edm4hep::Track&
                 targetTrack, int hitType,const char* msg,int nHitAdded);
         int nHotsOnTrack(edm4hep::Track& track, int hitType);
         int trackerHitColSize(DataHandle<edm4hep::TrackerHitCollection>& hitCol);

From 0c9a9312aebaf3a127261d25b3b92be7d6ae199a Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Thu, 5 Jan 2023 23:16:00 +0800
Subject: [PATCH 18/27] fixed script

---
 Examples/options/tut_detsim_rec_SDT.py | 322 -------------------------
 1 file changed, 322 deletions(-)
 delete mode 100644 Examples/options/tut_detsim_rec_SDT.py

diff --git a/Examples/options/tut_detsim_rec_SDT.py b/Examples/options/tut_detsim_rec_SDT.py
deleted file mode 100644
index 02ac7612f..000000000
--- a/Examples/options/tut_detsim_rec_SDT.py
+++ /dev/null
@@ -1,322 +0,0 @@
-#!/usr/bin/env python
-from Gaudi.Configuration import *
-
-from Configurables import k4DataSvc
-dsvc = k4DataSvc("EventDataSvc")
-
-from Configurables import RndmGenSvc, HepRndm__Engine_CLHEP__RanluxEngine_
-seed = [10]
-# rndmengine = HepRndm__Engine_CLHEP__RanluxEngine_() # The default engine in Gaudi
-rndmengine = HepRndm__Engine_CLHEP__HepJamesRandom_("RndmGenSvc.Engine") # The default engine in Geant4
-rndmengine.SetSingleton = True
-rndmengine.Seeds = seed
-
-rndmgensvc = RndmGenSvc("RndmGenSvc")
-rndmgensvc.Engine = rndmengine.name()
-
-##############################################################################
-# Event Data Svc
-##############################################################################
-from Configurables import k4DataSvc
-dsvc = k4DataSvc("EventDataSvc")
-
-
-# option for standalone tracker study
-geometry_option = "CRD_o1_v01/CRD_o1_v01-onlyTracker.xml"
-#geometry_option = "CRD_o1_v01/CRD_o1_v01-onlyTracker_noWire_18.xml"
-#geometry_option = "CRD_o1_v01/CRD_o1_v01.xml"
-
-if not os.getenv("DETCRDROOT"):
-    print("Can't find the geometry. Please setup envvar DETCRDROOT." )
-    sys.exit(-1)
-
-geometry_path = os.path.join(os.getenv("DETCRDROOT"), "compact", geometry_option)
-if not os.path.exists(geometry_path):
-    print("Can't find the compact geometry file: %s"%geometry_path)
-    sys.exit(-1)
-
-from Configurables import GeomSvc
-geosvc = GeomSvc("GeomSvc")
-geosvc.compact = geometry_path
-
-##############################################################################
-# Physics Generator
-##############################################################################
-from Configurables import GenAlgo
-from Configurables import GtGunTool
-from Configurables import StdHepRdr
-from Configurables import SLCIORdr
-from Configurables import HepMCRdr
-from Configurables import GenPrinter
-gun = GtGunTool("GtGunTool")
-gun.Particles = ["mu-"]
-gun.EnergyMins = [40] # GeV
-gun.EnergyMaxs = [40] # GeV
-gun.ThetaMins  = [85]    # deg
-gun.ThetaMaxs  = [85]  # deg
-gun.PhiMins    = [0]    # deg
-gun.PhiMaxs    = [360]  # deg
-# stdheprdr = StdHepRdr("StdHepRdr")
-# stdheprdr.Input = "/cefs/data/stdhep/CEPC250/2fermions/E250.Pbhabha.e0.p0.whizard195/bhabha.e0.p0.00001.stdhep"
-# lciordr = SLCIORdr("SLCIORdr")
-# lciordr.Input = "/cefs/data/stdhep/lcio250/signal/Higgs/E250.Pbbh.whizard195/E250.Pbbh_X.e0.p0.whizard195/Pbbh_X.e0.p0.00001.slcio"
-# hepmcrdr = HepMCRdr("HepMCRdr")
-# hepmcrdr.Input = "example_UsingIterators.txt"
-
-genprinter = GenPrinter("GenPrinter")
-
-genalg = GenAlgo("GenAlgo")
-genalg.GenTools = ["GtGunTool"]
-#genalg.GenTools = ["StdHepRdr"]
-# genalg.GenTools = ["StdHepRdr", "GenPrinter"]
-# genalg.GenTools = ["SLCIORdr", "GenPrinter"]
-# genalg.GenTools = ["HepMCRdr", "GenPrinter"]
-
-##############################################################################
-# Detector Simulation
-##############################################################################
-from Configurables import DetSimSvc
-detsimsvc = DetSimSvc("DetSimSvc")
-
-from Configurables import DetSimAlg
-detsimalg = DetSimAlg("DetSimAlg")
-detsimalg.RandomSeeds = seed
-# detsimalg.VisMacs = ["vis.mac"]
-detsimalg.RunCmds = [
-    #"/tracking/verbose 1",
-]
-detsimalg.AnaElems = [
-    # example_anatool.name()
-    # "ExampleAnaElemTool"
-    "Edm4hepWriterAnaElemTool"
-]
-detsimalg.RootDetElem = "WorldDetElemTool"
-
-from Configurables import AnExampleDetElemTool
-example_dettool = AnExampleDetElemTool("AnExampleDetElemTool")
-
-dedxoption = "BetheBlochEquationDedxSimTool"
-from Configurables import DriftChamberSensDetTool
-dc_sensdettool = DriftChamberSensDetTool("DriftChamberSensDetTool")
-dc_sensdettool.DedxSimTool = dedxoption
-
-from Configurables import DummyDedxSimTool
-from Configurables import BetheBlochEquationDedxSimTool
-
-if dedxoption == "DummyDedxSimTool":
-    dedx_simtool = DummyDedxSimTool("DummyDedxSimTool")
-elif dedxoption == "BetheBlochEquationDedxSimTool":
-    dedx_simtool = BetheBlochEquationDedxSimTool("BetheBlochEquationDedxSimTool")
-    dedx_simtool.material_Z = 2
-    dedx_simtool.material_A = 4
-    dedx_simtool.scale = 10
-    dedx_simtool.resolution = 0.0001
-    
-from Configurables import MarlinEvtSeeder
-evtseeder = MarlinEvtSeeder("EventSeeder")
-
-from Configurables import GearSvc
-gearsvc = GearSvc("GearSvc")
-
-from Configurables import TrackSystemSvc
-tracksystemsvc = TrackSystemSvc("TrackSystemSvc")
-
-# digitization
-vxdhitname  = "VXDTrackerHits"
-sithitname  = "SITTrackerHits"
-dchitname   = "DCTrackerHits"
-sethitname  = "SETTrackerHits"
-setspname   = "SETSpacePoints"
-ftdhitname  = "FTDTrackerHits"
-ftdspname   = "FTDSpacePoints"
-from Configurables import PlanarDigiAlg
-digiVXD = PlanarDigiAlg("VXDDigi")
-digiVXD.SimTrackHitCollection = "VXDCollection"
-digiVXD.TrackerHitCollection = vxdhitname
-digiVXD.ResolutionU = [0.0028, 0.006, 0.004, 0.004, 0.004, 0.004]
-digiVXD.ResolutionV = [0.0028, 0.006, 0.004, 0.004, 0.004, 0.004]
-digiVXD.UsePlanarTag = True
-#digiVXD.OutputLevel = DEBUG
-
-digiSIT = PlanarDigiAlg("SITDigi")
-digiSIT.IsStrip = False
-digiSIT.SimTrackHitCollection = "SITCollection"
-digiSIT.TrackerHitCollection = sithitname
-digiSIT.TrackerHitAssociationCollection = "SITTrackerHitAssociation"
-digiSIT.ResolutionU = [0.0072]
-digiSIT.ResolutionV = [0.086]
-digiSIT.UsePlanarTag = True
-#digiSIT.OutputLevel = DEBUG
-
-digiSET = PlanarDigiAlg("SETDigi")
-digiSET.IsStrip = False
-digiSET.SimTrackHitCollection = "SETCollection"
-digiSET.TrackerHitCollection = sethitname
-digiSET.TrackerHitAssociationCollection = "SETTrackerHitAssociation"
-digiSET.ResolutionU = [0.0072]
-digiSET.ResolutionV = [0.086]
-digiSET.UsePlanarTag = True
-#digiSET.OutputLevel = DEBUG
-
-digiFTD = PlanarDigiAlg("FTDDigi")
-digiFTD.IsStrip = False
-digiFTD.SimTrackHitCollection = "FTDCollection"
-digiFTD.TrackerHitCollection = ftdhitname
-digiFTD.TrackerHitAssociationCollection = "FTDTrackerHitAssociation"
-digiFTD.ResolutionU = [0.003, 0.003, 0.0072, 0.0072, 0.0072, 0.0072, 0.0072]
-digiFTD.ResolutionV = [0.003, 0.003, 0.0072, 0.0072, 0.0072, 0.0072, 0.0072]
-digiFTD.UsePlanarTag = True
-#digiFTD.OutputLevel = DEBUG
-
-from Configurables import DCHDigiAlg
-digiDC = DCHDigiAlg("DCHDigi")
-digiDC.DigiDCHitCollection = dchitname
-digiDC.WriteAna = True
-#digiDC.mom_threshold=98.
-#digiDC.mom_threshold_high=102.
-#digiDC.OutputLevel = DEBUG
-
-# two strip tracker hits -> one space point
-from Configurables import SpacePointBuilderAlg
-spFTD = SpacePointBuilderAlg("FTDBuilder")
-spFTD.TrackerHitCollection = ftdhitname
-spFTD.TrackerHitAssociationCollection = "FTDTrackerHitAssociation"
-spFTD.SpacePointCollection = ftdspname
-spFTD.SpacePointAssociationCollection = "FTDSpacePointAssociation"
-#spFTD.OutputLevel = DEBUG
-
-# tracking
-from Configurables import SiliconTrackingAlg
-tracking = SiliconTrackingAlg("SiliconTracking")
-tracking.HeaderCol = "EventHeader"
-tracking.VTXHitCollection = vxdhitname
-tracking.SITHitCollection = sithitname
-tracking.FTDPixelHitCollection = ftdhitname
-tracking.FTDSpacePointCollection = ftdspname
-tracking.SITRawHitCollection = "NotNeedForPixelSIT"
-tracking.FTDRawHitCollection = ftdhitname
-tracking.UseSIT = True
-tracking.SmoothOn = False
-#tracking.OutputLevel = DEBUG
-
-from Configurables import ForwardTrackingAlg
-forward = ForwardTrackingAlg("ForwardTracking")
-forward.FTDPixelHitCollection = ftdhitname
-forward.FTDSpacePointCollection = ftdspname
-forward.FTDRawHitCollection = ftdhitname
-forward.Chi2ProbCut = 0.0
-forward.HitsPerTrackMin = 3
-forward.BestSubsetFinder = "SubsetSimple"
-forward.Criteria = ["Crit2_DeltaPhi","Crit2_StraightTrackRatio","Crit3_3DAngle","Crit3_ChangeRZRatio","Crit3_IPCircleDist","Crit4_3DAngleChange","Crit4_DistToExtrapolation",
-                    "Crit2_DeltaRho","Crit2_RZRatio","Crit3_PT"]
-forward.CriteriaMin = [0,  0.9,  0,  0.995, 0,  0.8, 0,   20,  1.002, 0.1,      0,   0.99, 0,    0.999, 0,   0.99, 0]
-forward.CriteriaMax = [30, 1.02, 10, 1.015, 20, 1.3, 1.0, 150, 1.08,  99999999, 0.8, 1.01, 0.35, 1.001, 1.5, 1.01, 0.05]
-#forward.OutputLevel = DEBUG
-
-from Configurables import TrackSubsetAlg
-subset = TrackSubsetAlg("TrackSubset")
-subset.TrackInputCollections = ["ForwardTracks", "SiTracks"]
-subset.RawTrackerHitCollections = [vxdhitname, sithitname, ftdhitname, ftdspname]
-subset.TrackSubsetCollection = "SubsetTracks"
-#subset.OutputLevel = DEBUG
-
-##TODO: DC reconstruction, as preliminary, use Clupatra like as TPC
-#from Configurables import ClupatraAlg
-#clupatra = ClupatraAlg("Clupatra")
-#clupatra.TPCHitCollection = dchitname
-#clupatra.DistanceCut = 100.
-#clupatra.MaxDeltaChi2 = 100.
-#clupatra.Chi2Cut = 150.
-##clupatra.OutputLevel = DEBUG
-#
-#from Configurables import FullLDCTrackingAlg
-#full = FullLDCTrackingAlg("FullTracking")
-#full.VTXTrackerHits = vxdhitname
-#full.SITTrackerHits = sithitname
-#full.TPCTrackerHits = dchitname # add TPC or DC tracker hit here, if TPC or DC track is set by full.TPCTracks
-#full.SETTrackerHits = sethitname
-#full.FTDPixelTrackerHits = ftdhitname
-#full.FTDSpacePoints = ftdspname
-#full.SITRawHits     = "NotNeedForPixelSIT"
-#full.SETRawHits     = "NotNeedForPixelSET"
-#full.FTDRawHits     = ftdhitname
-#full.TPCTracks = "ClupatraTracks" # add standalone TPC or DC track here
-#full.SiTracks  = "SubsetTracks"
-#full.OutputTracks  = "MarlinTrkTracks"
-#full.SITHitToTrackDistance = 3.
-#full.SETHitToTrackDistance = 5.
-##full.OutputLevel = DEBUG
-#
-##TODO: more reconstruction, PFA etc.
-
-from Configurables import TruthTrackerAlg
-truthTrackerAlg = TruthTrackerAlg("TruthTrackerAlg")
-truthTrackerAlg.maxDigiCut=500
-truthTrackerAlg.useSi=True
-truthTrackerAlg.hist=True
-#truthTrackerAlg.useNoiseHits=True
-truthTrackerAlg.smearHits=True
-#truthTrackerAlg.useFirstHitForDC=True
-#truthTrackerAlg.useIdealHit=False
-truthTrackerAlg.DigiDCHitCollection="DCTrackerHits"
-#truthTrackerAlg.OutputLevel=DEBUG
-##############################################################################
-# GenfitAlg
-##############################################################################
-from Configurables import RecGenfitAlgSDT
-recGenfitAlgSDT = RecGenfitAlgSDT("RecGenfitAlgSDT")
-recGenfitAlgSDT.debugPid=1
-#recGenfitAlgSDT.debug=10
-#recGenfitAlgSDT.debugGenfit=10000
-recGenfitAlgSDT.DigiDCHitCollection="DCTrackerHits"
-recGenfitAlgSDT.SmearDCHitAssociationCollection = "SmearDCHitAssociationCollection"
-#recGenfitAlgSDT.OutputLevel=DEBUG
-recGenfitAlgSDT.measurementTypeSi=1 # -1: not use, 0:use space point, 1:use detector measurment
-recGenfitAlgSDT.measurementTypeDC=1 # -1: not use, 0:use space point, 1:use detector measurment
-#recGenfitAlgSDT.sigmaHitU=[0.11, 0.0028, 0.006, 0.004, 0.004, 0.004, 0.004]
-#recGenfitAlgSDT.sigmaHitV=[0.2, 0.0028, 0.006, 0.004, 0.004, 0.004, 0.004]
-
-from Configurables import NTupleSvc
-ntsvc = NTupleSvc("NTupleSvc")
-ntsvc.Output = ["MyTuples DATAFILE='DCH_digi.root' OPT='NEW' TYP='ROOT'",
-    "TruthTrackerAlg DATAFILE='truthTracker.root' OPT='NEW' TYP='ROOT'",
-    "RecGenfitAlgSDT DATAFILE='fit.root' OPT='NEW' TYP='ROOT'"
-]
-
-###############################################################################
-## Event service
-###############################################################################
-#from Configurables import k4DataSvc
-#dsvc = k4DataSvc("EventDataSvc",
-#    #input = "CRD-o1-v01-SimDigi00_1k.root"
-#    input = "test-detsim10.root"
-#)
-#from Configurables import PodioInput
-#podioinput = PodioInput("PodioReader", collections=[
-#        #"EventHeader",
-#        "MCParticle",
-#        "DriftChamberHitsCollection",
-#        "VXDCollection",
-#        "SITCollection",
-#        "SETCollection",
-#        #"DCHitAssociationCollection",
-#])
-
-# output
-from Configurables import PodioOutput
-out = PodioOutput("outputalg")
-out.filename = "CRD-o1-v01-onlyTracker.root"
-out.outputCommands = ["keep *"]
-
-# ApplicationMgr
-from Configurables import ApplicationMgr
-ApplicationMgr(
-    #TopAlg = [ genalg, detsimalg, digiVXD, digiSIT, digiSET, digiFTD, spFTD, digiDC, tracking, forward, subset, out],
-    #TopAlg = [podioinput,  digiVXD, digiSIT, digiSET, digiFTD, spFTD, digiDC, tracking, forward, subset, truthTrackerAlg, recGenfitAlgSDT, out],
-    TopAlg = [genalg, detsimalg, digiVXD, digiSIT, digiSET, digiFTD, spFTD, digiDC, tracking, forward, subset, truthTrackerAlg, recGenfitAlgSDT, out],
-    EvtSel = 'NONE',
-    EvtMax = 10,
-    ExtSvc = [rndmengine, rndmgensvc, dsvc, evtseeder, geosvc, gearsvc, ntsvc],
-    HistogramPersistency = 'ROOT',
-    OutputLevel = ERROR
-)

From 5664a316ad0170d1b72548d87425c7e2b5d81983 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Fri, 6 Jan 2023 16:13:54 +0800
Subject: [PATCH 19/27] Fixed some insecure bugs

---
 .../CRD_o1_v01/CRD_o1_v01-onlyTracker.xml     |  2 +-
 .../RecGenfitAlg/src/GenfitTrack.cpp          | 43 +++++----
 .../RecGenfitAlg/src/RecGenfitAlgSDT.cpp      | 95 ++++++++++---------
 .../src/TruthTracker/TruthTrackerAlg.cpp      | 33 +++----
 .../src/TruthTracker/TruthTrackerAlg.h        |  9 +-
 Utilities/DataHelper/src/TrackHelper.cc       |  5 +-
 run.sh                                        |  2 +-
 7 files changed, 100 insertions(+), 89 deletions(-)

diff --git a/Detector/DetCRD/compact/CRD_o1_v01/CRD_o1_v01-onlyTracker.xml b/Detector/DetCRD/compact/CRD_o1_v01/CRD_o1_v01-onlyTracker.xml
index d8c788d21..b4d34f857 100644
--- a/Detector/DetCRD/compact/CRD_o1_v01/CRD_o1_v01-onlyTracker.xml
+++ b/Detector/DetCRD/compact/CRD_o1_v01/CRD_o1_v01-onlyTracker.xml
@@ -32,7 +32,7 @@
   <include ref="../CRD_common_v01/VXD_v01_01.xml"/>
   <include ref="../CRD_common_v01/FTD_SkewRing_v01_01.xml"/>
   <include ref="../CRD_common_v01/SIT_SimplePixel_v01_01.xml"/>
-  <include ref="../CRD_common_v01/DC_Simple_v01_03.xml"/>
+  <include ref="../CRD_common_v01/DC_Simple_v01_04_noWire.xml"/>
   <include ref="../CRD_common_v01/SET_SimplePixel_v01_01.xml"/>
   
   <fields>
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp b/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp
index 5f2c9475f..1b154b957 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp
+++ b/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp
@@ -1019,33 +1019,33 @@ bool GenfitTrack::debugDistance(const edm4hep::TrackerHitCollection* dCDigiCol,
     int SDTHit = 0;
     unsigned int nPoints = m_track->getNumPoints();
     for(unsigned int i = 0; i<nPoints; i++){
-      genfit::TrackPoint* point = m_track->getPoint(i);
-      genfit::AbsMeasurement* absMea = point->getRawMeasurement();
-      genfit::PlanarMeasurementSDT* sdtMea =
-          dynamic_cast<genfit::PlanarMeasurementSDT*>(absMea);
-      if(sdtMea){
-        const edm4hep::TrackerHit* TrackerHit_ = sdtMea->getTrackerHit();
-        SDTHit++;
-      }else{
-        WireMeasurementDC* dcMea =
-            dynamic_cast<WireMeasurementDC*>(absMea);
-        if(dcMea){
-          const edm4hep::TrackerHit* TrackerHit_ = dcMea->getTrackerHit();
-          smearDistance.push_back(1e-3*driftVelocity*TrackerHit_->getTime());
-          DCHit++;
-          for(auto dcDigi: *dCDigiCol){
-            if(dcDigi.getCellID() == TrackerHit_->getCellID())
-            {
-                truthDistance.push_back(1e-3*driftVelocity*(dcDigi.getTime()));
+        genfit::TrackPoint* point = m_track->getPoint(i);
+        genfit::AbsMeasurement* absMea = point->getRawMeasurement();
+        genfit::PlanarMeasurementSDT* sdtMea =
+            dynamic_cast<genfit::PlanarMeasurementSDT*>(absMea);
+        if(sdtMea){
+            const edm4hep::TrackerHit* TrackerHit_ = sdtMea->getTrackerHit();
+            SDTHit++;
+        }else{
+            WireMeasurementDC* dcMea =
+                dynamic_cast<WireMeasurementDC*>(absMea);
+            if(dcMea){
+                const edm4hep::TrackerHit* TrackerHit_ = dcMea->getTrackerHit();
+                smearDistance.push_back(1e-3*driftVelocity*TrackerHit_->getTime());
+                DCHit++;
+                for(auto dcDigi: *dCDigiCol){
+                    if(dcDigi.getCellID() == TrackerHit_->getCellID())
+                    {
+                        truthDistance.push_back(1e-3*driftVelocity*(dcDigi.getTime()));
+                    }
+                }
             }
-          }
         }
-      }
     }
 
     DCHit = nFittedDC;
     SDTHit = nFittedSDT;
-    ngenfitHit = nFittedDC+nFittedDC;
+    ngenfitHit = nFittedSDT+nFittedDC;
 
     return true;
 }
@@ -1186,6 +1186,7 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
     if(m_debug>0)std::cout<<m_name<<" store track ndfCut "<<ndfCut<<" chi2Cut "
         <<chi2Cut<<std::endl;
 
+
     /// Get fit status
     const genfit::FitStatus* fitState = getFitStatus();
     double ndf = fitState->getNdf();
diff --git a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
index ee56ab6e5..8e015c943 100644
--- a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
+++ b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
@@ -273,7 +273,7 @@ StatusCode RecGenfitAlgSDT::initialize()
             //10 is greater than # of tracking detectors
             sc=m_tuple->addItem("hitDetID",10,m_nHitDetType);
             sc=m_tuple->addItem("nHitWithFitInfo",m_mcIndex,m_nHitWithFitInfo,5);
-            sc=m_tuple->addItem("nSimDCHit",m_nSimDCHit,0,500000);
+            sc=m_tuple->addItem("nSimDCHit",m_nSimDCHit,0,10000000);
             sc=m_tuple->addItem("mdcHitDriftT",m_nSimDCHit,m_mdcHitDriftT);
             sc=m_tuple->addItem("mdcHitDriftDl",m_nSimDCHit,m_mdcHitDriftDl);
             sc=m_tuple->addItem("mdcHitDriftDr",m_nSimDCHit,m_mdcHitDriftDr);
@@ -430,6 +430,7 @@ StatusCode RecGenfitAlgSDT::execute()
     std::vector<double> Res;
     for(auto sdtTrack: *sdtTrackCol)
     {
+        if(sdtTrack.trackerHits_size()<1e-9) continue;
         ///Loop over 5 particle hypothesis(0-4): e,mu,pi,K,p
         ///-1 for chargedgeantino
         for(unsigned int pidType=0;pidType<m_nPDG;pidType++)
@@ -451,11 +452,11 @@ StatusCode RecGenfitAlgSDT::execute()
             //        return StatusCode::SUCCESS;
             //    }
             //}else{
-std::cout << " sdtTrack size = " << sdtTrack.trackerHits_size() << std::endl;
             if(!genfitTrack->createGenfitTrackFromEDM4HepTrack(pidType,
                         sdtTrack, eventStartTime,m_isUseCovTrack)){
                 debug()<<"createGenfitTrackFromEDM4HepTrack from SDT track failed!"<<endmsg;
-                return StatusCode::SUCCESS;
+                delete genfitTrack;
+                continue;
             }
             //}
 
@@ -506,7 +507,8 @@ std::cout << " sdtTrack size = " << sdtTrack.trackerHits_size() << std::endl;
             // skip events w.o hits
             if(0==nHitAdded){
                 debug()<<m_eventNo<<" No hit added to track!"<<endmsg;
-                return StatusCode::SUCCESS;
+                delete genfitTrack;
+                continue;
             }
             if(m_debug) genfitTrack->printSeed();
 
@@ -787,6 +789,7 @@ void RecGenfitAlgSDT::debugEvent(const edm4hep::TrackCollection* sdtTrackCol,
     m_nSdtTrack=sdtTrackCol->size();
     for(auto sdtTrack: *sdtTrackCol){
         m_nSdtTrackHit = sdtTrack.trackerHits_size();
+        if(sdtTrack.trackerHits_size()<1e-9) continue;
         for(int ihit=0;ihit<sdtTrack.trackerHits_size();ihit++){
             edm4hep::TrackerHit sdtTrackHit = sdtTrack.getTrackerHits(ihit);
         }
@@ -829,48 +832,50 @@ void RecGenfitAlgSDT::debugEvent(const edm4hep::TrackCollection* sdtTrackCol,
 
     m_pidIndex=5;
 
-    mcParticleCol=m_mcParticleCol.get();
-    int iMcParticle=0;
-    HelixClass helix_mcP;
-    for(auto mcParticle : *mcParticleCol){
-        edm4hep::Vector3f mcPocaMom = mcParticle.getMomentum();//GeV
-        edm4hep::Vector3d mcPocaPos = mcParticle.getVertex();
-
-        double mcPos[3]={(mcPocaPos.x),(mcPocaPos.y),(mcPocaPos.z)};
-        double mcMom[3]={(mcPocaMom.x),(mcPocaMom.y),(mcPocaMom.z)};
-        //for(int i=0;i<3;i++){debug()<<"mcPos "<<mcPos[i]<<endmsg;}
-        //for(int i=0;i<3;i++){debug()<<"mcMom "<<mcMom[i]<<endmsg;}
-        float mcCharge = mcParticle.getCharge();
-        helix_mcP.Initialize_VP(mcPos,mcMom,mcCharge,
-                m_genfitField->getBz(mcPos)/GenfitUnit::tesla);
-
-        mcP_D0[iMcParticle] = helix_mcP.getD0();
-        mcP_phi[iMcParticle] = helix_mcP.getPhi0();
-        mcP_omega[iMcParticle] = helix_mcP.getOmega();
-        mcP_Z0[iMcParticle] = helix_mcP.getZ0();
-        mcP_tanLambda[iMcParticle] = helix_mcP.getTanLambda();
-
-        debug()<< "debugEvent Bz " << m_genfitField->getBz(mcPos)/GenfitUnit::tesla
-            << "Tesla mc d0= " << mcP_D0
-            << " phi0= " << mcP_phi
-            << " omega= " << mcP_omega
-            << " Z0= " << mcP_Z0
-            << " tanLambda= " << mcP_tanLambda << endmsg;
-
-        float px=mcPocaMom.x;
-        float py=mcPocaMom.y;
-        float pz=mcPocaMom.z;
-        debug()<<"mc pos("<<mcPos[0]<<","<<mcPos[1]<<","<<mcPos[2]
-            <<") pxyz("<<px<<","<<py<<","<<pz<<") p"<<sqrt(px*px+py*py+pz*pz)
-            <<endmsg;
-        m_pocaMomMcP[iMcParticle]=sqrt(px*px+py*py+pz*pz);
-        m_pocaMomMcPt[iMcParticle]=sqrt(px*px+py*py);
-        m_pocaMomMc[iMcParticle][0]=px;
-        m_pocaMomMc[iMcParticle][1]=py;
-        m_pocaMomMc[iMcParticle][2]=pz;
-        iMcParticle++;
+    if((m_mcParticleCol.get())!=nullptr){
+        mcParticleCol=m_mcParticleCol.get();
+        int iMcParticle=0;
+        HelixClass helix_mcP;
+        for(auto mcParticle : *mcParticleCol){
+            edm4hep::Vector3f mcPocaMom = mcParticle.getMomentum();//GeV
+            edm4hep::Vector3d mcPocaPos = mcParticle.getVertex();
+
+            double mcPos[3]={(mcPocaPos.x),(mcPocaPos.y),(mcPocaPos.z)};
+            double mcMom[3]={(mcPocaMom.x),(mcPocaMom.y),(mcPocaMom.z)};
+            //for(int i=0;i<3;i++){debug()<<"mcPos "<<mcPos[i]<<endmsg;}
+            //for(int i=0;i<3;i++){debug()<<"mcMom "<<mcMom[i]<<endmsg;}
+            float mcCharge = mcParticle.getCharge();
+            helix_mcP.Initialize_VP(mcPos,mcMom,mcCharge,
+                    m_genfitField->getBz(mcPos)/GenfitUnit::tesla);
+
+            mcP_D0[iMcParticle] = helix_mcP.getD0();
+            mcP_phi[iMcParticle] = helix_mcP.getPhi0();
+            mcP_omega[iMcParticle] = helix_mcP.getOmega();
+            mcP_Z0[iMcParticle] = helix_mcP.getZ0();
+            mcP_tanLambda[iMcParticle] = helix_mcP.getTanLambda();
+
+            debug()<< "debugEvent Bz " << m_genfitField->getBz(mcPos)/GenfitUnit::tesla
+                << "Tesla mc d0= " << mcP_D0
+                << " phi0= " << mcP_phi
+                << " omega= " << mcP_omega
+                << " Z0= " << mcP_Z0
+                << " tanLambda= " << mcP_tanLambda << endmsg;
+
+            float px=mcPocaMom.x;
+            float py=mcPocaMom.y;
+            float pz=mcPocaMom.z;
+            debug()<<"mc pos("<<mcPos[0]<<","<<mcPos[1]<<","<<mcPos[2]
+                <<") pxyz("<<px<<","<<py<<","<<pz<<") p"<<sqrt(px*px+py*py+pz*pz)
+                <<endmsg;
+            m_pocaMomMcP[iMcParticle]=sqrt(px*px+py*py+pz*pz);
+            m_pocaMomMcPt[iMcParticle]=sqrt(px*px+py*py);
+            m_pocaMomMc[iMcParticle][0]=px;
+            m_pocaMomMc[iMcParticle][1]=py;
+            m_pocaMomMc[iMcParticle][2]=pz;
+            iMcParticle++;
+        }
+        m_mcIndex=iMcParticle;
     }
-    m_mcIndex=iMcParticle;
 
     int iHit=0;
     simHitCol=m_simDCHitCol.get();
diff --git a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp
index 0d5100b62..28eabd342 100644
--- a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp
+++ b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp
@@ -111,7 +111,6 @@ StatusCode TruthTrackerAlg::initialize()
         return StatusCode::FAILURE;
     }
 
-    m_tuple=nullptr;
     ///book tuple
     if(m_hist){
         NTuplePtr nt(ntupleSvc(), "TruthTrackerAlg/truthTrackerAlg");
@@ -232,7 +231,7 @@ StatusCode TruthTrackerAlg::execute()
     //mcRecoTrackerAssociationCol=m_mcRecoParticleAssociation.get();
 
     ///New SDT track
-    edm4hep::Track sdtTk=sdtTkCol->create();
+    edm4hep::MutableTrack sdtTk=sdtTkCol->create();
 
     int nVXDHit=0;
     int nSITHit=0;
@@ -316,7 +315,7 @@ StatusCode TruthTrackerAlg::execute()
 
     if(m_useDC){
         ///Create DC Track
-        edm4hep::Track dcTrack=dcTrackCol->create();
+        edm4hep::MutableTrack dcTrack=dcTrackCol->create();
 
         //Create TrackState
         edm4hep::TrackState trackStateFirstDCHit;
@@ -458,8 +457,10 @@ void TruthTrackerAlg::getTrackStateFromMcParticle(
         trackState.Z0=helix.getZ0();
         trackState.tanLambda=helix.getTanLambda();
         trackState.referencePoint=helix.getReferencePoint();
-        std::array<float,15> covMatrix;
-        for(int i=0;i<15;i++){covMatrix[i]=1.;}//FIXME
+
+        decltype(trackState.covMatrix) covMatrix;
+        for(int i=0;i<covMatrix.size();i++){covMatrix[i]=999.;}//FIXME
+
         trackState.covMatrix=covMatrix;
 
         getCircleFromPosMom(pos,mom,B[2]/dd4hep::tesla,mcParticle.getCharge(),m_helixRadius,m_helixXC,m_helixYC);
@@ -526,8 +527,8 @@ bool TruthTrackerAlg::getTrackStateFirstHit(
         trackState.Z0=helix.getZ0();
         trackState.tanLambda=helix.getTanLambda();
         trackState.referencePoint=helix.getReferencePoint();
-        std::array<float,15> covMatrix;
-        for(int i=0;i<15;i++){covMatrix[i]=100.;}//FIXME
+        std::array<float,21> covMatrix;
+        for(int i=0;i<21;i++){covMatrix[i]=100.;}//FIXME
         trackState.covMatrix=covMatrix;
         debug()<<"first hit trackState "<<trackState<<endmsg;
         return true;
@@ -591,7 +592,7 @@ void TruthTrackerAlg::debugEvent()
 
 int TruthTrackerAlg::addIdealHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
         colHandle, edm4hep::TrackerHitCollection*& truthTrackerHitCol,
-        edm4hep::Track& track, const char* msg,int nHitAdded)
+        edm4hep::MutableTrack& track, const char* msg,int nHitAdded)
 {
     if(nHitAdded>0) return nHitAdded;
     int nHit=0;
@@ -614,7 +615,7 @@ int TruthTrackerAlg::addIdealHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
 
         //add modified hit
         auto tmpHit = truthTrackerHitCol->create();
-        tmpHit=hit;
+        tmpHit=hit.clone();
         tmpHit.setTime(fabs(docaIdeal)*1e3/40.);//40#um/ns, drift time in ns
         track.addToTrackerHits(tmpHit);
 
@@ -665,7 +666,7 @@ int TruthTrackerAlg::makeNoiseHit(edm4hep::SimTrackerHitCollection* SimVec,
         trkHit.setCellID(wcellid);
         trkHit.setTime(pocaTime);
         trkHit.setEDep(mcHit.getEDep());
-        trkHit.setEdx(mcHit.getEdx());
+        //trkHit.setEdx(mcHit.getEdx());
         trkHit.setPosition(mcHit.getPosition());
         trkHit.setCovMatrix(mcHit.getCovMatrix());
         for(int iAsso=0;iAsso<(int) assoHits->size();iAsso++)
@@ -753,7 +754,7 @@ int TruthTrackerAlg::smearDCTkhit(DataHandle<edm4hep::TrackerHitCollection>&
         smearHit.setQuality(hit.getQuality());
         smearHit.setEDep(hit.getEDep());
         smearHit.setEDepError(hit.getEDepError());
-        smearHit.setEdx(hit.getEdx());
+        //smearHit.setEdx(hit.getEdx());
         smearHit.setPosition(hit.getPosition());
         smearHit.setCovMatrix(hit.getCovMatrix());
         smearHit.addToRawHits(hit.getObjectID());
@@ -789,7 +790,7 @@ int TruthTrackerAlg::smearDCTkhit(DataHandle<edm4hep::TrackerHitCollection>&
 }
 
 int TruthTrackerAlg::addHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
-        colHandle, edm4hep::Track& track, const char* msg,int nHitAdded)
+        colHandle, edm4hep::MutableTrack& track, const char* msg,int nHitAdded)
 {
     if(nHitAdded>0) return nHitAdded;
     int nHit=0;
@@ -806,7 +807,7 @@ int TruthTrackerAlg::addHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
 int TruthTrackerAlg::addSimHitsToTk(
         DataHandle<edm4hep::SimTrackerHitCollection>& colHandle,
         edm4hep::TrackerHitCollection*& truthTrackerHitCol,
-        edm4hep::Track& track, const char* msg,int nHitAdded)
+        edm4hep::MutableTrack& track, const char* msg,int nHitAdded)
 {
     if(nHitAdded>0) return nHitAdded;
     int nHit=0;
@@ -861,12 +862,12 @@ int TruthTrackerAlg::addSimHitsToTk(
 }
 
 int TruthTrackerAlg::addHotsToTk(edm4hep::Track& sourceTrack,
-        edm4hep::Track& targetTrack, int hitType,const char* msg,int nHitAdded)
+        edm4hep::MutableTrack& targetTrack, int hitType,const char* msg,int nHitAdded)
 {
     if(nHitAdded>0) return nHitAdded;
     int nHit=0;
     for(unsigned int iHit=0;iHit<sourceTrack.trackerHits_size();iHit++){
-        edm4hep::ConstTrackerHit hit=sourceTrack.getTrackerHits(iHit);
+        edm4hep::TrackerHit hit=sourceTrack.getTrackerHits(iHit);
         UTIL::BitField64 encoder(lcio::ILDCellID0::encoder_string);
         encoder.setValue(hit.getCellID());
         if(encoder[lcio::ILDCellID0::subdet]==hitType){
@@ -885,7 +886,7 @@ int TruthTrackerAlg::nHotsOnTrack(edm4hep::Track& track, int hitType)
 {
     int nHit=0;
     for(unsigned int iHit=0;iHit<track.trackerHits_size();iHit++){
-        edm4hep::ConstTrackerHit hit=track.getTrackerHits(iHit);
+        edm4hep::TrackerHit hit=track.getTrackerHits(iHit);
         UTIL::BitField64 encoder(lcio::ILDCellID0::encoder_string);
         encoder.setValue(hit.getCellID());
         if(encoder[lcio::ILDCellID0::subdet]==hitType){
diff --git a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h
index 32136cd4c..563d98543 100644
--- a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h
+++ b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h
@@ -22,6 +22,7 @@ namespace edm4hep {
     class TrackerHitCollection;
     class TrackCollection;
     class Track;
+    class MutableTrack;
     class TrackState;
     class ReconstructedParticleCollection;
     class MCRecoTrackerAssociationCollection;
@@ -42,7 +43,7 @@ class TruthTrackerAlg: public GaudiAlgorithm
                 mcParticleCol, edm4hep::TrackState& stat);
         int addSimHitsToTk(DataHandle<edm4hep::SimTrackerHitCollection>&
                 colHandle, edm4hep::TrackerHitCollection*& truthTrackerHitCol,
-                edm4hep::Track& track, const char* msg,int nHitAdded);
+                edm4hep::MutableTrack& track, const char* msg,int nHitAdded);
         int smearDCTkhit(DataHandle<edm4hep::TrackerHitCollection>&
                 colHandle,DataHandle<edm4hep::TrackerHitCollection>& smearCol,
                 DataHandle<edm4hep::SimTrackerHitCollection>& SimDCHitCol,
@@ -51,12 +52,12 @@ class TruthTrackerAlg: public GaudiAlgorithm
                 DataHandle<edm4hep::MCRecoTrackerAssociationCollection>& AssoSmearDCHitCol,
                 double resX, double resY, double resZ);
         int addHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
-                colHandle, edm4hep::Track& track, const char* msg,int nHitAdded);
+                colHandle, edm4hep::MutableTrack& track, const char* msg,int nHitAdded);
         int addIdealHitsToTk(DataHandle<edm4hep::TrackerHitCollection>&
                 colHandle, edm4hep::TrackerHitCollection*& truthTrackerHitCol,
-                edm4hep::Track& track, const char* msg,int nHitAdded);
+                edm4hep::MutableTrack& track, const char* msg,int nHitAdded);
 
-        int addHotsToTk(edm4hep::Track& sourceTrack,edm4hep::Track&
+        int addHotsToTk(edm4hep::Track& sourceTrack,edm4hep::MutableTrack&
                 targetTrack, int hitType,const char* msg,int nHitAdded);
         int nHotsOnTrack(edm4hep::Track& track, int hitType);
         int trackerHitColSize(DataHandle<edm4hep::TrackerHitCollection>& hitCol);
diff --git a/Utilities/DataHelper/src/TrackHelper.cc b/Utilities/DataHelper/src/TrackHelper.cc
index 6f5db4cef..9e1f437fb 100644
--- a/Utilities/DataHelper/src/TrackHelper.cc
+++ b/Utilities/DataHelper/src/TrackHelper.cc
@@ -121,8 +121,11 @@ void CEPC::getTrackStateFromPosMom(edm4hep::TrackState& trackState,double Bz,
             if(i>=j) { 
                 k1=k++;
                 //covMatrix[k++]=covMatrix_5(i,j);
+                if(5==i){
+                    covMatrix[k1]=-999;
+                    continue;
+                }
                 covMatrix[k1]=covMatrix_5(i,j);
-                if(5==i) covMatrix[k1]=-999;
             }
         }
     }
diff --git a/run.sh b/run.sh
index 97f7f2150..bb42b5c8d 100755
--- a/run.sh
+++ b/run.sh
@@ -67,7 +67,7 @@ function run-job() {
 
 # The current default platform
 lcg_platform=x86_64-centos7-gcc8-opt
-lcg_version=101.0.0
+lcg_version=101.0.1
 
 bldtool=${CEPCSW_BLDTOOL} # make, ninja # set in env var
 

From 62a8769a5d8e9237fb5893fad7b14bf5dc39a6f6 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Mon, 11 Mar 2024 19:17:45 +0800
Subject: [PATCH 20/27] Updata 103.0.2

---
 Detector/DetDriftChamber/compact/det.xml      |   4 +-
 Reconstruction/PFA/Arbor/src/ArborToolLCIO.cc |   7 +
 .../GaudiPandora/src/MCParticleCreator.cpp    |  10 +-
 .../Pandora/GaudiPandora/src/PandoraPFAlg.cpp |   6 +-
 .../Pandora/GaudiPandora/src/TrackCreator.cpp |  37 +++-
 .../MatrixPandora/src/MCParticleCreator.cpp   |  10 +-
 .../MatrixPandora/src/PandoraMatrixAlg.cpp    |  10 +-
 .../MatrixPandora/src/TrackCreator.cpp        |  32 ++-
 .../RecGenfitAlg/src/GenfitTrack.cpp          | 196 ++++++++++++++---
 Reconstruction/RecGenfitAlg/src/GenfitTrack.h |  17 +-
 .../src/ForwardTrackingAlg.cpp                |  18 +-
 .../src/SiliconTrackingAlg.cpp                |  15 +-
 .../FullLDCTracking/FullLDCTrackingAlg.cpp    |  50 ++++-
 .../TrackSystemSvc/src/MarlinKalTestTrack.cc  |  10 +-
 Service/TrackSystemSvc/src/MarlinTrkUtils.cc  |  54 ++++-
 Simulation/DetSimAna/CMakeLists.txt           |   5 +
 .../src/Edm4hepWriterAnaElemTool.cpp          | 129 +++++++++--
 .../DetSimAna/src/Edm4hepWriterAnaElemTool.h  |  16 +-
 .../DetSimAna/src/ExampleAnaElemTool.cpp      |   2 +-
 Simulation/DetSimInterface/CMakeLists.txt     |   3 +
 .../DetSimInterface/CommonUserEventInfo.hh    |  39 ++++
 .../DetSimInterface/CommonUserTrackInfo.hh    |  35 +++
 .../include/DetSimInterface/IDedxSimTool.h    |   1 +
 .../src/CommonUserEventInfo.cc                |  53 +++++
 .../src/CommonUserTrackInfo.cc                |  22 ++
 Simulation/DetSimSD/CMakeLists.txt            |  30 ++-
 .../include/DetSimSD/DDG4SensitiveDetector.h  |   2 +-
 .../DetSimSD/include/DetSimSD/Geant4Hits.h    | 201 ++++++++++++++++++
 .../DetSimSD/src/DDG4SensitiveDetector.cpp    |   1 -
 .../DetSimSD/src/DriftChamberSensDetTool.cpp  |  20 +-
 .../src/DriftChamberSensitiveDetector.cpp     |   2 +-
 Simulation/DetSimSD/src/Geant4Hits.cpp        | 135 ++++++++++++
 .../src/GenericTrackerSensDetTool.cpp         |  11 +-
 .../src/GenericTrackerSensitiveDetector.cpp   |   3 +-
 .../src/TrackerCombineSensitiveDetector.cpp   |  58 +++++
 .../src/TrackerCombineSensitiveDetector.h     |  95 +++++++++
 build.sh                                      |  13 +-
 setup.sh                                      |  24 ++-
 38 files changed, 1234 insertions(+), 142 deletions(-)
 mode change 100755 => 100644 Reconstruction/Tracking/src/FullLDCTracking/FullLDCTrackingAlg.cpp
 create mode 100644 Simulation/DetSimInterface/include/DetSimInterface/CommonUserEventInfo.hh
 create mode 100644 Simulation/DetSimInterface/include/DetSimInterface/CommonUserTrackInfo.hh
 create mode 100644 Simulation/DetSimInterface/src/CommonUserEventInfo.cc
 create mode 100644 Simulation/DetSimInterface/src/CommonUserTrackInfo.cc
 create mode 100644 Simulation/DetSimSD/include/DetSimSD/Geant4Hits.h
 create mode 100644 Simulation/DetSimSD/src/Geant4Hits.cpp
 create mode 100644 Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.cpp
 create mode 100644 Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.h

diff --git a/Detector/DetDriftChamber/compact/det.xml b/Detector/DetDriftChamber/compact/det.xml
index 3c86627d3..fcc55f727 100644
--- a/Detector/DetDriftChamber/compact/det.xml
+++ b/Detector/DetDriftChamber/compact/det.xml
@@ -32,7 +32,7 @@
     <constant name="DC_rbegin" value="800*mm"/>
     <constant name="DC_rend" value="1800*mm"/>
 
-    <constant name="DC_layer_number" value="100"/>
+    <constant name="DC_layer_number" value="55"/>
     <constant name="Alpha" value="0*deg"/>
 
     <constant name="Gas_radius_min" value="DC_rbegin+DC_inner_wall_thickness+DC_safe_distance"/>
@@ -44,7 +44,7 @@
     <constant name="Gas_half_length" value="DC_half_length-DC_Endcap_dz-DC_safe_distance"/>
     <constant name="Gas_length" value="Gas_half_length*2"/>
 
-    <constant name="DC_cell_width" value="10*mm"/>
+    <constant name="DC_cell_width" value="18*mm"/>
 
     <constant name="DC_inner_wall_radius_min" value="DC_rbegin"/>
     <constant name="DC_inner_wall_radius_max" value="DC_rbegin+DC_inner_wall_thickness"/>
diff --git a/Reconstruction/PFA/Arbor/src/ArborToolLCIO.cc b/Reconstruction/PFA/Arbor/src/ArborToolLCIO.cc
index d97a82d6e..6a1e0cc20 100644
--- a/Reconstruction/PFA/Arbor/src/ArborToolLCIO.cc
+++ b/Reconstruction/PFA/Arbor/src/ArborToolLCIO.cc
@@ -35,6 +35,8 @@
 #include <DDRec/CellIDPositionConverter.h>
 #include "DetInterface/IGeomSvc.h"
 
+#include "podio/podioVersion.h"
+
 using namespace std;
 /* 
 void ClusterBuilding( LCEvent * evtPP, std::string Name, std::vector<CalorimeterHit*> Hits, std::vector< std::vector<int> > BranchOrder, int DHCALFlag )
@@ -859,7 +861,12 @@ edm4hep::ClusterCollection* ArborToolLCIO::ClusterVecMerge( std::vector<edm4hep:
 	edm4hep::Cluster Mergebranch_A;
 	edm4hep::Cluster Mergebranch_B;
 	edm4hep::Cluster tmpMergebranch;
+#if PODIO_BUILD_VERSION < PODIO_VERSION(0, 17, 4)
 	edm4hep::Cluster Mainbranch (0);
+#else
+	auto Mainbranch = edm4hep::Cluster::makeEmpty();
+#endif
+
 
 	TVector3 tmpClusterSeedPos, MBSeedPos;	
 
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/src/MCParticleCreator.cpp b/Reconstruction/PFA/Pandora/GaudiPandora/src/MCParticleCreator.cpp
index 1912eee92..48908a643 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/src/MCParticleCreator.cpp
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/src/MCParticleCreator.cpp
@@ -53,7 +53,7 @@ pandora::StatusCode MCParticleCreator::CreateMCParticles(const CollectionMaps& c
                     mcParticleParameters.m_particleId = pMcParticle.getPDG();
                     mcParticleParameters.m_mcParticleType = pandora::MC_3D;
                     mcParticleParameters.m_pParentAddress = &pMcParticle;
-                    unsigned int p_id = pMcParticle.id();
+                    unsigned int p_id = pMcParticle.id().index;
                     //auto p_mc = const_cast<edm4hep::MCParticle*>(&pMcParticle);
                     auto p_mc = &pMcParticle;
                     (*m_id_pMC_map) [p_id]   = p_mc;
@@ -131,8 +131,8 @@ pandora::StatusCode MCParticleCreator::CreateCaloHitToMCParticleRelationships(co
                             auto conb = pSimHit.getContributions(iCont);
                             auto ipa = conb.getParticle();
                             float  ien = conb.getEnergy();
-                            if( m_id_pMC_map->find(ipa.id()) == m_id_pMC_map->end() ) continue;
-                            auto p_tmp = (*m_id_pMC_map)[ipa.id()]; 
+                            if( m_id_pMC_map->find(ipa.id().index) == m_id_pMC_map->end() ) continue;
+                            auto p_tmp = (*m_id_pMC_map)[ipa.id().index];
                             mcParticleToEnergyWeightMap[p_tmp] += ien;
                         }
                         
@@ -190,13 +190,13 @@ pandora::StatusCode MCParticleCreator::CreateTrackToMCParticleRelationships(cons
                         if( pMCRecoTrackerAssociationCollection.at(ic).getRec().id() != pTrack->getTrackerHits(ith).id() ) continue;
                         auto pSimHit = pMCRecoTrackerAssociationCollection.at(ic).getSim();
                         auto ipa = pSimHit.getMCParticle();
-                        if( m_id_pMC_map->find(ipa.id()) == m_id_pMC_map->end() ) continue;
+                        if( m_id_pMC_map->find(ipa.id().index) == m_id_pMC_map->end() ) continue;
                         const float trueMomentum(pandora::CartesianVector(ipa.getMomentum()[0], ipa.getMomentum()[1], ipa.getMomentum()[2]).GetMagnitude());
                         const float deltaMomentum(std::fabs(recoMomentum - trueMomentum));
                         if (deltaMomentum < bestDeltaMomentum)
                         {
                             //pBestMCParticle =((*m_id_pMC_map)[ipa.id()]);
-                            best_mc_id = ipa.id() ;
+                            best_mc_id = ipa.id().index ;
                             bestDeltaMomentum = deltaMomentum;
                         }
                     }
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/src/PandoraPFAlg.cpp b/Reconstruction/PFA/Pandora/GaudiPandora/src/PandoraPFAlg.cpp
index cfe8f2f25..a95ea9c70 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/src/PandoraPFAlg.cpp
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/src/PandoraPFAlg.cpp
@@ -669,9 +669,9 @@ StatusCode PandoraPFAlg::CreateMCRecoParticleAssociation()
                         if(it->getRec().id() != hit.id()) continue;
                         for(auto itc = it->getSim().contributions_begin(); itc != it->getSim().contributions_end(); itc++)
                         {
-                            if(mc_map.find(itc->getParticle().id()) == mc_map.end()) mc_map[itc->getParticle().id()] = itc->getParticle() ;
-                            if(id_edep_map.find(itc->getParticle().id()) != id_edep_map.end()) id_edep_map[itc->getParticle().id()] = id_edep_map[itc->getParticle().id()] + itc->getEnergy() ;
-                            else                                                               id_edep_map[itc->getParticle().id()] = itc->getEnergy() ;
+                            if(mc_map.find(itc->getParticle().id().index) == mc_map.end()) mc_map[itc->getParticle().id().index] = itc->getParticle() ;
+                            if(id_edep_map.find(itc->getParticle().id().index) != id_edep_map.end()) id_edep_map[itc->getParticle().id().index] = id_edep_map[itc->getParticle().id().index] + itc->getEnergy() ;
+                            else                                                               id_edep_map[itc->getParticle().id().index] = itc->getEnergy() ;
                             tot_en += itc->getEnergy() ;
                         }
                     }
diff --git a/Reconstruction/PFA/Pandora/GaudiPandora/src/TrackCreator.cpp b/Reconstruction/PFA/Pandora/GaudiPandora/src/TrackCreator.cpp
index 940d116f1..8ebe8e239 100644
--- a/Reconstruction/PFA/Pandora/GaudiPandora/src/TrackCreator.cpp
+++ b/Reconstruction/PFA/Pandora/GaudiPandora/src/TrackCreator.cpp
@@ -10,6 +10,14 @@
 #include "edm4hep/Vertex.h"
 #include "edm4hep/Vector3f.h"
 #include "edm4hep/ReconstructedParticle.h"
+#if __has_include("edm4hep/EDM4hepVersion.h")
+#include "edm4hep/EDM4hepVersion.h"
+#else
+// Copy the necessary parts from  the header above to make whatever we need to work here
+#define EDM4HEP_VERSION(major, minor, patch) ((UINT64_C(major) << 32) | (UINT64_C(minor) << 16) | (UINT64_C(patch)))
+// v00-09 is the last version without the capitalization change of the track vector members
+#define EDM4HEP_BUILD_VERSION EDM4HEP_VERSION(0, 9, 0)
+#endif
 
 #include "gear/BField.h"
 #include "gear/CalorimeterParameters.h"
@@ -313,7 +321,7 @@ pandora::StatusCode TrackCreator::ExtractKinks(const CollectionMaps& collectionM
                     for (unsigned int iTrack = 0, nTracks = pReconstructedParticle.tracks_size(); iTrack < nTracks; ++iTrack)
                     {
                         auto pTrack = pReconstructedParticle.getTracks(iTrack);
-                        (0 == iTrack) ? m_parentTrackList.insert(pTrack.id()) : m_daughterTrackList.insert(pTrack.id());
+                        (0 == iTrack) ? m_parentTrackList.insert(pTrack.id().index) : m_daughterTrackList.insert(pTrack.id().index);
 
                         int trackPdgCode = pandora::UNKNOWN_PARTICLE_TYPE;
 
@@ -413,7 +421,7 @@ pandora::StatusCode TrackCreator::ExtractProngsAndSplits(const CollectionMaps& c
                     for (unsigned int iTrack = 0, nTracks = pReconstructedParticle.tracks_size(); iTrack < nTracks; ++iTrack)
                     {
                         edm4hep::Track pTrack = pReconstructedParticle.getTracks(iTrack);
-                        (0 == iTrack) ? m_parentTrackList.insert(pTrack.id()) : m_daughterTrackList.insert(pTrack.id());
+                        (0 == iTrack) ? m_parentTrackList.insert(pTrack.id().index) : m_daughterTrackList.insert(pTrack.id().index);
 
                         if (0 == m_settings.m_shouldFormTrackRelationships) continue;
 
@@ -482,7 +490,7 @@ pandora::StatusCode TrackCreator::ExtractV0s(const CollectionMaps& collectionMap
                     for (unsigned int iTrack = 0, nTracks = pReconstructedParticle.tracks_size(); iTrack < nTracks; ++iTrack)
                     {
                         edm4hep::Track pTrack = pReconstructedParticle.getTracks(iTrack);
-                        m_v0TrackList.insert(pTrack.id());
+                        m_v0TrackList.insert(pTrack.id().index);
 
                         int trackPdgCode = pandora::UNKNOWN_PARTICLE_TYPE;
 
@@ -538,7 +546,7 @@ bool TrackCreator::IsConflictingRelationship(const edm4hep::ReconstructedParticl
     for (unsigned int iTrack = 0, nTracks = Particle.tracks_size(); iTrack < nTracks; ++iTrack)
     {
         edm4hep::Track pTrack = Particle.getTracks(iTrack) ;
-        unsigned int pTrack_id = pTrack.id() ;
+        unsigned int pTrack_id = pTrack.id().index ;
 
         if (this->IsDaughter(pTrack_id) || this->IsParent(pTrack_id) || this->IsV0(pTrack_id))
             return true;
@@ -851,7 +859,7 @@ void TrackCreator::DefineTrackPfoUsage(const edm4hep::Track *const pTrack, Pando
     bool canFormPfo(false);
     bool canFormClusterlessPfo(false);
 
-    if (trackParameters.m_reachesCalorimeter.Get() && !this->IsParent(pTrack->id()))
+    if (trackParameters.m_reachesCalorimeter.Get() && !this->IsParent(pTrack->id().index))
     {
         const float d0(std::fabs(pTrack->getTrackStates(0).D0)), z0(std::fabs(pTrack->getTrackStates(0).Z0));
 
@@ -880,8 +888,8 @@ void TrackCreator::DefineTrackPfoUsage(const edm4hep::Track *const pTrack, Pando
             const float zCutForNonVertexTracks(m_tpcInnerR * std::fabs(pZ / pT) + m_settings.m_zCutForNonVertexTracks);
             const bool passRzQualityCuts((zMin < zCutForNonVertexTracks) && (rInner < m_tpcInnerR + m_settings.m_maxTpcInnerRDistance));
 
-            const bool isV0(this->IsV0(pTrack->id()));
-            const bool isDaughter(this->IsDaughter(pTrack->id()));
+            const bool isV0(this->IsV0(pTrack->id().index));
+            const bool isDaughter(this->IsDaughter(pTrack->id().index));
 
             // Decide whether track can be associated with a pandora cluster and used to form a charged PFO
             if ((d0 < m_settings.m_d0TrackCut) && (z0 < m_settings.m_z0TrackCut) && (rInner < m_tpcInnerR + m_settings.m_maxTpcInnerRDistance))
@@ -918,7 +926,7 @@ void TrackCreator::DefineTrackPfoUsage(const edm4hep::Track *const pTrack, Pando
                 }
             }
         }
-        else if (this->IsDaughter(pTrack->id()) || this->IsV0(pTrack->id()))
+        else if (this->IsDaughter(pTrack->id().index) || this->IsV0(pTrack->id().index))
         {
             std::cout<<"WARNING Recovering daughter or v0 track " << trackParameters.m_momentumAtDca.Get().GetMagnitude() << std::endl;
             canFormPfo = true;
@@ -1020,9 +1028,15 @@ int TrackCreator::GetNTpcHits(const edm4hep::Track *const pTrack) const
         //According to FG: [ 2 * lcio::ILDDetID::TPC - 2 ] is the first number and it is supposed to
         //be the number of hits in the fit and this is what should be used !
         // at least for DD4hep/DDSim
+#if EDM4HEP_BUILD_VERSION > EDM4HEP_VERSION(0, 9, 0)
+        return pTrack->getSubdetectorHitNumbers(3);//FIXME https://github.com/wenxingfang/CEPCSW/blob/master/Reconstruction/Tracking/src/FullLDCTracking/FullLDCTrackingAlg.cpp#L483
+    }
+    else return pTrack->getSubdetectorHitNumbers(2 * 4 - 1);// lcio::ILDDetID::TPC=4, still use LCIO code now
+#else
         return pTrack->getSubDetectorHitNumbers(3);//FIXME https://github.com/wenxingfang/CEPCSW/blob/master/Reconstruction/Tracking/src/FullLDCTracking/FullLDCTrackingAlg.cpp#L483
     }
     else return pTrack->getSubDetectorHitNumbers(2 * 4 - 1);// lcio::ILDDetID::TPC=4, still use LCIO code now
+#endif
 }
 
 //------------------------------------------------------------------------------------------------------------------------------------------
@@ -1036,9 +1050,16 @@ int TrackCreator::GetNFtdHits(const edm4hep::Track *const pTrack) const
     // ---- use hitsInFit :
     //return pTrack->getSubdetectorHitNumbers()[ 2 * lcio::ILDDetID::FTD - 1 ];
     if(m_settings.m_use_dd4hep_geo){
+#if EDM4HEP_BUILD_VERSION > EDM4HEP_VERSION(0, 9, 0)
+        return pTrack->getSubdetectorHitNumbers(1);//FIXME https://github.com/wenxingfang/CEPCSW/blob/master/Reconstruction/Tracking/src/FullLDCTracking/FullLDCTrackingAlg.cpp#L481
+    }
+    else return pTrack->getSubdetectorHitNumbers( 2 * 3 - 1 );// lcio::ILDDetID::FTD=3
+#else
         return pTrack->getSubDetectorHitNumbers(1);//FIXME https://github.com/wenxingfang/CEPCSW/blob/master/Reconstruction/Tracking/src/FullLDCTracking/FullLDCTrackingAlg.cpp#L481
     }
     else return pTrack->getSubDetectorHitNumbers( 2 * 3 - 1 );// lcio::ILDDetID::FTD=3
+
+#endif
 }
 
 //------------------------------------------------------------------------------------------------------------------------------------------
diff --git a/Reconstruction/PFA/Pandora/MatrixPandora/src/MCParticleCreator.cpp b/Reconstruction/PFA/Pandora/MatrixPandora/src/MCParticleCreator.cpp
index 40f44d1a4..2da131685 100644
--- a/Reconstruction/PFA/Pandora/MatrixPandora/src/MCParticleCreator.cpp
+++ b/Reconstruction/PFA/Pandora/MatrixPandora/src/MCParticleCreator.cpp
@@ -57,7 +57,7 @@ pandora::StatusCode MCParticleCreator::CreateMCParticles(const CollectionMaps& c
                     mcParticleParameters.m_particleId = pMcParticle.getPDG();
                     mcParticleParameters.m_mcParticleType = pandora::MC_3D;
                     mcParticleParameters.m_pParentAddress = &pMcParticle;
-                    unsigned int p_id = pMcParticle.id();
+                    unsigned int p_id = pMcParticle.id().index;
                     auto p_mc = &pMcParticle;
                     (*m_id_pMC_map) [p_id]   = p_mc;
                     mcParticleParameters.m_momentum = pandora::CartesianVector(pMcParticle.getMomentum()[0], pMcParticle.getMomentum()[1],
@@ -271,8 +271,8 @@ pandora::StatusCode MCParticleCreator::CreateCaloHitToMCParticleRelationships(co
                             edm4hep::CaloHitContribution conb = pSimHit.getContributions(iCont);
                             auto ipa = conb.getParticle();
                             float  ien = conb.getEnergy();
-                            if( m_id_pMC_map->find(ipa.id()) == m_id_pMC_map->end() ) continue;
-                            auto p_tmp = (*m_id_pMC_map)[ipa.id()]; 
+                            if( m_id_pMC_map->find(ipa.id().index) == m_id_pMC_map->end() ) continue;
+                            auto p_tmp = (*m_id_pMC_map)[ipa.id().index];
                             mcParticleToEnergyWeightMap[p_tmp] += ien;
                         }
                         
@@ -331,12 +331,12 @@ pandora::StatusCode MCParticleCreator::CreateTrackToMCParticleRelationships(cons
                         if( pMCRecoTrackerAssociationCollection.at(ic).getRec().id() != pTrack->getTrackerHits(ith).id() ) continue;
                         auto pSimHit = pMCRecoTrackerAssociationCollection.at(ic).getSim();
                         auto ipa = pSimHit.getMCParticle();
-                        if( m_id_pMC_map->find(ipa.id()) == m_id_pMC_map->end() ) continue;
+                        if( m_id_pMC_map->find(ipa.id().index) == m_id_pMC_map->end() ) continue;
                         const float trueMomentum(pandora::CartesianVector(ipa.getMomentum()[0], ipa.getMomentum()[1], ipa.getMomentum()[2]).GetMagnitude());
                         const float deltaMomentum(std::fabs(recoMomentum - trueMomentum));
                         if (deltaMomentum < bestDeltaMomentum)
                         {
-                            pBestMCParticle = ((*m_id_pMC_map)[ipa.id()]);
+                            pBestMCParticle = ((*m_id_pMC_map)[ipa.id().index]);
                             bestDeltaMomentum = deltaMomentum;
                         }
                     }
diff --git a/Reconstruction/PFA/Pandora/MatrixPandora/src/PandoraMatrixAlg.cpp b/Reconstruction/PFA/Pandora/MatrixPandora/src/PandoraMatrixAlg.cpp
index b0a1d7ca4..16996f6ca 100644
--- a/Reconstruction/PFA/Pandora/MatrixPandora/src/PandoraMatrixAlg.cpp
+++ b/Reconstruction/PFA/Pandora/MatrixPandora/src/PandoraMatrixAlg.cpp
@@ -591,7 +591,7 @@ StatusCode PandoraMatrixAlg::Ana()
         {
             if(reco_associa_col->at(j).getRec().id() != pReco.id() ) continue;
             std::cout<<"MC pid ="<<reco_associa_col->at(j).getSim().getPDG()<<",weight="<<reco_associa_col->at(j).getWeight()<<", px="<<reco_associa_col->at(j).getSim().getMomentum()[0]<<", py="<<reco_associa_col->at(j).getSim().getMomentum()[1]<<",pz="<<reco_associa_col->at(j).getSim().getMomentum()[2]<<std::endl;
-            tmp_mc_id    .push_back(reco_associa_col->at(j).getSim().id());
+            tmp_mc_id    .push_back(reco_associa_col->at(j).getSim().id().index);
             tmp_mc_weight.push_back(reco_associa_col->at(j).getWeight());
         }
         m_pReco_mc_id    .push_back(tmp_mc_id);
@@ -604,7 +604,7 @@ StatusCode PandoraMatrixAlg::Ana()
     { 
         for(unsigned int i=0 ; i< MCParticle->size(); i++)
         {
-            m_mc_id    .push_back(MCParticle->at(i).id());
+            m_mc_id    .push_back(MCParticle->at(i).id().index);
             m_mc_p_size.push_back(MCParticle->at(i).parents_size());
             m_mc_pid   .push_back(MCParticle->at(i).getPDG());
             m_mc_mass  .push_back(MCParticle->at(i).getMass());
@@ -655,9 +655,9 @@ StatusCode PandoraMatrixAlg::CreateMCRecoParticleAssociation()
                         if(it->getRec().id() != hit.id()) continue;
                         for(auto itc = it->getSim().contributions_begin(); itc != it->getSim().contributions_end(); itc++)
                         {
-                            if(mc_map.find(itc->getParticle().id()) == mc_map.end()) mc_map[itc->getParticle().id()] = itc->getParticle() ;
-                            if(id_edep_map.find(itc->getParticle().id()) != id_edep_map.end()) id_edep_map[itc->getParticle().id()] = id_edep_map[itc->getParticle().id()] + itc->getEnergy() ;
-                            else                                                               id_edep_map[itc->getParticle().id()] = itc->getEnergy() ;
+                            if(mc_map.find(itc->getParticle().id().index) == mc_map.end()) mc_map[itc->getParticle().id().index] = itc->getParticle() ;
+                            if(id_edep_map.find(itc->getParticle().id().index) != id_edep_map.end()) id_edep_map[itc->getParticle().id().index] = id_edep_map[itc->getParticle().id().index] + itc->getEnergy() ;
+                            else                                                               id_edep_map[itc->getParticle().id().index] = itc->getEnergy() ;
                             tot_en += itc->getEnergy() ;
                         }
                     }
diff --git a/Reconstruction/PFA/Pandora/MatrixPandora/src/TrackCreator.cpp b/Reconstruction/PFA/Pandora/MatrixPandora/src/TrackCreator.cpp
index dd633f076..c290e0693 100644
--- a/Reconstruction/PFA/Pandora/MatrixPandora/src/TrackCreator.cpp
+++ b/Reconstruction/PFA/Pandora/MatrixPandora/src/TrackCreator.cpp
@@ -10,6 +10,14 @@
 
 #include "edm4hep/Vertex.h"
 #include "edm4hep/ReconstructedParticle.h"
+#if __has_include("edm4hep/EDM4hepVersion.h")
+#include "edm4hep/EDM4hepVersion.h"
+#else
+// Copy the necessary parts from  the header above to make whatever we need to work here
+#define EDM4HEP_VERSION(major, minor, patch) ((UINT64_C(major) << 32) | (UINT64_C(minor) << 16) | (UINT64_C(patch)))
+// v00-09 is the last version without the capitalization change of the track vector members
+#define EDM4HEP_BUILD_VERSION EDM4HEP_VERSION(0, 9, 0)
+#endif
 
 #include "gear/BField.h"
 #include "gear/CalorimeterParameters.h"
@@ -177,7 +185,7 @@ pandora::StatusCode TrackCreator::ExtractKinks(const CollectionMaps& collectionM
                     for (unsigned int iTrack = 0, nTracks = pReconstructedParticle.tracks_size(); iTrack < nTracks; ++iTrack)
                     {
                         auto pTrack = pReconstructedParticle.getTracks(iTrack);
-                        (0 == iTrack) ? m_parentTrackList.insert(pTrack.id()) : m_daughterTrackList.insert(pTrack.id());
+                        (0 == iTrack) ? m_parentTrackList.insert(pTrack.id().index) : m_daughterTrackList.insert(pTrack.id().index);
 
                         int trackPdgCode = pandora::UNKNOWN_PARTICLE_TYPE;
 
@@ -277,7 +285,7 @@ pandora::StatusCode TrackCreator::ExtractProngsAndSplits(const CollectionMaps& c
                     for (unsigned int iTrack = 0, nTracks = pReconstructedParticle.tracks_size(); iTrack < nTracks; ++iTrack)
                     {
                         auto pTrack = pReconstructedParticle.getTracks(iTrack);
-                        (0 == iTrack) ? m_parentTrackList.insert(pTrack.id()) : m_daughterTrackList.insert(pTrack.id());
+                        (0 == iTrack) ? m_parentTrackList.insert(pTrack.id().index) : m_daughterTrackList.insert(pTrack.id().index);
 
                         if (0 == m_settings.m_shouldFormTrackRelationships) continue;
 
@@ -346,7 +354,7 @@ pandora::StatusCode TrackCreator::ExtractV0s(const CollectionMaps& collectionMap
                     for (unsigned int iTrack = 0, nTracks = pReconstructedParticle.tracks_size(); iTrack < nTracks; ++iTrack)
                     {
                         auto pTrack = pReconstructedParticle.getTracks(iTrack);
-                        m_v0TrackList.insert(pTrack.id());
+                        m_v0TrackList.insert(pTrack.id().index);
 
                         int trackPdgCode = pandora::UNKNOWN_PARTICLE_TYPE;
 
@@ -401,7 +409,7 @@ bool TrackCreator::IsConflictingRelationship(const edm4hep::ReconstructedParticl
     for (unsigned int iTrack = 0, nTracks = Particle.tracks_size(); iTrack < nTracks; ++iTrack)
     {
         edm4hep::Track pTrack = Particle.getTracks(iTrack) ;
-        unsigned int pTrack_id = pTrack.id() ;
+        unsigned int pTrack_id = pTrack.id().index ;
 
         if (this->IsDaughter(pTrack_id) || this->IsParent(pTrack_id) || this->IsV0(pTrack_id))
             return true;
@@ -712,7 +720,7 @@ void TrackCreator::DefineTrackPfoUsage(edm4hep::Track *const pTrack, PandoraApi:
     bool canFormPfo(false);
     bool canFormClusterlessPfo(false);
 
-    if (trackParameters.m_reachesCalorimeter.Get() && !this->IsParent(pTrack->id()))
+    if (trackParameters.m_reachesCalorimeter.Get() && !this->IsParent(pTrack->id().index))
     {
         const float d0(std::fabs(pTrack->getTrackStates(0).D0)), z0(std::fabs(pTrack->getTrackStates(0).Z0));
 
@@ -740,8 +748,8 @@ void TrackCreator::DefineTrackPfoUsage(edm4hep::Track *const pTrack, PandoraApi:
             const float zCutForNonVertexTracks(m_tpcInnerR * std::fabs(pZ / pT) + m_settings.m_zCutForNonVertexTracks);
             const bool passRzQualityCuts((zMin < zCutForNonVertexTracks) && (rInner < m_tpcInnerR + m_settings.m_maxTpcInnerRDistance));
 
-            const bool isV0(this->IsV0(pTrack->id()));
-            const bool isDaughter(this->IsDaughter(pTrack->id()));
+            const bool isV0(this->IsV0(pTrack->id().index));
+            const bool isDaughter(this->IsDaughter(pTrack->id().index));
 
             // Decide whether track can be associated with a pandora cluster and used to form a charged PFO
             if ((d0 < m_settings.m_d0TrackCut) && (z0 < m_settings.m_z0TrackCut) && (rInner < m_tpcInnerR + m_settings.m_maxTpcInnerRDistance))
@@ -778,7 +786,7 @@ void TrackCreator::DefineTrackPfoUsage(edm4hep::Track *const pTrack, PandoraApi:
                 }
             }
         }
-        else if (this->IsDaughter(pTrack->id()) || this->IsV0(pTrack->id()))
+        else if (this->IsDaughter(pTrack->id().index) || this->IsV0(pTrack->id().index))
         {
             std::cout<<"WARNING Recovering daughter or v0 track " << trackParameters.m_momentumAtDca.Get().GetMagnitude() << std::endl;
             canFormPfo = true;
@@ -870,14 +878,22 @@ bool TrackCreator::PassesQualityCuts(edm4hep::Track *const pTrack, const Pandora
 
 int TrackCreator::GetNTpcHits(edm4hep::Track *const pTrack) const
 {
+#if EDM4HEP_BUILD_VERSION > EDM4HEP_VERSION(0, 9, 0)
+    return pTrack->getSubdetectorHitNumbers(2 * lcio::ILDDetID::TPC - 1);// still use LCIO code now
+#else
     return pTrack->getSubDetectorHitNumbers(2 * lcio::ILDDetID::TPC - 1);// still use LCIO code now
+#endif
 }
 
 //------------------------------------------------------------------------------------------------------------------------------------------
 
 int TrackCreator::GetNFtdHits(edm4hep::Track *const pTrack) const
 {
+#if EDM4HEP_BUILD_VERSION > EDM4HEP_VERSION(0, 9, 0)
+    return pTrack->getSubdetectorHitNumbers( 2 * lcio::ILDDetID::FTD - 1 );
+#else
     return pTrack->getSubDetectorHitNumbers( 2 * lcio::ILDDetID::FTD - 1 );
+#endif
 }
 
 //------------------------------------------------------------------------------------------------------------------------------------------
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp b/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp
index 1b154b957..5e865cb16 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp
+++ b/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp
@@ -67,6 +67,7 @@ const int GenfitTrack::s_PDG[2][5]
 
     bool
 sortDCSimHit(edm4hep::SimTrackerHit hit1,edm4hep::SimTrackerHit hit2)
+//sortDCSimHit(edm4hep::ConstSimTrackerHit hit1,edm4hep::ConstSimTrackerHit hit2)
 {
     //std::cout<<"hit1"<<hit1<<std::endl;
     //std::cout<<"hit2"<<hit2<<std::endl;
@@ -75,11 +76,13 @@ sortDCSimHit(edm4hep::SimTrackerHit hit1,edm4hep::SimTrackerHit hit2)
 }
     bool
 sortDCDigi(std::pair<double,edm4hep::TrackerHit*> hitPair1,std::pair<double,edm4hep::TrackerHit*> hitPair2)
+//sortDCDigi(std::pair<double,edm4hep::ConstTrackerHit*> hitPair1,std::pair<double,edm4hep::ConstTrackerHit*> hitPair2)
 {
     bool isEarly=hitPair1.first<hitPair2.first;
     return isEarly;
 }
 //bool sortDCDigiLayer(std::pair<int,edm4hep::TrackerHit> hitPair1,std::pair<int,edm4hep::TrackerHit> hitPair2)
+//bool sortDCDigiLayer(std::pair<int,edm4hep::ConstTrackerHit> hitPair1,std::pair<int,edm4hep::ConstTrackerHit> hitPair2)
 //{
 //    bool isEarly=hitPair1.first<hitPair2.first;
 //    return isEarly;
@@ -162,7 +165,7 @@ bool GenfitTrack::createGenfitTrackFromEDM4HepTrack(int pidType,
     if(track.trackerHits_size()<=0) {
         std::cout << " track.trackerHits_size = " << track.trackerHits_size() << std::endl;
         if(m_debug){
-          std::cout<<"createGenfitTrackFromEDM4HepTrack skip track w/o hit"<<std::endl;
+            std::cout<<"createGenfitTrackFromEDM4HepTrack skip track w/o hit"<<std::endl;
         }
         return false;
     }
@@ -234,6 +237,7 @@ bool GenfitTrack::addSpacePointMeasurement(const TVector3& pos,
 /// Return isurface of a silicon hit
 const dd4hep::rec::ISurface*
 GenfitTrack::getISurface(edm4hep::TrackerHit* hit){
+//GenfitTrack::getISurface(edm4hep::ConstTrackerHit* hit){
     dd4hep::rec::SurfaceManager surfaceManager(*m_geomSvc->lcdd());
 
     std::string detectorName;
@@ -280,6 +284,7 @@ GenfitTrack::getISurface(edm4hep::TrackerHit* hit){
 /// Add a 1d strip or 2d pixel smeared by sigma
     bool
 GenfitTrack::addSiliconMeasurement(edm4hep::TrackerHit* hit,
+//GenfitTrack::addSiliconMeasurement(edm4hep::ConstTrackerHit* hit,
         float sigmaU,float sigmaV,int cellID,int hitID)
 {
     if(m_debug>0) std::cout<<"addSiliconMeasurement "<<*hit<<std::endl;
@@ -362,6 +367,47 @@ int GenfitTrack::addSiliconMeasurements(edm4hep::Track& track,
     return nHitAdd;
 }
 
+//Add wire measurement on wire, unit conversion here
+int GenfitTrack::addWireMeasurementsFromListTrF(const edm4hep::TrackerHitCollection* trkHits,
+        float sigma,int sortMethod)
+{
+    double driftVelocity=40.;
+    std::vector<edm4hep::TrackerHit*> hits;
+    for(auto trkHit:*trkHits){
+        hits.push_back(&trkHit);
+    }
+
+    std::vector<edm4hep::TrackerHit*> sortedTrackerHits;
+    getSortedTrackerHitsTrF(hits,sortedTrackerHits,sortMethod);
+
+    if(m_debug>0){
+        std::cout<<"n sortedTrackerHits "<<sortedTrackerHits.size()<<std::endl;
+    }
+    int nHitAdd=0;
+    for(auto trackerHit : sortedTrackerHits){
+
+        TVector3 end0(0,0,0);
+        TVector3 end1(0,0,0);
+        getEndPointsOfWire(trackerHit->getCellID(),end0,end1);
+
+        ///New a TrackPoint,create connection between meas. and trackPoint
+        WireMeasurementDC* wireMeasurementDC=
+            new WireMeasurementDC(1e-3*driftVelocity*trackerHit->getTime(),sigma,
+                    end0,end1,getDetTypeID(trackerHit->getCellID()),nHitAdd,nullptr);
+
+        int layer = m_decoderDC->get(trackerHit->getCellID(),"layer");
+        int cellID = m_decoderDC->get(trackerHit->getCellID(),"cellID");
+        const edm4hep::TrackerHit trackerHit_;
+        wireMeasurementDC->setTrackerHit(trackerHit_,layer,cellID);
+
+        m_track->insertPoint(new genfit::TrackPoint(wireMeasurementDC,m_track));
+        if(m_debug>=2){ std::cout<<nHitAdd-1; wireMeasurementDC->Print(); }
+        nHitAdd++;
+    }//end of loop over sotred hits
+    return nHitAdd;
+}//end of addWireMeasurementsFromList
+
+
 //Add wire measurement on wire, unit conversion here
 //int GenfitTrack::addWireMeasurementsFromList(podio::RelationRange<edm4hep::TrackerHit> hits,float sigma,
 int GenfitTrack::addWireMeasurementsFromList(std::vector<edm4hep::TrackerHit*>& hits,float sigma,
@@ -371,11 +417,11 @@ int GenfitTrack::addWireMeasurementsFromList(std::vector<edm4hep::TrackerHit*>&
     if(m_debug>0){ std::cout<<"addWireMeasurementsFromList"<<std::endl; }
     //podio::RelationRange<edm4hep::TrackerHit> hits_t=track.getTrackerHits();
     std::vector<edm4hep::TrackerHit*> sortedTrackerHits;
-//    sortedTrackerHits.reserve(100);
+    //    sortedTrackerHits.reserve(100);
     getSortedTrackerHits(hits,assoHits,sortedTrackerHits,sortMethod);
 
     if(m_debug>0){
-      std::cout<<"n sortedTrackerHits "<<sortedTrackerHits.size()<<std::endl;
+        std::cout<<"n sortedTrackerHits "<<sortedTrackerHits.size()<<std::endl;
     }
     int nHitAdd=0;
     for(auto trackerHit : sortedTrackerHits){
@@ -385,6 +431,7 @@ int GenfitTrack::addWireMeasurementsFromList(std::vector<edm4hep::TrackerHit*>&
         GenfitHit* genfitHit=
             makeAGenfitHit(trackerHit,&simTrackerHitAsso,sigma,truthAmbig,
                     skipCorner,skipNear);
+
         if(nullptr==genfitHit) continue;
         m_genfitHitVec.push_back(genfitHit);
 
@@ -397,6 +444,7 @@ int GenfitTrack::addWireMeasurementsFromList(std::vector<edm4hep::TrackerHit*>&
     return nHitAdd;
 }//end of addWireMeasurementsFromList
 
+
 //Add wire measurement on wire, unit conversion here
 int GenfitTrack::addWireMeasurementsOnTrack(edm4hep::Track& track,float sigma,
         const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
@@ -405,7 +453,7 @@ int GenfitTrack::addWireMeasurementsOnTrack(edm4hep::Track& track,float sigma,
     if(m_debug>0){ std::cout<<"addWireMeasurementsOnTrack"<<std::endl; }
 
     if(m_debug>0){
-      std::cout<<"n trackerHits size"<<track.trackerHits_size()<<std::endl;
+        std::cout<<"n trackerHits size"<<track.trackerHits_size()<<std::endl;
     }
     int nHitAdd=0;
     if(0==track.trackerHits_size()){
@@ -486,8 +534,8 @@ unsigned int GenfitTrack::getNumPoints() const
 }
 
 GenfitHit* GenfitTrack::GetHit(long unsigned int i) const {
-  if(i>=m_genfitHitVec.size())return nullptr;
-  return m_genfitHitVec[i];
+    if(i>=m_genfitHitVec.size())return nullptr;
+    return m_genfitHitVec[i];
 }
 
 unsigned int GenfitTrack::getNumPointsDet(int detTypeID) const
@@ -819,8 +867,8 @@ int GenfitTrack::addSpacePointsDC(const edm4hep::Track& track,
         std::vector<float> sigmaU,std::vector<float> sigmaV)
 {
     if(m_debug>=2){
-    std::cout<<m_name<<" 5. addSpacePointsDC nTrackerHit="
-        <<track.trackerHits_size()<<std::endl;
+        std::cout<<m_name<<" 5. addSpacePointsDC nTrackerHit="
+            <<track.trackerHits_size()<<std::endl;
     }
 
     ///Get TrackerHit with min. time in Cell
@@ -1079,7 +1127,9 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
         const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
         std::vector<double>& driftDis,
         std::vector<double>& FittedDoca,
-        std::vector<double>& Res)
+        std::vector<double>& truthDoca,
+        std::vector<double>& Res,
+        std::vector<double>& truthRes)
 {
 
     int id = 0;
@@ -1092,28 +1142,46 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
     //  getNumRawMeasurements
     unsigned int nPoints = m_track->getNumPoints();
     std::cout << " nPoints =  " << nPoints << std::endl;
+    unsigned int nPointsWithMea = m_track->getNumPointsWithMeasurement();
+    std::cout << " nPointsWithMea =  " << nPointsWithMea << std::endl;
 
     std::vector<double> hitMomMag;
 
+    //std::cout << __FILE__ << " " << __LINE__ << std::endl;
     while(1){
         genfit::TrackPoint* point = m_track->getPointWithFitterInfo(id);
+        //std::cout << __FILE__ << " " << __LINE__ << std::endl;
         if(!point)break;
+        //std::cout << __FILE__ << " " << __LINE__ << " id = " << id << std::endl;
         id++;
         genfit::AbsMeasurement* absMea = point->getRawMeasurement();
+        //std::cout << __FILE__ << " " << __LINE__ << " absMea: " << std::endl;
+        //absMea->Print();
 
         // getPoint FitterInfo
         genfit::AbsFitterInfo* FitterInfo = point->getFitterInfo();
+        //std::cout << __FILE__ << " " << __LINE__ << " FitterInfo: " << std::endl;
+        //FitterInfo->Print();
         genfit::KalmanFitterInfo *KalmanfitterInfo =
             dynamic_cast<genfit::KalmanFitterInfo*>(FitterInfo);
 
+        //std::cout << __FILE__ << " " << __LINE__ << " KalmanfitterInfo: " << std::endl;
+        //KalmanfitterInfo->Print();
+
         unsigned int nNumMea = KalmanfitterInfo->getNumMeasurements();
+        //std::cout << __FILE__ << " " << __LINE__ << " nNumMea = " << nNumMea << std::endl;
 
         bool flag = false;
         for(int i=0;i<nNumMea;i++)
         {
             genfit::MeasurementOnPlane* MeaOnPlane =
                 KalmanfitterInfo->getMeasurementOnPlane(i);
+            //std::cout << __FILE__ << " " << __LINE__ << " MeaOnPlane: " << std::endl;
+            //MeaOnPlane->Print();
+
             double weight = MeaOnPlane->getWeight();
+            std::cout << __FILE__ << " " << __LINE__ << " weight = " << weight << std::endl;
+
             if(weight>0.8) flag = true;
         }
         if(flag) fitid++;
@@ -1133,6 +1201,7 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
                 dynamic_cast<WireMeasurementDC*>(absMea);
             if(dcMea){
                 const edm4hep::TrackerHit* TrackerHit_ = dcMea->getTrackerHit();
+                if(nullptr==TrackerHit_) std::cout << __LINE__ << std::endl;
                 track.addToTrackerHits(*TrackerHit_);
 
 
@@ -1142,33 +1211,14 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
 
                     truthMomEdep.push_back(TrackerHit_->getEDep());
                     double DriftDis,fittedDoca,res = 0;
-                    GetDocaRes(dcFit,DriftDis,fittedDoca,res);
-                    driftDis.push_back(DriftDis);
-                    FittedDoca.push_back(fittedDoca);
+                    GetDocaRes((id-1),DriftDis,fittedDoca,res);
+                    driftDis.push_back(10*DriftDis);
+                    FittedDoca.push_back(10*fittedDoca);
+                    truthDoca.push_back(40*1e-3*TrackerHit_->getTime());
+                    truthRes.push_back((40*1e-3*TrackerHit_->getTime())-10*fittedDoca);
                     Res.push_back(res);
 
-                    //                    TMatrixDSym fittedHitCov(6);//cm, GeV
-                    //                    TLorentzVector fittedHitPos;
-                    //                    TVector3 fittedHitMom;
-                    //                    int fittedState=getFittedState(fittedHitPos,fittedHitMom,fittedHitCov,dcFit);
-                    //                    hitMomMag.push_back(fittedHitMom.Mag());
-                    //
-                    //                    for(int iSim=0;iSim<assoHits->size();iSim++)
-                    //                    {
-                    //                        //if(*TrackerHit_ == assoHits->at(iSim).getRec())
-                    //                        if(TrackerHit_->getCellID() == assoHits->at(iSim).getRec().getCellID())
-                    //                        {
-                    //                           // std::cout << " if  TrackerHit_ = " << TrackerHit_->getCellID() << std::endl;
-                    //                           // std::cout << " if assoHits->at(iSim).getRec() = " << assoHits->at(iSim).getRec().getCellID() << std::endl;
-                    //                           // std::cout << " Sim Mom = " << assoHits->at(iSim).getSim().getMomentum() << std::endl;
-                    //                           // std::cout << " Sim MomMag = " << sqrt(assoHits->at(iSim).getSim().getMomentum()[0]*assoHits->at(iSim).getSim().getMomentum()[0]+assoHits->at(iSim).getSim().getMomentum()[1]*assoHits->at(iSim).getSim().getMomentum()[1]+assoHits->at(iSim).getSim().getMomentum()[2]*assoHits->at(iSim).getSim().getMomentum()[2]) << std::endl;
-                    //
-                    //                            break;
-                    //                        }
-                    //                    }
-
-                    //std::cout << " i = " << dcFit << "fittedMom = " << fittedHitMom.X() << " " << fittedHitMom.Y() << " " << fittedHitMom.Z() << std::endl;
-                    //std::cout << " i = " << dcFit << "fittedMomMag = " << fittedHitMom.Mag() << std::endl;
+
                     dcFit++;
                 }
             }
@@ -1183,10 +1233,12 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
 
     std::cout<<"nDC: "<<nFittedDC<<", nSDT: "<<nFittedSDT<<std::endl;
     std::cout<<"nFittedDC: "<<dcFit<<", nFittedSDT: "<<sdtFit<<std::endl;
+
+    if(fitid<1e-9) return false;
+
     if(m_debug>0)std::cout<<m_name<<" store track ndfCut "<<ndfCut<<" chi2Cut "
         <<chi2Cut<<std::endl;
 
-
     /// Get fit status
     const genfit::FitStatus* fitState = getFitStatus();
     double ndf = fitState->getNdf();
@@ -1499,6 +1551,35 @@ void GenfitTrack::getTrackFromEDMTrack(const edm4hep::Track& edm4HepTrack,
     }
 }
 
+void GenfitTrack::getTrackFromEDMTrackFinding(const edm4hep::Track& edm4HepTrack,
+        double& charge, TVectorD& trackParam, TMatrixDSym& cov,TVector3& pos,
+        TVector3& mom){
+    //double Bz=m_genfitField->getBz(TVector3{0.,0.,0.})/GenfitUnit::tesla;
+    // FIXME
+    //double BZ=GenfitField::getBzFinding(TVector3{0.,0.,0.});
+    double Bz=3*GenfitUnit::tesla;
+    double charge_double;
+    CEPC::getPosMomFromTrackState(edm4HepTrack.getTrackStates(1),Bz,pos,mom,charge_double,cov);
+
+    //std::cout<<__LINE__<<" Bz "<<Bz<<" charge "<<charge_double<<std::endl;
+    //pos.Print();
+    //mom.Print();
+    charge=(int) charge_double;
+    trackParam[0]=pos[0]*GenfitUnit::mm;
+    trackParam[1]=pos[1]*GenfitUnit::mm;
+    trackParam[2]=pos[2]*GenfitUnit::mm;
+    trackParam[3]=mom[0]*GenfitUnit::GeV;
+    trackParam[4]=mom[1]*GenfitUnit::GeV;
+    trackParam[5]=mom[2]*GenfitUnit::GeV;
+
+    //cov unit conversion
+    for(int i=0;i<6;i++){
+        for(int j=0;j<6;j++){
+            cov(i,j) = cov(i,j)*GenfitUnit::mm;
+        }
+    }
+}
+
 //to genfit unit
 void GenfitTrack::getISurfaceOUV(const dd4hep::rec::ISurface* iSurface,TVector3& o,
         TVector3& u,TVector3& v, double& lengthU,double& lengthV){
@@ -1570,6 +1651,51 @@ bool GenfitTrack::isCDCHit(edm4hep::TrackerHit* hit){
         getDetTypeID(hit->getCellID());
 }
 
+// TrackFinding
+void GenfitTrack::getSortedTrackerHitsTrF(
+        std::vector<edm4hep::TrackerHit*> trackerHits,
+        std::vector<edm4hep::TrackerHit*>& sortedDCTrackerHits,
+        int sortMethod){
+
+    std::vector<std::pair<double,edm4hep::TrackerHit*> > sortedDCTrackerHitPair;
+    for(auto trackerHit : trackerHits){
+        //edm4hep::TrackerHit* thisHit = trackerHit;
+        //if(!isCDCHit(thisHit))continue;//skip non-DC trackerHit
+
+        double time=trackerHit->getTime();
+        if(0==sortMethod){
+            //by time
+            sortedDCTrackerHitPair.push_back(std::make_pair(time,trackerHit));
+            if(m_debug>0){ std::cout<<"sorted DC digi by time"<<std::endl;}
+        }else if(1==sortMethod){
+            //by layer
+            sortedDCTrackerHitPair.push_back(std::make_pair(
+                        m_decoderDC->get(trackerHit->getCellID(),"layer"),trackerHit));
+            if(m_debug>0){ std::cout<<"sorted DC digi by layer"<<std::endl;}
+        }else{
+            sortedDCTrackerHits.push_back(trackerHit);
+        }
+    }
+    if(0==sortMethod || 1==sortMethod){
+        std::sort(sortedDCTrackerHitPair.begin(),sortedDCTrackerHitPair.end(),
+                sortDCDigi);
+        for(auto trackerHit:sortedDCTrackerHitPair){
+            sortedDCTrackerHits.push_back(trackerHit.second);
+        }
+    }
+    if(m_debug>0){
+        std::cout<<"trackerHits on track after sort\n";
+        for(auto trackerHit:sortedDCTrackerHits){
+            std::cout<<trackerHit->getCellID()<<"("<<std::setw(2)
+                <<m_decoderDC->get(trackerHit->getCellID(),"layer")
+                <<","<<std::setw(3)
+                <<m_decoderDC->get(trackerHit->getCellID(),"cellID")<<")\n";
+        }
+        std::cout<<"\n"; std::cout.unsetf(std::ios_base::floatfield);
+    }
+    return;
+}//end of getSortedTrackerHits
+
 void GenfitTrack::getSortedTrackerHits(
         std::vector<edm4hep::TrackerHit*>& trackerHits,
         const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitTrack.h b/Reconstruction/RecGenfitAlg/src/GenfitTrack.h
index 27ef200b6..8a3e914a4 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitTrack.h
+++ b/Reconstruction/RecGenfitAlg/src/GenfitTrack.h
@@ -71,7 +71,7 @@ namespace dd4hep {
 class GenfitTrack {
     friend int GenfitFitter::processTrack(
             GenfitTrack* track, bool resort);
-
+    
     friend int GenfitFitter::processTrackWithRep(
             GenfitTrack* track, int repID, bool resort);
 
@@ -102,7 +102,6 @@ class GenfitTrack {
             const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
         std::vector<float> sigmaU,std::vector<float> sigmaV);
 
-
     ///Add WireMeasurements of hits on track
     virtual int addWireMeasurementsOnTrack(edm4hep::Track& track,float sigma,
             const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
@@ -113,6 +112,9 @@ class GenfitTrack {
             const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
             int sortMethod,bool truthAmbig,float skipCorner, float skipNear);
 
+    virtual int addWireMeasurementsFromListTrF(const edm4hep::TrackerHitCollection* trkHits,
+            float sigma,int sortMethod);
+
     ///Add one silicon hits
     bool addSiliconMeasurement(edm4hep::TrackerHit* hit,
             float sigmaU,float sigmaV,int cellID,int hitID);
@@ -141,7 +143,9 @@ class GenfitTrack {
             const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
             std::vector<double>& driftDis,
             std::vector<double>& FittedDoca,
-            std::vector<double>& Res);
+            std::vector<double>& truthDoca,
+            std::vector<double>& Res,
+            std::vector<double>& truthRes);
 
     ///A tool to convert track to the first layer of DC
     void pivotToFirstLayer(const edm4hep::Vector3d& pos,
@@ -221,6 +225,10 @@ class GenfitTrack {
 
     /// Get a hit according to index
     GenfitHit* GetHit(long unsigned int i) const;
+    
+    static void getTrackFromEDMTrackFinding(const edm4hep::Track& edm4HepTrack,
+            double& charge, TVectorD& trackParam, TMatrixDSym& cov,TVector3& pos,
+            TVector3& mom);
     protected:
     //genfit::Track* getTrack() {return m_track;}
 
@@ -265,6 +273,9 @@ class GenfitTrack {
             const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
             std::vector<edm4hep::TrackerHit*>& sortedDCTrackerHits,
             int sortMethod);
+    void getSortedTrackerHitsTrF(std::vector<edm4hep::TrackerHit*> trackerHits,
+            std::vector<edm4hep::TrackerHit*>& sortedDCTrackerHits,
+            int sortMethod=1);
 
     genfit::Track* m_track;/// track
     int m_debug;/// debug level
diff --git a/Reconstruction/SiliconTracking/src/ForwardTrackingAlg.cpp b/Reconstruction/SiliconTracking/src/ForwardTrackingAlg.cpp
index df95acc6c..3eb06e297 100644
--- a/Reconstruction/SiliconTracking/src/ForwardTrackingAlg.cpp
+++ b/Reconstruction/SiliconTracking/src/ForwardTrackingAlg.cpp
@@ -6,6 +6,14 @@
 #include "edm4hep/TrackerHit.h"
 #include "edm4hep/TrackerHit.h"
 #include "edm4hep/Track.h"
+#if __has_include("edm4hep/EDM4hepVersion.h")
+#include "edm4hep/EDM4hepVersion.h"
+#else
+// Copy the necessary parts from  the header above to make whatever we need to work here
+#define EDM4HEP_VERSION(major, minor, patch) ((UINT64_C(major) << 32) | (UINT64_C(minor) << 16) | (UINT64_C(patch)))
+// v00-09 is the last version without the capitalization change of the track vector members
+#define EDM4HEP_BUILD_VERSION EDM4HEP_VERSION(0, 9, 0)
+#endif
 
 #include "UTIL/ILDConf.h"
 
@@ -1001,13 +1009,21 @@ void ForwardTrackingAlg::finaliseTrack( edm4hep::MutableTrack* trackImpl ){
   //trackImpl->subdetectorHitNumbers()[ 2 * lcio::ILDDetID::TPC - 1 ] = hitNumbers[lcio::ILDDetID::TPC];
   //trackImpl->subdetectorHitNumbers()[ 2 * lcio::ILDDetID::SET - 1 ] = hitNumbers[lcio::ILDDetID::SET];
   //trackImpl->subdetectorHitNumbers()[ 2 * lcio::ILDDetID::ETD - 1 ] = hitNumbers[lcio::ILDDetID::ETD];
+#if EDM4HEP_BUILD_VERSION > EDM4HEP_VERSION(0, 9, 0)
+  trackImpl->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::VXD]);
+  trackImpl->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::SIT]);
+  trackImpl->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::FTD]);
+  trackImpl->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::TPC]);
+  trackImpl->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::SET]);
+  trackImpl->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::ETD]);
+#else
   trackImpl->addToSubDetectorHitNumbers(hitNumbers[UTIL::ILDDetID::VXD]);
   trackImpl->addToSubDetectorHitNumbers(hitNumbers[UTIL::ILDDetID::SIT]);
   trackImpl->addToSubDetectorHitNumbers(hitNumbers[UTIL::ILDDetID::FTD]);
   trackImpl->addToSubDetectorHitNumbers(hitNumbers[UTIL::ILDDetID::TPC]);
   trackImpl->addToSubDetectorHitNumbers(hitNumbers[UTIL::ILDDetID::SET]);
   trackImpl->addToSubDetectorHitNumbers(hitNumbers[UTIL::ILDDetID::ETD]);
-     
+#endif
   return;
 }
 
diff --git a/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.cpp b/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.cpp
index f9b6a5466..1ef104fa4 100644
--- a/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.cpp
+++ b/Reconstruction/SiliconTracking/src/SiliconTrackingAlg.cpp
@@ -9,6 +9,14 @@
 //#include "edm4hep/TrackerHitPlane.h"
 #include "edm4hep/Track.h"
 #include "edm4hep/TrackState.h"
+#if __has_include("edm4hep/EDM4hepVersion.h")
+#include "edm4hep/EDM4hepVersion.h"
+#else
+// Copy the necessary parts from  the header above to make whatever we need to work here
+#define EDM4HEP_VERSION(major, minor, patch) ((UINT64_C(major) << 32) | (UINT64_C(minor) << 16) | (UINT64_C(patch)))
+// v00-09 is the last version without the capitalization change of the track vector members
+#define EDM4HEP_BUILD_VERSION EDM4HEP_VERSION(0, 9, 0)
+#endif
 
 #include <iostream>
 #include <algorithm>
@@ -2833,10 +2841,15 @@ void SiliconTrackingAlg::FinalRefit(edm4hep::TrackCollection* trk_col) {
       MarlinTrk::addHitNumbersToTrack(&track, all_hits, false, cellID_encoder);
       
       delete marlinTrk;
-
+#if EDM4HEP_BUILD_VERSION > EDM4HEP_VERSION(0, 9, 0)
+      int nhits_in_vxd = track.getSubdetectorHitNumbers(0);
+      int nhits_in_ftd = track.getSubdetectorHitNumbers(1);
+      int nhits_in_sit = track.getSubdetectorHitNumbers(2);
+#else
       int nhits_in_vxd = track.getSubDetectorHitNumbers(0);
       int nhits_in_ftd = track.getSubDetectorHitNumbers(1);
       int nhits_in_sit = track.getSubDetectorHitNumbers(2);
+#endif
       
       //debug() << " Hit numbers for Track "<< track.id() << ": "
       debug() << " Hit numbers for Track "<< iTrk <<": "
diff --git a/Reconstruction/Tracking/src/FullLDCTracking/FullLDCTrackingAlg.cpp b/Reconstruction/Tracking/src/FullLDCTracking/FullLDCTrackingAlg.cpp
old mode 100755
new mode 100644
index 08e1fb022..ee5f1feb2
--- a/Reconstruction/Tracking/src/FullLDCTracking/FullLDCTrackingAlg.cpp
+++ b/Reconstruction/Tracking/src/FullLDCTracking/FullLDCTrackingAlg.cpp
@@ -8,6 +8,14 @@
 #include <edm4hep/TrackerHit.h>
 #include <edm4hep/TrackerHit.h>
 #include <edm4hep/Track.h>
+#if __has_include("edm4hep/EDM4hepVersion.h")
+#include "edm4hep/EDM4hepVersion.h"
+#else
+// Copy the necessary parts from  the header above to make whatever we need to work here
+#define EDM4HEP_VERSION(major, minor, patch) ((UINT64_C(major) << 32) | (UINT64_C(minor) << 16) | (UINT64_C(patch)))
+// v00-09 is the last version without the capitalization change of the track vector members
+#define EDM4HEP_BUILD_VERSION EDM4HEP_VERSION(0, 9, 0)
+#endif
 
 #include <iostream>
 #include <algorithm>
@@ -513,11 +521,19 @@ void FullLDCTrackingAlg::AddTrackColToEvt(TrackExtendedVec & trkVec, edm4hep::Tr
     float z0TrkCand = trkCand->getZ0();
     //    float phi0TrkCand = trkCand->getPhi();
     // FIXME, fucd
+#if EDM4HEP_BUILD_VERSION > EDM4HEP_VERSION(0, 9, 0)
+    int nhits_in_vxd = track.getSubdetectorHitNumbers(0);
+    int nhits_in_ftd = track.getSubdetectorHitNumbers(1);
+    int nhits_in_sit = track.getSubdetectorHitNumbers(2);
+    int nhits_in_tpc = track.getSubdetectorHitNumbers(3);
+    int nhits_in_set = track.getSubdetectorHitNumbers(4);
+#else
     int nhits_in_vxd = track.getSubDetectorHitNumbers(0);
     int nhits_in_ftd = track.getSubDetectorHitNumbers(1);
     int nhits_in_sit = track.getSubDetectorHitNumbers(2);
     int nhits_in_tpc = track.getSubDetectorHitNumbers(3);
     int nhits_in_set = track.getSubDetectorHitNumbers(4);
+#endif
     //int nhits_in_vxd = Track->subdetectorHitNumbers()[ 2 * lcio::ILDDetID::VXD - 2 ];
     //int nhits_in_ftd = Track->subdetectorHitNumbers()[ 2 * lcio::ILDDetID::FTD - 2 ];
     //int nhits_in_sit = Track->subdetectorHitNumbers()[ 2 * lcio::ILDDetID::SIT - 2 ];
@@ -1150,13 +1166,18 @@ void FullLDCTrackingAlg::prepareVectors() {
       trackExt->setNDF(tpcTrack.getNdf());
       trackExt->setChi2(tpcTrack.getChi2());
       for (int iHit=0;iHit<nHits;++iHit) {
-	edm4hep::TrackerHit hit = tpcTrack.getTrackerHits(iHit);//hitVec[iHit];
-	if(!hit.isAvailable()) error() << "Tracker hit not available" << endmsg;
+	edm4hep::TrackerHit hit = tpcTrack.getTrackerHits(iHit);
+	if (!hit.isAvailable()) {
+	  error() << "Tracker hit not available" << endmsg;
+	  continue;
+	}
 	//info() << "hit " << hit.id() << " " << hit.getCellID() << " " << hit.getPosition()[0] << " " << hit.getPosition()[1] << " " << hit.getPosition()[2] << endmsg;
 	auto it = mapTrackerHits.find(hit);
-	if(it==mapTrackerHits.end()) error() << "Cannot find hit " << hit.id() << " in map" << endmsg;
-	else continue;
-        TrackerHitExtended * hitExt = it->second;
+	if (it==mapTrackerHits.end()) {
+	  error() << "Cannot find hit " << hit.id() << " in map" << endmsg;
+	  continue;
+	}
+        TrackerHitExtended* hitExt = it->second;
 	//info() << hit.id() << " " << hitExt << endmsg;
         hitExt->setTrackExtended( trackExt );
         trackExt->addTrackerHitExtended( hitExt );
@@ -1215,8 +1236,17 @@ void FullLDCTrackingAlg::prepareVectors() {
       char strg[200];
       HelixClass helixSi;
       for (int iHit=0;iHit<nHits;++iHit) {
-	edm4hep::TrackerHit hit = siTrack.getTrackerHits(iHit);//hitVec[iHit];
-        TrackerHitExtended * hitExt = mapTrackerHits[hit];
+	edm4hep::TrackerHit hit = siTrack.getTrackerHits(iHit);
+	if (!hit.isAvailable()) {
+	  error() << "Tracker hit not available" << endmsg;
+	  continue;
+	}
+	auto it = mapTrackerHits.find(hit);
+        if (it==mapTrackerHits.end()) {
+	  error() << "Cannot find hit " << hit.id() << " in map" << endmsg;
+	  continue;
+	}
+        TrackerHitExtended* hitExt = it->second;
         hitExt->setTrackExtended( trackExt );
         
         trackExt->addTrackerHitExtended( hitExt );
@@ -1518,8 +1548,8 @@ TrackExtended * FullLDCTrackingAlg::CombineTracks(TrackExtended * tpcTrack, Trac
   int nTPCHits = int(tpcHitVec.size());
   int nHits = nTPCHits + nSiHits;
   
-  //std::cout << "FullLDCTrackingAlg::CombineTracks nSiHits = " << nSiHits << endmsg;
-  //std::cout << "FullLDCTrackingAlg::CombineTracks nTPCHits = " << nTPCHits << endmsg;
+  //debug() << "FullLDCTrackingAlg::CombineTracks nSiHits = " << nSiHits << endmsg;
+  //debug() << "FullLDCTrackingAlg::CombineTracks nTPCHits = " << nTPCHits << endmsg;
   
   TrackerHitVec trkHits;
   trkHits.reserve(nHits);
@@ -1732,7 +1762,7 @@ TrackExtended * FullLDCTrackingAlg::CombineTracks(TrackExtended * tpcTrack, Trac
       tpcHitInFit.push_back(tpcHitVec[i]);
     }
   }
-  
+
   debug() << "FullLDCTrackingAlg::CombineTracks: Check for Silicon Hit rejections ... " << endmsg;
   
   if ( (int)siOutliers.size() > _maxAllowedSiHitRejectionsForTrackCombination ) {
diff --git a/Service/TrackSystemSvc/src/MarlinKalTestTrack.cc b/Service/TrackSystemSvc/src/MarlinKalTestTrack.cc
index ffedd64ed..3ca601461 100644
--- a/Service/TrackSystemSvc/src/MarlinKalTestTrack.cc
+++ b/Service/TrackSystemSvc/src/MarlinKalTestTrack.cc
@@ -26,6 +26,8 @@
 #include "gear/GEAR.h"
 #include "gear/BField.h"
 
+#include "podio/podioVersion.h"
+
 //#include "streamlog/streamlog.h"
 
 
@@ -76,8 +78,12 @@ namespace MarlinTrk {
   
   
   MarlinKalTestTrack::MarlinKalTestTrack(MarlinKalTest* ktest) 
-    : _ktest(ktest), _trackHitAtPositiveNDF(edm4hep::TrackerHit(0)) {
-    
+    : _ktest(ktest),
+#if PODIO_BUILD_VERSION < PODIO_VERSION(0, 17, 4)
+      _trackHitAtPositiveNDF(edm4hep::TrackerHit(0)) {
+#else
+      _trackHitAtPositiveNDF(edm4hep::TrackerHit::makeEmpty()) {
+#endif
     _kaltrack = new TKalTrack() ;
     _kaltrack->SetOwner() ;
     
diff --git a/Service/TrackSystemSvc/src/MarlinTrkUtils.cc b/Service/TrackSystemSvc/src/MarlinTrkUtils.cc
index ffa0f7f93..fcacb19cf 100644
--- a/Service/TrackSystemSvc/src/MarlinTrkUtils.cc
+++ b/Service/TrackSystemSvc/src/MarlinTrkUtils.cc
@@ -16,6 +16,15 @@
 #include "edm4hep/Track.h"
 #include "edm4hep/MutableTrack.h"
 
+#if __has_include("edm4hep/EDM4hepVersion.h")
+#include "edm4hep/EDM4hepVersion.h"
+#else
+// Copy the necessary parts from  the header above to make whatever we need to work here
+#define EDM4HEP_VERSION(major, minor, patch) ((UINT64_C(major) << 32) | (UINT64_C(minor) << 16) | (UINT64_C(patch)))
+// v00-09 is the last version without the capitalization change of the track vector members
+#define EDM4HEP_BUILD_VERSION EDM4HEP_VERSION(0, 9, 0)
+#endif
+
 #include <UTIL/BitField64.h>
 #include <UTIL/ILDConf.h>
 #include <UTIL/BitSet32.h>
@@ -24,6 +33,8 @@
 
 #include "TMatrixD.h"
 
+#include "podio/podioVersion.h"
+
 #define MIN_NDF 6
 
 namespace MarlinTrk {
@@ -258,7 +269,9 @@ namespace MarlinTrk {
     // set the initial track parameters  
     ///////////////////////////////////////////////////////
     
-    return_error = marlinTrk->initialise( *pre_fit, bfield_z, IMarlinTrack::backward ) ;
+    //return_error = marlinTrk->initialise( *pre_fit, bfield_z, IMarlinTrack::backward ) ;
+    // fucd: previous fixed as IMarlinTrack::backward, can not change? using input value now
+    return_error = marlinTrk->initialise( *pre_fit, bfield_z, fit_backwards ) ;
     if (return_error != IMarlinTrack::success) {
       
       std::cout << "MarlinTrk::createFit Initialisation of track fit failed with error : " << return_error << std::endl;
@@ -388,10 +401,10 @@ namespace MarlinTrk {
     return_error = marlintrk->getNDF(ndf);
 
     if ( return_error != IMarlinTrack::success) {
-      //streamlog_out(DEBUG3) << "MarlinTrk::finaliseLCIOTrack: getNDF returns " << return_error << std::endl;
+      //std::cout << "MarlinTrk::finaliseLCIOTrack: getNDF returns " << return_error << std::endl;
       return return_error;
     } else if( ndf < 0 ) {
-      //streamlog_out(DEBUG2) << "MarlinTrk::finaliseLCIOTrack: number of degrees of freedom less than 0 track dropped : NDF = " << ndf << std::endl;
+      //std::cout << "MarlinTrk::finaliseLCIOTrack: number of degrees of freedom less than 0 track dropped : NDF = " << ndf << std::endl;
       return IMarlinTrack::error;
     } else {
       //streamlog_out(DEBUG1) << "MarlinTrk::finaliseLCIOTrack: NDF = " << ndf << std::endl;
@@ -481,9 +494,14 @@ namespace MarlinTrk {
     ///////////////////////////////////////////////////////
     
     edm4hep::TrackState* trkStateAtLastHit = new edm4hep::TrackState() ;
+
     edm4hep::TrackerHit lastHit = hits_in_fit.front().first;
           
+#if PODIO_BUILD_VERSION < PODIO_VERSION(0, 17, 4)
     edm4hep::TrackerHit last_constrained_hit(0);// = 0 ;
+#else
+		auto last_constrained_hit = edm4hep::TrackerHit::makeEmpty();
+#endif
     marlintrk->getTrackerHitAtPositiveNDF(last_constrained_hit);
 
     return_error = marlintrk->smooth(lastHit);
@@ -543,7 +561,6 @@ namespace MarlinTrk {
       track->addToTrackStates(*trkStateAtFirstHit);
     } else {
       //streamlog_out( WARNING ) << "  >>>>>>>>>>> MarlinTrk::finaliseLCIOTrack:  could not get TrackState at First Hit " << firstHit << std::endl ;
-      delete trkStateAtFirstHit;
     }
     
     double r_first = firstHit.getPosition()[0]*firstHit.getPosition()[0] + firstHit.getPosition()[1]*firstHit.getPosition()[1];
@@ -569,7 +586,7 @@ namespace MarlinTrk {
         track->addToTrackStates(*trkStateAtLastHit);
       } else {
 	std::cout << "ERROR>>>>>>>>>>> MarlinTrk::finaliseLCIOTrack:  could not get TrackState at Last Hit " << last_constrained_hit.id() << std::endl ;
-        delete trkStateAtLastHit;
+        //delete trkStateAtLastHit;
       }
       
 //      const EVENT::FloatVec& ma = trkStateAtLastHit->getCovMatrix();
@@ -587,17 +604,22 @@ namespace MarlinTrk {
 //      return_error = createTrackStateAtCaloFace(marlintrk, trkStateCalo, lastHit, tanL_is_positive);
       
       if ( return_error == 0 ) {
+	//std::cout << "fucdout referencePoint " << trkStateCalo.referencePoint << std::endl;
         trkStateCalo.location = MarlinTrk::Location::AtCalorimeter;
         track->addToTrackStates(trkStateCalo);
       } else {
-        //streamlog_out( WARNING ) << "  >>>>>>>>>>> MarlinTrk::finaliseLCIOTrack:  could not get TrackState at Calo Face "  << std::endl ;
+	std::cout << "  >>>>>>>>>>> MarlinTrk::finaliseLCIOTrack:  could not get TrackState at Calo Face "  << std::endl ;
         //delete trkStateCalo;
       }
     } else {
       track->addToTrackStates(*atLastHit);
       track->addToTrackStates(*atCaloFace);
+      //delete trkStateAtLastHit;
     }
-    
+
+    if(trkStateAtFirstHit) delete trkStateAtFirstHit;
+    if(trkStateAtLastHit)  delete trkStateAtLastHit;
+    if(trkStateIP)         delete trkStateIP;
     ///////////////////////////////////////////////////////
     // done
     ///////////////////////////////////////////////////////
@@ -688,12 +710,21 @@ namespace MarlinTrk {
     if ( hits_in_fit == false ) { // all hit atributed by patrec
       offset = 1 ;
     }
+#if EDM4HEP_BUILD_VERSION > EDM4HEP_VERSION(0, 9, 0)
+    track->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::VXD]);
+    track->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::FTD]);
+    track->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::SIT]);
+    track->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::TPC]);
+    track->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::SET]);
+    track->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::ETD]);
+#else
     track->addToSubDetectorHitNumbers(hitNumbers[UTIL::ILDDetID::VXD]);
     track->addToSubDetectorHitNumbers(hitNumbers[UTIL::ILDDetID::FTD]);
     track->addToSubDetectorHitNumbers(hitNumbers[UTIL::ILDDetID::SIT]);
     track->addToSubDetectorHitNumbers(hitNumbers[UTIL::ILDDetID::TPC]);
     track->addToSubDetectorHitNumbers(hitNumbers[UTIL::ILDDetID::SET]);
     track->addToSubDetectorHitNumbers(hitNumbers[UTIL::ILDDetID::ETD]);
+#endif
     //track->subdetectorHitNumbers().resize(2 * lcio::ILDDetID::ETD);
     //track->subdetectorHitNumbers()[ 2 * lcio::ILDDetID::VXD - offset ] = hitNumbers[lcio::ILDDetID::VXD];
     //track->subdetectorHitNumbers()[ 2 * lcio::ILDDetID::FTD - offset ] = hitNumbers[lcio::ILDDetID::FTD];
@@ -732,12 +763,21 @@ namespace MarlinTrk {
     if ( hits_in_fit == false ) { // all hit atributed by patrec
       offset = 1 ;
     }
+#if EDM4HEP_BUILD_VERSION > EDM4HEP_VERSION(0, 9, 0)
+    track->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::VXD]);
+    track->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::FTD]);
+    track->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::SIT]);
+    track->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::TPC]);
+    track->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::SET]);
+    track->addToSubdetectorHitNumbers(hitNumbers[UTIL::ILDDetID::ETD]);
+#else
     track->addToSubDetectorHitNumbers(hitNumbers[lcio::ILDDetID::VXD]);
     track->addToSubDetectorHitNumbers(hitNumbers[lcio::ILDDetID::FTD]);
     track->addToSubDetectorHitNumbers(hitNumbers[lcio::ILDDetID::SIT]);
     track->addToSubDetectorHitNumbers(hitNumbers[lcio::ILDDetID::TPC]);
     track->addToSubDetectorHitNumbers(hitNumbers[lcio::ILDDetID::SET]);
     track->addToSubDetectorHitNumbers(hitNumbers[lcio::ILDDetID::ETD]);
+#endif
     //track->subdetectorHitNumbers().resize(2 * lcio::ILDDetID::ETD);
     //track->subdetectorHitNumbers()[ 2 * lcio::ILDDetID::VXD - offset ] = hitNumbers[lcio::ILDDetID::VXD];
     //track->subdetectorHitNumbers()[ 2 * lcio::ILDDetID::FTD - offset ] = hitNumbers[lcio::ILDDetID::FTD];
diff --git a/Simulation/DetSimAna/CMakeLists.txt b/Simulation/DetSimAna/CMakeLists.txt
index 883dfd821..b1bd935f3 100644
--- a/Simulation/DetSimAna/CMakeLists.txt
+++ b/Simulation/DetSimAna/CMakeLists.txt
@@ -5,12 +5,17 @@ include(${Geant4_USE_FILE})
 gaudi_add_module(DetSimAna
                  SOURCES src/Edm4hepWriterAnaElemTool.cpp
                  LINK DetSimInterface
+                      DetSimSDLib
                       ${DD4hep_COMPONENT_LIBRARIES} 
                       Gaudi::GaudiKernel
                       EDM4HEP::edm4hep EDM4HEP::edm4hepDict
                       k4FWCore::k4FWCore
 )
 
+target_include_directories(DetSimAna PUBLIC
+  $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>/include
+  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
+
 install(TARGETS DetSimAna
   EXPORT CEPCSWTargets
   RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT bin
diff --git a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp
index b05e7994b..0c687f827 100644
--- a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp
+++ b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.cpp
@@ -1,5 +1,6 @@
 #include "Edm4hepWriterAnaElemTool.h"
 
+#include "G4Step.hh"
 #include "G4Event.hh"
 #include "G4THitsCollection.hh"
 #include "G4EventManager.hh"
@@ -12,13 +13,36 @@
 #include "DDG4/Geant4Mapping.h"
 #include "DDG4/Geant4HitCollection.h"
 #include "DDG4/Geant4Data.h"
-#include "DDG4/Geant4Hits.h"
+#include "DetSimSD/Geant4Hits.h"
 
 DECLARE_COMPONENT(Edm4hepWriterAnaElemTool)
 
 void
 Edm4hepWriterAnaElemTool::BeginOfRunAction(const G4Run*) {
+    auto msglevel = msgLevel();
+    if (msglevel == MSG::VERBOSE || msglevel == MSG::DEBUG) {
+        verboseOutput = true;
+    }
+
     G4cout << "Begin Run of detector simultion..." << G4endl;
+
+    // access geometry service
+    m_geosvc = service<IGeomSvc>("GeomSvc");
+    if (m_geosvc) {
+        dd4hep::Detector* dd4hep_geo = m_geosvc->lcdd();
+        // try to get the constants
+        R = dd4hep_geo->constant<double>("tracker_region_rmax")/dd4hep::mm*CLHEP::mm;
+        Z = dd4hep_geo->constant<double>("tracker_region_zmax")/dd4hep::mm*CLHEP::mm;
+
+        info() << "Tracker Region "
+               << " R: " << R
+               << " Z: " << Z
+               << endmsg;
+
+    } else {
+        error() << "Failed to find GeomSvc." << endmsg;
+    }
+
 }
 
 void
@@ -30,6 +54,15 @@ void
 Edm4hepWriterAnaElemTool::BeginOfEventAction(const G4Event* anEvent) {
     msg() << "Event " << anEvent->GetEventID() << endmsg;
 
+    // event info
+    m_userinfo = nullptr;
+    if (anEvent->GetUserInformation()) {
+        m_userinfo = dynamic_cast<CommonUserEventInfo*>(anEvent->GetUserInformation());
+        if (verboseOutput) {
+            m_userinfo->dumpIdxG4Track2Edm4hep();
+        }
+    }
+
     auto mcGenCol = m_mcParGenCol.get();
     mcCol = m_mcParCol.createAndPut();
 
@@ -50,17 +83,18 @@ Edm4hepWriterAnaElemTool::BeginOfEventAction(const G4Event* anEvent) {
         newparticle.setColorFlow      (mcGenParticle.getColorFlow());
     }
     
-    msg() << "mcCol size: " << mcCol->size() << endmsg;
+    msg() << "mcCol size (original) : " << mcCol->size() << endmsg;
 
     // reset
     m_track2primary.clear();
-
+ 
 }
 
 void
 Edm4hepWriterAnaElemTool::EndOfEventAction(const G4Event* anEvent) {
-    // save all data
 
+    msg() << "mcCol size (after simulation) : " << mcCol->size() << endmsg;
+    // save all data
     // create collections.
     auto trackercols = m_trackerCol.createAndPut();
     auto calorimetercols = m_calorimeterCol.createAndPut();
@@ -257,7 +291,12 @@ Edm4hepWriterAnaElemTool::EndOfEventAction(const G4Event* anEvent) {
                         pritrkid = 1;
                     }
 
-                    edm_trk_hit.setMCParticle(mcCol->at(pritrkid-1));
+                    if (m_userinfo) {
+                        auto idxedm4hep =  m_userinfo->idxG4Track2Edm4hep(pritrkid);
+                        if (idxedm4hep != -1) {
+                            edm_trk_hit.setMCParticle(mcCol->at(idxedm4hep));
+                        }
+                    }
 
                     if (pritrkid != trackID) {
                         // If the track is a secondary, then the primary track id and current track id is different
@@ -297,7 +336,12 @@ Edm4hepWriterAnaElemTool::EndOfEventAction(const G4Event* anEvent) {
                             pritrkid = 1;
                         }
 
-                        edm_calo_contrib.setParticle(mcCol->at(pritrkid-1)); // todo
+                        if (m_userinfo) {
+                            auto idxedm4hep =  m_userinfo->idxG4Track2Edm4hep(pritrkid);
+                            if (idxedm4hep != -1) {
+                                edm_calo_contrib.setParticle(mcCol->at(idxedm4hep)); // todo
+                            }
+                        }
                         edm_calo_hit.addToContributions(edm_calo_contrib);
                     }
                 }
@@ -345,17 +389,27 @@ void
 Edm4hepWriterAnaElemTool::PostUserTrackingAction(const G4Track* track) {
     int curtrkid = track->GetTrackID(); // starts from 1
     int curparid = track->GetParentID();
+    int idxedm4hep = -1;
 
-    if (curparid == 0) {
+    if (m_userinfo) {
+        idxedm4hep =  m_userinfo->idxG4Track2Edm4hep(curtrkid);
+    }
+
+    if (curparid == 0) { // Primary Track
         // select the primary tracks (parentID == 0)
         // auto mcCol = m_mcParCol.get();
 
-        if (curtrkid-1>=mcCol->size()) {
+        if (idxedm4hep == -1) {
+            error () << "Failed to get idxedm4hep according to the g4track id " << curtrkid << endmsg;
+            return;
+        }
+
+        if (idxedm4hep>=mcCol->size()) {
             error() << "out of range: curtrkid is " << curtrkid
                     << " while the MCParticle size is " << mcCol->size() << endmsg;
             return;
         }
-        auto primary_particle = mcCol->at(curtrkid-1);
+        auto primary_particle = mcCol->at(idxedm4hep);
 
         const G4ThreeVector& stop_pos  = track->GetPosition();
         edm4hep::Vector3d endpoint(stop_pos.x()/CLHEP::mm,
@@ -407,14 +461,14 @@ Edm4hepWriterAnaElemTool::PostUserTrackingAction(const G4Track* track) {
 
                 // select the necessary processes
                 if (creatorProcess==proc_decay) {
-                    info() << "Creator Process is Decay for secondary particle: "
-                           << " idx: " << i
-                           << " trkid: " << sectrk->GetTrackID() // not valid until track
-                           << " particle: " << secparticle->GetParticleName()
-                           << " pdg: " << secparticle->GetPDGEncoding()
-                           << " at position: " << sectrk->GetPosition() //
-                           << " time: " << sectrk->GetGlobalTime()
-                           << " momentum: " << sectrk->GetMomentum() // 
+                    debug() << "Creator Process is Decay for secondary particle: "
+                            << " idx: " << i
+                            << " trkid: " << sectrk->GetTrackID() // not valid until track
+                            << " particle: " << secparticle->GetParticleName()
+                            << " pdg: " << secparticle->GetPDGEncoding()
+                            << " at position: " << sectrk->GetPosition() //
+                            << " time: " << sectrk->GetGlobalTime()
+                            << " momentum: " << sectrk->GetMomentum() // 
                            << endmsg;
                     is_decay = true;
 
@@ -445,6 +499,15 @@ Edm4hepWriterAnaElemTool::PostUserTrackingAction(const G4Track* track) {
 
                     mcp.addToParents(primary_particle);
                     primary_particle.addToDaughters(mcp);
+
+                    // store the edm4hep obj idx in track info.
+                    // using this idx, the MCParticle object could be modified later. 
+                    auto trackinfo = new CommonUserTrackInfo();
+                    trackinfo->setIdxEdm4hep(mcp.getObjectID().index);
+                    sectrk->SetUserInformation(trackinfo);
+                    debug() << " Appending MCParticle: (id: " 
+                            << mcp.getObjectID().index << ")"
+                            << endmsg;
                 }
             }
         }
@@ -462,8 +525,36 @@ Edm4hepWriterAnaElemTool::PostUserTrackingAction(const G4Track* track) {
 }
 
 void
-Edm4hepWriterAnaElemTool::UserSteppingAction(const G4Step*) {
-
+Edm4hepWriterAnaElemTool::UserSteppingAction(const G4Step* aStep) {
+    auto aTrack = aStep->GetTrack();
+    // try to get user track info
+    auto trackinfo = dynamic_cast<CommonUserTrackInfo*>(aTrack->GetUserInformation());
+
+    // ========================================================================
+    // Note:
+    // if there is no track info, then do nothing. 
+    // ========================================================================
+    if (trackinfo) {
+        // back scattering is defined as following:
+        // - pre point is not in tracker
+        // - post point is in tracker
+        // For details, look at Mokka's source code:
+        //   https://llrforge.in2p3.fr/trac/Mokka/browser/trunk/source/Kernel/src/SteppingAction.cc
+        const auto& pre_pos = aStep->GetPreStepPoint()->GetPosition();
+        const auto& post_pos = aStep->GetPostStepPoint()->GetPosition();
+
+        bool is_pre_in_tracker = pre_pos.perp() < R && std::fabs(pre_pos.z()) < Z;
+        bool is_post_in_tracker = post_pos.perp() < R && std::fabs(post_pos.z()) < Z;
+
+        if ((!is_pre_in_tracker) and is_post_in_tracker) {
+            // set back scattering
+            auto idxedm4hep = trackinfo->idxEdm4hep();
+            mcCol->at(idxedm4hep).setBackscatter(true);
+            debug() << " set back scatter for MCParticle "
+                    << " (ID: " << idxedm4hep << ")"
+                    << endmsg;
+        }
+    }
 }
 
 StatusCode
diff --git a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.h b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.h
index 7b992d307..e4415b178 100644
--- a/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.h
+++ b/Simulation/DetSimAna/src/Edm4hepWriterAnaElemTool.h
@@ -6,6 +6,10 @@
 #include "GaudiKernel/AlgTool.h"
 #include "k4FWCore/DataHandle.h"
 #include "DetSimInterface/IAnaElemTool.h"
+#include "DetSimInterface/CommonUserEventInfo.hh"
+#include "DetSimInterface/CommonUserTrackInfo.hh"
+
+#include "DetInterface/IGeomSvc.h"
 
 #include "edm4hep/MCParticleCollection.h"
 #include "edm4hep/SimTrackerHitCollection.h"
@@ -42,10 +46,10 @@ class Edm4hepWriterAnaElemTool: public extends<AlgTool, IAnaElemTool> {
 private:
     // In order to associate MCParticle with contribution, we need to access MC Particle.
     // - collection MCParticle: the particles in Generator
-    DataHandle<edm4hep::MCParticleCollection> m_mcParGenCol{"MCParticle", 
+    DataHandle<edm4hep::MCParticleCollection> m_mcParGenCol{"MCParticleGen", 
             Gaudi::DataHandle::Writer, this};
     // - collection MCParticleG4: the simulated particles in Geant4
-    DataHandle<edm4hep::MCParticleCollection> m_mcParCol{"MCParticleG4", 
+    DataHandle<edm4hep::MCParticleCollection> m_mcParCol{"MCParticle", 
             Gaudi::DataHandle::Writer, this};
     edm4hep::MCParticleCollection* mcCol;
 
@@ -140,6 +144,14 @@ class Edm4hepWriterAnaElemTool: public extends<AlgTool, IAnaElemTool> {
 
     std::map<int, int> m_track2primary;
 
+    CommonUserEventInfo* m_userinfo = nullptr;
+
+    // get the limitation of R/Z in tracker
+    SmartIF<IGeomSvc> m_geosvc;
+    double R = 0;
+    double Z = 0;
+
+    bool verboseOutput = false;
 };
 
 #endif
diff --git a/Simulation/DetSimAna/src/ExampleAnaElemTool.cpp b/Simulation/DetSimAna/src/ExampleAnaElemTool.cpp
index d912414d4..1e11da48b 100644
--- a/Simulation/DetSimAna/src/ExampleAnaElemTool.cpp
+++ b/Simulation/DetSimAna/src/ExampleAnaElemTool.cpp
@@ -9,7 +9,7 @@
 #include "DDG4/Geant4Mapping.h"
 #include "DDG4/Geant4HitCollection.h"
 #include "DDG4/Geant4Data.h"
-#include "DDG4/Geant4Hits.h"
+#include "DetSimSD/Geant4Hits.h"
 
 DECLARE_COMPONENT(ExampleAnaElemTool)
 
diff --git a/Simulation/DetSimInterface/CMakeLists.txt b/Simulation/DetSimInterface/CMakeLists.txt
index ed99eead6..21963df1a 100644
--- a/Simulation/DetSimInterface/CMakeLists.txt
+++ b/Simulation/DetSimInterface/CMakeLists.txt
@@ -4,7 +4,10 @@
 
 gaudi_add_library(DetSimInterface
                  SOURCES src/IDetSimSvc.cpp
+                         src/CommonUserEventInfo.cc
+                         src/CommonUserTrackInfo.cc
                  LINK Gaudi::GaudiKernel
+                      ${Geant4_LIBRARIES}
 )
 
 install(TARGETS DetSimInterface
diff --git a/Simulation/DetSimInterface/include/DetSimInterface/CommonUserEventInfo.hh b/Simulation/DetSimInterface/include/DetSimInterface/CommonUserEventInfo.hh
new file mode 100644
index 000000000..3319598a2
--- /dev/null
+++ b/Simulation/DetSimInterface/include/DetSimInterface/CommonUserEventInfo.hh
@@ -0,0 +1,39 @@
+#ifndef CommonUserEventInfo_hh
+#define CommonUserEventInfo_hh
+
+/*
+ * Description:
+ *   This class is a part of simulation framework to allow users to extend the G4Event.
+ *
+ *   For example, when G4 converts the EDM4hep/G4 primary vertex/particle to G4 track, 
+ *   the relationship between the EDM4hep track and G4 track is missing. 
+ *   So a map is used as a bookkeeping.
+ *
+ * Author:
+ *   Tao Lin <lintao AT ihep.ac.cn>
+ */
+
+#include "G4VUserEventInformation.hh"
+#include <map>
+
+class CommonUserEventInfo: public G4VUserEventInformation {
+public:
+
+    CommonUserEventInfo();
+    virtual ~CommonUserEventInfo();
+
+public:
+    virtual void Print() const;
+
+    // set the relationship between idx in geant4 and idx in mc particle collection.
+    // idxG4: G4 track ID (starts from 1)
+    // idxEdm4hep: index in MC Particle collection (starts from 0)
+    bool setIdxG4Track2Edm4hep(int idxG4, int idxEdm4hep);
+    int idxG4Track2Edm4hep(int idxG4) const;
+    void dumpIdxG4Track2Edm4hep() const;
+
+private:
+    std::map<int, int> m_g4track_to_edm4hep;
+};
+
+#endif
diff --git a/Simulation/DetSimInterface/include/DetSimInterface/CommonUserTrackInfo.hh b/Simulation/DetSimInterface/include/DetSimInterface/CommonUserTrackInfo.hh
new file mode 100644
index 000000000..ce63e602d
--- /dev/null
+++ b/Simulation/DetSimInterface/include/DetSimInterface/CommonUserTrackInfo.hh
@@ -0,0 +1,35 @@
+#ifndef CommonUserTrackInfo_hh
+#define CommonUserTrackInfo_hh
+
+/* Description:
+ *   This class is a part of simulation framework to extend the G4Track.
+ *
+ *   Some secondaries are created due to decay. However, their G4 Track IDs are
+ *   not valid until the tracks are tracking by geant4. In order to associate
+ *   these tracks and their edm4hep MC particle, we use the track information
+ *   to record the extra track information.
+ *
+ * Author:
+ *   Tao Lin <lintao AT ihep.ac.cn>
+ */
+
+#include "G4VUserTrackInformation.hh"
+
+class CommonUserTrackInfo: public G4VUserTrackInformation {
+public:
+    CommonUserTrackInfo();
+    ~CommonUserTrackInfo();
+
+public:
+
+    virtual void Print() const;
+
+    // get the idx in the EDM4hep MC particle collection
+    bool setIdxEdm4hep(int idxEdm4hep);
+    int idxEdm4hep() const;
+
+private:
+    int m_idxEdm4hep = -1;
+};
+
+#endif
diff --git a/Simulation/DetSimInterface/include/DetSimInterface/IDedxSimTool.h b/Simulation/DetSimInterface/include/DetSimInterface/IDedxSimTool.h
index 8c804500a..4da01d532 100644
--- a/Simulation/DetSimInterface/include/DetSimInterface/IDedxSimTool.h
+++ b/Simulation/DetSimInterface/include/DetSimInterface/IDedxSimTool.h
@@ -28,6 +28,7 @@ class IDedxSimTool: virtual public IAlgTool {
     virtual double dedx(const G4Step* aStep) = 0;
     virtual double dedx(const edm4hep::MCParticle& mc) = 0;
     virtual double dndx(double betagamma) = 0;
+    virtual void endOfEvent() {}
 
 };
 
diff --git a/Simulation/DetSimInterface/src/CommonUserEventInfo.cc b/Simulation/DetSimInterface/src/CommonUserEventInfo.cc
new file mode 100644
index 000000000..7992c69c8
--- /dev/null
+++ b/Simulation/DetSimInterface/src/CommonUserEventInfo.cc
@@ -0,0 +1,53 @@
+#include "DetSimInterface/CommonUserEventInfo.hh"
+#include <iostream>
+
+CommonUserEventInfo::CommonUserEventInfo() {
+
+}
+
+CommonUserEventInfo::~CommonUserEventInfo() {
+
+}
+
+void
+CommonUserEventInfo::Print() const {
+
+}
+
+bool
+CommonUserEventInfo::setIdxG4Track2Edm4hep(int idxG4, int idxEdm4hep) {
+    auto it = m_g4track_to_edm4hep.find(idxG4);
+
+    // if already exists, return false
+    if (it != m_g4track_to_edm4hep.end()) {
+        return false;
+    }
+
+    m_g4track_to_edm4hep[idxG4] = idxEdm4hep;
+
+    return true;
+}
+
+int
+CommonUserEventInfo::idxG4Track2Edm4hep(int idxG4) const {
+    int ret = -1;
+
+    auto it = m_g4track_to_edm4hep.find(idxG4);
+
+    // if found
+    if (it != m_g4track_to_edm4hep.end()) {
+        ret = it->second;
+    }
+
+    return ret;
+}
+
+void
+CommonUserEventInfo::dumpIdxG4Track2Edm4hep() const {
+    std::cout << "---- Dumping IdxG4Track2Edm4hep: "
+              << " total size: " << m_g4track_to_edm4hep.size()
+              << std::endl;
+    for (auto [idxG4, idxE4]: m_g4track_to_edm4hep) {
+        std::cout << " - " << idxG4 << " -> " << idxE4 << std::endl;
+    }
+}
diff --git a/Simulation/DetSimInterface/src/CommonUserTrackInfo.cc b/Simulation/DetSimInterface/src/CommonUserTrackInfo.cc
new file mode 100644
index 000000000..9a923a35a
--- /dev/null
+++ b/Simulation/DetSimInterface/src/CommonUserTrackInfo.cc
@@ -0,0 +1,22 @@
+#include "DetSimInterface/CommonUserTrackInfo.hh"
+#include <iostream>
+
+CommonUserTrackInfo::CommonUserTrackInfo() {
+
+}
+
+CommonUserTrackInfo::~CommonUserTrackInfo() {
+
+}
+
+void CommonUserTrackInfo::Print() const {
+
+}
+
+bool CommonUserTrackInfo::setIdxEdm4hep(int idxEdm4hep) {
+    m_idxEdm4hep = idxEdm4hep;
+}
+
+int CommonUserTrackInfo::idxEdm4hep() const {
+    return m_idxEdm4hep;
+}
diff --git a/Simulation/DetSimSD/CMakeLists.txt b/Simulation/DetSimSD/CMakeLists.txt
index fa8ba9ef3..f3a9618ac 100644
--- a/Simulation/DetSimSD/CMakeLists.txt
+++ b/Simulation/DetSimSD/CMakeLists.txt
@@ -2,20 +2,34 @@
 find_package(Geant4 REQUIRED ui_all vis_all)
 include(${Geant4_USE_FILE})
 
+gaudi_add_library(DetSimSDLib
+                  SOURCES src/Geant4Hits.cpp
+                          src/DDG4SensitiveDetector.cpp
+                          src/CaloSensitiveDetector.cpp
+                          src/DriftChamberSensitiveDetector.cpp
+                          src/TimeProjectionChamberSensitiveDetector.cpp
+                          src/GenericTrackerSensitiveDetector.cpp
+                          src/TrackerCombineSensitiveDetector.cpp
+                  LINK DetSimInterface
+                       DetInterface
+                       ${DD4hep_COMPONENT_LIBRARIES}
+)
+target_include_directories(DetSimSDLib PUBLIC
+  $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>/include
+  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
+install(TARGETS DetSimSDLib
+  EXPORT CEPCSWTargets
+  RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT bin
+  LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT shlib
+  COMPONENT dev)
+
 gaudi_add_module(DetSimSD 
                  SOURCES src/CalorimeterSensDetTool.cpp
-                         src/DDG4SensitiveDetector.cpp
-                         src/CaloSensitiveDetector.cpp
-
                          src/DriftChamberSensDetTool.cpp
-                         src/DriftChamberSensitiveDetector.cpp
-
                          src/TimeProjectionChamberSensDetTool.cpp
-                         src/TimeProjectionChamberSensitiveDetector.cpp
-
                          src/GenericTrackerSensDetTool.cpp
-                         src/GenericTrackerSensitiveDetector.cpp
                  LINK DetSimInterface
+                      DetSimSDLib
                       DetInterface
                       ${DD4hep_COMPONENT_LIBRARIES} 
                       Gaudi::GaudiKernel
diff --git a/Simulation/DetSimSD/include/DetSimSD/DDG4SensitiveDetector.h b/Simulation/DetSimSD/include/DetSimSD/DDG4SensitiveDetector.h
index 687771e34..c4a29eb39 100644
--- a/Simulation/DetSimSD/include/DetSimSD/DDG4SensitiveDetector.h
+++ b/Simulation/DetSimSD/include/DetSimSD/DDG4SensitiveDetector.h
@@ -15,7 +15,7 @@
 
 
 #include "DD4hep/Detector.h"
-#include "DDG4/Geant4Hits.h"
+#include "DetSimSD/Geant4Hits.h"
 
 #include "G4Step.hh"
 #include "G4HCofThisEvent.hh"
diff --git a/Simulation/DetSimSD/include/DetSimSD/Geant4Hits.h b/Simulation/DetSimSD/include/DetSimSD/Geant4Hits.h
new file mode 100644
index 000000000..60fc18d47
--- /dev/null
+++ b/Simulation/DetSimSD/include/DetSimSD/Geant4Hits.h
@@ -0,0 +1,201 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+#ifndef DDG4_GEANT4HITS_H
+#define DDG4_GEANT4HITS_H
+
+// Framework include files
+#include "DD4hep/Objects.h"
+#include "DDG4/Geant4StepHandler.h"
+
+// Geant4 include files
+#include "G4VHit.hh"
+#include "G4Step.hh"
+#include "G4StepPoint.hh"
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
+  namespace sim {
+
+    // Forward declarations;
+    class Geant4Hit;
+    class Geant4TrackerHit;
+    class Geant4CalorimeterHit;
+
+    /// Deprecated:  Base class for hit comparisons.
+    /** @class HitCompare Geant4Hits.h DDG4/Geant4Hits.h
+     *
+     * @author  M.Frank
+     * @version 1.0
+     */
+    template <class HIT> class HitCompare {
+    public:
+      /// Default destructor
+      virtual ~HitCompare() {}
+      /// Comparison function
+      virtual bool operator()(const HIT* h) const = 0;
+    };
+
+    /// Deprecated: Seek the hits of an arbitrary collection for the same position.
+    /** @class HitPositionCompare Geant4Hits.h DDG4/Geant4Hits.h
+     *
+     * @author  M.Frank
+     * @version 1.0
+     */
+    template <class HIT> struct HitPositionCompare: public HitCompare<HIT> {
+      /// Reference to the hit position
+      const Position& pos;
+      /// Constructor
+      HitPositionCompare(const Position& p) : pos(p) {}
+      /// Default destructor
+      virtual ~HitPositionCompare() {}
+      /// Comparison function
+      virtual bool operator()(const HIT* h) const {
+        return pos == h->position;
+      }
+    };
+
+    /// Deprecated: basic geant4 hit class for deprecated sensitive detectors
+    /** @class Geant4Hit Geant4Hits.h DDG4/Geant4Hits.h
+     *
+     * Geant4 hit base class. Here only the basic
+     * quantites are stored such as the energy deposit and
+     * the time stamp.
+     *
+     * @author  M.Frank
+     * @version 1.0
+     */
+    class Geant4Hit: public G4VHit {
+    public:
+
+      // cellID
+      unsigned long cellID = 0;
+
+      /// Deprecated!!!
+      struct MonteCarloContrib {
+        /// Geant 4 Track identifier
+        int trackID = -1;
+        /// Particle ID from the PDG table
+        int pdgID = -1;
+        /// Total energy deposit in this hit
+        double deposit = 0.0;
+        /// Timestamp when this energy was deposited
+        double time = 0.0;
+        /// Default constructor
+        MonteCarloContrib() = default;
+        /// Copy constructor
+        MonteCarloContrib(const MonteCarloContrib& c) = default;
+        /// Initializing constructor
+        MonteCarloContrib(int track_id, double dep, double time_stamp)
+          : trackID(track_id), pdgID(-1), deposit(dep), time(time_stamp) {}
+        /// Initializing constructor
+        MonteCarloContrib(int track_id, int pdg, double dep, double time_stamp)
+          : trackID(track_id), pdgID(pdg), deposit(dep), time(time_stamp) {}
+        /// Assignment operator
+        MonteCarloContrib& operator=(const MonteCarloContrib& c) = default;
+        /// Clear data
+        void clear() {
+          time = deposit = 0.0;
+          pdgID = trackID = -1;
+        }
+      };
+      typedef MonteCarloContrib Contribution;
+      typedef std::vector<MonteCarloContrib> Contributions;
+
+    public:
+      /// Standard constructor
+      Geant4Hit() = default;
+      /// Default destructor
+      virtual ~Geant4Hit() { }
+      /// Check if the Geant4 track is a Geantino
+      static bool isGeantino(G4Track* track);
+      /// Extract the MC contribution for a given hit from the step information
+      static Contribution extractContribution(G4Step* step);
+    };
+
+    /// Deprecated: Geant4 tracker hit class for deprecated sensitive detectors
+    /** @class Geant4TrackerHit Geant4Hits.h DDG4/Geant4Hits.h
+     *
+     * Geant4 tracker hit class. Tracker hits contain the momentum
+     * direction as well as the hit position.
+     *
+     * @author  M.Frank
+     * @version 1.0
+     */
+    class Geant4TrackerHit: public Geant4Hit {
+    public:
+      /// Hit position
+      Position position;
+      /// Hit direction
+      Direction momentum;
+      /// Length of the track segment contributing to this hit
+      double length;
+      /// Monte Carlo / Geant4 information
+      Contribution truth;
+      /// Energy deposit of the hit
+      double energyDeposit;
+
+    public:
+      /// Default constructor
+      Geant4TrackerHit();
+      /// Standard initializing constructor
+      Geant4TrackerHit(int track_id, int pdg_id, double deposit, double time_stamp);
+      /// Default destructor
+      virtual ~Geant4TrackerHit() {}
+      /// Clear hit content
+      Geant4TrackerHit& clear();
+      /// Store Geant4 point and step information into tracker hit structure.
+      Geant4TrackerHit& storePoint(G4Step* step, G4StepPoint* point);
+
+      /// Assignment operator
+      Geant4TrackerHit& operator=(const Geant4TrackerHit& c);
+      /// Geant4 required object allocator
+      void *operator new(size_t);
+      /// Geat4 required object destroyer
+      void operator delete(void *ptr);
+    };
+
+    /// Deprecated: Geant4 calorimeter hit class for deprecated sensitive detectors
+    /** @class Geant4CalorimeterHit Geant4Hits.h DDG4/Geant4Hits.h
+     *
+     * Geant4 calorimeter hit class. Calorimeter hits contain the momentum
+     * direction as well as the hit position.
+     *
+     * @author  M.Frank
+     * @version 1.0
+     */
+    class Geant4CalorimeterHit: public Geant4Hit {
+    public:
+      /// Hit position
+      Position position;
+      /// Hit contributions by individual particles
+      Contributions truth;
+      /// Total energy deposit
+      double energyDeposit;
+    public:
+      /// Standard constructor
+      Geant4CalorimeterHit(const Position& cell_pos);
+      /// Default destructor
+      virtual ~Geant4CalorimeterHit() { }
+      /// Geant4 required object allocator
+      void *operator new(size_t);
+      /// Geat4 required object destroyer
+      void operator delete(void *ptr);
+    };
+
+  }    // End namespace sim
+}      // End namespace dd4hep
+
+#endif // DDG4_GEANT4HITS_H
diff --git a/Simulation/DetSimSD/src/DDG4SensitiveDetector.cpp b/Simulation/DetSimSD/src/DDG4SensitiveDetector.cpp
index a1698ee3c..3d16e02be 100644
--- a/Simulation/DetSimSD/src/DDG4SensitiveDetector.cpp
+++ b/Simulation/DetSimSD/src/DDG4SensitiveDetector.cpp
@@ -1,7 +1,6 @@
 #include "DetSimSD/DDG4SensitiveDetector.h"
 
 #include "DDG4/Geant4Converter.h"
-#include "DDG4/Geant4Hits.h"
 #include "DD4hep/Segmentations.h"
 
 #include "DD4hep/Printout.h"
diff --git a/Simulation/DetSimSD/src/DriftChamberSensDetTool.cpp b/Simulation/DetSimSD/src/DriftChamberSensDetTool.cpp
index 43dfa1782..58c49d6c6 100644
--- a/Simulation/DetSimSD/src/DriftChamberSensDetTool.cpp
+++ b/Simulation/DetSimSD/src/DriftChamberSensDetTool.cpp
@@ -5,7 +5,7 @@
 #include "DD4hep/Detector.h"
 
 #include "DriftChamberSensitiveDetector.h"
-
+#include "TrackerCombineSensitiveDetector.h"
 DECLARE_COMPONENT(DriftChamberSensDetTool)
 
 StatusCode DriftChamberSensDetTool::initialize() {
@@ -22,7 +22,6 @@ StatusCode DriftChamberSensDetTool::initialize() {
         error() << "Failed to find dedx simtoo." << endmsg;
         return StatusCode::FAILURE;
     }
-
     return sc;
 }
 
@@ -39,12 +38,19 @@ DriftChamberSensDetTool::createSD(const std::string& name) {
     G4VSensitiveDetector* sd = nullptr;
 
     if (name == "DriftChamber") {
-        DriftChamberSensitiveDetector* dcsd = new DriftChamberSensitiveDetector(name, *dd4hep_geo);
-        dcsd->setDedxSimTool(m_dedx_simtool);
-
-        sd = dcsd;
+      auto sens = dd4hep_geo->sensitiveDetector(name);
+      if(!sens.combineHits()){
+	DriftChamberSensitiveDetector* dcsd = new DriftChamberSensitiveDetector(name, *dd4hep_geo);
+	dcsd->setDedxSimTool(m_dedx_simtool);
+	sd = dcsd;
+      }
+      else{
+	sd = new TrackerCombineSensitiveDetector(name, *dd4hep_geo);
+      }
+    }
+    else{
+      warning() << "The SD " << name << " want to use SD for DriftChamber" << endmsg;
     }
-
 
     return sd;
 }
diff --git a/Simulation/DetSimSD/src/DriftChamberSensitiveDetector.cpp b/Simulation/DetSimSD/src/DriftChamberSensitiveDetector.cpp
index c6ff3db08..44bf01d10 100644
--- a/Simulation/DetSimSD/src/DriftChamberSensitiveDetector.cpp
+++ b/Simulation/DetSimSD/src/DriftChamberSensitiveDetector.cpp
@@ -71,5 +71,5 @@ DriftChamberSensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory*) {
 
 void
 DriftChamberSensitiveDetector::EndOfEvent(G4HCofThisEvent* HCE) {
-
+    m_dedx_simtool->endOfEvent();
 }
diff --git a/Simulation/DetSimSD/src/Geant4Hits.cpp b/Simulation/DetSimSD/src/Geant4Hits.cpp
new file mode 100644
index 000000000..0358bf019
--- /dev/null
+++ b/Simulation/DetSimSD/src/Geant4Hits.cpp
@@ -0,0 +1,135 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include "DetSimSD/Geant4Hits.h"
+
+// Geant4 include files
+#include "G4Allocator.hh"
+#include "G4ParticleDefinition.hh"
+#include "G4ChargedGeantino.hh"
+#include "G4OpticalPhoton.hh"
+#include "G4Geantino.hh"
+
+// C/C++ include files
+#include <iostream>
+
+using namespace std;
+using namespace dd4hep::sim;
+
+G4ThreadLocal G4Allocator<Geant4TrackerHit>* TrackerHitAllocator = 0;
+G4ThreadLocal G4Allocator<Geant4CalorimeterHit>* CalorimeterHitAllocator = 0;
+
+
+/// Check if the Geant4 track is a Geantino
+bool Geant4Hit::isGeantino(G4Track* track) {
+  if (track) {
+    G4ParticleDefinition* def = track->GetDefinition();
+    if (def == G4ChargedGeantino::Definition())
+      return true;
+    if (def == G4Geantino::Definition()) {
+      return true;
+    }
+  }
+  return false;
+}
+
+Geant4Hit::Contribution Geant4Hit::extractContribution(G4Step* step) {
+  G4Track* trk = step->GetTrack();
+  double energy_deposit =
+    (trk->GetDefinition() == G4OpticalPhoton::OpticalPhotonDefinition()) ?
+    trk->GetTotalEnergy() : step->GetTotalEnergyDeposit();
+  Contribution contrib(trk->GetTrackID(), trk->GetDefinition()->GetPDGEncoding(), energy_deposit, trk->GetGlobalTime());
+  return contrib;
+}
+
+/// Default constructor
+Geant4TrackerHit::Geant4TrackerHit()
+  : Geant4Hit(), position(), momentum(), length(0.0), truth(), energyDeposit(0.0) {
+}
+
+/// Standard initializing constructor
+Geant4TrackerHit::Geant4TrackerHit(int track_id, int pdg_id, double deposit, double time_stamp)
+  : Geant4Hit(), position(), momentum(), length(0.0), truth(track_id, pdg_id, deposit, time_stamp), energyDeposit(deposit) {
+}
+
+/// Assignment operator
+Geant4TrackerHit& Geant4TrackerHit::operator=(const Geant4TrackerHit& c) {
+  if ( this != &c )  {
+    position = c.position;
+    momentum = c.momentum;
+    length = c.length;
+    truth = c.truth;
+    energyDeposit = c.energyDeposit;
+  }
+  return *this;
+}
+
+/// Clear hit content
+Geant4TrackerHit& Geant4TrackerHit::clear() {
+  position.SetXYZ(0, 0, 0);
+  momentum.SetXYZ(0, 0, 0);
+  length = 0.0;
+  truth.clear();
+  energyDeposit = 0.0;
+  return *this;
+}
+
+/// Store Geant4 point and step information into tracker hit structure.
+Geant4TrackerHit& Geant4TrackerHit::storePoint(G4Step* step, G4StepPoint* pnt) {
+  G4Track* trk = step->GetTrack();
+  G4ThreeVector pos = pnt->GetPosition();
+  G4ThreeVector mom = pnt->GetMomentum();
+
+  truth.trackID = trk->GetTrackID();
+  truth.pdgID = trk->GetDefinition()->GetPDGEncoding();
+  truth.deposit = step->GetTotalEnergyDeposit();
+  truth.time = trk->GetGlobalTime();
+  energyDeposit = step->GetTotalEnergyDeposit();
+  position.SetXYZ(pos.x(), pos.y(), pos.z());
+  momentum.SetXYZ(mom.x(), mom.y(), mom.z());
+  length = 0;
+  return *this;
+}
+
+/// Geant4 required object allocator
+void* Geant4TrackerHit::operator new(size_t) {
+  if ( TrackerHitAllocator )
+    return TrackerHitAllocator->MallocSingle();
+  TrackerHitAllocator = new G4Allocator<Geant4TrackerHit>;
+  return TrackerHitAllocator->MallocSingle();
+}
+
+/// Geat4 required object destroyer
+void Geant4TrackerHit::operator delete(void *p) {
+  TrackerHitAllocator->FreeSingle((Geant4TrackerHit*) p);
+}
+
+/// Standard constructor
+Geant4CalorimeterHit::Geant4CalorimeterHit(const Position& pos)
+  : Geant4Hit(), position(pos), truth(), energyDeposit(0) {
+}
+
+/// Geant4 required object allocator
+void* Geant4CalorimeterHit::operator new(size_t) {
+  if ( CalorimeterHitAllocator )
+    return CalorimeterHitAllocator->MallocSingle();
+  CalorimeterHitAllocator = new G4Allocator<Geant4CalorimeterHit>;
+  return CalorimeterHitAllocator->MallocSingle();
+}
+
+/// Geat4 required object destroyer
+void Geant4CalorimeterHit::operator delete(void *p) {
+  CalorimeterHitAllocator->FreeSingle((Geant4CalorimeterHit*) p);
+}
+
diff --git a/Simulation/DetSimSD/src/GenericTrackerSensDetTool.cpp b/Simulation/DetSimSD/src/GenericTrackerSensDetTool.cpp
index 480f509aa..edb275a8d 100644
--- a/Simulation/DetSimSD/src/GenericTrackerSensDetTool.cpp
+++ b/Simulation/DetSimSD/src/GenericTrackerSensDetTool.cpp
@@ -5,6 +5,7 @@
 #include "DD4hep/Detector.h"
 
 #include "GenericTrackerSensitiveDetector.h"
+#include "TrackerCombineSensitiveDetector.h"
 
 #include "CLHEP/Units/SystemOfUnits.h"
 
@@ -33,8 +34,14 @@ G4VSensitiveDetector* GenericTrackerSensDetTool::createSD(const std::string& nam
   debug() << "createSD for " << name << endmsg;
   
   dd4hep::Detector* dd4hep_geo = m_geosvc->lcdd();
-
-  G4VSensitiveDetector* sd = new GenericTrackerSensitiveDetector(name, *dd4hep_geo);
+  auto sens = dd4hep_geo->sensitiveDetector(name);
+  G4VSensitiveDetector* sd = nullptr;
+  if(sens.combineHits()){
+    sd = new TrackerCombineSensitiveDetector(name, *dd4hep_geo);
+  }
+  else{
+    sd = new GenericTrackerSensitiveDetector(name, *dd4hep_geo);
+  }
 
   return sd;
 }
diff --git a/Simulation/DetSimSD/src/GenericTrackerSensitiveDetector.cpp b/Simulation/DetSimSD/src/GenericTrackerSensitiveDetector.cpp
index d250079ef..5e9ba1a6a 100644
--- a/Simulation/DetSimSD/src/GenericTrackerSensitiveDetector.cpp
+++ b/Simulation/DetSimSD/src/GenericTrackerSensitiveDetector.cpp
@@ -23,10 +23,11 @@ void GenericTrackerSensitiveDetector::Initialize(G4HCofThisEvent* HCE){
 }
 
 G4bool GenericTrackerSensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory*){
-  
   G4TouchableHandle touchPost = step->GetPostStepPoint()->GetTouchableHandle(); 
   G4TouchableHandle touchPre  = step->GetPreStepPoint()->GetTouchableHandle(); 
   dd4hep::sim::Geant4StepHandler h(step);
+  if (fabs(h.trackDef()->GetPDGCharge()) < 0.01) return true;
+
   dd4hep::Position prePos    = h.prePos();
   dd4hep::Position postPos   = h.postPos();
   dd4hep::Position direction = postPos - prePos;
diff --git a/Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.cpp b/Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.cpp
new file mode 100644
index 000000000..591c3cf32
--- /dev/null
+++ b/Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.cpp
@@ -0,0 +1,58 @@
+#include "TrackerCombineSensitiveDetector.h"
+
+#include "G4Step.hh"
+#include "G4VProcess.hh"
+#include "G4SDManager.hh"
+#include "DD4hep/DD4hepUnits.h"
+
+TrackerCombineSensitiveDetector::TrackerCombineSensitiveDetector(const std::string& name,
+								 dd4hep::Detector& description)
+  : DDG4SensitiveDetector(name, description),
+    m_hc(nullptr){
+  G4String CollName = m_sensitive.hitsCollection();
+  collectionName.insert(CollName);
+}
+
+void TrackerCombineSensitiveDetector::Initialize(G4HCofThisEvent* HCE){
+  userData.e_cut = m_sensitive.energyCutoff();
+
+  m_hc = new HitCollection(GetName(), collectionName[0]);
+  int HCID = G4SDManager::GetSDMpointer()->GetCollectionID(m_hc);
+  HCE->AddHitsCollection( HCID, m_hc ); 
+}
+
+G4bool TrackerCombineSensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory*){
+  dd4hep::sim::Geant4StepHandler h(step);
+  if (fabs(h.trackDef()->GetPDGCharge()) < 0.01) return true;
+
+  bool return_code = false;
+  if ( userData.current == -1 ) userData.start(getCellID(step), step, h.pre);
+  else if ( !userData.track || userData.current != h.track->GetTrackID() ) {
+    return_code = userData.extractHit(m_hc) != 0;
+    userData.start(getCellID(step), step, h.pre);
+  }
+
+  // ....update .....
+  userData.update(step);
+
+  void *prePV = h.volume(h.pre), *postPV = h.volume(h.post);
+  if ( prePV != postPV ) {
+    return_code = userData.extractHit(m_hc) != 0;
+    void* postSD = h.sd(h.post);
+    if ( 0 != postSD )   {
+      void* preSD = h.sd(h.pre);
+      if ( preSD == postSD ) {
+	// fucd: getCellID(step) for preVolume not postVolume, so should start at next step 
+	//userData.start(getCellID(step), step, h.post);
+      }
+    }
+  }
+  else if ( userData.track->GetTrackStatus() == fStopAndKill ) {
+    return_code = userData.extractHit(m_hc) != 0;
+  }
+  return return_code;
+}
+
+void TrackerCombineSensitiveDetector::EndOfEvent(G4HCofThisEvent* HCE){
+  userData.clear();
+}
diff --git a/Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.h b/Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.h
new file mode 100644
index 000000000..cf0cb844e
--- /dev/null
+++ b/Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.h
@@ -0,0 +1,95 @@
+// *********************************************************
+//
+// $Id: TrackerCombineSensitiveDetector.hh,v 1.0 2022/03/27
+
+#ifndef TrackerCombineSensitiveDetector_h
+#define TrackerCombineSensitiveDetector_h
+
+#include "DetSimSD/DDG4SensitiveDetector.h"
+#include "DDG4/Defs.h"
+
+namespace dd4hep {
+  namespace sim {
+    struct TrackerCombine {
+      Geant4TrackerHit  pre;
+      Geant4TrackerHit  post;
+      G4Track*          track;
+      double            e_cut;
+      int               current;
+      long long int     cellID;
+      TrackerCombine() : pre(), post(), track(0), e_cut(0.0), current(-1), cellID(0)  {}
+      void start(long long int cell, G4Step* step, G4StepPoint* point)   {
+	pre.storePoint(step,point);
+	current = pre.truth.trackID;
+	track   = step->GetTrack();
+	cellID  = cell;
+	post    = pre;
+	//std::cout << "start: " << cellID << " " << pre.position << " current = " << current << std::endl;
+      }
+      void update(G4Step* step) {
+	post.storePoint(step,step->GetPostStepPoint());
+	pre.truth.deposit += post.truth.deposit;
+	//std::cout << "update: " << cellID << " " << post.position << " current = " << current << std::endl;
+      }
+      void clear()   {
+	pre.truth.clear();
+	current = -1;
+	track = 0;
+      }
+      Geant4TrackerHit* extractHit(DDG4SensitiveDetector::HitCollection* c) {
+	//std::cout << "create Geant4TrackerHit: " << cellID << " current = " << current << " track = " << track << " de = " << pre.truth.deposit << std::endl;  
+	if ( current == -1 || !track ) {
+	  return 0;
+	}
+	else if ( pre.truth.deposit <= e_cut && !Geant4Hit::isGeantino(track) ) {
+	  clear();
+	  return 0;
+	}
+	double rho1 = pre.position.Rho();
+	double rho2 = post.position.Rho();
+	double rho = 0.5*(rho1+rho2);
+	Position pos = 0.5 * (pre.position + post.position);
+	double z = pos.z();
+	double r = sqrt(rho*rho+z*z);
+	Position path = post.position - pre.position;
+	double angle_O_pre_post = acos(-pre.position.Unit().Dot(path.Unit()));
+	double angle_O_post_pre = acos(post.position.Unit().Dot(path.Unit()));
+	double angle_O_P_pre = asin(pre.position.R()*sin(angle_O_pre_post)/r);
+	if(angle_O_pre_post>dd4hep::halfpi||angle_O_post_pre>dd4hep::halfpi){
+	  bool backward = angle_O_post_pre>angle_O_pre_post;
+	  double angle_O_P_pre = backward ? dd4hep::pi - asin(pre.position.R()*sin(angle_O_pre_post)/r) : asin(pre.position.R()*sin(angle_O_pre_post)/r);
+	  double pre2P = r/sin(angle_O_pre_post)*sin(angle_O_pre_post+angle_O_P_pre);
+	  pos = pre.position + pre2P*path.Unit();
+	}
+	Momentum mom = 0.5 * (pre.momentum + post.momentum);
+	Geant4TrackerHit* hit = new Geant4TrackerHit(pre.truth.trackID,
+						     pre.truth.pdgID,
+						     pre.truth.deposit,
+						     pre.truth.time);
+	hit->cellID   = cellID;
+	hit->position = pos;
+	hit->momentum = mom;
+	hit->length   = path.R();;
+	clear();
+	c->insert(hit);
+	return hit;
+      }
+    };
+  }
+}
+
+class TrackerCombineSensitiveDetector: public DDG4SensitiveDetector {
+ public:
+  TrackerCombineSensitiveDetector(const std::string& name, dd4hep::Detector& description);
+  
+  void Initialize(G4HCofThisEvent* HCE);
+  G4bool ProcessHits(G4Step* step, G4TouchableHistory* history);
+  void EndOfEvent(G4HCofThisEvent* HCE);
+  
+ protected:
+  HitCollection* m_hc = nullptr;
+
+ private:
+  dd4hep::sim::TrackerCombine userData;
+};
+#endif
diff --git a/build.sh b/build.sh
index 337287fe0..5c7393d16 100755
--- a/build.sh
+++ b/build.sh
@@ -83,7 +83,12 @@ function run-cmake() {
 }
 
 function run-make() {
-    cmake --build .
+    local njobs=-j$(nproc)
+    cmake --build . $njobs
+}
+
+function run-install() {
+    cmake --install .
 }
 
 ##############################################################################
@@ -91,8 +96,8 @@ function run-make() {
 ##############################################################################
 
 # The current default platform
-lcg_platform=x86_64-centos7-gcc8-opt
-lcg_version=101.0.1
+lcg_platform=x86_64-centos7-gcc11-opt
+lcg_version=103.0.2
 
 bldtool=${CEPCSW_BLDTOOL} # make, ninja # set in env var
 
@@ -103,3 +108,5 @@ check-working-builddir || exit -1
 run-cmake || exit -1
 
 run-make || exit -1
+
+run-install || exit -1
diff --git a/setup.sh b/setup.sh
index a75d5f39d..3e09a68ff 100644
--- a/setup.sh
+++ b/setup.sh
@@ -9,6 +9,8 @@
 # Author: Tao Lin <lintao@ihep.ac.cn>
 ##############################################################################
 
+THISSCRITDIR=$(dirname $(readlink -e "${BASH_SOURCE[0]}" 2>/dev/null) 2>/dev/null) # Darwin readlink doesnt accept -e
+
 function info:() {
     echo "INFO: $*" 1>&2
 }
@@ -41,6 +43,25 @@ function setup-external() {
 
 }
 
+function setup-install-area() {
+    local installarea=$THISSCRITDIR/InstallArea
+    if [ ! -d "$installarea" ]; then
+        return
+    fi
+
+    export PATH=$installarea/bin:$PATH
+    export LD_LIBRARY_PATH=$installarea/lib:$LD_LIBRARY_PATH
+    export PYTHONPATH=$installarea/lib:$PYTHONPATH
+    export PYTHONPATH=$installarea/python:$PYTHONPATH
+    export ROOT_INCLUDE_PATH=$installarea/include:$ROOT_INCLUDE_PATH
+
+    local extrasetupscript=$installarea/setup.sh
+    if [ -f "$extrasetupscript" ]; then
+        source $extrasetupscript
+    fi
+
+    info: "Setup CEPCSW: $installarea"
+}
 
 ##############################################################################
 # Parse the command line options
@@ -49,8 +70,9 @@ function setup-external() {
 # CEPCSW_LCG_VERSION=${1}; shift
 
 if [ -z "$CEPCSW_LCG_VERSION" ]; then
-    CEPCSW_LCG_VERSION=101.0.1
+    CEPCSW_LCG_VERSION=103.0.2
 fi
 export CEPCSW_LCG_VERSION
 
 setup-external
+setup-install-area

From 220144f48026d8cdb241588900abd25a13240958 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Mon, 11 Mar 2024 19:39:18 +0800
Subject: [PATCH 21/27] Set the alpha of sense wire

---
 Detector/DetDriftChamber/compact/det.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Detector/DetDriftChamber/compact/det.xml b/Detector/DetDriftChamber/compact/det.xml
index ae3e2390d..22548148c 100644
--- a/Detector/DetDriftChamber/compact/det.xml
+++ b/Detector/DetDriftChamber/compact/det.xml
@@ -36,7 +36,7 @@
     <constant name="DC_rend" value="1800*mm"/>
 
     <constant name="DC_layer_number" value="55"/>
-    <constant name="Alpha" value="0*deg"/>
+    <constant name="Alpha" value="12*deg"/>
 
     <constant name="Gas_radius_min" value="DC_rbegin+DC_inner_wall_thickness+DC_safe_distance"/>
 

From 6bfda1af5ce5ef59387deed5806adb1cfd8af093 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Mon, 11 Mar 2024 19:54:55 +0800
Subject: [PATCH 22/27] Update DriftChamber construct

---
 Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp     | 3 ---
 .../DetSegmentation/include/DetSegmentation/GridDriftChamber.h | 2 --
 Detector/DetSegmentation/src/GridDriftChamber.cpp              | 1 -
 Digitisers/DCHDigi/src/DCHDigiAlg.cpp                          | 3 ---
 Digitisers/DCHDigi/src/DCHDigiAlg.h                            | 1 -
 5 files changed, 10 deletions(-)

diff --git a/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp b/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
index 67b36859b..634698ce1 100644
--- a/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
+++ b/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
@@ -171,7 +171,6 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
             offset = 0.5 * cell_phi;
         }
         double epsilon = sign_eps*std::atan(rmid_zZero * std::tan(alpha / 2.0) / chamber_half_length);
-        //double alpha0 = 2*std::asin(chamber_length * std::tan(epsilon)/(2*rmid_zEnd));
 
         segmentationDC->setGeomParams(chamber_id, layer_id, cell_phi, rmid_zEnd , epsilon, offset);
         segmentationDC->setWiresInLayer(chamber_id, layer_id, nCell);
@@ -241,8 +240,6 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
         }//end of loop over cell
         dd4hep::Transform3D transform_layer(dd4hep::Rotation3D(),
                 dd4hep::Position(0,0,0));
-        dd4hep::PlacedVolume layer_phy = det_chamber_vol.placeVolume(layer_vol,transform_layer);
-        layer_phy.addPhysVolID("layer", layer_id);
     }//end of loop over layers
 
 
diff --git a/Detector/DetSegmentation/include/DetSegmentation/GridDriftChamber.h b/Detector/DetSegmentation/include/DetSegmentation/GridDriftChamber.h
index 911a6f4cb..77e9bfa56 100644
--- a/Detector/DetSegmentation/include/DetSegmentation/GridDriftChamber.h
+++ b/Detector/DetSegmentation/include/DetSegmentation/GridDriftChamber.h
@@ -34,7 +34,6 @@ typedef struct CID
  {
    int chamberID;
    int layerID;
-//   CID(){}
    CID(int i, int j): chamberID(i),layerID(j){}
    // the operator < defines the operation used in map
    friend bool operator < (const CID &c1, const CID &c2);
@@ -176,7 +175,6 @@ class GridDriftChamber : public Segmentation {
  }
 
   double m_cellSize;
-//  double m_epsilon0;
   double m_detectorLength;
   double m_layer_width;
   double m_DC_rbegin;
diff --git a/Detector/DetSegmentation/src/GridDriftChamber.cpp b/Detector/DetSegmentation/src/GridDriftChamber.cpp
index b6cc05850..5c59f2006 100644
--- a/Detector/DetSegmentation/src/GridDriftChamber.cpp
+++ b/Detector/DetSegmentation/src/GridDriftChamber.cpp
@@ -329,6 +329,5 @@ double GridDriftChamber::Distance(const CellID& cID, const TVector3& pointIn, co
     return distance;
 }
 
-
 }
 }
diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
index 927c7b27d..21a840411 100644
--- a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
+++ b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp
@@ -167,9 +167,6 @@ StatusCode DCHDigiAlg::execute()
       TVector3 Wend  (0,0,0);
       m_segmentation->cellposition(wcellid, Wstart, Wend);
       float dd4hep_mm = dd4hep::mm;
-      //std::cout<<"dd4hep_mm="<<dd4hep_mm<<std::endl;
-      //    Wstart =(1/dd4hep_mm)* Wstart;// from DD4HEP cm to mm
-      //    Wend   =(1/dd4hep_mm)* Wend  ;
       if(m_debug) std::cout<<"DCHDigi wcellid ="<<wcellid<< ",chamber="<<chamber<<",layer="<<layer<<",cellID="<<cellID<<",s_x="<<Wstart.x()<<",s_y="<<Wstart.y()<<",s_z="<<Wstart.z()<<",E_x="<<Wend.x()<<",E_y="<<Wend.y()<<",E_z="<<Wend.z()<<std::endl;
 
       TVector3  denominator = (Wend-Wstart) ;
diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.h b/Digitisers/DCHDigi/src/DCHDigiAlg.h
index 6effe0a29..cc6a53127 100644
--- a/Digitisers/DCHDigi/src/DCHDigiAlg.h
+++ b/Digitisers/DCHDigi/src/DCHDigiAlg.h
@@ -96,7 +96,6 @@ class DCHDigiAlg : public GaudiAlgorithm
   Gaudi::Property<bool>  m_debug{ this, "debug", false};
   Gaudi::Property<double>  m_wireEff{ this, "wireEff", 1.0};
 
-
   // Input collections
   DataHandle<edm4hep::SimTrackerHitCollection> r_SimDCHCol{"DriftChamberHitsCollection", Gaudi::DataHandle::Reader, this};
   // Output collections

From 8f74aead3a5960ddc9ce7561ce777329046abebc Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Wed, 13 Mar 2024 12:08:35 +0800
Subject: [PATCH 23/27] Test CI

---
 Reconstruction/PFA/Arbor/src/MarlinArbor.cc | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 mode change 100755 => 100644 Reconstruction/PFA/Arbor/src/MarlinArbor.cc

diff --git a/Reconstruction/PFA/Arbor/src/MarlinArbor.cc b/Reconstruction/PFA/Arbor/src/MarlinArbor.cc
old mode 100755
new mode 100644

From f1a023226b6b9852b3cd5f846d0ec11d3b6df081 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Wed, 13 Mar 2024 16:35:35 +0800
Subject: [PATCH 24/27] Update RecGenfitAlgSDT

---
 .../RecGenfitAlg/src/RecGenfitAlgSDT.cpp      | 42 +++++++------------
 .../RecGenfitAlg/src/RecGenfitAlgSDT.h        |  9 +++-
 2 files changed, 23 insertions(+), 28 deletions(-)

diff --git a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
index 8e015c943..f3a125509 100644
--- a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
+++ b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
@@ -91,6 +91,9 @@ DECLARE_COMPONENT( RecGenfitAlgSDT )
     declareProperty("SmearDCHitAssociationCollection", r_SmearAssociationCol,
             "Handle of output smear simulationhit and TrackerHit collection");
 
+    declareProperty("DCTrackFindingHitCollection", m_DCTrackFindingCol,
+            "Handle of output TrackFinding TrackerHit collection");
+
 }
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
@@ -100,14 +103,6 @@ StatusCode RecGenfitAlgSDT::initialize()
     MsgStream log(msgSvc(), name());
     info()<<" RecGenfitAlgSDT initialize()"<<endmsg;
 
-//    time_t timep;
-//    time(&timep);
-//    std::cout << "Myliu say: the time is "
-//              << ctime(&timep)
-//              << "at the begin of RecGenfitAlgSDT::initialize()"
-//              << std::endl;
-//    system("/scratchfs/bes/myliu/script/memory_rec.sh");
-
     m_eventNo=0;
 
     ///Get GeomSvc
@@ -130,8 +125,7 @@ StatusCode RecGenfitAlgSDT::initialize()
             m_skipWireMaterial);
     m_genfitFitter->setEnergyLossBrems(m_correctBremsstrahlung);
     m_genfitFitter->setNoiseBrems(m_correctBremsstrahlung);
-    //m_genfitFitter->setMultipleMeasurementHandling(
-            //genfit::eMultipleMeasurementHandling(m_multipleMeasurementHandling.value()));
+    //genfit::eMultipleMeasurementHandling(m_multipleMeasurementHandling.value()));
     if(m_debug>10) m_genfitFitter->setDebug(m_debug-10);
     if(m_noMaterialEffects) m_genfitFitter->setNoEffects(true);
     if(-1==m_debugPid) m_genfitFitter->setNoEffects(true);
@@ -233,7 +227,7 @@ StatusCode RecGenfitAlgSDT::initialize()
             sc=m_tuple->addItem("PocaMomZ",m_mcIndex,m_PocaMomZ);
 
             sc=m_tuple->addItem("PocaErrCov",m_mcIndex,m_PocaErrCov,6);
-            
+
             sc=m_tuple->addItem("ErrorcovMatrix",m_mcIndex,m_ErrorcovMatrix,15);
             sc=m_tuple->addItem("D0",m_mcIndex,m_D0);
             sc=m_tuple->addItem("phi",m_mcIndex,m_phi);
@@ -269,6 +263,7 @@ StatusCode RecGenfitAlgSDT::initialize()
             sc=m_tuple->addItem("nHitFailedKal",m_mcIndex,m_nHitFailedKal,5);
             sc=m_tuple->addItem("nHitFitted",m_mcIndex,m_nHitFitted,5);
             sc=m_tuple->addItem("nDCDigi",m_nDCDigi,0,50000);
+            sc=m_tuple->addItem("nTruthDCDigi",m_nTruthDCDigi,0,50000);
             sc=m_tuple->addItem("nHitKalInput",m_nHitKalInput,0,300000);
             //10 is greater than # of tracking detectors
             sc=m_tuple->addItem("hitDetID",10,m_nHitDetType);
@@ -329,7 +324,9 @@ StatusCode RecGenfitAlgSDT::initialize()
             sc=m_tuple->addItem("truthMomedep",m_nTrackerHitDC,m_truthMomEdep);
             sc=m_tuple->addItem("driftDis",m_nTrackerHitDC,m_driftDis);
             sc=m_tuple->addItem("FittedDoca",m_nTrackerHitDC,m_FittedDoca);
+            sc=m_tuple->addItem("truthDoca",m_nTrackerHitDC,m_truthDoca);
             sc=m_tuple->addItem("Res",m_nTrackerHitDC,m_Res);
+            sc=m_tuple->addItem("truthRes",m_nTrackerHitDC,m_truthRes);
             sc=m_tuple->addItem("nTrackerHitSDT",m_nTrackerHitSDT);
             sc=m_tuple->addItem("nGenFitTrackerHit",m_nGenFitTrackerHit);
             debug()<< "Book tuple RecGenfitAlgSDT/recGenfitAlgSDT" << endmsg;
@@ -340,12 +337,6 @@ StatusCode RecGenfitAlgSDT::initialize()
 
     //init genfit event display
     if(m_showDisplay) m_genfitDisplay = genfit::EventDisplay::getInstance();
-//    time(&timep);
-//    std::cout << "Myliu say: the time is "
-//              << ctime(&timep)
-//              << "at the end of RecGenfitAlgSDT::initialize()"
-//              << std::endl;
-//    system("/scratchfs/bes/myliu/script/memory_rec.sh");
 
     return StatusCode::SUCCESS;
 }
@@ -355,13 +346,6 @@ StatusCode RecGenfitAlgSDT::initialize()
 StatusCode RecGenfitAlgSDT::execute()
 {
     info()<<"RecGenfitAlgSDT in execute()"<<endmsg;
-//    time_t timep;
-//    time(&timep);
-//    std::cout << "Myliu say: the time is "
-//              << ctime(&timep)
-//              << "at the begin of RecGenfitAlgSDT::execute()"
-//              << std::endl;
-//    system("/scratchfs/bes/myliu/script/memory_rec.sh");
 
     edm4hep::ReconstructedParticleCollection* sdtRecParticleCol=
         m_SDTRecParticleCol.createAndPut();
@@ -427,7 +411,9 @@ StatusCode RecGenfitAlgSDT::execute()
     std::vector<float> truthMomEdep;
     std::vector<double> driftDis;
     std::vector<double> FittedDoca;
+    std::vector<double> truthDoca;
     std::vector<double> Res;
+    std::vector<double> truthRes;
     for(auto sdtTrack: *sdtTrackCol)
     {
         if(sdtTrack.trackerHits_size()<1e-9) continue;
@@ -538,7 +524,7 @@ StatusCode RecGenfitAlgSDT::execute()
                         pocaToOrigin_pos,pocaToOrigin_mom,pocaToOrigin_cov,
                         pidType,m_ndfCut,m_chi2Cut,nFittedDC,nFittedSDT,
                         ngenfitHit,trackL,hitMom,truthMomEdep,assoDCHitsCol,
-                        driftDis,FittedDoca,Res)){
+                        driftDis,FittedDoca,truthDoca,Res,truthRes)){
                 debug()<<"Fitting failed!"<<std::endl;
             }else{
                 ++m_fitSuccess[pidType];
@@ -570,7 +556,9 @@ StatusCode RecGenfitAlgSDT::execute()
         for(int i=0;i<truthMomEdep.size();i++) m_truthMomEdep[i] = truthMomEdep[i];
         for(int i=0;i<driftDis.size();i++) m_driftDis[i] = driftDis[i];
         for(int i=0;i<FittedDoca.size();i++) m_FittedDoca[i] = FittedDoca[i];
+        for(int i=0;i<truthDoca.size();i++) m_truthDoca[i] = truthDoca[i];
         for(int i=0;i<Res.size();i++) m_Res[i] = Res[i];
+        for(int i=0;i<truthRes.size();i++) m_truthRes[i] = truthRes[i];
         auto finish = std::chrono::high_resolution_clock::now();
         std::chrono::duration<double> elapsed = finish - start;
         debug() << "Elapsed time: " << elapsed.count() << " s"<<endmsg;
@@ -842,8 +830,8 @@ void RecGenfitAlgSDT::debugEvent(const edm4hep::TrackCollection* sdtTrackCol,
 
             double mcPos[3]={(mcPocaPos.x),(mcPocaPos.y),(mcPocaPos.z)};
             double mcMom[3]={(mcPocaMom.x),(mcPocaMom.y),(mcPocaMom.z)};
-            //for(int i=0;i<3;i++){debug()<<"mcPos "<<mcPos[i]<<endmsg;}
-            //for(int i=0;i<3;i++){debug()<<"mcMom "<<mcMom[i]<<endmsg;}
+            for(int i=0;i<3;i++){debug()<<"mcPos "<<mcPos[i]<<endmsg;}
+            for(int i=0;i<3;i++){debug()<<"mcMom "<<mcMom[i]<<endmsg;}
             float mcCharge = mcParticle.getCharge();
             helix_mcP.Initialize_VP(mcPos,mcMom,mcCharge,
                     m_genfitField->getBz(mcPos)/GenfitUnit::tesla);
diff --git a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.h b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.h
index 7387ea870..60fe9cf8b 100644
--- a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.h
+++ b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.h
@@ -43,12 +43,12 @@ namespace dd4hep {
 namespace edm4hep{
     class EventHeaderCollection;
     class MCParticleCollection;
+    class MutableReconstructedParticle;
     class SimTrackerHitCollection;
     class TrackCollection;
     class TrackerHitCollection;
     class MCRecoTrackerAssociationCollection;
     class ReconstructedParticle;
-    class MutableReconstructedParticle;
     class ReconstructedParticleCollection;
     class MutableReconstructedParticleCollection;
     class TrackerHit;
@@ -127,6 +127,10 @@ class RecGenfitAlgSDT:public GaudiAlgorithm {
         DataHandle<edm4hep::MCRecoTrackerAssociationCollection> r_NoiseAssociationCol{
             "NoiseDCHitAssociationCollection", Gaudi::DataHandle::Reader, this};
 
+        //Track Finding
+        DataHandle<edm4hep::TrackerHitCollection> m_DCTrackFindingCol{
+            "DCTrackFindingHitCollection",Gaudi::DataHandle::Reader, this};
+
         //Output hits and particles
         DataHandle<edm4hep::ReconstructedParticleCollection> m_SDTRecParticleCol{
             "SDTRecParticleCollection", Gaudi::DataHandle::Writer, this};
@@ -295,6 +299,7 @@ class RecGenfitAlgSDT:public GaudiAlgorithm {
         NTuple::Matrix<int> m_isFitted;
         NTuple::Matrix<int> m_fittedState;
         NTuple::Item<int> m_nDCDigi;
+        NTuple::Item<int> m_nTruthDCDigi;
         NTuple::Item<int> m_nHitMc;
         NTuple::Item<int> m_nSdtTrack;
         NTuple::Item<int> m_nSdtTrackHit;
@@ -365,8 +370,10 @@ class RecGenfitAlgSDT:public GaudiAlgorithm {
         NTuple::Array<double> m_hitMomEdep;
         NTuple::Array<float> m_truthMomEdep;
         NTuple::Array<float> m_FittedDoca;
+        NTuple::Array<float> m_truthDoca;
         NTuple::Array<float> m_driftDis;
         NTuple::Array<float> m_Res;
+        NTuple::Array<float> m_truthRes;
 
 };
 #endif

From cd085c384318b6e842e1b64cc4a3b3f237907555 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Wed, 13 Mar 2024 20:15:24 +0800
Subject: [PATCH 25/27] XML file for oblique geometry

---
 .../CRD_common_v01/DC_Simple_v01_05.xml       |   6 +-
 .../CRD_o1_v01/CRD_o1_v01-onlyTracker.xml     |   2 +-
 .../src/driftchamber/DriftChamber.cpp         |   2 +
 .../RecGenfitAlg/src/GenfitTrack.cpp          | 149 +-----------------
 Reconstruction/RecGenfitAlg/src/GenfitTrack.h |   4 -
 .../RecGenfitAlg/src/RecGenfitAlgSDT.cpp      |  92 +----------
 6 files changed, 9 insertions(+), 246 deletions(-)

diff --git a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_05.xml b/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_05.xml
index 6c05c4fa0..383019ecb 100644
--- a/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_05.xml
+++ b/Detector/DetCRD/compact/CRD_common_v01/DC_Simple_v01_05.xml
@@ -12,12 +12,12 @@
 
   <define>
 
-    <constant name="DC_layer_number" value="100"/>
+    <constant name="DC_layer_number" value="55"/>
     <constant name="Alpha" value="12*deg"/>
     <constant name="Gas_radius_min" value="DC_rbegin+DC_inner_wall_thickness+DC_safe_distance"/>
     <constant name="Gas_half_length" value="DC_half_length-DC_Endcap_dz-DC_safe_distance"/>
     <constant name="Gas_length" value="Gas_half_length*2"/>
-    <constant name="DC_cell_width" value="10*mm"/>
+    <constant name="DC_cell_width" value="18*mm"/>
     <constant name="DC_inner_wall_radius_min" value="DC_rbegin"/>
     <constant name="DC_inner_wall_radius_max" value="DC_rbegin+DC_inner_wall_thickness"/>
     <constant name="DC_Endcap_rmin" value="DC_rbegin"/>
@@ -25,7 +25,7 @@
 
     <constant name="DC_construct_wire" value="0"/>
 
-    <constant name="DC_layer_width" value="9.57687*mm"/>
+    <constant name="DC_layer_width" value="18*mm"/>
 
   </define>
 
diff --git a/Detector/DetCRD/compact/CRD_o1_v01/CRD_o1_v01-onlyTracker.xml b/Detector/DetCRD/compact/CRD_o1_v01/CRD_o1_v01-onlyTracker.xml
index 3ac63dc4b..d80301fb2 100644
--- a/Detector/DetCRD/compact/CRD_o1_v01/CRD_o1_v01-onlyTracker.xml
+++ b/Detector/DetCRD/compact/CRD_o1_v01/CRD_o1_v01-onlyTracker.xml
@@ -31,7 +31,7 @@
   <include ref="../CRD_common_v01/VXD_v01_01.xml"/>
   <include ref="../CRD_common_v01/FTD_SkewRing_v01_01.xml"/>
   <include ref="../CRD_common_v01/SIT_SimplePixel_v01_01.xml"/>
-  <include ref="../CRD_common_v01/DC_Simple_v01_04_noWire.xml"/>
+  <include ref="../CRD_common_v01/DC_Simple_v01_05.xml"/>
   <include ref="../CRD_common_v01/SET_SimplePixel_v01_01.xml"/>
   
   <fields>
diff --git a/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp b/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
index 634698ce1..ab80570fc 100644
--- a/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
+++ b/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
@@ -240,6 +240,8 @@ static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
         }//end of loop over cell
         dd4hep::Transform3D transform_layer(dd4hep::Rotation3D(),
                 dd4hep::Position(0,0,0));
+        dd4hep::PlacedVolume layer_phy = det_chamber_vol.placeVolume(layer_vol,transform_layer);
+        layer_phy.addPhysVolID("layer", layer_id);
     }//end of loop over layers
 
 
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp b/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp
index ccd4c72a9..19bb23c79 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp
+++ b/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp
@@ -68,27 +68,16 @@ const int GenfitTrack::s_PDG[2][5]
 
     bool
 sortDCSimHit(edm4hep::SimTrackerHit hit1,edm4hep::SimTrackerHit hit2)
-//sortDCSimHit(edm4hep::ConstSimTrackerHit hit1,edm4hep::ConstSimTrackerHit hit2)
 {
-    //std::cout<<"hit1"<<hit1<<std::endl;
-    //std::cout<<"hit2"<<hit2<<std::endl;
     bool isEarly=hit1.getTime()<hit2.getTime();
     return isEarly;
 }
     bool
 sortDCDigi(std::pair<double,edm4hep::TrackerHit*> hitPair1,std::pair<double,edm4hep::TrackerHit*> hitPair2)
-//sortDCDigi(std::pair<double,edm4hep::ConstTrackerHit*> hitPair1,std::pair<double,edm4hep::ConstTrackerHit*> hitPair2)
 {
     bool isEarly=hitPair1.first<hitPair2.first;
     return isEarly;
 }
-//bool sortDCDigiLayer(std::pair<int,edm4hep::TrackerHit> hitPair1,std::pair<int,edm4hep::TrackerHit> hitPair2)
-//bool sortDCDigiLayer(std::pair<int,edm4hep::ConstTrackerHit> hitPair1,std::pair<int,edm4hep::ConstTrackerHit> hitPair2)
-//{
-//    bool isEarly=hitPair1.first<hitPair2.first;
-//    return isEarly;
-//}
-
 
 GenfitTrack::GenfitTrack(const GenfitField* genfitField,
         const dd4hep::DDSegmentation::GridDriftChamber* seg,
@@ -164,7 +153,6 @@ bool GenfitTrack::createGenfitTrackFromEDM4HepTrack(int pidType,
 
     ///Skip track w.o. hit
     if(track.trackerHits_size()<=0) {
-        std::cout << " track.trackerHits_size = " << track.trackerHits_size() << std::endl;
         if(m_debug){
             std::cout<<"createGenfitTrackFromEDM4HepTrack skip track w/o hit"<<std::endl;
         }
@@ -269,23 +257,12 @@ GenfitTrack::getISurface(edm4hep::TrackerHit* hit){
     dd4hep::rec::ISurface* iSurface=nullptr;
     if(iter!=surfaceMap->end()){iSurface=(*iter).second;}
 
-    //std::multimap< unsigned long, dd4hep::rec::ISurface*>::const_iterator it,itend;
-    //it=surfaceMap->begin();
-    //itend= surfaceMap->end();
-    //std::cout<<" print map "<<detectorName<<std::endl;
-    //for(; it!=itend; it++){
-    //    dd4hep::rec::ISurface* surf = it->second;
-    //    dd4hep::rec::Vector3D origin = surf->origin();
-    //    std::cout <<"surf id "<< surf->id() << " origin xyz " << origin.x()
-    //        << " " << origin.y() << " " << origin.z() << std::endl;
-    //}
     return iSurface;
 }
 
 /// Add a 1d strip or 2d pixel smeared by sigma
     bool
 GenfitTrack::addSiliconMeasurement(edm4hep::TrackerHit* hit,
-//GenfitTrack::addSiliconMeasurement(edm4hep::ConstTrackerHit* hit,
         float sigmaU,float sigmaV,int cellID,int hitID)
 {
     if(m_debug>0) std::cout<<"addSiliconMeasurement "<<*hit<<std::endl;
@@ -326,8 +303,6 @@ GenfitTrack::addSiliconMeasurement(edm4hep::TrackerHit* hit,
     genfit::PlanarMeasurementSDT* planarMeasurement=new genfit::PlanarMeasurementSDT(
             hitCoords,hitCov,cellID,hitID,nullptr);
     planarMeasurement->setTrackerHit(hit);
-    //genfit::PlanarMeasurement* planarMeasurement=new genfit::PlanarMeasurement(
-    //        hitCoords,hitCov,cellID,hitID,nullptr);
     planarMeasurement->setPlane(plane);
     m_track->insertPoint(new genfit::TrackPoint(planarMeasurement,m_track));
 
@@ -416,9 +391,7 @@ int GenfitTrack::addWireMeasurementsFromList(std::vector<edm4hep::TrackerHit*>&
         int sortMethod, bool truthAmbig,float skipCorner,float skipNear)
 {
     if(m_debug>0){ std::cout<<"addWireMeasurementsFromList"<<std::endl; }
-    //podio::RelationRange<edm4hep::TrackerHit> hits_t=track.getTrackerHits();
     std::vector<edm4hep::TrackerHit*> sortedTrackerHits;
-    //    sortedTrackerHits.reserve(100);
     getSortedTrackerHits(hits,assoHits,sortedTrackerHits,sortMethod);
 
     if(m_debug>0){
@@ -593,7 +566,6 @@ void GenfitTrack::setDebugLocal(int debug){
 #ifdef GENFIT_MY_DEBUG
     if(m_track){
         for(unsigned int i=0;i<m_track->getNumReps();i++){
-            //m_track->getTrackRep(i)->setDebugLvlLocal(debug);
         }
     }
     m_debugLocal=debug;
@@ -611,10 +583,8 @@ void GenfitTrack::printSeed() const
     mom.Print();
     print(pos,mom);
     TMatrixDSym covSeed=m_track->getCovSeed();
-    //if(m_debug>1)
     std::cout << " covSeed = " << std::endl;
     covSeed.Print();
-    //std::cout<<" pdg "<<0<<getRep(0)<<std::endl;//FIXME
 }
 
 void GenfitTrack::printFitted(int repID) const
@@ -650,9 +620,6 @@ void GenfitTrack::print( TLorentzVector pos, TVector3 mom,
             m_track->getTrackRep(i)->Print();
         }
     }
-    //for(unsigned int i=0; i<m_track->getNumPoints(); i++){
-    //  m_track->getPoint(i)->print();
-    //}
 }
 
 /// Get position, momentum, cov on plane of hitID-th hit
@@ -761,7 +728,6 @@ double GenfitTrack::extrapolateToHit(TVector3& poca, TVector3& pocaDir,
     int chargeId;
     mcParticle.getCharge() >0 ? chargeId=0 : chargeId=1;//s_PDG[0]: positive particle
     genfit::RKTrackRep* rep = new genfit::RKTrackRep(s_PDG[chargeId][repID]);
-    //genfit::MeasuredStateOnPlane state(rep);
     genfit::StateOnPlane state(rep);
     rep->setPosMom(state, pos, mom);
 
@@ -803,35 +769,6 @@ double GenfitTrack::extrapolateToHit(TVector3& poca, TVector3& pocaDir,
     return extrapoLen/GenfitUnit::mm*dd4hep::mm;
 }//end of extrapolateToHit
 
-/////Add space point measurement from edm4hep::Track to genfit track
-//int GenfitTrack::addHitsOnEdm4HepTrack(const edm4hep::Track& track,
-//        const edm4hep::MCRecoTrackerAssociationCollection* assoHits,
-//        std::vector<float> sigma,bool smear,
-//        bool measurementTypeSi, bool measurementTypeDC){
-//    ///Get TrackerHit on Track
-//    int hitID=0;
-//    for(unsigned int iHit=0;iHit<track.trackerHits_size();iHit++){
-//        edm4hep::TrackerHit hit=track.getTrackerHits(iHit);
-//        ///Get hit type
-//        int detTypeID=getDetTypeID(hit.getCellID());
-//        if(m_debug>=2)std::cout<<"addHitsOnEdm4HepTrack "<<iHit<<" hit "<<hit
-//            <<" detTypeID "<<detTypeID<<" type "<<hit.getType()<<std::endl;
-//
-//        bool hitIsSpapcePoint=UTIL::BitSet32(hit.getType())[
-//                              UTIL::ILDTrkHitTypeBit::COMPOSITE_SPACEPOINT];
-//        bool hitIsPlanar=UTIL::BitSet32(hit.getType())[
-//                         UTIL::ILDTrkHitTypeBit::ONE_DIMENSIONAL];
-//        if(m_debug>2){
-//            std::cout<<detTypeID<<" COMPOSITE_SPACEPOINT "<<hitIsSpapcePoint
-//                <<std::endl;
-//            std::cout<<detTypeID<<" ONE_DIMENSIONAL "<<hitIsPlanar<<std::endl;
-//        }
-//
-//    }
-//
-//    return 1;
-//}
-
 ///Add space point measurement of silicon from edm4hep::Track to genfit track
 int GenfitTrack::addSpacePointsSi(const edm4hep::Track& track,
         std::vector<float> sigmaU,std::vector<float> sigmaV)
@@ -844,8 +781,6 @@ int GenfitTrack::addSpacePointsSi(const edm4hep::Track& track,
         edm4hep::TrackerHit hit=track.getTrackerHits(iHit);
         edm4hep::Vector3d pos=hit.getPosition();
 
-        //edm4hep::Vector3d pos=simTrackerHitAsso.getPosition();
-
         TVector3 p(pos.x,pos.y,pos.z);
 
         p.Print();
@@ -919,18 +854,6 @@ int GenfitTrack::addSpacePointsDC(const edm4hep::Track& track,
     return nHitAdd;
 }//end of addSpacePointsDC
 
-//double GenfitTrack::extrapolateToPoint(TVector3& pos, TVector3& mom,
-//        TMatrixDSym& cov,
-//        const TVector3& point,
-//        int repID,// same with pidType
-//        bool stopAtBoundary,
-//        bool calcJacobianNoise) const
-//{
-//    return extrapolateToPoint(pos,mom,cov,point,repID,stopAtBoundary,
-//            calcJacobianNoise);
-//
-//}//end of extrapolateToPoint
-
 double GenfitTrack::extrapolateToPoint(TVector3& pos, TVector3& mom,
         TMatrixDSym& cov, const TVector3& point,
         int repID,// same with pidType
@@ -975,7 +898,6 @@ double GenfitTrack::extrapolateToPoint(TVector3& pos, TVector3& mom,
                 "In extrapolateToPoint KalmanFittedStateOnPlane is null"<<std::endl;
             return trackLength*dd4hep::cm;//FIXME unit
         }
-        //rep->setDebugLvl(10);
         trackLength = rep->extrapolateToPoint(*state,
                 point*(1/dd4hep::cm),stopAtBoundary, calcJacobianNoise);
 
@@ -1142,47 +1064,30 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
 
     //  getNumRawMeasurements
     unsigned int nPoints = m_track->getNumPoints();
-    std::cout << " nPoints =  " << nPoints << std::endl;
     unsigned int nPointsWithMea = m_track->getNumPointsWithMeasurement();
-    std::cout << " nPointsWithMea =  " << nPointsWithMea << std::endl;
 
     std::vector<double> hitMomMag;
 
-    //std::cout << __FILE__ << " " << __LINE__ << std::endl;
     while(1){
         genfit::TrackPoint* point = m_track->getPointWithFitterInfo(id);
-        //std::cout << __FILE__ << " " << __LINE__ << std::endl;
         if(!point)break;
-        //std::cout << __FILE__ << " " << __LINE__ << " id = " << id << std::endl;
         id++;
         genfit::AbsMeasurement* absMea = point->getRawMeasurement();
-        //std::cout << __FILE__ << " " << __LINE__ << " absMea: " << std::endl;
-        //absMea->Print();
 
         // getPoint FitterInfo
         genfit::AbsFitterInfo* FitterInfo = point->getFitterInfo();
-        //std::cout << __FILE__ << " " << __LINE__ << " FitterInfo: " << std::endl;
-        //FitterInfo->Print();
         genfit::KalmanFitterInfo *KalmanfitterInfo =
             dynamic_cast<genfit::KalmanFitterInfo*>(FitterInfo);
 
-        //std::cout << __FILE__ << " " << __LINE__ << " KalmanfitterInfo: " << std::endl;
-        //KalmanfitterInfo->Print();
-
         unsigned int nNumMea = KalmanfitterInfo->getNumMeasurements();
-        //std::cout << __FILE__ << " " << __LINE__ << " nNumMea = " << nNumMea << std::endl;
 
         bool flag = false;
         for(int i=0;i<nNumMea;i++)
         {
             genfit::MeasurementOnPlane* MeaOnPlane =
                 KalmanfitterInfo->getMeasurementOnPlane(i);
-            //std::cout << __FILE__ << " " << __LINE__ << " MeaOnPlane: " << std::endl;
-            //MeaOnPlane->Print();
 
             double weight = MeaOnPlane->getWeight();
-            std::cout << __FILE__ << " " << __LINE__ << " weight = " << weight << std::endl;
-
             if(weight>0.8) flag = true;
         }
         if(flag) fitid++;
@@ -1226,15 +1131,9 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
         }
     }
 
-    std::cout << " id = " << id << std::endl;
-    std::cout << " fitid = " << fitid << std::endl;
-
     nFittedDC = dcFit;
     nFittedSDT = SDTHit;
 
-    std::cout<<"nDC: "<<nFittedDC<<", nSDT: "<<nFittedSDT<<std::endl;
-    std::cout<<"nFittedDC: "<<dcFit<<", nFittedSDT: "<<sdtFit<<std::endl;
-
     if(fitid<1e-9) return false;
 
     if(m_debug>0)std::cout<<m_name<<" store track ndfCut "<<ndfCut<<" chi2Cut "
@@ -1271,8 +1170,6 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
     TVector3 mom;
     pos.SetXYZ(fittedPos.X(),fittedPos.Y(),fittedPos.Z());
     mom.SetXYZ(fittedMom.X(),fittedMom.Y(),fittedMom.Z());
-    //std::cout << "fitted momx = " << mom.X() << "momy = " << mom.Y() << "momz = " << mom.Z() << " mom.Mag = " << mom.Mag() << std::endl;
-    //std::cout << "fitted posx = " << pos.X() << "posy = " << pos.Y() << "posz = " << pos.Z() << std::endl;
     double radius = 80.022;  // cm
     const TVector3 linePoint(0,0,0);
     const TVector3 lineDirection(0,0,1);
@@ -1283,15 +1180,12 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
         double tracklength =
             extrapolateToCylinder(pos,mom,radius,linePoint,lineDirection,repID);
         hitMomMag.push_back(mom.Mag());
-        //std::cout << "momx = " << mom.X() << "momy = " << mom.Y() << "momz = " << mom.Z() << " mom.Mag = " << mom.Mag() << std::endl;
-        //std::cout << "posx = " << pos.X() << "posy = " << pos.Y() << "posz = " << pos.Z() << std::endl;
         trackL.push_back(tracklength);
     }
 
     for(int j=0;j<hitMomMag.size()-1;j++)
     {
         hitMom.push_back(hitMomMag[j]-hitMomMag[j+1]);
-        //std::cout << " Error Dep = " << hitMomMag[j]-hitMomMag[j+1] << std::endl;
     }
 
     if(m_debug>0)std::cout<<m_name<<" fit result: get status OK? pidType "
@@ -1341,11 +1235,8 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
 
     ///track status at POCA to referencePoint: origin
     const TVector3 referencePoint(0,0,0);
-    //TVector3 
     pocaToOrigin_pos.SetXYZ(1e9*dd4hep::cm,1e9*dd4hep::cm,1e9*dd4hep::cm);
-    //TVector3 
     pocaToOrigin_mom.SetXYZ(1e9*dd4hep::GeV,1e9*dd4hep::GeV,1e9*dd4hep::GeV);
-    //TMatrixDSym pocaToOrigin_cov;
     if(extrapolateToPoint(pocaToOrigin_pos,pocaToOrigin_mom,pocaToOrigin_cov,
                 referencePoint) > 1e6*dd4hep::cm){
         if(m_debug>0)std::cout<<m_name<<" extrapolate to origin failed"<<std::endl;
@@ -1369,12 +1260,6 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
         covMatrix_6[i][0]=fittedCov[i][0]/dd4hep::mm;//d0 row
         covMatrix_6[i][2]=fittedCov[i][1]/dd4hep::mm;//omega row
         covMatrix_6[i][3]=fittedCov[i][2]/dd4hep::mm;//z0 row
-        //covMatrix_6[0][i]=fittedCov[0][i]/GenfitUnit::cm*dd4hep::cm;//d0 column
-        //covMatrix_6[2][i]=fittedCov[2][i]*GenfitUnit::cm/dd4hep::cm;//omega column
-        //covMatrix_6[3][i]=fittedCov[3][i]/GenfitUnit::cm*dd4hep::cm;//z0 column
-        //covMatrix_6[i][0]=fittedCov[i][0]/GenfitUnit::cm*dd4hep::cm;//d0 row
-        //covMatrix_6[i][2]=fittedCov[i][2]*GenfitUnit::cm/dd4hep::cm;//omega row
-        //covMatrix_6[i][3]=fittedCov[i][3]/GenfitUnit::cm*dd4hep::cm;//z0 row
     }
 
     double Bz=m_genfitField->getBz(referencePoint)/GenfitUnit::tesla;
@@ -1403,34 +1288,15 @@ bool GenfitTrack::storeTrack(edm4hep::MutableReconstructedParticle& recParticle,
 
     //ngenfitHit = m_genfitHitVec.size();
     ngenfitHit = nPoints;
-    std::cout << " m_genfitHitVec size = " << m_genfitHitVec.size() << std::endl;
-    //    for(long unsigned int i=0; i<m_genfitHitVec.size();i++)
-    //    {
-    //        GenfitHit * genfitHit = GetHit(i);
-    //        edm4hep::TrackerHit* trackHit =
-    //            const_cast<edm4hep::TrackerHit*>(genfitHit->getTrackerHit());
-    //
-    //        track.addToTrackerHits(*trackHit);
-    //    }
-    //track.setType();
+
     track.setChi2(chi2);
     track.setNdf(ndf);
-    //track.setDEdx();
-    //track.setRadiusOfInnermostHit();//FIXME
-    //track.addToTrackerHits();
-
-    //new ReconstructedParticle
-    //recParticle->setType();
-    //dcRecParticle->setEnergy();
 
     recParticle.setMomentum(edm4hep::Vector3f(pocaToOrigin_mom.X(),
                 pocaToOrigin_mom.Y(),pocaToOrigin_mom.Z()));
     recParticle.setReferencePoint(edm4hep::Vector3f(referencePoint.X(),
                 referencePoint.Y(),referencePoint.Z()));
     recParticle.setCharge(charge);
-    //recParticle->setMass();
-    //recParticle.setCovMatrix(trackState->covMatrix);
-    //recParticle->setStartVertex();
     recParticle.addToTracks(track);
     if(m_debug>2){
         std::cout<<m_name<<" storeTrack trackState "<<trackState<<std::endl;
@@ -1533,9 +1399,6 @@ void GenfitTrack::getTrackFromEDMTrack(const edm4hep::Track& edm4HepTrack,
     double charge_double;
     CEPC::getPosMomFromTrackState(edm4HepTrack.getTrackStates(0),Bz,pos,mom,charge_double,cov);
 
-    //std::cout<<__LINE__<<" Bz "<<Bz<<" charge "<<charge_double<<std::endl;
-    //pos.Print();
-    //mom.Print();
     charge=(int) charge_double;
     trackParam[0]=pos[0]*GenfitUnit::mm;
     trackParam[1]=pos[1]*GenfitUnit::mm;
@@ -1555,16 +1418,12 @@ void GenfitTrack::getTrackFromEDMTrack(const edm4hep::Track& edm4HepTrack,
 void GenfitTrack::getTrackFromEDMTrackFinding(const edm4hep::Track& edm4HepTrack,
         double& charge, TVectorD& trackParam, TMatrixDSym& cov,TVector3& pos,
         TVector3& mom){
-    //double Bz=m_genfitField->getBz(TVector3{0.,0.,0.})/GenfitUnit::tesla;
+
     // FIXME
-    //double BZ=GenfitField::getBzFinding(TVector3{0.,0.,0.});
     double Bz=3*GenfitUnit::tesla;
     double charge_double;
     CEPC::getPosMomFromTrackState(edm4HepTrack.getTrackStates(1),Bz,pos,mom,charge_double,cov);
 
-    //std::cout<<__LINE__<<" Bz "<<Bz<<" charge "<<charge_double<<std::endl;
-    //pos.Print();
-    //mom.Print();
     charge=(int) charge_double;
     trackParam[0]=pos[0]*GenfitUnit::mm;
     trackParam[1]=pos[1]*GenfitUnit::mm;
@@ -1637,8 +1496,6 @@ int GenfitTrack::getSigmas(int cellID,std::vector<float> sigmaUVec,
     }
     if(m_debug){
         std::cout<<"sigmaUID "<<sigmaUID<<" sigmaVID "<<sigmaVID<<std::endl;
-        //std::cout<<"pos "<<pos_smeared[0]<<" "<<pos_smeared[1]<<" "<<pos_smeared[2]<<std::endl;
-        //std::cout<<"angle "<<atan2(pos_smeared[1],pos_smeared[0])<<std::endl;
         std::cout<<"sigmaU "<<sigmaUVec[sigmaUID]*GenfitUnit::mm
             <<" sigmaV "<<sigmaVVec[sigmaVID]*GenfitUnit::mm<<std::endl;
     }
@@ -1660,8 +1517,6 @@ void GenfitTrack::getSortedTrackerHitsTrF(
 
     std::vector<std::pair<double,edm4hep::TrackerHit*> > sortedDCTrackerHitPair;
     for(auto trackerHit : trackerHits){
-        //edm4hep::TrackerHit* thisHit = trackerHit;
-        //if(!isCDCHit(thisHit))continue;//skip non-DC trackerHit
 
         double time=trackerHit->getTime();
         if(0==sortMethod){
diff --git a/Reconstruction/RecGenfitAlg/src/GenfitTrack.h b/Reconstruction/RecGenfitAlg/src/GenfitTrack.h
index 91fe15b9d..58f25014c 100644
--- a/Reconstruction/RecGenfitAlg/src/GenfitTrack.h
+++ b/Reconstruction/RecGenfitAlg/src/GenfitTrack.h
@@ -164,10 +164,6 @@ class GenfitTrack {
     /// Output: pos and mom of POCA point to point
     /// Input: genfitTrack,point,repID,stopAtBoundary and calcAverageState
     /// repID same with pidType
-//    double extrapolateToPoint(TVector3& pos, TVector3& mom,TMatrixDSym& cov,
-//            const TVector3& point, int repID=0, bool stopAtBoundary = false,
-//            bool calcJacobianNoise = true) const;
-
     double extrapolateToPoint(TVector3& pos, TVector3& mom, TMatrixDSym& cov,
             const TVector3& point, int repID=0,
             bool stopAtBoundary = false, bool calcJacobianNoise = true) const;
diff --git a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
index f3a125509..c15dee5e0 100644
--- a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
+++ b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp
@@ -365,13 +365,6 @@ StatusCode RecGenfitAlgSDT::execute()
     std::chrono::time_point<std::chrono::high_resolution_clock> start;
     if(m_tuple) start=std::chrono::high_resolution_clock::now();
 
-    /////retrieve EventHeader
-    //auto header = _headerCol.get()->at(0);
-    //int evtNo = header.getEventNumber();
-    //int runNo = header.getRunNumber();
-    //info()<<"run "<<header.getEventNumber()
-    //  <<" "<<header.getRunNumber()<<std::endl;
-
     ///retrieve silicon Track and TrackHits
     const edm4hep::TrackCollection* sdtTrackCol=nullptr;
     if(m_SDTTrackCol.exist())sdtTrackCol=m_SDTTrackCol.get();
@@ -430,14 +423,7 @@ StatusCode RecGenfitAlgSDT::execute()
             GenfitTrack* genfitTrack=new GenfitTrack(m_genfitField,
                     m_gridDriftChamber,m_geomSvc);
             genfitTrack->setDebug(m_debug);
-            //if(m_useTruthTrack){
-            //    //single track only FIXME
-            //    if(!genfitTrack->createGenfitTrackFromMCParticle(pidType,
-            //                *(mcParticleCol->begin()), eventStartTime)){
-            //        debug()<<"createGenfitTrackFromMCParticle failed!"<<endmsg;
-            //        return StatusCode::SUCCESS;
-            //    }
-            //}else{
+
             if(!genfitTrack->createGenfitTrackFromEDM4HepTrack(pidType,
                         sdtTrack, eventStartTime,m_isUseCovTrack)){
                 debug()<<"createGenfitTrackFromEDM4HepTrack from SDT track failed!"<<endmsg;
@@ -479,9 +465,6 @@ StatusCode RecGenfitAlgSDT::execute()
                                 m_sigmaHitU[0],r_NoiseAssociationCol.get(),m_sortMethod,m_truthAmbig,
                                 m_skipCorner,m_skipNear);//mm
                      } else {
-                        //nHitAdded+=genfitTrack->addWireMeasurementsOnTrack(sdtTrack,
-                        //        m_sigmaHitU[0],assoDCHitsCol,m_sortMethod,m_truthAmbig,
-                        //        m_skipCorner,m_skipNear);//mm
                         nHitAdded+=genfitTrack->addWireMeasurementsOnTrack(sdtTrack,
                                 m_sigmaHitU[0],r_SmearAssociationCol.get(),m_sortMethod,m_truthAmbig,
                                 m_skipCorner,m_skipNear);//mm
@@ -505,12 +488,6 @@ StatusCode RecGenfitAlgSDT::execute()
             m_genfitFitter->setDebugGenfit(m_debugGenfit);
             m_genfitFitter->processTrack(genfitTrack,m_resortHits.value());
 
-            ///----------------------------------
-            ///Get TrackLength
-            ///---------------------------------
-            //TVector3 pos, TVector3 mom;
-            //double tracklength = genfitTrack->extrapolateToCylinder();
-
             ///-----------------------------------
             ///Store track
             ///-----------------------------------
@@ -566,23 +543,8 @@ StatusCode RecGenfitAlgSDT::execute()
         debugEvent(sdtTrackCol,sdtRecTrackCol,eventStartTime,nFittedSDT);
     }
 
-
-
-    //if(m_genfitDisplay) while(1){
-    //    std::cout<<"Press any key to finish..."<<std::endl;
-    //    //system ("pause");
-    //}
-
-
     if(m_tuple) sc=m_tuple->write();
 
-    //    time(&timep);
-    //    std::cout << "Myliu say: the time is "
-    //              << ctime(&timep)
-    //              << "at the end of RecGenfitAlgSDT::execute()"
-    //              << std::endl;
-    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
-
     return StatusCode::SUCCESS;
 }
 
@@ -612,15 +574,6 @@ void RecGenfitAlgSDT::debugTrack(int iStrack,int pidType,const GenfitTrack* genf
         TVector3 pocaToOrigin_pos,TVector3 pocaToOrigin_mom,
         TMatrixDSym pocaToOrigin_cov)
 {
-
-    //    time_t timep;
-    //    time(&timep);
-    //    std::cout << "Myliu say: the time is "
-    //              << ctime(&timep)
-    //              << "at the begin of debugTrack()"
-    //              << std::endl;
-    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
-
     /// Get fit status
     const genfit::FitStatus* fitState = genfitTrack->getFitStatus();
     int charge= fitState->getCharge();
@@ -751,28 +704,12 @@ void RecGenfitAlgSDT::debugTrack(int iStrack,int pidType,const GenfitTrack* genf
             <<" ndf "<<m_nDofKal[iStrack][pidType]
             <<" chi2 "<<m_chi2Kal[pidType]<<endmsg;
     }
-    //    time(&timep);
-    //    std::cout << "Myliu say: the time is "
-    //              << ctime(&timep)
-    //              << "at the end of debugTrack()"
-    //              << std::endl;
-    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
 }
 
 void RecGenfitAlgSDT::debugEvent(const edm4hep::TrackCollection* sdtTrackCol,
         const edm4hep::TrackCollection* sdtRecTrackCol,
         double eventStartTime,int nFittedSDT)
 {
-
-    //    time_t timep;
-    //    time(&timep);
-    //    std::cout << "Myliu say: the time is "
-    //              << ctime(&timep)
-    //              << "at the begin of debugEvent()"
-    //              << std::endl;
-    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
-
-
     int iSdtTrack=0;
     m_nSdtTrack=sdtTrackCol->size();
     for(auto sdtTrack: *sdtTrackCol){
@@ -883,12 +820,9 @@ void RecGenfitAlgSDT::debugEvent(const edm4hep::TrackCollection* sdtTrackCol,
     m_nSdtRecTrack=sdtRecTrackCol->size();
     int isdttrack=0;
     for(auto sdtRecTrack: *sdtRecTrackCol){
-        std::cout << " sdtRecTrack.trackerHits_size() = " << sdtRecTrack.trackerHits_size() << std::endl;
         for(int iHit=0;iHit<sdtRecTrack.trackerHits_size();iHit++)
         {
             edm4hep::TrackerHit sdtRecTrackHit = sdtRecTrack.getTrackerHits(iHit);
-            //std::cout << " sdtRecTrackHit eDep = " << sdtRecTrackHit.getEDep() << std::endl;
-
         }
         for(unsigned int i=0; i<sdtRecTrack.trackStates_size(); i++) {
             edm4hep::TrackState trackStat=sdtRecTrack.getTrackStates(i);
@@ -973,27 +907,11 @@ void RecGenfitAlgSDT::debugEvent(const edm4hep::TrackCollection* sdtTrackCol,
 
         iDCDigi++;
     }
-    //    time(&timep);
-    //    std::cout << "Myliu say: the time is "
-    //              << ctime(&timep)
-    //              << "at the end of debugEvent()"
-    //              << std::endl;
-    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
 }
 
 void RecGenfitAlgSDT::selectHits(const edm4hep::Track&,
         std::vector<edm4hep::TrackerHit*>& dcDigiSelected)
 {
-
-    //    time_t timep;
-    //    time(&timep);
-    //    std::cout << "Myliu say: the time is "
-    //              << ctime(&timep)
-    //              << "at the begin of selectHits()"
-    //              << std::endl;
-    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
-
-
     //for single track only, FIXME
     double eventStartTime=0;
     unsigned int pidType=1;//mu
@@ -1014,8 +932,6 @@ void RecGenfitAlgSDT::selectHits(const edm4hep::Track&,
             double docaExt=1e9;
             bool stopAtBoundary=false;
             bool calcJacobianNoise=true;
-            //for(auto mcParticle : *mcParticleCol){
-            //}
             edm4hep::MCParticle mcParticle=*(mcParticleCol->begin());//FIXME single track only
 
             genfitTrack->extrapolateToHit(poca,pocaDir,pocaOnWire,docaExt,
@@ -1053,10 +969,4 @@ void RecGenfitAlgSDT::selectHits(const edm4hep::Track&,
         }
     }//end loop over track
     delete genfitTrack;
-    //    time(&timep);
-    //    std::cout << "Myliu say: the time is "
-    //              << ctime(&timep)
-    //              << "at the end of selectHits()"
-    //              << std::endl;
-    //    system("/scratchfs/bes/myliu/script/memory_rec.sh");
 }//end of select hit

From 5f0879c6e4aff60ecc8a87c4795de23d9cc6df38 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Fri, 15 Mar 2024 13:12:36 +0800
Subject: [PATCH 26/27] Add some description

---
 .../src/driftchamber/DriftChamber.cpp         |   9 +
 .../src/driftchamber/DriftChamber_stero.cpp   | 307 ------------------
 Digitisers/DCHDigi/src/DCHDigiAlg.h           |   3 +
 3 files changed, 12 insertions(+), 307 deletions(-)
 delete mode 100644 Detector/DetDriftChamber/src/driftchamber/DriftChamber_stero.cpp

diff --git a/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp b/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
index ab80570fc..1ffdd929e 100644
--- a/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
+++ b/Detector/DetDriftChamber/src/driftchamber/DriftChamber.cpp
@@ -1,3 +1,12 @@
+//====================================================================
+//  Detector description implementation of the Drift Chamber
+//--------------------------------------------------------------------
+//
+//  Author: Tao Lin
+//          Mengyao Liu
+//
+//====================================================================
+
 #include "DD4hep/DetFactoryHelper.h"
 #include "DD4hep/Printout.h"
 #include "XML/Layering.h"
diff --git a/Detector/DetDriftChamber/src/driftchamber/DriftChamber_stero.cpp b/Detector/DetDriftChamber/src/driftchamber/DriftChamber_stero.cpp
deleted file mode 100644
index 0b9061a9f..000000000
--- a/Detector/DetDriftChamber/src/driftchamber/DriftChamber_stero.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-//====================================================================
-//  Detector description implementation of the Drift Chamber
-//--------------------------------------------------------------------
-//
-//  Author: Tao Lin
-//          Mengyao Liu
-//
-//====================================================================
-
-#include "DD4hep/DetFactoryHelper.h"
-#include "DD4hep/Printout.h"
-#include "XML/Layering.h"
-#include "XML/Utilities.h"
-#include "XML/XMLElements.h"
-#include "DDRec/DetectorData.h"
-#include "DDSegmentation/Segmentation.h"
-#include "DetSegmentation/GridDriftChamber.h"
-
-using namespace dd4hep;
-using namespace dd4hep::detail;
-using namespace dd4hep::rec ;
-
-#define MYDEBUG(x) std::cout << __FILE__ << ":" << __LINE__ << ": " << x << std::endl;
-#define MYDEBUGVAL(x) std::cout << __FILE__ << ":" << __LINE__ << ": " << #x << ": " << x << std::endl;
-
-static dd4hep::Ref_t create_detector(dd4hep::Detector& theDetector,
-        xml_h e,
-        dd4hep::SensitiveDetector sens) {
-    // ------- Lambda functions ---- //
-    auto delta_a_func = [](auto x, auto y) { return 0.5 * ( x + y ); };
-    auto delta_b_func = [](auto x, auto y) { return 2 * std::sqrt((x + y) * (x - y)); };
-    auto epsilon_func = [](auto delta_a, auto L) { return std::atan(delta_a / L); };
-
-    // =======================================================================
-    // Parameter Definition
-    // =======================================================================
-
-    xml_det_t x_det = e;
-
-    xml_coll_t c(x_det,_U(chamber));
-    xml_comp_t x_chamber = c;
-
-    xml_coll_t cc(x_det,_U(side));
-    xml_comp_t x_side = cc;
-
-    std::string det_name = x_det.nameStr();
-    std::string det_type = x_det.typeStr();
-
-    dd4hep::SensitiveDetector sd = sens;
-
-    // - global
-    double chamber_half_length     = theDetector.constant<double>("DC_half_length");
-    double chamber_length     = theDetector.constant<double>("DC_length");
-
-    // - chamber
-    double chamber_radius_min = theDetector.constant<double>("SDT_chamber_radius_min");
-    double chamber_radius_max = theDetector.constant<double>("SDT_chamber_radius_max");
-    double SDT_half_length     = theDetector.constant<double>("SDT_chamber_half_length");
-    int chamberID = x_chamber.id();
-
-    // - layer
-    double chamber_layer_width  = theDetector.constant<double>("SDT_chamber_layer_width");
-    double chamber_cell_width  = theDetector.constant<double>("SDT_chamber_cell_width");
-    double chamber_layer_rbegin = theDetector.constant<double>("DC_chamber_layer_rbegin");
-    double chamber_layer_rend = theDetector.constant<double>("DC_chamber_layer_rend");
-    int chamber_layer_number = floor((chamber_layer_rend-chamber_layer_rbegin)/chamber_layer_width);
-
-    double cellsize = theDetector.constant<double>("SDT_chamber_cell_width");
-
-    double safe_distance = theDetector.constant<double>("DC_safe_distance");
-    double alpha = theDetector.constant<double>("Alpha");
-
-    // =======================================================================
-    // Detector Construction
-    // =======================================================================
-
-    dd4hep::DetElement sdet(det_name, x_det.id());
-
-    Volume envelope = dd4hep::xml::createPlacedEnvelope( theDetector,  e , sdet ) ;
-
-    dd4hep::xml::setDetectorTypeFlag( e, sdet ) ;
-
-    if( theDetector.buildType() == BUILD_ENVELOPE ) return sdet ;
-
-
-//    dd4hep::Material det_mat(theDetector.material("Air"));
-    dd4hep::Material det_mat(theDetector.material(x_det.materialStr()));
-//    dd4hep::Material chamber_mat(theDetector.material("GasHe_90Isob_10"));
-    dd4hep::Material chamber_mat = theDetector.material(x_chamber.materialStr());
-
-    // - global
-    Assembly det_vol( det_name+"_assembly" ) ;
-
-    // - chamber volume
-    dd4hep::Tube det_chamber_solid(chamber_radius_min, chamber_radius_max, chamber_half_length);
-    dd4hep::Volume det_chamber_vol(det_name+"_chamber_vol", det_chamber_solid, chamber_mat);
-
-    // - wall
-    double chamber_inner_wall_rmin = theDetector.constant<double>("SDT_chamber_inner_wall_radius_min");
-    double chamber_inner_wall_rmax = theDetector.constant<double>("SDT_chamber_inner_wall_radius_max");
-    double chamber_outer_wall_rmin = theDetector.constant<double>("SDT_chamber_outer_wall_radius_min");
-    double chamber_outer_wall_rmax = theDetector.constant<double>("SDT_chamber_outer_wall_radius_max");
-
-//    dd4hep::Material wall_mat(theDetector.material("CarbonFiber"));
-    dd4hep::Material wall_mat(theDetector.material(x_side.materialStr()));
-
-    double wall_rmin[2] = {chamber_inner_wall_rmin, chamber_outer_wall_rmin};
-    double wall_rmax[2] = {chamber_inner_wall_rmax, chamber_outer_wall_rmax};
-
-   // - wire
-    dd4hep::Volume module_vol;
-    dd4hep::Volume Module_vol;
-    for(xml_coll_t c(x_det,_U(module)); c; ++c) {
-      xml_comp_t x_module = c;
-      double  module_rmin = x_module.rmin();
-      double  module_rmax = x_module.rmax();
-      std::string module_name = x_module.nameStr();
-      dd4hep::Tube module_solid(module_rmin,module_rmax,chamber_half_length);
-      if(x_module.id()==0) {
-         module_vol = dd4hep::Volume(module_name,module_solid,det_mat);
-         module_vol.setVisAttributes(theDetector.visAttributes(x_module.visStr()));
-      } else {
-         Module_vol = dd4hep::Volume(module_name,module_solid,det_mat);
-         Module_vol.setVisAttributes(theDetector.visAttributes(x_module.visStr()));
-      }
-
-      for(xml_coll_t l(x_module,_U(tubs)); l; ++l) {
-         xml_comp_t x_tube =l;
-         double tube_rmin = x_tube.rmin();
-         double tube_rmax = x_tube.rmax();
-         std::string tube_name = x_tube.nameStr();
-         std::string wire_name= module_name + tube_name;
-         dd4hep::Material tube_mat = theDetector.material(x_tube.materialStr());
-         dd4hep::Tube wire_solid(tube_rmin,tube_rmax,chamber_half_length);
-         dd4hep::Volume wire_vol(wire_name,wire_solid,tube_mat);
-         dd4hep::Transform3D transform_wire(dd4hep::Rotation3D(),dd4hep::Position(0.,0.,0.));
-         dd4hep::PlacedVolume wire_phy;
-         if(x_module.id()==0) {
-            wire_phy = module_vol.placeVolume(wire_vol,transform_wire);
-         } else {
-            wire_phy = Module_vol.placeVolume(wire_vol,transform_wire);
-         }
-      }
-  }
-
-    // End cap
-    double Endcap_rmin = theDetector.constant<double>("DC_Endcap_rmin");
-    double Endcap_rmax = theDetector.constant<double>("DC_Endcap_rmax");
-    double Endcap_z = theDetector.constant<double>("DC_Endcap_dz");
-    dd4hep::Tube det_Endcap_solid(Endcap_rmin,Endcap_rmax,0.5*Endcap_z);
-    dd4hep::Volume det_Endcap_vol(det_name+"Endcap",det_Endcap_solid,det_mat);
-    det_Endcap_vol.setVisAttributes(theDetector,"YellowVis");
-
-    //Initialize the segmentation
-    dd4hep::Readout readout = sd.readout();
-    dd4hep::Segmentation geomseg = readout.segmentation();
-    dd4hep::Segmentation* _geoSeg = &geomseg;
-
-    auto DCHseg = dynamic_cast<dd4hep::DDSegmentation::GridDriftChamber*>(_geoSeg->segmentation());
-
-    // - layer
-    int chamber_id = 0;
-    int layerIndex = -1;
-    for(int layer_id = 0; layer_id < chamber_layer_number; layer_id++) {
-
-        double rmin,rmax,offset=0;
-
-        double sign_eps = 1;
-
-        dd4hep::Volume* current_vol_ptr = nullptr;
-//        current_vol_ptr = &det_chamber_vol;
-        rmin = chamber_layer_rbegin+(layer_id*chamber_layer_width);
-        rmax = rmin+chamber_layer_width;
-        layerIndex = layer_id;
-
-        //Construction of drift chamber layers
-        double rmid = delta_a_func(rmin,rmax);
-        double Rmid = rmid/std::cos(alpha/2);
-        double ilayer_cir = 2 * M_PI * rmid;
-        double ncell = ilayer_cir / chamber_layer_width;
-        int ncell_layer = floor(ncell);
-        int numWire = ncell_layer;
-        double layer_Phi = 2*M_PI / ncell_layer;
-
-        if(layer_id %2 ==0)
-        {
-             offset = 0.;
-             sign_eps = -1;
-        }
-        else { offset = 0.5 * layer_Phi; }
-
-
-        double epsilon = sign_eps*std::atan(2 * Rmid * std::tan(alpha / 2.0) / chamber_length);
-        double alpha0 = 2*std::asin(chamber_length * std::tan(epsilon)/(2*Rmid));
-
-        DCHseg->setGeomParams(chamber_id, layerIndex, layer_Phi, rmid, epsilon, offset);
-        DCHseg->setWiresInLayer(chamber_id, layerIndex, numWire);
-
-        double r_in_test = rmid*std::cos(alpha / 2.0);
-
-        double r_in0 = rmid - cellsize / 2.0;
-        double r_in = r_in0 / std::cos(alpha / 2.0);
-
-        double r_out0 = rmid + cellsize / 2.0;
-        double r_out = r_out0 / std::cos(alpha / 2.0);
-
-        double delta_a_in = delta_b_func(r_in, r_in0);
-        double delta_a_out = delta_b_func(r_out, r_out0);
-
-        double eps_in = epsilon_func(delta_a_in, chamber_length );
-        double eps_out = epsilon_func(delta_a_out, chamber_length );
-
-//        dd4hep::Tube layer_vol_solid(rmin,rmax,chamber_half_length);
-        dd4hep::Hyperboloid layer_vol_solid(r_in0, eps_in, r_out0, eps_out, chamber_half_length);
-        dd4hep::Volume layer_vol(det_name+"_layer_vol",layer_vol_solid,det_mat);
-        current_vol_ptr = &layer_vol;
-
-        if ( x_det.isSensitive() )   {
-            layer_vol.setRegion(theDetector,x_det.regionStr());
-            layer_vol.setLimitSet(theDetector,x_det.limitsStr());
-            layer_vol.setSensitiveDetector(sens);
-            sd.setType("tracker");
-        }
-
-        // - wire vol
-        //phi <-------------------> -phi
-        //    |   F8    F7   F6   F5|  Only on the outermost layer.
-        //    |                     |
-        //    |         S         F4|
-        //    |                     |
-        //    |   F0    F1   F2   F3|
-        //    -----------------------
-        for(int icell=0; icell< numWire; icell++) {
-            double wire_phi = (icell+0.5)*layer_Phi + offset;
-
-            // - signal wire
-            dd4hep::RotationZ rz(wire_phi);
-            dd4hep::RotationY ry(epsilon);
-            dd4hep::Position tr3D = Position(rmid*std::cos(0.5*M_PI+wire_phi),rmid*std::sin(0.5*M_PI+wire_phi),0.);
-            dd4hep::Transform3D transform_signal_wire(rz*ry,tr3D);
-
-            dd4hep::PlacedVolume module_phy = (*current_vol_ptr).placeVolume(module_vol,transform_signal_wire);
-           // - Field wire
-            dd4hep::PlacedVolume Module_phy;
-            double radius[5] = {rmid-chamber_layer_width*0.5+safe_distance,rmid-chamber_layer_width*0.5+safe_distance,rmid,rmid+chamber_layer_width*0.5-safe_distance,rmid+chamber_layer_width*0.5-safe_distance};
-            double phi[5] = {wire_phi,wire_phi-layer_Phi*0.5,wire_phi-layer_Phi*0.5,wire_phi-layer_Phi*0.5,wire_phi};
-            int num = 3;
-            if(layer_id==(chamber_layer_number-1)) {
-               num = 5;
-            }
-            for(int i=0; i<num ; i++) {
-                dd4hep::RotationZ rz_field(phi[i]);
-                dd4hep::RotationY ry_field(epsilon);
-                dd4hep::Position tr3D_field = Position(radius[i]*std::cos(0.5*M_PI+phi[i]),radius[i]*std::sin(0.5*M_PI+phi[i]),0.);
-                dd4hep::Transform3D transform_field_wire(rz_field*ry_field,tr3D_field);
-
-                Module_phy = (*current_vol_ptr).placeVolume(Module_vol,transform_field_wire);
-            }
-        }
-        dd4hep::Transform3D transform_layer(dd4hep::Rotation3D(),
-                dd4hep::Position(0,0,0));
-        dd4hep::PlacedVolume layer_phy = det_chamber_vol.placeVolume(layer_vol,transform_layer);
-        layer_phy.addPhysVolID("layer", layer_id);
-    }
-
-    // - place in det
-    // - chamber
-    dd4hep::Transform3D transform_chamber(dd4hep::Rotation3D(),
-            dd4hep::Position(0,0,0));
-    dd4hep::PlacedVolume det_chamber_phy = det_vol.placeVolume(det_chamber_vol,
-                 transform_chamber);
-
-    det_chamber_phy.addPhysVolID("chamber", chamberID);
-
-    // - place in world
-    dd4hep::Transform3D transform(dd4hep::Rotation3D(),
-            dd4hep::Position(0,0,0));
-    dd4hep::PlacedVolume phv = envelope.placeVolume(det_vol,transform);
-    // - place wall
-    dd4hep::PlacedVolume wall_phy;
-    for(int i=0; i<2; i++) {
-       dd4hep::Tube wall_solid(wall_rmin[i],wall_rmax[i],chamber_half_length);
-       dd4hep::Volume wall_vol(det_name+"_wall_vol",wall_solid,wall_mat);
-       wall_vol.setVisAttributes(theDetector,"VisibleGreen");
-       wall_phy = envelope.placeVolume(wall_vol,transform);
-    }
-
-    // - place Endcap
-    double endcap_pos[2] = {chamber_half_length+Endcap_z*0.5,-chamber_half_length-Endcap_z*0.5};
-    dd4hep::PlacedVolume endcap_phy;
-    for(int i=0; i<2; i++) {
-        dd4hep::Transform3D Endcap_transform(dd4hep::Rotation3D(),dd4hep::Position(0,0,endcap_pos[i]));
-        endcap_phy = envelope.placeVolume(det_Endcap_vol,Endcap_transform);
-   }
-
-    if ( x_det.hasAttr(_U(id)) )  {
-        phv.addPhysVolID("system",x_det.id());
-    }
-    DetElement assDE( sdet , det_name+"_assembly" , x_det.id() )  ;
-    assDE.setPlacement(phv);
-
-    MYDEBUG("Build Detector Drift Chamber successfully.");
-    return sdet;
-
-}
-
-DECLARE_DETELEMENT(DriftChamber_Stero, create_detector);
diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.h b/Digitisers/DCHDigi/src/DCHDigiAlg.h
index cc6a53127..946363c1c 100644
--- a/Digitisers/DCHDigi/src/DCHDigiAlg.h
+++ b/Digitisers/DCHDigi/src/DCHDigiAlg.h
@@ -54,10 +54,13 @@ class DCHDigiAlg : public GaudiAlgorithm
   NTuple::Array<int  > m_chamber   ;
   NTuple::Array<int  > m_layer     ;
   NTuple::Array<int  > m_cell      ;
+  //The position of wire at -z
   NTuple::Array<float> m_cell_x    ;
   NTuple::Array<float> m_cell_y    ;
+  //The position of wire at +z
   NTuple::Array<float> m_cell1_x   ;
   NTuple::Array<float> m_cell1_y   ;
+
   NTuple::Array<float> m_simhit_x  ;
   NTuple::Array<float> m_simhit_y  ;
   NTuple::Array<float> m_simhit_z  ;

From c8d62f37f68c9c5fa152fcdf0031f0ab985bd826 Mon Sep 17 00:00:00 2001
From: myliu <201916234@mail.sdu.edu.cn>
Date: Fri, 15 Mar 2024 13:26:36 +0800
Subject: [PATCH 27/27] Update version of th DC constructor

---
 Detector/DetDriftChamber/CMakeLists.txt | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Detector/DetDriftChamber/CMakeLists.txt b/Detector/DetDriftChamber/CMakeLists.txt
index 70a29ad77..fbf8e01ce 100644
--- a/Detector/DetDriftChamber/CMakeLists.txt
+++ b/Detector/DetDriftChamber/CMakeLists.txt
@@ -16,7 +16,6 @@ find_package(ROOT COMPONENTS MathCore GenVector Geom REQUIRED)
 
 gaudi_add_module(DetDriftChamber
                  SOURCES src/driftchamber/DriftChamber.cpp
-                 SOURCES src/driftchamber/DriftChamber_stero.cpp
 		 LINK DetSegmentation
                       ${DD4hep_COMPONENT_LIBRARIES} 
                   # ROOT Geant4