diff --git a/Reconstruction/RecActsTracking/src/RecActsTracking.cpp b/Reconstruction/RecActsTracking/src/RecActsTracking.cpp
index cd228ee7b5be4b3f5fc31b2ea115424a4293746e..9f46bbba6f6d713cf0f09ec37963eaf41aa2019b 100644
--- a/Reconstruction/RecActsTracking/src/RecActsTracking.cpp
+++ b/Reconstruction/RecActsTracking/src/RecActsTracking.cpp
@@ -22,17 +22,7 @@ DECLARE_COMPONENT(RecActsTracking)
 RecActsTracking::RecActsTracking(const std::string& name, ISvcLocator* svcLoc)
     : GaudiAlgorithm(name, svcLoc)
 {
-    // input collections
-    // declareProperty("VXDTrackerHits", _inVTXTrackHdl, "Handle of the Input VTX TrackerHits collection");
-    // declareProperty("SITTrackerHits", _inSITTrackHdl, "Handle of the Input SIT TrackerHits collection");
-
-    // declareProperty("VXDCollection", _inVTXColHdl, "Handle of the Input VTX Sim Hit collection");
-    // declareProperty("SITCollection", _inSITColHdl, "Handle of the Input SIT Sim Hit collection");
-
-    // declareProperty("MCParticleCollection", _inMCColHdl, "Handle of the Input MCParticle collection");
-
-    // Output Collections
-    // declareProperty("OutputTracks", _outColHdl, "Handle of the ACTS SiTrack output collection");
+    // _encoder = new UTIL::BitField64(lcio::ILDCellID0::encoder_string);
 }
 
 StatusCode RecActsTracking::initialize()
@@ -55,6 +45,41 @@ StatusCode RecActsTracking::initialize()
         return StatusCode::FAILURE;
     }
 
+    if(!m_particle.value().empty()){
+        info() << "Assume Particle: " << m_particle.value() << endmsg;
+        if(m_particle.value() == "muon"){
+            particleHypothesis = Acts::ParticleHypothesis::muon();
+        }
+        else if(m_particle.value() == "pion"){
+            particleHypothesis = Acts::ParticleHypothesis::pion();
+        }
+        else if(m_particle.value() == "electron"){
+            particleHypothesis = Acts::ParticleHypothesis::electron();
+        }
+        else if(m_particle.value() == "kaon"){
+            particleHypothesis = Acts::ParticleHypothesis::kaon();
+        }
+        else if(m_particle.value() == "proton"){
+            particleHypothesis = Acts::ParticleHypothesis::proton();
+        }
+        else if(m_particle.value() == "photon"){
+            particleHypothesis = Acts::ParticleHypothesis::photon();
+        }
+        else if(m_particle.value() == "geantino"){
+            particleHypothesis = Acts::ParticleHypothesis::geantino();
+        }
+        else if(m_particle.value() == "chargedgeantino"){
+            particleHypothesis = Acts::ParticleHypothesis::chargedGeantino();
+        }
+        else{
+            info() << "Supported Assumed Particle: " << particleNames[0] << ", " << particleNames[1] << ", " << particleNames[2] << ", "
+                                             << particleNames[3] << ", " << particleNames[4] << ", " << particleNames[5] << ", "
+                                             << particleNames[6] << ", " << particleNames[7] << endmsg;
+            error() << "Unsupported particle name " << m_particle.value() << endmsg;
+            return StatusCode::FAILURE;
+        }
+    }
+
     TGeo_ROOTFilePath = TGeo_path.value();
     TGeoConfig_jFilePath = TGeo_config_path.value();
     MaterialMap_jFilePath = MaterialMap_path.value();
@@ -95,15 +120,15 @@ StatusCode RecActsTracking::initialize()
     info() << "Seeding tools initialized successfully!" << endmsg;
 
     // configure the acts tools
-    seed_cfg.seedFinderOptions.bFieldInZ = 3_T;
-    seed_cfg.seedFinderConfig.deltaRMin = 4_mm;
-    seed_cfg.seedFinderConfig.deltaRMax = 25_mm;
-    seed_cfg.seedFinderConfig.rMax = 40_mm;
-    seed_cfg.seedFinderConfig.rMin = 8_mm;
-    seed_cfg.seedFinderConfig.impactMax = 4_mm;
+    seed_cfg.seedFinderOptions.bFieldInZ = m_field.value();
+    seed_cfg.seedFinderConfig.deltaRMin = SeedDeltaRMin.value();
+    seed_cfg.seedFinderConfig.deltaRMax = SeedDeltaRMax.value();
+    seed_cfg.seedFinderConfig.rMax = SeedRMax.value();
+    seed_cfg.seedFinderConfig.rMin = SeedRMin.value();
+    seed_cfg.seedFinderConfig.impactMax = SeedImpactMax.value();
     seed_cfg.seedFinderConfig.useVariableMiddleSPRange = false;
-    seed_cfg.seedFinderConfig.rMinMiddle = 15_mm; // range for middle spacepoint (TDR)
-    seed_cfg.seedFinderConfig.rMaxMiddle = 30_mm; // range for middle spacepoint (TDR)
+    seed_cfg.seedFinderConfig.rMinMiddle = SeedRMinMiddle.value();
+    seed_cfg.seedFinderConfig.rMaxMiddle = SeedRMaxMiddle.value();
 
     // initialize the acts tools
     seed_cfg.seedFilterConfig = seed_cfg.seedFilterConfig.toInternalUnits();
@@ -148,28 +173,6 @@ StatusCode RecActsTracking::execute()
 {
     auto trkCol = _outColHdl.createAndPut();
 
-    bool MCsuccess = true;
-    const edm4hep::MCParticleCollection* mcCols = nullptr;
-    mcCols = _inMCColHdl.get();
-    if(mcCols)
-    {
-        for(auto particle : *mcCols)
-        {
-            if (particle.getPDG() != 13)
-            {
-                MCsuccess = false;
-                continue;
-            }
-            break;
-        }
-    }
-
-    if (!MCsuccess)
-    {
-        _nEvt++;
-        return StatusCode::SUCCESS;
-    }
-
     SpacePointPtrs.clear();
     sourceLinks.clear();
     measurements.clear();
@@ -351,7 +354,7 @@ StatusCode RecActsTracking::execute()
     Acts::GainMatrixUpdater kfUpdater;
     Acts::MeasurementSelector::Config measurementSelectorCfg =
     {
-        {Acts::GeometryIdentifier(), {{}, {30}, {1u}}},
+        {Acts::GeometryIdentifier(), {{}, {CKFchi2Cut.value()}, {numMeasurementsCutOff.value()}}},
     };
 
     MeasurementSelector measSel{ Acts::MeasurementSelector(measurementSelectorCfg) };
@@ -473,21 +476,83 @@ StatusCode RecActsTracking::execute()
             if (!firstSmoothingResult.ok())
             {
                 m_nFailedSmoothing++;
+                debug() << "First smoothing for seed " 
+                       << iSeed << " and track " << firstTrack.index()
+                       << " failed with error " << firstSmoothingResult.error() << endmsg;
                 continue;
             }
 
             seedNumber(trackCandidate) = nSeed - 1;
-
-            auto firstExtrapolationResult = Acts::extrapolateTrackToReferenceSurface(
-                trackCandidate, *pSurface, extrapolator, extrapolationOptions, extrapolationStrategy);
-
-            if (!firstExtrapolationResult.ok())
+      
+            // second way track finding
+            std::size_t nSecond = 0;
+            if (CKFtwoWay)
             {
-                m_nFailedExtrapolation++;
-                continue;
+                std::optional<Acts::VectorMultiTrajectory::TrackStateProxy> firstMeasurement;
+                for (auto trackState : trackCandidate.trackStatesReversed())
+                {
+                    bool isMeasurement = trackState.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag);
+                    bool isOutlier = trackState.typeFlags().test(Acts::TrackStateFlag::OutlierFlag);
+                    if (isMeasurement && !isOutlier) { firstMeasurement = trackState; }
+                }
+                
+                if (firstMeasurement.has_value())
+                {
+                    Acts::BoundTrackParameters secondInitialParameters = trackCandidate.createParametersFromState(*firstMeasurement);
+                    auto secondResult = (*findTracks)(secondInitialParameters, secondOptions, tracksTemp);
+                    if (!secondResult.ok())
+                    {
+                        debug() << "Second track finding failed for seed "
+                                << iSeed << " with error" << secondResult.error() << endmsg;
+                    } else {
+                        auto firstState = *std::next(trackCandidate.trackStatesReversed().begin(), trackCandidate.nTrackStates() - 1);
+                        auto& secondTracksForSeed = secondResult.value();
+                        for (auto& secondTrack : secondTracksForSeed)
+                        { 
+                            if (secondTrack.nTrackStates() < 2) { continue; }
+                            auto secondTrackCopy = tracksTemp.makeTrack();
+                            secondTrackCopy.copyFrom(secondTrack, true);
+                            secondTrackCopy.reverseTrackStates(true);
+
+                            firstState.previous() = (*std::next(secondTrackCopy.trackStatesReversed().begin())).index();
+                            Acts::calculateTrackQuantities(trackCandidate);
+                            auto secondExtrapolationResult = Acts::extrapolateTrackToReferenceSurface(
+                                trackCandidate, *pSurface, extrapolator,
+                                extrapolationOptions, extrapolationStrategy);
+                            if (!secondExtrapolationResult.ok())
+                            {
+                                m_nFailedExtrapolation++;
+                                debug() << "Second extrapolation for seed " 
+                                        << iSeed << " and track " << secondTrack.index()
+                                        << " failed with error "
+                                        << secondExtrapolationResult.error() << endmsg;
+                                continue;
+                            }
+
+                            addTrack(trackCandidate);
+
+                            ++nSecond;
+                        }
+
+                        firstState.previous() = Acts::kTrackIndexInvalid;
+                        Acts::calculateTrackQuantities(trackCandidate);
+                    }
+                }
             }
 
-            addTrack(trackCandidate);
+            // if no second track was found, we will use only the first track
+            if (nSecond == 0) {
+                auto firstExtrapolationResult = Acts::extrapolateTrackToReferenceSurface(
+                    trackCandidate, *pSurface, extrapolator, extrapolationOptions, extrapolationStrategy);
+
+                if (!firstExtrapolationResult.ok())
+                {
+                    m_nFailedExtrapolation++;
+                    continue;
+                }
+
+                addTrack(trackCandidate);
+            }
         }
     }
 
@@ -523,7 +588,7 @@ StatusCode RecActsTracking::execute()
                 const auto& MeasSourceLink = cur_measurement_sl.get<IndexSourceLink>();
                 auto cur_measurement = measurements[MeasSourceLink.index()];
                 auto cur_measurement_gid = MeasSourceLink.geometryId();
-                if (std::find(VXD_inner_volume_ids.begin(), VXD_inner_volume_ids.end(), cur_measurement_gid.volume()) != VXD_inner_volume_ids.end()){
+                if (std::find(VXD_volume_ids.begin(), VXD_volume_ids.end(), cur_measurement_gid.volume()) != VXD_volume_ids.end()){
                     nVTXHit++;
                 } else if (std::find(SIT_acts_volume_ids.begin(), SIT_acts_volume_ids.end(), cur_measurement_gid.volume()) != SIT_acts_volume_ids.end()){
                     nSITHit++;
@@ -649,6 +714,9 @@ int RecActsTracking::InitialiseVTX()
             double momentum_y = simhit.getMomentum()[1];
             double momentum_z = simhit.getMomentum()[2];
 
+            const Acts::Vector3 globalmom{momentum_x, momentum_y, momentum_z};
+            std::array<float, 6> m_covMatrix = hit.getCovMatrix();
+
             dd4hep::rec::ISurface* surface = nullptr;
             auto it = m_vtx_surfaces->find(simcellid);
             if (it != m_vtx_surfaces->end()) {
@@ -675,12 +743,12 @@ int RecActsTracking::InitialiseVTX()
 
             if (m_layer <= 3){
                 // set acts geometry identifier
-                // VXD_inner_volume_ids{16, 17, 18, 19};
-                uint64_t acts_volume = VXD_inner_volume_ids[m_layer];
+                uint64_t acts_volume = VXD_volume_ids[m_layer];
                 uint64_t acts_boundary = 0;
                 uint64_t acts_layer = 2;
                 uint64_t acts_approach = 0;
-                uint64_t acts_sensitive = m_module + 1;
+                // uint64_t acts_sensitive = m_module + 1;
+                uint64_t acts_sensitive = 1;
 
                 Acts::GeometryIdentifier moduleGeoId;
                 moduleGeoId.setVolume(acts_volume);
@@ -703,7 +771,6 @@ int RecActsTracking::InitialiseVTX()
 
                 // get the local position of the hit
                 const Acts::Vector3 globalPos{acts_x, acts_y, acts_z};
-                const Acts::Vector3 globalmom{momentum_x, momentum_y, momentum_z};
                 auto acts_local_postion = acts_surface->globalToLocal(geoContext, globalPos, globalmom, onSurfaceTolerance);
                 if (!acts_local_postion.ok()){
                     info() << "Error: failed to get local position for VTX hit " << simcellid << endmsg;
@@ -724,9 +791,10 @@ int RecActsTracking::InitialiseVTX()
                 SpacePointPtrs.push_back(hitExt);
 
                 // create and store the measurement
+                // Cylinder covMatrix[6] = {resU*resU/2, 0, resU*resU/2, 0, 0, resV*resV}
                 Acts::ActsSquareMatrix<2> cov = Acts::ActsSquareMatrix<2>::Identity();
-                cov(0, 0) = std::max<double>(std::abs(acts_global_postion[0] - simhit.getPosition()[0]), eps);
-                cov(1, 1) = std::max<double>(std::abs(acts_global_postion[1] - simhit.getPosition()[1]), eps);
+                cov(0, 0) = std::max<double>(double(std::sqrt(m_covMatrix[2]*2)), eps.value());
+                cov(1, 1) = std::max<double>(double(std::sqrt(m_covMatrix[5])), eps.value());
                 measurements.emplace_back(Acts::Measurement<Acts::BoundIndices, 2>(sl, indices, par, cov));
 
                 // std::vector<std::string> truth_col = {std::to_string(m_layer*2 + m_module), std::to_string(simhit.getPosition()[0]), std::to_string(simhit.getPosition()[1]), std::to_string(simhit.getPosition()[2])};
@@ -736,8 +804,7 @@ int RecActsTracking::InitialiseVTX()
 
             } else {
                 // set acts geometry identifier
-                // VXD_outer_volume_id = 20;
-                uint64_t acts_volume = VXD_outer_volume_id;
+                uint64_t acts_volume = VXD_volume_ids[4];
                 uint64_t acts_boundary = 0;
                 uint64_t acts_layer = 2;
                 uint64_t acts_approach = 0;
@@ -760,7 +827,6 @@ int RecActsTracking::InitialiseVTX()
                 IndexSourceLink::SurfaceAccessor surfaceAccessor{*trackingGeometry};
                 const Acts::Surface* acts_surface = surfaceAccessor(sl);
                 const Acts::Vector3 globalPos{acts_x, acts_y, acts_z};
-                const Acts::Vector3 globalmom{momentum_x, momentum_y, momentum_z};
                 auto acts_local_postion = acts_surface->globalToLocal(geoContext, globalPos, globalmom, onSurfaceTolerance);
                 if (!acts_local_postion.ok()){
                     info() << "Error: failed to get local position for VTX hit " << simcellid << endmsg;
@@ -776,9 +842,10 @@ int RecActsTracking::InitialiseVTX()
                 debug() << "debug surface at: x:" << acts_global_postion[0] << ", y:" << acts_global_postion[1] << ", z:" << acts_global_postion[2] << endmsg;
 
                 // create and store the measurement
+                // Plane covMatrix[6] = {u_direction[0], u_direction[1], resU, v_direction[0], v_direction[1], resV}
                 Acts::ActsSquareMatrix<2> cov = Acts::ActsSquareMatrix<2>::Identity();
-                cov(0, 0) = std::max<double>(std::abs(acts_global_postion[0] - simhit.getPosition()[0]), eps);
-                cov(1, 1) = std::max<double>(std::abs(acts_global_postion[1] - simhit.getPosition()[1]), eps);
+                cov(0, 0) = std::max<double>(double(m_covMatrix[2]), eps.value());
+                cov(1, 1) = std::max<double>(double(m_covMatrix[5]), eps.value());
                 measurements.emplace_back(Acts::Measurement<Acts::BoundIndices, 2>(sl, indices, par, cov));
 
                 // std::vector<std::string> truth_col = {std::to_string(m_layer+4), std::to_string(simhit.getPosition()[0]), std::to_string(simhit.getPosition()[1]), std::to_string(simhit.getPosition()[2])};
@@ -849,6 +916,8 @@ int RecActsTracking::InitialiseSIT()
             double momentum_x = simhit.getMomentum()[0];
             double momentum_y = simhit.getMomentum()[1];
             double momentum_z = simhit.getMomentum()[2];
+            const Acts::Vector3 globalmom{momentum_x, momentum_y, momentum_z};
+            std::array<float, 6> m_covMatrix = hit.getCovMatrix();
 
             dd4hep::rec::ISurface* surface = nullptr;
             auto it = m_sit_surfaces->find(simcellid);
@@ -864,20 +933,12 @@ int RecActsTracking::InitialiseSIT()
                 return 0;
             }
 
-            if (ielem == 0) {
-                min_z = hitSITCol->at(ielem).getPosition()[2];
-            } else {
-                if (std::abs(acts_z - min_z) > 100) {
-                    continue;
-                }
-            }
-
             // set acts geometry identifier
             uint64_t acts_volume = SIT_acts_volume_ids[m_layer];
             uint64_t acts_boundary = 0;
             uint64_t acts_layer = 2;
             uint64_t acts_approach = 0;
-            uint64_t acts_sensitive = m_stave*SIT_module_nums[m_layer]*SIT_sensor_nums + m_module*SIT_sensor_nums + m_sensor + 1;
+            uint64_t acts_sensitive = m_stave*SIT_module_nums[m_layer] + m_module + 1;
 
             Acts::GeometryIdentifier moduleGeoId;
             moduleGeoId.setVolume(acts_volume);
@@ -896,7 +957,6 @@ int RecActsTracking::InitialiseSIT()
             IndexSourceLink::SurfaceAccessor surfaceAccessor{*trackingGeometry};
             const Acts::Surface* acts_surface = surfaceAccessor(sl);
             const Acts::Vector3 globalPos{acts_x, acts_y, acts_z};
-            const Acts::Vector3 globalmom{momentum_x, momentum_y, momentum_z};
             auto acts_local_postion = acts_surface->globalToLocal(geoContext, globalPos, globalmom, onSurfaceTolerance);
             if (!acts_local_postion.ok()){
                 info() << "Error: failed to get local position for SIT hit " << simcellid << endmsg;
@@ -913,8 +973,8 @@ int RecActsTracking::InitialiseSIT()
 
             // create and store the measurement
             Acts::ActsSquareMatrix<2> cov = Acts::ActsSquareMatrix<2>::Identity();
-            cov(0, 0) = std::max<double>(std::abs(acts_global_postion[0] - simhit.getPosition()[0]), eps);
-            cov(1, 1) = std::max<double>(std::abs(acts_global_postion[1] - simhit.getPosition()[1]), eps);
+            cov(0, 0) = std::max<double>(double(m_covMatrix[2]), eps.value());
+            cov(1, 1) = std::max<double>(double(m_covMatrix[5]), eps.value());
             measurements.emplace_back(Acts::Measurement<Acts::BoundIndices, 2>(sl, indices, par, cov));
 
             // std::vector<std::string> truth_col = {std::to_string(m_layer), std::to_string(simhit.getPosition()[0]), std::to_string(simhit.getPosition()[1]), std::to_string(simhit.getPosition()[2])};
diff --git a/Reconstruction/RecActsTracking/src/RecActsTracking.h b/Reconstruction/RecActsTracking/src/RecActsTracking.h
index be7c889ac054830b290f1c255740f05b93074e3c..2bd5a688678be0a676b7e38b608681926042f336 100644
--- a/Reconstruction/RecActsTracking/src/RecActsTracking.h
+++ b/Reconstruction/RecActsTracking/src/RecActsTracking.h
@@ -179,9 +179,25 @@ class RecActsTracking : public GaudiAlgorithm
         Gaudi::Property<std::string> TGeo_path{this, "TGeoFile"};
         Gaudi::Property<std::string> TGeo_config_path{this, "TGeoConfigFile"};
         Gaudi::Property<std::string> MaterialMap_path{this, "MaterialMapFile"};
+        Gaudi::Property<std::string> m_particle{this, "AssumeParticle"};
         Gaudi::Property<double> m_field{this, "Field", 3.0}; // tesla
         Gaudi::Property<double> onSurfaceTolerance{this, "onSurfaceTolerance", 1e-2}; // mm
-
+        Gaudi::Property<double> eps{this, "eps", 1e-5}; // mm
+
+        // seed finder config
+        Gaudi::Property<double> SeedDeltaRMin{this, "SeedDeltaRMin", 4}; // mm
+        Gaudi::Property<double> SeedDeltaRMax{this, "SeedDeltaRMax", 13}; // mm
+        Gaudi::Property<double> SeedRMax{this, "SeedRMax", 30}; // mm
+        Gaudi::Property<double> SeedRMin{this, "SeedRMin", 10}; // mm
+        Gaudi::Property<double> SeedImpactMax{this, "SeedImpactMax", 3}; // mm
+        Gaudi::Property<double> SeedRMinMiddle{this, "SeedRMinMiddle", 14}; // mm
+        Gaudi::Property<double> SeedRMaxMiddle{this, "SeedRMaxMiddle", 24}; // mm
+
+        // CKF config
+        Gaudi::Property<double> CKFchi2Cut{this, "CKFchi2Cut", 20};
+        Gaudi::Property<std::size_t> numMeasurementsCutOff{this, "numMeasurementsCutOff", 1};
+        Gaudi::Property<bool> CKFtwoWay{this, "CKFtwoWay", true};
+        
         SmartIF<IGeomSvc> m_geosvc;
         SmartIF<IChronoStatSvc> chronoStatSvc;
         dd4hep::DDSegmentation::BitFieldCoder *vxd_decoder;
@@ -221,7 +237,6 @@ class RecActsTracking : public GaudiAlgorithm
 
         // utils
         int _nEvt;
-        double eps = 1.0e-05;
         const double _FCT = 2.99792458E-4;
         Acts::Vector3 acts_field_value = Acts::Vector3(0., 0., 3*_FCT); // tesla
         // Acts::Vector3 acts_field_value = Acts::Vector3(0., 0., 3); // tesla
@@ -253,11 +268,11 @@ class RecActsTracking : public GaudiAlgorithm
             0 * Acts::UnitConstants::ns / (Acts::UnitConstants::e * Acts::UnitConstants::GeV)};
         std::array<double, 6> initialVarInflation = {10., 10., 10., 10., 10., 10.};
         Acts::ParticleHypothesis particleHypothesis = Acts::ParticleHypothesis::muon();
+        std::array<std::string, 8> particleNames = {"muon", "pion", "electron", "kaon", "proton", "photon", "geantino", "chargedgeantino"};
         // Acts::ParticleHypothesis particleHypothesis = Acts::ParticleHypothesis::chargedGeantino();
 
         // gid convert configuration
-        std::vector<uint64_t> VXD_inner_volume_ids{16, 17, 18, 19};
-        uint64_t VXD_outer_volume_id = 20;
+        std::vector<uint64_t> VXD_volume_ids{16, 17, 18, 19, 20};
         std::vector<uint64_t> SIT_acts_volume_ids{22, 24, 26};
         std::vector<uint64_t> SIT_module_nums{7, 10, 14};
         uint64_t SIT_sensor_nums = 14;