diff --git a/Detector/DetDriftChamber/compact/det.xml b/Detector/DetDriftChamber/compact/det.xml index 7ee0d9ae62e7700f6cffcb4770329e0383344907..a070d543de61ff6e44f8952b24be492cea927c9f 100644 --- a/Detector/DetDriftChamber/compact/det.xml +++ b/Detector/DetDriftChamber/compact/det.xml @@ -16,7 +16,7 @@ </includes> <define> - <constant name="world_size" value="30*m"/> + <constant name="world_size" value="2226*mm"/> <constant name="world_x" value="world_size"/> <constant name="world_y" value="world_size"/> <constant name="world_z" value="world_size"/> @@ -65,7 +65,7 @@ </regions> <detectors> - <detector id="1" name="DriftChamber" type="DriftChamber" readout="DriftChamberHitsCollection" vis="VisibleBlue" sensitive="true" region="DriftChamberRegion"> + <detector id="7" name="DriftChamber" type="DriftChamber" readout="DriftChamberHitsCollection" vis="VisibleBlue" sensitive="true" region="DriftChamberRegion"> <envelope vis="SeeThrough"> <shape type="BooleanShape" operation="Union" material="Air"> <shape type="Tube" rmin="SDT_radius_min" rmax="909*mm" dz="SDT_half_length" /> diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp index 36783972a794fab389b648b8b36f772a3cf7ff06..6f88f5898faf2ce84fb3ae4d1f4410fcb521a0bb 100644 --- a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp +++ b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp @@ -74,14 +74,12 @@ StatusCode DCHDigiAlg::initialize() m_tuple->addItem( "dca" , m_n_digi,m_dca ).ignore(); m_tuple->addItem( "hit_dE" , m_n_digi,m_hit_dE ).ignore(); m_tuple->addItem( "hit_dE_dx", m_n_digi,m_hit_dE_dx ).ignore(); - } - else { // did not manage to book the N tuple.... - error() << " Cannot book N-tuple:" << long( m_tuple ) << endmsg; - return StatusCode::FAILURE; + } else { // did not manage to book the N tuple.... + info() << " Cannot book N-tuple:" << long( m_tuple ) << endmsg; } } } - std::cout<<"DCHDigiAlg::initialized"<< std::endl; + info()<<"DCHDigiAlg::initialized"<<endmsg; return GaudiAlgorithm::initialize(); } @@ -93,7 +91,7 @@ StatusCode DCHDigiAlg::execute() edm4hep::TrackerHitCollection* Vec = w_DigiDCHCol.createAndPut(); edm4hep::MCRecoTrackerAssociationCollection* AssoVec = w_AssociationCol.createAndPut(); const edm4hep::SimTrackerHitCollection* SimHitCol = r_SimDCHCol.get(); - std::cout<<"input sim hit size="<< SimHitCol->size() <<std::endl; + debug()<<"input sim hit size="<< SimHitCol->size() <<endmsg; for( int i = 0; i < SimHitCol->size(); i++ ) { edm4hep::SimTrackerHit SimHit = SimHitCol->at(i); @@ -110,7 +108,7 @@ StatusCode DCHDigiAlg::execute() id_hits_map[id] = vhit ; } } - if(m_WriteAna){ + if(m_WriteAna && (nullptr!=m_tuple)){ m_n_sim = 0; m_n_digi = 0 ; } @@ -164,7 +162,7 @@ StatusCode DCHDigiAlg::execute() asso.setSim(iter->second.at(i)); asso.setWeight(iter->second.at(i).getEDep()/tot_edep); - if(m_WriteAna){ + if(m_WriteAna && (nullptr!=m_tuple)){ m_simhit_x[m_n_sim] = pos.x(); m_simhit_y[m_n_sim] = pos.y(); m_simhit_z[m_n_sim] = pos.z(); @@ -178,7 +176,7 @@ StatusCode DCHDigiAlg::execute() trkHit.setPosition (edm4hep::Vector3d(pos_x, pos_y, pos_z));//position of closest sim hit trkHit.setCovMatrix(std::array<float, 6>{m_res_x, 0, m_res_y, 0, 0, m_res_z});//cov(x,x) , cov(y,x) , cov(y,y) , cov(z,x) , cov(z,y) , cov(z,z) in mm - if(m_WriteAna){ + if(m_WriteAna && (nullptr!=m_tuple)){ m_chamber [m_n_digi] = chamber; m_layer [m_n_digi] = layer ; m_cell [m_n_digi] = cellID; @@ -195,10 +193,10 @@ StatusCode DCHDigiAlg::execute() } - std::cout<<"output digi DCHhit size="<< Vec->size() <<std::endl; + debug()<<"output digi DCHhit size="<< Vec->size() <<endmsg; _nEvt ++ ; - if(m_WriteAna){ + if(m_WriteAna && (nullptr!=m_tuple)){ StatusCode status = m_tuple->write(); if ( status.isFailure() ) { error() << " Cannot fill N-tuple:" << long( m_tuple ) << endmsg; diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.h b/Digitisers/DCHDigi/src/DCHDigiAlg.h index e703998271af669f23c15a1e5482bd0d516199ad..5ddf59a5426a86358f0b2d775cef8946e46ddbc1 100644 --- a/Digitisers/DCHDigi/src/DCHDigiAlg.h +++ b/Digitisers/DCHDigi/src/DCHDigiAlg.h @@ -81,7 +81,7 @@ protected: // Input collections DataHandle<edm4hep::SimTrackerHitCollection> r_SimDCHCol{"DriftChamberHitsCollection", Gaudi::DataHandle::Reader, this}; // Output collections - DataHandle<edm4hep::TrackerHitCollection> w_DigiDCHCol{"DigiDCHitsCollection", Gaudi::DataHandle::Writer, this}; + DataHandle<edm4hep::TrackerHitCollection> w_DigiDCHCol{"DigiDCHitCollection", Gaudi::DataHandle::Writer, this}; DataHandle<edm4hep::MCRecoTrackerAssociationCollection> w_AssociationCol{"DCHitAssociationCollection", Gaudi::DataHandle::Writer, this}; }; diff --git a/Examples/options/sim_fit_CRD.py b/Examples/options/sim_fit_CRD.py new file mode 100644 index 0000000000000000000000000000000000000000..e877aeb4f5eef6c197cc7a939baba95e76ea46e0 --- /dev/null +++ b/Examples/options/sim_fit_CRD.py @@ -0,0 +1,278 @@ +#!/usr/bin/env python +from Gaudi.Configuration import * + +############################################################################## +# Event service +############################################################################## +from Configurables import k4DataSvc +dsvc = k4DataSvc("EventDataSvc") + +############################################################################## +# Random seed +############################################################################## +from Configurables import RndmGenSvc, HepRndm__Engine_CLHEP__RanluxEngine_ +# rndmengine = HepRndm__Engine_CLHEP__RanluxEngine_() # The default engine in Gaudi +rndmengine = HepRndm__Engine_CLHEP__HepJamesRandom_() # The default engine in Geant4 +rndmengine.SetSingleton = True +rndmengine.Seeds = [10] + +from Configurables import MarlinEvtSeeder +evtseeder = MarlinEvtSeeder("EventSeeder") + +############################################################################## +# Detector geometry +############################################################################## +geometry_option = "CRD_o1_v01/CRD_o1_v01_noECAL.xml" + +if not os.getenv("DETCRDROOT"): + print("Can't find the geometry. Please setup envvar DETCRDROOT." ) + sys.exit(-1) + +geometry_path = os.path.join(os.getenv("DETCRDROOT"), "compact", geometry_option) +if not os.path.exists(geometry_path): + print("Can't find the compact geometry file: %s"%geometry_path) + sys.exit(-1) + +from Configurables import GeomSvc +geosvc = GeomSvc("GeomSvc") +geosvc.compact = geometry_path + +from Configurables import GearSvc +gearsvc = GearSvc("GearSvc") + +############################################################################## +# Physics Generator +############################################################################## +from Configurables import GenAlgo +from Configurables import GtGunTool +from Configurables import StdHepRdr +from Configurables import SLCIORdr +from Configurables import HepMCRdr +from Configurables import GenPrinter +gun = GtGunTool("GtGunTool") +gun.Particles = ["mu-"] +gun.EnergyMins = [100.] # GeV +gun.EnergyMaxs = [100.] # GeV +gun.ThetaMins = [0] # deg +gun.ThetaMaxs = [180] # deg +gun.PhiMins = [0] # deg +gun.PhiMaxs = [360] # deg +# stdheprdr = StdHepRdr("StdHepRdr") +# stdheprdr.Input = "/cefs/data/stdhep/CEPC250/2fermions/E250.Pbhabha.e0.p0.whizard195/bhabha.e0.p0.00001.stdhep" +# lciordr = SLCIORdr("SLCIORdr") +# lciordr.Input = "/cefs/data/stdhep/lcio250/signal/Higgs/E250.Pbbh.whizard195/E250.Pbbh_X.e0.p0.whizard195/Pbbh_X.e0.p0.00001.slcio" +# hepmcrdr = HepMCRdr("HepMCRdr") +# hepmcrdr.Input = "example_UsingIterators.txt" + +genprinter = GenPrinter("GenPrinter") + +genalg = GenAlgo("GenAlgo") +genalg.GenTools = ["GtGunTool"] +#genalg.GenTools = ["StdHepRdr"] +# genalg.GenTools = ["StdHepRdr", "GenPrinter"] +# genalg.GenTools = ["SLCIORdr", "GenPrinter"] +# genalg.GenTools = ["HepMCRdr", "GenPrinter"] + +############################################################################## +# Detector Simulation +############################################################################## +from Configurables import DetSimSvc +detsimsvc = DetSimSvc("DetSimSvc") + +from Configurables import DetSimAlg +detsimalg = DetSimAlg("DetSimAlg") +#detsimalg.VisMacs = ["vis.mac"] +detsimalg.RunCmds = [ +# "/tracking/verbose 1", +] +detsimalg.AnaElems = [ + # example_anatool.name() + # "ExampleAnaElemTool" + "Edm4hepWriterAnaElemTool" +] +detsimalg.RootDetElem = "WorldDetElemTool" + +from Configurables import AnExampleDetElemTool +example_dettool = AnExampleDetElemTool("AnExampleDetElemTool") + +from Configurables import CalorimeterSensDetTool +from Configurables import DriftChamberSensDetTool + +calo_sensdettool = CalorimeterSensDetTool("CalorimeterSensDetTool") +driftchamber_sensdettool = DriftChamberSensDetTool("DriftChamberSensDetTool") + +############################################################################## +# DedxSimTool +############################################################################## +# dedxoption = "DummyDedxSimTool" +dedxoption = "BetheBlochEquationDedxSimTool" + +driftchamber_sensdettool.DedxSimTool = dedxoption + +from Configurables import DummyDedxSimTool +from Configurables import BetheBlochEquationDedxSimTool + +if dedxoption == "DummyDedxSimTool": + dedx_simtool = DummyDedxSimTool("DummyDedxSimTool") +elif dedxoption == "BetheBlochEquationDedxSimTool": + dedx_simtool = BetheBlochEquationDedxSimTool("BetheBlochEquationDedxSimTool") + dedx_simtool.material_Z = 2 + dedx_simtool.material_A = 4 + dedx_simtool.scale = 10 + dedx_simtool.resolution = 0.0001 + +############################################################################## +# DCHDigiAlg +############################################################################## +from Configurables import DCHDigiAlg +dCHDigiAlg = DCHDigiAlg("DCHDigiAlg") +dCHDigiAlg.readout = "DriftChamberHitsCollection" +dCHDigiAlg.drift_velocity = 40#um/ns +dCHDigiAlg.mom_threshold = 0 #GeV +dCHDigiAlg.WriteAna = True + +############################################################################## +# PODIO +############################################################################## +from Configurables import PodioOutput +out = PodioOutput("outputalg") +out.filename = "CRD-o1-v01-sim00.root" +out.outputCommands = ["keep *"] + + +############################################################################## +# Silicon digitization +############################################################################## +vxdhitname = "VXDTrackerHits" +sithitname = "SITTrackerHits" +sitspname = "SITSpacePoints" +tpchitname = "TPCTrackerHits" +sethitname = "SETTrackerHits" +setspname = "SETSpacePoints" +ftdspname = "FTDSpacePoints" +ftdhitname = "FTDTrackerHits" +from Configurables import PlanarDigiAlg +digiVXD = PlanarDigiAlg("VXDDigi") +digiVXD.SimTrackHitCollection = "VXDCollection" +digiVXD.TrackerHitCollection = vxdhitname +digiVXD.ResolutionU = [0.0028, 0.006, 0.004, 0.004, 0.004, 0.004] +digiVXD.ResolutionV = [0.0028, 0.006, 0.004, 0.004, 0.004, 0.004] + +digiSIT = PlanarDigiAlg("SITDigi") +digiSIT.IsStrip = 1 +digiSIT.SimTrackHitCollection = "SITCollection" +digiSIT.TrackerHitCollection = sithitname +digiSIT.TrackerHitAssociationCollection = "SITTrackerHitAssociation" +digiSIT.ResolutionU = [0.007] +digiSIT.ResolutionV = [0.000] + +digiSET = PlanarDigiAlg("SETDigi") +digiSET.IsStrip = 1 +digiSET.SimTrackHitCollection = "SETCollection" +digiSET.TrackerHitCollection = sethitname +digiSET.TrackerHitAssociationCollection = "SETTrackerHitAssociation" +digiSET.ResolutionU = [0.007] +digiSET.ResolutionV = [0.000] + +digiFTD = PlanarDigiAlg("FTDDigi") +digiFTD.SimTrackHitCollection = "FTDCollection" +digiFTD.TrackerHitCollection = ftdhitname +digiFTD.TrackerHitAssociationCollection = "FTDTrackerHitAssociation" +digiFTD.ResolutionU = [0.003, 0.003, 0.007, 0.007, 0.007, 0.007, 0.007, 0.007] +digiFTD.ResolutionV = [0.003, 0.003, 0, 0, 0, 0, 0, 0 ] +#digiFTD.OutputLevel = DEBUG + +from Configurables import SpacePointBuilderAlg +spSIT = SpacePointBuilderAlg("SITBuilder") +spSIT.TrackerHitCollection = sithitname +spSIT.TrackerHitAssociationCollection = "SITTrackerHitAssociation" +spSIT.SpacePointCollection = sitspname +spSIT.SpacePointAssociationCollection = "SITSpacePointAssociation" +#spSIT.OutputLevel = DEBUG + +spFTD = SpacePointBuilderAlg("FTDBuilder") +spFTD.TrackerHitCollection = ftdhitname +spFTD.TrackerHitAssociationCollection = "FTDTrackerHitAssociation" +spFTD.SpacePointCollection = ftdspname +spFTD.SpacePointAssociationCollection = "FTDSpacePointAssociation" +#spFTD.OutputLevel = DEBUG + + +############################################################################## +# Silicon reconstruction +############################################################################## +from Configurables import TrackSystemSvc +tracksystemsvc = TrackSystemSvc("TrackSystemSvc") + +from Configurables import SiliconTrackingAlg +tracking = SiliconTrackingAlg("SiliconTracking") +tracking.HeaderCol = "EventHeader" +tracking.VTXHitCollection = vxdhitname +tracking.SITHitCollection = sitspname +tracking.FTDPixelHitCollection = ftdhitname +tracking.FTDSpacePointCollection = ftdspname +tracking.SITRawHitCollection = sithitname +tracking.FTDRawHitCollection = ftdhitname +tracking.UseSIT = 1 +tracking.SmoothOn = 0 +#tracking.OutputLevel = DEBUG + +from Configurables import ForwardTrackingAlg +forward = ForwardTrackingAlg("ForwardTracking") +forward.FTDPixelHitCollection = ftdhitname +forward.FTDSpacePointCollection = ftdspname +forward.FTDRawHitCollection = ftdhitname +forward.Chi2ProbCut = 0.0 +forward.HitsPerTrackMin = 3 +forward.BestSubsetFinder = "SubsetSimple" +forward.Criteria = ["Crit2_DeltaPhi","Crit2_StraightTrackRatio","Crit3_3DAngle","Crit3_ChangeRZRatio","Crit3_IPCircleDist","Crit4_3DAngleChange","Crit4_DistToExtrapolation", + "Crit2_DeltaRho","Crit2_RZRatio","Crit3_PT"] +forward.CriteriaMin = [0, 0.9, 0, 0.995, 0, 0.8, 0, 20, 1.002, 0.1, 0, 0.99, 0, 0.999, 0, 0.99, 0] +forward.CriteriaMax = [30, 1.02, 10, 1.015, 20, 1.3, 1.0, 150, 1.08, 99999999, 0.8, 1.01, 0.35, 1.001, 1.5, 1.01, 0.05] +#forward.OutputLevel = DEBUG + +from Configurables import TrackSubsetAlg +subset = TrackSubsetAlg("TrackSubset") +subset.TrackInputCollections = ["ForwardTracks", "SiTracks"] +subset.RawTrackerHitCollections = [vxdhitname, sithitname, ftdhitname, sitspname, ftdspname] +subset.TrackSubsetCollection = "SubsetTracks" +#subset.OutputLevel = DEBUG + +############################################################################## +# TruthTrackerAlg +############################################################################## +from Configurables import TruthTrackerAlg +truthTrackerAlg = TruthTrackerAlg("TruthTrackerAlg") +truthTrackerAlg.SiSubsetTrackCollection = "SubsetTracks" + +############################################################################## +# RecGenfitAlgSDT +############################################################################## +from Configurables import RecGenfitAlgSDT +recGenfitAlgSDT = RecGenfitAlgSDT("RecGenfitAlgSDT") +recGenfitAlgSDT.debug=10 + +############################################################################## +# NTupleSvc +############################################################################## +from Configurables import NTupleSvc +ntsvc = NTupleSvc("NTupleSvc") +ntsvc.Output = [ +#"MyTuples DATAFILE='DCH_digi_ana.root' OPT='NEW' TYP='ROOT'", + "RecGenfitAlgSDT DATAFILE='fit_SDT.root' OPT='NEW' TYP='ROOT'"] + + +############################################################################## +# ApplicationMgr +############################################################################## +from Configurables import ApplicationMgr +ApplicationMgr( + TopAlg = [genalg, detsimalg, digiVXD, digiSIT, digiSET, digiFTD, spSIT, + spFTD, tracking, forward, subset, dCHDigiAlg, truthTrackerAlg, + recGenfitAlgSDT, out], + EvtSel = 'NONE', + EvtMax = 1, + ExtSvc = [rndmengine, dsvc, ntsvc, evtseeder, geosvc, gearsvc, tracksystemsvc], + HistogramPersistency = "ROOT", + OutputLevel=DEBUG +) diff --git a/Examples/options/tut_detsim_digi_fit_DC.py b/Examples/options/tut_detsim_digi_fit_DC.py new file mode 100644 index 0000000000000000000000000000000000000000..52a7c026596dcee1047590b74bf08c513b1966a3 --- /dev/null +++ b/Examples/options/tut_detsim_digi_fit_DC.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python + +import os +print(os.environ["DD4HEP_LIBRARY_PATH"]) +import sys +# sys.exit(0) + +from Gaudi.Configuration import * + +############################################################################## +# Random Number Svc +############################################################################## +from Configurables import RndmGenSvc, HepRndm__Engine_CLHEP__RanluxEngine_ + +# rndmengine = HepRndm__Engine_CLHEP__RanluxEngine_() # The default engine in Gaudi +rndmengine = HepRndm__Engine_CLHEP__HepJamesRandom_() # The default engine in Geant4 +rndmengine.SetSingleton = True +rndmengine.Seeds = [42] + +# rndmgensvc = RndmGenSvc("RndmGenSvc") +# rndmgensvc.Engine = rndmengine.name() + + +############################################################################## +# Event Data Svc +############################################################################## +from Configurables import k4DataSvc +dsvc = k4DataSvc("EventDataSvc") + + +############################################################################## +# Geometry Svc +############################################################################## + +# geometry_option = "CepC_v4-onlyTracker.xml" +geometry_option = "det.xml" + +if not os.getenv("DETDRIFTCHAMBERROOT"): + print("Can't find the geometry. Please setup envvar DETDRIFTCHAMBERROOT." ) + sys.exit(-1) + +geometry_path = os.path.join(os.getenv("DETDRIFTCHAMBERROOT"), "compact", geometry_option) +if not os.path.exists(geometry_path): + print("Can't find the compact geometry file: %s"%geometry_path) + sys.exit(-1) + +from Configurables import GeomSvc +geosvc = GeomSvc("GeomSvc") +geosvc.compact = geometry_path + +############################################################################## +# Physics Generator +############################################################################## +from Configurables import GenAlgo +from Configurables import GtGunTool +from Configurables import StdHepRdr +from Configurables import SLCIORdr +from Configurables import HepMCRdr +from Configurables import GenPrinter + +gun = GtGunTool("GtGunTool") +# gun.Particles = ["pi+"] +# gun.EnergyMins = [100.] # GeV +# gun.EnergyMaxs = [100.] # GeV + +gun.Particles = ["e-"] + +# gun.PositionXs = [100.] # mm +# gun.PositionYs = [100.] # mm +# gun.PositionZs = [0.] # mm + + +gun.EnergyMins = [10.] # GeV +gun.EnergyMaxs = [10.] # GeV + +gun.ThetaMins = [90] # rad; 45deg +gun.ThetaMaxs = [90] # rad; 45deg + +gun.PhiMins = [0] # rad; 0deg +gun.PhiMaxs = [360] # rad; 360deg +#gun.PhiMins = [0] # rad; 0deg +#gun.PhiMaxs = [360] # rad; 360deg + +# stdheprdr = StdHepRdr("StdHepRdr") +# stdheprdr.Input = "/cefs/data/stdhep/CEPC250/2fermions/E250.Pbhabha.e0.p0.whizard195/bhabha.e0.p0.00001.stdhep" + +# lciordr = SLCIORdr("SLCIORdr") +# lciordr.Input = "/cefs/data/stdhep/lcio250/signal/Higgs/E250.Pbbh.whizard195/E250.Pbbh_X.e0.p0.whizard195/Pbbh_X.e0.p0.00001.slcio" + +# hepmcrdr = HepMCRdr("HepMCRdr") +# hepmcrdr.Input = "example_UsingIterators.txt" + +genprinter = GenPrinter("GenPrinter") + +genalg = GenAlgo("GenAlgo") +genalg.GenTools = ["GtGunTool"] +# genalg.GenTools = ["StdHepRdr"] +# genalg.GenTools = ["StdHepRdr", "GenPrinter"] +# genalg.GenTools = ["SLCIORdr", "GenPrinter"] +# genalg.GenTools = ["HepMCRdr", "GenPrinter"] + +############################################################################## +# Detector Simulation +############################################################################## +from Configurables import DetSimSvc + +detsimsvc = DetSimSvc("DetSimSvc") + +# from Configurables import ExampleAnaElemTool +# example_anatool = ExampleAnaElemTool("ExampleAnaElemTool") + +from Configurables import DetSimAlg + +detsimalg = DetSimAlg("DetSimAlg") + +if int(os.environ.get("VIS", 0)): + detsimalg.VisMacs = ["vis.mac"] + +detsimalg.RunCmds = [ +# "/tracking/verbose 1", +] +detsimalg.AnaElems = [ + # example_anatool.name() + # "ExampleAnaElemTool" + "Edm4hepWriterAnaElemTool" +] +detsimalg.RootDetElem = "WorldDetElemTool" + +from Configurables import AnExampleDetElemTool +example_dettool = AnExampleDetElemTool("AnExampleDetElemTool") + +from Configurables import CalorimeterSensDetTool +from Configurables import DriftChamberSensDetTool + +calo_sensdettool = CalorimeterSensDetTool("CalorimeterSensDetTool") +driftchamber_sensdettool = DriftChamberSensDetTool("DriftChamberSensDetTool") + +# dedxoption = "DummyDedxSimTool" +dedxoption = "BetheBlochEquationDedxSimTool" + +driftchamber_sensdettool.DedxSimTool = dedxoption + +from Configurables import DummyDedxSimTool +from Configurables import BetheBlochEquationDedxSimTool + +if dedxoption == "DummyDedxSimTool": + dedx_simtool = DummyDedxSimTool("DummyDedxSimTool") +elif dedxoption == "BetheBlochEquationDedxSimTool": + dedx_simtool = BetheBlochEquationDedxSimTool("BetheBlochEquationDedxSimTool") + dedx_simtool.material_Z = 2 + dedx_simtool.material_A = 4 + dedx_simtool.scale = 10 + dedx_simtool.resolution = 0.0001 + +############################################################################## +from Configurables import DCHDigiAlg +dCHDigiAlg = DCHDigiAlg("DCHDigiAlg") + +############################################################################## +# POD I/O +############################################################################## +from Configurables import PodioOutput +out = PodioOutput("outputalg") +out.filename = "rec_DCH.root" +out.outputCommands = ["keep *"] + +############################################################################## +# TruthTrackerAlg +############################################################################## +from Configurables import TruthTrackerAlg +truthTrackerAlg = TruthTrackerAlg("TruthTrackerAlg") + +############################################################################## +# GenfitAlg +############################################################################## +from Configurables import RecGenfitAlgDC +recGenfitAlgDC = RecGenfitAlgDC("RecGenfitAlgDC") + +############################################################################## +# NTupleSvc +############################################################################## +from Configurables import NTupleSvc +ntsvc = NTupleSvc("NTupleSvc") +ntsvc.Output = ["MyTuples DATAFILE='dCHDigiAlg.root' OPT='NEW' TYP='ROOT'", + "RecGenfitAlgDC DATAFILE='recGenfitAlgDC.root' OPT='NEW' TYP='ROOT'"] + +############################################################################## +# ApplicationMgr +############################################################################## + +from Configurables import ApplicationMgr +ApplicationMgr( TopAlg = [genalg, detsimalg, dCHDigiAlg, truthTrackerAlg, + recGenfitAlgDC,out], + EvtSel = 'NONE', + EvtMax = 10, + ExtSvc = [rndmengine, dsvc, geosvc, ntsvc], + HistogramPersistency = "ROOT", + OutputLevel=DEBUG +) diff --git a/Reconstruction/CMakeLists.txt b/Reconstruction/CMakeLists.txt index e506b90c7c3096915bb1d881d3109984958fa517..6dd63b02cda864eb8f587f8a9f8f6bc57f1b5030 100644 --- a/Reconstruction/CMakeLists.txt +++ b/Reconstruction/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(Digi_Calo) add_subdirectory(PFA) add_subdirectory(SiliconTracking) add_subdirectory(Tracking) +add_subdirectory(RecGenfitAlg) diff --git a/Reconstruction/RecGenfitAlg/CMakeLists.txt b/Reconstruction/RecGenfitAlg/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..630086dce7a22cef058903d2859aaed2d469959c --- /dev/null +++ b/Reconstruction/RecGenfitAlg/CMakeLists.txt @@ -0,0 +1,36 @@ +# RecGenfitAlg + +if (GenFit_FOUND) +gaudi_add_module(RecGenfitAlg + SOURCES src/RecGenfitAlgSDT.cpp + src/RecGenfitAlgDC.cpp + src/GenfitTrack.cpp + src/GenfitField.cpp + src/GenfitFitter.cpp + src/GenfitMaterialInterface.cpp + src/GenfitMsg.cpp + LINK GearSvc + Gaudi::GaudiAlgLib + Gaudi::GaudiKernel + ${GEAR_LIBRARIES} + ${GSL_LIBRARIES} + ${LCIO_LIBRARIES} + DetSegmentation + DetInterface + DataHelperLib + EDM4HEP::edm4hep + EDM4HEP::edm4hepDict + GenFit::genfit2 +) + +target_include_directories(RecGenfitAlg PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>/include + $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> +) + +install(TARGETS RecGenfitAlg + EXPORT CEPCSWTargets + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT bin + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT shlib + COMPONENT dev) +endif() diff --git a/Reconstruction/RecGenfitAlg/README.md b/Reconstruction/RecGenfitAlg/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c9cddb4c8b0b9285c1a42a72140c953b9f79797a --- /dev/null +++ b/Reconstruction/RecGenfitAlg/README.md @@ -0,0 +1,13 @@ +# RecGenfitAlg package + +This package is the track fitting algorithms to do track fitting with genfit. +It's incudingg the interface to genfit fitter, track and measurement: +* GenfitAlg: The algorithm for drift chamber fitting with genfit +* GenfitFitter: fitter implementation +* GenfitTrack: class for create and access of genfit Track and Measurement +* GenfitField: implementation of genfit AbsField +* GenfitGeoMaterialInterface: implementation of genfit AbsMaterialInterface +* GenfitMsg: a class to get Gaudi message instance in Genfit classes. +* GenfitAlgDC: a class to fit drift chamber +* GenfitAlgSDT: a class to fit drift chamber+silicon + diff --git a/Reconstruction/RecGenfitAlg/src/GenfitField.cpp b/Reconstruction/RecGenfitAlg/src/GenfitField.cpp new file mode 100644 index 0000000000000000000000000000000000000000..341e52f3d9c1a0e6539b62bec6225410dbbad7d4 --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/GenfitField.cpp @@ -0,0 +1,58 @@ +#include "GenfitField.h" +#include "GenfitMsg.h" + +//External +#include "DD4hep/DD4hepUnits.h" + +//genfit +#include "FieldManager.h" +#include "ConstField.h" + +///------------------------------------------------------------- +/// GenfitField constructor +///------------------------------------------------------------- +GenfitField::GenfitField(dd4hep::OverlayedField dd4hepField) +:m_dd4hepField(dd4hepField) +{ + genfit::FieldManager::getInstance()->init(this); +} + + +///------------------------------------------------------------- +/// GenfitField get field value by TVector3 +///------------------------------------------------------------- +/// unit in genfit is cm and kGauss +TVector3 GenfitField::get(const TVector3& pos) const +{ + double B[3]={1e9,1e9,1e9}; + get(pos.X(),pos.Y(),pos.Z(),B[0],B[1],B[2]); + return TVector3(B[0],B[1],B[2]); +} + +///------------------------------------------------------------- +/// GenfitField get field value by double +///------------------------------------------------------------- +/// unit in genfit for position is cm and Bxyz is kGauss +/// unit in DD4hepUnits kilogaus and cm? FIXME +void +GenfitField::get(const double& posX, const double& posY, const double& posZ, + double& Bx, double& By, double& Bz) const +{ + /// get field from dd4hepField + const dd4hep::Direction& field=m_dd4hepField.magneticField( + dd4hep::Position(posX/dd4hep::cm,posY/dd4hep::cm,posZ/dd4hep::cm)); + //m_dd4hepField.magneticField(pos,B); + + Bx=field.X()/dd4hep::kilogauss; + By=field.Y()/dd4hep::kilogauss; + Bz=field.Z()/dd4hep::kilogauss; + +// std::cout<<"GenfitField " +// <<Form("xyz(%f,%f,%f)cm B(%f,%f,%f)kilogauss",posX,posY,posZ,Bx,By,Bz) +// <<std::endl; +} + +double GenfitField::getBz(const TVector3& pos) const +{ + return get(pos).Z(); +} diff --git a/Reconstruction/RecGenfitAlg/src/GenfitField.h b/Reconstruction/RecGenfitAlg/src/GenfitField.h new file mode 100644 index 0000000000000000000000000000000000000000..406d0e6b75ccc7c2f87e23fa0bbd60718d92dfd8 --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/GenfitField.h @@ -0,0 +1,38 @@ +/////////////////////////////////////////////////////////// +//// An implementation of genfit AbsBField - GenfitField +//// Authors: +//// Yao ZHANG (zhangyao@ihep.ac.cn) +/////////////////////////////////////////////////////////// + +#ifndef RECGENFITALG_GENFITFIELD_H +#define RECGENFITALG_GENFITFIELD_H + +#include "AbsBField.h" +#include "DD4hep/Fields.h" + +class TVector3; + + +/// Calss for translating Field into genfit::AbsBField +class GenfitField : public genfit::AbsBField{ + public: + GenfitField(dd4hep::OverlayedField dd4hepField); + virtual ~GenfitField(){;} + + //Get field value from TVector3 + TVector3 get(const TVector3& pos) const override; + + //Get field value from doubles + void get(const double& posX, const double& posY, const double& posZ, + double& Bx, double& By, double& Bz) const override; + + //Get Bz, kilogauss + double getBz(const TVector3& pos) const; + + //Get dd4hep field + const dd4hep::OverlayedField field() const {return m_dd4hepField;} + + private: + dd4hep::OverlayedField m_dd4hepField; +}; +#endif diff --git a/Reconstruction/RecGenfitAlg/src/GenfitFitter.cpp b/Reconstruction/RecGenfitAlg/src/GenfitFitter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..15d40830f9d3fa8deb71e0ca3e306ee7e5ad7c37 --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/GenfitFitter.cpp @@ -0,0 +1,612 @@ +#include "GenfitFitter.h" +#include "GenfitTrack.h" +#include "GenfitMsg.h" +#include "GenfitField.h" +#include "GenfitMaterialInterface.h" + +//Gaudi +#include "GaudiKernel/StatusCode.h" +#include "GaudiKernel/ISvcLocator.h" + +//External +#include "DD4hep/DD4hepUnits.h" +#include "DD4hep/Detector.h" + +//genfit +#include <Track.h> +#include <Exception.h> +#include <FieldManager.h> +#include <TGeoMaterialInterface.h> +#include <TGeoManager.h> +#include <MaterialEffects.h> +#include <MeasuredStateOnPlane.h> +#include <KalmanFitter.h> +#include <KalmanFitterRefTrack.h> +#include <StateOnPlane.h> +#include <DAF.h> +#include <AbsKalmanFitter.h> +#include <KalmanFitterInfo.h> + +//ROOT +#include <TVector3.h> +#include <TGeoManager.h> + +//STL +#include <iostream> +#include <string> + + +GenfitFitter::~GenfitFitter(){ + delete m_absKalman; +} + +GenfitFitter::GenfitFitter(const char* type, const char* name): + m_absKalman(nullptr) + ,m_genfitField(nullptr) + ,m_geoMaterial(nullptr) + ,m_fitterType(type) + ,m_name(name) + ,m_minIterations(4) + ,m_maxIterations(10) + ,m_deltaPval(1e-3) + ,m_relChi2Change(0.2) + ,m_blowUpFactor(1e3) + ,m_resetOffDiagonals(true) + ,m_blowUpMaxVal(1.e6) + ,m_multipleMeasurementHandling(genfit::unweightedClosestToPredictionWire) + ,m_maxFailedHits(-1) + ,m_deltaWeight(1e-3) + ,m_annealingBetaStart(100) + ,m_annealingBetaStop(0.01) + ,m_annealingNSteps(0.01) + ,m_noEffects(false) + ,m_energyLossBetheBloch(true) + ,m_noiseBetheBloch(true) + ,m_noiseCoulomb(true) + ,m_energyLossBrems(false) + ,m_noiseBrems(false) + ,m_ignoreBoundariesBetweenEqualMaterials(true) + ,m_mscModelName("GEANE") + ,m_debug(0) + ,m_hist(0) +{ + /// Initialize genfit fitter + init(); +} + +void GenfitFitter::setField(const GenfitField* field) +{ + if(nullptr==m_genfitField) m_genfitField=field; +} + +/// Set geometry for material, use geometry from IOADatabase +void GenfitFitter::setGeoMaterial(const dd4hep::Detector* dd4hepGeo) +{ + if(nullptr==m_geoMaterial){ + m_geoMaterial=GenfitMaterialInterface::getInstance(dd4hepGeo); + } +} + +/// initialize genfit fitter +int GenfitFitter::init(bool deleteOldFitter) +{ + if(deleteOldFitter && m_absKalman) delete m_absKalman; + + GenfitMsg::get()<<MSG::DEBUG<<"Initialize GenfitFitter with " + <<m_fitterType<<endmsg; + + if (m_fitterType=="DAFRef") { + m_absKalman = new genfit::DAF(true,getDeltaPval(), + getConvergenceDeltaWeight()); + } + else if (m_fitterType=="DAF") { + m_absKalman = new genfit::DAF(false,getDeltaPval(), + getConvergenceDeltaWeight()); + } + else if (m_fitterType=="KalmanFitter") { + m_absKalman = new genfit::KalmanFitter(getMaxIterations()); + } + else if (m_fitterType=="KalmanFitterRefTrack") { + m_absKalman = new genfit::KalmanFitterRefTrack(getMaxIterations()); + } + else { + m_absKalman = nullptr; + GenfitMsg::get()<< MSG::DEBUG<<"Fitter type is invalid:" + <<m_fitterType<<endmsg; + return -1; + } + GenfitMsg::get()<<MSG::DEBUG<<"Fitter type is "<<m_fitterType<<endmsg; + m_absKalman->setDebugLvl(m_debug); + + return 0; +} + +/// Fit a track from a candidate track +int GenfitFitter::processTrackWithRep(GenfitTrack* track,int repID,bool resort) +{ + GenfitMsg::get()<<MSG::DEBUG<< "In ProcessTrackWithRep rep "<<repID<<endmsg; + if(getDebug()>2) print(""); + + if(getDebug()>0){ + GenfitMsg::get()<<MSG::DEBUG<<"Print track seed "<<endmsg; + track->getTrack()->getStateSeed().Print(); + } + /// Do the fitting + try{ + m_absKalman->processTrackWithRep(track->getTrack(), track->getRep(repID), + resort); + }catch(genfit::Exception& e){ + GenfitMsg::get()<<MSG::DEBUG<<"Genfit exception caught "<<endmsg; + e.what(); + return false; + } + GenfitMsg::get()<<MSG::DEBUG<<"End of ProcessTrackWithRep"<<endmsg; + return true; +} // End of ProcessTrackWithRep + +/// Fit a track from a candidate track +int GenfitFitter::processTrack(GenfitTrack* track, bool resort) +{ + GenfitMsg::get()<<MSG::DEBUG<<"In ProcessTrack"<<endmsg; + if(getDebug()>2) print(""); + + /// Do the fitting + try{ + m_absKalman->processTrack(track->getTrack(),resort); + }catch(genfit::Exception& e){ + GenfitMsg::get()<<MSG::DEBUG<<"Genfit exception caught "<<endmsg; + e.what(); + return false; + } + GenfitMsg::get()<<MSG::DEBUG<<"End of ProcessTrack"<<endmsg; + return true; +} // End of ProcessTrack + + +void GenfitFitter::setFitterType(const char* val) +{ + std::string oldFitterType=m_fitterType; + m_fitterType = val; + GenfitMsg::get()<<MSG::DEBUG<<"Fitter type is "<<m_fitterType<<endmsg; + init(oldFitterType==val); +} + +/// Extrapolate track to the cloest point of approach(POCA) to the wire of hit, +/// return StateOnPlane of this POCA +/// inputs +/// pos,mom ... position & momentum at starting point, unit= [mm]&[GeV/c] +/// (converted to [cm]&[GeV/c] inside this function) +/// hit ... destination +/// outputs poca [mm] (converted from [cm] in this function) ,global +double GenfitFitter::extrapolateToHit( TVector3& poca, TVector3& pocaDir, + TVector3& pocaOnWire, double& doca, const GenfitTrack* track, + TVector3 pos, TVector3 mom, + TVector3 end0,//one end of the hit wire + TVector3 end1,//the orhter end of the hit wire + int debug, + int repID, + bool stopAtBoundary, + bool calcJacobianNoise) +{ + + return track->extrapolateToHit(poca,pocaDir,pocaOnWire,doca,pos,mom,end0, + end1,debug,repID,stopAtBoundary,calcJacobianNoise); +}//end of ExtrapolateToHit + + +/// Extrapolate the track to the cyliner at fixed raidus +/// position & momentum as starting point +/// position and momentum at global coordinate in dd4hepUnit +/// return trackLength in dd4hepUnit + double +GenfitFitter::extrapolateToCylinder(TVector3& pos, TVector3& mom, + GenfitTrack* track, double radius, const TVector3 linePoint, + const TVector3 lineDirection, int hitID, int repID, + bool stopAtBoundary, bool calcJacobianNoise) +{ + double trackLength(1e9*dd4hep::cm); + if(!track->getFitStatus(repID)->isFitted()) return trackLength; + try{ + // get track rep + genfit::AbsTrackRep* rep = track->getRep(repID); + if(nullptr == rep) { + GenfitMsg::get()<<MSG::DEBUG<<"In ExtrapolateToCylinder rep is null" + <<endmsg; + return trackLength*dd4hep::cm; + } + + // get track point with fitter info + genfit::TrackPoint* tp = + track->getTrack()->getPointWithFitterInfo(hitID,rep); + if(nullptr == tp) { + GenfitMsg::get()<<MSG::DEBUG<< + "In ExtrapolateToCylinder TrackPoint is null"<<endmsg; + return trackLength*dd4hep::cm; + } + + // get fitted state on plane of this track point + genfit::KalmanFittedStateOnPlane* state = + static_cast<genfit::KalmanFitterInfo*>( + tp->getFitterInfo(rep))->getBackwardUpdate(); + + if(nullptr == state){ + GenfitMsg::get()<<MSG::DEBUG<<"In ExtrapolateToCylinder " + <<"no KalmanFittedStateOnPlane in backwardUpdate"<<endmsg; + return trackLength*dd4hep::cm; + } + rep->setPosMom(*state, pos*(1/dd4hep::cm), mom*(1/dd4hep::GeV)); + + /// extrapolate + trackLength = rep->extrapolateToCylinder(*state, + radius/dd4hep::cm, linePoint*(1/dd4hep::cm), lineDirection, + stopAtBoundary, calcJacobianNoise); + // get pos&mom at extrapolated point on the cylinder + rep->getPosMom(*state,pos,mom);//FIXME exception exist + pos = pos*dd4hep::cm; + mom = mom*dd4hep::GeV; + } catch(genfit::Exception& e){ + GenfitMsg::get() << MSG::ERROR + <<"Exception in GenfitFitter::extrapolateToCylinder " + << e.what()<<endmsg; + trackLength = 1e9*dd4hep::cm; + } + return trackLength*dd4hep::cm; +} + +double GenfitFitter::extrapolateToPoint(TVector3& pos, TVector3& mom, + const GenfitTrack* track, + const TVector3& point, + int repID,// same with pidType + bool stopAtBoundary, + bool calcJacobianNoise) const +{ + double trackLength(1e9*dd4hep::cm); + if(!track->getFitStatus(repID)->isFitted()) return trackLength; + try{ + // get track rep + genfit::AbsTrackRep* rep = track->getRep(repID); + if(nullptr == rep) { + GenfitMsg::get()<<MSG::DEBUG<<"In ExtrapolateToPoint rep " + <<repID<<" not exist!"<<endmsg; + return trackLength*dd4hep::cm; + } + + /// extrapolate to point + //genfit::StateOnPlane state(*(&(track->getTrack()->getFittedState(0,rep)))); + + // get track point with fitter info + genfit::TrackPoint* tp = + track->getTrack()->getPointWithFitterInfo(0,rep); + if(nullptr == tp) { + GenfitMsg::get()<<MSG::DEBUG<< + "In ExtrapolateToPoint TrackPoint is null"<<endmsg; + return trackLength*dd4hep::cm; + } + + // get fitted state on plane of this track point + genfit::KalmanFittedStateOnPlane* state = + static_cast<genfit::KalmanFitterInfo*>( + tp->getFitterInfo(rep))->getBackwardUpdate(); + + if(nullptr == state) { + GenfitMsg::get()<<MSG::DEBUG<< + "In ExtrapolateToPoint KalmanFittedStateOnPlane is null"<<endmsg; + return trackLength*dd4hep::cm; + } + trackLength = rep->extrapolateToPoint(*state, + point*(1/dd4hep::cm),stopAtBoundary, calcJacobianNoise); + rep->getPosMom(*state,pos,mom);//FIXME exception exist + pos = pos*dd4hep::cm; + mom = mom*dd4hep::GeV; + } catch(genfit::Exception& e){ + GenfitMsg::get() << MSG::ERROR + <<"Exception in GenfitFitter::extrapolateToPoint" + << e.what()<<endmsg; + trackLength = 1e9*dd4hep::cm; + } + return trackLength*dd4hep::cm; +}//end of ExtrapolateToPoint + +GenfitFitter& GenfitFitter::operator=( + const GenfitFitter& r) +{ + m_fitterType = r.m_fitterType; + m_minIterations = r.m_minIterations; + m_maxIterations = r.m_maxIterations; + m_deltaPval = r.m_deltaPval; + m_relChi2Change = r.m_relChi2Change; + m_blowUpFactor = r.m_blowUpFactor; + m_resetOffDiagonals = r.m_resetOffDiagonals; + m_blowUpMaxVal = r.m_blowUpMaxVal; + m_multipleMeasurementHandling = r.m_multipleMeasurementHandling; + m_maxFailedHits = r.m_maxFailedHits; + m_annealingNSteps = r.m_annealingNSteps; + m_deltaWeight = r.m_deltaWeight; + m_annealingBetaStart = r.m_annealingBetaStart; + m_annealingBetaStop = r.m_annealingBetaStop; + m_noEffects = r.m_noEffects; + m_energyLossBetheBloch= r.m_energyLossBetheBloch; + m_noiseBetheBloch = r.m_noiseBetheBloch; + m_noiseCoulomb = r.m_noiseCoulomb; + m_energyLossBrems = r.m_energyLossBrems; + m_noiseBrems = r.m_noiseBrems; + m_ignoreBoundariesBetweenEqualMaterials + = r.m_ignoreBoundariesBetweenEqualMaterials; + m_mscModelName = r.m_mscModelName; + m_debug = r.m_debug; + m_hist = r.m_hist; + return *this; +} + +void GenfitFitter::print(const char* name) +{ + + if(0==strlen(name)) name=m_name; + //TODO print all fitting parameters + GenfitMsg::get()<<MSG::DEBUG<<name + <<" GenfitFitter Global Parameters:"<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" Fitter type = " << m_fitterType<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" Fitting Parameters:"<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" MinIteration = " << m_minIterations<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" MaxIteration = " << m_maxIterations<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" m_deltaPval = " << m_deltaPval<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" Material Effect Parameters:"<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" m_noEffects = " << m_noEffects<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" m_energyLossBetheBloch= " << m_energyLossBetheBloch<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" m_noiseBetheBloch = " << m_noiseBetheBloch<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" m_noiseCoulomb = " << m_noiseCoulomb<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" m_energyLossBrems = " << m_energyLossBrems<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" m_noiseBrems = " << m_noiseBrems<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" m_ignoreBoundariesBetweenEqualMaterials= " + << m_ignoreBoundariesBetweenEqualMaterials<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" m_mscModelName = " << m_mscModelName<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" m_debug = " << m_debug<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<name + <<" m_hist = " << m_hist<<endmsg; + + if(m_fitterType=="DAF"||m_fitterType=="DAFRef"){ + genfit::DAF* daf = getDAF(); + + if(nullptr != daf){ + std::ostringstream sBetas; + std::vector<double> betas = daf->getBetas(); + for (unsigned int i=0; i<betas.size(); ++i) { + sBetas<<betas.at(i)<<","; + } + GenfitMsg::get()<<MSG::DEBUG<<" print "<<betas.size()<< + " betas: %s "<<sBetas.str()<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<m_name + << " m_deltaWeight = " << m_deltaWeight<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<" DAF maxIterations= " + << daf->getMaxIterations()<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<" DAF minIterations= " + << daf->getMinIterations()<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<" DAF deltaPval= " + << daf->getDeltaPval()<<endmsg; + } + } + genfit::KalmanFitterRefTrack* ref = getKalRef(); + if(nullptr != ref){ + std::ostringstream sBetas; + GenfitMsg::get()<<MSG::DEBUG<<" DAF maxIterations= " + << ref->getMaxIterations()<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<" DAF minIterations= " + << ref->getMinIterations()<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<" DAF deltaPval= " + << ref->getDeltaPval()<<endmsg; + } +} + +///Setters of AbsKalmanFitter +void GenfitFitter::setMinIterations(unsigned int val) +{ + m_absKalman->setMinIterations(val); + m_minIterations = val; +} + +void GenfitFitter::setMaxIterations(unsigned int val) +{ + if(val<=4) { + GenfitMsg::get()<<MSG::ERROR<<"Could NOT set MaxIteration<=4!"<<endmsg; + } + m_absKalman->setMaxIterations(val); + m_maxIterations = val; +} + +void GenfitFitter::setMaxIterationsBetas(double bStart,double bFinal, + unsigned int val) +{ + m_absKalman->setMaxIterations(val); + m_maxIterations = val; + if(val<=4) { + GenfitMsg::get()<<MSG::ERROR<<"Could NOT set MaxIteration<=4!"<<endmsg; + } + GenfitMsg::get()<<MSG::DEBUG<<"bStart "<<bStart<<" bFinal "<<bFinal + <<" MaxIteration "<<val<<endmsg; + // genfit version less than 2.2.0 + genfit::DAF* daf = dynamic_cast<genfit::DAF*> (m_absKalman); + daf->setAnnealingScheme(bStart,bFinal,val); +} + +void GenfitFitter::setDeltaPval(double val) +{ + m_absKalman->setDeltaPval(val); + m_deltaPval = val; +} + +void GenfitFitter::setRelChi2Change(double val) +{ + m_absKalman->setRelChi2Change(val); + m_relChi2Change = val; +} + +void GenfitFitter::setBlowUpFactor(double val) +{ + m_absKalman->setBlowUpFactor(val); + m_blowUpFactor = val; +} + +void GenfitFitter::setResetOffDiagonals(bool val) +{ + m_absKalman->setResetOffDiagonals(val); + m_resetOffDiagonals = val; +} + +void GenfitFitter::setBlowUpMaxVal(double val) +{ + m_absKalman->setBlowUpMaxVal(val); + m_blowUpMaxVal = val; +} + +void GenfitFitter::setMultipleMeasurementHandling( + genfit::eMultipleMeasurementHandling val) +{ + m_absKalman->setMultipleMeasurementHandling(val); + m_multipleMeasurementHandling = val; +} + +void GenfitFitter::setMaxFailedHits(int val) +{ + m_absKalman->setMaxFailedHits(val); + m_maxFailedHits = val; +} + +///DAF setters +void GenfitFitter::setConvergenceDeltaWeight(double val) +{ + genfit::DAF* daf = getDAF(); + if(nullptr != daf) daf->setConvergenceDeltaWeight(val); + m_deltaWeight = val; +} +void GenfitFitter::setAnnealingScheme( + double bStart, double bFinal, unsigned int nSteps) +{ + genfit::DAF* daf = getDAF(); + if(nullptr != daf) daf->setAnnealingScheme(bStart, bFinal, nSteps); + m_annealingBetaStart = bStart; + m_annealingBetaStop = bFinal; + m_annealingNSteps = nSteps; +} + +//TODO chi2Cuts? +///Material effects +void GenfitFitter::setNoEffects(bool val) +{ + genfit::MaterialEffects::getInstance()->setNoEffects(); + m_noEffects = val; +} + +void GenfitFitter::setEnergyLossBetheBloch(bool val) +{ + genfit::MaterialEffects::getInstance()->setEnergyLossBetheBloch(val); + m_energyLossBetheBloch = val; +} + +void GenfitFitter::setNoiseBetheBloch(bool val) +{ + genfit::MaterialEffects::getInstance()->setNoiseBetheBloch(val); + m_noiseBetheBloch = val; +} + +void GenfitFitter::setNoiseCoulomb(bool val) +{ + genfit::MaterialEffects::getInstance()->setNoiseCoulomb(val); + m_noiseCoulomb = val; +} + +void GenfitFitter::setEnergyLossBrems(bool val) +{ + genfit::MaterialEffects::getInstance()->setEnergyLossBrems(val); + m_energyLossBrems = val; +} + +void GenfitFitter::setNoiseBrems(bool val) +{ + genfit::MaterialEffects::getInstance()->setNoiseBrems(val); + m_noiseBrems = val; +} + +void GenfitFitter::setIgnoreBoundariesBetweenEqualMaterials(bool val) +{ + genfit::MaterialEffects::getInstance()-> + ignoreBoundariesBetweenEqualMaterials(val); + m_ignoreBoundariesBetweenEqualMaterials = val; +} + +void GenfitFitter::setMscModelName(std::string val) +{ + genfit::MaterialEffects::getInstance()->setMscModel(val); + m_mscModelName = val; +} + +void GenfitFitter::setMaterialDebugLvl(unsigned int val) +{ + genfit::MaterialEffects::getInstance()->setDebugLvl(val); +} + +///Set GenfitFitter parameters +void GenfitFitter::setDebug(unsigned int val) +{ + GenfitMsg::get()<<MSG::DEBUG<<"set fitter debugLvl "<<val<<endmsg; + m_absKalman->setDebugLvl(val); + if(nullptr!=getDAF()) getDAF()->setDebugLvl(val); + if(val>10) genfit::MaterialEffects::getInstance()->setDebugLvl(val); + m_debug = val; +} + +void GenfitFitter::setHist(unsigned int val) {m_hist = val;} + +genfit::DAF* GenfitFitter::getDAF() +{ + genfit::DAF* daf = nullptr; + try{ + daf = dynamic_cast<genfit::DAF*> (m_absKalman); + }catch(...){ + GenfitMsg::get()<< MSG::ERROR + << "dynamic_cast m_rom AbsFitter to DAF m_ailed!"<<endmsg; + return nullptr; + } + return daf; +} + +genfit::KalmanFitterRefTrack* GenfitFitter::getKalRef() +{ + genfit::KalmanFitterRefTrack* ref=nullptr; + try{ + ref = dynamic_cast<genfit::KalmanFitterRefTrack*> (m_absKalman); + }catch(...){ + GenfitMsg::get()<< MSG::ERROR + << "dynamic_cast m_rom AbsFitter to KalmanFitterRefTrack m_ailed!" + <<endmsg; + } + return ref; +} + +void GenfitFitter::initHist(std::string name) +{ + GenfitMsg::get()<<MSG::DEBUG<<"GenfitFitter::initHist "<<name<<endmsg; + //getDAF()->initHist(name); +} + +void GenfitFitter::writeHist() +{ + GenfitMsg::get()<<MSG::DEBUG<<"GenfitFitter::writeHist "<<endmsg; + //getDAF()->writeHist(); +} + + diff --git a/Reconstruction/RecGenfitAlg/src/GenfitFitter.h b/Reconstruction/RecGenfitAlg/src/GenfitFitter.h new file mode 100644 index 0000000000000000000000000000000000000000..9ca4664456dab2f9484f1b1e9ad2c8d33fc5474a --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/GenfitFitter.h @@ -0,0 +1,200 @@ +////////////////////////////////////////////////////////////////// +/// +/// This is an interface of to call genfit fitter +/// +/// In this file, including: +/// a genfit fitter class +/// Fitter type is fixed after creation +/// Magnetic field and geometry for material effect are singletons in genfit. +/// They will be set before fitting and before each time call track rep. +/// +/// Authors: +/// Yao ZHANG (zhangyao@ihep.ac.cn) +/// +////////////////////////////////////////////////////////////////// + +#ifndef RECGENFITALG_GENFITFITTER_H +#define RECGENFITALG_GENFITFITTER_H + +#include "AbsKalmanFitter.h" +#include <string> + +class GenfitField; +class GenfitMaterialInterface; +class GenfitTrack; +class TVector3; +class TGeoManager; +class ISvcLocator; +namespace genfit{ + class AbsKalmanFitter; + class KalmanFitterRefTrack; + class DAF; +} +namespace dd4hep{ + class OverlayedField; + class Detector; +} + + +/// The GenfitTrack class +class GenfitFitter{ + public: + /// Type of fitters are :DAFRef,DAF,KalmanFitter,KalmanFitterRefTrack + GenfitFitter(const char* type="DAFRef",const char* name="GenfitFitter"); + virtual ~GenfitFitter(); + + /// Magnetic field and geometry for material effect in genfit + /// please SET before use !!!! + void setField(const GenfitField* field); + /// please SET before use !!!! + void setGeoMaterial(const dd4hep::Detector* dd4hepGeo); + + /// Main fitting function + int processTrack(GenfitTrack* track, bool resort=false); + + /// fitting with rep + int processTrackWithRep(GenfitTrack* track,int repID=0, + bool resort=false); + + /// Extrapolate the track to the CDC hit + /// Output: poca pos and dir and poca distance to the hit wire + /// Input: genfit track, pos and mom, two ends of a wire + /// pos, and mom are position & momentum at starting point + double extrapolateToHit(TVector3& poca, TVector3& pocaDir, + TVector3& pocaOnWire, double& doca, const GenfitTrack* track, + TVector3 pos, TVector3 mom, TVector3 end0, TVector3 end1, + int debug=0, int repID=0, bool stopAtBoundary=false, + bool calcJacobianNoise=false); + + /// Extrapolate the track to the cyliner at fixed raidus + /// Output: pos and mom at fixed radius + /// Input: genfitTrack, radius of cylinder at center of the origin, + /// repID, stopAtBoundary and calcAverageState + double extrapolateToCylinder(TVector3& pos, TVector3& mom, + GenfitTrack* track, double radius, const TVector3 linePoint, + const TVector3 lineDirection, int hitID =0, int repID=0, + bool stopAtBoundary=false, bool calcJacobianNoise=false); + + /// Extrapolate the track to the point + /// Output: pos and mom of POCA point to point + /// Input: genfitTrack,point,repID,stopAtBoundary and calcAverageState + /// repID same with pidType + double extrapolateToPoint(TVector3& pos, TVector3& mom, + const GenfitTrack* genfitTrack, const TVector3& point, + int repID=0, bool stopAtBoundary = false, + bool calcJacobianNoise = false) const; + + /// setters of fitter properties + void setFitterType(const char* val); + void setMinIterations(unsigned int val); + void setMaxIterations(unsigned int val); + void setMaxIterationsBetas(double bStart,double bFinal,unsigned int val); + void setDeltaPval(double val); + void setRelChi2Change(double val); + void setBlowUpFactor(double val); + void setResetOffDiagonals(bool val); + void setBlowUpMaxVal(double val); + void setMultipleMeasurementHandling( + genfit::eMultipleMeasurementHandling val); + void setMaxFailedHits(int val); + void setConvergenceDeltaWeight(double val); + void setAnnealingScheme(double bStart,double bFinal,unsigned int nSteps); + //TODO chi2cut? + void setNoEffects(bool val); + void setEnergyLossBetheBloch(bool val); + void setNoiseBetheBloch(bool val); + void setNoiseCoulomb(bool val); + void setEnergyLossBrems(bool val); + void setNoiseBrems(bool val); + void setIgnoreBoundariesBetweenEqualMaterials(bool val); + void setMscModelName(std::string val); + void setMaterialDebugLvl(unsigned int val); + void setDebug(unsigned int val); + void setHist(unsigned int val); + + /// getters of fitter properties + std::string getFitterType() const {return m_fitterType;} + unsigned int getMinIterations() const { return m_minIterations; } + unsigned int getMaxIterations() const { return m_maxIterations; } + double getDeltaPval() const { return m_deltaPval; } + double getRelChi2Change() const { return m_relChi2Change; } + double getBlowUpFactor() const { return m_blowUpFactor; } + double getBlowUpMaxVal() const { return m_blowUpMaxVal; } + bool getResetOffDiagonals() const { return m_resetOffDiagonals; } + genfit::eMultipleMeasurementHandling getMultipleMeasurementHandling() + const { return m_multipleMeasurementHandling; } + int getMaxFailedHits() const { return m_maxFailedHits; } + double getConvergenceDeltaWeight() const { return m_deltaWeight; } + float getAnnealingBetaStart() const {return m_annealingBetaStart;} + float getAnnealingBetaStop() const {return m_annealingBetaStop;} + bool getNoEffects(){return m_noEffects;} + bool getEnergyLossBetheBloch(){return m_energyLossBetheBloch;} + bool getNoiseBetheBloch(){return m_noiseBetheBloch;} + bool getNoiseCoulomb(){return m_noiseCoulomb;} + bool getEnergyLossBrems(){return m_energyLossBrems;} + bool getNoiseBrems(){return m_noiseBrems;} + bool getIgnoreBoundariesBetweenEqualMaterials() + {return m_ignoreBoundariesBetweenEqualMaterials;} + std::string getMscModelName(){return m_mscModelName;} + int getDebug() const {return m_debug;} + int getHist() const {return m_hist;} + + /// Printer + void print(const char* name=""); + void initHist(std::string name); + void writeHist(); + + const char* getName(void) const {return m_name;} + + private: + GenfitFitter(const GenfitFitter&){}; + GenfitFitter& operator=(const GenfitFitter&); + + /// Initialze fitter and setting fitter parameter + int init(bool deleteOldFitter=false); + + /// Get DAF fitter + genfit::DAF* getDAF(); + /// Get KalmanFitterRefTrack + genfit::KalmanFitterRefTrack* getKalRef(); + + genfit::AbsKalmanFitter* m_absKalman;/// kalman fitter object + + const GenfitField* m_genfitField;//pointer to genfit field + GenfitMaterialInterface* m_geoMaterial;//pointer to genfit geo + + ///fitting method: DAFRef,DAF,KalmanFitter,KalmanFitterRefTrack + std::string m_fitterType; + + const char* m_name; + + /// control parameters of fitter + unsigned int m_minIterations; /// minimum number of iterations + unsigned int m_maxIterations; /// maximum number of iterations + double m_deltaPval; /// delta pVal that converged + double m_relChi2Change; /// + double m_blowUpFactor; /// + bool m_resetOffDiagonals; /// + double m_blowUpMaxVal; /// + genfit::eMultipleMeasurementHandling m_multipleMeasurementHandling;/// + int m_maxFailedHits; /// + double m_deltaWeight; /// delta weight that converged + double m_annealingBetaStart;/// start beta for annealing + double m_annealingBetaStop; /// stop beta for annealing + unsigned int m_annealingNSteps; /// n steps + + /// control parAmeters of material effects + bool m_noEffects; + bool m_energyLossBetheBloch; + bool m_noiseBetheBloch; + bool m_noiseCoulomb; + bool m_energyLossBrems; + bool m_noiseBrems; + bool m_ignoreBoundariesBetweenEqualMaterials; + std::string m_mscModelName; + + int m_debug; /// debug + int m_hist; /// hist +}; + +#endif diff --git a/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.cpp b/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.cpp new file mode 100644 index 0000000000000000000000000000000000000000..73a59316e0dbbe52c1b1743eaa6bb6bcc4b4b6c9 --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.cpp @@ -0,0 +1,353 @@ +/// +/// Authors: ZHANG Yao (zhangyao@ihep.ac.cn) +/// + +#include "GenfitMaterialInterface.h" +//Gaudi +#include "GaudiKernel/Bootstrap.h" +#include "GaudiKernel/SmartIF.h" +#include "GaudiKernel/ISvcLocator.h" +//CEPCSW +#include "DetInterface/IGeomSvc.h" +//Externals +#include "DD4hep/Detector.h" +//#include "DD4hep/DD4hepUnits.h" +//genfit +#include "Exception.h" +//ROOT +#include "TGeoManager.h" +#include "TGeoNode.h" +#include "TGeoMedium.h" +#include "TGeoMaterial.h" +#include "TGeoManager.h" +#include "MaterialEffects.h" +#include "Material.h" +//STL +#include <assert.h> +#include <math.h> + +GenfitMaterialInterface* GenfitMaterialInterface::m_instance = nullptr; + +//#define DEBUG_GENFITGEO 1 + +double MeanExcEnergy_get(int Z); +double MeanExcEnergy_get(TGeoMaterial*); + +GenfitMaterialInterface::GenfitMaterialInterface( + const dd4hep::Detector* dd4hepGeo) +{ + assert(nullptr!=dd4hepGeo); + m_geoManager=&(dd4hepGeo->manager()); + assert(nullptr!=m_geoManager); +} + +GenfitMaterialInterface* GenfitMaterialInterface::getInstance( + const dd4hep::Detector* dd4hepGeo) +{ + if(nullptr == m_instance){ + m_instance = new GenfitMaterialInterface(dd4hepGeo); + } + genfit::MaterialEffects::getInstance()->init(m_instance); + return m_instance; +} + +void GenfitMaterialInterface::destruct(){ + delete m_instance; +} + +TGeoManager* GenfitMaterialInterface::getGeoManager() +{ + return m_geoManager; +} + + bool +GenfitMaterialInterface::initTrack(double posX, double posY, + double posZ, double dirX, double dirY, double dirZ) +{ + //debugLvl_ = 1; +#ifdef DEBUG_GENFITGEO + std::cout << "GenfitMaterialInterface::initTrack. \n"; + std::cout << "Pos "; TVector3(posX, posY, posZ).Print(); + std::cout << "Dir "; TVector3(dirX, dirY, dirZ).Print(); +#endif + + // Move to the new point. + bool result = !isSameLocation(posX, posY, posZ, kTRUE); + + // Set the intended direction. + setCurrentDirection(dirX, dirY, dirZ); + + if (debugLvl_ > 0) { + std::cout << " GenfitMaterialInterface::initTrack at \n"; + std::cout << " position: "; TVector3(posX, posY, posZ).Print(); + std::cout << " direction: "; TVector3(dirX, dirY, dirZ).Print(); + } + + return result; +} + + +genfit::Material GenfitMaterialInterface::getMaterialParameters() +{ + TGeoMaterial* mat = + getGeoManager()->GetCurrentVolume()->GetMedium()->GetMaterial(); + //Scalar density; /// Density in g / cm^3 + //Scalar Z; /// Atomic number + //Scalar A; /// Mass number in g / mol + //Scalar radiationLength; /// Radiation Length in cm + //Scalar mEE; /// Mean excitaiton energy in eV + //Material from CEPCSW is NOT follow the dd4hep?FIXME + + //std::cout<<__FILE__<<" "<<__LINE__<<" yzhang debug material "<<std::endl; + //mat->Print(); + return genfit::Material(mat->GetDensity(), mat->GetZ(), mat->GetA(), + mat->GetRadLen(), MeanExcEnergy_get(mat)); +} + + double +GenfitMaterialInterface::findNextBoundary(const genfit::RKTrackRep* rep, + const genfit::M1x7& stateOrig, + double sMax, // signed + bool varField) +{ + //debugLvl_ = 1; + // cm, distance limit beneath which straight-line steps are taken. + const double delta(1.E-2); + const double epsilon(1.E-1); // cm, allowed upper bound on arch + // deviation from straight line + + genfit::M1x3 SA; + genfit::M1x7 state7, oldState7; + oldState7 = stateOrig; + + int stepSign(sMax < 0 ? -1 : 1); + + double s = 0; // trajectory length to boundary + + const unsigned maxIt = 300; + unsigned it = 0; + + // Initialize the geometry to the current location (set by caller). + findNextBoundary(fabs(sMax) - s); + double safety = getSafeDistance(); // >= 0 + double slDist = getStep(); + + // this should not happen, but it happens sometimes. + // The reason are probably overlaps in the geometry. + // Without this "hack" many small steps with size of minStep will be made, + // until eventually the maximum number of iterations are exceeded + // and the extrapolation fails + if (slDist < safety) + slDist = safety; + double step = slDist; + + if (debugLvl_ > 0) + std::cout << " safety = " << safety << "; step, slDist = " << step << "\n"; + + while (1) { + if (++it > maxIt){ + genfit::Exception exc("GenfitMaterialInterface::findNextBoundary ==> maximum number of iterations exceeded",__LINE__,__FILE__); + exc.setFatal(); + throw exc; + } + + // No boundary in sight? + if (s + safety > fabs(sMax)) { + if (debugLvl_ > 0) + std::cout << " next boundary is further away than sMax \n"; + return stepSign*(s + safety); //sMax; + } + + // Are we at the boundary? + if (slDist < delta) { + if (debugLvl_ > 0) + std::cout << " very close to the boundary -> return" + << " stepSign*(s + slDist) = " + << stepSign << "*(" << s + slDist << ")\n"; + return stepSign*(s + slDist); + } + + // We have to find whether there's any boundary on our path. + + // Follow curved arch, then see if we may have missed a boundary. + // Always propagate complete way from original start to avoid + // inconsistent extrapolations. + state7 = stateOrig; + rep->RKPropagate(state7, nullptr, SA, stepSign*(s + step), varField); + + // Straight line distance虏 between extrapolation finish and + // the end of the previously determined safe segment. + double dist2 = (pow(state7[0] - oldState7[0], 2) + + pow(state7[1] - oldState7[1], 2) + + pow(state7[2] - oldState7[2], 2)); + // Maximal lateral deviation虏. + double maxDeviation2 = 0.25*(step*step - dist2); + + if (step > safety + && maxDeviation2 > epsilon*epsilon) { + // Need to take a shorter step to reliably estimate material, + // but only if we didn't move by safety. In order to avoid + // issues with roundoff we check 'step > safety' instead of + // 'step != safety'. If we moved by safety, there couldn't have + // been a boundary that we missed along the path, but we could + // be on the boundary. + + // Take a shorter step, but never shorter than safety. + step = std::max(step / 2, safety); + } else { + getGeoManager()->PushPoint(); + bool volChanged = initTrack(state7[0], state7[1], state7[2], + stepSign*state7[3], stepSign*state7[4], + stepSign*state7[5]); + + if (volChanged) { + if (debugLvl_ > 0) + std::cout << " volChanged\n"; + // Move back to start. + getGeoManager()->PopPoint(); + + // Extrapolation may not take the exact step length we asked + // for, so it can happen that a requested step < safety takes + // us across the boundary. This is then the best estimate we + // can get of the distance to the boundary with the stepper. + if (step <= safety) { + if (debugLvl_ > 0) + std::cout << + " step <= safety, return stepSign*(s + step) = " + << stepSign*(s + step) << "\n"; + return stepSign*(s + step); + } + + // Volume changed during the extrapolation. Take a shorter + // step, but never shorter than safety. + step = std::max(step / 2, safety); + } else { + // we're in the new place, the step was safe, advance + s += step; + + oldState7 = state7; + getGeoManager()->PopDummy(); // Pop stack, but stay in place. + + findNextBoundary(fabs(sMax) - s); + safety = getSafeDistance(); + slDist = getStep(); + + // this should not happen, but it happens sometimes. + // The reason are probably overlaps in the geometry. + // Without this "hack" many small steps with size of minStep will be made, + // until eventually the maximum number of iterations are exceeded and the extrapolation fails + if (slDist < safety) + slDist = safety; + step = slDist; + if (debugLvl_ > 0){ + std::cout << " safety = " << safety + << "; step, slDist = " << step << "\n"; + } + } + } + } +} + + +/* + Reference for elemental mean excitation energies at: +http://physics.nist.gov/PhysRefData/XrayMassCoef/tab1.html + +Code ported from GEANT 3 +*/ + +const int MeanExcEnergy_NELEMENTS = 93; // 0 = vacuum, 1 = hydrogen, 92 = uranium +const double MeanExcEnergy_vals[MeanExcEnergy_NELEMENTS] = { + 1.e15, 19.2, 41.8, 40.0, 63.7, 76.0, 78., 82.0, + 95.0, 115.0, 137.0, 149.0, 156.0, 166.0, 173.0, 173.0, + 180.0, 174.0, 188.0, 190.0, 191.0, 216.0, 233.0, 245.0, + 257.0, 272.0, 286.0, 297.0, 311.0, 322.0, 330.0, 334.0, + 350.0, 347.0, 348.0, 343.0, 352.0, 363.0, 366.0, 379.0, + 393.0, 417.0, 424.0, 428.0, 441.0, 449.0, 470.0, 470.0, + 469.0, 488.0, 488.0, 487.0, 485.0, 491.0, 482.0, 488.0, + 491.0, 501.0, 523.0, 535.0, 546.0, 560.0, 574.0, 580.0, + 591.0, 614.0, 628.0, 650.0, 658.0, 674.0, 684.0, 694.0, + 705.0, 718.0, 727.0, 736.0, 746.0, 757.0, 790.0, 790.0, + 800.0, 810.0, 823.0, 823.0, 830.0, 825.0, 794.0, 827.0, + 826.0, 841.0, 847.0, 878.0, 890.0, }; +// Logarithms of the previous table, used to calculate mixtures. +const double MeanExcEnergy_logs[MeanExcEnergy_NELEMENTS] = { + 34.5388, 2.95491, 3.7329, 3.68888, 4.15418, 4.33073, 4.35671, 4.40672, + 4.55388, 4.74493, 4.91998, 5.00395, 5.04986, 5.11199, 5.15329, 5.15329, + 5.19296, 5.15906, 5.23644, 5.24702, 5.25227, 5.37528, 5.45104, 5.50126, + 5.54908, 5.6058, 5.65599, 5.69373, 5.73979, 5.77455, 5.79909, 5.81114, + 5.85793, 5.84932, 5.8522, 5.83773, 5.86363, 5.8944, 5.90263, 5.93754, + 5.97381, 6.03309, 6.04973, 6.05912, 6.08904, 6.10702, 6.15273, 6.15273, + 6.1506, 6.19032, 6.19032, 6.18826, 6.18415, 6.19644, 6.17794, 6.19032, + 6.19644, 6.21661, 6.25958, 6.28227, 6.30262, 6.32794, 6.35263, 6.36303, + 6.38182, 6.41999, 6.44254, 6.47697, 6.4892, 6.51323, 6.52796, 6.54247, + 6.5582, 6.57647, 6.58893, 6.60123, 6.61473, 6.62936, 6.67203, 6.67203, + 6.68461, 6.69703, 6.71296, 6.71296, 6.72143, 6.71538, 6.67708, 6.7178, + 6.71659, 6.73459, 6.7417, 6.77765, 6.79122, }; + + +double +MeanExcEnergy_get(int Z, bool logs = false) { + assert(Z >= 0 && Z < MeanExcEnergy_NELEMENTS); + if (logs) + return MeanExcEnergy_logs[Z]; + else + return MeanExcEnergy_vals[Z]; +} + + +double +MeanExcEnergy_get(TGeoMaterial* mat) { + if (mat->IsMixture()) { + // The mean excitation energy is calculated as the geometric mean + // of the mEEs of the components, weighted for abundance. + double logMEE = 0.; + double denom = 0.; + TGeoMixture* mix = (TGeoMixture*)mat; + for (int i = 0; i < mix->GetNelements(); ++i) { + int index = int(mix->GetZmixt()[i]); + double weight = mix->GetWmixt()[i] * mix->GetZmixt()[i] / mix->GetAmixt()[i]; + logMEE += weight * MeanExcEnergy_get(index, true); + denom += weight; + } + logMEE /= denom; + return exp(logMEE); + } + + // not a mixture + int index = int(mat->GetZ()); + return MeanExcEnergy_get(index, false); +} + +double GenfitMaterialInterface::getSafeDistance() +{ + return getGeoManager()->GetSafeDistance(); +} + +double GenfitMaterialInterface::getStep() +{ + return getGeoManager()->GetSafeDistance(); +} + +TGeoNode* GenfitMaterialInterface::findNextBoundary(double stepmax, + const char* path,bool frombdr) +{ + return getGeoManager()->FindNextBoundary(stepmax,path,frombdr); +} + +bool GenfitMaterialInterface::isSameLocation(double posX, double posY, + double posZ, bool change) +{ + //std::cout<<" MatInt "<<__LINE__<<" posXYZ*dd4hep::cm "<<posX*dd4hep::cm + //<<" posY "<<posY*dd4hep::cm<<" posZ "<<posZ*dd4hep::cm<<std::endl; + return getGeoManager()->IsSameLocation(posX,posY, + posZ,change); +} + +void GenfitMaterialInterface::setCurrentDirection(double nx, double ny, + double nz) +{ + return getGeoManager()->SetCurrentDirection(nx, ny, nz); + +} + diff --git a/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.h b/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..83da9fc1e4cbb372e7c7d7ee35efde3bd5d22646 --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/GenfitMaterialInterface.h @@ -0,0 +1,74 @@ +///////////////////////////////////////////////////////////////////////// +// An implementation of genfit AbsMaterialInterface +// +// Author: +// Yao ZHANG (zhangyao@ihep.ac.cn) +// +// +///////////////////////////////////////////////////////////////////////// + +#ifndef RECGENFITALG_GENFITMATERIALINTERFACE_H +#define RECGENFITALG_GENFITMATERIALINTERFACE_H + +#include "AbsMaterialInterface.h" + +class RKTrackRep; +class TGeoManager; +class TGeoNode; +namespace dd4hep{ + class Detector; +} + +/** + * @brief MaterialInterface implementation for use with ROOT's TGeoManager. + */ +class GenfitMaterialInterface : public genfit::AbsMaterialInterface{ + public: + GenfitMaterialInterface(const dd4hep::Detector* dd4hepGeo); + virtual ~GenfitMaterialInterface(){}; + static GenfitMaterialInterface* getInstance( + const dd4hep::Detector* dd4hepGeo); + void destruct(); + + //Set Detector pointer of dd4hep + void setDetector(dd4hep::Detector*); + + /** @brief Initialize the navigator at given position and with given + direction. Returns true if the volume changed. + */ + bool initTrack(double posX, double posY, double posZ, + double dirX, double dirY, double dirZ) override; + + genfit::Material getMaterialParameters() override; + + + /** @brief Make a step (following the curvature) until step length + * sMax or the next boundary is reached. After making a step to a + * boundary, the position has to be beyond the boundary, i.e. the + * current material has to be that beyond the boundary. The actual + * step made is returned. + */ + double findNextBoundary(const genfit::RKTrackRep* rep, + const genfit::M1x7& state7, + double sMax, + bool varField = true) override; + + // ClassDef(GenfitMaterialInterface, 1); + + private: + static GenfitMaterialInterface* m_instance; + TGeoManager* getGeoManager(); + TGeoManager* m_geoManager; + double getSafeDistance(); + double getStep(); + TGeoNode* findNextBoundary(double stepmax, const char* path="", + bool frombdr=false); + bool isSameLocation(double posX, double posY, double posZ, + bool change=false); + void setCurrentDirection(double nx, double ny, double nz); + +}; + +/** @} */ + +#endif // GenfitMaterialInterface diff --git a/Reconstruction/RecGenfitAlg/src/GenfitMsg.cpp b/Reconstruction/RecGenfitAlg/src/GenfitMsg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6799d68e0ed8120274c7b5a0d6ac24eb8fb4b078 --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/GenfitMsg.cpp @@ -0,0 +1,19 @@ +#include "GenfitMsg.h" +#include "GaudiKernel/ServiceHandle.h" +#include "GaudiKernel/IMessageSvc.h" + +MsgStream* GenfitMsg::m_log = nullptr; + +MsgStream GenfitMsg::get(){ + if(nullptr == m_log){ + SmartIF<IMessageSvc> msgSvc( + Gaudi::svcLocator()->service<IMessageSvc>("MessageSvc")); + m_log = new MsgStream(msgSvc, "GenfitMsg"); + (*m_log) << MSG::DEBUG << "initialize GenfitMsg" << endmsg; + } + return (*m_log); +} + +GenfitMsg::~GenfitMsg(){ + delete m_log; +} diff --git a/Reconstruction/RecGenfitAlg/src/GenfitMsg.h b/Reconstruction/RecGenfitAlg/src/GenfitMsg.h new file mode 100644 index 0000000000000000000000000000000000000000..43808b42b425ef29245445c2144c8a255facda4b --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/GenfitMsg.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////// +/// +/// This is a class for genfit interfaces classes to access Gaudi log +/// system +/// +/// Authors: +/// Yao ZHANG(zhangyao@ihep.ac.cn) +/// +////////////////////////////////////////////////////////////////////// +#ifndef RECGENFITALG_GENFITMSG_H +#define RECGENFITALG_GENFITMSG_H + +#include "GaudiKernel/MsgStream.h" + +class GenfitMsg { + public: + static MsgStream get(); + private: + GenfitMsg(){}; + virtual ~GenfitMsg(); + static MsgStream* m_log; + +}; + +#endif + diff --git a/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp b/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f210dc9f69c88a0cbc6407b18911c181c700accf --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/GenfitTrack.cpp @@ -0,0 +1,838 @@ +#include "GenfitTrack.h" +#include "GenfitMsg.h" +#include "GenfitField.h" + +//CEPCSW +#include "DataHelper/HelixClass.h" +#include "UTIL/ILDConf.h" + +//Externals +#include "DD4hep/DD4hepUnits.h" +#include "edm4hep/MCParticle.h" +#include "edm4hep/Track.h" +#include "edm4hep/TrackerHitConst.h" +#include "edm4hep/SimTrackerHit.h" +#include "edm4hep/ReconstructedParticle.h" +#include "edm4hep/TrackerHitCollection.h" +#include "edm4hep/MCRecoTrackerAssociationCollection.h" +#include "edm4hep/Vector3d.h" +#include "DetSegmentation/GridDriftChamber.h" + +//genfit +#include "Track.h" +#include "MeasuredStateOnPlane.h" +#include "RKTrackRep.h" +#include "TrackPoint.h" +#include "StateOnPlane.h" +#include "KalmanFitterInfo.h" +#include "KalmanFittedStateOnPlane.h" +#include "AbsTrackRep.h" +#include "FitStatus.h" +#include "SpacepointMeasurement.h" +#include "WireMeasurementNew.h" + +//ROOT +#include "TRandom.h" +#include "TVector3.h" +#include "TLorentzVector.h" +#include "TMatrixDSym.h" + +//cpp +#include <cfloat> + +const int GenfitTrack::s_PDG[2][5] +={{-11,-13,211,321,2212},{11,13,-211,-321,-2212}}; + + bool +sortDCHit(edm4hep::ConstSimTrackerHit hit1,edm4hep::ConstSimTrackerHit hit2) +{ + //std::cout<<"hit1"<<hit1<<std::endl; + //std::cout<<"hit2"<<hit2<<std::endl; + bool isEarly=hit1.getTime()<hit2.getTime(); + return isEarly; +} + + GenfitTrack::GenfitTrack(const GenfitField* genfitField, const dd4hep::DDSegmentation::GridDriftChamber* seg, const char* name) +:m_name(name),m_track(nullptr),m_reps(),m_debug(0), +m_genfitField(genfitField),m_gridDriftChamber(seg) +{ + +} + +GenfitTrack::~GenfitTrack() +{ + ///Note: track reps and points will be deleted in the destructor of track + ///implemented in genfit::Track::Clear() + delete m_track; +} + +/// create a Genfit track from track state, without trackRep +/// Initialize track with seed states +/// NO unit conversion here +bool GenfitTrack::createGenfitTrack(int pdgType,int charge, + TLorentzVector posInit, TVector3 momInit, TMatrixDSym covMInit) +{ + TVectorD seedState(6); + TMatrixDSym seedCov(6); + + //for(int i = 0; i < 6; ++i) { + // for(int j = 0; j < 6; ++j) { + // seedCov(i,j)=covMInit(i,j); + // } + //} + //yzhang FIXME + //seed position + for(int i = 0; i < 3; ++i) { + seedState(i)=posInit[i]; + //yzhang TODO from covMInit to seedCov + double resolution = 0.1;//*dd4hep::mm/dd4hep::cm; + seedCov(i,i)=resolution*resolution; + if(i==2) seedCov(i,i)=0.5*0.5; + } + //seed momentum + for(int i = 3; i < 6; ++i){ + //seedState(i)=momInit[i-3]*(dd4hep::GeV); + seedState(i)=momInit[i-3]; + //yzhang TODO from covMInit to seedCov + seedCov(i,i)=0.01;//pow(resolution / sqrt(3),2); + } + + if(nullptr==m_track) m_track=new genfit::Track(); + m_track->setStateSeed(seedState); + m_track->setCovSeed(seedCov); + + /// new a track representation and add to the track + int chargeId=0; + charge>0 ? chargeId=0 : chargeId=1; + + GenfitMsg::get()<<MSG::DEBUG<<m_name<<" CreateGenfitTrack seed pos(" + <<seedState[0]<<" "<<seedState[1]<<" "<<seedState[2]<<")cm (" + <<seedState[3]<<" "<<seedState[4]<<" "<<seedState[5]<<")GeV charge " + <<charge<<" pdg "<<s_PDG[chargeId][pdgType]<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<"seedCov "<<endmsg; + + addTrackRep(s_PDG[chargeId][pdgType]); + + if(m_debug>0) seedCov.Print(); + return true; +} + +///Create a Genfit track with MCParticle, unit conversion here +bool GenfitTrack::createGenfitTrackFromMCParticle(int pidType, + const edm4hep::MCParticle& mcParticle, double eventStartTime) +{ + ///get track parameters from McParticle + edm4hep::Vector3d mcPocaPos = mcParticle.getVertex();//mm + edm4hep::Vector3f mcPocaMom = mcParticle.getMomentum();//GeV + GenfitMsg::get()<<MSG::DEBUG<<"seedPos poca "<< mcPocaPos.x + <<" "<<mcPocaPos.y<<" "<<mcPocaPos.z<<" mm "<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<"seedMom poca "<< mcPocaMom.x + <<" "<<mcPocaMom.y<<" "<<mcPocaMom.z<<" GeV "<<endmsg; + + ///Pivot to first layer to avoid correction of beam pipe + edm4hep::Vector3d firstLayerPos(1e9,1e9,1e9); + edm4hep::Vector3f firstLayerMom(1e9,1e9,1e9); + pivotToFirstLayer(mcPocaPos,mcPocaMom,firstLayerPos,firstLayerMom); + + //TODO convert unit + ///Get seed position and momentum + TLorentzVector seedPos(firstLayerPos.x,firstLayerPos.y,firstLayerPos.z, + eventStartTime); + TVector3 seedMom(firstLayerMom.x,firstLayerMom.y,firstLayerMom.z); + GenfitMsg::get()<<MSG::DEBUG<<"seedPos "<< firstLayerPos.x + <<" "<<firstLayerPos.y<<" "<<firstLayerPos.z<<endmsg; + GenfitMsg::get()<<MSG::DEBUG<<"seedMom "<< firstLayerMom.x + <<" "<<firstLayerMom.y<<" "<<firstLayerMom.z<<endmsg; + + ///Get error matrix of seed track + TMatrixDSym covM(5);//FIXME, TODO + + ///Create a genfit track with seed + GenfitMsg::get()<<MSG::DEBUG<<"createGenfitTrack " ; + if(!GenfitTrack::createGenfitTrack(pidType,mcParticle.getCharge(), + seedPos,seedMom,covM)){ + GenfitMsg::get()<<MSG::ERROR<<"GenfitTrack" + <<" Error in createGenfitTrack" <<endmsg; + return false; + }else{ + GenfitMsg::get()<<MSG::DEBUG<<"GenfitTrack " + <<"createGenfitTrackFromMCParticle track created" <<endmsg; + } + return true; +}//end of createGenfitTrackFromMCParticle + +///Create a Genfit track with MCParticle, unit conversion here +bool GenfitTrack::createGenfitTrackFromEDM4HepTrack(int pidType, + const edm4hep::Track& track, double eventStartTime) +{ + //std::cout<<__FILE__<<" "<<__LINE__<<" bz kilogauss "<<m_genfitField->getBz({0.,0.,0.})/dd4hep::kilogauss<<std::endl; + //std::cout<<__FILE__<<" "<<__LINE__<<" bz tesla "<<m_genfitField->getBz({0.,0.,0.})/dd4hep::tesla<<std::endl; + //std::cout<<__FILE__<<" "<<__LINE__<<" bz "<<m_genfitField->getBz({0.,0.,0.})<< dd4hep::kilogauss <<" "<<dd4hep::tesla<<std::endl; + //TODO + //pivotToFirstLayer(mcPocaPos,mcPocaMom,firstLayerPos,firstLayerMom); + //Get track parameters + edm4hep::TrackState trackStat=track.getTrackStates(0);//FIXME? + HelixClass helixClass; + helixClass.Initialize_Canonical(trackStat.phi,trackStat.D0, + trackStat.Z0,trackStat.omega,trackStat.tanLambda, + m_genfitField->getBz({0.,0.,0.})*dd4hep::kilogauss/dd4hep::tesla); + TLorentzVector posInit(helixClass.getReferencePoint()[0], + helixClass.getReferencePoint()[1], + helixClass.getReferencePoint()[2],eventStartTime); + posInit.SetX(posInit.X()*dd4hep::mm); + posInit.SetY(posInit.Y()*dd4hep::mm); + posInit.SetZ(posInit.Z()*dd4hep::mm); + TVector3 momInit(helixClass.getMomentum()[0], + helixClass.getMomentum()[1],helixClass.getMomentum()[2]); + momInit.SetX(momInit.x()*dd4hep::GeV); + momInit.SetY(momInit.y()*dd4hep::GeV); + momInit.SetZ(momInit.z()*dd4hep::GeV); + TMatrixDSym covMInit; + if(!createGenfitTrack(pidType, + int(trackStat.omega/fabs(trackStat.omega)),//charge,FIXME? + posInit,momInit,covMInit)){ + return false; + } + return true; +} + +/// Add a 3d SpacepointMeasurement on TrackerHit +bool GenfitTrack::addSpacePointTrakerHit(edm4hep::ConstTrackerHit& hit, + int hitID) +{ + edm4hep::Vector3d pos=hit.getPosition(); + TVectorD p(3); + p[0]=pos.x*dd4hep::mm; + p[1]=pos.y*dd4hep::mm; + p[2]=pos.z*dd4hep::mm; + + GenfitMsg::get()<<MSG::DEBUG<<m_name<<" addSpacePointTrakerHit"<<hitID + <<"pos "<<p[0]<<" "<<p[1]<<" "<<p[2]<<" cm"<<endmsg; + /// New a SpacepointMeasurement + double cov[6]; + for(int i=0;i<6;i++) { + cov[i]=hit.getCovMatrix(i); + GenfitMsg::get()<<MSG::DEBUG<<"cov "<<cov[i]<<endmsg; + } + TMatrixDSym hitCov(3);//FIXME? + //in SimpleDigi/src/PlanarDigiAlg.cpp + //cov[0] = u_direction[0]; + //cov[1] = u_direction[1]; + //cov[2] = resU; + //cov[3] = v_direction[0]; + //cov[4] = v_direction[1]; + //cov[5] = resV; + hitCov(0,0)=cov[2]*dd4hep::mm*dd4hep::mm; + hitCov(1,1)=cov[2]*dd4hep::mm*dd4hep::mm; + hitCov(2,2)=cov[2]*dd4hep::mm*dd4hep::mm; + + genfit::SpacepointMeasurement* sMeas = + new genfit::SpacepointMeasurement(p,hitCov,(int) hit.getCellID(),hitID, + nullptr); + genfit::TrackPoint* trackPoint = new genfit::TrackPoint(sMeas,m_track); + m_track->insertPoint(trackPoint); + + GenfitMsg::get()<<MSG::DEBUG<<"end of addSpacePointTrakerHit"<<endmsg; + return true; +} + +/// Add a 3d SpacepointMeasurement with MC truth position smeared by sigma +bool GenfitTrack::addSpacePointMeasurement(const TVectorD& pos, + double sigma, int detID, int hitID, bool smear) +{ + double sigma_t=sigma*dd4hep::mm; + /// Convert from CEPCSW unit to genfit unit, cm + TVectorD pos_t(3); + pos_t(0)=pos(0)*dd4hep::mm; + pos_t(1)=pos(1)*dd4hep::mm; + pos_t(2)=pos(2)*dd4hep::mm; + + /// smear hit position with same weight + TVectorD pos_smeared(3); + for (int i=0;i<3;i++){ + pos_smeared[i]=pos_t(i); + if(smear) pos_smeared[i]+=gRandom->Gaus(0,sigma_t/TMath::Sqrt(3.)); + } + + /// New a SpacepointMeasurement + TMatrixDSym hitCov(3); + hitCov(0,0)=sigma_t*sigma_t; + hitCov(1,1)=sigma_t*sigma_t; + hitCov(2,2)=sigma_t*sigma_t; + + GenfitMsg::get()<< MSG::DEBUG<<m_name<<" addSpacePointMeasurement detID " + <<detID<<" hitId "<<hitID<<" " <<pos_t[0]<<" "<<pos_t[1]<<" "<<pos_t[2] + <<" cm smeared "<<pos_smeared[0]<<" "<<pos_smeared[1]<<" " + <<pos_smeared[2]<<" sigma_t "<<sigma_t<<" cm"<<endmsg; + + genfit::SpacepointMeasurement* sMeas = + new genfit::SpacepointMeasurement(pos_smeared,hitCov,detID,hitID,nullptr); + genfit::TrackPoint* trackPoint = new genfit::TrackPoint(sMeas,m_track); + m_track->insertPoint(trackPoint); + + return true; +} + + +/// Add a WireMeasurement, no Unit conversion here +void GenfitTrack::addWireMeasurement(double driftDistance, + double driftDistanceError, const TVector3& endPoint1, + const TVector3& endPoint2, int lrAmbig, int detID, int hitID) +{ + try{ + /// New a WireMeasurement + genfit::WireMeasurementNew* wireMeas = new genfit::WireMeasurementNew( + driftDistance, driftDistanceError, endPoint1, endPoint2, detID, + hitID, nullptr); + wireMeas->setMaxDistance(0.5);//0.5 cm FIXME + wireMeas->setLeftRightResolution(lrAmbig); + + GenfitMsg::get()<<MSG::DEBUG<<m_name<<" Add wire measurement(cm) "<<hitID + <<" ep1("<<endPoint1[0]<<" "<<endPoint1[1]<<" "<<endPoint1[2] + <<") ep2("<<endPoint2[0]<<" "<<endPoint2[1]<<" "<<endPoint2[2] + <<") drift "<<driftDistance<<" driftErr "<<driftDistanceError + <<" lr "<<lrAmbig<<" detId "<<detID << " hitId "<< hitID + <<endmsg; + + ///New a TrackPoint,create connection between meas. and trackPoint + genfit::TrackPoint* trackPoint=new genfit::TrackPoint(wireMeas,m_track); + wireMeas->setTrackPoint(trackPoint); + + m_track->insertPoint(trackPoint); + + }catch(genfit::Exception& e){ + GenfitMsg::get()<<MSG::DEBUG<<m_name + <<"Add wire measurement exception"<<endmsg; + e.what(); + } +}//end of addWireMeasurementOnTrack + +//Add wire measurement on wire, unit conversion here +bool GenfitTrack::addWireMeasurementOnTrack(edm4hep::Track& track,double sigma) +{ + for(unsigned int iHit=0;iHit<track.trackerHits_size();iHit++){ + edm4hep::ConstTrackerHit hit=track.getTrackerHits(iHit); + + double driftVelocity=40;//FIXME, TODO, um/ns + double driftDistance=hit.getTime()*driftVelocity*dd4hep::um; + TVector3 endPointStart(0,0,0); + TVector3 endPointEnd(0,0,0); + m_gridDriftChamber->cellposition(hit.getCellID(),endPointStart, + endPointEnd); + int lrAmbig=0; + GenfitMsg::get()<<MSG::DEBUG<<m_name<<" time "<<hit.getTime() + <<" driftVelocity " <<driftVelocity<<std::endl; + GenfitMsg::get()<<MSG::DEBUG<<m_name<<" wire pos " <<endPointStart.X() + <<" "<<endPointStart.Y()<<" " <<endPointStart.Z()<<" " + <<endPointEnd.X()<<" " <<endPointEnd.Y()<<" " + <<endPointEnd.Z()<<" " <<std::endl; + endPointStart.SetX(endPointStart.x()*dd4hep::cm); + endPointStart.SetY(endPointStart.y()*dd4hep::cm); + endPointStart.SetZ(endPointStart.z()*dd4hep::cm); + endPointEnd.SetX(endPointEnd.x()*dd4hep::cm); + endPointEnd.SetY(endPointEnd.y()*dd4hep::cm); + endPointEnd.SetZ(endPointEnd.z()*dd4hep::cm); + addWireMeasurement(driftDistance,sigma*dd4hep::cm,endPointStart, + endPointEnd,lrAmbig,hit.getCellID(),iHit); + } + return true; +}//end of addWireMeasurementOnTrack of Track + +/// Get MOP +bool GenfitTrack::getMOP(int hitID, + genfit::MeasuredStateOnPlane& mop, genfit::AbsTrackRep* trackRep) const +{ + if(nullptr == trackRep) trackRep = getRep(); + try{ + mop = m_track->getFittedState(hitID,trackRep); + }catch(genfit::Exception& e){ + e.what(); + return false; + } + return true; +} + +/// New and add a track representation to track +genfit::RKTrackRep* GenfitTrack::addTrackRep(int pdg) +{ + /// create a new track representation + genfit::RKTrackRep* rep = new genfit::RKTrackRep(pdg); + m_reps.push_back(rep); + m_track->addTrackRep(rep); + //try{ + // genfit::MeasuredStateOnPlane stateInit(rep); + // rep->setPosMomCov(stateInit, pos, mom, covM); + //}catch(genfit::Exception e){ + // GenfitMsg::get() << MSG::DEBUG<<m_name<<" Exception in set track status" + // <<endmsg ; + // std::cout<<e.what()<<std::endl; + // return false; + //} + return rep; +} + +/// Get the position from genfit::Track::getStateSeed +const TLorentzVector GenfitTrack::getSeedStatePos()const +{ + TVectorD seedStat(6); + seedStat = m_track->getStateSeed(); + TVector3 p(seedStat[0],seedStat[1],seedStat[2]); + p = p*dd4hep::cm; + TLorentzVector pos(p[0],p[1],p[2],9999);//FIXME + return pos; +} + +/// Get the momentum from genfit::Track::getStateSeed +const TVector3 GenfitTrack::getSeedStateMom() const +{ + TVectorD seedStat(6); seedStat = m_track->getStateSeed(); + TVector3 mom(seedStat[3],seedStat[4],seedStat[5]); + return mom*dd4hep::GeV; +} + +/// Get the seed states of momentum and position +void GenfitTrack::getSeedStateMom(TLorentzVector& pos, TVector3& mom) const +{ + TVectorD seedStat(6); seedStat = m_track->getStateSeed(); + mom = TVector3(seedStat[3],seedStat[4],seedStat[5])*dd4hep::GeV; + seedStat = m_track->getStateSeed(); + TVector3 p = TVector3(seedStat[0],seedStat[1],seedStat[2])*dd4hep::cm; + pos.SetXYZT(p[0],p[1],p[2],9999);//FIXME time +} + +unsigned int GenfitTrack::getNumPoints() const +{ + return m_track->getNumPoints(); +} + +/// Test the fit result FIXME +bool GenfitTrack::fitSuccess(int repID) const +{ + + genfit::FitStatus* fitStatus = m_track->getFitStatus(getRep(repID)); + + /// Test fitting converged + if (!fitStatus->isFitted()||!fitStatus->isFitConverged() + ||fitStatus->isFitConvergedFully()) { + GenfitMsg::get() << MSG::DEBUG<<m_name<< "Fitting is failed... isFitted" + <<fitStatus->isFitted()<<" , isFitConverged " + <<fitStatus->isFitConverged()<<", isFitConvergedFully " + <<fitStatus->isFitConvergedFully()<<endmsg; + return false; + } + + double chi2 = fitStatus->getChi2(); + double ndf = fitStatus->getNdf(); + GenfitMsg::get() << MSG::INFO << "Fit result: chi2 "<<chi2 <<" ndf "<<ndf + << " chi2/ndf = " << chi2/ndf<<endmsg; + + /// Test fitting chi2 + if (chi2<= 0) { + GenfitMsg::get() << MSG::DEBUG<<m_name<< "Fit chi2<0 (chi2,ndf) = (" << + chi2 << "," << ndf << ")"<<endmsg; + return false; + } + return true; +} + +void GenfitTrack::setDebug(int debug) +{ + m_debug = debug; + for(unsigned int i=0;i<m_reps.size();i++){ m_reps[i]->setDebugLvl(debug); } +} + +void GenfitTrack::printSeed() const +{ + TLorentzVector pos = getSeedStatePos(); + TVector3 mom = getSeedStateMom(); + print(pos,mom); + GenfitMsg::get()<<MSG::DEBUG<<m_name<<" NumPoints "<<getNumPoints()<<endmsg; +} + +void GenfitTrack::printFitted(int repID) const +{ + TLorentzVector fittedPos; + TVector3 fittedMom; + TMatrixDSym cov; + + GenfitMsg::get()<<MSG::DEBUG<<m_name<< "printFitted nHit=" + <<m_track->getNumPoints()<<endmsg; + for(unsigned int iHit=0; iHit<m_track->getNumPoints(); iHit++){ + if (getPosMomCovMOP((int) iHit, fittedPos, fittedMom, cov, repID)){ + //print(fittedPos,fittedMom,to_string(iHit).c_str());//TODO + }else{ + GenfitMsg::get()<<MSG::DEBUG<<m_name<<"Hit "<<iHit + <<" have no fitter info"<<endmsg; + } + } +} + +/// Print track information +void GenfitTrack::print( TLorentzVector pos, TVector3 mom, + const char* comment) const +{ + TVector3 pglo = pos.Vect(); + TVector3 mglo = mom; + + // TODO + GenfitMsg::get()<<MSG::DEBUG<<m_name<<" "<<comment<<endmsg; + + if(m_debug>1){ + for(unsigned int i=0;i<m_reps.size();i++){ m_reps[i]->Print(); } + } + //for(unsigned int i=0; i<m_track->getNumPoints(); i++){ + // m_track->getPoint(i)->print(); + //} +} + +/// Get position, momentum, cov on plane of hitID-th hit +bool GenfitTrack::getPosMomCovMOP(int hitID, TLorentzVector& pos, + TVector3& mom, TMatrixDSym& cov, int repID) const +{ + TVector3 p; + genfit::MeasuredStateOnPlane mop; + if(!getMOP(hitID,mop,getRep(repID))) return false; + mop.getPosMomCov(p,mom,cov); + pos.SetVect(p*dd4hep::cm); + pos.SetT(9999);//FIXME + mom = mom*(dd4hep::GeV); + //FIXME + //TrackingUtils::CovConvertUnit(cov, dd4hep::cm, dd4hep::GeV); + return true; +} + +int GenfitTrack::getNumPointsWithFittedInfo(int repID) const +{ + int nHitWithFittedInfo = 0; + int nHit = m_track->getNumPointsWithMeasurement(); + for(int i=0; i<nHit; i++){ + if(nullptr != m_track->getPointWithFitterInfo(i,getRep(repID))){ + nHitWithFittedInfo++; + } + } + return nHitWithFittedInfo; +} + +int GenfitTrack::getFittedState(TLorentzVector& pos, TVector3& mom, + TMatrixDSym& cov, int repID, bool biased) const +{ + //check number of hit with fitter info + if(getNumPointsWithFittedInfo(repID)<=2) return 1; + + //get track rep + genfit::AbsTrackRep* rep = getRep(repID); + if(nullptr == rep) return 2; + + //get first or last measured state on plane + genfit::MeasuredStateOnPlane mop; + try{ + mop = m_track->getFittedState(biased); + }catch(genfit::Exception& e){ + std::cout<<" getNumPointsWithFittedInfo " + <<getNumPointsWithFittedInfo(repID) + <<" no TrackPoint with fitted info "<<std::endl; + GenfitMsg::get()<<MSG::DEBUG<<m_name + <<"Exception in getFittedState"<<endmsg; + std::cout<<e.what()<<std::endl; + return 3; + } + + //get state + TVector3 p; + mop.getPosMomCov(p,mom,cov); + pos.SetVect(p*dd4hep::cm); + pos.SetT(9999);//FIXME + mom = mom*(dd4hep::GeV); + + return 0;//success +} + +// Get point with fitter info +int GenfitTrack::getDetIDWithFitterInfo(int hitID, int idRaw) const +{ + return m_track->getPointWithFitterInfo(hitID)-> + getRawMeasurement(idRaw)->getDetId(); +} + +int GenfitTrack::getPDG(int id) const +{ + return m_reps[id]->getPDG(); +} + +int GenfitTrack::getPDGCharge(int id) const +{ + return m_reps[id]->getPDGCharge(); +} + +const genfit::FitStatus* +GenfitTrack::getFitStatus(int repID) const +{ + return m_track->getFitStatus(getRep(repID)); +} + +/// Extrapolate track to the cloest point of approach(POCA) to the wire of hit, +/// return StateOnPlane of this POCA +/// inputs +/// pos,mom ... position & momentum at starting point, unit= [mm]&[GeV/c] +/// (converted to [cm]&[GeV/c] inside this function) +/// hit ... destination +/// outputs poca [mm] (converted from [cm] in this function) ,global +double GenfitTrack::extrapolateToHit( TVector3& poca, TVector3& pocaDir, + TVector3& pocaOnWire, double& doca, TVector3 pos, TVector3 mom, + TVector3 end0,//one end of the hit wire + TVector3 end1,//the orhter end of the hit wire + int debug, + int repID, + bool stopAtBoundary, + bool calcJacobianNoise)const +{ + + //genfit::MeasuredStateOnPlane state = getMOP(iPoint); // better? + //genfit::MeasuredStateOnPlane state = getMOP(0); // better? + //To do the extrapolation without IHitSelection,above 2 lines are not used. + pos = pos*dd4hep::cm;//FIXME + mom = mom*dd4hep::GeV; + + //std::cout<<__LINE__<<" extrapolate to Hit pos and mom"<<std::endl; + //pos.Print(); + //mom.Print(); + + genfit::AbsTrackRep* rep = new genfit::RKTrackRep(getRep(repID)->getPDG()); + rep->setDebugLvl(debug); + genfit::MeasuredStateOnPlane state(rep); + rep->setPosMom(state, pos, mom); + + + //genfit::MeasuredStateOnPlane state(m_track->getRep(repID)); + //m_track->getRep(repID)->setPosMom(state, pos, mom); + + //m_track->PrintSeed(); + double extrapoLen(0); + //std::cout<<" wire1 "<<std::endl; + //end0.Print(); + //std::cout<<" wire0 "<<std::endl; + //end1.Print(); + //std::cout<<" state "<<std::endl; + //state.Print(); + + + // forth + try { + //genfit::RKTrackRep* rkRep = + // dynamic_cast<genfit::RKTrackRep*> (m_track->getRep(repID)); + //extrapoLen = rkRep->extrapolateToLine(state, end0, end1, poca, + // pocaDir, pocaOnWire, stopAtBoundary, calcJacobianNoise); + extrapoLen = rep->extrapolateToLine(state, end0, end1, poca, + pocaDir, pocaOnWire, stopAtBoundary, calcJacobianNoise); + }catch(genfit::Exception& e) { + GenfitMsg::get() << MSG::ERROR + <<"Exception in GenfigFitter::ExtrapolateToHit"<<e.what()<<endmsg; + return extrapoLen; + } + + //poca = poca*(dd4hep::cm); + //pocaOnWire = pocaOnWire*(dd4hep::cm); + pocaOnWire = pocaOnWire; + doca = (pocaOnWire-poca).Mag(); + //TODO: debug pocaOnWire + GenfitMsg::get() << MSG::DEBUG << " poca "<<poca.x()<<","<<poca.y() + <<" "<<poca.z()<<" doca "<<doca<<endmsg; + GenfitMsg::get() << MSG::DEBUG << " pocaOnWire "<<pocaOnWire.x() + <<","<<pocaOnWire.y()<<" "<<pocaOnWire.z()<<" doca "<<doca<<endmsg; + + return extrapoLen*(dd4hep::cm); +}//end of ExtrapolateToHit + + +///Add space point measurement from edm4hep::Track to genfit track +int GenfitTrack::addSimTrackerHits(const edm4hep::Track& track, + const edm4hep::MCRecoTrackerAssociationCollection* assoHits, + float sigma,bool smear){ + //A TrakerHit collection + std::vector<edm4hep::ConstSimTrackerHit> sortedDCTrackHitCol; + + GenfitMsg::get()<<MSG::DEBUG<<m_name<<" VXD " + <<lcio::ILDDetID::VXD<<" SIT " + <<lcio::ILDDetID::SIT<<" SET " + <<lcio::ILDDetID::SET<<" FTD " + <<lcio::ILDDetID::FTD<<" "<<endmsg; + ///Get TrackerHit on Track + int hitID=0; + for(unsigned int iHit=0;iHit<track.trackerHits_size();iHit++){ + edm4hep::ConstTrackerHit hit=track.getTrackerHits(iHit); + + UTIL::BitField64 encoder(lcio::ILDCellID0::encoder_string); + encoder.setValue(hit.getCellID()); + int detID=encoder[lcio::ILDCellID0::subdet]; + GenfitMsg::get()<<MSG::DEBUG<<m_name<<" "<<iHit<<" hit "<<hit + <<" detID "<<detID<<endmsg; + + if(detID==lcio::ILDDetID::VXD || detID==lcio::ILDDetID::SIT || + detID==lcio::ILDDetID::SET || detID==lcio::ILDDetID::FTD){ + if(addSpacePointTrakerHit(hit,hitID)){ + GenfitMsg::get()<<MSG::DEBUG<<"add slicon space point"<<endmsg; + hitID++; + }else{ + GenfitMsg::get()<<MSG::ERROR<<"silicon addSpacePointTrakerHit" + <<detID<<" "<<hit.getCellID()<<" faieled"<<endmsg; + } + }else if(detID==7){ + //if(addSpacePointMeasurement(p,sigma,hit.getCellID(),hitID)){ + // GenfitMsg::get()<<MSG::DEBUG<<"add DC space point"<<endmsg; + // hitID++; + //}else{ + // GenfitMsg::get()<<MSG::ERROR<<"addSpacePointMeasurement" + // <<detID<<" faieled" <<endmsg; + //} + float minTime=FLT_MAX; + edm4hep::ConstSimTrackerHit minTimeSimHit; + //Select the SimTrakerHit with least time + for(int iSimHit=0;iSimHit<(int) assoHits->size();iSimHit++){ + if(assoHits->at(iSimHit).getRec()==hit && + assoHits->at(iSimHit).getSim().getTime()<minTime){ + minTimeSimHit=assoHits->at(iSimHit).getSim(); + minTime=assoHits->at(iSimHit).getSim().getTime(); + } + } + //std::cout<<"minTimeSimHit "<<minTimeSimHit<<std::endl; + sortedDCTrackHitCol.push_back(minTimeSimHit); + }else{ + GenfitMsg::get()<<MSG::DEBUG<<" Skip add this hit!"<<endmsg; + } + }//end loop over hit on track + + GenfitMsg::get()<<MSG::DEBUG<<" addSimTrakerHits trackerHits_size=" + <<track.trackerHits_size()<<endmsg; + + ///Add DC hits to track + //Sort sim DC hits by time + //std::sort(sortedDCTrackHitCol.begin(),sortedDCTrackHitCol.end(),sortDCHit); + for(auto dCTrackerHit: sortedDCTrackHitCol){ + edm4hep::Vector3d pos=dCTrackerHit.getPosition(); + TVectorD p(3); + p[0]=pos.x; + p[1]=pos.y; + p[2]=pos.z; + unsigned long long detID = dCTrackerHit.getCellID(); + if(addSpacePointMeasurement(p,sigma,detID,hitID,smear)){ + GenfitMsg::get()<<MSG::DEBUG<<"add DC space point"<<endmsg; + hitID++; + }else{ + GenfitMsg::get()<<MSG::ERROR<<"addSpacePointMeasurement" + <<detID<<" faieled" <<endmsg; + } + } + + GenfitMsg::get()<<MSG::DEBUG<<"GenfitTrack nHitAdded "<<hitID<<endmsg; + return hitID; +} + +bool GenfitTrack::storeTrack(edm4hep::ReconstructedParticle& recParticle, + int pidType, int ndfCut, double chi2Cut) +{ + + /// Get fit status + const genfit::FitStatus* fitState = m_track->getFitStatus(); + double ndf = fitState->getNdf(); + if(ndf>ndfCut) return false; + double chi2 = fitState->getChi2(); + if(chi2>chi2Cut) return false; + double charge = fitState->getCharge(); + int isFitted = fitState->isFitted(); + int isConverged = fitState->isFitConverged(); + int isConvergedFully = fitState->isFitConvergedFully(); + TMatrixDSym fittedCov; + TLorentzVector fittedPos; + TVector3 fittedMom; + int fittedState=getFittedState(fittedPos,fittedMom,fittedCov); + GenfitMsg::get()<<MSG::DEBUG<<"fit result: get status OK? pidType " + <<pidType<<" fittedState==0 " <<(0==fittedState)<<" isFitted "<<isFitted + <<" isConverged "<<isConverged<<" ndf "<<ndf<<endmsg; + if((0!=fittedState) || (!isFitted) || !isConvergedFully || (ndf<ndfCut)){ + GenfitMsg::get()<<MSG::DEBUG<<" fitting failed"<<endmsg; + }else{ + GenfitMsg::get()<<MSG::DEBUG<<"fit result: Pos("<< + fittedPos.X()<<" "<< + fittedPos.Y()<<" "<< + fittedPos.Z()<<") mom("<< + fittedMom.X()<<" "<< + fittedMom.Y()<<" "<< + fittedMom.Z()<<") p_tot "<< + fittedMom.Mag()<<" pt "<< + fittedMom.Perp()<< + " chi2 "<<chi2<< + " ndf "<<ndf + <<endmsg; + } + float pos[3]={float(fittedPos.X()),float(fittedPos.Y()),float(fittedPos.Z())}; + float mom[3]={float(fittedMom.X()),float(fittedMom.Y()),float(fittedMom.Z())}; + HelixClass helix; + helix.Initialize_VP(pos,mom,charge,m_genfitField->getBz(fittedPos.Vect())); + + + /////track status at POCA to origin + //TVector3 origin(pivot); + //TVector3 pocaToOrigin_pos(1e9*dd4hep::cm,1e9*dd4hep::cm,1e9*dd4hep::cm); + //TVector3 pocaToOrigin_mom(1e9*dd4hep::GeV,1e9*dd4hep::GeV,1e9*dd4hep::GeV); + + //if(ExtrapolateToPoint(pocaToOrigin_pos,pocaToOrigin_mom, + // m_track,origin) > 1e6*dd4hep::cm){ + // log<<"extrapolate to origin failed"; + // return false; + //} + + + //new TrackState + edm4hep::TrackState* trackState = new edm4hep::TrackState(); + trackState->location=0;//edm4hep::AtIP; + trackState->D0=helix.getD0(); + trackState->phi=helix.getPhi0(); + trackState->omega=helix.getOmega(); + trackState->Z0=helix.getZ0(); + trackState->tanLambda=helix.getTanLambda(); + trackState->referencePoint=helix.getReferencePoint(); + + // std::array<float,15> covMatrix; + // int k=0; + // for(int i=0;i<5;i++){ + // for(int j=0;j<5;j++){ + // if(i<=j) covMatrix[k]=;//FIXME + // } + // } + // trackState.covMatrix= + + //new Track + edm4hep::Track* track = new edm4hep::Track(); + //track->setType(); + track->setChi2(fitState->getChi2()); + track->setNdf(fitState->getNdf()); + //track->setDEdx(); + //track->setRadiusOfInnermostHit();//FIXME + //track->addToTrackerHits(); + + //new ReconstructedParticle + //recParticle->setType(); + //dcRecParticle->setEnergy(); + + edm4hep::Vector3f momVec3(helix.getMomentum()[0], + helix.getMomentum()[1],helix.getMomentum()[2]); + recParticle.setMomentum(momVec3); + //recParticle->setReferencePoint(referencePoint); + recParticle.setCharge(helix.getCharge()); + // recParticle->setMass(); + // recParticle->setCovMatrix(); + // rcRecParticle->setStartVertex(); + //recParticle->addToTracks(track); + + return true; +} + +void GenfitTrack::pivotToFirstLayer(edm4hep::Vector3d& pos, + edm4hep::Vector3f& mom, edm4hep::Vector3d& firstPos, + edm4hep::Vector3f& firstMom) +{ + //FIXME, TODO + firstPos=pos; + firstMom=mom; +} + diff --git a/Reconstruction/RecGenfitAlg/src/GenfitTrack.h b/Reconstruction/RecGenfitAlg/src/GenfitTrack.h new file mode 100644 index 0000000000000000000000000000000000000000..708c33e38ba282c92f5d0f8ef579fde688d150f4 --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/GenfitTrack.h @@ -0,0 +1,204 @@ +////////////////////////////////////////////////////////////////// +/// +/// This is an interface of to call genfit +/// A genfit track can be created, fitted and extrapolated +/// Track with only track representation(s) +/// +/// In this file, including: +/// a genfit track class +/// +/// Units are following DD4hepUnits +/// +/// Authors: +/// Zhang Yao (zhangyao@ihep.ac.cn) +/// Y.Fujii (yfujii@ihep.ac.cn) +/// Yohei Nakatsugawa (yohei@ihep.ac.cn) +/// +////////////////////////////////////////////////////////////////// + +#ifndef RECGENFITALG_GENFITTRACK_H +#define RECGENFITALG_GENFITTRACK_H + +#include "GenfitFitter.h" + +//ROOT +#include "TVectorD.h" +#include "TMatrixDSym.h" + +//STL +#include <vector> + +class TLorentzVector; + +namespace genfit{ + class Track; + class FitStatus; + class AbsTrackRep; + class RKTrackRep; + class KalmanFittedStateOnPlane; +} +namespace edm4hep{ + class MCParticle; + class SimTrackerHitCollection; + class ReconstructedParticle; + class MCRecoTrackerAssociationCollection; + class Track; + class ConstTrackerHit; + class Vector3d; + class Vector3f; +} +namespace dd4hep { + namespace DDSegmentation{ + class GridDriftChamber; + } +} + +class GenfitTrack { + friend int GenfitFitter::processTrack( + GenfitTrack* track, bool resort=false); + + friend int GenfitFitter::processTrackWithRep( + GenfitTrack* track, int repID=0, bool resort=false); + + friend double GenfitFitter::extrapolateToHit(TVector3& poca, + TVector3& pocaDir, + TVector3& pocaOnWire, double& doca, const GenfitTrack* track, + TVector3 pos, TVector3 mom, TVector3 end0, TVector3 end1, int debug, + int repID=0, bool stopAtBoundary=false, bool calcJacobianNoise=false); + + friend double GenfitFitter::extrapolateToCylinder(TVector3& pos, + TVector3& mom, + GenfitTrack* track, double radius, const TVector3 linePoint, + const TVector3 lineDirection, int hitID =0, int repID=0, + bool stopAtBoundary=false, bool calcJacobianNoise=false); + + friend double GenfitFitter::extrapolateToPoint(TVector3& pos, TVector3& mom, + const GenfitTrack* genfitTrack, const TVector3& point, int repID=0, + bool stopAtBoundary = false, bool calcJacobianNoise = false) const; + + public: + GenfitTrack(const GenfitField* field, + const dd4hep::DDSegmentation::GridDriftChamber* seg, + const char* name="GenfitTrack"); + virtual ~GenfitTrack(); + + /// Add a Genfit track + virtual bool createGenfitTrack(int pdgType,int charge,TLorentzVector pos, TVector3 mom, + TMatrixDSym covM); + //virtual bool createGenfitTrack(TLorentzVector posInit,TVector3 momInit, + //TMatrixDSym covMInit); + + ///Create genfit track from MCParticle + bool createGenfitTrackFromMCParticle(int pidTyep,const edm4hep::MCParticle& + mcParticle, double eventStartTime=0.); + bool createGenfitTrackFromEDM4HepTrack(int pidType,const edm4hep::Track& track, + double eventStartTime); + + // /// Prepare a hit list, return number of hits on track + // int PrepareHits();//TODO + + /// Add a space point measurement, return number of hits on track + bool addSpacePointTrakerHit(edm4hep::ConstTrackerHit& hit, int hitID); + + /// Add a space point measurement, return number of hits on track + virtual bool addSpacePointMeasurement(const TVectorD&, double, + int detID=-1, int hitID=-1, bool smear=false); + + /// Add a WireMeasurement with MC truth position smeared by sigma + virtual void addWireMeasurement(double driftDistance, + double driftDistanceError, const TVector3& endPoint1, + const TVector3& endPoint2, int lrAmbig, int detID, int hitID); + + /// Add a WireMeasurement with DC digi + virtual bool addWireMeasurementOnTrack(edm4hep::Track& track, double sigma); + + ///Add space point from truth to track + int addSimTrackerHits(const edm4hep::Track& track, + const edm4hep::MCRecoTrackerAssociationCollection* assoHits, + float sigma,bool smear=false);// float nSigmaSelection + + ///Store track to ReconstructedParticle + bool storeTrack(edm4hep::ReconstructedParticle& dcRecParticle,int pidType, + int ndfCut=1e9, double chi2Cut=1.e9); + + ///A tool to convert track to the first layer of DC + void pivotToFirstLayer(edm4hep::Vector3d& pos,edm4hep::Vector3f& mom, + edm4hep::Vector3d& firstPos, edm4hep::Vector3f& firstMom); + + /// Copy a track to event + //void CopyATrack()const; + + ///Extrapolate to Hit + double extrapolateToHit( TVector3& poca, TVector3& pocaDir, + TVector3& pocaOnWire, double& doca, TVector3 pos, TVector3 mom, + TVector3 end0,//one end of the hit wire + TVector3 end1,//the orhter end of the hit wire + int debug, + int repID, + bool stopAtBoundary, + bool calcJacobianNoise) const; + + bool getPosMomCovMOP(int hitID, TLorentzVector& pos, TVector3& mom, + TMatrixDSym& cov, int repID=0) const; + + /// get the seed position and momentum from track + const TLorentzVector getSeedStatePos() const; + const TVector3 getSeedStateMom() const; + void getSeedStateMom(TLorentzVector& pos, TVector3& mom) const; + unsigned int getNumPoints() const; + + /// get the fitted track status + const genfit::FitStatus* getFitStatus(int repID=0) const; + int getFittedState(TLorentzVector& pos, TVector3& mom, TMatrixDSym& cov, + int repID=0, bool biased=true) const; + int getNumPointsWithFittedInfo(int repID=0) const; + bool getFirstPointWithFittedInfo(int repID=0) const; + bool fitSuccess(int repID) const; + + /// get the wire infomation + int getDetIDWithFitterInfo(int hitID, int idRaw=0) const; + + int getPDG(int id=0) const; + int getPDGCharge(int id=0) const; + + /// print genfit track + void printSeed() const;//print seed + void printFitted(int repID=0) const;//print seed + void print(TLorentzVector pos, TVector3 mom, const char* comment="") const; + + /// set and get debug level + void setDebug(int debug); + int getDebug(void) const { return m_debug;} + + /// get name of this object + const char* getName() const {return m_name;} + genfit::Track* getTrack() const{return m_track;} + + /// Add a track representation + genfit::RKTrackRep* addTrackRep(int pdg); + + protected: + //genfit::Track* getTrack() {return m_track;} + + private: + + const char* m_name; + + ///Note! private functions are using genfit unit, cm and MeV + + genfit::AbsTrackRep* getRep(int id=0) const {return m_reps[id];} + bool getMOP(int hitID, genfit::MeasuredStateOnPlane& mop, + genfit::AbsTrackRep* trackRep=nullptr) const; + + genfit::Track* m_track;/// track + std::vector<genfit::AbsTrackRep*> m_reps;/// track repesentations + int m_debug;/// debug level + + const GenfitField* m_genfitField;//pointer to genfit field + const dd4hep::DDSegmentation::GridDriftChamber* m_gridDriftChamber; + + static const int s_PDG[2][5]; + +}; + +#endif diff --git a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgDC.cpp b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgDC.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cef756adc1d6cc624bf8519d69b5e367423413d9 --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgDC.cpp @@ -0,0 +1,409 @@ +#include "RecGenfitAlgDC.h" +#include "GenfitTrack.h" +#include "GenfitFitter.h" +#include "GenfitField.h" + +//genfit +#include "EventDisplay.h" + +//cepcsw +#include "DetInterface/IGeomSvc.h" +#include "DataHelper/HelixClass.h" +#include "DetSegmentation/GridDriftChamber.h" + +//externals +#include "edm4hep/EventHeaderCollection.h" +#include "edm4hep/MCParticle.h" +#include "edm4hep/MCParticleCollection.h" +#include "edm4hep/SimTrackerHitCollection.h" +#include "edm4hep/TrackerHitCollection.h" +#include "edm4hep/TrackCollection.h" +#include "edm4hep/MCRecoTrackerAssociationCollection.h" +#include "edm4hep/ReconstructedParticle.h" +#include "edm4hep/ReconstructedParticleCollection.h" +#include "edm4hep/Track.h" +#include "edm4hep/TrackCollection.h" +#include "DD4hep/DD4hepUnits.h" +#include "DD4hep/Detector.h" +#include "UTIL/BitField64.h" +#include "DDSegmentation/Segmentation.h" +#include "TRandom.h" +#include "TLorentzVector.h" + +//stl +#include "time.h" + + +DECLARE_COMPONENT( RecGenfitAlgDC ) + +///////////////////////////////////////////////////////////////////// +RecGenfitAlgDC::RecGenfitAlgDC(const std::string& name, ISvcLocator* pSvcLocator): + GaudiAlgorithm(name, pSvcLocator),m_nPDG(5),m_dd4hep(nullptr), + m_gridDriftChamber(nullptr),m_decoder(nullptr) +{ + //declareProperty("EventHeaderCol", _headerCol); + declareProperty("MCParticle", m_mcParticleCol, + "Handle of the input MCParticle collection"); + declareProperty("DriftChamberHitsCollection", m_simDCHitCol, + "Handle of the input SimHit collection"); + declareProperty("DigiDCHitCollection", m_digiDCHitsCol, + "Handle of digi DCHit collection"); + declareProperty("DCTrackCollection", m_dcTrackCol, + "Handle of DC track collection"); + declareProperty("DCHitAssociationCollection", m_dcHitAssociationCol, + "Handle of simTrackerHit and TrackerHit association collection"); + declareProperty("DCRecParticleCollection", m_dcRecParticleCol, + "Handle of drift chamber reconstructed particle collection"); +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +StatusCode RecGenfitAlgDC::initialize() +{ + MsgStream log(msgSvc(), name()); + info()<<"RecGenfitAlgDC initialize()"<<endmsg; + + ///Get GeomSvc + m_geomSvc=Gaudi::svcLocator()->service("GeomSvc"); + if (nullptr==m_geomSvc) { + std::cout<<"Failed to find GeomSvc"<<std::endl; + return StatusCode::FAILURE; + } + ///Get Detector + m_dd4hep = m_geomSvc->lcdd(); + ///Get Field + m_dd4hepField=m_geomSvc->lcdd()->field(); + + /// New a genfit fitter + m_genfitFitter=new GenfitFitter(m_fitterType.toString().c_str()); + m_genfitField=new GenfitField(m_dd4hepField); + m_genfitFitter->setField(m_genfitField); + m_genfitFitter->setGeoMaterial(m_geomSvc->lcdd()); + m_genfitFitter->setEnergyLossBrems(m_correctBremsstrahlung); + m_genfitFitter->setNoiseBrems(m_correctBremsstrahlung); + if(m_debug>10) m_genfitFitter->setDebug(m_debug-10); + if(m_noMaterialEffects) m_genfitFitter->setNoEffects(true); + if(-1==m_debugPid) m_genfitFitter->setNoEffects(true); + if(-1==m_debugPid) m_debugPid=0;//charged geantino with electron pid + if(m_fitterType=="DAF"||m_fitterType=="DafRef"){ + m_genfitFitter->setMaxIterationsBetas(m_bStart,m_bFinal,m_maxIteration); + } else { + m_genfitFitter->setMaxIterations(m_maxIteration); + } + //print genfit parameters + if(m_debug) m_genfitFitter->print(); + if(""!=m_genfitHistRootName) m_genfitFitter->initHist(m_genfitHistRootName); + + //initialize member vairables + for(int i=0;i<5;i++) m_fitSuccess[i]=0; + m_nDCTrack=0; + ///Get Readout + dd4hep::Readout readout=m_dd4hep->readout(m_readout_name); + ///Get Segmentation + m_gridDriftChamber=dynamic_cast<dd4hep::DDSegmentation::GridDriftChamber*> + (readout.segmentation().segmentation()); + if(nullptr==m_gridDriftChamber){ + error() << "Failed to get the GridDriftChamber" << endmsg; + return StatusCode::FAILURE; + } + ///Get Decoder + m_decoder = m_geomSvc->getDecoder(m_readout_name); + if (nullptr==m_decoder) { + error() << "Failed to get the decoder" << endmsg; + return StatusCode::FAILURE; + } + + + ///book tuple + NTuplePtr nt(ntupleSvc(), "RecGenfitAlgDC/recGenfitAlgDC"); + if(nt){ + m_tuple=nt; + }else{ + m_tuple=ntupleSvc()->book("RecGenfitAlgDC/recGenfitAlgDC", + CLID_ColumnWiseTuple,"RecGenfitAlgDC"); + if(m_tuple){ + StatusCode sc; + sc=m_tuple->addItem("run",m_run); + sc=m_tuple->addItem("evt",m_evt); + sc=m_tuple->addItem("tkId",m_tkId); + sc=m_tuple->addItem("mcIndex",m_mcIndex,0,100);//max. 100 particles + sc=m_tuple->addItem("truthPocaMc",m_mcIndex,m_truthPocaMc,3); + sc=m_tuple->addItem("pocaPosMc",m_mcIndex,m_pocaPosMc,3); + sc=m_tuple->addItem("pocaMomMc",m_mcIndex,m_pocaMomMc,3); + sc=m_tuple->addItem("pocaMomMcP",m_mcIndex,m_pocaMomMcP); + sc=m_tuple->addItem("pocaMomMcPt",m_mcIndex,m_pocaMomMcPt); + sc=m_tuple->addItem("pocaPosMdc",3,m_pocaPosMdc); + sc=m_tuple->addItem("pocaMomMdc",3,m_pocaMomMdc); + sc=m_tuple->addItem("index",m_pidIndex, 0, 5); + sc=m_tuple->addItem("firstPosKalP",5,3,m_firstPosKal); + sc=m_tuple->addItem("firstMomKalP",5,m_firstMomKalP); + sc=m_tuple->addItem("firstMomKalPt",5,m_firstMomKalPt); + sc=m_tuple->addItem("pocaPosKal",5,3,m_pocaPosKal); + sc=m_tuple->addItem("pocaMomKal",5,3,m_pocaMomKal); + sc=m_tuple->addItem("pocaMomKalP",5,m_pocaMomKalP); + sc=m_tuple->addItem("pocaMomKalPt",5,m_pocaMomKalPt); + sc=m_tuple->addItem("chargeKal",5,m_chargeKal); + sc=m_tuple->addItem("nDofKal",5,m_nDofKal); + sc=m_tuple->addItem("chi2Kal",5,m_chi2Kal); + sc=m_tuple->addItem("isFitted",5,m_isFitted); + sc=m_tuple->addItem("isFitConverged",5,m_isFitConverged); + sc=m_tuple->addItem("isFitConvergedFully",5, + m_isFitConvergedFully); + sc=m_tuple->addItem("nHitFailedKal",5,m_nHitFailedKal); + sc=m_tuple->addItem("nHitFitted",5,m_nHitFitted); + sc=m_tuple->addItem("nDigi",m_nDigi); + sc=m_tuple->addItem("nHitMc",m_nHitMc); + sc=m_tuple->addItem("nHitKalInput",m_nHitKalInput); + sc=m_tuple->addItem("nHitWithFitInfo",5,m_nHitWithFitInfo); + sc=m_tuple->addItem("nSimDCHit",m_nSimDCHit,0,50000); + sc=m_tuple->addItem("mdcHitDriftT",m_nSimDCHit,m_mdcHitDriftT); + sc=m_tuple->addItem("mdcHitDriftDl",m_nSimDCHit,m_mdcHitDriftDl); + sc=m_tuple->addItem("mdcHitDriftDr",m_nSimDCHit,m_mdcHitDriftDr); + sc=m_tuple->addItem("mdcHitLr",m_nSimDCHit,m_mdcHitLr); + sc=m_tuple->addItem("mdcHitLayer",m_nSimDCHit,m_mdcHitLayer); + sc=m_tuple->addItem("mdcHitWire",m_nSimDCHit,m_mdcHitWire); + sc=m_tuple->addItem("mdcHitExpDoca",m_nSimDCHit,m_mdcHitExpDoca); + sc=m_tuple->addItem("mdcHitExpMcDoca",m_nSimDCHit,m_mdcHitExpMcDoca); + sc=m_tuple->addItem("mdcHitErr",m_nSimDCHit,m_mdcHitErr); + sc=m_tuple->addItem("time",5,m_time); + sc=m_tuple->addItem("mdcHitMcTkId",m_nSimDCHit,m_mdcHitMcTkId); + sc=m_tuple->addItem("mdcHitMcLr",m_nSimDCHit,m_mdcHitMcLr); + sc=m_tuple->addItem("mdcHitMcDrift",m_nSimDCHit,m_mdcHitMcDrift); + sc=m_tuple->addItem("mdcHitMcX",m_nSimDCHit,m_mdcHitMcX); + sc=m_tuple->addItem("mdcHitMcY",m_nSimDCHit,m_mdcHitMcY); + sc=m_tuple->addItem("mdcHitMcZ",m_nSimDCHit,m_mdcHitMcZ); + sc=m_tuple->addItem("mcPocaX",m_nSimDCHit,m_mdcHitExpMcPocaX); + sc=m_tuple->addItem("mcPocaY",m_nSimDCHit,m_mdcHitExpMcPocaY); + sc=m_tuple->addItem("mcPocaZ",m_nSimDCHit,m_mdcHitExpMcPocaZ); + sc=m_tuple->addItem("mcPocaWireX",m_nSimDCHit,m_mdcHitExpMcPocaWireX); + sc=m_tuple->addItem("mcPocaWireY",m_nSimDCHit,m_mdcHitExpMcPocaWireY); + sc=m_tuple->addItem("mcPocaWireZ",m_nSimDCHit,m_mdcHitExpMcPocaWireZ); + debug()<< "Book tuple RecGenfitAlgDC/genfit" << endmsg; + }else{ + error()<< "Cannot book tuple RecGenfitAlgDC/genfit" << endmsg; + } + }//end of book tuple + + //init genfit event display + //if(m_showDisplay) m_genfitDisplay = genfit::EventDisplay::getInstance(); + + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +StatusCode RecGenfitAlgDC::execute() +{ + StatusCode sc; + m_timer=clock(); + info()<<"RecGenfitAlgDC in execute()"<<endmsg; + + /////retrieve EventHeader + //auto header = _headerCol.get()->at(0); + //int evtNo = header.getEventNumber(); + //int runNo = header.getRunNumber(); + + //std::cout<<"run "<<header.getEventNumber() + // <<" "<<header.getRunNumber()<<std::endl; + + ///retrieve Track and TrackHits + const edm4hep::TrackCollection* dcTrackCol=nullptr; + dcTrackCol=m_dcTrackCol.get(); + if(nullptr==dcTrackCol) { + debug()<<"TrackCollection not found"<<endmsg; + return StatusCode::SUCCESS; + } + const edm4hep::TrackerHitCollection* didiDCHitsCol=nullptr; + didiDCHitsCol=m_digiDCHitsCol.get(); + if(nullptr==didiDCHitsCol) { + debug()<<"DigiDCHitCollection not found"<<endmsg; + return StatusCode::SUCCESS; + } + ///retrieve DC Hit Association + auto assoDCHitsCol=m_dcHitAssociationCol.get(); + + edm4hep::ReconstructedParticleCollection* dcRecParticleCol= + m_dcRecParticleCol.createAndPut(); + + ///---------------------------------------------------- + ///Loop over Track and do fitting for each track + ///---------------------------------------------------- + debug()<<"DCTrackCol size="<<dcTrackCol->size()<<endmsg; + for(auto dcTrack: *dcTrackCol){ + ///Loop over 5 particle hypothesis(0-4): e,mu,pi,K,p + ///-1 for chargedgeantino + for(unsigned int pidType=0;pidType<m_nPDG;pidType++){ + if((m_debugPid>=0) && (m_debugPid!=pidType)) continue; + ///----------------------------------- + ///Create a GenFit track + ///----------------------------------- + GenfitTrack* genfitTrack=new GenfitTrack(m_genfitField, + m_gridDriftChamber); + genfitTrack->setDebug(m_debug); + double eventStartTime=0; + if(!genfitTrack->createGenfitTrackFromEDM4HepTrack(pidType,dcTrack, + eventStartTime)){ + debug()<<"createGenfitTrackFromEDM4HepTrack failed!"<<endmsg; + return StatusCode::SUCCESS; + } + if(m_useTruthHit){ + if(0==genfitTrack->addSimTrackerHits(dcTrack,assoDCHitsCol, + m_sigmaHit.value(),m_smearHit)){ + debug()<<"addSimTrackerHits failed!"<<endmsg; + return StatusCode::FAILURE; + } + }else{ + if(0==genfitTrack->addWireMeasurementOnTrack(dcTrack, + m_sigmaHit.value())){ + debug()<<"addWireMeasurementOnTrack failed!"<<endmsg; + return StatusCode::FAILURE; + } + } + if(m_debug) genfitTrack->printSeed(); + + ///----------------------------------- + ///call genfit fitting procedure + ///----------------------------------- + m_genfitFitter->processTrack(genfitTrack,m_resortHits); + m_genfitFitter->setDebug(m_debug); + + ///----------------------------------- + ///Store track + ///----------------------------------- + auto dcRecParticle=dcRecParticleCol->create(); + genfitTrack->storeTrack(dcRecParticle,pidType,m_ndfCut, + m_chi2Cut); + if(m_debug) genfitTrack->printSeed(); + + if(m_tuple) debugTrack(pidType,genfitTrack); + if(m_showDisplay) { + //m_genfitDisplay->addEvent(genfitTrack->getTrack()); + //m_genfitDisplay->open(); + }else{ + delete genfitTrack; + } + ++m_fitSuccess[pidType]; + }//end loop over particle type + }//end loop over a track + + if(m_tuple) debugEvent(); + + + //if(m_genfitDisplay) while(1){ + // std::cout<<"Press any key to finish..."<<std::endl; + // //system ("pause"); + //} + + if(m_tuple) sc=m_tuple->write(); + + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +StatusCode RecGenfitAlgDC::finalize() +{ + MsgStream log(msgSvc(), name()); + info()<< "RecGenfitAlgDC in finalize()" << endmsg; + + m_genfitFitter->writeHist(); + delete m_genfitFitter; + info()<<"RecGenfitAlgDC nRecTrack="<<m_nDCTrack<<" success e " + <<m_fitSuccess[0]<<" mu "<<m_fitSuccess[1]<<" pi "<<m_fitSuccess[2] + <<" K "<<m_fitSuccess[3]<<" p "<<m_fitSuccess[4]<<std::endl; + if(m_nDCTrack>0){ + std::cout<<"RecGenfitAlgDC Success rate = "<<std::endl; + for (int i=0;i<5;i++){ + std::cout<<Form("%d %2.2f",i,((float) m_fitSuccess[i])/m_nDCTrack) + <<std::endl; + } + } + return StatusCode::SUCCESS; +} + +void RecGenfitAlgDC::debugTrack(int pidType,const GenfitTrack* genfitTrack) +{ + /// Get fit status + const genfit::FitStatus* fitState = genfitTrack->getFitStatus(); + int charge= fitState->getCharge(); + + m_chargeKal[pidType]= charge; + m_nHitWithFitInfo[pidType]=genfitTrack->getNumPointsWithFittedInfo(); + m_chi2Kal[pidType]=fitState->getChi2(); + m_nDofKal[pidType]=fitState->getNdf(); + m_isFitted[pidType]=(int)fitState->isFitted(); + m_isFitConverged[pidType]=(int) fitState->isFitConverged(); + m_isFitConvergedFully[pidType]=(int) fitState->isFitConvergedFully(); + + ///get fitted state of track + TMatrixDSym fittedCov; + TLorentzVector fittedPos; + TVector3 fittedMom; + int fittedState=genfitTrack->getFittedState(fittedPos,fittedMom,fittedCov); + HelixClass helix;//mm and GeV + float pos[3]={float(fittedPos.X()/dd4hep::mm),float(fittedPos.Y()/dd4hep::mm), + float(fittedPos.Z()/dd4hep::mm)}; + float mom[3]={float(fittedMom.X()),float(fittedMom.Y()),float(fittedMom.Z())}; + helix.Initialize_VP(pos,mom,charge,m_genfitField->getBz(fittedPos.Vect())); + m_pocaMomKalP[pidType]=fittedMom.Mag(); + + if(m_debug>0){ + /// Get fit status + debug()<<"evt "<<m_evt<<" fit result: get status OK? pidType " + <<pidType<<" fittedState "<<fittedState<<" isFitted " + <<m_isFitted[pidType]<<" isConverged "<<m_isFitConverged[pidType] + <<" isFitConvergedFully "<<m_isFitConvergedFully[pidType] + <<" ndf "<<m_nDofKal[pidType] + <<" chi2 "<<m_chi2Kal[pidType]<<endmsg; + if((0!=fittedState)||(!m_isFitted[pidType])||(m_nDofKal[pidType]<m_ndfCut)){ + debug()<<"fitting failed"<<endmsg; + }else{ + debug()<<"evt "<<m_evt<<" fit result: Pos("<< + fittedPos.X()<<" "<< + fittedPos.Y()<<" "<< + fittedPos.Z()<<") mom("<< + fittedMom.X()<<" "<< + fittedMom.Y()<<" "<< + fittedMom.Z()<<") p_tot "<< + fittedMom.Mag()<<" pt "<< + fittedMom.Perp()<<endmsg; + } + } + +} + +void RecGenfitAlgDC::debugEvent() +{ + const edm4hep::MCParticleCollection* mcParticleCol = nullptr; + const edm4hep::SimTrackerHitCollection* simDCHitCol=nullptr; + + m_pidIndex=5; + + mcParticleCol=m_mcParticleCol.get(); + simDCHitCol=m_simDCHitCol.get(); + m_nSimDCHit=simDCHitCol->size(); + int iMcParticle=0; + int iHit=0; + for(auto mcParticle : *mcParticleCol){ + for(auto simDCHit: *simDCHitCol){ + edm4hep::Vector3d pos=simDCHit.position(); + TVectorD p(3); + p[0]=pos.x;//no unit conversion here + p[1]=pos.y; + p[2]=pos.z; + m_mdcHitMcX[iHit]=pos.x; + m_mdcHitMcY[iHit]=pos.y; + m_mdcHitMcZ[iHit]=pos.z; + iHit++; + } + edm4hep::Vector3f mcPocaMom = mcParticle.getMomentum();//GeV + float px=mcPocaMom.x; + float py=mcPocaMom.y; + float pz=mcPocaMom.z; + debug()<<" "<<px<<" "<<py<<" "<<pz<<endmsg; + m_pocaMomMcP[iMcParticle]=sqrt(px*px+py*py+pz*pz); + iMcParticle++; + } + m_mcIndex=iHit; + +} diff --git a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgDC.h b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgDC.h new file mode 100644 index 0000000000000000000000000000000000000000..14922bc694d5c6909232a73795d9afbfd2338630 --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgDC.h @@ -0,0 +1,190 @@ +////////////////////////////////////////////////////////////////////// +/// +/// This is an algorithm for track fitting for CEPC track with genfit. +/// +/// In this file, including: +/// An algorithm for drift chamber track fitting with genfit with 5 hypothesis +/// +/// Units are following DD4hepUnits +/// +/// Authors: +/// Yao ZHANG(zhangyao@ihep.ac.cn) +/// +///////////////////////////////////////////////////////////////////// + +#ifndef RECGENFITALG_RECGENFITALGDC_H +#define RECGENFITALG_RECGENFITALGDC_H + +#include "GaudiAlg/GaudiAlgorithm.h" +#include "GaudiKernel/NTuple.h" +#include "k4FWCore/DataHandle.h" +#include "DD4hep/Fields.h" +#include <string> + +class GenfitFitter; +class GenfitField; +class GenfitTrack; +class IGeomSvc; +class time; +namespace genfit{ + class EventDisplay; +} +namespace dd4hep { + class Detector; + //class rec::CellIDPositionConverter; + namespace DDSegmentation{ + class GridDriftChamber; + class BitFieldCoder; + } +} +namespace edm4hep{ + class EventHeaderCollection; + class MCParticleCollection; + class SimTrackerHitCollection; + class TrackCollection; + class TrackerHitCollection; + class MCRecoTrackerAssociationCollection; + class ReconstructedParticle; + class ReconstructedParticleCollection; +} + +///////////////////////////////////////////////////////////////////////////// + +class RecGenfitAlgDC:public GaudiAlgorithm { + public: + RecGenfitAlgDC (const std::string& name, ISvcLocator* pSvcLocator); + StatusCode initialize() override; + StatusCode execute() override; + StatusCode finalize() override; + + private: + GenfitFitter* m_genfitFitter;//The pointer to a GenfitFitter + const GenfitField* m_genfitField;//The pointer to a GenfitField + + void debugTrack(int pidType,const GenfitTrack* genfitTrack); + void debugEvent(); + + DataHandle<edm4hep::EventHeaderCollection> _headerCol{ + "EventHeaderCol", Gaudi::DataHandle::Reader, this}; + //Drift chamber rec hit and trac + DataHandle<edm4hep::TrackerHitCollection> m_digiDCHitsCol{ + "DigiDCHitCollection", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackCollection> m_dcTrackCol{ + "DCTrackCollection", Gaudi::DataHandle::Reader, this}; + //Mc truth + DataHandle<edm4hep::MCParticleCollection> m_mcParticleCol{ + "MCParticle", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::SimTrackerHitCollection> m_simDCHitCol{ + "DriftChamberHitsCollection" , Gaudi::DataHandle::Reader, this}; + + DataHandle<edm4hep::MCRecoTrackerAssociationCollection> + m_dcHitAssociationCol{"DCHitAssociationCollection", + Gaudi::DataHandle::Reader, this}; + //output hits and particles + DataHandle<edm4hep::TrackerHitCollection> m_dcFitRecHitCol{ + "DCFitRecHitsCollection", Gaudi::DataHandle::Writer, this}; + DataHandle<edm4hep::ReconstructedParticleCollection> m_dcRecParticleCol{ + "DCRecParticleCollection", Gaudi::DataHandle::Writer, this}; + + const unsigned int m_nPDG;//5:e,mu,pi,K,proton + SmartIF<IGeomSvc> m_geomSvc; + dd4hep::OverlayedField m_dd4hepField; + dd4hep::Detector* m_dd4hep; + dd4hep::DDSegmentation::GridDriftChamber* m_gridDriftChamber; + dd4hep::DDSegmentation::BitFieldCoder* m_decoder; + Gaudi::Property<std::string> m_readout_name{this, + "readout", "DriftChamberHitsCollection"}; + Gaudi::Property<int> m_debug{this,"debug",false}; + Gaudi::Property<bool> m_smearHit{this,"smearHit",true}; + Gaudi::Property<float> m_sigmaHit{this,"sigmaHit",0.11};//mm + Gaudi::Property<float> m_nSigmaHit{this,"nSigmaHit",5}; + Gaudi::Property<double> m_initCovResPos{this,"initCovResPos",1}; + Gaudi::Property<double> m_initCovResMom{this,"initCovResMom",0.1}; + //Fitter type default is DAFRef. + //Candidates are DAF,DAFRef,KalmanFitter and KalmanFitterRefTrack. + Gaudi::Property<std::string> m_fitterType{this,"fitterTyep","DAFRef"}; + Gaudi::Property<bool> m_correctBremsstrahlung{this, + "correctBremsstrahlung",false}; + Gaudi::Property<bool> m_noMaterialEffects{this, + "noMaterialEffects",false}; + Gaudi::Property<int> m_maxIteration{this,"maxIteration",20}; + Gaudi::Property<int> m_resortHits{this,"resortHits",true}; + Gaudi::Property<double> m_bStart{this,"bStart",100}; + Gaudi::Property<double> m_bFinal{this,"bFinal",0.01}; + Gaudi::Property<double> m_dcCornerCuts{this,"dcCornerCuts",-999}; + Gaudi::Property<double> m_ndfCut{this,"ndfCut",1}; + Gaudi::Property<double> m_chi2Cut{this,"chi2Cut",1000}; + //-1,chargedGeantino;0,1,2,3,4:e,mu,pi,K,proton + Gaudi::Property<int> m_debugPid{this,"debugPid",-99}; + Gaudi::Property<bool> m_useTruthTrack{this,"useTruthTrack",true}; + Gaudi::Property<bool> m_useTruthHit{this,"useTruthHit",true}; + Gaudi::Property<std::string> m_genfitHistRootName{this, + "genfitHistRootName",""}; + Gaudi::Property<bool> m_showDisplay{this,"showDisplay",false}; + int m_fitSuccess[5]; + int m_nDCTrack; + //bool m_useRecLRAmbig; + + genfit::EventDisplay* m_genfitDisplay; + clock_t m_timer; + + /// tuples + NTuple::Tuple* m_tuple; + NTuple::Item<int> m_run; + NTuple::Item<int> m_evt; + NTuple::Item<int> m_tkId; + NTuple::Item<int> m_mcIndex;//number of navigated mcParicle + NTuple::Matrix<double> m_truthPocaMc;//2 dim matched particle and 3 pos. + NTuple::Matrix<double> m_pocaPosMc;//2 dim matched particle and 3 pos. + NTuple::Matrix<double> m_pocaMomMc;//2 dim matched particle and 3 mom. + NTuple::Array<double> m_pocaMomMcP;//2 dim matched particle and p + NTuple::Array<double> m_pocaMomMcPt;//2 dim matched particle and pt + NTuple::Array<double> m_pocaPosMdc;//pos 0:x,1:y,2:z + NTuple::Array<double> m_pocaMomMdc;//mom. 0:px,1:py,2:pz + NTuple::Item<int> m_pidIndex; + NTuple::Matrix<double> m_firstPosKal;//5 hyposis and pos. at first + NTuple::Array<double> m_firstMomKalP;//5 hyposis and mom. at first + NTuple::Array<double> m_firstMomKalPt;//5 hyposis and mom. at first + NTuple::Matrix<double> m_pocaPosKal;//5 hyposis and 3 mom. + NTuple::Matrix<double> m_pocaMomKal;//5 hyposis and 3 mom. + NTuple::Array<double> m_pocaMomKalP;//5 hyposis and p + NTuple::Array<double> m_pocaMomKalPt;//5 hyposis and pt + NTuple::Array<int> m_chargeKal; + NTuple::Array<double> m_chi2Kal; + NTuple::Array<double> m_nDofKal; + NTuple::Array<int> m_isFitConverged; + NTuple::Array<int> m_isFitConvergedFully; + NTuple::Array<int> m_isFitted; + NTuple::Item<int> m_nDigi; + NTuple::Item<int> m_nHitMc; + NTuple::Item<int> m_nSimDCHit; + NTuple::Array<int> m_nHitWithFitInfo; + NTuple::Item<int> m_nHitKalInput; + NTuple::Array<double> m_mdcHitDriftT; + NTuple::Array<double> m_mdcHitDriftDl; + NTuple::Array<double> m_mdcHitDriftDr; + NTuple::Array<int> m_mdcHitLr; + NTuple::Array<int> m_mdcHitLayer; + NTuple::Array<int> m_mdcHitWire; + NTuple::Array<double> m_mdcHitExpDoca; + NTuple::Array<double> m_mdcHitExpMcDoca; + NTuple::Array<double> m_mdcHitErr; + NTuple::Array<int> m_nHitFailedKal; + NTuple::Array<int> m_nHitFitted; + NTuple::Array<double> m_time; + //truth + NTuple::Array<int> m_mdcHitMcLr; + NTuple::Array<int> m_mdcHitMcTkId; + NTuple::Array<double> m_mdcHitMcDrift; + NTuple::Array<double> m_mdcHitMcX; + NTuple::Array<double> m_mdcHitMcY; + NTuple::Array<double> m_mdcHitMcZ; + NTuple::Array<double> m_mdcHitExpMcPocaX; + NTuple::Array<double> m_mdcHitExpMcPocaY; + NTuple::Array<double> m_mdcHitExpMcPocaZ; + NTuple::Array<double> m_mdcHitExpMcPocaWireX; + NTuple::Array<double> m_mdcHitExpMcPocaWireY; + NTuple::Array<double> m_mdcHitExpMcPocaWireZ; + +}; +#endif diff --git a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp new file mode 100644 index 0000000000000000000000000000000000000000..18f19c8eac116e44c259725e39951ab97b481bd4 --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.cpp @@ -0,0 +1,404 @@ +#include "RecGenfitAlgSDT.h" +#include "GenfitTrack.h" +#include "GenfitFitter.h" +#include "GenfitField.h" + +//genfit +#include "EventDisplay.h" + +//cepcsw +#include "DetInterface/IGeomSvc.h" +#include "DataHelper/HelixClass.h" +#include "DetSegmentation/GridDriftChamber.h" + +//externals +#include "edm4hep/EventHeaderCollection.h" +#include "edm4hep/MCParticle.h" +#include "edm4hep/MCParticleCollection.h" +#include "edm4hep/SimTrackerHitCollection.h" +#include "edm4hep/TrackerHitCollection.h" +#include "edm4hep/TrackCollection.h" +#include "edm4hep/MCRecoTrackerAssociationCollection.h" +#include "edm4hep/ReconstructedParticle.h" +#include "edm4hep/ReconstructedParticleCollection.h" +#include "edm4hep/Track.h" +#include "edm4hep/TrackCollection.h" +#include "DD4hep/DD4hepUnits.h" +#include "DD4hep/Detector.h" +#include "UTIL/BitField64.h" +#include "DDSegmentation/Segmentation.h" +#include "TRandom.h" +#include "TLorentzVector.h" + +//stl +#include "time.h" + + +DECLARE_COMPONENT( RecGenfitAlgSDT ) + +///////////////////////////////////////////////////////////////////// +RecGenfitAlgSDT::RecGenfitAlgSDT(const std::string& name, + ISvcLocator* pSvcLocator): + GaudiAlgorithm(name, pSvcLocator),m_nPDG(5),m_dd4hep(nullptr), + m_gridDriftChamber(nullptr),m_decoder(nullptr) +{ + declareProperty("EventHeaderCollection", m_headerCol); + declareProperty("MCParticleCollection", m_mcParticleCol, + "Handle of the input MCParticle collection"); + declareProperty("DriftChamberHitCollection", m_DCSimHitCol, + "Handle of the input DC SimTrakerHit collection"); + declareProperty("DriftChamberDigiCollection", m_DCDigiCol, + "Handle of DC digi(TrakerHit) collection"); + declareProperty("DCTrackCollection", m_DCTrackCol, + "Handle of DC track collection"); + declareProperty("DCHitAssociationCollection", m_DCHitAssociationCol, + "Handle of simTrackerHit and TrackerHit association collection"); + declareProperty("SDTTrackCollection", m_SDTTrackCol, + "Handle of input silicon track collection"); + declareProperty("SDTRecParticleCollection", m_SDTRecParticleCol, + "Handle of silicon+drift chamber rec. particle collection"); +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +StatusCode RecGenfitAlgSDT::initialize() +{ + MsgStream log(msgSvc(), name()); + info()<<" RecGenfitAlgSDT initialize()"<<endmsg; + + ///Get GeomSvc + m_geomSvc=Gaudi::svcLocator()->service("GeomSvc"); + if (nullptr==m_geomSvc) { + std::cout<<"Failed to find GeomSvc"<<std::endl; + return StatusCode::FAILURE; + } + ///Get Detector + m_dd4hep = m_geomSvc->lcdd(); + ///Get Field + m_dd4hepField=m_geomSvc->lcdd()->field(); + + /// New a genfit fitter + m_genfitFitter=new GenfitFitter(m_fitterType.toString().c_str()); + m_genfitField=new GenfitField(m_dd4hepField); + m_genfitFitter->setField(m_genfitField); + m_genfitFitter->setGeoMaterial(m_geomSvc->lcdd()); + m_genfitFitter->setEnergyLossBrems(m_correctBremsstrahlung); + m_genfitFitter->setNoiseBrems(m_correctBremsstrahlung); + if(m_debug>10) m_genfitFitter->setDebug(m_debug-10); + if(m_noMaterialEffects) m_genfitFitter->setNoEffects(true); + if(-1==m_debugPid) m_genfitFitter->setNoEffects(true); + if(-1==m_debugPid) m_debugPid=0;//charged geantino with electron pid + if(m_fitterType=="DAF"||m_fitterType=="DafRef"){ + m_genfitFitter->setMaxIterationsBetas(m_bStart,m_bFinal,m_maxIteration); + } else { + m_genfitFitter->setMaxIterations(m_maxIteration); + } + //print genfit parameters + if(m_debug) m_genfitFitter->print(); + if(""!=m_genfitHistRootName) m_genfitFitter->initHist(m_genfitHistRootName); + + //initialize member vairables + for(int i=0;i<5;i++) m_fitSuccess[i]=0; + m_nRecTrack=0; + ///Get Readout + dd4hep::Readout readout=m_dd4hep->readout(m_readout_name); + ///Get Segmentation + m_gridDriftChamber=dynamic_cast<dd4hep::DDSegmentation::GridDriftChamber*> + (readout.segmentation().segmentation()); + if(nullptr==m_gridDriftChamber){ + error() << "Failed to get the GridDriftChamber" << endmsg; + return StatusCode::FAILURE; + } + ///Get Decoder + m_decoder = m_geomSvc->getDecoder(m_readout_name); + if (nullptr==m_decoder) { + error() << "Failed to get the decoder" << endmsg; + return StatusCode::FAILURE; + } + + + ///book tuple + NTuplePtr nt(ntupleSvc(), "RecGenfitAlgSDT/recGenfitAlgSDT"); + if(nt){ + m_tuple=nt; + }else{ + m_tuple=ntupleSvc()->book("RecGenfitAlgSDT/recGenfitAlgSDT", + CLID_ColumnWiseTuple,"RecGenfitAlgSDT"); + if(m_tuple){ + StatusCode sc; + sc=m_tuple->addItem("run",m_run); + sc=m_tuple->addItem("evt",m_evt); + sc=m_tuple->addItem("tkId",m_tkId); + sc=m_tuple->addItem("mcIndex",m_mcIndex,0,100);//max. 100 particles + sc=m_tuple->addItem("truthPocaMc",m_mcIndex,m_truthPocaMc,3); + sc=m_tuple->addItem("pocaPosMc",m_mcIndex,m_pocaPosMc,3); + sc=m_tuple->addItem("pocaMomMc",m_mcIndex,m_pocaMomMc,3); + sc=m_tuple->addItem("pocaMomMcP",m_mcIndex,m_pocaMomMcP); + sc=m_tuple->addItem("pocaMomMcPt",m_mcIndex,m_pocaMomMcPt); + sc=m_tuple->addItem("pocaPosMdc",3,m_pocaPosMdc); + sc=m_tuple->addItem("pocaMomMdc",3,m_pocaMomMdc); + sc=m_tuple->addItem("index",m_pidIndex, 0, 5); + sc=m_tuple->addItem("firstPosKalP",5,3,m_firstPosKal); + sc=m_tuple->addItem("firstMomKalP",5,m_firstMomKalP); + sc=m_tuple->addItem("firstMomKalPt",5,m_firstMomKalPt); + sc=m_tuple->addItem("pocaPosKal",5,3,m_pocaPosKal); + sc=m_tuple->addItem("pocaMomKal",5,3,m_pocaMomKal); + sc=m_tuple->addItem("pocaMomKalP",5,m_pocaMomKalP); + sc=m_tuple->addItem("pocaMomKalPt",5,m_pocaMomKalPt); + sc=m_tuple->addItem("chargeKal",5,m_chargeKal); + sc=m_tuple->addItem("nDofKal",5,m_nDofKal); + sc=m_tuple->addItem("chi2Kal",5,m_chi2Kal); + sc=m_tuple->addItem("isFitted",5,m_isFitted); + sc=m_tuple->addItem("isFitConverged",5,m_isFitConverged); + sc=m_tuple->addItem("isFitConvergedFully",5, + m_isFitConvergedFully); + sc=m_tuple->addItem("nHitFailedKal",5,m_nHitFailedKal); + sc=m_tuple->addItem("nHitFitted",5,m_nHitFitted); + sc=m_tuple->addItem("nDigi",m_nDigi); + sc=m_tuple->addItem("nHitMc",m_nHitMc); + sc=m_tuple->addItem("nHitKalInput",m_nHitKalInput); + sc=m_tuple->addItem("nHitWithFitInfo",5,m_nHitWithFitInfo); + sc=m_tuple->addItem("nSimDCHit",m_nSimDCHit,0,50000); + sc=m_tuple->addItem("mdcHitDriftT",m_nSimDCHit,m_mdcHitDriftT); + sc=m_tuple->addItem("mdcHitDriftDl",m_nSimDCHit,m_mdcHitDriftDl); + sc=m_tuple->addItem("mdcHitDriftDr",m_nSimDCHit,m_mdcHitDriftDr); + sc=m_tuple->addItem("mdcHitLr",m_nSimDCHit,m_mdcHitLr); + sc=m_tuple->addItem("mdcHitLayer",m_nSimDCHit,m_mdcHitLayer); + sc=m_tuple->addItem("mdcHitWire",m_nSimDCHit,m_mdcHitWire); + sc=m_tuple->addItem("mdcHitExpDoca",m_nSimDCHit,m_mdcHitExpDoca); + sc=m_tuple->addItem("mdcHitExpMcDoca",m_nSimDCHit,m_mdcHitExpMcDoca); + sc=m_tuple->addItem("mdcHitErr",m_nSimDCHit,m_mdcHitErr); + sc=m_tuple->addItem("time",5,m_time); + sc=m_tuple->addItem("mdcHitMcTkId",m_nSimDCHit,m_mdcHitMcTkId); + sc=m_tuple->addItem("mdcHitMcLr",m_nSimDCHit,m_mdcHitMcLr); + sc=m_tuple->addItem("mdcHitMcDrift",m_nSimDCHit,m_mdcHitMcDrift); + sc=m_tuple->addItem("mdcHitMcX",m_nSimDCHit,m_mdcHitMcX); + sc=m_tuple->addItem("mdcHitMcY",m_nSimDCHit,m_mdcHitMcY); + sc=m_tuple->addItem("mdcHitMcZ",m_nSimDCHit,m_mdcHitMcZ); + sc=m_tuple->addItem("mcPocaX",m_nSimDCHit,m_mdcHitExpMcPocaX); + sc=m_tuple->addItem("mcPocaY",m_nSimDCHit,m_mdcHitExpMcPocaY); + sc=m_tuple->addItem("mcPocaZ",m_nSimDCHit,m_mdcHitExpMcPocaZ); + sc=m_tuple->addItem("mcPocaWireX",m_nSimDCHit,m_mdcHitExpMcPocaWireX); + sc=m_tuple->addItem("mcPocaWireY",m_nSimDCHit,m_mdcHitExpMcPocaWireY); + sc=m_tuple->addItem("mcPocaWireZ",m_nSimDCHit,m_mdcHitExpMcPocaWireZ); + debug()<< "Book tuple RecGenfitAlgSDT/genfit" << endmsg; + }else{ + error()<< "Cannot book tuple RecGenfitAlgSDT/genfit" << endmsg; + } + }//end of book tuple + + //init genfit event display + //if(m_showDisplay) m_genfitDisplay = genfit::EventDisplay::getInstance(); + + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +StatusCode RecGenfitAlgSDT::execute() +{ + StatusCode sc=StatusCode::SUCCESS; + m_timer=clock(); + info()<<"RecGenfitAlgSDT in execute()"<<endmsg; + + /////retrieve EventHeader + //auto header = _headerCol.get()->at(0); + //int evtNo = header.getEventNumber(); + //int runNo = header.getRunNumber(); + + //std::cout<<"run "<<header.getEventNumber() + // <<" "<<header.getRunNumber()<<std::endl; + + ///retrieve silicon Track and TrackHits + const edm4hep::TrackCollection* sdtTrackCol=nullptr; + sdtTrackCol=m_SDTTrackCol.get(); + if(nullptr==sdtTrackCol) { + debug()<<"TrackCollection not found"<<endmsg; + return StatusCode::SUCCESS; + } + //const edm4hep::TrackerHitCollection* dcDigiCol=nullptr; + //dcDigiCol=m_DCDigiCol.get(); + //if(nullptr==dcDigiCol) { + // debug()<<"DigiDCHitCollection not found"<<endmsg; + // return StatusCode::SUCCESS; + //} + ///retrieve DC Hit Association + auto dcHitAssociationCol=m_DCHitAssociationCol.get(); + + + edm4hep::ReconstructedParticleCollection* sdtRecParticleCol= + m_SDTRecParticleCol.createAndPut(); + + ///---------------------------------------------------- + ///Loop over Track and do fitting for each track + ///---------------------------------------------------- + debug()<<"SDTTrackCol size="<<sdtTrackCol->size()<<endmsg; + for(auto sdtTrack: *sdtTrackCol){ + ///Loop over 5 particle hypothesis(0-4): e,mu,pi,K,p + ///-1 for chargedgeantino + for(unsigned int pidType=0;pidType<m_nPDG;pidType++){ + if((m_debugPid>=0) && (m_debugPid!=pidType)) continue; + ///----------------------------------- + ///Create a GenFit track + ///----------------------------------- + GenfitTrack* genfitTrack=new GenfitTrack(m_genfitField, + m_gridDriftChamber); + genfitTrack->setDebug(m_debug); + double eventStartTime=0; + if(!genfitTrack->createGenfitTrackFromEDM4HepTrack(pidType,sdtTrack, + eventStartTime)){ + debug()<<"createGenfitTrack failed!"<<endmsg; + return StatusCode::SUCCESS; + } + if(0==genfitTrack->addSimTrackerHits(sdtTrack,dcHitAssociationCol, + m_sigmaHit.value())){ + debug()<<"addSimTrackerHits failed!"<<endmsg; + return StatusCode::SUCCESS; + } + if(m_debug) genfitTrack->printSeed(); + + ///----------------------------------- + ///call genfit fitting procedure + ///----------------------------------- + m_genfitFitter->processTrack(genfitTrack,m_resortHits); + m_genfitFitter->setDebug(m_debug); + + ///----------------------------------- + ///Store track + ///----------------------------------- + auto dcRecParticle=sdtRecParticleCol->create(); + genfitTrack->storeTrack(dcRecParticle,pidType,m_ndfCut, + m_chi2Cut); + if(m_debug) genfitTrack->printSeed(); + + if(m_tuple) debugTrack(pidType,genfitTrack); + if(m_showDisplay) { + //m_genfitDisplay->addEvent(genfitTrack->getTrack()); + //m_genfitDisplay->open(); + }else{ + delete genfitTrack; + } + ++m_fitSuccess[pidType]; + }//end loop over particle type + }//end loop over a track + m_nRecTrack++; + + if(m_tuple) debugEvent(); + + + //if(m_genfitDisplay) while(1){ + // std::cout<<"Press any key to finish..."<<std::endl; + // //system ("pause"); + //} + + if(m_tuple) sc=m_tuple->write(); + + return StatusCode::SUCCESS; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +StatusCode RecGenfitAlgSDT::finalize() +{ + MsgStream log(msgSvc(), name()); + info()<< " RecGenfitAlgSDT in finalize()" << endmsg; + + m_genfitFitter->writeHist(); + delete m_genfitFitter; + info()<<"RecGenfitAlgSDT nRecTrack="<<m_nRecTrack<<" success e " + <<m_fitSuccess[0]<<" mu "<<m_fitSuccess[1]<<" pi "<<m_fitSuccess[2] + <<" K "<<m_fitSuccess[3]<<" p "<<m_fitSuccess[4]<<std::endl; + if(m_nRecTrack>0){ + std::cout<<"RecGenfitAlgSDT Success rate = "<<std::endl; + for (int i=0;i<5;i++){ + std::cout<<Form("%d %2.2f",i,((float) m_fitSuccess[i])/m_nRecTrack) + <<std::endl; + } + } + return StatusCode::SUCCESS; +} + +void RecGenfitAlgSDT::debugTrack(int pidType,const GenfitTrack* genfitTrack) +{ + /// Get fit status + const genfit::FitStatus* fitState = genfitTrack->getFitStatus(); + int charge= fitState->getCharge(); + + m_chargeKal[pidType]= charge; + m_nHitWithFitInfo[pidType]=genfitTrack->getNumPointsWithFittedInfo(); + m_chi2Kal[pidType]=fitState->getChi2(); + m_nDofKal[pidType]=fitState->getNdf(); + m_isFitted[pidType]=(int)fitState->isFitted(); + m_isFitConverged[pidType]=(int) fitState->isFitConverged(); + m_isFitConvergedFully[pidType]=(int) fitState->isFitConvergedFully(); + + ///get fitted state of track + TMatrixDSym fittedCov; + TLorentzVector fittedPos; + TVector3 fittedMom; + int fittedState=genfitTrack->getFittedState(fittedPos,fittedMom,fittedCov); + HelixClass helix;//mm and GeV + float pos[3]={float(fittedPos.X()/dd4hep::mm),float(fittedPos.Y()/dd4hep::mm), + float(fittedPos.Z()/dd4hep::mm)}; + float mom[3]={float(fittedMom.X()),float(fittedMom.Y()),float(fittedMom.Z())}; + helix.Initialize_VP(pos,mom,charge,m_genfitField->getBz(fittedPos.Vect())); + m_pocaMomKalP[pidType]=fittedMom.Mag(); + + if(m_debug>0){ + /// Get fit status + debug()<<"evt "<<m_evt<<" fit result: get status OK? pidType " + <<pidType<<" fittedState "<<fittedState<<" isFitted " + <<m_isFitted[pidType]<<" isConverged "<<m_isFitConverged[pidType] + <<" isFitConvergedFully "<<m_isFitConvergedFully[pidType] + <<" ndf "<<m_nDofKal[pidType] + <<" chi2 "<<m_chi2Kal[pidType]<<endmsg; + if((0!=fittedState)||(!m_isFitted[pidType])||(m_nDofKal[pidType]<m_ndfCut)){ + debug()<<"fitting failed"<<endmsg; + }else{ + debug()<<"evt "<<m_evt<<" fit result: Pos("<< + fittedPos.X()<<" "<< + fittedPos.Y()<<" "<< + fittedPos.Z()<<") mom("<< + fittedMom.X()<<" "<< + fittedMom.Y()<<" "<< + fittedMom.Z()<<") p_tot "<< + fittedMom.Mag()<<" pt "<< + fittedMom.Perp()<<endmsg; + } + } +} + +void RecGenfitAlgSDT::debugEvent() +{ + const edm4hep::MCParticleCollection* mcParticleCol = nullptr; + const edm4hep::SimTrackerHitCollection* simDCHitCol=nullptr; + + m_pidIndex=5; + + mcParticleCol=m_mcParticleCol.get(); + simDCHitCol=m_simDCHitCol.get(); + m_nSimDCHit=simDCHitCol->size(); + int iMcParticle=0; + int iHit=0; + for(auto mcParticle : *mcParticleCol){ + for(auto simDCHit: *simDCHitCol){ + edm4hep::Vector3d pos=simDCHit.position(); + TVectorD p(3); + p[0]=pos.x;//no unit conversion here + p[1]=pos.y; + p[2]=pos.z; + m_mdcHitMcX[iHit]=pos.x; + m_mdcHitMcY[iHit]=pos.y; + m_mdcHitMcZ[iHit]=pos.z; + iHit++; + } + edm4hep::Vector3f mcPocaMom = mcParticle.getMomentum();//GeV + float px=mcPocaMom.x; + float py=mcPocaMom.y; + float pz=mcPocaMom.z; + debug()<<" "<<px<<" "<<py<<" "<<pz<<endmsg; + m_pocaMomMcP[iMcParticle]=sqrt(px*px+py*py+pz*pz); + iMcParticle++; + } + m_mcIndex=iHit; +} diff --git a/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.h b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.h new file mode 100644 index 0000000000000000000000000000000000000000..1a1031e1b3db3b17d5c509ebbed76304f09a1600 --- /dev/null +++ b/Reconstruction/RecGenfitAlg/src/RecGenfitAlgSDT.h @@ -0,0 +1,192 @@ +////////////////////////////////////////////////////////////////////// +/// +/// This is an algorithm for track fitting for CEPC track with genfit. +/// +/// In this file, including: +/// An algorithm for combined silicon and drift chamber track fitting +/// with genfit for 5 particle hypothesis +/// +/// Units are following DD4hepUnits +/// +/// Authors: +/// Yao ZHANG(zhangyao@ihep.ac.cn) +/// +///////////////////////////////////////////////////////////////////// + +#ifndef RECGENFITALG_RECGENFITALGSDT_H +#define RECGENFITALG_RECGENFITALGSDT_H + +#include "GaudiAlg/GaudiAlgorithm.h" +#include "GaudiKernel/NTuple.h" +#include "k4FWCore/DataHandle.h" +#include "DD4hep/Fields.h" +#include <string> + +class GenfitFitter; +class GenfitField; +class GenfitTrack; +class IGeomSvc; +class time; +namespace genfit{ + class EventDisplay; +} +namespace dd4hep { + class Detector; + //class rec::CellIDPositionConverter; + namespace DDSegmentation{ + class GridDriftChamber; + class BitFieldCoder; + } +} +namespace edm4hep{ + class EventHeaderCollection; + class MCParticleCollection; + class SimTrackerHitCollection; + class TrackCollection; + class TrackerHitCollection; + class MCRecoTrackerAssociationCollection; + class ReconstructedParticle; + class ReconstructedParticleCollection; +} + +///////////////////////////////////////////////////////////////////////////// + +class RecGenfitAlgSDT:public GaudiAlgorithm { + public: + RecGenfitAlgSDT (const std::string& name, ISvcLocator* pSvcLocator); + StatusCode initialize() override; StatusCode execute() override; StatusCode finalize() override; + + private: + GenfitFitter* m_genfitFitter;//The pointer to a GenfitFitter + const GenfitField* m_genfitField;//The pointer to a GenfitField + + void debugTrack(int pidType,const GenfitTrack* genfitTrack); + void debugEvent(); + + DataHandle<edm4hep::EventHeaderCollection> m_headerCol{ + "EventHeaderCol", Gaudi::DataHandle::Reader, this}; + //Drift chamber rec hit and trac + DataHandle<edm4hep::TrackerHitCollection> m_DCDigiCol{ + "DigiDCHitCollection", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::SimTrackerHitCollection> m_DCSimHitCol{ + "DCSimHitsCollection", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackCollection> m_DCTrackCol{ + "DCTrackCollection", Gaudi::DataHandle::Reader, this}; + //Mc truth + DataHandle<edm4hep::MCParticleCollection> m_mcParticleCol{ + "MCParticle", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::SimTrackerHitCollection> m_simDCHitCol{ + "DriftChamberHitsCollection" , Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::MCRecoTrackerAssociationCollection> + m_DCHitAssociationCol{"DCHitAssociationCollection", + Gaudi::DataHandle::Reader, this}; + + //Track from silicon detectors + DataHandle<edm4hep::TrackCollection> m_SDTTrackCol{"SDTTrackCollection", + Gaudi::DataHandle::Reader, this}; + + //Output hits and particles + DataHandle<edm4hep::ReconstructedParticleCollection> m_SDTRecParticleCol{ + "SDTRecParticleCollection", Gaudi::DataHandle::Writer, this}; + + const unsigned int m_nPDG;//5:e,mu,pi,K,proton + SmartIF<IGeomSvc> m_geomSvc; + dd4hep::OverlayedField m_dd4hepField; + dd4hep::Detector* m_dd4hep; + dd4hep::DDSegmentation::GridDriftChamber* m_gridDriftChamber; + dd4hep::DDSegmentation::BitFieldCoder* m_decoder; + Gaudi::Property<std::string> m_readout_name{this, + "readout", "DriftChamberHitsCollection"}; + Gaudi::Property<int> m_debug{this,"debug",0}; + Gaudi::Property<float> m_sigmaHit{this,"sigmaHit",0.11};//mm + Gaudi::Property<float> m_nSigmaHit{this,"nSigmaHit",5}; + Gaudi::Property<double> m_initCovResPos{this,"initCovResPos",1}; + Gaudi::Property<double> m_initCovResMom{this,"initCovResMom",0.1}; + //Fitter type default is DAFRef. + //Candidates are DAF,DAFRef,KalmanFitter and KalmanFitterRefTrack. + Gaudi::Property<std::string> m_fitterType{this,"fitterTyep","DAFRef"}; + Gaudi::Property<bool> m_correctBremsstrahlung{this, + "correctBremsstrahlung",false}; + Gaudi::Property<bool> m_noMaterialEffects{this, + "noMaterialEffects",false}; + Gaudi::Property<int> m_maxIteration{this,"maxIteration",20}; + Gaudi::Property<int> m_resortHits{this,"resortHits",true}; + Gaudi::Property<double> m_bStart{this,"bStart",100}; + Gaudi::Property<double> m_bFinal{this,"bFinal",0.01}; + Gaudi::Property<double> m_DCCornerCuts{this,"dcCornerCuts",-999}; + Gaudi::Property<double> m_ndfCut{this,"ndfCut",1}; + Gaudi::Property<double> m_chi2Cut{this,"chi2Cut",1000}; + //-1,chargedGeantino;0,1,2,3,4:e,mu,pi,K,proton + Gaudi::Property<int> m_debugPid{this,"debugPid",-99}; + Gaudi::Property<bool> m_useTruthTrack{this,"useTruthTrack",true}; + Gaudi::Property<bool> m_useTruthHit{this,"useTruthHit",true}; + Gaudi::Property<std::string> m_genfitHistRootName{this, + "genfitHistRootName",""}; + Gaudi::Property<bool> m_showDisplay{this,"showDisplay",false}; + int m_fitSuccess[5]; + int m_nRecTrack; + //bool m_useRecLRAmbig; + + genfit::EventDisplay* m_genfitDisplay; + clock_t m_timer; + + /// tuples + NTuple::Tuple* m_tuple; + NTuple::Item<int> m_run; + NTuple::Item<int> m_evt; + NTuple::Item<int> m_tkId; + NTuple::Item<int> m_mcIndex;//number of navigated mcParicle + NTuple::Matrix<double> m_truthPocaMc;//2 dim matched particle and 3 pos. + NTuple::Matrix<double> m_pocaPosMc;//2 dim matched particle and 3 pos. + NTuple::Matrix<double> m_pocaMomMc;//2 dim matched particle and 3 mom. + NTuple::Array<double> m_pocaMomMcP;//2 dim matched particle and p + NTuple::Array<double> m_pocaMomMcPt;//2 dim matched particle and pt + NTuple::Array<double> m_pocaPosMdc;//pos 0:x,1:y,2:z + NTuple::Array<double> m_pocaMomMdc;//mom. 0:px,1:py,2:pz + NTuple::Item<int> m_pidIndex; + NTuple::Matrix<double> m_firstPosKal;//5 hyposis and pos. at first + NTuple::Array<double> m_firstMomKalP;//5 hyposis and mom. at first + NTuple::Array<double> m_firstMomKalPt;//5 hyposis and mom. at first + NTuple::Matrix<double> m_pocaPosKal;//5 hyposis and 3 mom. + NTuple::Matrix<double> m_pocaMomKal;//5 hyposis and 3 mom. + NTuple::Array<double> m_pocaMomKalP;//5 hyposis and p + NTuple::Array<double> m_pocaMomKalPt;//5 hyposis and pt + NTuple::Array<int> m_chargeKal; + NTuple::Array<double> m_chi2Kal; + NTuple::Array<double> m_nDofKal; + NTuple::Array<int> m_isFitConverged; + NTuple::Array<int> m_isFitConvergedFully; + NTuple::Array<int> m_isFitted; + NTuple::Item<int> m_nDigi; + NTuple::Item<int> m_nHitMc; + NTuple::Item<int> m_nSimDCHit; + NTuple::Array<int> m_nHitWithFitInfo; + NTuple::Item<int> m_nHitKalInput; + NTuple::Array<double> m_mdcHitDriftT; + NTuple::Array<double> m_mdcHitDriftDl; + NTuple::Array<double> m_mdcHitDriftDr; + NTuple::Array<int> m_mdcHitLr; + NTuple::Array<int> m_mdcHitLayer; + NTuple::Array<int> m_mdcHitWire; + NTuple::Array<double> m_mdcHitExpDoca; + NTuple::Array<double> m_mdcHitExpMcDoca; + NTuple::Array<double> m_mdcHitErr; + NTuple::Array<int> m_nHitFailedKal; + NTuple::Array<int> m_nHitFitted; + NTuple::Array<double> m_time; + //truth + NTuple::Array<int> m_mdcHitMcLr; + NTuple::Array<int> m_mdcHitMcTkId; + NTuple::Array<double> m_mdcHitMcDrift; + NTuple::Array<double> m_mdcHitMcX; + NTuple::Array<double> m_mdcHitMcY; + NTuple::Array<double> m_mdcHitMcZ; + NTuple::Array<double> m_mdcHitExpMcPocaX; + NTuple::Array<double> m_mdcHitExpMcPocaY; + NTuple::Array<double> m_mdcHitExpMcPocaZ; + NTuple::Array<double> m_mdcHitExpMcPocaWireX; + NTuple::Array<double> m_mdcHitExpMcPocaWireY; + NTuple::Array<double> m_mdcHitExpMcPocaWireZ; + +}; +#endif diff --git a/Reconstruction/Tracking/CMakeLists.txt b/Reconstruction/Tracking/CMakeLists.txt index 3dd11b3332d73041ae8ca50f21bd48012423c9cd..5123c2922caa0f44e9346f3e11b8bc0710fb04ea 100644 --- a/Reconstruction/Tracking/CMakeLists.txt +++ b/Reconstruction/Tracking/CMakeLists.txt @@ -1,4 +1,3 @@ - # Modules gaudi_add_module(Tracking SOURCES src/Clupatra/ClupatraAlg.cpp diff --git a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp index 612fae8e2a0de342361d2ad0527a5c90b9055629..d9bd55f85c3afc6528d45f3b530e5c666b821ec3 100644 --- a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp +++ b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.cpp @@ -1,5 +1,15 @@ #include "TruthTrackerAlg.h" #include "DataHelper/HelixClass.h" +#include "DDSegmentation/Segmentation.h" +#include "DetSegmentation/GridDriftChamber.h" +#include "DetInterface/IGeomSvc.h" +#include "DD4hep/Detector.h" +#include "DD4hep/IDDescriptor.h" +#include "DD4hep/Plugins.h" +#include "DD4hep/DD4hepUnits.h" + +//external +#include "CLHEP/Random/RandGauss.h" #include "edm4hep/EventHeaderCollection.h" #include "edm4hep/MCParticleCollection.h" #include "edm4hep/SimTrackerHitCollection.h" @@ -8,35 +18,30 @@ #include "edm4hep/MCRecoTrackerAssociationCollection.h" #include "edm4hep/MCRecoParticleAssociationCollection.h" #include "edm4hep/ReconstructedParticleCollection.h" -#include "DDSegmentation/Segmentation.h" -#include "DetSegmentation/GridDriftChamber.h" -#include "DetInterface/IGeomSvc.h" -//#include "edm4hep/SimCalorimeterHitCollection.h" -//#include "edm4hep/CaloHitContributionCollection.h" - -#include "DD4hep/Detector.h" -#include "DD4hep/IDDescriptor.h" -#include "DD4hep/Plugins.h" -#include "DD4hep/DD4hepUnits.h" DECLARE_COMPONENT(TruthTrackerAlg) TruthTrackerAlg::TruthTrackerAlg(const std::string& name, ISvcLocator* svcLoc) -: GaudiAlgorithm(name, svcLoc), m_dd4hep(nullptr), m_gridDriftChamber(nullptr),m_decoder(nullptr) +: GaudiAlgorithm(name, svcLoc),m_dd4hep(nullptr),m_gridDriftChamber(nullptr), + m_decoder(nullptr) { declareProperty("MCParticle", m_mcParticleCol, "Handle of the input MCParticle collection"); - declareProperty("DigiDCHitCollection", m_digiDCHitsCol, - "Handle of digi DCHit collection"); - declareProperty("DCHitAssociationCollection", m_dcHitAssociationCol, - "Handle of association collection"); - declareProperty("DCTrackCollection", m_dcTrackCol, - "Handle of association collection"); - declareProperty("DCRecParticleCollection", m_dcRecParticleCol, + declareProperty("DigiDCHitCollection", m_DCDigiCol, + "Handle of DC digi(TrackerHit) collection"); + declareProperty("DCHitAssociationCollection", m_DCHitAssociationCol, + "Handle of association collection"); + declareProperty("DCTrackCollection", m_DCTrackCol, + "Handle of DC track collection"); + declareProperty("SiSubsetTrackCollection", m_siSubsetTrackCol, + "Handle of silicon subset track collection"); + declareProperty("SDTTrackCollection", m_SDTTrackCol, + "Handle of SDT track collection"); + declareProperty("DCRecParticleCollection", m_DCRecParticleCol, "Handle of drift chamber reconstructed particle collection"); - declareProperty("DCRecParticleAssociationCollection", m_dcRecParticleAssociationCol, + declareProperty("DCRecParticleAssociationCollection", + m_DCRecParticleAssociationCol, "Handle of drift chamber reconstructed particle collection"); - declareProperty("debug", m_debug=false); } StatusCode TruthTrackerAlg::initialize() @@ -85,16 +90,22 @@ StatusCode TruthTrackerAlg::execute() } ///Retrieve DC digi const edm4hep::TrackerHitCollection* digiDCHitsCol=nullptr; - digiDCHitsCol=m_digiDCHitsCol.get();//FIXME DEBUG + digiDCHitsCol=m_DCDigiCol.get();//FIXME DEBUG if(nullptr==digiDCHitsCol){ debug()<<"TrackerHitCollection not found"<<endmsg; - //return StatusCode::SUCCESS; + //return StatusCode::SUCCESS;//FIXME return when no hits in DC + silicon } + if((int) digiDCHitsCol->size()>m_maxDCDigiCut) return StatusCode::SUCCESS; ///Output Track collection - edm4hep::TrackCollection* dcTrackCol=m_dcTrackCol.createAndPut(); + edm4hep::TrackCollection* dcTrackCol=m_DCTrackCol.createAndPut(); + edm4hep::TrackCollection* sdtTrackCol=m_SDTTrackCol.createAndPut(); + edm4hep::ReconstructedParticleCollection* dcRecParticleCol(nullptr); + if(m_writeRecParticle){ + dcRecParticleCol=m_DCRecParticleCol.createAndPut(); + } ////TODO - /////Output MCRecoTrackerAssociationCollection collection + //Output MCRecoTrackerAssociationCollection collection //const edm4hep::MCRecoTrackerAssociationCollection* // mcRecoTrackerAssociationCol=nullptr; //if(nullptr==mcRecoTrackerAssociationCol){ @@ -104,29 +115,91 @@ StatusCode TruthTrackerAlg::execute() //} //mcRecoTrackerAssociationCol=m_mcRecoParticleAssociation.get(); - ///Convert MCParticle to Track and ReconstructedParticle - if(m_debug){ - debug()<<"MCParticleCol size="<<mcParticleCol->size()<<endmsg; + ///Retrieve silicon Track + const edm4hep::TrackCollection* siTrackCol=nullptr; + if(m_siSubsetTrackCol.exist()) siTrackCol=m_siSubsetTrackCol.get(); + if(nullptr!=siTrackCol) { + ///New SDT track + for(auto siTrack:*siTrackCol){ + edm4hep::Track sdtTrack=sdtTrackCol->create(); + edm4hep::TrackState sdtTrackState; + edm4hep::TrackState siTrackStat=siTrack.getTrackStates(0);//FIXME? + sdtTrackState.location=siTrackStat.location; + sdtTrackState.D0=siTrackStat.D0; + sdtTrackState.phi=siTrackStat.phi; + sdtTrackState.omega=siTrackStat.omega; + sdtTrackState.Z0=siTrackStat.Z0; + sdtTrackState.tanLambda=siTrackStat.tanLambda; + sdtTrackState.referencePoint=siTrackStat.referencePoint; + for(int k=0;k<15;k++){ + sdtTrackState.covMatrix[k]=siTrackStat.covMatrix[k]; + } + sdtTrack.addToTrackStates(sdtTrackState); + sdtTrack.setType(siTrack.getType()); + sdtTrack.setChi2(siTrack.getChi2()); + sdtTrack.setNdf(siTrack.getNdf()); + sdtTrack.setDEdx(siTrack.getDEdx()); + sdtTrack.setDEdxError(siTrack.getDEdxError()); + sdtTrack.setRadiusOfInnermostHit(siTrack.getRadiusOfInnermostHit()); + debug()<<"siTrack trackerHits_size="<<siTrack.trackerHits_size()<<endmsg; + for(unsigned int iSiTackerHit=0;iSiTackerHit<siTrack.trackerHits_size(); + iSiTackerHit++){ + sdtTrack.addToTrackerHits(siTrack.getTrackerHits(iSiTackerHit)); + } + //TODO tracks + for(auto digiDC:*digiDCHitsCol){ + //if(Sim->MCParti!=current) continue;//TODO + sdtTrack.addToTrackerHits(digiDC); + } + } } + + ///Convert MCParticle to Track and ReconstructedParticle + debug()<<"MCParticleCol size="<<mcParticleCol->size()<<endmsg; for(auto mcParticle : *mcParticleCol){ - //if(fabs(mcParticle.getCharge()<1e-6) continue;//Skip neutral particles - edm4hep::Vector3d posV= mcParticle.getVertex(); - edm4hep::Vector3f momV= mcParticle.getMomentum();//GeV - float pos[3]={posV.x, posV.y, posV.z}; - float mom[3]={momV.x, momV.y, momV.z}; - //FIXME - //pivotToFirstLayer(mcPocaPos,mcPocaMom,firstLayerPos,firstLayerMom); + /// skip mcParticleVertex do not have enough associated hits TODO + + ///Vertex + const edm4hep::Vector3d mcParticleVertex=mcParticle.getVertex();//mm + edm4hep::Vector3f mcParticleVertexSmeared;//mm + mcParticleVertexSmeared.x= + CLHEP::RandGauss::shoot(mcParticleVertex.x,m_resVertexX); + mcParticleVertexSmeared.y= + CLHEP::RandGauss::shoot(mcParticleVertex.y,m_resVertexY); + mcParticleVertexSmeared.z= + CLHEP::RandGauss::shoot(mcParticleVertex.z,m_resVertexZ); + ///Momentum + edm4hep::Vector3f mcParticleMom=mcParticle.getMomentum();//GeV + double mcParticlePt=sqrt(mcParticleMom.x*mcParticleMom.x+ + mcParticleMom.y*mcParticleMom.y); + //double mcParticlePtSmeared= + // CLHEP::RandGauss::shoot(mcParticlePt,m_resPT); + double mcParticleMomPhi=atan2(mcParticleMom.y,mcParticleMom.x); + double mcParticleMomPhiSmeared= + CLHEP::RandGauss::shoot(mcParticleMomPhi,m_resMomPhi); + edm4hep::Vector3f mcParticleMomSmeared; + mcParticleMomSmeared.x=mcParticlePt*cos(mcParticleMomPhiSmeared); + mcParticleMomSmeared.y=mcParticlePt*sin(mcParticleMomPhiSmeared); + mcParticleMomSmeared.z= + CLHEP::RandGauss::shoot(mcParticleMom.z,m_resPz); + + ///Converted to Helix double B[3]={1e9,1e9,1e9}; m_dd4hepField.magneticField({0.,0.,0.},B); - if(m_debug)std::cout<<" PDG "<<mcParticle.getPDG()<<" charge " - << mcParticle.getCharge() - <<" pos "<<pos[0]<<" "<<pos[1]<<" "<<pos[2] - <<" mom "<<mom[0]<<" "<<mom[1]<<" "<<mom[2] - <<" Bxyz "<<B[0]/dd4hep::tesla<<" "<<B[1]/dd4hep::tesla - <<" "<<B[2]/dd4hep::tesla<<" tesla"<<std::endl; - HelixClass helix; - helix.Initialize_VP(pos,mom,(int) mcParticle.getCharge(),B[2]/dd4hep::tesla); + //float pos[3]={mcParticleVertexSmeared.x, + // mcParticleVertexSmeared.y,mcParticleVertexSmeared.z}; + //float mom[3]={mcParticleMomSmeared.x,mcParticleMomSmeared.y, + // mcParticleMomSmeared.z}; + ////FIXME DEBUG + float pos[3]={(float)mcParticleVertex.x, + (float)mcParticleVertex.y,(float)mcParticleVertex.z}; + float mom[3]={(float)mcParticleMom.x,(float)mcParticleMom.y, + (float)mcParticleMom.z}; + helix.Initialize_VP(pos,mom,mcParticle.getCharge(),B[2]/dd4hep::tesla); + + ///new Track + edm4hep::Track dcTrack=dcTrackCol->create(); edm4hep::TrackState trackState; trackState.D0=helix.getD0(); trackState.phi=helix.getPhi0(); @@ -137,40 +210,61 @@ StatusCode TruthTrackerAlg::execute() std::array<float,15> covMatrix; for(int i=0;i<15;i++){covMatrix[i]=999.;}//FIXME trackState.covMatrix=covMatrix; - - if(m_debug){ - std::cout<<" helix d0 "<<trackState.D0<< - " phi "<<trackState.phi<< - " omega "<<trackState.omega<< - " z0 "<<trackState.Z0<< - " tanLambda "<<trackState.tanLambda<< - " referencePoint "<<trackState.referencePoint<< std::endl; - } - //new Track - edm4hep::Track track = dcTrackCol->create(); - track.addToTrackStates(trackState); - if(nullptr!=digiDCHitsCol) { - //track.setType();//TODO - //track.setChi2(trackState->getChi2()); - track.setNdf(digiDCHitsCol->size()-5); - //track.setDEdx();//TODO - //track.setRadiusOfInnermostHit();//TODO - for(int i=0; i<digiDCHitsCol->size(); i++ ){ - edm4hep::TrackerHit digiDC=digiDCHitsCol->at(i); - //if(Sim->MCParti!=current) continue;//TODO - track.addToTrackerHits(digiDC); - } + dcTrack.addToTrackStates(trackState); + //dcTrack.setType();//TODO + //dcTrack.setChi2(gauss(digiDCHitsCol->size-5(),1));//FIXME + dcTrack.setNdf(digiDCHitsCol->size()-5); + //dcTrack.setDEdx();//TODO + //set hits + double radiusOfInnermostHit=1e9; + debug()<<"digiDCHitsCol size"<<digiDCHitsCol->size()<<endmsg; + for(auto digiDC : *digiDCHitsCol){ + //if(Sim->MCParti!=current) continue;//TODO + edm4hep::Vector3d digiPos=digiDC.getPosition(); + double r=sqrt(digiPos.x*digiPos.x+digiPos.y*digiPos.y); + if(r<radiusOfInnermostHit) radiusOfInnermostHit=r; + dcTrack.addToTrackerHits(digiDC); } - //TODO - //new ReconstructedParticle - //recParticle->setType(); - //dcRecParticle->setEnergy(); - //edm4hep::Vector3f momVec3(helix.getMomentum()[0], - // helix.getMomentum()[1],helix.getMomentum()[2]); - //recParticle->setMomentum(momVec3); - } + dcTrack.setRadiusOfInnermostHit(radiusOfInnermostHit);//TODO + + edm4hep::ReconstructedParticle dcRecParticle; + if(m_writeRecParticle){ + dcRecParticle=dcRecParticleCol->create(); + ///new ReconstructedParticle + //dcRecParticle.setType();//TODO + double mass=mcParticle.getMass(); + double p=sqrt(mcParticleMomSmeared.x*mcParticleMomSmeared.x+ + mcParticleMomSmeared.y*mcParticleMomSmeared.y+ + mcParticleMomSmeared.z*mcParticleMomSmeared.z); + dcRecParticle.setEnergy(sqrt(mass*mass+p*p)); + dcRecParticle.setMomentum(mcParticleMomSmeared); + dcRecParticle.setReferencePoint(mcParticleVertexSmeared); + dcRecParticle.setCharge(mcParticle.getCharge()); + dcRecParticle.setMass(mass); + //dcRecParticle.setGoodnessOfPID();//TODO + //std::array<float>,10> covMat=?;//TODO + //dcRecParticle.setCovMatrix(covMat);//TODO + //dcRecParticle.setStartVertex();//TODO + edm4hep::ParticleID particleID(0,mcParticle.getPDG(),0,1);//FIXME + dcRecParticle.setParticleIDUsed(particleID); + dcRecParticle.addToTracks(dcTrack); + }//end of write RecParticle + + debug()<<"mcParticle "<<mcParticle + <<" momPhi "<<mcParticleMomPhi + <<" mcParticleVertex("<<mcParticleVertex<<")mm " + <<" mcParticleVertexSmeared("<<mcParticleVertexSmeared<<")mm " + <<" mcParticleMom("<<mcParticleMom<<")GeV " + <<" mcParticleMomSmeared("<<mcParticleMomSmeared<<")GeV " + <<" Bxyz "<<B[0]/dd4hep::tesla<<" "<<B[1]/dd4hep::tesla + <<" "<<B[2]/dd4hep::tesla<<" tesla"<<endmsg; + debug()<<"trackState:location,D0,phi,omega,Z0,tanLambda" + <<",referencePoint,cov"<<std::endl<<trackState<<std::endl; + debug()<<"dcTrack"<<dcTrack<<endmsg; + if(m_writeRecParticle) debug()<<"dcRecParticle"<<dcRecParticle<<endmsg; + }//end loop over MCParticleCol - if(m_debug) std::cout<<"Output DCTrack size="<<dcTrackCol->size()<<std::endl; + debug()<<"Output DCTrack size="<<dcTrackCol->size()<<endmsg; return StatusCode::SUCCESS; } diff --git a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h index 23e581e1b73a4e1f962ddc3e53cfb8e525258de6..30efd0a8a71f7d4ec4211fcb6e074e781ecc9fa0 100644 --- a/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h +++ b/Reconstruction/Tracking/src/TruthTracker/TruthTrackerAlg.h @@ -27,9 +27,9 @@ class TruthTrackerAlg: public GaudiAlgorithm public: TruthTrackerAlg(const std::string& name, ISvcLocator* svcLoc); - virtual StatusCode initialize(); - virtual StatusCode execute(); - virtual StatusCode finalize(); + virtual StatusCode initialize() override; + virtual StatusCode execute() override; + virtual StatusCode finalize() override; private: SmartIF<IGeomSvc> m_geomSvc; @@ -41,25 +41,38 @@ class TruthTrackerAlg: public GaudiAlgorithm //reader DataHandle<edm4hep::MCParticleCollection> m_mcParticleCol{ "MCParticle", Gaudi::DataHandle::Reader, this}; - DataHandle<edm4hep::TrackerHitCollection> m_digiDCHitsCol{ - "DigiDCHitsCollection", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackerHitCollection> m_DCDigiCol{ + "DigiDCHitCollection", Gaudi::DataHandle::Reader, this}; DataHandle<edm4hep::MCRecoTrackerAssociationCollection> - m_dcHitAssociationCol{ "DCHitAssociationCollection", + m_DCHitAssociationCol{ "DCHitAssociationCollection", + Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::TrackCollection> + m_siSubsetTrackCol{ "SiSubsetTrackCollection", Gaudi::DataHandle::Reader, this}; //writer - DataHandle<edm4hep::TrackCollection> m_dcTrackCol{"DCTrackCollection", - Gaudi::DataHandle::Writer, this}; - DataHandle<edm4hep::ReconstructedParticleCollection> m_dcRecParticleCol{ + DataHandle<edm4hep::TrackCollection> m_DCTrackCol{ + "DCTrackCollection", Gaudi::DataHandle::Writer, this}; + DataHandle<edm4hep::TrackCollection> m_SDTTrackCol{ + "SDTTrackCollection", Gaudi::DataHandle::Writer, this}; + DataHandle<edm4hep::ReconstructedParticleCollection> m_DCRecParticleCol{ "DCRecParticleCollection", Gaudi::DataHandle::Writer, this}; DataHandle<edm4hep::MCRecoParticleAssociationCollection> - m_dcRecParticleAssociationCol{"DCRecMCRecoParticleAssociationCollection", + m_DCRecParticleAssociationCol{ + "DCRecMCRecoParticleAssociationCollection", Gaudi::DataHandle::Writer, this}; //readout for getting segmentation Gaudi::Property<std::string> m_readout_name{this, "readout", "DriftChamberHitsCollection"}; - - Gaudi::Property<int> m_debug{ this, "debug", false}; + Gaudi::Property<bool> m_writeRecParticle{this,"writeRecParticle",false}; + Gaudi::Property<float> m_resPT{this,"resPT",0};//ratio + Gaudi::Property<float> m_resPz{this,"resPz",0};//ratio + Gaudi::Property<float> m_resMomPhi{this,"resMomPhi",0};//radian + Gaudi::Property<float> m_resMomTheta{this,"resMomTheta",0};//radian + Gaudi::Property<float> m_resVertexX{this,"resVertexX",0.003};//3um + Gaudi::Property<float> m_resVertexY{this,"resVertexY",0.003};//3um + Gaudi::Property<float> m_resVertexZ{this,"resVertexZ",0.003};//3um + Gaudi::Property<int> m_maxDCDigiCut{this,"maxDigiCut",1e6}; }; #endif