diff --git a/Tracker/TrackerAlignTools/TrackerAlignGenTools/src/TrackerAlignDBTool.cxx b/Tracker/TrackerAlignTools/TrackerAlignGenTools/src/TrackerAlignDBTool.cxx index 4483eb5b4cd52b31aa70cb915ba6500641297685..227a1d7c2157aa09c54f2803b2654bec924610e0 100644 --- a/Tracker/TrackerAlignTools/TrackerAlignGenTools/src/TrackerAlignDBTool.cxx +++ b/Tracker/TrackerAlignTools/TrackerAlignGenTools/src/TrackerAlignDBTool.cxx @@ -209,8 +209,8 @@ StatusCode TrackerAlignDBTool::createDB() const { const auto iStation = m_sctid->station(ident); const auto iLayer = m_sctid->layer(ident); - const auto iModuleEta = m_sctid->eta_module(ident); - const auto iModulePhi = m_sctid->phi_module(ident); + const auto iModuleEta = m_sctid->eta_module(ident); + const auto iModulePhi = m_sctid->phi_module(ident); int iModule = iModulePhi; if (iModuleEta < 0) iModule +=4; @@ -258,26 +258,31 @@ StatusCode TrackerAlignDBTool::createDB() const auto iStation = m_sctid->station(ident); auto iLayer = m_sctid->layer(ident); - const auto buildKey = [](auto iStation, auto iLayer) { - std::stringstream ss; - ss << iStation << iLayer; - return ss.str(); - }; - - const auto key = buildKey(iStation, iLayer); - if (not (m_alignment.find(key) == m_alignment.end())) { - const std::vector<double> c = m_alignment.value().find(key)->second; - ATH_MSG_VERBOSE("Applying correction for " << key); - ATH_MSG_VERBOSE(c[0] << " " << c[1] << " " << c[2] << " " << c[3] << " " << c[4] << " " << c[5]); - Amg::Translation3D newtranslation(c[0], c[1], c[2]); - Amg::Transform3D alignment = newtranslation * Amg::RotationMatrix3D::Identity(); - alignment *= Amg::AngleAxis3D(c[5], Amg::Vector3D(0.,0.,1.)); - alignment *= Amg::AngleAxis3D(c[4], Amg::Vector3D(0.,1.,0.)); - alignment *= Amg::AngleAxis3D(c[3], Amg::Vector3D(1.,0.,0.)); - - pat->add(ident2, Amg::EigenTransformToCLHEP(alignment)); + const auto buildKey = [](auto iStation, auto iLayer) { + std::stringstream ss; + ss << iStation << iLayer; + return ss.str(); + }; + + const auto key = buildKey(iStation, iLayer); + if (not (m_alignment.find(key) == m_alignment.end())) { + const std::vector<double> c = m_alignment.value().find(key)->second; + ATH_MSG_VERBOSE("Applying correction for " << key); + ATH_MSG_VERBOSE(c[0] << " " << c[1] << " " << c[2] << " " << c[3] << " " << c[4] << " " << c[5]); + Amg::Translation3D newtranslation(c[0], c[1], c[2]); + Amg::Transform3D alignment = newtranslation * Amg::RotationMatrix3D::Identity(); + alignment *= Amg::AngleAxis3D(c[5], Amg::Vector3D(0.,0.,1.)); + alignment *= Amg::AngleAxis3D(c[4], Amg::Vector3D(0.,1.,0.)); + alignment *= Amg::AngleAxis3D(c[3], Amg::Vector3D(1.,0.,0.)); + + Amg::Translation3D newtransl(0,0,element->transform().translation()[2]); + Amg::Transform3D newcorr= newtransl * Amg::RotationMatrix3D::Identity(); + + pat->add(ident2, Amg::EigenTransformToCLHEP(newcorr*alignment*newcorr.inverse())); + +// pat->add(ident2, Amg::EigenTransformToCLHEP(alignment)); } else { - ATH_MSG_VERBOSE("No correction given for " << key); + ATH_MSG_VERBOSE("No correction given for " << key); } } else @@ -294,12 +299,6 @@ StatusCode TrackerAlignDBTool::createDB() const std::string key1 = dirkey(ident1, 1); if ((pat = getTransPtr(key1))) { - // Amg::Translation3D translation(0.1,0.2,0.3); - //Amg::Transform3D globshift=translation*Amg::RotationMatrix3D::Identity(); - //std::cout<<"rotation"<<std::endl; - //std::cout<<globshift.rotation()(0,0)<<" , "<<globshift.rotation()(1,1)<<" , "<<globshift.rotation()(2,2)<<std::endl; - //std::cout<<"translation"<<std::endl; - //std::cout<<globshift.translation()(0,0)<<" , "<<globshift.translation()(1,1)<<" , "<<globshift.translation()(2,2)<<std::endl; Amg::Transform3D globshift; globshift.setIdentity(); for (int station : m_stations) diff --git a/Tracker/TrackerDetDescr/TrackerReadoutGeometry/src/SCT_DetectorManager.cxx b/Tracker/TrackerDetDescr/TrackerReadoutGeometry/src/SCT_DetectorManager.cxx index 33aa094fc5abee616cd7713d054c510eed394960..96acb3c5f306e472c35af834f597f0c2a74c0f86 100755 --- a/Tracker/TrackerDetDescr/TrackerReadoutGeometry/src/SCT_DetectorManager.cxx +++ b/Tracker/TrackerDetDescr/TrackerReadoutGeometry/src/SCT_DetectorManager.cxx @@ -180,6 +180,7 @@ namespace TrackerDD { GeoVAlignmentStore* alignStore) const { if (level == 0) { // 0 - At the element level + std::cout<<"like SCT_DetectorManager::setAlignableTransformDelta 183 level "<<level<<std::endl; // We retrieve it via a hashId. IdentifierHash idHash = m_idHelper->wafer_hash(id); @@ -194,6 +195,7 @@ namespace TrackerDD { SiDetectorElement * element = m_elementCollection[idHash]; if (!element) return false; + std::cout<<"like SCT_DetectorManager::setAlignableTransformDelta 198"<<std::endl; // Its a local transform //See header file for definition of m_isLogical @@ -213,6 +215,7 @@ namespace TrackerDD { } else if (level == 1) { // module level + std::cout<<"like SCT_DetectorManager::setAlignableTransformDelta 218"<<std::endl; // We retrieve it via a hashId. IdentifierHash idHash = m_idHelper->wafer_hash(id); if (!idHash.is_valid()) return false; diff --git a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/python/TrackerSpacePointFormationConfig.py b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/python/TrackerSpacePointFormationConfig.py index 4bd7402d130957407bdf9d3ca3a660b18530060a..d98f18b66a4f4d5a6eb8fa461382b021b10de7b9 100644 --- a/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/python/TrackerSpacePointFormationConfig.py +++ b/Tracker/TrackerRecAlgs/TrackerSpacePointFormation/python/TrackerSpacePointFormationConfig.py @@ -67,7 +67,8 @@ def TrackerSpacePointFinderCfg(flags, **kwargs): """Return ComponentAccumulator for SCT SpacePoints and Output""" acc=TrackerDDSiElementPropertiesTableCondAlgCfg(flags) acc.merge(TrackerSpacePointFinderBasicCfg(flags, **kwargs)) - acc.merge(TrackerSpacePointFinder_OutputCfg(flags)) + if flags.Output.doWriteESD: + acc.merge(TrackerSpacePointFinder_OutputCfg(flags)) return acc def StatisticsCfg(flags, **kwargs): diff --git a/Tracking/Acts/FaserActsGeometry/python/ActsGeometryConfig.py b/Tracking/Acts/FaserActsGeometry/python/ActsGeometryConfig.py index d81e6fd90ce1bd9128b715857840fd93c9fcf126..9b13d866e9ef5808d3953f5a7529683341566aa4 100644 --- a/Tracking/Acts/FaserActsGeometry/python/ActsGeometryConfig.py +++ b/Tracking/Acts/FaserActsGeometry/python/ActsGeometryConfig.py @@ -37,6 +37,7 @@ def ActsTrackingGeometryToolCfg(configFlags, name = "ActsTrackingGeometryTool" ) result = ComponentAccumulator() acc = ActsTrackingGeometrySvcCfg(configFlags) result.merge(acc) + result.merge(ActsAlignmentCondAlgCfg(configFlags)) Acts_ActsTrackingGeometryTool = FaserActsTrackingGeometryTool actsTrackingGeometryTool = Acts_ActsTrackingGeometryTool("TrackingGeometryTool") result.addPublicTool(actsTrackingGeometryTool) @@ -61,7 +62,7 @@ def ActsAlignmentCondAlgCfg(configFlags, name = "ActsAlignmentCondAlg", **kwargs acc = ActsTrackingGeometrySvcCfg(configFlags) result.merge(acc) - Acts_ActsAlignmentCondAlg = CompFactory.ActsAlignmentCondAlg + Acts_ActsAlignmentCondAlg = CompFactory.FaserActsAlignmentCondAlg actsAlignmentCondAlg = Acts_ActsAlignmentCondAlg(name, **kwargs) result.addCondAlgo(actsAlignmentCondAlg) @@ -98,17 +99,6 @@ def ActsMaterialTrackWriterSvcCfg(name="FaserActsMaterialTrackWriterSvc", result.addService(ActsMaterialTrackWriterSvc, primary=True) return result -def ActsMaterialStepConverterToolCfg(name = "ActsMaterialStepConverterTool" ) : - result=ComponentAccumulator() - - Acts_ActsMaterialStepConverterTool = CompFactory.ActsMaterialStepConverterTool - ActsMaterialStepConverterTool = Acts_ActsMaterialStepConverterTool(name) - - from AthenaCommon.Constants import INFO - ActsMaterialStepConverterTool.OutputLevel = INFO - - result.addPublicTool(ActsMaterialStepConverterTool, primary=True) - return result def ActsSurfaceMappingToolCfg(configFlags, name = "FaserActsSurfaceMappingTool" ) : result=ComponentAccumulator() diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsAlignmentCondAlg.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsAlignmentCondAlg.cxx index 5f0735b99c7192d7d761191046157b42340e7cf9..3e38e6fd02c81a67a6f90450b96d074d680006c7 100644 --- a/Tracking/Acts/FaserActsGeometry/src/FaserActsAlignmentCondAlg.cxx +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsAlignmentCondAlg.cxx @@ -108,10 +108,12 @@ StatusCode FaserActsAlignmentCondAlg::execute() { size_t nElems = 0; trkGeom->visitSurfaces([&actsAlignStore, &nElems](const Acts::Surface *srf) { const Acts::DetectorElementBase *detElem = - srf->associatedDetectorElement(); + srf->associatedDetectorElement(); + if(detElem){ const auto *gmde = static_cast<const FaserActsDetectorElement *>(detElem); gmde->storeTransform(actsAlignStore.get()); nElems++; + } }); ATH_MSG_DEBUG("FaserActsAlignmentStore populated for " << nElems << " detector elements"); diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsDetectorElement.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsDetectorElement.cxx index 5545334849da0bb6b068c768773ae4878e52b5f5..59357dfc70de1a9b9d025d2c2bbf2b5a7d0a421b 100644 --- a/Tracking/Acts/FaserActsGeometry/src/FaserActsDetectorElement.cxx +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsDetectorElement.cxx @@ -118,9 +118,10 @@ FaserActsDetectorElement::transform(const Acts::GeometryContext& anygctx) const void FaserActsDetectorElement::storeTransform(FaserActsAlignmentStore* gas) const { - Amg::Transform3D g2l - = m_detElement->getMaterialGeom()->getDefAbsoluteTransform() - * Amg::CLHEPTransformToEigen(m_detElement->recoToHitTransform()); +// Amg::Transform3D g2l +// = m_detElement->getMaterialGeom()->getDefAbsoluteTransform() +// * Amg::CLHEPTransformToEigen(m_detElement->recoToHitTransform()); + Amg::Transform3D g2l = m_detElement->transform() ; // need to make sure translation has correct units g2l.translation() *= length_unit; diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationTool.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationTool.cxx index 0e92508b08f01b792c15913a45f37cda8c0eb5c0..d31fe8d3c11e804e115aef2cc6dfc08a2354b9e7 100644 --- a/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationTool.cxx +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsExtrapolationTool.cxx @@ -126,8 +126,7 @@ FaserActsExtrapolationTool::propagationSteps(const EventContext& ctx, Acts::MagneticFieldContext mctx = getMagneticFieldContext(ctx); const FaserActsGeometryContext& gctx - //= m_trackingGeometryTool->getGeometryContext(ctx); - = m_trackingGeometryTool->getNominalGeometryContext(); + = m_trackingGeometryTool->getGeometryContext(ctx); auto anygctx = gctx.context(); @@ -200,8 +199,7 @@ FaserActsExtrapolationTool::propagate(const EventContext& ctx, Acts::MagneticFieldContext mctx = getMagneticFieldContext(ctx); const FaserActsGeometryContext& gctx - //= m_trackingGeometryTool->getGeometryContext(ctx); - = m_trackingGeometryTool->getNominalGeometryContext(); + = m_trackingGeometryTool->getGeometryContext(ctx); auto anygctx = gctx.context(); @@ -319,8 +317,7 @@ FaserActsExtrapolationTool::propagate(const EventContext& ctx, ATH_MSG_VERBOSE(name() << "::" << __FUNCTION__ << " begin"); Acts::MagneticFieldContext mctx = getMagneticFieldContext(ctx); - const FaserActsGeometryContext& gctx = m_trackingGeometryTool->getNominalGeometryContext(); -// const FaserActsGeometryContext& gctx = m_trackingGeometryTool->getGeometryContext(ctx); + const FaserActsGeometryContext& gctx = m_trackingGeometryTool->getGeometryContext(ctx); auto anygctx = gctx.context(); diff --git a/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx index a45c7c06d37214248a19b189ca40886339c9f1b4..aef43cf4022b059edf059d614d22929b84644871 100644 --- a/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx +++ b/Tracking/Acts/FaserActsGeometry/src/FaserActsTrackingGeometrySvc.cxx @@ -63,7 +63,7 @@ FaserActsTrackingGeometrySvc::initialize() //get all the subdetectors const GeoModelExperiment* theExpt = nullptr; - ATH_CHECK( m_detStore->retrieve( theExpt ,"FASER")); + ATH_CHECK( m_detStore->retrieve( theExpt )); const GeoVDetectorManager *vetoManager = theExpt->getManager("Veto"); const GeoVDetectorManager *triggerManager = theExpt->getManager("Trigger"); const GeoVDetectorManager *dipoleManager = theExpt->getManager("Dipole"); diff --git a/Tracking/Acts/FaserActsKalmanFilter/CMakeLists.txt b/Tracking/Acts/FaserActsKalmanFilter/CMakeLists.txt index f93c094287a4966f84689abaa2615da2b2ef8882..874d604249142448e76634c8dac9a8d0ef1db8f5 100755 --- a/Tracking/Acts/FaserActsKalmanFilter/CMakeLists.txt +++ b/Tracking/Acts/FaserActsKalmanFilter/CMakeLists.txt @@ -29,6 +29,7 @@ atlas_add_component(FaserActsKalmanFilter CircleFit.h CircleFitTrackSeedTool.h CKF2.h + CKF2Alignment.h CombinatorialKalmanFilterAlg.h EffPlotTool.h FASERSourceLink.h @@ -73,6 +74,7 @@ atlas_add_component(FaserActsKalmanFilter src/CircleFit.cxx src/CircleFitTrackSeedTool.cxx src/CKF2.cxx + src/CKF2Alignment.cxx src/CreateTrkTrackTool.h src/CreateTrkTrackTool.cxx # src/ClusterTrackSeedTool.cxx diff --git a/Tracking/Acts/FaserActsKalmanFilter/python/CKF2Alignment.py b/Tracking/Acts/FaserActsKalmanFilter/python/CKF2Alignment.py new file mode 100644 index 0000000000000000000000000000000000000000..eb5f84da0eb61bf7031090cf49911b9728ea82d0 --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/python/CKF2Alignment.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python + +import sys +from AthenaCommon.Logging import log, logging +from AthenaCommon.Constants import INFO +from AthenaCommon.Configurable import Configurable +from CalypsoConfiguration.AllConfigFlags import ConfigFlags +from AthenaConfiguration.TestDefaults import defaultTestFiles +from CalypsoConfiguration.MainServicesConfig import MainServicesCfg +from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg +from AthenaPoolCnvSvc.PoolWriteConfig import PoolWriteCfg +from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg +from TrackerPrepRawDataFormation.TrackerPrepRawDataFormationConfig import FaserSCT_ClusterizationCfg +from TrackerSpacePointFormation.TrackerSpacePointFormationConfig import TrackerSpacePointFinderCfg +from TrackerSegmentFit.TrackerSegmentFitConfig import SegmentFitAlgCfg +from FaserActsKalmanFilter.GhostBustersConfig import GhostBustersCfg +from TruthSeededTrackFinder.TruthSeededTrackFinderConfig import TruthSeededTrackFinderCfg +from FaserSCT_GeoModel.FaserSCT_GeoModelConfig import FaserSCT_GeometryCfg +from FaserActsGeometry.ActsGeometryConfig import ActsTrackingGeometryToolCfg +from FaserActsGeometry.ActsGeometryConfig import ActsExtrapolationToolCfg +from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator +from MagFieldServices.MagFieldServicesConfig import MagneticFieldSvcCfg +from AthenaConfiguration.ComponentFactory import CompFactory + +THistSvc=CompFactory.getComps("THistSvc") + +CKF2Alignment, FaserActsExtrapolationTool, FaserActsTrackingGeometryTool=CompFactory.getComps("CKF2Alignment", "FaserActsExtrapolationTool","FaserActsTrackingGeometryTool") +from FaserActsGeometry.ActsGeometryConfig import ActsTrackingGeometrySvcCfg + + +def CKF2AlignmentCfg(flags, **kwargs): + acc = FaserSCT_GeometryCfg(flags) + acc.merge(MagneticFieldSvcCfg(flags)) + result, actsTrackingGeometryTool = ActsTrackingGeometryToolCfg(flags) +# acts_tracking_geometry_svc = ActsTrackingGeometrySvcCfg(flags) + acc.merge(result) + track_seed_tool = CompFactory.CircleFitTrackSeedTool() + #remove the IFT in the track finding or not + track_seed_tool.removeIFT = False + sigma_loc0 = 1.9e-2 + sigma_loc1 = 9e-1 + sigma_phi = 3.3e-2 + sigma_theta = 2.9e-4 + p = 1000 + sigma_p = 0.1 * p + sigma_qop = sigma_p / (p * p) + initial_variance_inflation = [100, 100, 100, 100, 1000] + track_seed_tool.covLoc0 = initial_variance_inflation[0] * sigma_loc1 * sigma_loc1 + track_seed_tool.covLoc1 = initial_variance_inflation[1] * sigma_loc0 * sigma_loc0 + track_seed_tool.covPhi = initial_variance_inflation[2] * sigma_phi * sigma_phi + track_seed_tool.covTheta = initial_variance_inflation[3] * sigma_theta * sigma_theta + track_seed_tool.covQOverP = initial_variance_inflation[4] * sigma_qop * sigma_qop + track_seed_tool.std_cluster = 0.0231 + track_seed_tool.TrackCollection = "Segments" + # useless in the alignment, will clean them up + trajectory_states_writer_tool = CompFactory.RootTrajectoryStatesWriterTool() + trajectory_states_writer_tool.noDiagnostics = kwargs.pop("noDiagnostics", True) + trajectory_states_writer_tool1 = CompFactory.RootTrajectoryStatesWriterTool() + trajectory_states_writer_tool1.noDiagnostics = kwargs.pop("noDiagnostics", True) + trajectory_states_writer_tool1.FilePath = "/pool/track_states_ckf1_10root" + + trajectory_summary_writer_tool = CompFactory.RootTrajectorySummaryWriterTool() + trajectory_summary_writer_tool.noDiagnostics = kwargs.pop("noDiagnostics", True) + trajectory_summary_writer_tool1 = CompFactory.RootTrajectorySummaryWriterTool() + trajectory_summary_writer_tool1.FilePath = "/pool/track_summary_ckf1_0.root" + trajectory_summary_writer_tool1.noDiagnostics = kwargs.pop("noDiagnostics", True) + actsExtrapolationTool = CompFactory.FaserActsExtrapolationTool("FaserActsExtrapolationTool") + actsExtrapolationTool.MaxSteps = 1000 + actsExtrapolationTool.TrackingGeometryTool = actsTrackingGeometryTool + acc.merge(result) + + trajectory_performance_writer_tool = CompFactory.PerformanceWriterTool("PerformanceWriterTool") + trajectory_performance_writer_tool.ExtrapolationTool = actsExtrapolationTool + trajectory_performance_writer_tool.noDiagnostics = kwargs.pop("noDiagnostics", True) + ckf2fit = CompFactory.CKF2Alignment(**kwargs) + #biased residual or unbiased + ckf2fit.BiasedResidual = False + ckf2fit.ExtrapolationTool = actsExtrapolationTool + ckf2fit.TrackingGeometryTool=actsTrackingGeometryTool + kalman_fitter1 = CompFactory.KalmanFitterTool(name="fitterTool1") + kalman_fitter1.noDiagnostics = True + kalman_fitter1.ActsLogging = "INFO" + kalman_fitter1.SummaryWriter = False + kalman_fitter1.StatesWriter = False + kalman_fitter1.SeedCovarianceScale = 10 + kalman_fitter1.isMC = False + kalman_fitter1.RootTrajectoryStatesWriterTool = trajectory_states_writer_tool1 + kalman_fitter1.RootTrajectorySummaryWriterTool = trajectory_summary_writer_tool1 + ckf2fit.KalmanFitterTool1 = kalman_fitter1 + ckf2fit.TrackSeed = track_seed_tool + ckf2fit.ActsLogging = "INFO" + ckf2fit.isMC = False + ckf2fit.nMax = 10 + ckf2fit.chi2Max = 100000 + ckf2fit.maxSteps = 5000 + histSvc= CompFactory.THistSvc() + # output ntuple + histSvc.Output += [ "CKF2Alignment DATAFILE='kfalignment_mc.root' OPT='RECREATE'"] + acc.addService(histSvc) + acc.addEventAlgo(ckf2fit) + return acc + +if __name__ == "__main__": + +# log.setLevel(INFO) + Configurable.configurableRun3Behavior = True + + # Configure + ConfigFlags.Input.Files = [ '' ] #input RDO + ConfigFlags.IOVDb.GlobalTag = "OFLCOND-FASER-03" + ConfigFlags.GeoModel.FaserVersion = "FASERNU-03" # FASER cosmic ray geometry (station 2 only) + ConfigFlags.TrackingGeometry.MaterialSource = "material-maps.json" # material map + ConfigFlags.Input.isMC = True + ConfigFlags.GeoModel.Align.Dynamic = False + ConfigFlags.Input.ProjectName = "data21" # Needed to bypass autoconfig + ConfigFlags.Beam.NumberOfCollisions = 0. + ConfigFlags.addFlag("Input.InitialTimeStamp", 0) + ConfigFlags.Exec.MaxEvents = -1 + ConfigFlags.Output.doWriteESD = False + #ConfigFlags.Concurrency.NumThreads = 1 +# ConfigFlags.addFlag("Alignment.Output", "ckf_alignment.root") + ConfigFlags.fillFromArgs(sys.argv[1:]) + ConfigFlags.dump() + ConfigFlags.lock() + + from FaserGeoModel.FaserGeoModelConfig import FaserGeometryCfg + # Core components + acc = MainServicesCfg(ConfigFlags) + acc.merge(FaserGeometryCfg(ConfigFlags)) + acc.merge(PoolReadCfg(ConfigFlags)) + acc.merge(PoolWriteCfg(ConfigFlags)) + from FaserByteStreamCnvSvc.FaserByteStreamCnvSvcConfig import FaserByteStreamCnvSvcCfg + # Inner Detector + acc.merge(FaserSCT_ClusterizationCfg(ConfigFlags)) + acc.merge(TrackerSpacePointFinderCfg(ConfigFlags)) + acc.merge(SegmentFitAlgCfg(ConfigFlags, SharedHitFraction=0.61, MinClustersPerFit=5, TanThetaXZCut=0.083)) + acc.merge(GhostBustersCfg(ConfigFlags)) + acc.merge(CKF2AlignmentCfg(ConfigFlags)) + logging.getLogger('forcomps').setLevel(INFO) + acc.foreach_component("*").OutputLevel = INFO + acc.foreach_component("*ClassID*").OutputLevel = INFO + + # Execute and finish + sc = acc.run() + sys.exit(not sc.isSuccess()) diff --git a/Tracking/Acts/FaserActsKalmanFilter/python/GhostBustersConfig.py b/Tracking/Acts/FaserActsKalmanFilter/python/GhostBustersConfig.py index ebe56d179393fcf3f51cb8df510271fbf5a85ebe..57d7c035d2fe56f3ec62a4a9c0013421c37b57ff 100644 --- a/Tracking/Acts/FaserActsKalmanFilter/python/GhostBustersConfig.py +++ b/Tracking/Acts/FaserActsKalmanFilter/python/GhostBustersConfig.py @@ -26,7 +26,8 @@ def GhostBustersCfg(flags, **kwargs): acts_tracking_geometry_svc = ActsTrackingGeometrySvcCfg(flags) acc.merge(acts_tracking_geometry_svc ) acc.addEventAlgo(CompFactory.GhostBusters(**kwargs)) - acc.merge(GhostBusters_OutputCfg(flags)) + if flags.Output.doWriteESD: + acc.merge(GhostBusters_OutputCfg(flags)) # thistSvc = CompFactory.THistSvc() # thistSvc.Output += ["HIST2 DATAFILE='GhostBusters.root' OPT='RECREATE'"] diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/CKF2Alignment.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/CKF2Alignment.cxx new file mode 100755 index 0000000000000000000000000000000000000000..afd377fc5effaa67f7c9e949bf6ad31c2bddd665 --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/src/CKF2Alignment.cxx @@ -0,0 +1,1405 @@ +#include "CKF2Alignment.h" + +#include "StoreGate/ReadHandle.h" +#include "StoreGate/ReadCondHandleKey.h" +#include "TrackerSpacePoint/FaserSCT_SpacePointCollection.h" +#include "TrackerSpacePoint/FaserSCT_SpacePoint.h" +#include "TrackerIdentifier/FaserSCT_ID.h" +#include "TrkPrepRawData/PrepRawData.h" +#include "TrackerPrepRawData/FaserSCT_Cluster.h" +#include "TrackerRIO_OnTrack/FaserSCT_ClusterOnTrack.h" +#include "TrkRIO_OnTrack/RIO_OnTrack.h" +#include "TrkSurfaces/Surface.h" +#include "Identifier/Identifier.h" +#include "Acts/Geometry/GeometryIdentifier.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "FaserActsKalmanFilter/IndexSourceLink.h" +#include "FaserActsKalmanFilter/Measurement.h" +#include "FaserActsRecMultiTrajectory.h" +#include "TrackSelection.h" +#include <algorithm> + +#include "FaserActsGeometry/FASERMagneticFieldWrapper.h" + +#include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/Navigator.hpp" +#include "Acts/Surfaces/PerigeeSurface.hpp" +#include "Acts/Surfaces/PlaneSurface.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" +#include "Acts/MagneticField/MagneticFieldContext.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/TrackFitting/GainMatrixSmoother.hpp" +#include "Acts/TrackFitting/GainMatrixUpdater.hpp" + + +#include "Acts/EventData/Measurement.hpp" +#include "Acts/Definitions/Units.hpp" +#include "TFile.h" +#include "TTree.h" +#include "TMath.h" +#include "TMatrixDSym.h" +#include "TMatrixD.h" +#include <fstream> +#include <iostream> + +size_t CKF2Alignment::TrajectoryInfo::nClusters {0}; + +using TrajectoriesContainer = std::vector<FaserActsRecMultiTrajectory>; + +using namespace Acts::UnitLiterals; + +CKF2Alignment::CKF2Alignment( + const std::string& name, ISvcLocator* pSvcLocator) + : AthAlgorithm(name, pSvcLocator), m_thistSvc("THistSvc", name) {} + + + StatusCode CKF2Alignment::initialize() { + ATH_CHECK(m_fieldCondObjInputKey.initialize()); + ATH_CHECK(m_trackingGeometryTool.retrieve()); + ATH_CHECK(m_extrapolationTool.retrieve()); + ATH_CHECK(m_trackSeedTool.retrieve()); + ATH_CHECK(m_kalmanFitterTool1.retrieve()); + ATH_CHECK(m_createTrkTrackTool.retrieve()); + ATH_CHECK(detStore()->retrieve(m_idHelper,"FaserSCT_ID")); + m_fit = makeTrackFinderFunction(m_trackingGeometryTool->trackingGeometry(), + m_resolvePassive, m_resolveMaterial, m_resolveSensitive); + m_kf = makeTrackFitterFunction(m_trackingGeometryTool->trackingGeometry()); + // FIXME fix Acts logging level + if (m_actsLogging == "VERBOSE") { + m_logger = Acts::getDefaultLogger("KalmanFitter", Acts::Logging::VERBOSE); + } else if (m_actsLogging == "DEBUG") { + m_logger = Acts::getDefaultLogger("KalmanFitter", Acts::Logging::DEBUG); + } else { + m_logger = Acts::getDefaultLogger("KalmanFitter", Acts::Logging::INFO); + } + CHECK(m_thistSvc.retrieve()); + m_tree= new TTree("trackParam","tree"); + initializeTree(); + CHECK(m_thistSvc->regTree("/CKF2Alignment/trackParam",m_tree)); + m_tree->AutoSave(); + return StatusCode::SUCCESS; + } + + +StatusCode CKF2Alignment::execute() { + clearVariables(); + const EventContext& ctx = Gaudi::Hive::currentContext(); + m_numberOfEvents++; + + ATH_MSG_DEBUG("get the tracking geometry"); + bool save=false; + std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry + = m_trackingGeometryTool->trackingGeometry(); + + const FaserActsGeometryContext& faserActsGeometryContext = m_trackingGeometryTool->getGeometryContext(); + auto gctx = faserActsGeometryContext.context(); + Acts::MagneticFieldContext magFieldContext = getMagneticFieldContext(ctx); + Acts::CalibrationContext calibContext; + ATH_MSG_DEBUG("get the seed"); + + CHECK(m_trackSeedTool->run()); + std::shared_ptr<const Acts::Surface> initialSurface = + m_trackSeedTool->initialSurface(); + std::shared_ptr<std::vector<Acts::CurvilinearTrackParameters>> initialParameters = + m_trackSeedTool->initialTrackParameters(); + std::shared_ptr<std::vector<IndexSourceLink>> sourceLinks = + m_trackSeedTool->sourceLinks(); + double origin = m_trackSeedTool->targetZPosition(); + + ATH_MSG_DEBUG("get the output of seeding"); + std::shared_ptr<std::vector<Measurement>> measurements = m_trackSeedTool->measurements(); + std::shared_ptr<std::vector<const Tracker::FaserSCT_Cluster*>> clusters = m_trackSeedTool->clusters(); + std::vector<const Tracker::FaserSCT_Cluster*> clusters_sta0; + clusters_sta0.clear(); + std::shared_ptr<std::vector<const Tracker::FaserSCT_SpacePoint*>> spacePoints = m_trackSeedTool->spacePoints(); + std::shared_ptr<std::vector<std::array<std::vector<const Tracker::FaserSCT_Cluster*>, 3>>> seedClusters = m_trackSeedTool->seedClusters(); + + TrajectoryInfo::nClusters = sourceLinks->size(); + TrajectoriesContainer trajectories; + trajectories.reserve(initialParameters->size()); + if(sourceLinks->size()<15||sourceLinks->size()>40)return StatusCode::SUCCESS; + ATH_MSG_DEBUG("size of clusters/sourcelinks "<<clusters->size()<<"/"<<sourceLinks->size()); + + Acts::PropagatorPlainOptions pOptions; + pOptions.maxSteps = m_maxSteps; + + Acts::MeasurementSelector::Config measurementSelectorCfg = { + {Acts::GeometryIdentifier(), {m_chi2Max, m_nMax}}, + }; + + + // Set the CombinatorialKalmanFilter options + CKF2Alignment::TrackFinderOptions options( + gctx, magFieldContext, calibContext, + IndexSourceLinkAccessor(), MeasurementCalibrator(*measurements), + Acts::MeasurementSelector(measurementSelectorCfg), + Acts::LoggerWrapper{*m_logger}, pOptions, &(*initialSurface)); + + // Perform the track finding for all initial parameters + m_numberOfTrackSeeds += initialParameters->size(); + ATH_MSG_DEBUG("Invoke track finding with " << initialParameters->size() << " seeds."); + IndexSourceLinkContainer tmp; + for (const auto& sl : *sourceLinks) { + tmp.emplace_hint(tmp.end(), sl); + } + + for (const auto& init : *initialParameters) { + ATH_MSG_DEBUG(" position: " << init.position(gctx).transpose()); + ATH_MSG_DEBUG(" momentum: " << init.momentum().transpose()); + ATH_MSG_DEBUG(" charge: " << init.charge()); + } + + ATH_MSG_DEBUG("sourcelink size "<<tmp.size()); + auto results = (*m_fit)(tmp, *initialParameters, options); + + // results contain a MultiTrajectory for each track seed with a trajectory of each branch of the CKF. + // To simplify the ambiguity solving a list of MultiTrajectories is created, each containing only a single track. + std::list<TrajectoryInfo> allTrajectories; + for (auto &result : results) { + if (not result.ok()) { + continue; + } + CKFResult ckfResult = result.value(); + for (size_t trackTip : ckfResult.lastMeasurementIndices) { + allTrajectories.emplace_back(TrajectoryInfo(FaserActsRecMultiTrajectory( + ckfResult.fittedStates, {trackTip}, {{trackTip, ckfResult.fittedParameters.at(trackTip)}}))); + } + } + m_numberOfFittedTracks += allTrajectories.size(); + + // the list of MultiTrajectories is sorted by the number of measurements using the chi2 value as a tie-breaker + allTrajectories.sort([](const TrajectoryInfo &left, const TrajectoryInfo &right) { + if (left.nMeasurements > right.nMeasurements) return true; + if (left.nMeasurements < right.nMeasurements) return false; + if (left.chi2 < right.chi2) return true; + else return false; + }); + + // select all tracks with at least 13 heats and with 6 or less shared hits, starting from the best track + // TODO use Gaudi parameters for the number of hits and shared hits + // TODO allow shared hits only in the first station? + std::vector<FaserActsRecMultiTrajectory> selectedTrajectories {}; + while (not allTrajectories.empty()) { + TrajectoryInfo selected = allTrajectories.front(); + selectedTrajectories.push_back(selected.trajectory); + allTrajectories.remove_if([&](const TrajectoryInfo &p) { + return (p.nMeasurements <= 12) || ((p.clusterSet & selected.clusterSet).count() > 6); + }); + } + + + //only use the first track + int trackid=0; + for (const FaserActsRecMultiTrajectory &traj : selectedTrajectories) { + if(trackid>0)continue; + trackid++; + const auto& mj = traj.multiTrajectory(); + const auto& trackTips = traj.tips(); + if(trackTips.empty())continue; + auto& trackTip = trackTips.front(); + auto trajState = Acts::MultiTrajectoryHelpers::trajectoryState(mj, trackTip); + if(trajState.nMeasurements<15)continue; + + const auto params = traj.trackParameters(traj.tips().front()); + ATH_MSG_DEBUG("Fitted parameters"); + ATH_MSG_DEBUG(" params: " << params.parameters().transpose()); + ATH_MSG_DEBUG(" position: " << params.position(gctx).transpose()); + ATH_MSG_DEBUG(" momentum: " << params.momentum().transpose()); + ATH_MSG_DEBUG(" charge: " << params.charge()); + ATH_MSG_VERBOSE("checkte track"); + std::vector<double> t_align_stationId_sp; + std::vector<double> t_align_centery_sp; + std::vector<double> t_align_layerId_sp; + std::vector<double> t_align_moduleId_sp; + std::vector<double> t_align_clustersize_sp; + std::vector<double> t_align_stereoId; + std::vector<double> t_align_global_residual_y_sp; + std::vector<double> t_align_global_measured_y_sp; + std::vector<double> t_align_global_measured_x_sp; + std::vector<double> t_align_global_measured_z_sp; + std::vector<double> t_align_global_measured_ye_sp; + std::vector<double> t_align_global_fitted_ye_sp; + std::vector<double> t_align_global_fitted_y_sp; + std::vector<double> t_align_global_fitted_x_sp; + std::vector<double> t_align_local_residual_x_sp; + std::vector<double> t_align_unbiased; + std::vector<double> t_align_local_pull_x_sp; + std::vector<double> t_align_local_measured_x_sp; + std::vector<double> t_align_local_measured_xe_sp; + std::vector<double> t_align_local_fitted_xe_sp; + std::vector<double> t_align_local_fitted_x_sp; + std::vector<double> t_align_derivation_x_x; + std::vector<double> t_align_derivation_x_y; + std::vector<double> t_align_derivation_x_z; + std::vector<double> t_align_derivation_x_rx; + std::vector<double> t_align_derivation_x_ry; + std::vector<double> t_align_derivation_x_rz; + std::vector<double> t_align_derivation_global_y_x; + std::vector<double> t_align_derivation_global_y_y; + std::vector<double> t_align_derivation_global_y_z; + std::vector<double> t_align_derivation_global_y_rx; + std::vector<double> t_align_derivation_global_y_ry; + std::vector<double> t_align_derivation_global_y_rz; + bool foundift=false; + std::unique_ptr<const Acts::BoundTrackParameters> ini_Param=nullptr; + //get residual from ACTS + if(m_biased){ + mj.visitBackwards(trackTip, [&](const auto &state) { + /// Only fill the track states with non-outlier measurement + auto typeFlags = state.typeFlags(); + if (not typeFlags.test(Acts::TrackStateFlag::MeasurementFlag) and not typeFlags.test(Acts::TrackStateFlag::OutlierFlag)) + { + return true; + } + + const auto& surface = state.referenceSurface(); + Acts::BoundVector meas = state.projector().transpose() * state.calibrated(); + Acts::Vector2 local(meas[Acts::eBoundLoc0], meas[Acts::eBoundLoc1]); + const Acts::Vector3 dir = Acts::makeDirectionUnitFromPhiTheta(meas[Acts::eBoundPhi], meas[Acts::eBoundTheta]); + Acts::Vector3 mom(1, 1, 1); + Acts::Vector3 global = surface.localToGlobal(gctx, local, dir); + if (state.hasSmoothed()) + { + Acts::BoundTrackParameters parameter( + state.referenceSurface().getSharedPtr(), + state.smoothed(), + state.smoothedCovariance()); + auto covariance = state.smoothedCovariance(); + + /// Local hit residual info + auto H = state.effectiveProjector(); + auto resCov = state.effectiveCalibratedCovariance() + + H * covariance * H.transpose(); + auto residual = state.effectiveCalibrated() - H * state.smoothed(); + + if (state.hasUncalibrated()) { + const Tracker::FaserSCT_Cluster* cluster = state.uncalibrated().hit(); + auto trans2 = cluster->detectorElement()->surface().transform(); + auto trans1 = trans2; + Identifier id = cluster->identify(); + int istation = m_idHelper->station(id); + int ilayer = m_idHelper->layer(id); + int stereoid = m_idHelper->side(id); + if(stereoid==1){ + trans1=cluster->detectorElement()->otherSide()->surface().transform(); + } + ATH_MSG_DEBUG(" save the residual "<<residual(Acts::eBoundLoc0)); + const auto iModuleEta = m_idHelper->eta_module(id); + const auto iModulePhi = m_idHelper->phi_module(id); + int iModule = iModulePhi; + if (iModuleEta < 0) iModule +=4; + ATH_MSG_DEBUG("ID "<<istation<<"/"<<ilayer<<"/"<<iModule<<"/"<<stereoid<<"/"<<ilayer); + t_align_stationId_sp.push_back(istation); + t_align_centery_sp.push_back(cluster->detectorElement()->center().y()); + t_align_layerId_sp.push_back(ilayer); + t_align_moduleId_sp.push_back(iModule); + t_align_clustersize_sp.push_back(cluster->rdoList().size()); + t_align_stereoId.push_back(stereoid); + t_align_global_measured_x_sp.push_back(cluster->globalPosition().x()); + t_align_global_measured_y_sp.push_back(cluster->globalPosition().y()); + t_align_global_measured_z_sp.push_back(cluster->globalPosition().z()); + t_align_global_fitted_x_sp.push_back(global.x()); + t_align_global_fitted_y_sp.push_back(global.y()); + t_align_local_residual_x_sp.push_back(residual(Acts::eBoundLoc0)); + t_align_unbiased.push_back(0); + t_align_local_pull_x_sp.push_back(residual(Acts::eBoundLoc0)/sqrt(resCov(Acts::eBoundLoc0, Acts::eBoundLoc0))); + t_align_local_measured_x_sp.push_back(cluster->localPosition().x()); + t_align_local_measured_xe_sp.push_back(sqrt(cluster->localCovariance()(0,0))); + t_align_local_fitted_xe_sp.push_back(sqrt(covariance(Acts::eBoundLoc0, Acts::eBoundLoc0))); + t_align_local_fitted_x_sp.push_back(meas[Acts::eBoundLoc0]); + save=true; + Amg::Vector2D local_mea=cluster->localPosition() ; + t_align_derivation_x_x.push_back(getDerivation(ctx, parameter, trans1,local_mea, 0, stereoid, trans2, 0)); + t_align_derivation_x_y.push_back(getDerivation(ctx, parameter, trans1,local_mea, 1, stereoid, trans2, 0)); + t_align_derivation_x_z.push_back(getDerivation(ctx, parameter, trans1,local_mea, 2, stereoid, trans2, 0)); + t_align_derivation_x_rx.push_back(getDerivation(ctx, parameter, trans1,local_mea, 3, stereoid, trans2, 0)); + t_align_derivation_x_ry.push_back(getDerivation(ctx, parameter, trans1,local_mea, 4, stereoid, trans2, 0)); + t_align_derivation_x_rz.push_back(getDerivation(ctx, parameter, trans1,local_mea, 5, stereoid, trans2, 0)); + t_align_derivation_global_y_x.push_back(getDerivation(ctx, parameter, trans1,local_mea, 0, stereoid, trans2, 1)); + t_align_derivation_global_y_y.push_back(getDerivation(ctx, parameter, trans1,local_mea, 1, stereoid, trans2, 1)); + t_align_derivation_global_y_z.push_back(getDerivation(ctx, parameter, trans1,local_mea, 2, stereoid, trans2, 1)); + t_align_derivation_global_y_rx.push_back(getDerivation(ctx, parameter, trans1,local_mea, 3, stereoid, trans2, 1)); + t_align_derivation_global_y_ry.push_back(getDerivation(ctx, parameter, trans1,local_mea, 4, stereoid, trans2, 1)); + t_align_derivation_global_y_rz.push_back(getDerivation(ctx, parameter, trans1,local_mea, 5, stereoid, trans2, 1)); + ATH_MSG_VERBOSE("local derivation "<<t_align_derivation_x_x.back()<<" "<<t_align_derivation_x_y.back()<<" "<<t_align_derivation_x_z.back()<<" "<<t_align_derivation_x_rx.back()<<" "<<t_align_derivation_x_ry.back()<<" "<<t_align_derivation_x_rz.back()); + ATH_MSG_VERBOSE("global derivation "<<t_align_derivation_global_y_x.back()<<" "<<t_align_derivation_global_y_y.back()<<" "<<t_align_derivation_global_y_z.back()<<""<<t_align_derivation_global_y_rx.back()<<" "<<t_align_derivation_global_y_ry.back()<<" "<<t_align_derivation_global_y_rz.back()); + //get the residual for IFT + if(istation==1&&ilayer==0&&!foundift){ + Amg::Transform3D ini_trans = Amg::Translation3D(0,0, -1910.) * Amg::RotationMatrix3D::Identity(); + auto ini_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(ini_trans, std::make_shared<const Acts::RectangleBounds>(1000.,1000.)); + ini_Param = m_extrapolationTool->propagate( ctx, parameter, *ini_surface, Acts::backward); + //std::unique_ptr<const Acts::BoundTrackParameters> ini_Param = m_extrapolationTool->propagate( ctx, parameter, *ini_surface, Acts::backward); + //find the closet cluster + if(ini_Param!=nullptr){ + for(int i=0;i<3;i++){ + for(int st=0;st<2;st++){ + double chisq=999.; + size_t iclus=999; + double fitx=-999.; + double fity=-999.; + double gfitx=-999.; + double gfity=-999.; + double resi=-999.; + for(size_t ic =0 ;ic <clusters->size();ic++){ + auto cluster = clusters->at(ic); + Identifier id = cluster->identify(); + int jstation = m_idHelper->station(id); + int jlayer = m_idHelper->layer(id); + if(jstation!=0||jlayer!=i)continue; + int jstereoid = m_idHelper->side(id); + if(st==0){if(jstereoid==1)continue;} + if(st==1){if(jstereoid!=1)continue;} + auto trans2 = cluster->detectorElement()->surface().transform(); + Amg::Transform3D shift_trans = Amg::Translation3D(0,0, cluster->globalPosition().z()) * Amg::RotationMatrix3D::Identity(); + auto shift_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(shift_trans, std::make_shared<const Acts::RectangleBounds>(1000.,1000.)); + auto shift_Param = m_extrapolationTool->propagate( ctx, *ini_Param, *shift_surface); + if(shift_Param!=nullptr){ + auto shift_parameter = shift_Param->parameters(); + Amg::Vector2D local_m(shift_parameter[Acts::eBoundLoc0],shift_parameter[Acts::eBoundLoc1]); + Amg::Vector3D glopos(local_m.x(),local_m.y(),cluster->globalPosition().z()); + auto localpos=trans2.inverse()*glopos; + ATH_MSG_DEBUG("looping cluster "<<local_m.x()<<" "<<local_m.y()<<" : "<<cluster->globalPosition()); + ATH_MSG_DEBUG("local cluster "<<localpos.x()<<" "<<localpos.y()<<" : "<<cluster->localPosition()); + double dist2 =(glopos.x()-cluster->globalPosition().x())*(glopos.x()-cluster->globalPosition().x())/40./40.+(glopos.y()-cluster->globalPosition().y())*(glopos.y()-cluster->globalPosition().y()); + if(dist2<chisq){ + chisq=dist2; + iclus=ic; + fitx=localpos.x(); + fity=localpos.y(); + gfitx=glopos.x(); + gfity=glopos.y(); + resi=cluster->localPosition().x() - localpos.x(); + } + } + } + if(iclus>200)continue; + clusters_sta0.push_back(clusters->at(iclus)); + foundift=true; + ATH_MSG_DEBUG(" local position "<<fitx<<" "<<fity<<" : "<<clusters->at(iclus)->localPosition()); + ATH_MSG_DEBUG(" global position "<<gfitx<<" "<<gfity<<" : "<<clusters->at(iclus)->globalPosition()); + Amg::Vector3D localresi(clusters->at(iclus)->localPosition().x()-fitx,clusters->at(iclus)->localPosition().y()-fity,0.); + auto gloresi=clusters->at(iclus)->detectorElement()->surface().transform()*localresi; + ATH_MSG_DEBUG(" local/global residual "<<localresi.x()<<" "<<localresi.y()<<" : "<<gloresi.x()<<" "<<gloresi.y()<<" "<<gloresi.z()); + + Identifier id = clusters->at(iclus)->identify(); + int istation = m_idHelper->station(id); + int ilayer = m_idHelper->layer(id); + if(istation!=0||ilayer!=i)continue; + int stereoid = m_idHelper->side(id); + auto trans2 = clusters->at(iclus)->detectorElement()->surface().transform(); + auto trans1 = trans2; + if(stereoid==1){ + trans1=clusters->at(iclus)->detectorElement()->otherSide()->surface().transform(); + } + ATH_MSG_DEBUG(" save the residual "<<resi); + const auto iModuleEta = m_idHelper->eta_module(id); + const auto iModulePhi = m_idHelper->phi_module(id); + int iModule = iModulePhi; + if (iModuleEta < 0) iModule +=4; + ATH_MSG_DEBUG("ID "<<istation<<"/"<<ilayer<<"/"<<iModule<<"/"<<stereoid<<"/"<<ilayer); + t_align_stationId_sp.push_back(istation); + t_align_centery_sp.push_back(clusters->at(iclus)->detectorElement()->center().y()); + t_align_layerId_sp.push_back(ilayer); + t_align_moduleId_sp.push_back(iModule); + t_align_clustersize_sp.push_back(clusters->at(iclus)->rdoList().size()); + t_align_stereoId.push_back(stereoid); + t_align_global_measured_x_sp.push_back(clusters->at(iclus)->globalPosition().x()); + t_align_global_measured_y_sp.push_back(clusters->at(iclus)->globalPosition().y()); + t_align_global_measured_z_sp.push_back(clusters->at(iclus)->globalPosition().z()); + t_align_global_fitted_x_sp.push_back(gfitx); + t_align_global_fitted_y_sp.push_back(gfity); + t_align_local_residual_x_sp.push_back(resi); + t_align_unbiased.push_back(2); + t_align_local_pull_x_sp.push_back(resi/sqrt(clusters->at(iclus)->localCovariance()(0,0))); + t_align_local_measured_x_sp.push_back(clusters->at(iclus)->localPosition().x()); + t_align_local_measured_xe_sp.push_back(sqrt(cluster->localCovariance()(0,0))); + t_align_local_fitted_xe_sp.push_back(sqrt(cluster->localCovariance()(0,0))); + t_align_local_fitted_x_sp.push_back(fitx); + Amg::Vector2D local_mea=clusters->at(iclus)->localPosition() ; + t_align_derivation_x_x.push_back(getDerivation(ctx, parameter, trans1,local_mea, 0, stereoid, trans2, 0)); + t_align_derivation_x_y.push_back(getDerivation(ctx, parameter, trans1,local_mea, 1, stereoid, trans2, 0)); + t_align_derivation_x_z.push_back(getDerivation(ctx, parameter, trans1,local_mea, 2, stereoid, trans2, 0)); + t_align_derivation_x_rx.push_back(getDerivation(ctx, parameter, trans1,local_mea, 3, stereoid, trans2, 0)); + t_align_derivation_x_ry.push_back(getDerivation(ctx, parameter, trans1,local_mea, 4, stereoid, trans2, 0)); + t_align_derivation_x_rz.push_back(getDerivation(ctx, parameter, trans1,local_mea, 5, stereoid, trans2, 0)); + t_align_derivation_global_y_x.push_back(getDerivation(ctx, parameter, trans1,local_mea, 0, stereoid, trans2, 1)); + t_align_derivation_global_y_y.push_back(getDerivation(ctx, parameter, trans1,local_mea, 1, stereoid, trans2, 1)); + t_align_derivation_global_y_z.push_back(getDerivation(ctx, parameter, trans1,local_mea, 2, stereoid, trans2, 1)); + t_align_derivation_global_y_rx.push_back(getDerivation(ctx, parameter, trans1,local_mea, 3, stereoid, trans2, 1)); + t_align_derivation_global_y_ry.push_back(getDerivation(ctx, parameter, trans1,local_mea, 4, stereoid, trans2, 1)); + t_align_derivation_global_y_rz.push_back(getDerivation(ctx, parameter, trans1,local_mea, 5, stereoid, trans2, 1)); + ATH_MSG_VERBOSE("local derivation "<<t_align_derivation_x_x.back()<<" "<<t_align_derivation_x_y.back()<<" "<<t_align_derivation_x_z.back()<<" "<<t_align_derivation_x_rx.back()<<" "<<t_align_derivation_x_ry.back()<<" "<<t_align_derivation_x_rz.back()); + ATH_MSG_VERBOSE("global derivation "<<t_align_derivation_global_y_x.back()<<" "<<t_align_derivation_global_y_y.back()<<" "<<t_align_derivation_global_y_z.back()<<""<<t_align_derivation_global_y_rx.back()<<" "<<t_align_derivation_global_y_ry.back()<<" "<<t_align_derivation_global_y_rz.back()); + } + } + } + } + } + } + return true; + }); + ATH_MSG_VERBOSE("check track"); + + std::unique_ptr<Trk::Track> track = m_createTrkTrackTool->createTrack(gctx, traj); + if (track==nullptr||ini_Param==nullptr) continue; + origin = -1910.; + std::vector<TSOS4Residual> unbiase_resi= m_kalmanFitterTool1->getUnbiasedResidual(ctx, gctx, track.get(), Acts::BoundVector::Zero(), m_isMC, origin,clusters_sta0, *ini_Param); + ATH_MSG_DEBUG(" found tsos size "<<unbiase_resi.size()); + if(unbiase_resi.size()>0){ + + ATH_MSG_DEBUG(" check the tsos"); + for (auto& tsos : unbiase_resi){ + ATH_MSG_DEBUG(" check the param"); + auto cluster = tsos.cluster; + ATH_MSG_DEBUG("Positions "<<tsos.fit_global_x<<" "<<tsos.fit_global_y<<" "<<tsos.fit_global_z<<" , "<<cluster->globalPosition().x()<<" "<<cluster->globalPosition().y()<<" "<<cluster->globalPosition().z()); + ATH_MSG_DEBUG("Found the ctsos "); + double localx = tsos.fit_local_x; + double localy = tsos.fit_local_y; + double globalx= tsos.fit_global_x; + double globaly= tsos.fit_global_y; + double globalz= tsos.fit_global_z; + //transfer to cluster surface + Amg::Vector3D glo_pos(globalx,globaly,globalz); + std::optional<Amg::Vector2D> loc_pos = cluster->detectorElement()->surface().globalToLocal(glo_pos); + + ATH_MSG_DEBUG("local pos "<<localx<<" "<<localy<<" , "<<loc_pos->x()<<" "<<loc_pos->y()<<" :vs "<<cluster->localPosition().x()<<" "<<cluster->localPosition().y()); + localx = loc_pos->x(); + localy = loc_pos->y(); + ATH_MSG_DEBUG("global pos "<<globalx<<" "<<globaly<<" vs "<<cluster->globalPosition().x()<<" "<<cluster->globalPosition().y()); + // outputTracks->push_back(std::move(newtrack)); + ATH_MSG_DEBUG("Global pos "<<globalx<<" , "<<globaly); + auto trans2 = cluster->detectorElement()->surface().transform(); + auto trans1 = trans2; + Identifier id = cluster->identify(); + int istation = m_idHelper->station(id); + int ilayer = m_idHelper->layer(id); + if(istation!=0)continue; + //int layerid = istation*3 + ilayer; + // if(layerid == 0 || layerid == 11)continue; + int stereoid = m_idHelper->side(id); + if(stereoid==1){ + trans1=cluster->detectorElement()->otherSide()->surface().transform(); + } + Acts::BoundTrackParameters fitParameter=tsos.parameter; + const auto iModuleEta = m_idHelper->eta_module(id); + const auto iModulePhi = m_idHelper->phi_module(id); + int iModule = iModulePhi; + if (iModuleEta < 0) iModule +=4; + ATH_MSG_DEBUG("ID "<<istation<<"/"<<ilayer<<"/"<<iModule<<"/"<<stereoid<<"/"<<ilayer); + t_align_stationId_sp.push_back(istation); + t_align_centery_sp.push_back(cluster->detectorElement()->center().y()); + t_align_layerId_sp.push_back(ilayer); + t_align_moduleId_sp.push_back(iModule); + t_align_clustersize_sp.push_back(cluster->rdoList().size()); + t_align_stereoId.push_back(stereoid); + Amg::Vector2D local_mea=cluster->localPosition() ; + Amg::Vector2D local_meae=cluster->localPosition() + Amg::Vector2D(sqrt(cluster->localCovariance()(0,0)),0); + Amg::Vector2D local_fit(localx, localy); + Amg::Vector2D local_fite(localx+0.0001, localy+0.0001); + ATH_MSG_DEBUG(" save the residual "<<local_mea.x()-local_fit.x()<<" vs "<<tsos.residual); + t_align_local_residual_x_sp.push_back(tsos.residual); + t_align_unbiased.push_back(1); + t_align_local_pull_x_sp.push_back((local_mea.x()-local_fit.x())/(sqrt(((cluster->localCovariance()(0,0)+(local_fite.x()-local_fit.x())*(local_fite.x()-local_fit.x())))))); + t_align_local_measured_x_sp.push_back(local_mea.x()); + t_align_local_measured_xe_sp.push_back(fabs(local_meae.x()-local_mea.x())); + t_align_local_fitted_xe_sp.push_back(fabs(local_fit.x()-local_fite.x())); + t_align_local_fitted_x_sp.push_back(local_fit.x()); + + Amg::Vector3D global_fit= cluster->detectorElement()->surface().localToGlobal(local_fit); + Amg::Vector3D global_fite= cluster->detectorElement()->surface().localToGlobal( local_fite); + Amg::Vector3D global_mea= cluster->detectorElement()->surface().localToGlobal( local_mea); + Amg::Vector3D global_meae= cluster->detectorElement()->surface().localToGlobal( local_meae); + t_align_global_residual_y_sp.push_back(global_mea.y()-global_fit.y()); + t_align_global_measured_x_sp.push_back(global_mea.x()); + t_align_global_measured_y_sp.push_back(global_mea.y()); + t_align_global_measured_z_sp.push_back(global_mea.z()); + t_align_global_measured_ye_sp.push_back(fabs(global_mea.y()-global_meae.y())); + t_align_global_fitted_ye_sp.push_back(fabs(global_fite.y()-global_fite.y())); + t_align_global_fitted_x_sp.push_back(global_fit.x()); + t_align_global_fitted_y_sp.push_back(global_fit.y()); + t_align_derivation_x_x.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 0, stereoid, trans2, 0)); + t_align_derivation_x_y.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 1, stereoid, trans2, 0)); + t_align_derivation_x_z.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 2, stereoid, trans2, 0)); + t_align_derivation_x_rx.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 3, stereoid, trans2, 0)); + t_align_derivation_x_ry.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 4, stereoid, trans2, 0)); + t_align_derivation_x_rz.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 5, stereoid, trans2, 0)); + t_align_derivation_global_y_x.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 0, stereoid, trans2, 1)); + t_align_derivation_global_y_y.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 1, stereoid, trans2, 1)); + t_align_derivation_global_y_z.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 2, stereoid, trans2, 1)); + t_align_derivation_global_y_rx.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 3, stereoid, trans2, 1)); + t_align_derivation_global_y_ry.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 4, stereoid, trans2, 1)); + t_align_derivation_global_y_rz.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 5, stereoid, trans2, 1)); + ATH_MSG_VERBOSE("local derivation "<<t_align_derivation_x_x.back()<<" "<<t_align_derivation_x_y.back()<<" "<<t_align_derivation_x_z.back()<<" "<<t_align_derivation_x_rx.back()<<" "<<t_align_derivation_x_ry.back()<<" "<<t_align_derivation_x_rz.back()); + ATH_MSG_VERBOSE("global derivation "<<t_align_derivation_global_y_x.back()<<" "<<t_align_derivation_global_y_y.back()<<" "<<t_align_derivation_global_y_z.back()<<""<<t_align_derivation_global_y_rx.back()<<" "<<t_align_derivation_global_y_ry.back()<<" "<<t_align_derivation_global_y_rz.back()); + } + } + } + else{ + std::unique_ptr<Trk::Track> track = m_createTrkTrackTool->createTrack(gctx, traj); + if (track!=nullptr) { + for (const Trk::MeasurementBase *meas : *track->measurementsOnTrack()) { + const auto* clusterOnTrack = dynamic_cast<const Tracker::FaserSCT_ClusterOnTrack*>(meas); + if (clusterOnTrack) { + const Tracker::FaserSCT_Cluster* cluster = clusterOnTrack->prepRawData(); + ATH_MSG_DEBUG(" Found the cluster to be remove "<<cluster->globalPosition()); + //remove the cluster and re-fit to get unbiased residual + Identifier id = clusterOnTrack->identify(); + Identifier waferId = m_idHelper->wafer_id(id); + ATH_MSG_DEBUG("like cluster ID "<<m_idHelper->layer(id)<<" "<<m_idHelper->station(id)); + double localx(-999); + double localxe(999); + double localy(-999); + double localye(999); + double globalx(-999); + double globaly(999); + double globalz(999); +// int charge =0; +// Acts::BoundSymMatrix cov = Acts::BoundSymMatrix::Identity(); + ATH_MSG_DEBUG(" make unbiased residual"); + m_numberOfSelectedTracks++; + if((*track->measurementsOnTrack()).size()<15)continue; + //remove the cluster and re-fit to get unbiased residual + std::vector<TSOS4Residual> unbiase_resi= m_kalmanFitterTool1->getUnbiasedResidual(ctx, gctx, track.get(), cluster->globalPosition().z(), Acts::BoundVector::Zero(), m_isMC, origin); + if(unbiase_resi.size()>0){ + + ATH_MSG_DEBUG(" check the tsos"); + for (auto& tsos : unbiase_resi){ + ATH_MSG_DEBUG(" check the param"); + if(tsos.cluster->identify()!=cluster->identify())continue; + ATH_MSG_DEBUG("Positions "<<tsos.fit_global_x<<" "<<tsos.fit_global_y<<" "<<tsos.fit_global_z<<" , "<<cluster->globalPosition().x()<<" "<<cluster->globalPosition().y()<<" "<<cluster->globalPosition().z()); + ATH_MSG_DEBUG("Found the ctsos "); + localx = tsos.fit_local_x; + localy = tsos.fit_local_y; + globalx= tsos.fit_global_x; + globaly= tsos.fit_global_y; + globalz= tsos.fit_global_z; + //transfer to cluster surface + Amg::Vector3D glo_pos(globalx,globaly,globalz); + std::optional<Amg::Vector2D> loc_pos = cluster->detectorElement()->surface().globalToLocal(glo_pos); + + ATH_MSG_DEBUG("local pos "<<localx<<" "<<localy<<" , "<<loc_pos->x()<<" "<<loc_pos->y()<<" :vs "<<cluster->localPosition().x()<<" "<<cluster->localPosition().y()); + localx = loc_pos->x(); + localy = loc_pos->y(); + ATH_MSG_DEBUG("global pos "<<globalx<<" "<<globaly<<" vs "<<cluster->globalPosition().x()<<" "<<cluster->globalPosition().y()); + save=true; + ATH_MSG_DEBUG("Global pos "<<globalx<<" , "<<globaly); + auto trans2 = cluster->detectorElement()->surface().transform(); + auto trans1 = trans2; + Identifier id = cluster->identify(); + int istation = m_idHelper->station(id); + int ilayer = m_idHelper->layer(id); + int stereoid = m_idHelper->side(id); + if(stereoid==1){ + trans1=cluster->detectorElement()->otherSide()->surface().transform(); + } + Acts::BoundTrackParameters fitParameter=tsos.parameter; + const auto iModuleEta = m_idHelper->eta_module(id); + const auto iModulePhi = m_idHelper->phi_module(id); + int iModule = iModulePhi; + if (iModuleEta < 0) iModule +=4; + ATH_MSG_DEBUG("ID "<<istation<<"/"<<ilayer<<"/"<<iModule<<"/"<<stereoid<<"/"<<ilayer); + t_align_centery_sp.push_back(cluster->detectorElement()->center().y()); + t_align_stationId_sp.push_back(istation); + t_align_layerId_sp.push_back(ilayer); + t_align_moduleId_sp.push_back(iModule); + t_align_clustersize_sp.push_back(cluster->rdoList().size()); + t_align_stereoId.push_back(stereoid); + Amg::Vector2D local_mea=cluster->localPosition() ; + Amg::Vector2D local_meae=cluster->localPosition() + Amg::Vector2D(sqrt(cluster->localCovariance()(0,0)),0); + Amg::Vector2D local_fit(localx, localy); + Amg::Vector2D local_fite(localx+localxe, localy+localye); + ATH_MSG_DEBUG(" save the residual "<<local_mea.x()-local_fit.x()<<" vs "<<tsos.residual); + t_align_local_residual_x_sp.push_back(tsos.residual); + t_align_unbiased.push_back(3); + t_align_local_pull_x_sp.push_back((local_mea.x()-local_fit.x())/(sqrt(((cluster->localCovariance()(0,0)+(local_fite.x()-local_fit.x())*(local_fite.x()-local_fit.x())))))); + t_align_local_measured_x_sp.push_back(local_mea.x()); + t_align_local_measured_xe_sp.push_back(fabs(local_meae.x()-local_mea.x())); + t_align_local_fitted_xe_sp.push_back(fabs(local_fit.x()-local_fite.x())); + t_align_local_fitted_x_sp.push_back(local_fit.x()); + + Amg::Vector3D global_fit= cluster->detectorElement()->surface().localToGlobal(local_fit); + Amg::Vector3D global_fite= cluster->detectorElement()->surface().localToGlobal( local_fite); + Amg::Vector3D global_mea= cluster->detectorElement()->surface().localToGlobal( local_mea); + Amg::Vector3D global_meae= cluster->detectorElement()->surface().localToGlobal( local_meae); + t_align_global_residual_y_sp.push_back(global_mea.y()-global_fit.y()); + t_align_global_measured_x_sp.push_back(global_mea.x()); + t_align_global_measured_y_sp.push_back(global_mea.y()); + t_align_global_measured_z_sp.push_back(global_mea.z()); + t_align_global_measured_ye_sp.push_back(fabs(global_mea.y()-global_meae.y())); + t_align_global_fitted_ye_sp.push_back(fabs(global_fite.y()-global_fite.y())); + t_align_global_fitted_x_sp.push_back(global_fit.x()); + t_align_global_fitted_y_sp.push_back(global_fit.y()); + t_align_derivation_x_x.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 0, stereoid, trans2, 0)); + t_align_derivation_x_y.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 1, stereoid, trans2, 0)); + t_align_derivation_x_z.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 2, stereoid, trans2, 0)); + t_align_derivation_x_rx.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 3, stereoid, trans2, 0)); + t_align_derivation_x_ry.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 4, stereoid, trans2, 0)); + t_align_derivation_x_rz.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 5, stereoid, trans2, 0)); + t_align_derivation_global_y_x.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 0, stereoid, trans2, 1)); + t_align_derivation_global_y_y.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 1, stereoid, trans2, 1)); + t_align_derivation_global_y_z.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 2, stereoid, trans2, 1)); + t_align_derivation_global_y_rx.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 3, stereoid, trans2, 1)); + t_align_derivation_global_y_ry.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 4, stereoid, trans2, 1)); + t_align_derivation_global_y_rz.push_back(getDerivation(ctx, fitParameter, trans1,local_mea, 5, stereoid, trans2, 1)); + ATH_MSG_VERBOSE("local derivation "<<t_align_derivation_x_x.back()<<" "<<t_align_derivation_x_y.back()<<" "<<t_align_derivation_x_z.back()<<" "<<t_align_derivation_x_rx.back()<<" "<<t_align_derivation_x_ry.back()<<" "<<t_align_derivation_x_rz.back()); + ATH_MSG_VERBOSE("global derivation "<<t_align_derivation_global_y_x.back()<<" "<<t_align_derivation_global_y_y.back()<<" "<<t_align_derivation_global_y_z.back()<<""<<t_align_derivation_global_y_rx.back()<<" "<<t_align_derivation_global_y_ry.back()<<" "<<t_align_derivation_global_y_rz.back()); + } + } + } + } + } + } + ATH_MSG_VERBOSE("finish getting residuals"); + if(save){ + ATH_MSG_VERBOSE("save the results"); + m_fitParam_nMeasurements.push_back(trajState.nMeasurements); + m_fitParam_nStates.push_back(trajState.nStates); + m_fitParam_nOutliers.push_back(trajState.nOutliers); + m_fitParam_nHoles.push_back(trajState.nHoles); + m_fitParam_chi2.push_back(trajState.chi2Sum); + m_fitParam_ndf.push_back(trajState.NDF); + m_fitParam_x.push_back(params.position(gctx).transpose().x()); + m_fitParam_y.push_back(params.position(gctx).transpose().y()); + m_fitParam_z.push_back(params.position(gctx).transpose().z()); + m_fitParam_charge.push_back(params.charge()); + m_fitParam_px.push_back(params.momentum().transpose().x()); + m_fitParam_py.push_back(params.momentum().transpose().y()); + m_fitParam_pz.push_back(params.momentum().transpose().z()); + m_align_stationId_sp.push_back(t_align_stationId_sp); + m_align_centery_sp.push_back(t_align_centery_sp); + m_align_layerId_sp.push_back(t_align_layerId_sp); + m_align_moduleId_sp.push_back(t_align_moduleId_sp); + m_align_clustersize_sp.push_back(t_align_clustersize_sp); + m_align_stereoId.push_back(t_align_stereoId); + m_align_global_residual_y_sp.push_back(t_align_global_residual_y_sp); + m_align_global_measured_x_sp.push_back(t_align_global_measured_x_sp); + m_align_global_measured_y_sp.push_back(t_align_global_measured_y_sp); + m_align_global_measured_z_sp.push_back(t_align_global_measured_z_sp); + m_align_global_measured_ye_sp.push_back(t_align_global_measured_ye_sp); + m_align_global_fitted_ye_sp.push_back(t_align_global_fitted_ye_sp); + m_align_global_fitted_x_sp.push_back(t_align_global_fitted_x_sp); + m_align_global_fitted_y_sp.push_back(t_align_global_fitted_y_sp); + m_align_local_residual_x_sp.push_back(t_align_local_residual_x_sp); + m_align_unbiased_sp.push_back(t_align_unbiased); + m_align_local_pull_x_sp.push_back(t_align_local_pull_x_sp); + m_align_local_measured_x_sp.push_back(t_align_local_measured_x_sp); + m_align_local_measured_xe_sp.push_back(t_align_local_measured_xe_sp); + m_align_local_fitted_xe_sp.push_back(t_align_local_fitted_xe_sp); + m_align_local_fitted_x_sp.push_back(t_align_local_fitted_x_sp); + m_align_derivation_x_x.push_back(t_align_derivation_x_x); + m_align_derivation_x_y.push_back(t_align_derivation_x_y); + m_align_derivation_x_z.push_back(t_align_derivation_x_z); + m_align_derivation_x_rx.push_back(t_align_derivation_x_rx); + m_align_derivation_x_ry.push_back(t_align_derivation_x_ry); + m_align_derivation_x_rz.push_back(t_align_derivation_x_rz); + m_align_derivation_global_y_x.push_back(t_align_derivation_global_y_x); + m_align_derivation_global_y_y.push_back(t_align_derivation_global_y_y); + m_align_derivation_global_y_z.push_back(t_align_derivation_global_y_z); + m_align_derivation_global_y_rx.push_back(t_align_derivation_global_y_rx); + m_align_derivation_global_y_ry.push_back(t_align_derivation_global_y_ry); + m_align_derivation_global_y_rz.push_back(t_align_derivation_global_y_rz); + } + } + + if(save) + m_tree->Fill(); + + return StatusCode::SUCCESS; +} + + +StatusCode CKF2Alignment::finalize() { + ATH_MSG_INFO("CombinatorialKalmanFilterAlg::finalize()"); + ATH_MSG_INFO(m_numberOfEvents << " events processed."); + ATH_MSG_INFO(m_numberOfTrackSeeds << " seeds."); + ATH_MSG_INFO(m_numberOfFittedTracks << " fitted tracks."); + ATH_MSG_INFO(m_numberOfSelectedTracks << " selected and re-fitted tracks."); + //nominal geometry + double nominaly[4][3][8]={0.}; + double sigma=0.064; + nominaly[1][0][4]= -95.61; + nominaly[1][0][0]=-95.61; + nominaly[1][0][5]= -31.87; + nominaly[1][0][1]=-31.87; + nominaly[1][0][6]= 31.873; + nominaly[1][0][2]=31.877; + nominaly[1][0][7]= 95.61; + nominaly[1][0][3]=95.61; + nominaly[1][1][4]= -100.61; + nominaly[1][1][0]=-100.61; + nominaly[1][1][5]= -36.87; + nominaly[1][1][1]=-36.87; + nominaly[1][1][6]= 26.87; + nominaly[1][1][2]=26.87; + nominaly[1][1][7]= 90.61; + nominaly[1][1][3]=90.61; + nominaly[1][2][4]= -90.61; + nominaly[1][2][0]=-90.61; + nominaly[1][2][5]= -26.87; + nominaly[1][2][1]=-26.87; + nominaly[1][2][6]= 36.87; + nominaly[1][2][2]=36.87; + nominaly[1][2][7]= 100.61; + nominaly[1][2][3]=100.61; + nominaly[2][0][4]= -95.61; + nominaly[2][0][0]=-95.61; + nominaly[2][0][5]= -31.87; + nominaly[2][0][1]=-31.87; + nominaly[2][0][6]= 31.87; + nominaly[2][0][2]=31.87; + nominaly[2][0][7]= 95.61; + nominaly[2][0][3]=95.61; + nominaly[2][1][4]= -100.61; + nominaly[2][1][0]=-100.61; + nominaly[2][1][5]= -36.87; + nominaly[2][1][1]=-36.87; + nominaly[2][1][6]= 26.87; + nominaly[2][1][2]=26.87; + nominaly[2][1][7]= 90.61; + nominaly[2][1][3]=90.61; + nominaly[2][2][4]= -90.61; + nominaly[2][2][0]=-90.61; + nominaly[2][2][5]= -26.87; + nominaly[2][2][1]=-26.87; + nominaly[2][2][6]= 36.87; + nominaly[2][2][2]=36.87; + nominaly[2][2][7]= 100.61; + nominaly[2][2][3]=100.61; + nominaly[3][0][4]= -95.61; + nominaly[3][0][0]=-95.61; + nominaly[3][0][5]= -31.87; + nominaly[3][0][1]=-31.87; + nominaly[3][0][6]= 31.87; + nominaly[3][0][2]=31.87; + nominaly[3][0][7]= 95.61; + nominaly[3][0][3]=95.61; + nominaly[3][1][4]= -100.61; + nominaly[3][1][0]=-100.61; + nominaly[3][1][5]= -36.87; + nominaly[3][1][1]=-36.87; + nominaly[3][1][6]= 26.87; + nominaly[3][1][2]=26.87; + nominaly[3][1][7]= 90.61; + nominaly[3][1][3]=90.61; + nominaly[3][2][4]= -90.61; + nominaly[3][2][0]=-90.61; + nominaly[3][2][5]= -26.87; + nominaly[3][2][1]=-26.87; + nominaly[3][2][6]= 36.87; + nominaly[3][2][2]=36.87; + nominaly[3][2][7]=100.61; + nominaly[3][2][3]=100.61; + //dump the matrix to a txt file for alignment + std::vector<double>* t_fitParam_chi2=0; + std::vector<double>* t_fitParam_pz=0; + std::vector<double>* t_fitParam_x=0; + std::vector<double>* t_fitParam_y=0; + std::vector<std::vector<double>>* t_fitParam_align_local_residual_x_sp=0; + std::vector<std::vector<double>>* t_fitParam_align_local_measured_x_sp=0; + std::vector<std::vector<double>>* t_fitParam_align_local_measured_xe_sp=0; + std::vector<std::vector<double>>* t_fitParam_align_stationId_sp=0; + std::vector<std::vector<double>>* t_fitParam_align_centery_sp=0; + std::vector<std::vector<double>>* t_fitParam_align_layerId_sp=0; + std::vector<std::vector<double>>* t_fitParam_align_moduleId_sp=0; + std::vector<std::vector<double>>* t_fitParam_align_unbiased_sp=0; + std::vector<std::vector<double>>* t_fitParam_align_local_derivation_x_x=0; + std::vector<std::vector<double>>* t_fitParam_align_local_derivation_x_y=0; + std::vector<std::vector<double>>* t_fitParam_align_local_derivation_x_z=0; + std::vector<std::vector<double>>* t_fitParam_align_local_derivation_x_rx=0; + std::vector<std::vector<double>>* t_fitParam_align_local_derivation_x_ry=0; + std::vector<std::vector<double>>* t_fitParam_align_local_derivation_x_rz=0; + std::vector<std::vector<double>>* t_fitParam_align_global_derivation_y_x=0; + std::vector<std::vector<double>>* t_fitParam_align_global_derivation_y_y=0; + std::vector<std::vector<double>>* t_fitParam_align_global_derivation_y_z=0; + std::vector<std::vector<double>>* t_fitParam_align_global_derivation_y_rx=0; + std::vector<std::vector<double>>* t_fitParam_align_global_derivation_y_ry=0; + std::vector<std::vector<double>>* t_fitParam_align_global_derivation_y_rz=0; + std::vector<std::vector<double>>* t_fitParam_align_stereoId=0; + std::vector<int>* t_fitParam_nMeasurements=0; + m_tree->SetBranchAddress("fitParam_nMeasurements", &t_fitParam_nMeasurements); + m_tree->SetBranchAddress("fitParam_align_stereoId",&t_fitParam_align_stereoId); + m_tree->SetBranchAddress("fitParam_align_local_derivation_x_x",&t_fitParam_align_local_derivation_x_x); + m_tree->SetBranchAddress("fitParam_align_local_derivation_x_y",&t_fitParam_align_local_derivation_x_y); + m_tree->SetBranchAddress("fitParam_align_local_derivation_x_z",&t_fitParam_align_local_derivation_x_z); + m_tree->SetBranchAddress("fitParam_align_local_derivation_x_rx",&t_fitParam_align_local_derivation_x_rx); + m_tree->SetBranchAddress("fitParam_align_local_derivation_x_ry",&t_fitParam_align_local_derivation_x_ry); + m_tree->SetBranchAddress("fitParam_align_local_derivation_x_rz",&t_fitParam_align_local_derivation_x_rz); + m_tree->SetBranchAddress("fitParam_align_global_derivation_y_x",&t_fitParam_align_global_derivation_y_x); + m_tree->SetBranchAddress("fitParam_align_global_derivation_y_y",&t_fitParam_align_global_derivation_y_y); + m_tree->SetBranchAddress("fitParam_align_global_derivation_y_z",&t_fitParam_align_global_derivation_y_z); + m_tree->SetBranchAddress("fitParam_align_global_derivation_y_rx",&t_fitParam_align_global_derivation_y_rx); + m_tree->SetBranchAddress("fitParam_align_global_derivation_y_ry",&t_fitParam_align_global_derivation_y_ry); + m_tree->SetBranchAddress("fitParam_align_global_derivation_y_rz",&t_fitParam_align_global_derivation_y_rz); + m_tree->SetBranchAddress("fitParam_align_local_residual_x_sp",&t_fitParam_align_local_residual_x_sp); + m_tree->SetBranchAddress("fitParam_chi2",&t_fitParam_chi2); + m_tree->SetBranchAddress("fitParam_pz",&t_fitParam_pz); + m_tree->SetBranchAddress("fitParam_x",&t_fitParam_x); + m_tree->SetBranchAddress("fitParam_y",&t_fitParam_y); + m_tree->SetBranchAddress("fitParam_align_local_measured_x_sp",&t_fitParam_align_local_measured_x_sp); + m_tree->SetBranchAddress("fitParam_align_local_measured_xe_sp",&t_fitParam_align_local_measured_xe_sp); + m_tree->SetBranchAddress("fitParam_align_layerId_sp",&t_fitParam_align_layerId_sp); + m_tree->SetBranchAddress("fitParam_align_moduleId_sp",&t_fitParam_align_moduleId_sp); + m_tree->SetBranchAddress("fitParam_align_unbiased_sp",&t_fitParam_align_unbiased_sp); + m_tree->SetBranchAddress("fitParam_align_stationId_sp",&t_fitParam_align_stationId_sp); + m_tree->SetBranchAddress("fitParam_align_centery_sp",&t_fitParam_align_centery_sp); + int ntrk_mod[12][8]={0}; + int ntrk_sta[4]={0}; + int ntrk_lay[12]={0}; + //define matrix + int Ndim=6; + std::vector<TMatrixD> denom_lay; + std::vector<TMatrixD> num_lay; + std::vector<std::vector<TMatrixD>> denom_mod; + std::vector<std::vector<TMatrixD>> num_mod; + std::vector<std::vector<TMatrixD>> denom_mod1; + std::vector<std::vector<TMatrixD>> num_mod1; + //initialize to 0 + auto num_matrix = [](int n) { + TMatrixD num_t(n,1); + for(int i=0;i<n;i++){ + num_t[i][0]=0.; + } + return num_t; + }; + auto denom_matrix = [](int n) { + TMatrixD denom_t(n,n); + for(int i=0;i<n;i++){ + for(int j=0;j<n;j++){ + denom_t[i][j]=0.; + } + } + return denom_t; + }; + std::vector<TMatrixD> denom_sta; + std::vector<TMatrixD> num_sta; + for(int i=0;i<4;i++){ + denom_sta.push_back(denom_matrix(Ndim)); + num_sta.push_back(num_matrix(Ndim)); + } + for(int i=0;i<12;i++){ + denom_lay.push_back(denom_matrix(Ndim)); + num_lay.push_back(num_matrix(Ndim)); + std::vector<TMatrixD> denom_l; + std::vector<TMatrixD> num_l; + std::vector<TMatrixD> denom_l1; + std::vector<TMatrixD> num_l1; + for(int j=0;j<8;j++){ + denom_l.push_back(denom_matrix(Ndim)); + num_l.push_back(num_matrix(Ndim)); + denom_l1.push_back(denom_matrix(Ndim)); + num_l1.push_back(num_matrix(Ndim)); + } + denom_mod.push_back(denom_l1); + denom_mod1.push_back(denom_l1); + num_mod.push_back(num_l); + num_mod1.push_back(num_l1); + } + double chi_mod_y[12][8]={0}; + std::cout<<"found "<<m_tree->GetEntries()<<" events "<<std::endl; + //loop over all the entries + for(int ievt=0;ievt<m_tree->GetEntries();ievt++){ + m_tree->GetEntry(ievt); + if(ievt%10000==0)std::cout<<"processing "<<ievt<<" event"<<std::endl; + if(t_fitParam_chi2->size()<1)continue; + for(int i=0;i<1;i+=1){ + if(t_fitParam_chi2->at(i)>100||t_fitParam_pz->at(i)<300||sqrt(t_fitParam_x->at(i)*t_fitParam_x->at(i)+t_fitParam_y->at(i)*t_fitParam_y->at(i))>95)continue; + if(t_fitParam_align_local_residual_x_sp->at(i).size()<15)continue;//only use good track + for(size_t j=0;j<t_fitParam_align_local_residual_x_sp->at(i).size();j++){ + double resx1=999.; + double x1e=999.; + if(m_biased&&t_fitParam_align_stationId_sp->at(i).at(j)==0){ + if(t_fitParam_align_unbiased_sp->at(i).at(j)==1){ + resx1=(t_fitParam_align_local_residual_x_sp->at(i).at(j)); + x1e=sqrt(t_fitParam_align_local_measured_xe_sp->at(i).at(j)); + if(fabs(resx1)>1.0)continue; + } + else continue; + } + else{ + resx1=t_fitParam_align_local_residual_x_sp->at(i).at(j); + x1e=sqrt(t_fitParam_align_local_measured_xe_sp->at(i).at(j)); + if(fabs(resx1)>0.2)continue; + } + TMatrixD m1(Ndim,1); + m1[0][0]=t_fitParam_align_local_derivation_x_x->at(i).at(j)/x1e; + m1[1][0]=t_fitParam_align_local_derivation_x_y->at(i).at(j)/x1e; + m1[2][0]=t_fitParam_align_local_derivation_x_z->at(i).at(j)/x1e; + m1[3][0]=t_fitParam_align_local_derivation_x_rx->at(i).at(j)/x1e; + m1[4][0]=t_fitParam_align_local_derivation_x_ry->at(i).at(j)/x1e; + m1[5][0]=t_fitParam_align_local_derivation_x_rz->at(i).at(j)/x1e; + TMatrixD m2(1,Ndim); + TMatrixD m3(Ndim,Ndim); + m2.Transpose(m1); + m3=m1*m2; + TMatrixD m4(Ndim,1); + m4[0][0]=t_fitParam_align_local_derivation_x_x->at(i).at(j)/x1e*resx1/x1e; + m4[1][0]=t_fitParam_align_local_derivation_x_y->at(i).at(j)/x1e*resx1/x1e; + m4[2][0]=t_fitParam_align_local_derivation_x_z->at(i).at(j)/x1e*resx1/x1e; + m4[3][0]=t_fitParam_align_local_derivation_x_rx->at(i).at(j)/x1e*resx1/x1e; + m4[4][0]=t_fitParam_align_local_derivation_x_ry->at(i).at(j)/x1e*resx1/x1e; + m4[5][0]=t_fitParam_align_local_derivation_x_rz->at(i).at(j)/x1e*resx1/x1e; + TMatrixD m6(Ndim,1); + m6=m4; + TMatrixD mg1(Ndim,1); + mg1[0][0]=t_fitParam_align_global_derivation_y_x->at(i).at(j)/x1e; + mg1[1][0]=t_fitParam_align_global_derivation_y_y->at(i).at(j)/x1e; + mg1[2][0]=t_fitParam_align_global_derivation_y_z->at(i).at(j)/x1e; + mg1[3][0]=t_fitParam_align_global_derivation_y_rx->at(i).at(j)/x1e; + mg1[4][0]=t_fitParam_align_global_derivation_y_ry->at(i).at(j)/x1e; + mg1[5][0]=t_fitParam_align_global_derivation_y_rz->at(i).at(j)/x1e; + TMatrixD mg2(1,Ndim); + TMatrixD mg3(Ndim,Ndim); + mg2.Transpose(mg1); + mg3=mg1*mg2; + TMatrixD mg4(Ndim,1); + mg4[0][0]=t_fitParam_align_global_derivation_y_x->at(i).at(j)/x1e*resx1/x1e; + mg4[1][0]=t_fitParam_align_global_derivation_y_y->at(i).at(j)/x1e*resx1/x1e; + mg4[2][0]=t_fitParam_align_global_derivation_y_z->at(i).at(j)/x1e*resx1/x1e; + mg4[3][0]=t_fitParam_align_global_derivation_y_rx->at(i).at(j)/x1e*resx1/x1e; + mg4[4][0]=t_fitParam_align_global_derivation_y_ry->at(i).at(j)/x1e*resx1/x1e; + mg4[5][0]=t_fitParam_align_global_derivation_y_rz->at(i).at(j)/x1e*resx1/x1e; + TMatrixD mg6(Ndim,1); + mg6=mg4; + int istation=t_fitParam_align_stationId_sp->at(i).at(j); + int ilayer=t_fitParam_align_layerId_sp->at(i).at(j); + int imodule=t_fitParam_align_moduleId_sp->at(i).at(j); + //station: 1,2,3 + if(istation>=0&&istation<4){ + denom_sta[istation]+=mg3; + num_sta[istation]+=mg6; + ntrk_sta[istation]+=1; + } + int ilayer_tot = ilayer + (istation )*3; + double deltay=t_fitParam_align_centery_sp->at(i).at(j)-nominaly[istation][ilayer][imodule]; + ATH_MSG_DEBUG("nominal/new geometry Y position = "<<nominaly[istation][ilayer][imodule]<<"/"<<t_fitParam_align_centery_sp->at(i).at(j)); + chi_mod_y[ilayer_tot][imodule]+=deltay/sigma/sigma; + if(ilayer_tot>=0&&ilayer_tot<12){ + denom_lay[ilayer_tot]+=mg3; + num_lay[ilayer_tot]+=mg6; + ntrk_lay[ilayer_tot]+=1; + denom_mod[ilayer_tot][imodule]+=m3; + num_mod[ilayer_tot][imodule]+=m6; + ntrk_mod[ilayer_tot][imodule]+=1; + } + } + } + } + + std::cout<<"Get the nominal transform"<<std::endl; + //get the alignment constants + std::ofstream align_output("alignment_matrix.txt",std::ios::out); + for(int i=0;i<4;i++){ + for(int ii=0;ii<Ndim;ii++){ + align_output<<i<<" "<<ii<<" "<<denom_sta[i][ii][0]<<" "<<denom_sta[i][ii][1]<<" "<<denom_sta[i][ii][2]<<" "<<denom_sta[i][ii][3]<<" "<<denom_sta[i][ii][4]<<" "<<denom_sta[i][ii][5]<<" "<<0<<std::endl; + if(ii==0) + std::cout<<i<<" "<<ii<<" "<<denom_sta[i][ii][0]<<" "<<denom_sta[i][ii][1]<<" "<<denom_sta[i][ii][2]<<" "<<denom_sta[i][ii][3]<<" "<<denom_sta[i][ii][4]<<" "<<denom_sta[i][ii][5]<<" "<<0<<std::endl; + } + align_output<<i<<" "<<6<<" "<<num_sta[i][0][0]<<" "<<num_sta[i][1][0]<<" "<<num_sta[i][2][0]<<" "<<num_sta[i][3][0]<<" "<<num_sta[i][4][0]<<" "<<num_sta[i][5][0]<<" "<<ntrk_sta[i]<<std::endl; + } + std::cout<<"Get the deltas for stations"<<std::endl; + //layers + for(size_t i=0;i<denom_lay.size();i++){ + for(int ii=0;ii<Ndim;ii++){ + align_output<<i/3<<i%3<<" "<<ii<<" "<<denom_lay[i][ii][0]<<" "<<denom_lay[i][ii][1]<<" "<<denom_lay[i][ii][2]<<" "<<denom_lay[i][ii][3]<<" "<<denom_lay[i][ii][4]<<" "<<denom_lay[i][ii][5]<<" "<<0<<std::endl; + } + align_output<<i/3<<i%3<<" "<<6<<" "<<num_lay[i][0][0]<<" "<<num_lay[i][1][0]<<" "<<num_lay[i][2][0]<<" "<<num_lay[i][3][0]<<" "<<num_lay[i][4][0]<<" "<<num_lay[i][5][0]<<" "<<ntrk_lay[i]<<std::endl; + } + + std::cout<<"Get the deltas for layers"<<std::endl; + for(size_t i=0;i<denom_lay.size();i++){ + for( size_t j=0;j<num_mod[i].size();j++){ + for(int ii=0;ii<Ndim;ii++){ + align_output<<i/3<<i%3<<j<<" "<<ii<<" "<<denom_mod[i][j][ii][0]<<" "<<denom_mod[i][j][ii][1]<<" "<<denom_mod[i][j][ii][2]<<" "<<denom_mod[i][j][ii][3]<<" "<<denom_mod[i][j][ii][4]<<" "<<denom_mod[i][j][ii][5]<<" "<<chi_mod_y[i][j]<<std::endl; + } + align_output<<i/3<<i%3<<j<<" "<<6<<" "<<num_mod[i][j][0][0]<<" "<<num_mod[i][j][1][0]<<" "<<num_mod[i][j][2][0]<<" "<<num_mod[i][j][3][0]<<" "<<num_mod[i][j][4][0]<<" "<<num_mod[i][j][5][0]<<" "<<ntrk_mod[i][j]<<std::endl; + } + } + std::cout<<"closing the output"<<std::endl; + align_output.close(); + return StatusCode::SUCCESS; +} + + +Acts::MagneticFieldContext CKF2Alignment::getMagneticFieldContext(const EventContext& ctx) const { + SG::ReadCondHandle<FaserFieldCacheCondObj> readHandle{m_fieldCondObjInputKey, ctx}; + if (!readHandle.isValid()) { + std::stringstream msg; + msg << "Failed to retrieve magnetic field condition data " << m_fieldCondObjInputKey.key() << "."; + throw std::runtime_error(msg.str()); + } + const FaserFieldCacheCondObj* fieldCondObj{*readHandle}; + return Acts::MagneticFieldContext(fieldCondObj); +} + + + + +void CKF2Alignment::computeSharedHits(std::vector<IndexSourceLink>* sourceLinks, TrackFinderResult& results) const { + // Compute shared hits from all the reconstructed tracks + // Compute nSharedhits and Update ckf results + // hit index -> list of multi traj indexes [traj, meas] + static_assert(Acts::SourceLinkConcept<IndexSourceLink>, + "Source link does not fulfill SourceLinkConcept"); + + std::vector<std::size_t> firstTrackOnTheHit( + sourceLinks->size(), std::numeric_limits<std::size_t>::max()); + std::vector<std::size_t> firstStateOnTheHit( + sourceLinks->size(), std::numeric_limits<std::size_t>::max()); + + for (unsigned int iresult = 0; iresult < results.size(); iresult++) { + if (not results.at(iresult).ok()) { + continue; + } + + auto& ckfResult = results.at(iresult).value(); + auto& measIndexes = ckfResult.lastMeasurementIndices; + + for (auto measIndex : measIndexes) { + ckfResult.fittedStates.visitBackwards(measIndex, [&](const auto& state) { + if (not state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) + return; + + std::size_t hitIndex = state.uncalibrated().index(); + + // Check if hit not already used + if (firstTrackOnTheHit.at(hitIndex) == + std::numeric_limits<std::size_t>::max()) { + firstTrackOnTheHit.at(hitIndex) = iresult; + firstStateOnTheHit.at(hitIndex) = state.index(); + return; + } + + // if already used, control if first track state has been marked + // as shared + int indexFirstTrack = firstTrackOnTheHit.at(hitIndex); + int indexFirstState = firstStateOnTheHit.at(hitIndex); + if (not results.at(indexFirstTrack).value().fittedStates.getTrackState(indexFirstState).typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) + results.at(indexFirstTrack).value().fittedStates.getTrackState(indexFirstState).typeFlags().set(Acts::TrackStateFlag::SharedHitFlag); + + // Decorate this track + results.at(iresult).value().fittedStates.getTrackState(state.index()).typeFlags().set(Acts::TrackStateFlag::SharedHitFlag); + }); + } + } +} + + +namespace { + + using Updater = Acts::GainMatrixUpdater; + using Smoother = Acts::GainMatrixSmoother; + + using Stepper = Acts::EigenStepper<>; + using Navigator = Acts::Navigator; + using Propagator = Acts::Propagator<Stepper, Navigator>; + using CKF = Acts::CombinatorialKalmanFilter<Propagator, Updater, Smoother>; + + using TrackParametersContainer = std::vector<CKF2Alignment::TrackParameters>; + + struct TrackFinderFunctionImpl + : public CKF2Alignment::TrackFinderFunction { + CKF trackFinder; + + TrackFinderFunctionImpl(CKF&& f) : trackFinder(std::move(f)) {} + + CKF2Alignment::TrackFinderResult operator()( + const IndexSourceLinkContainer& sourcelinks, + const TrackParametersContainer& initialParameters, + const CKF2Alignment::TrackFinderOptions& options) + const override { + return trackFinder.findTracks(sourcelinks, initialParameters, options); + }; + }; + +} // namespace + +std::shared_ptr<CKF2Alignment::TrackFinderFunction> +CKF2Alignment::makeTrackFinderFunction( + std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry, + bool resolvePassive, bool resolveMaterial, bool resolveSensitive) { + auto magneticField = std::make_shared<FASERMagneticFieldWrapper>(); + Stepper stepper(std::move(magneticField)); + Navigator::Config cfg{trackingGeometry}; + cfg.resolvePassive = resolvePassive; + cfg.resolveMaterial = resolveMaterial; + cfg.resolveSensitive = resolveSensitive; + Navigator navigator(cfg); + Propagator propagator(std::move(stepper), std::move(navigator)); + CKF trackFinder(std::move(propagator)); + + // build the track finder functions. owns the track finder object. + return std::make_shared<TrackFinderFunctionImpl>(std::move(trackFinder)); +} + + +namespace { + + using Updater = Acts::GainMatrixUpdater; + using Smoother = Acts::GainMatrixSmoother; + using Stepper = Acts::EigenStepper<>; + using Propagator = Acts::Propagator<Stepper, Acts::Navigator>; + using Fitter = Acts::KalmanFitter<Propagator, Updater, Smoother>; + + struct TrackFitterFunctionImpl + : public CKF2Alignment::TrackFitterFunction { + Fitter trackFitter; + + TrackFitterFunctionImpl(Fitter &&f) : trackFitter(std::move(f)) {} + + CKF2Alignment::KFResult operator()( + const std::vector<IndexSourceLink> &sourceLinks, + const Acts::BoundTrackParameters &initialParameters, + const CKF2Alignment::TrackFitterOptions &options) + const override { + return trackFitter.fit(sourceLinks, initialParameters, options); + }; + }; + +} // namespace + + +std::shared_ptr<CKF2Alignment::TrackFitterFunction> +CKF2Alignment::makeTrackFitterFunction( + std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry) { + auto magneticField = std::make_shared<FASERMagneticFieldWrapper>(); + auto stepper = Stepper(std::move(magneticField)); + Acts::Navigator::Config cfg{trackingGeometry}; + cfg.resolvePassive = false; + cfg.resolveMaterial = true; + cfg.resolveSensitive = true; + Acts::Navigator navigator(cfg); + Propagator propagator(std::move(stepper), std::move(navigator)); + Fitter trackFitter(std::move(propagator)); + return std::make_shared<TrackFitterFunctionImpl>(std::move(trackFitter)); +} + + +void CKF2Alignment::initializeTree(){ + m_tree->Branch("evtId",&m_numberOfEvents); + m_tree->Branch("fitParam_x", &m_fitParam_x); + m_tree->Branch("fitParam_charge", &m_fitParam_charge); + m_tree->Branch("fitParam_y", &m_fitParam_y); + m_tree->Branch("fitParam_z", &m_fitParam_z); + m_tree->Branch("fitParam_px", &m_fitParam_px); + m_tree->Branch("fitParam_py", &m_fitParam_py); + m_tree->Branch("fitParam_pz", &m_fitParam_pz); + m_tree->Branch("fitParam_chi2", &m_fitParam_chi2); + m_tree->Branch("fitParam_ndf", &m_fitParam_ndf); + m_tree->Branch("fitParam_nHoles", &m_fitParam_nHoles); + m_tree->Branch("fitParam_nOutliers", &m_fitParam_nOutliers); + m_tree->Branch("fitParam_nStates", &m_fitParam_nStates); + m_tree->Branch("fitParam_nMeasurements", &m_fitParam_nMeasurements); + m_tree->Branch("fitParam_align_stereoId", &m_align_stereoId); + m_tree->Branch("fitParam_align_stationId_sp", &m_align_stationId_sp); + m_tree->Branch("fitParam_align_centery_sp", &m_align_centery_sp); + m_tree->Branch("fitParam_align_layerId_sp", &m_align_layerId_sp); + m_tree->Branch("fitParam_align_moduleId_sp", &m_align_moduleId_sp); + m_tree->Branch("fitParam_align_clustersize_sp", &m_align_clustersize_sp); + m_tree->Branch("fitParam_align_local_derivation_x_x", &m_align_derivation_x_x); + m_tree->Branch("fitParam_align_local_derivation_x_y", &m_align_derivation_x_y); + m_tree->Branch("fitParam_align_local_derivation_x_z", &m_align_derivation_x_z); + m_tree->Branch("fitParam_align_local_derivation_x_rx", &m_align_derivation_x_rx); + m_tree->Branch("fitParam_align_local_derivation_x_ry", &m_align_derivation_x_ry); + m_tree->Branch("fitParam_align_local_derivation_x_rz", &m_align_derivation_x_rz); + m_tree->Branch("fitParam_align_global_derivation_y_x", &m_align_derivation_global_y_x); + m_tree->Branch("fitParam_align_global_derivation_y_y", &m_align_derivation_global_y_y); + m_tree->Branch("fitParam_align_global_derivation_y_z", &m_align_derivation_global_y_z); + m_tree->Branch("fitParam_align_global_derivation_y_rx", &m_align_derivation_global_y_rx); + m_tree->Branch("fitParam_align_global_derivation_y_ry", &m_align_derivation_global_y_ry); + m_tree->Branch("fitParam_align_global_derivation_y_rz", &m_align_derivation_global_y_rz); + m_tree->Branch("fitParam_align_local_residual_x_sp", &m_align_local_residual_x_sp); + m_tree->Branch("fitParam_align_unbiased_sp", &m_align_unbiased_sp); + m_tree->Branch("fitParam_align_local_pull_x_sp", &m_align_local_pull_x_sp); + m_tree->Branch("fitParam_align_local_measured_x_sp", &m_align_local_measured_x_sp); + m_tree->Branch("fitParam_align_local_measured_xe_sp", &m_align_local_measured_xe_sp); + m_tree->Branch("fitParam_align_local_fitted_xe_sp", &m_align_local_fitted_xe_sp); + m_tree->Branch("fitParam_align_local_fitted_x_sp", &m_align_local_fitted_x_sp); + m_tree->Branch("fitParam_align_global_residual_y_sp", &m_align_global_residual_y_sp); + m_tree->Branch("fitParam_align_global_measured_x_sp", &m_align_global_measured_x_sp); + m_tree->Branch("fitParam_align_global_measured_y_sp", &m_align_global_measured_y_sp); + m_tree->Branch("fitParam_align_global_measured_ye_sp", &m_align_global_measured_ye_sp); + m_tree->Branch("fitParam_align_global_measured_z_sp", &m_align_global_measured_z_sp); + m_tree->Branch("fitParam_align_global_fitted_ye_sp", &m_align_global_fitted_ye_sp); + m_tree->Branch("fitParam_align_global_fitted_x_sp", &m_align_global_fitted_x_sp); + m_tree->Branch("fitParam_align_global_fitted_y_sp", &m_align_global_fitted_y_sp); +} + +void CKF2Alignment::clearVariables(){ + m_fitParam_x.clear(); + m_fitParam_charge.clear(); + m_fitParam_y.clear(); + m_fitParam_z.clear(); + m_fitParam_px.clear(); + m_fitParam_py.clear(); + m_fitParam_pz.clear(); + m_fitParam_chi2.clear(); + m_fitParam_ndf.clear(); + m_fitParam_nHoles.clear(); + m_fitParam_nOutliers.clear(); + m_fitParam_nStates.clear(); + m_fitParam_nMeasurements.clear(); + m_align_derivation_x_x.clear(); + m_align_derivation_x_y.clear(); + m_align_derivation_x_z.clear(); + m_align_derivation_x_rx.clear(); + m_align_derivation_x_ry.clear(); + m_align_derivation_x_rz.clear(); + m_align_derivation_global_y_x.clear(); + m_align_derivation_global_y_y.clear(); + m_align_derivation_global_y_z.clear(); + m_align_derivation_global_y_rx.clear(); + m_align_derivation_global_y_ry.clear(); + m_align_derivation_global_y_rz.clear(); + m_align_local_residual_x_sp.clear(); + m_align_unbiased_sp.clear(); + m_align_local_pull_x_sp.clear(); + m_align_local_measured_x_sp.clear(); + m_align_local_measured_xe_sp.clear(); + m_align_local_fitted_xe_sp.clear(); + m_align_local_fitted_x_sp.clear(); + m_align_global_residual_y_sp.clear(); + m_align_global_measured_x_sp.clear(); + m_align_global_measured_y_sp.clear(); + m_align_global_measured_z_sp.clear(); + m_align_global_measured_ye_sp.clear(); + m_align_global_fitted_ye_sp.clear(); + m_align_global_fitted_x_sp.clear(); + m_align_global_fitted_y_sp.clear(); + m_align_stationId_sp.clear(); + m_align_centery_sp.clear(); + m_align_layerId_sp.clear(); + m_align_moduleId_sp.clear(); + m_align_clustersize_sp.clear(); + m_align_stereoId.clear(); +} + + +double CKF2Alignment::getLocalDerivation(Amg::Transform3D trans1, Amg::Vector2D loc_pos, int ia, int side , Amg::Transform3D trans2)const { + double delta[6]={0.001,0.001,0.001,0.0001,0.0001,0.0001}; + auto translation_m = Amg::Translation3D(0,0,0); + Amg::Transform3D transform_m= translation_m* Amg::RotationMatrix3D::Identity(); + auto translation_p = Amg::Translation3D(0,0,0); + Amg::Transform3D transform_p= translation_p* Amg::RotationMatrix3D::Identity(); + switch (ia) + { + case 0: + transform_m *= Amg::Translation3D(0-delta[ia],0,0); + transform_p *= Amg::Translation3D(0+delta[ia],0,0); + break; + case 1: + transform_m *= Amg::Translation3D(0,0-delta[ia],0); + transform_p *= Amg::Translation3D(0,0+delta[ia],0); + break; + case 2: + transform_m *= Amg::Translation3D(0,0,0-delta[ia]); + transform_p *= Amg::Translation3D(0,0,0+delta[ia]); + break; + case 3: + transform_m *= Amg::AngleAxis3D(0-delta[ia], Amg::Vector3D(1,0,0)); + transform_p *= Amg::AngleAxis3D(0+delta[ia], Amg::Vector3D(1,0,0)); + break; + case 4: + transform_m *= Amg::AngleAxis3D(0-delta[ia], Amg::Vector3D(0,1,0)); + transform_p *= Amg::AngleAxis3D(0+delta[ia], Amg::Vector3D(0,1,0)); + break; + case 5: + transform_m *= Amg::AngleAxis3D(0-delta[ia], Amg::Vector3D(0,0,1)); + transform_p *= Amg::AngleAxis3D(0+delta[ia], Amg::Vector3D(0,0,1)); + break; + default: + ATH_MSG_FATAL("Unknown alignment parameter" ); + break; + } + + auto local3 = Amg::Vector3D(loc_pos.x(),loc_pos.y(),0.); + Amg::Vector3D glo_pos = trans1 * local3; + Amg::Vector3D local_m = (trans1 * transform_m).inverse()*glo_pos; + Amg::Vector3D local_p = (trans1 * transform_p).inverse()*glo_pos; + if(side!=1) + return (local_p.x()-local_m.x())/2./delta[ia]; + else{ + Amg::Vector3D local_m2=trans2.inverse()*trans1*local_m; + Amg::Vector3D local_p2=trans2.inverse()*trans1*local_p; + return (local_p2.x()-local_m2.x())/2./delta[ia]; + } +} + + +double CKF2Alignment::getDerivation(const EventContext& ctx, Acts::BoundTrackParameters& fitParameters, Amg::Transform3D trans1, Amg::Vector2D loc_pos, int ia, int side , Amg::Transform3D trans2, int global)const { + double delta[6]={0.001,0.001,0.001,0.0001,0.0001,0.0001}; + auto translation_m = Amg::Translation3D(0,0,0); + Amg::Transform3D transform_m= translation_m* Amg::RotationMatrix3D::Identity(); + auto translation_p = Amg::Translation3D(0,0,0); + Amg::Transform3D transform_p= translation_p* Amg::RotationMatrix3D::Identity(); + switch (ia) + { + case 0: + transform_m *= Amg::Translation3D(0-delta[ia],0,0); + transform_p *= Amg::Translation3D(0+delta[ia],0,0); + break; + case 1: + transform_m *= Amg::Translation3D(0,0-delta[ia],0); + transform_p *= Amg::Translation3D(0,0+delta[ia],0); + break; + case 2: + transform_m *= Amg::Translation3D(0,0,0-delta[ia]); + transform_p *= Amg::Translation3D(0,0,0+delta[ia]); + break; + case 3: + transform_m *= Amg::AngleAxis3D(0-delta[ia], Amg::Vector3D(1,0,0)); + transform_p *= Amg::AngleAxis3D(0+delta[ia], Amg::Vector3D(1,0,0)); + break; + case 4: + transform_m *= Amg::AngleAxis3D(0-delta[ia], Amg::Vector3D(0,1,0)); + transform_p *= Amg::AngleAxis3D(0+delta[ia], Amg::Vector3D(0,1,0)); + break; + case 5: + transform_m *= Amg::AngleAxis3D(0-delta[ia], Amg::Vector3D(0,0,1)); + transform_p *= Amg::AngleAxis3D(0+delta[ia], Amg::Vector3D(0,0,1)); + break; + default: + ATH_MSG_FATAL("Unknown alignment parameter" ); + break; + } + + auto local3 = Amg::Vector3D(loc_pos.x(),loc_pos.y(),0.); + Amg::Vector3D glo_pos = trans2 * local3; + auto trans_m = trans1 * transform_m; + auto trans_p = trans1 * transform_p; + if(side==1 && global!=1){ + trans_m = trans1 * transform_m * trans1.inverse() * trans2; + trans_p = trans1 * transform_p * trans1.inverse() * trans2; + } + if (global==1){ + Amg::Transform3D trans_g = Amg::Translation3D(0,0, glo_pos.z()) * Amg::RotationMatrix3D::Identity(); + auto trans_l2g = trans_g.inverse()*trans1; + trans_m = trans1 * trans_l2g.inverse() * transform_m * trans_l2g; + trans_p = trans1 * trans_l2g.inverse() * transform_p * trans_l2g; + if(side==1){ + auto tmpm = trans_m; + auto tmpp = trans_p; + trans_m = tmpm * trans1.inverse() * trans2; + trans_p = tmpp * trans1.inverse() * trans2; + } + } + + Amg::Transform3D ini_trans = Amg::Translation3D(0,0, glo_pos.z()-10) * Amg::RotationMatrix3D::Identity(); + auto ini_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(ini_trans, std::make_shared<const Acts::RectangleBounds>(1000.,1000.)); + std::unique_ptr<const Acts::BoundTrackParameters> ini_Param = m_extrapolationTool->propagate( ctx, fitParameters, *ini_surface, Acts::backward); + if(ini_Param==nullptr)return -9999.; + + + auto shift_m_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(trans_m, std::make_shared<const Acts::RectangleBounds>(1000.,1000.)); + auto shift_p_surface = Acts::Surface::makeShared<Acts::PlaneSurface>(trans_p, std::make_shared<const Acts::RectangleBounds>(1000.,1000.)); + auto shift_m_Param = m_extrapolationTool->propagate( ctx, *ini_Param, *shift_m_surface, Acts::forward); + auto shift_p_Param = m_extrapolationTool->propagate( ctx, *ini_Param, *shift_p_surface, Acts::forward); + if(shift_m_Param!=nullptr||shift_p_Param!=nullptr){ + auto shift_m_parameter = shift_m_Param->parameters(); + auto shift_p_parameter = shift_p_Param->parameters(); + Amg::Vector2D local_m(shift_m_parameter[Acts::eBoundLoc0],shift_m_parameter[Acts::eBoundLoc1]); + Amg::Vector2D local_p(shift_p_parameter[Acts::eBoundLoc0],shift_p_parameter[Acts::eBoundLoc1]); + return (local_p.x()-local_m.x())/2./delta[ia]; + } + return -99999.; +} + diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/CKF2Alignment.h b/Tracking/Acts/FaserActsKalmanFilter/src/CKF2Alignment.h new file mode 100755 index 0000000000000000000000000000000000000000..1cc5f368942797b2a193ed69fdebf4bf2db2df4c --- /dev/null +++ b/Tracking/Acts/FaserActsKalmanFilter/src/CKF2Alignment.h @@ -0,0 +1,199 @@ +#ifndef FASERACTSKALMANFILTER_CKF2ALIGNMENT_H +#define FASERACTSKALMANFILTER_CKF2ALIGNMENT_H + + +#include "AthenaBaseComps/AthReentrantAlgorithm.h" +#include "AthenaBaseComps/AthAlgorithm.h" +#include "TrackerSpacePoint/FaserSCT_SpacePointContainer.h" +#include "TrackerPrepRawData/FaserSCT_ClusterContainer.h" +#include "FaserActsGeometryInterfaces/IFaserActsTrackingGeometryTool.h" +#include "FaserActsGeometryInterfaces/IFaserActsExtrapolationTool.h" +#include "Acts/TrackFitting/KalmanFitter.hpp" +#include "Acts/TrackFinding/CombinatorialKalmanFilter.hpp" +#include "Acts/TrackFinding/MeasurementSelector.hpp" +#include "FaserActsKalmanFilter/Measurement.h" +#include "MagFieldConditions/FaserFieldCacheCondObj.h" +#include "TrkTrack/TrackCollection.h" +#include "FaserActsKalmanFilter/ITrackSeedTool.h" +#include "KalmanFitterTool.h" +#include <boost/dynamic_bitset.hpp> +#include "GaudiKernel/ITHistSvc.h" +#include "CreateTrkTrackTool.h" + +using ConstTrackStateProxy = Acts::detail_lt::TrackStateProxy<IndexSourceLink, 6, true>; +using ClusterSet = boost::dynamic_bitset<>; + +class TTree; +class FaserSCT_ID; + + +namespace TrackerDD { + class SCT_DetectorManager; +} + +class CKF2Alignment : public AthAlgorithm { + public: + CKF2Alignment(const std::string& name, ISvcLocator* pSvcLocator); + virtual ~CKF2Alignment() = default; + + StatusCode initialize() override; + StatusCode execute() override; + StatusCode finalize() override; + void initializeTree(); + void clearVariables(); + + using TrackFinderOptions = + Acts::CombinatorialKalmanFilterOptions<IndexSourceLinkAccessor, + MeasurementCalibrator, + Acts::MeasurementSelector>; + using CKFResult = Acts::CombinatorialKalmanFilterResult<IndexSourceLink>; + using TrackFitterResult = Acts::Result<CKFResult>; + using TrackFinderResult = std::vector<TrackFitterResult>; + + using KFResult = + Acts::Result<Acts::KalmanFitterResult<IndexSourceLink>>; + + using TrackFitterOptions = + Acts::KalmanFitterOptions<MeasurementCalibrator, Acts::VoidOutlierFinder, + Acts::VoidReverseFilteringLogic>; + + using TrackParameters = Acts::CurvilinearTrackParameters; + using TrackParametersContainer = std::vector<TrackParameters>; + + // Track Finding + class TrackFinderFunction { + public: + virtual ~TrackFinderFunction() = default; + virtual TrackFinderResult operator()(const IndexSourceLinkContainer&, + const TrackParametersContainer&, + const TrackFinderOptions&) const = 0; + }; + + static std::shared_ptr<TrackFinderFunction> makeTrackFinderFunction( + std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry, + bool resolvePassive, bool resolveMaterial, bool resolveSensitive); + + // Track Fitting + class TrackFitterFunction { + public: + virtual ~TrackFitterFunction() = default; + virtual KFResult operator()(const std::vector<IndexSourceLink>&, + const Acts::BoundTrackParameters&, + const TrackFitterOptions&) const = 0; + }; + + struct TrajectoryInfo { + TrajectoryInfo(const FaserActsRecMultiTrajectory &traj) : + trajectory{traj}, clusterSet{nClusters} { + auto state = Acts::MultiTrajectoryHelpers::trajectoryState(traj.multiTrajectory(), traj.tips().front()); + traj.multiTrajectory().visitBackwards(traj.tips().front(), [&](const ConstTrackStateProxy& state) { + auto typeFlags = state.typeFlags(); + if (not typeFlags.test(Acts::TrackStateFlag::MeasurementFlag)) { + return true; + } + clusterSet.set(state.uncalibrated().index()); + return true; + }); + nMeasurements = state.nMeasurements; + chi2 = state.chi2Sum; + } + + static size_t nClusters; + FaserActsRecMultiTrajectory trajectory; + ClusterSet clusterSet; + size_t nMeasurements; + double chi2; + }; + + static std::shared_ptr<TrackFitterFunction> makeTrackFitterFunction( + std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry); + + virtual Acts::MagneticFieldContext getMagneticFieldContext(const EventContext& ctx) const; + + private: + int m_numberOfEvents {0}; + int m_numberOfTrackSeeds {0}; + int m_numberOfFittedTracks {0}; + int m_numberOfSelectedTracks {0}; + + void computeSharedHits(std::vector<IndexSourceLink>* sourceLinks, TrackFinderResult& results) const; + std::shared_ptr<TrackFinderFunction> m_fit; + std::shared_ptr<TrackFitterFunction> m_kf; + std::unique_ptr<const Acts::Logger> m_logger; + const FaserSCT_ID* m_idHelper {nullptr}; + const TrackerDD::SCT_DetectorManager* m_detManager {nullptr}; + + Gaudi::Property<bool> m_biased{this, "BiasedResidual", true}; + Gaudi::Property<std::string> m_actsLogging {this, "ActsLogging", "VERBOSE"}; + Gaudi::Property<int> m_minNumberMeasurements {this, "MinNumberMeasurements", 12}; + Gaudi::Property<bool> m_resolvePassive {this, "resolvePassive", false}; + Gaudi::Property<bool> m_resolveMaterial {this, "resolveMaterial", true}; + Gaudi::Property<bool> m_resolveSensitive {this, "resolveSensitive", true}; + Gaudi::Property<double> m_maxSteps {this, "maxSteps", 10000}; + Gaudi::Property<double> m_chi2Max {this, "chi2Max", 15}; + Gaudi::Property<unsigned long> m_nMax {this, "nMax", 10}; + SG::ReadCondHandleKey<FaserFieldCacheCondObj> m_fieldCondObjInputKey {this, "FaserFieldCacheCondObj", "fieldCondObj", "Name of the Magnetic Field conditions object key"}; + ToolHandle<ITrackSeedTool> m_trackSeedTool {this, "TrackSeed", "ClusterTrackSeedTool"}; + ToolHandle<IFaserActsTrackingGeometryTool> m_trackingGeometryTool {this, "TrackingGeometryTool", "FaserActsTrackingGeometryTool"}; + ToolHandle<KalmanFitterTool> m_kalmanFitterTool1 {this, "KalmanFitterTool1", "KalmanFitterTool"}; + ToolHandle<CreateTrkTrackTool> m_createTrkTrackTool {this, "CreateTrkTrackTool", "CreateTrkTrackTool"}; + Gaudi::Property<bool> m_isMC {this, "isMC", false}; + ToolHandle<IFaserActsExtrapolationTool> m_extrapolationTool{this, "ExtrapolationTool", "FaserActsExtrapolationTool"}; + + double getDerivation(const EventContext& ctx, Acts::BoundTrackParameters& fitParameters, Amg::Transform3D trans1, Amg::Vector2D loc_pos, int ia, int side , Amg::Transform3D trans2, int global)const ; + double getLocalDerivation(Amg::Transform3D trans1, Amg::Vector2D loc_pos, int ia, int side , Amg::Transform3D trans2)const; + //output ntuple + ServiceHandle<ITHistSvc> m_thistSvc; + TTree* m_tree; + mutable int m_eventId=0; + mutable int m_trackId=0; + mutable std::vector<double> m_fitParam_x; + mutable std::vector<double> m_fitParam_charge; + mutable std::vector<double> m_fitParam_y; + mutable std::vector<double> m_fitParam_z; + mutable std::vector<double> m_fitParam_px; + mutable std::vector<double> m_fitParam_py; + mutable std::vector<double> m_fitParam_pz; + mutable std::vector<double> m_fitParam_chi2; + mutable std::vector<int> m_fitParam_ndf; + mutable std::vector<int> m_fitParam_nHoles; + mutable std::vector<int> m_fitParam_nOutliers; + mutable std::vector<int> m_fitParam_nStates; + mutable std::vector<int> m_fitParam_nMeasurements; + mutable std::vector<std::vector<double>> m_align_stationId_sp; + mutable std::vector<std::vector<double>> m_align_centery_sp; + mutable std::vector<std::vector<double>> m_align_layerId_sp; + mutable std::vector<std::vector<double>> m_align_moduleId_sp; + mutable std::vector<std::vector<double>> m_align_clustersize_sp; + mutable std::vector<std::vector<double>> m_align_global_residual_y_sp; + mutable std::vector<std::vector<double>> m_align_global_measured_x_sp; + mutable std::vector<std::vector<double>> m_align_global_measured_y_sp; + mutable std::vector<std::vector<double>> m_align_global_measured_z_sp; + mutable std::vector<std::vector<double>> m_align_global_measured_ye_sp; + mutable std::vector<std::vector<double>> m_align_global_fitted_ye_sp; + mutable std::vector<std::vector<double>> m_align_global_fitted_y_sp; + mutable std::vector<std::vector<double>> m_align_global_fitted_x_sp; + mutable std::vector<std::vector<double>> m_align_local_residual_x_sp; + mutable std::vector<std::vector<double>> m_align_unbiased_sp; + mutable std::vector<std::vector<double>> m_align_local_pull_x_sp; + mutable std::vector<std::vector<double>> m_align_local_measured_x_sp; + mutable std::vector<std::vector<double>> m_align_local_measured_xe_sp; + mutable std::vector<std::vector<double>> m_align_local_fitted_xe_sp; + mutable std::vector<std::vector<double>> m_align_local_fitted_x_sp; + mutable std::vector<std::vector<double>> m_align_derivation_x_x; + mutable std::vector<std::vector<double>> m_align_derivation_x_y; + mutable std::vector<std::vector<double>> m_align_derivation_x_z; + mutable std::vector<std::vector<double>> m_align_derivation_x_rx; + mutable std::vector<std::vector<double>> m_align_derivation_x_ry; + mutable std::vector<std::vector<double>> m_align_derivation_x_rz; + mutable std::vector<std::vector<double>> m_align_derivation_global_y_x; + mutable std::vector<std::vector<double>> m_align_derivation_global_y_y; + mutable std::vector<std::vector<double>> m_align_derivation_global_y_z; + mutable std::vector<std::vector<double>> m_align_derivation_global_y_rx; + mutable std::vector<std::vector<double>> m_align_derivation_global_y_ry; + mutable std::vector<std::vector<double>> m_align_derivation_global_y_rz; + mutable std::vector<std::vector<double>> m_align_stereoId; +}; + +#endif // FASERACTSKALMANFILTER_CKF2Alignment_H + diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/CircleFitTrackSeedTool.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/CircleFitTrackSeedTool.cxx index 41611bad5882de7e15ce3de15f6c4833fbf10581..952f75287f594e5df31feb2b6a493bfe235a4086 100644 --- a/Tracking/Acts/FaserActsKalmanFilter/src/CircleFitTrackSeedTool.cxx +++ b/Tracking/Acts/FaserActsKalmanFilter/src/CircleFitTrackSeedTool.cxx @@ -7,7 +7,6 @@ #include "Identifier/Identifier.h" #include "Acts/Geometry/GeometryIdentifier.hpp" #include "CircleFit.h" -#include "Identifier/Identifier.h" #include "LinearFit.h" #include "TrackClassification.h" #include <array> @@ -80,12 +79,14 @@ StatusCode CircleFitTrackSeedTool::run(std::vector<int> maskedLayers) { if (std::find(maskedLayers.begin(), maskedLayers.end(), 3 * m_idHelper->station(id) + m_idHelper->layer(id)) != maskedLayers.end()) { continue; } +// if(m_idHelper->station(id)==0) continue; CircleFitTrackSeedTool::s_indexMap[cluster->identify()] = measurements.size(); if (identifierMap->count(id) != 0) { Acts::GeometryIdentifier geoId = identifierMap->at(id); IndexSourceLink sourceLink(geoId, measurements.size(), cluster); // create measurement const auto& par = cluster->localPosition(); + auto cova = cluster->localCovariance(); Eigen::Matrix<double, 1, 1> pos {par.x(),}; Eigen::Matrix<double, 1, 1> cov {0.0231 * 0.0231,}; ThisMeasurement meas(sourceLink, Indices, pos, cov); @@ -101,7 +102,13 @@ StatusCode CircleFitTrackSeedTool::run(std::vector<int> maskedLayers) { std::array<std::vector<Segment>, 4> segments {}; for (const Trk::Track* track : *trackCollection) { auto s = Segment(track, m_idHelper, maskedLayers); + //remove IFT in seeding + if(m_removeIFT){ + if (s.station != -1 &&s.station != 0) segments[s.station].push_back(s); + } + else{ if (s.station != -1) segments[s.station].push_back(s); + } } std::vector<Segment> combination {}; @@ -151,7 +158,7 @@ StatusCode CircleFitTrackSeedTool::run(std::vector<int> maskedLayers) { selectedSeeds.begin(), selectedSeeds.end(), [](const Seed &lhs, const Seed &rhs) { return lhs.minZ < rhs.minZ; }); - double origin = !selectedSeeds.empty() ? minSeed->minZ - 1 : 0; + double origin = !selectedSeeds.empty() ? minSeed->minZ - 10 : 0; m_targetZPosition = origin; std::vector<Acts::CurvilinearTrackParameters> initParams {}; for (const Seed &seed : selectedSeeds) { @@ -212,6 +219,7 @@ CircleFitTrackSeedTool::Segment::Segment(const Trk::Track* track, const FaserSCT } } station = idHelper->station(id); +// if(station==0)continue; clusterSet.set(CircleFitTrackSeedTool::s_indexMap.at(id)); auto fitParameters = track->trackParameters()->front(); position = fitParameters->position(); @@ -265,12 +273,11 @@ CircleFitTrackSeedTool::Seed::Seed(const std::vector<Segment> &segments) : size = clusters.size(); } + void CircleFitTrackSeedTool::Seed::fit() { CircleFit::CircleData circleData(positions); CircleFit::Circle circle = CircleFit::circleFit(circleData); momentum = circle.r > 0 ? circle.r * 0.001 * 0.3 * 0.55 : 9999999.; - // the magnetic field bends a positively charged particle downwards, thus the - // y-component of the center of a fitted circle is negative. charge = circle.cy < 0 ? 1 : -1; } @@ -281,8 +288,6 @@ void CircleFitTrackSeedTool::Seed::fakeFit(double B) { cy = circle.cy; r = circle.r; momentum = r * 0.3 * B * m_MeV2GeV; - // the magnetic field bends a positively charged particle downwards, thus the - // y-component of the center of a fitted circle is negative. charge = circle.cy < 0 ? 1 : -1; } @@ -292,6 +297,7 @@ void CircleFitTrackSeedTool::Seed::linearFit(const std::vector<Acts::Vector2> &p c0 = origin[1] - origin[0] * c1; } + double CircleFitTrackSeedTool::Seed::getY(double z) { double sqt = std::sqrt(-cx*cx + 2*cx*z + r*r - z*z); return abs(cy - sqt) < abs(cy + sqt) ? cy - sqt : cy + sqt; diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/CircleFitTrackSeedTool.h b/Tracking/Acts/FaserActsKalmanFilter/src/CircleFitTrackSeedTool.h index 7866b89fc32fe2ccd8a0391f421b1d203ff1e8e0..0467c92620eebd955f0a78f11cfdea3fd0cb0b1d 100644 --- a/Tracking/Acts/FaserActsKalmanFilter/src/CircleFitTrackSeedTool.h +++ b/Tracking/Acts/FaserActsKalmanFilter/src/CircleFitTrackSeedTool.h @@ -116,6 +116,7 @@ private: Gaudi::Property<double> m_covTheta {this, "covTheta", 1}; Gaudi::Property<double> m_covQOverP {this, "covQOverP", 1}; Gaudi::Property<double> m_covTime {this, "covTime", 1}; + Gaudi::Property<bool> m_removeIFT{this, "removeIFT", false}; }; inline const std::shared_ptr<std::vector<Acts::CurvilinearTrackParameters>> diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.cxx index 051687e21c6d0b1c1874a26ac4ddeb5d55c55124..c0d02183f5616df5b624152fee61d4c1bf6bba37 100644 --- a/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.cxx +++ b/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.cxx @@ -39,6 +39,329 @@ StatusCode KalmanFitterTool::finalize() { return StatusCode::SUCCESS; } +//get the unbiased residual for the cluster at Z = clusz +//output is a vector of the outliers +// +std::vector<TSOS4Residual> +KalmanFitterTool::getUnbiasedResidual(const EventContext &ctx, const Acts::GeometryContext &gctx, + Trk::Track* inputTrack, double clusz, const Acts::BoundVector& inputVector, + bool isMC, double origin) const { + std::vector<TSOS4Residual> resi; + resi.clear(); + std::vector<FaserActsRecMultiTrajectory> myTrajectories; + ATH_MSG_DEBUG("start kalmanfilter "<<inputTrack->measurementsOnTrack()->size()<<" "<<origin<<" "<<clusz); + + if (!inputTrack->measurementsOnTrack() || inputTrack->measurementsOnTrack()->size() < m_minMeasurements) { + ATH_MSG_DEBUG("Input track has no or too little measurements and cannot be fitted"); + return resi; + } + + if (!inputTrack->trackParameters() || inputTrack->trackParameters()->empty()) { + ATH_MSG_DEBUG("Input track has no track parameters and cannot be fitted"); + return resi; + } + + + auto pSurface = Acts::Surface::makeShared<Acts::PlaneSurface>( + Acts::Vector3 {0, 0, origin}, Acts::Vector3{0, 0, -1}); + + Acts::MagneticFieldContext mfContext = getMagneticFieldContext(ctx); + Acts::CalibrationContext calibContext = Acts::CalibrationContext(); + + auto [sourceLinks, measurements] = getMeasurementsFromTrack(inputTrack); + auto trackParameters = getParametersFromTrack(inputTrack->trackParameters()->front(), inputVector, origin); + ATH_MSG_DEBUG("trackParameters: " << trackParameters.parameters().transpose()); + ATH_MSG_DEBUG("position: " << trackParameters.position(gctx).transpose()); + ATH_MSG_DEBUG("momentum: " << trackParameters.momentum().transpose()); + ATH_MSG_DEBUG("charge: " << trackParameters.charge()); + ATH_MSG_DEBUG("size of measurements : " << sourceLinks.size()); + + FaserActsOutlierFinder faserActsOutlierFinder{0}; + faserActsOutlierFinder.cluster_z=clusz; + faserActsOutlierFinder.StateChiSquaredPerNumberDoFCut=10000.; + Acts::KalmanFitterOptions<MeasurementCalibrator, FaserActsOutlierFinder, Acts::VoidReverseFilteringLogic> + kfOptions(gctx, mfContext, calibContext, MeasurementCalibrator(measurements), + faserActsOutlierFinder, Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, + //FaserActsOutlierFinder(), Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, + //Acts::VoidOutlierFinder(), Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, + Acts::PropagatorPlainOptions(), &(*pSurface)); + kfOptions.multipleScattering = false; + kfOptions.energyLoss = false; + + ATH_MSG_DEBUG("Invoke fitter"); + auto result = (*m_fit)(sourceLinks, trackParameters, kfOptions); + + if (result.ok()) { + const auto& fitOutput = result.value(); + if (fitOutput.fittedParameters) { + const auto& params = fitOutput.fittedParameters.value(); + ATH_MSG_DEBUG("ReFitted parameters"); + ATH_MSG_DEBUG(" params: " << params.parameters().transpose()); + ATH_MSG_DEBUG(" position: " << params.position(gctx).transpose()); + ATH_MSG_DEBUG(" momentum: " << params.momentum().transpose()); + ATH_MSG_DEBUG(" charge: " << params.charge()); + using IndexedParams = std::unordered_map<size_t, Acts::BoundTrackParameters>; + IndexedParams indexedParams; + indexedParams.emplace(fitOutput.lastMeasurementIndex, std::move(params)); + std::vector<size_t> trackTips; + trackTips.reserve(1); + trackTips.emplace_back(fitOutput.lastMeasurementIndex); + myTrajectories.emplace_back(std::move(fitOutput.fittedStates), + std::move(trackTips), + std::move(indexedParams)); + for (const FaserActsRecMultiTrajectory &traj : myTrajectories) { + const auto& mj = traj.multiTrajectory(); + const auto& trackTips = traj.tips(); + if(trackTips.empty())continue; + auto& trackTip = trackTips.front(); + mj.visitBackwards(trackTip, [&](const auto &state) { + auto typeFlags = state.typeFlags(); + if (not typeFlags.test(Acts::TrackStateFlag::OutlierFlag)) + { + return true; + } + + if (state.hasUncalibrated()&&state.hasSmoothed()) { + Acts::BoundTrackParameters parameter( + state.referenceSurface().getSharedPtr(), + state.smoothed(), + state.smoothedCovariance()); + auto covariance = state.smoothedCovariance(); + auto H = state.effectiveProjector(); + auto residual = state.effectiveCalibrated() - H * state.smoothed(); + const Tracker::FaserSCT_Cluster* cluster = state.uncalibrated().hit(); + const auto& surface = state.referenceSurface(); + Acts::BoundVector meas = state.projector().transpose() * state.calibrated(); + Acts::Vector2 local(meas[Acts::eBoundLoc0], meas[Acts::eBoundLoc1]); + const Acts::Vector3 dir = Acts::makeDirectionUnitFromPhiTheta(meas[Acts::eBoundPhi], meas[Acts::eBoundTheta]); + resi.push_back({local.x(),local.y(),parameter.position(gctx).x(), parameter.position(gctx).y(), parameter.position(gctx).z(), cluster,residual(Acts::eBoundLoc0),parameter}); + ATH_MSG_DEBUG(" residual/global position: " << residual(Acts::eBoundLoc0)<<" "<<parameter.position(gctx).x()<<" "<<parameter.position(gctx).y()<<" "<<parameter.position(gctx).z()); + } + return true; + }); + + } + + } else { + ATH_MSG_DEBUG("No fitted parameters for track"); + } + } + return resi; + +} + +//get the unbiased residual for IFT, i.e. remove whole IFT in the track fitting +//output is a vector of the outliers +// +std::vector<TSOS4Residual> +KalmanFitterTool::getUnbiasedResidual(const EventContext &ctx, const Acts::GeometryContext &gctx, + Trk::Track* inputTrack, const Acts::BoundVector& inputVector, + bool isMC, double origin, std::vector<const Tracker::FaserSCT_Cluster*>& clusters, const Acts::BoundTrackParameters ini_Param) const { + std::vector<TSOS4Residual> resi; + resi.clear(); + std::vector<FaserActsRecMultiTrajectory> myTrajectories; + + if (!inputTrack->measurementsOnTrack() || inputTrack->measurementsOnTrack()->size() < m_minMeasurements) { + ATH_MSG_DEBUG("Input track has no or too little measurements and cannot be fitted"); + return resi; + } + + if (!inputTrack->trackParameters() || inputTrack->trackParameters()->empty()) { + ATH_MSG_DEBUG("Input track has no track parameters and cannot be fitted"); + return resi; + } + + + auto pSurface = Acts::Surface::makeShared<Acts::PlaneSurface>( + Acts::Vector3 {0, 0, origin}, Acts::Vector3{0, 0, -1}); + + Acts::MagneticFieldContext mfContext = getMagneticFieldContext(ctx); + Acts::CalibrationContext calibContext = Acts::CalibrationContext(); + + auto [sourceLinks, measurements] = getMeasurementsFromTrack(inputTrack/*, wafer_id*/, clusters); + ATH_MSG_DEBUG("trackParameters: " << ini_Param.parameters().transpose()); + ATH_MSG_DEBUG("position: " << ini_Param.position(gctx).transpose()); + ATH_MSG_DEBUG("momentum: " << ini_Param.momentum().transpose()); + ATH_MSG_DEBUG("charge: " << ini_Param.charge()); + + FaserActsOutlierFinder faserActsOutlierFinder{0}; + faserActsOutlierFinder.cluster_z=-1000000.; + faserActsOutlierFinder.StateChiSquaredPerNumberDoFCut=10000.; + Acts::KalmanFitterOptions<MeasurementCalibrator, FaserActsOutlierFinder, Acts::VoidReverseFilteringLogic> + kfOptions(gctx, mfContext, calibContext, MeasurementCalibrator(measurements), + faserActsOutlierFinder, Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, + Acts::PropagatorPlainOptions(), &(*pSurface)); + kfOptions.multipleScattering = false; + kfOptions.energyLoss = false; + + ATH_MSG_DEBUG("Invoke fitter"); + auto result = (*m_fit)(sourceLinks, ini_Param, kfOptions); + + if (result.ok()) { + const auto& fitOutput = result.value(); + if (fitOutput.fittedParameters) { + const auto& params = fitOutput.fittedParameters.value(); + ATH_MSG_DEBUG("ReFitted parameters"); + ATH_MSG_DEBUG(" params: " << params.parameters().transpose()); + ATH_MSG_DEBUG(" position: " << params.position(gctx).transpose()); + ATH_MSG_DEBUG(" momentum: " << params.momentum().transpose()); + ATH_MSG_DEBUG(" charge: " << params.charge()); + using IndexedParams = std::unordered_map<size_t, Acts::BoundTrackParameters>; + IndexedParams indexedParams; + indexedParams.emplace(fitOutput.lastMeasurementIndex, std::move(params)); + std::vector<size_t> trackTips; + trackTips.reserve(1); + trackTips.emplace_back(fitOutput.lastMeasurementIndex); + myTrajectories.emplace_back(std::move(fitOutput.fittedStates), + std::move(trackTips), + std::move(indexedParams)); + for (const FaserActsRecMultiTrajectory &traj : myTrajectories) { + const auto& mj = traj.multiTrajectory(); + const auto& trackTips = traj.tips(); + if(trackTips.empty())continue; + auto& trackTip = trackTips.front(); + mj.visitBackwards(trackTip, [&](const auto &state) { + auto typeFlags = state.typeFlags(); + if (not typeFlags.test(Acts::TrackStateFlag::OutlierFlag)) + { + return true; + } + + if (state.hasUncalibrated()&&state.hasSmoothed()) { + Acts::BoundTrackParameters parameter( + state.referenceSurface().getSharedPtr(), + state.smoothed(), + state.smoothedCovariance()); + auto covariance = state.smoothedCovariance(); + auto H = state.effectiveProjector(); + auto residual = state.effectiveCalibrated() - H * state.smoothed(); + const Tracker::FaserSCT_Cluster* cluster = state.uncalibrated().hit(); + const auto& surface = state.referenceSurface(); + Acts::BoundVector meas = state.projector().transpose() * state.calibrated(); + Acts::Vector2 local(meas[Acts::eBoundLoc0], meas[Acts::eBoundLoc1]); + const Acts::Vector3 dir = Acts::makeDirectionUnitFromPhiTheta(meas[Acts::eBoundPhi], meas[Acts::eBoundTheta]); + resi.push_back({local.x(),local.y(),parameter.position(gctx).x(), parameter.position(gctx).y(), parameter.position(gctx).z(), cluster,residual(Acts::eBoundLoc0),parameter}); + } + return true; + }); + + } + + } else { + ATH_MSG_DEBUG("No fitted parameters for track"); + } + } + return resi; + +} + +//get the unbiased residual for IFT, i.e. remove whole IFT in the track fitting +//output is a vector of the outliers +// +std::vector<TSOS4Residual> +KalmanFitterTool::getUnbiasedResidual(const EventContext &ctx, const Acts::GeometryContext &gctx, + Trk::Track* inputTrack, const Acts::BoundVector& inputVector, + bool isMC, double origin) const { + std::vector<TSOS4Residual> resi; + resi.clear(); + std::vector<FaserActsRecMultiTrajectory> myTrajectories; + + if (!inputTrack->measurementsOnTrack() || inputTrack->measurementsOnTrack()->size() < m_minMeasurements) { + ATH_MSG_DEBUG("Input track has no or too little measurements and cannot be fitted"); + return resi; + } + + if (!inputTrack->trackParameters() || inputTrack->trackParameters()->empty()) { + ATH_MSG_DEBUG("Input track has no track parameters and cannot be fitted"); + return resi; + } + + + auto pSurface = Acts::Surface::makeShared<Acts::PlaneSurface>( + Acts::Vector3 {0, 0, origin}, Acts::Vector3{0, 0, -1}); + + Acts::MagneticFieldContext mfContext = getMagneticFieldContext(ctx); + Acts::CalibrationContext calibContext = Acts::CalibrationContext(); + + auto [sourceLinks, measurements] = getMeasurementsFromTrack(inputTrack/*, wafer_id*/); + auto trackParameters = getParametersFromTrack(inputTrack->trackParameters()->front(), inputVector, origin); + ATH_MSG_DEBUG("trackParameters: " << trackParameters.parameters().transpose()); + ATH_MSG_DEBUG("position: " << trackParameters.position(gctx).transpose()); + ATH_MSG_DEBUG("momentum: " << trackParameters.momentum().transpose()); + ATH_MSG_DEBUG("charge: " << trackParameters.charge()); + + + FaserActsOutlierFinder faserActsOutlierFinder{0}; + faserActsOutlierFinder.cluster_z=-1000000.; + faserActsOutlierFinder.StateChiSquaredPerNumberDoFCut=10000.; + Acts::KalmanFitterOptions<MeasurementCalibrator, FaserActsOutlierFinder, Acts::VoidReverseFilteringLogic> + kfOptions(gctx, mfContext, calibContext, MeasurementCalibrator(measurements), + faserActsOutlierFinder, Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, + Acts::PropagatorPlainOptions(), &(*pSurface)); + kfOptions.multipleScattering = false; + kfOptions.energyLoss = false; + + ATH_MSG_DEBUG("Invoke fitter"); + auto result = (*m_fit)(sourceLinks, trackParameters, kfOptions); + + if (result.ok()) { + const auto& fitOutput = result.value(); + if (fitOutput.fittedParameters) { + const auto& params = fitOutput.fittedParameters.value(); + ATH_MSG_DEBUG("ReFitted parameters"); + ATH_MSG_DEBUG(" params: " << params.parameters().transpose()); + ATH_MSG_DEBUG(" position: " << params.position(gctx).transpose()); + ATH_MSG_DEBUG(" momentum: " << params.momentum().transpose()); + ATH_MSG_DEBUG(" charge: " << params.charge()); + using IndexedParams = std::unordered_map<size_t, Acts::BoundTrackParameters>; + IndexedParams indexedParams; + indexedParams.emplace(fitOutput.lastMeasurementIndex, std::move(params)); + std::vector<size_t> trackTips; + trackTips.reserve(1); + trackTips.emplace_back(fitOutput.lastMeasurementIndex); + myTrajectories.emplace_back(std::move(fitOutput.fittedStates), + std::move(trackTips), + std::move(indexedParams)); + for (const FaserActsRecMultiTrajectory &traj : myTrajectories) { + const auto& mj = traj.multiTrajectory(); + const auto& trackTips = traj.tips(); + if(trackTips.empty())continue; + auto& trackTip = trackTips.front(); + mj.visitBackwards(trackTip, [&](const auto &state) { + auto typeFlags = state.typeFlags(); + if (not typeFlags.test(Acts::TrackStateFlag::OutlierFlag)) + { + return true; + } + + if (state.hasUncalibrated()&&state.hasSmoothed()) { + Acts::BoundTrackParameters parameter( + state.referenceSurface().getSharedPtr(), + state.smoothed(), + state.smoothedCovariance()); + auto covariance = state.smoothedCovariance(); + auto H = state.effectiveProjector(); + auto residual = state.effectiveCalibrated() - H * state.smoothed(); + const Tracker::FaserSCT_Cluster* cluster = state.uncalibrated().hit(); + const auto& surface = state.referenceSurface(); + Acts::BoundVector meas = state.projector().transpose() * state.calibrated(); + Acts::Vector2 local(meas[Acts::eBoundLoc0], meas[Acts::eBoundLoc1]); + const Acts::Vector3 dir = Acts::makeDirectionUnitFromPhiTheta(meas[Acts::eBoundPhi], meas[Acts::eBoundTheta]); +resi.push_back({local.x(),local.y(),parameter.position(gctx).x(), parameter.position(gctx).y(), parameter.position(gctx).z(), cluster,residual(Acts::eBoundLoc0),parameter}); + } + return true; + }); + + } + + } else { + ATH_MSG_DEBUG("No fitted parameters for track"); + } + } + return resi; + +} + std::unique_ptr<Trk::Track> KalmanFitterTool::fit(const EventContext &ctx, const Acts::GeometryContext &gctx, Trk::Track* inputTrack, const Acts::BoundVector& inputVector, @@ -70,9 +393,12 @@ KalmanFitterTool::fit(const EventContext &ctx, const Acts::GeometryContext &gctx ATH_MSG_DEBUG("momentum: " << trackParameters.momentum().transpose()); ATH_MSG_DEBUG("charge: " << trackParameters.charge()); - Acts::KalmanFitterOptions<MeasurementCalibrator, Acts::VoidOutlierFinder, Acts::VoidReverseFilteringLogic> + FaserActsOutlierFinder faserActsOutlierFinder{0}; + faserActsOutlierFinder.cluster_z=-1000000.; + faserActsOutlierFinder.StateChiSquaredPerNumberDoFCut=10000.; + Acts::KalmanFitterOptions<MeasurementCalibrator, FaserActsOutlierFinder, Acts::VoidReverseFilteringLogic> kfOptions(gctx, mfContext, calibContext, MeasurementCalibrator(measurements), - Acts::VoidOutlierFinder(), Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, + faserActsOutlierFinder, Acts::VoidReverseFilteringLogic(), Acts::LoggerWrapper{*m_logger}, Acts::PropagatorPlainOptions(), &(*pSurface)); kfOptions.multipleScattering = false; kfOptions.energyLoss = false; @@ -95,9 +421,6 @@ KalmanFitterTool::fit(const EventContext &ctx, const Acts::GeometryContext &gctx std::vector<size_t> trackTips; trackTips.reserve(1); trackTips.emplace_back(fitOutput.lastMeasurementIndex); - // trajectories.emplace_back(std::move(fitOutput.fittedStates), - // std::move(trackTips), - // std::move(indexedParams)); myTrajectories.emplace_back(std::move(fitOutput.fittedStates), std::move(trackTips), std::move(indexedParams)); @@ -172,6 +495,84 @@ Acts::MagneticFieldContext KalmanFitterTool::getMagneticFieldContext(const Event } +std::tuple<std::vector<IndexSourceLink>, std::vector<Measurement>> +KalmanFitterTool::getMeasurementsFromTrack(Trk::Track *track, std::vector<const Tracker::FaserSCT_Cluster*>& clusters) const { + const int kSize = 1; + ATH_MSG_DEBUG("clusters in refit "<<clusters.size()); + std::array<Acts::BoundIndices, kSize> Indices = {Acts::eBoundLoc0}; + using ThisMeasurement = Acts::Measurement<IndexSourceLink, Acts::BoundIndices, kSize>; + using IdentifierMap = std::map<Identifier, Acts::GeometryIdentifier>; + + std::shared_ptr<IdentifierMap> identifierMap = m_trackingGeometryTool->getIdentifierMap(); + std::vector<IndexSourceLink> sourceLinks; + std::vector<Measurement> measurements; + for(auto cluster : clusters){ + Identifier id = cluster->identify(); + int ista = m_idHelper->station(id); + int ilay = m_idHelper->layer(id); + ATH_MSG_DEBUG("station/layer "<<ista<<" "<<ilay); + Identifier waferId = m_idHelper->wafer_id(id); + if (identifierMap->count(waferId) != 0) { + ATH_MSG_DEBUG("found the identifier "<<ista<<" "<<ilay); + Acts::GeometryIdentifier geoId = identifierMap->at(waferId); + IndexSourceLink sourceLink(geoId, measurements.size(), cluster); + Eigen::Matrix<double, 1, 1> pos {cluster->localPosition().x()}; + Eigen::Matrix<double, 1, 1> cov {0.08 * 0.08 / 12}; + ThisMeasurement actsMeas(sourceLink, Indices, pos, cov); + sourceLinks.push_back(sourceLink); + measurements.emplace_back(std::move(actsMeas)); + } + } + for (const Trk::MeasurementBase *meas : *track->measurementsOnTrack()) { + const auto* clusterOnTrack = dynamic_cast<const Tracker::FaserSCT_ClusterOnTrack*>(meas); + const Tracker::FaserSCT_Cluster* cluster = clusterOnTrack->prepRawData(); + if (clusterOnTrack) { + Identifier id = clusterOnTrack->identify(); + Identifier waferId = m_idHelper->wafer_id(id); + if (identifierMap->count(waferId) != 0) { + Acts::GeometryIdentifier geoId = identifierMap->at(waferId); + IndexSourceLink sourceLink(geoId, measurements.size(), cluster); + Eigen::Matrix<double, 1, 1> pos {meas->localParameters()[Trk::locX],}; + Eigen::Matrix<double, 1, 1> cov {0.08 * 0.08 / 12}; + ThisMeasurement actsMeas(sourceLink, Indices, pos, cov); + sourceLinks.push_back(sourceLink); + measurements.emplace_back(std::move(actsMeas)); + } + } + } + return std::make_tuple(sourceLinks, measurements); +} + +std::tuple<std::vector<IndexSourceLink>, std::vector<Measurement>> +KalmanFitterTool::getMeasurementsFromTrack(Trk::Track *track, Identifier& wafer_id) const { + const int kSize = 1; + std::array<Acts::BoundIndices, kSize> Indices = {Acts::eBoundLoc0}; + using ThisMeasurement = Acts::Measurement<IndexSourceLink, Acts::BoundIndices, kSize>; + using IdentifierMap = std::map<Identifier, Acts::GeometryIdentifier>; + + std::shared_ptr<IdentifierMap> identifierMap = m_trackingGeometryTool->getIdentifierMap(); + std::vector<IndexSourceLink> sourceLinks; + std::vector<Measurement> measurements; + for (const Trk::MeasurementBase *meas : *track->measurementsOnTrack()) { + const auto* clusterOnTrack = dynamic_cast<const Tracker::FaserSCT_ClusterOnTrack*>(meas); + const Tracker::FaserSCT_Cluster* cluster = clusterOnTrack->prepRawData(); + if (clusterOnTrack) { + Identifier id = clusterOnTrack->identify(); + Identifier waferId = m_idHelper->wafer_id(id); + + if (identifierMap->count(waferId) != 0) { + Acts::GeometryIdentifier geoId = identifierMap->at(waferId); + IndexSourceLink sourceLink(geoId, measurements.size(), cluster); + Eigen::Matrix<double, 1, 1> pos {meas->localParameters()[Trk::locX],}; + Eigen::Matrix<double, 1, 1> cov {0.08 * 0.08 / 12}; + ThisMeasurement actsMeas(sourceLink, Indices, pos, cov); + sourceLinks.push_back(sourceLink); + measurements.emplace_back(std::move(actsMeas)); + } + } + } + return std::make_tuple(sourceLinks, measurements); +} std::tuple<std::vector<IndexSourceLink>, std::vector<Measurement>> KalmanFitterTool::getMeasurementsFromTrack(Trk::Track *track) const { const int kSize = 1; diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.h b/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.h index 0894e3ab2139decc1f0950a89f6200dc9ea2930f..584cda2c98bf32d7050150a690a0926439e11f91 100644 --- a/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.h +++ b/Tracking/Acts/FaserActsKalmanFilter/src/KalmanFitterTool.h @@ -15,9 +15,54 @@ #include "TrkTrack/Track.h" #include "TrkTrack/TrackCollection.h" #include "CreateTrkTrackTool.h" +#include "TrackerIdentifier/FaserSCT_ID.h" +#include "Identifier/Identifier.h" +struct TSOS4Residual{ + double fit_local_x; + double fit_local_y; + double fit_global_x; + double fit_global_y; + double fit_global_z; + const Tracker::FaserSCT_Cluster* cluster; + double residual; + Acts::BoundTrackParameters parameter; + +}; class FaserSCT_ID; +//set the cluster to be removed as outlier in order to get the unbiased residual +/// Outlier finder using a Chi2 cut. +struct FaserActsOutlierFinder { + double StateChiSquaredPerNumberDoFCut = 10000.; + double cluster_z = -10000.; + template <typename track_state_t> + bool operator()(const track_state_t& state) const { + //remove the whole IFT + if(cluster_z<-10000){ + if(state.uncalibrated().hit()->globalPosition().z()<-100)return true; + } + + if (not state.hasCalibrated() or not state.hasPredicted()) { + return false; + } + return Acts::visit_measurement( + state.calibrated(), state.calibratedCovariance(), + state.calibratedSize(), + [&](const auto calibrated, const auto calibratedCovariance) { + //remove the cluster + if(fabs(state.uncalibrated().hit()->globalPosition().z()-cluster_z)<3)return true; + constexpr size_t kMeasurementSize = decltype(calibrated)::RowsAtCompileTime; + const auto H = + state.projector() + .template topLeftCorner<kMeasurementSize, Acts::BoundIndices::eBoundSize>() + .eval(); + const auto residual = calibrated - H * state.predicted(); + double chi2 = (residual.transpose() * ((calibratedCovariance + H * state.predictedCovariance() * H.transpose())).inverse() * residual).value(); + return bool(chi2 > StateChiSquaredPerNumberDoFCut * kMeasurementSize); + }); + } +}; class KalmanFitterTool : virtual public AthAlgTool { public: @@ -29,7 +74,8 @@ public: using TrackParameters = Acts::BoundTrackParameters; using IndexedParams = std::unordered_map<size_t, TrackParameters>; using TrackFitterOptions = - Acts::KalmanFitterOptions<MeasurementCalibrator, Acts::VoidOutlierFinder, Acts::VoidReverseFilteringLogic>; + Acts::KalmanFitterOptions<MeasurementCalibrator, FaserActsOutlierFinder, Acts::VoidReverseFilteringLogic>; + //Acts::KalmanFitterOptions<MeasurementCalibrator, Acts::VoidOutlierFinder, Acts::VoidReverseFilteringLogic>; using TrackFitterResult = Acts::Result<Acts::KalmanFitterResult<IndexSourceLink>>; class TrackFitterFunction { public: @@ -45,12 +91,27 @@ public: Trk::Track *inputTrack, const Acts::BoundVector& inputVector = Acts::BoundVector::Zero(), bool isMC=false, double origin=0) const; + std::vector<TSOS4Residual> getUnbiasedResidual(const EventContext &ctx, const Acts::GeometryContext &gctx, + Trk::Track *inputTrack, + const Acts::BoundVector& inputVector = Acts::BoundVector::Zero(), + bool isMC=false, double origin=0) const; + std::vector<TSOS4Residual> getUnbiasedResidual(const EventContext &ctx, const Acts::GeometryContext &gctx, + Trk::Track *inputTrack, double clusz, + const Acts::BoundVector& inputVector , + bool isMC, double origin) const; + std::vector<TSOS4Residual> getUnbiasedResidual(const EventContext &ctx, const Acts::GeometryContext &gctx, + Trk::Track *inputTrack, + const Acts::BoundVector& inputVector , + bool isMC, double origin, std::vector<const Tracker::FaserSCT_Cluster*>& clus,const Acts::BoundTrackParameters ini_Param) const; private: const FaserSCT_ID* m_idHelper {nullptr}; std::tuple<std::vector<IndexSourceLink>, std::vector<Measurement>> getMeasurementsFromTrack(Trk::Track *track) const; - // Acts::BoundTrackParameters getParametersFromTrack(const Acts::BoundVector& params, const Trk::TrackParameters *inputParameters) const; + std::tuple<std::vector<IndexSourceLink>, std::vector<Measurement>> + getMeasurementsFromTrack(Trk::Track *track, Identifier& wafer_id) const; + std::tuple<std::vector<IndexSourceLink>, std::vector<Measurement>> + getMeasurementsFromTrack(Trk::Track *track, std::vector<const Tracker::FaserSCT_Cluster*>& clusters) const; Acts::BoundTrackParameters getParametersFromTrack(const Trk::TrackParameters *inputParameters, const Acts::BoundVector& inputVector, double origin) const; std::shared_ptr<TrackFitterFunction> m_fit; std::unique_ptr<const Acts::Logger> m_logger; @@ -67,6 +128,12 @@ private: ToolHandle<RootTrajectoryStatesWriterTool> m_trajectoryStatesWriterTool {this, "RootTrajectoryStatesWriterTool", "RootTrajectoryStatesWriterTool"}; ToolHandle<RootTrajectorySummaryWriterTool> m_trajectorySummaryWriterTool {this, "RootTrajectorySummaryWriterTool", "RootTrajectorySummaryWriterTool"}; ToolHandle<CreateTrkTrackTool> m_createTrkTrackTool {this, "CreateTrkTrackTool", "CreateTrkTrackTool"}; + +// Acts::KalmanFitterExtensions<Acts::VectorMultiTrajectory> getExtensions(); + +// FaserActsOutlierFinder m_outlierFinder{0}; +// ReverseFilteringLogic m_reverseFilteringLogic{0}; +// Acts::KalmanFitterExtensions<Acts::VectorMultiTrajectory> m_kfExtensions; }; #endif //FASERACTSKALMANFILTER_KALMANFITTERTOOL_H diff --git a/Tracking/Acts/FaserActsKalmanFilter/src/components/FaserActsKalmanFilter_entries.cxx b/Tracking/Acts/FaserActsKalmanFilter/src/components/FaserActsKalmanFilter_entries.cxx index d9fefbddfb3b5e651f5ac697ac231bb9e41918d3..be32f4959409c57903c674bf7fd5d28209ad295d 100755 --- a/Tracking/Acts/FaserActsKalmanFilter/src/components/FaserActsKalmanFilter_entries.cxx +++ b/Tracking/Acts/FaserActsKalmanFilter/src/components/FaserActsKalmanFilter_entries.cxx @@ -23,6 +23,7 @@ #include "../TrackSeedWriterTool.h" #include "../ActsTrackSeedTool.h" #include "../CKF2.h" +#include "../CKF2Alignment.h" #include "../KalmanFitterTool.h" #include "../MyTrackSeedTool.h" #include "../SeedingAlg.h" @@ -53,6 +54,7 @@ DECLARE_COMPONENT(PerformanceWriterTool) DECLARE_COMPONENT(TrackSeedWriterTool) DECLARE_COMPONENT(ActsTrackSeedTool) DECLARE_COMPONENT(CKF2) +DECLARE_COMPONENT(CKF2Alignment) DECLARE_COMPONENT(KalmanFitterTool) DECLARE_COMPONENT(MyTrackSeedTool) DECLARE_COMPONENT(SeedingAlg)