LDMX Software
tracking::reco::CKFProcessor Class Referencefinal

Public Member Functions

 CKFProcessor (const std::string &name, framework::Process &process)
 Constructor.
 
virtual ~CKFProcessor ()=default
 Destructor.
 
void onProcessStart () override
 Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.
 
void onNewRun (const ldmx::RunHeader &rh) override
 onNewRun is the first function called for each processor after the conditions are fully configured and accessible.
 
void onProcessEnd () override
 Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.
 
void configure (framework::config::Parameters &parameters) override
 Configure the processor using the given user specified parameters.
 
void produce (framework::Event &event) override
 Run the processor.
 
- Public Member Functions inherited from tracking::reco::TrackingGeometryUser
 TrackingGeometryUser (const std::string &name, framework::Process &p)
 
- Public Member Functions inherited from framework::Producer
 Producer (const std::string &name, Process &process)
 Class constructor.
 
virtual void process (Event &event) final
 Processing an event for a Producer is calling produce.
 
- Public Member Functions inherited from framework::EventProcessor
 DECLARE_FACTORY (EventProcessor, EventProcessor *, const std::string &, Process &)
 declare that we have a factory for this class
 
 EventProcessor (const std::string &name, Process &process)
 Class constructor.
 
virtual ~EventProcessor ()=default
 Class destructor.
 
virtual void beforeNewRun (ldmx::RunHeader &run_header)
 Callback for Producers to add parameters to the run header before conditions are initialized.
 
virtual void onFileOpen (EventFile &event_file)
 Callback for the EventProcessor to take any necessary action when a new event input ROOT file is opened.
 
virtual void onFileClose (EventFile &event_file)
 Callback for the EventProcessor to take any necessary action when a event input ROOT file is closed.
 
template<class T >
const T & getCondition (const std::string &condition_name)
 Access a conditions object for the current event.
 
TDirectory * getHistoDirectory ()
 Access/create a directory in the histogram file for this event processor to create histograms and analysis tuples.
 
void setStorageHint (framework::StorageControl::Hint hint)
 Mark the current event as having the given storage control hint from this module_.
 
void setStorageHint (framework::StorageControl::Hint hint, const std::string &purposeString)
 Mark the current event as having the given storage control hint from this module and the given purpose string.
 
int getLogFrequency () const
 Get the current logging frequency from the process.
 
int getRunNumber () const
 Get the run number from the process.
 
std::string getName () const
 Get the processor name.
 
void createHistograms (const std::vector< framework::config::Parameters > &histos)
 Internal function which is used to create histograms passed from the python configuration @parma histos vector of Parameters that configure histograms to create.
 

Private Member Functions

auto makeGeoIdSourceLinkMap (const geo::TrackersTrackingGeometry &tg, const std::vector< ldmx::Measurement > &ldmxsps) -> std::unordered_multimap< Acts::GeometryIdentifier, acts_examples::IndexSourceLink >
 
template<typename geometry_t , typename source_link_hash_t , typename source_link_equality_t >
std::vector< std::vector< std::size_t > > computeSharedHits (std::vector< ldmx::Track > tracks, std::vector< ldmx::Measurement > meas_coll, geometry_t &tg, source_link_hash_t &&sourceLinkHash, source_link_equality_t &&sourceLinkEquality) const
 

Private Attributes

bool dumpobj_ {false}
 
int pionstates_ {10}
 
int nevents_ {0}
 
double processing_time_ {0.}
 
std::map< std::string, double > profiling_map_
 
bool debug_acts_ {false}
 
std::shared_ptr< Acts::PlaneSurface > target_surface_
 
Acts::RotationMatrix3 surf_rotation_
 
double bfield_ {0}
 
bool const_b_field_ {true}
 
bool remove_stereo_ {false}
 
bool use1_dmeasurements_ {true}
 
int min_hits_ {7}
 
double propagator_step_size_ {200.}
 
int propagator_max_steps_ {1000}
 
bool use_extrapolate_location_ {true}
 
std::vector< double > extrapolate_location_ {0., 0., 0.}
 
bool use_seed_perigee_ {false}
 
std::string measurement_collection_ {"TaggerMeasurements"}
 
std::string sim_particles_coll_name_
 
std::string sim_particles_event_passname_
 
double outlier_pval_
 
std::string out_trk_collection_ {"Tracks"}
 
std::string seed_coll_name_ {"seedTracks"}
 
std::string field_map_ {""}
 
std::string input_pass_name_ {""}
 
std::unique_ptr< const CkfPropagator > propagator_
 
std::unique_ptr< const Acts::CombinatorialKalmanFilter< CkfPropagator, TrackContainer > > ckf_
 
std::shared_ptr< tracking::reco::TrackExtrapolatorTool< CkfPropagator > > trk_extrap_
 
std::unique_ptr< const CkfPropagator > propagator_zero_b_
 
std::unique_ptr< const Acts::CombinatorialKalmanFilter< CkfPropagator, TrackContainer > > ckf_zero_b_
 
std::shared_ptr< tracking::reco::TrackExtrapolatorTool< CkfPropagator > > trk_extrap_zero_b_
 
std::unique_ptr< const CkfPropagator > propagator_const_b_
 
std::unique_ptr< const Acts::CombinatorialKalmanFilter< CkfPropagator, TrackContainer > > ckf_const_b_
 
std::shared_ptr< tracking::reco::TrackExtrapolatorTool< CkfPropagator > > trk_extrap_const_b_
 
int nseeds_
 n seeds and n tracks
 
int ntracks_
 
int eventnr_
 
int n_fieldmap_ckf_failed_tagger_ {0}
 
int n_fieldmap_ckf_failed_recoil_ {0}
 
int n_constb_ckf_recovered_tagger_ {0}
 
int n_zerob_ckf_recovered_recoil_ {0}
 
int n_fieldmap_target_extrap_failed_tagger_ {0}
 
int n_constb_target_extrap_recovered_tagger_ {0}
 
int n_fieldmap_target_extrap_failed_recoil_ {0}
 
int n_zerob_target_extrap_recovered_recoil_ {0}
 
int n_fieldmap_ecal_extrap_failed_recoil_ {0}
 
int n_zerob_ecal_extrap_recovered_recoil_ {0}
 
std::vector< double > map_offset_
 
bool tagger_tracking_ {true}
 

Additional Inherited Members

- Protected Member Functions inherited from tracking::reco::TrackingGeometryUser
const Acts::GeometryContext & geometryContext ()
 
const Acts::MagneticFieldContext & magneticFieldContext ()
 
const Acts::CalibrationContext & calibrationContext ()
 
const geo::TrackersTrackingGeometrygeometry ()
 
void loadBField (const std::string &path, const std::vector< double > &map_offset={0., 0., 0.})
 Load the interpolated B-field map from path and cache it.
 
void loadBField (const std::vector< double > &map_offset={0., 0., 0.})
 Load B-field from the path recorded in the detector GDML.
 
std::shared_ptr< Acts::MagneticFieldProvider > bField () const
 Return the loaded B-field provider.
 
- Protected Member Functions inherited from framework::EventProcessor
void abortEvent ()
 Abort the event immediately.
 
- Protected Attributes inherited from framework::EventProcessor
HistogramPool histograms_
 helper object for making and filling histograms
 
NtupleManagerntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger the_log_
 The logger for this EventProcessor.
 

Detailed Description

Definition at line 94 of file CKFProcessor.h.

Constructor & Destructor Documentation

◆ CKFProcessor()

tracking::reco::CKFProcessor::CKFProcessor ( const std::string & name,
framework::Process & process )

Constructor.

Parameters
nameThe name of the instance of this object.
processThe process running this producer.

Definition at line 20 of file CKFProcessor.cxx.

21 : TrackingGeometryUser(name, process) {}
virtual void process(Event &event) final
Processing an event for a Producer is calling produce.

Member Function Documentation

◆ computeSharedHits()

template<typename geometry_t , typename source_link_hash_t , typename source_link_equality_t >
std::vector< std::vector< std::size_t > > tracking::reco::CKFProcessor::computeSharedHits ( std::vector< ldmx::Track > tracks,
std::vector< ldmx::Measurement > meas_coll,
geometry_t & tg,
source_link_hash_t && sourceLinkHash,
source_link_equality_t && sourceLinkEquality ) const
private

Definition at line 935 of file CKFProcessor.cxx.

938 {
939 auto measurement_index_map =
940 std::unordered_map<Acts::SourceLink, std::size_t, source_link_hash_t,
941 source_link_equality_t>(0, sourceLinkHash,
942 sourceLinkEquality);
943
944 std::vector<std::vector<std::size_t>> measurements_per_track;
945 boost::container::flat_map<std::size_t,
946 boost::container::flat_set<std::size_t>>
947 tracks_per_measurement;
948 std::vector<std::size_t> shared_measurements_per_track;
949 auto number_of_tracks = 0;
950
951 // Iterate through all input tracks, collect their properties like measurement
952 // count and chi2 and fill the measurement map in order to relate tracks to
953 // each other if they have shared hits.
954 for (const auto& track : tracks) {
955 // Kick out tracks that do not fulfill our initial requirements
956 // if (track.getNhits() < n_measurements_min_) {
957 // continue;
958 // }
959
960 std::vector<std::size_t> measurements;
961 for (auto imeas : track.getMeasurementsIdxs()) {
962 auto meas = meas_coll.at(imeas);
963 const Acts::Surface* hit_surface = tg.getSurface(meas.getLayerID());
964 // Store the index_ source link
965 acts_examples::IndexSourceLink idx_sl(hit_surface->geometryId(), imeas);
966 Acts::SourceLink source_link = Acts::SourceLink(idx_sl);
967
968 auto emplace = measurement_index_map.try_emplace(
969 source_link, measurement_index_map.size());
970 measurements.push_back(emplace.first->second);
971 }
972
973 measurements_per_track.push_back(std::move(measurements));
974
975 ++number_of_tracks;
976 }
977
978 // Now we relate measurements to tracks
979 for (std::size_t i_track = 0; i_track < number_of_tracks; ++i_track) {
980 for (auto i_measurement : measurements_per_track[i_track]) {
981 tracks_per_measurement[i_measurement].insert(i_track);
982 }
983 }
984
985 // Finally, we can accumulate the number of shared measurements per track
986 shared_measurements_per_track = std::vector<std::size_t>(number_of_tracks, 0);
987
988 std::vector<std::vector<std::size_t>> shared_measurement_idxs_per_track;
989 for (std::size_t i_track = 0; i_track < number_of_tracks; ++i_track) {
990 std::vector<std::size_t> shared_measurement_idxs;
991 for (auto i_measurement : measurements_per_track[i_track]) {
992 if (tracks_per_measurement[i_measurement].size() > 1) {
993 ++shared_measurements_per_track[i_track];
994 shared_measurement_idxs.push_back(i_measurement);
995 }
996 }
997 shared_measurement_idxs_per_track.push_back(shared_measurement_idxs);
998 }
999 return shared_measurement_idxs_per_track;
1000}

◆ configure()

void tracking::reco::CKFProcessor::configure ( framework::config::Parameters & parameters)
overridevirtual

Configure the processor using the given user specified parameters.

Parameters
parametersSet of parameters used to configure this processor.

Reimplemented from framework::EventProcessor.

Definition at line 839 of file CKFProcessor.cxx.

839 {
840 dumpobj_ = parameters.get<bool>("dumpobj", 0);
841 pionstates_ = parameters.get<int>("pionstates", 0);
842
843 bfield_ = parameters.get<double>("bfield", -1.5);
844 const_b_field_ = parameters.get<bool>("const_b_field", false);
845 field_map_ = parameters.get<std::string>("field_map");
846 propagator_step_size_ = parameters.get<double>("propagator_step_size", 200.);
847 propagator_max_steps_ = parameters.get<int>("propagator_max_steps", 10000);
848 measurement_collection_ = parameters.get<std::string>(
849 "measurement_collection", "TaggerMeasurements");
850 outlier_pval_ = parameters.get<double>("outlier_pval_", 3.84);
851
852 debug_acts_ = parameters.get<bool>("debug_acts", false);
853
854 remove_stereo_ = parameters.get<bool>("remove_stereo", false);
855 use1_dmeasurements_ = parameters.get<bool>("use1Dmeasurements", true);
856 min_hits_ = parameters.get<int>("min_hits", 7);
857
858 // Ckf specific options
859 use_extrapolate_location_ =
860 parameters.get<bool>("use_extrapolate_location", true);
861 extrapolate_location_ =
862 parameters.get<std::vector<double>>("extrapolate_location", {0., 0., 0.});
863 use_seed_perigee_ = parameters.get<bool>("use_seed_perigee", false);
864
865 // seeds from the event
866 seed_coll_name_ = parameters.get<std::string>("seed_coll_name", "seedTracks");
867
868 sim_particles_coll_name_ =
869 parameters.get<std::string>("sim_particles_coll_name");
870 sim_particles_event_passname_ =
871 parameters.get<std::string>("sim_particles_event_passname");
872
873 // output track collection
874 out_trk_collection_ =
875 parameters.get<std::string>("out_trk_collection", "Tracks");
876
877 // keep track on which system tracking is running
878 tagger_tracking_ = parameters.get<bool>("tagger_tracking", true);
879
880 // BField Systematics
881 map_offset_ =
882 parameters.get<std::vector<double>>("map_offset_", {0., 0., 0.});
883
884 input_pass_name_ = parameters.get<std::string>("input_pass_name");
885} // end of configure()
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78

References framework::config::Parameters::get().

◆ makeGeoIdSourceLinkMap()

auto tracking::reco::CKFProcessor::makeGeoIdSourceLinkMap ( const geo::TrackersTrackingGeometry & tg,
const std::vector< ldmx::Measurement > & ldmxsps ) -> std::unordered_multimap<Acts::GeometryIdentifier, acts_examples::IndexSourceLink>
private

Definition at line 887 of file CKFProcessor.cxx.

891 {
892 std::unordered_multimap<Acts::GeometryIdentifier,
894 geo_id_sl_map;
895
896 ldmx_log(debug) << "The makeGeoIdSourceLinkMap has " << measurements.size()
897 << " measurements";
898
899 // Check the hits associated to the surfaces
900 for (unsigned int i_meas = 0; i_meas < measurements.size(); i_meas++) {
901 ldmx::Measurement meas = measurements.at(i_meas);
902 unsigned int layerid = meas.getLayerID();
903
904 const Acts::Surface* hit_surface = tg.getSurface(layerid);
905
906 if (hit_surface) {
907 // Transform the ldmx space point from global to local and store the
908 // information
909
910 acts_examples::IndexSourceLink idx_sl(hit_surface->geometryId(), i_meas);
911 // mg aug 2024 ... these don't print statements
912 // don't compile using v36 in Acts...figure out later
913 /*
914 ldmx_log(debug)
915 << "Insert measurement on surface located at::"
916 << hit_surface->transform(geometry_context()).translation();
917 ldmx_log(debug) << "and geoId::" << hit_surface->geometryId();
918
919 ldmx_log(debug) << "Surface info::"
920 << std::tie(*hit_surface, geometry_context());
921 */
922 geo_id_sl_map.insert(std::make_pair(hit_surface->geometryId(), idx_sl));
923
924 } else
925 ldmx_log(debug) << getName() << "::HIT " << i_meas << " at layer_"
926 << (measurements.at(i_meas)).getLayerID()
927 << " is not associated to any surface?!";
928 }
929
930 return geo_id_sl_map;
931}
std::string getName() const
Get the processor name.
int getLayerID() const

◆ onNewRun()

void tracking::reco::CKFProcessor::onNewRun ( const ldmx::RunHeader & rh)
overridevirtual

onNewRun is the first function called for each processor after the conditions are fully configured and accessible.

This is where you could create single-processors, multi-event calculation objects.

Reimplemented from framework::EventProcessor.

Definition at line 23 of file CKFProcessor.cxx.

23 {
24 profiling_map_["setup"] = 0.;
25 profiling_map_["hits"] = 0.;
26 profiling_map_["seeds"] = 0.;
27 profiling_map_["ckf_setup"] = 0.;
28 profiling_map_["ckf_run"] = 0.;
29 profiling_map_["result_loop"] = 0.;
30
31 // Initialize counters
32 nseeds_ = 0;
33 ntracks_ = 0;
34 eventnr_ = 0;
35
36 // Generate a constant magnetic field
37 Acts::Vector3 b_field(0., 0., bfield_ * Acts::UnitConstants::T);
38
39 // Setup a constant magnetic field
40 const auto const_b_field = std::make_shared<Acts::ConstantBField>(b_field);
41
42 // Define the target surface - be careful:
43 // x - downstream
44 // y - left (when looking along x)
45 // z - up
46 // Passing identity here means that your target surface is oriented in the
47 // same way
48 surf_rotation_ = Acts::RotationMatrix3::Zero();
49 // u direction along +Y
50 surf_rotation_(1, 0) = 1;
51 // v direction along +Z
52 surf_rotation_(2, 1) = 1;
53 // w direction along +X
54 surf_rotation_(0, 2) = 1;
55
56 Acts::Vector3 target_pos(0., 0., 0.);
57 Acts::Translation3 target_translation(target_pos);
58 Acts::Transform3 target_transform(target_translation * surf_rotation_);
59
60 // Unbounded surface
61 target_surface_ =
62 Acts::Surface::makeShared<Acts::PlaneSurface>(target_transform);
63
64 // Setup a interpolated bfield map
65 if (field_map_.empty())
66 loadBField(map_offset_);
67 else
68 loadBField(field_map_, map_offset_);
69 const auto map =
70 std::static_pointer_cast<InterpolatedMagneticField3>(bField());
71
72 auto acts_logging_level = Acts::Logging::FATAL;
73 if (debug_acts_) acts_logging_level = Acts::Logging::VERBOSE;
74
75 // Setup the steppers
76 const auto stepper = Acts::EigenStepper<>{map};
77 const auto const_stepper = Acts::EigenStepper<>{const_b_field};
78 const auto multi_stepper = Acts::MultiEigenStepperLoop{map};
79
80 // Setup the navigator
81 Acts::Navigator::Config nav_cfg{geometry().getTG()};
82 nav_cfg.resolveMaterial = true;
83 nav_cfg.resolvePassive = true;
84 nav_cfg.resolveSensitive = true;
85 const Acts::Navigator navigator(nav_cfg);
86
87 propagator_ = std::make_unique<CkfPropagator>(
88 stepper, navigator,
89 Acts::getDefaultLogger("CKF_PROP", acts_logging_level));
90
91 // Setup the finder / fitters
92 ckf_ = std::make_unique<std::decay_t<decltype(*ckf_)>>(
93 *propagator_, Acts::getDefaultLogger("CKF", acts_logging_level));
94 trk_extrap_ = std::make_shared<std::decay_t<decltype(*trk_extrap_)>>(
95 *propagator_, geometryContext(), magneticFieldContext());
96
97 // Setup zero-B CKF as fallback
98 Acts::ConstantBField zero_b_field(Acts::Vector3(0., 0., 0.));
99 const auto zero_b_stepper = Acts::EigenStepper<>{
100 std::make_shared<Acts::ConstantBField>(zero_b_field)};
101 propagator_zero_b_ =
102 std::make_unique<CkfPropagator>(zero_b_stepper, navigator);
103 ckf_zero_b_ = std::make_unique<std::decay_t<decltype(*ckf_zero_b_)>>(
104 *propagator_zero_b_,
105 Acts::getDefaultLogger("CKF_ZERO_B", acts_logging_level));
106 trk_extrap_zero_b_ =
107 std::make_shared<std::decay_t<decltype(*trk_extrap_zero_b_)>>(
108 *propagator_zero_b_, geometryContext(), magneticFieldContext());
109
110 // Setup const-B (1.5T) CKF as fallback for tagger
111 propagator_const_b_ =
112 std::make_unique<CkfPropagator>(const_stepper, navigator);
113 ckf_const_b_ = std::make_unique<std::decay_t<decltype(*ckf_const_b_)>>(
114 *propagator_const_b_,
115 Acts::getDefaultLogger("CKF_CONST_B", acts_logging_level));
116 trk_extrap_const_b_ =
117 std::make_shared<std::decay_t<decltype(*trk_extrap_const_b_)>>(
118 *propagator_const_b_, geometryContext(), magneticFieldContext());
119} // end of CKFProcessor::onNewRun()
int nseeds_
n seeds and n tracks
std::shared_ptr< Acts::MagneticFieldProvider > bField() const
Return the loaded B-field provider.
void loadBField(const std::string &path, const std::vector< double > &map_offset={0., 0., 0.})
Load the interpolated B-field map from path and cache it.

References tracking::reco::TrackingGeometryUser::bField(), tracking::reco::TrackingGeometryUser::loadBField(), and nseeds_.

◆ onProcessEnd()

void tracking::reco::CKFProcessor::onProcessEnd ( )
overridevirtual

Callback for the EventProcessor to take any necessary action when the processing of events finishes, such as calculating job-summary quantities.

Reimplemented from framework::EventProcessor.

Definition at line 753 of file CKFProcessor.cxx.

753 {
754 ldmx_log(info) << "--------------------------------- ";
755 ldmx_log(info) << "Found " << ntracks_ << " tracks / " << nseeds_
756 << " nseeds";
757 ldmx_log(info) << "AVG Time/Event: " << std::fixed << std::setprecision(1)
758 << processing_time_ / nevents_ << " ms";
759 ldmx_log(info) << "Breakdown::";
760 ldmx_log(info) << " setup Avg Time/Event = " << std::fixed
761 << std::setprecision(3) << profiling_map_["setup"] / nevents_
762 << " ms";
763 ldmx_log(info) << " hits Avg Time/Event = " << std::fixed
764 << std::setprecision(2) << profiling_map_["hits"] / nevents_
765 << " ms";
766 ldmx_log(info) << " seeds Avg Time/Event = " << std::fixed
767 << std::setprecision(3) << profiling_map_["seeds"] / nevents_
768 << " ms";
769 ldmx_log(info) << " ckf_setup Avg Time/Event = " << std::fixed
770 << std::setprecision(3)
771 << profiling_map_["ckf_setup"] / nevents_ << " ms";
772 ldmx_log(info) << " ckf_run Avg Time/Event = " << std::fixed
773 << std::setprecision(3) << profiling_map_["ckf_run"] / nevents_
774 << " ms";
775 ldmx_log(info) << " result_loop Avg Time/Event = " << std::fixed
776 << std::setprecision(1)
777 << profiling_map_["result_loop"] / nevents_ << " ms";
778
779 // CKF fallback statistics
780 ldmx_log(info) << "CKF Fallback Statistics::";
781 if (tagger_tracking_) {
782 ldmx_log(info) << " Tagger: Field-map CKF failed "
783 << n_fieldmap_ckf_failed_tagger_
784 << " times, const-B CKF recovered "
785 << n_constb_ckf_recovered_tagger_ << " ("
786 << (n_fieldmap_ckf_failed_tagger_ > 0
787 ? 100.0 * n_constb_ckf_recovered_tagger_ /
788 n_fieldmap_ckf_failed_tagger_
789 : 0.0)
790 << "%)";
791
792 // Extrapolation fallback statistics for tagger
793 ldmx_log(info) << "Extrapolation Fallback Statistics::";
794 ldmx_log(info) << " Tagger Target: Field-map extrap failed "
795 << n_fieldmap_target_extrap_failed_tagger_
796 << " times, const-B extrap recovered "
797 << n_constb_target_extrap_recovered_tagger_ << " ("
798 << (n_fieldmap_target_extrap_failed_tagger_ > 0
799 ? 100.0 * n_constb_target_extrap_recovered_tagger_ /
800 n_fieldmap_target_extrap_failed_tagger_
801 : 0.0)
802 << "%)";
803 }
804
805 if (!tagger_tracking_) {
806 ldmx_log(info) << " Recoil: Field-map CKF failed "
807 << n_fieldmap_ckf_failed_recoil_
808 << " times, zero-B CKF recovered "
809 << n_zerob_ckf_recovered_recoil_ << " ("
810 << (n_fieldmap_ckf_failed_recoil_ > 0
811 ? 100.0 * n_zerob_ckf_recovered_recoil_ /
812 n_fieldmap_ckf_failed_recoil_
813 : 0.0)
814 << "%)";
815
816 // Extrapolation fallback statistics
817 ldmx_log(info) << "Extrapolation Fallback Statistics::";
818 ldmx_log(info) << " Recoil Target: Field-map extrap failed "
819 << n_fieldmap_target_extrap_failed_recoil_
820 << " times, zero-B extrap recovered "
821 << n_zerob_target_extrap_recovered_recoil_ << " ("
822 << (n_fieldmap_target_extrap_failed_recoil_ > 0
823 ? 100.0 * n_zerob_target_extrap_recovered_recoil_ /
824 n_fieldmap_target_extrap_failed_recoil_
825 : 0.0)
826 << "%)";
827 ldmx_log(info) << " Recoil ECAL: Field-map extrap failed "
828 << n_fieldmap_ecal_extrap_failed_recoil_
829 << " times, zero-B extrap recovered "
830 << n_zerob_ecal_extrap_recovered_recoil_ << " ("
831 << (n_fieldmap_ecal_extrap_failed_recoil_ > 0
832 ? 100.0 * n_zerob_ecal_extrap_recovered_recoil_ /
833 n_fieldmap_ecal_extrap_failed_recoil_
834 : 0.0)
835 << "%)";
836 }
837}

References nseeds_.

◆ onProcessStart()

void tracking::reco::CKFProcessor::onProcessStart ( )
overridevirtual

Callback for the EventProcessor to take any necessary action when the processing of events starts, such as creating histograms.

Reimplemented from framework::EventProcessor.

Definition at line 745 of file CKFProcessor.cxx.

745 {
746 if (use1_dmeasurements_)
747 ldmx_log(debug) << "Use1Dmeasurements = " << std::boolalpha
748 << use1_dmeasurements_;
749 if (remove_stereo_)
750 ldmx_log(debug) << "Remove_stereo = " << std::boolalpha << remove_stereo_;
751}

◆ produce()

void tracking::reco::CKFProcessor::produce ( framework::Event & event)
overridevirtual

Run the processor.

Parameters
eventThe event to process.

Implements framework::Producer.

Definition at line 121 of file CKFProcessor.cxx.

121 {
122 eventnr_++;
123 // get the tracking geometry from conditions
124 auto tg{geometry()};
125
126 // TODO use global variable instead and call clear;
127
128 std::vector<ldmx::Track> tracks;
129
130 auto start = std::chrono::high_resolution_clock::now();
131
132 nevents_++;
133
134 ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("LDMX Tracking Geometry Maker",
135 Acts::Logging::DEBUG));
136
137 // Move this at the start of the producer
138 Acts::PropagatorOptions<Acts::StepperPlainOptions,
139 Acts::NavigatorPlainOptions, ActionList, AbortList>
140 propagator_options(geometryContext(), magneticFieldContext());
141
142 propagator_options.pathLimit = std::numeric_limits<double>::max();
143 // Activate loop protection at some pt value
144 propagator_options.loopProtection = false;
145 //(startParameters.transverseMomentum() < cfg.ptLoopers);
146
147 // Switch the material interaction on/off & eventually into logging mode
148 auto& m_interactor =
149 propagator_options.actionList.get<Acts::MaterialInteractor>();
150 m_interactor.multipleScattering = true;
151 m_interactor.energyLoss = true;
152 m_interactor.recordInteractions = false;
153
154 // The logger can be switched to sterile, e.g. for timing logging
155 auto& s_logger =
156 propagator_options.actionList.get<Acts::detail::SteppingLogger>();
157 s_logger.sterile = true;
158 // Set a maximum step size
159 propagator_options.stepping.maxStepSize =
160 propagator_step_size_ * Acts::UnitConstants::mm;
161 propagator_options.maxSteps = propagator_max_steps_;
162
163 // #######################//
164 // Kalman Filter algorithm//
165 // #######################//
166
167 // Step 1 - Form the source links
168
169 // a) Loop over the sim Hits
170
171 auto setup = std::chrono::high_resolution_clock::now();
172 profiling_map_["setup"] +=
173 std::chrono::duration<double, std::milli>(setup - start).count();
174
175 const auto& measurements = event.getCollection<ldmx::Measurement>(
176 measurement_collection_, input_pass_name_);
177
178 // check if SimParticleMap is available for truth matching
179 std::shared_ptr<tracking::sim::TruthMatchingTool> truth_matching_tool =
180 nullptr;
181 std::map<int, ldmx::SimParticle> particle_map;
182
183 if (event.exists(sim_particles_coll_name_, sim_particles_event_passname_)) {
184 ldmx_log(debug) << "Setting up track truth matching tool";
185 particle_map = event.getMap<int, ldmx::SimParticle>(
186 sim_particles_coll_name_, sim_particles_event_passname_);
187 truth_matching_tool = std::make_shared<tracking::sim::TruthMatchingTool>(
188 particle_map, measurements);
189 }
190
191 // The mapping between the geometry identifier
192 // and the IndexsourceLink that points to the hit
193 const auto geo_id_sl_map = makeGeoIdSourceLinkMap(tg, measurements);
194
195 auto hits = std::chrono::high_resolution_clock::now();
196 profiling_map_["hits"] +=
197 std::chrono::duration<double, std::milli>(hits - setup).count();
198
199 // ============ Setup the CKF ============
200
201 // Retrieve the seeds
202 const auto& seed_tracks =
203 event.getCollection<ldmx::Track>(seed_coll_name_, input_pass_name_);
204
205 ldmx_log(info) << "Number of " << seed_coll_name_
206 << " seed tracks = " << seed_tracks.size();
207
208 if (seed_tracks.empty()) {
209 std::vector<ldmx::Track> empty;
210 ldmx_log(warn) << "No seed tracks, returning...";
211 event.add(out_trk_collection_, empty);
212 return;
213 }
214
215 // Run the CKF on each seed and produce a track candidate
216 std::vector<Acts::BoundTrackParameters> start_parameters;
217
218 ldmx_log(debug) << "Transform the seed track to bound parameters";
219 int seed_track_index{0};
220 for (auto& seed : seed_tracks) {
221 // Transform the seed track to bound parameters.
222 // Perigee is stored in LDMX global frame; convert to ACTS frame for
223 // surface.
224 Acts::Vector3 perigee_acts = tracking::sim::utils::ldmx2Acts(Acts::Vector3(
225 seed.getPerigeeX(), seed.getPerigeeY(), seed.getPerigeeZ()));
226 std::shared_ptr<Acts::PerigeeSurface> perigee_surface =
227 Acts::Surface::makeShared<Acts::PerigeeSurface>(perigee_acts);
228
229 Acts::BoundVector param_vec;
230 param_vec << seed.getD0(), seed.getZ0(), seed.getPhi(), seed.getTheta(),
231 seed.getQoP(), seed.getT();
232
233 Acts::BoundSquareMatrix cov_mat =
234 tracking::sim::utils::unpackCov(seed.getPerigeeCov());
235
236 ldmx_log(debug) << " For seed index_ = " << seed_track_index
237 << ": Perigee X / Y / Z = " << seed.getPerigeeX() << " / "
238 << seed.getPerigeeY() << " / " << seed.getPerigeeZ()
239 << ", D0 = " << param_vec[0] << ", Z0 = " << param_vec[1]
240 << ", Phi = " << param_vec[2]
241 << ", Theta = " << param_vec[3]
242 << ", QoP = " << param_vec[4]
243 << ", Time = " << param_vec[5];
244
245 ldmx_log(debug) << " Cov matrix diagonal (" << cov_mat(0, 0) << ", "
246 << cov_mat(1, 1) << ", " << cov_mat(2, 2) << ")";
247
248 // need to set particle hypothesis...set to electron for now...
249 auto part_hypo{Acts::SinglyChargedParticleHypothesis::electron()};
250 start_parameters.push_back(Acts::BoundTrackParameters(
251 perigee_surface, param_vec, cov_mat, part_hypo));
252
253 // This is a global variable for performance checks
254 nseeds_++;
255 // This is just to index_ the seed we are looking at
256 seed_track_index++;
257 } // loop on seeds
258
259 auto seeds = std::chrono::high_resolution_clock::now();
260 profiling_map_["seeds"] +=
261 std::chrono::duration<double, std::milli>(seeds - hits).count();
262
263 Acts::GainMatrixUpdater kf_updater;
264
265 // configuration for the measurement selector. Empty geometry identifier means
266 // applicable to all the detector elements
267
268 Acts::MeasurementSelector::Config measurement_selector_cfg = {
269 // global default: no chi2 cut, only one measurement per surface
270 {Acts::GeometryIdentifier(), {{}, {outlier_pval_}, {1u}}},
271 };
272
273 Acts::MeasurementSelector meas_sel{measurement_selector_cfg};
274
275 tracking::sim::LdmxMeasurementCalibrator calibrator{measurements};
276
277 Acts::CombinatorialKalmanFilterExtensions<TrackContainer> ckf_extensions;
278
279 if (use1_dmeasurements_) {
280 ckf_extensions.calibrator
282 Acts::VectorMultiTrajectory>>(&calibrator);
283 } else {
284 ckf_extensions.calibrator
286 Acts::VectorMultiTrajectory>>(&calibrator);
287 }
288
289 ckf_extensions.updater.connect<
290 &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
291 &kf_updater);
292
293 ckf_extensions.measurementSelector
294 .connect<&Acts::MeasurementSelector::select<Acts::VectorMultiTrajectory>>(
295 &meas_sel);
296
297 ldmx_log(debug) << "SourceLinkAccessor...";
298
299 // Create source link accessor and connect delegate
300 struct SourceLinkAccIt {
301 using BaseIt = decltype(geo_id_sl_map.begin());
302 BaseIt it_;
303
304#pragma GCC diagnostic push
305#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
306
307 using difference_type = typename BaseIt::difference_type;
308 using iterator_category = typename BaseIt::iterator_category;
309 // using value_type = typename BaseIt::value_type::second_type;
310 using value_type = Acts::SourceLink;
311 using pointer = typename BaseIt::pointer;
312 using reference = value_type&;
313#pragma GCC diagnostic pop
314
315 SourceLinkAccIt& operator++() {
316 ++it_;
317 return *this;
318 }
319 bool operator==(const SourceLinkAccIt& other) const {
320 return it_ == other.it_;
321 }
322 bool operator!=(const SourceLinkAccIt& other) const {
323 return !(*this == other);
324 }
325 // const value_type& operator*() const { return it->second; }
326
327 // by value
328 value_type operator*() const { return value_type{it_->second}; }
329 };
330
331 auto source_link_accessor = [&](const Acts::Surface& surface)
332 -> std::pair<SourceLinkAccIt, SourceLinkAccIt> {
333 auto [begin, end] = geo_id_sl_map.equal_range(surface.geometryId());
334 return {SourceLinkAccIt{begin}, SourceLinkAccIt{end}};
335 };
336
337 Acts::SourceLinkAccessorDelegate<SourceLinkAccIt>
338 source_link_accessor_delegate;
339 source_link_accessor_delegate
340 .connect<&decltype(source_link_accessor)::operator(),
341 decltype(source_link_accessor)>(&source_link_accessor);
342
343 ldmx_log(debug) << "Setting up surfaces...";
344
345 std::shared_ptr<const Acts::PerigeeSurface> origin_surface =
346 Acts::Surface::makeShared<Acts::PerigeeSurface>(
347 Acts::Vector3(0., 0., 0.));
348
349 ldmx_log(debug) << "About to run CKF...";
350
351 // run the CKF for all initial track states
352 auto ckf_setup = std::chrono::high_resolution_clock::now();
353 profiling_map_["ckf_setup"] +=
354 std::chrono::duration<double, std::milli>(ckf_setup - seeds).count();
355
356 Acts::VectorTrackContainer vtc;
357 Acts::VectorMultiTrajectory mtj;
358 Acts::TrackContainer tc{vtc, mtj};
359
360 // The number of track candidates (i.e. startParameters.size()) is always
361 // the same as the number of seed tracks
362 ldmx_log(debug) << "Loop on the track candidates";
363 for (size_t track_id = 0u; track_id < start_parameters.size(); ++track_id) {
364 ldmx_log(debug) << "---------------------------";
365 ldmx_log(debug) << "Candidate Track ID = " << track_id;
366 // Define the CKF options here:
367 const Acts::CombinatorialKalmanFilterOptions<SourceLinkAccIt,
368 TrackContainer>
369 ckf_options(TrackingGeometryUser::geometryContext(),
370 TrackingGeometryUser::magneticFieldContext(),
371 TrackingGeometryUser::calibrationContext(),
372 source_link_accessor_delegate, ckf_extensions,
373 propagator_options, true /* multiple scattering */,
374 false /* energy loss */);
375
376 ldmx_log(debug) << " Checking options: multiple scattering = "
377 << ckf_options.multipleScattering
378 << " energy loss = " << ckf_options.energyLoss;
379
380 // Try field-map CKF first
381 auto results =
382 ckf_->findTracks(start_parameters.at(track_id), ckf_options, tc);
383
384 auto start_params = start_parameters.at(track_id).parameters().transpose();
385
386 // If field-map CKF fails, try appropriate fallback based on tracking system
387 if (!results.ok()) {
388 if (!tagger_tracking_) {
389 // Recoil tracking: try zero-B CKF as fallback
390 n_fieldmap_ckf_failed_recoil_++;
391 ldmx_log(debug)
392 << " Field-map CKF failed, trying zero-B CKF fallback";
393 results = ckf_zero_b_->findTracks(start_parameters.at(track_id),
394 ckf_options, tc);
395 if (results.ok()) {
396 n_zerob_ckf_recovered_recoil_++;
397 ldmx_log(debug) << " Yay! Zero-B CKF succeeded as fallback!";
398 } else {
399 ldmx_log(debug) << " Zero-B CKF also failed!";
400 }
401 } else {
402 // Tagger tracking: try const-B (1.5T) CKF as fallback
403 n_fieldmap_ckf_failed_tagger_++;
404 ldmx_log(debug)
405 << " Field-map CKF failed, trying const-B (1.5T) CKF fallback";
406 results = ckf_const_b_->findTracks(start_parameters.at(track_id),
407 ckf_options, tc);
408 if (results.ok()) {
409 n_constb_ckf_recovered_tagger_++;
410 ldmx_log(debug) << " Yay! Const-B CKF succeeded as fallback!";
411 } else {
412 ldmx_log(debug) << " Const-B CKF also failed!";
413 }
414 }
415 }
416
417 ldmx_log(debug)
418 << " Checking CKF success for track candidate with params: "
419 << " D0 = " << start_params[0] << " Z0 = " << start_params[1]
420 << ", Phi = " << start_params[2] << " Theta = " << start_params[3]
421 << ", QoP = " << start_params[4] << " Time = " << start_params[5];
422 if (not results.ok()) {
423 ldmx_log(debug) << " CKF failed!";
424 continue;
425 } else {
426 ldmx_log(debug) << " CKF succeded!";
427 }
428
429 auto& tracks_from_seed = results.value();
430 if (tracks_from_seed.size() != 1) {
431 ldmx_log(info) << " tracksFromSeed.size = " << tracks_from_seed.size();
432 }
433 // For now it seems this loop is only looping on a single element
434 for (auto& track : tracks_from_seed) {
435 // do the track smoothing...this is not done in the CKF code anymore
436 Acts::smoothTrack(geometryContext(), track); // from TrackHelpers
437 // Build the output Track
438 ldmx::Track trk;
439
440 // Extrapolate to the target surface
441 auto opt_target = trk_extrap_->extrapolate(track, target_surface_);
442
443 if (!opt_target) {
444 if (tagger_tracking_) {
445 n_fieldmap_target_extrap_failed_tagger_++;
446 ldmx_log(debug) << " Field-map target extrapolation failed, "
447 "trying const-B (1.5T) fallback";
448 opt_target = trk_extrap_const_b_->extrapolate(track, target_surface_);
449 if (opt_target)
450 n_constb_target_extrap_recovered_tagger_++;
451 else
452 ldmx_log(debug) << " Both field-map and Const-B target "
453 "extrapolation failed!";
454 } else {
455 n_fieldmap_target_extrap_failed_recoil_++;
456 ldmx_log(debug) << " Field-map target extrapolation failed, "
457 "trying zero-B fallback";
458 opt_target = trk_extrap_zero_b_->extrapolate(track, target_surface_);
459 if (opt_target)
460 n_zerob_target_extrap_recovered_recoil_++;
461 else
462 ldmx_log(debug)
463 << " Both field-map and Zero-B target extrapolation failed!";
464 }
465 }
466
467 if (!opt_target) {
468 ldmx_log(debug) << " Could not extrapolate to target! nhits = "
469 << track.nMeasurements() << " Printing track states:";
470 for (const auto ts : track.trackStatesReversed()) {
471 if (ts.hasSmoothed())
472 ldmx_log(debug) << " Parameters: " << ts.smoothed().transpose();
473 else
474 ldmx_log(debug) << " Track state not smoothed!";
475 }
476 ldmx_log(debug) << " ...skipping this track candidate...";
477 continue;
478 }
479
480 ldmx_log(debug) << " Successfully obtained TrackState at target";
481
482 // Build TrackState in LDMX coordinates and add to track
483 auto ts_at_target = tracking::sim::utils::makeTrackState(
484 geometryContext(), *opt_target, ldmx::AtTarget);
485 trk.addTrackState(ts_at_target);
486
487 ldmx_log(debug) << " Position at target (LDMX): ("
488 << ts_at_target.pos_[0] << ", " << ts_at_target.pos_[1]
489 << ", " << ts_at_target.pos_[2] << ") mm"
490 << " Momentum: (" << ts_at_target.mom_[0] << ", "
491 << ts_at_target.mom_[1] << ", " << ts_at_target.mom_[2]
492 << ") GeV";
493
494 // Update ACTS track reference surface (needed for downstream ACTS usage)
495 track.setReferenceSurface(target_surface_);
496 track.parameters() = opt_target->parameters();
497
498 // Store perigee (bound) parameters at the target for convenience
499 trk.setPerigeeParameters(tracking::sim::utils::convertActsToLdmxPars(
500 opt_target->parameters()));
501 if (opt_target->covariance()) {
502 std::vector<double> cov_vec;
503 tracking::sim::utils::flatCov(*(opt_target->covariance()), cov_vec);
504 trk.setPerigeeCov(cov_vec);
505 }
506 // Perigee location: target surface origin rotated to LDMX frame
507 Acts::Vector3 target_loc_ldmx = tracking::sim::utils::acts2Ldmx(
508 target_surface_->transform(geometryContext()).translation());
509 trk.setPerigeeLocation(target_loc_ldmx[0], target_loc_ldmx[1],
510 target_loc_ldmx[2]);
511
512 trk.setChi2(track.chi2());
513 trk.setNhits(track.nMeasurements());
514 trk.setNdf(track.nMeasurements() - 5);
515 trk.setNsharedHits(track.nSharedHits());
516 trk.setCharge(opt_target->parameters()[Acts::eBoundQOverP] > 0 ? 1 : -1);
517
518 // At least min_hits hits and p > 50 MeV
519 if ((trk.getNhits() <= min_hits_) ||
520 (std::abs(1. / trk.getQoP()) <= 0.05)) {
521 ldmx_log(debug)
522 << " > Track candidate did NOT meet the requirements: Nhits = "
523 << trk.getNhits() << " and p = " << std::abs(1. / trk.getQoP())
524 << " GeV";
525 continue;
526 }
527
528 // Add measurements to the final track
529 ldmx_log(debug) << " Add measurements to the final track from "
530 << track.nTrackStates() << " TrackStates with "
531 << track.nMeasurements() << " measurements";
532
533 int trk_state_index{0};
534 for (const auto ts : track.trackStatesReversed()) {
535 // Check TrackStates Quality
536 ldmx_log(debug) << " Checking Track State index_ = "
537 << trk_state_index << " at location "
538 << ts.referenceSurface()
539 .transform(geometryContext())
540 .translation()
541 .transpose();
542
543 if (ts.hasSmoothed()) {
544 ldmx_log(debug) << " Smoothed track parameters: "
545 << ts.smoothed().transpose();
546 // ldmx_log(debug) << " Smoothed covariance mtx:\n" <<
547 // ts.smoothedCovariance();
548 }
549
550 // Check if the track state is a measurement
551 auto type_flags = ts.typeFlags();
552
553 if (type_flags.test(Acts::TrackStateFlag::MeasurementFlag) &&
554 ts.hasUncalibratedSourceLink()) {
556 ts.getUncalibratedSourceLink()
557 .template get<acts_examples::IndexSourceLink>();
558
559 ldmx::Measurement ldmx_meas = measurements.at(sl.index());
560 ldmx_log(debug) << " Adding measurement to ldmx::track with "
561 "source link index_ = "
562 << sl.index();
563 ldmx_log(trace) << " Measurement:\n" << ldmx_meas;
564 trk.addMeasurementIndex(sl.index());
565
566 // Store the smoothed state for algebraic unbiased residuals in the
567 // DQM. The leave-one-out formula (NIM A 262, 444, 1987) removes
568 // this hit's contribution analytically:
569 // r_ubs = V/(V - C) * (m - x_smooth), pull = r_ubs * sqrt(V-C)/V
570 // This works correctly for all layers, including seed layers where
571 // the predicted state would be biased.
572 if (ts.hasSmoothed()) {
573 trk.addSmoothedLoc0(
574 static_cast<float>(ts.smoothed()[Acts::eBoundLoc0]),
575 static_cast<float>(ts.smoothedCovariance()(Acts::eBoundLoc0,
576 Acts::eBoundLoc0)));
577 }
578
579 // Extract path length from the track state based on the angle
580 if (ts.hasSmoothed()) {
581 const auto& meas_surface = ts.referenceSurface();
582 const auto& smoothed_params = ts.smoothed();
583
584 // Get the momentum from the track parameters
585 // momentum = p * direction where direction = (sin(theta)*cos(phi),
586 // sin(theta)*sin(phi), cos(theta))
587 float p_inv = smoothed_params[Acts::eBoundQOverP];
588 float p = 1.0f / std::abs(p_inv);
589 float theta = smoothed_params[Acts::eBoundTheta];
590 float phi = smoothed_params[Acts::eBoundPhi];
591
592 Acts::Vector3 global_momentum(p * std::sin(theta) * std::cos(phi),
593 p * std::sin(theta) * std::sin(phi),
594 p * std::cos(theta));
595
596 // Get the local frame (transform from global to local)
597 auto local_frame_transform =
598 meas_surface.transform(geometryContext());
599 Acts::Vector3 local_momentum =
600 local_frame_transform.rotation().transpose() * global_momentum;
601
602 // Calculate local angle components (tangent of angles)
603 float phi_u = (local_momentum.z() != 0)
604 ? local_momentum.x() / local_momentum.z()
605 : 0.;
606 float phi_v = (local_momentum.z() != 0)
607 ? local_momentum.y() / local_momentum.z()
608 : 0.;
609
610 // Calculate the total angle from the local angle components
611 // tan(angle) = sqrt(phi_u^2 + phi_v^2)
612 // cos(angle) = 1 / sqrt(1 + tan(angle)^2)
613 // path_length = thickness / cos(angle)
614 float sensor_thickness = 0.0f;
615 if (const auto* det_el = meas_surface.associatedDetectorElement()) {
616 sensor_thickness = static_cast<float>(det_el->thickness());
617 } else {
618 ldmx_log(warn) << "No detector element for measurement surface"
619 << " — skipping dE/dx for this hit";
620 continue;
621 }
622 float tan_angle_sq = phi_u * phi_u + phi_v * phi_v;
623 float cos_angle = 1.0f / std::sqrt(1.0f + tan_angle_sq);
624 float path_length = sensor_thickness / cos_angle;
625
626 ldmx_log(debug) << " Local angles: phi_u = " << phi_u
627 << ", phi_v = " << phi_v
628 << "; Path length = " << path_length << " mm";
629
630 // Calculate dE/dx and add to track (in MeV/mm)
631 float edep = ldmx_meas.getEdep();
632 float dedx = edep / path_length;
633 trk.addDedxMeasurement(dedx);
634
635 ldmx_log(debug) << " Edep = " << edep
636 << " MeV, dE/dx = " << dedx << " MeV/mm";
637 }
638 } else {
639 ldmx_log(debug) << " This TrackState is not a measurement";
640 }
641 trk_state_index++;
642 }
643
644 ldmx_log(debug) << " Starting extrapolations";
645 // Extrapolations
646 // To ECAL
647 const double ecal_scoring_plane = 240.5;
648 Acts::Vector3 pos(ecal_scoring_plane, 0., 0.);
649 Acts::Translation3 surf_translation(pos);
650 Acts::Transform3 surf_transform(surf_translation * surf_rotation_);
651 const std::shared_ptr<Acts::PlaneSurface> ecal_surface =
652 Acts::Surface::makeShared<Acts::PlaneSurface>(surf_transform);
653
654 // Beam Origin unbounded surface
655 const std::shared_ptr<Acts::Surface> beam_origin_surface =
656 tracking::sim::utils::unboundSurface(-700);
657
658 if (tagger_tracking_) {
659 ldmx_log(debug) << " Beam Origin Extrapolation";
660 auto opt_beam_origin =
661 trk_extrap_->extrapolate(track, beam_origin_surface);
662 if (opt_beam_origin) {
663 trk.addTrackState(tracking::sim::utils::makeTrackState(
664 geometryContext(), *opt_beam_origin, ldmx::AtBeamOrigin));
665 ldmx_log(debug)
666 << " Successfully obtained TrackState at beam origin";
667 }
668 }
669
670 // Recoil Extrapolation to ECAL only
671 if (!tagger_tracking_) {
672 ldmx_log(debug) << " Ecal Extrapolation";
673 auto opt_ecal = trk_extrap_->extrapolate(track, ecal_surface);
674
675 if (!opt_ecal) {
676 n_fieldmap_ecal_extrap_failed_recoil_++;
677 ldmx_log(debug) << " Field-map ECAL extrapolation failed, trying "
678 "zero-B fallback";
679 opt_ecal = trk_extrap_zero_b_->extrapolate(track, ecal_surface);
680 if (opt_ecal)
681 n_zerob_ecal_extrap_recovered_recoil_++;
682 else
683 ldmx_log(debug)
684 << " Both field-map and Zero-B ECAL extrapolation failed!";
685 }
686
687 if (opt_ecal) {
688 auto ts_at_ecal = tracking::sim::utils::makeTrackState(
689 geometryContext(), *opt_ecal, ldmx::AtECAL);
690 trk.addTrackState(ts_at_ecal);
691 ldmx_log(debug) << " Successfully obtained TrackState at ECAL";
692 ldmx_log(debug) << " Position at ECAL (LDMX): ("
693 << ts_at_ecal.pos_[0] << ", " << ts_at_ecal.pos_[1]
694 << ", " << ts_at_ecal.pos_[2] << ") mm";
695 }
696 }
697
698 // Truth matching
699 if (truth_matching_tool) {
700 auto truth_info = truth_matching_tool->truthMatch(trk);
701 trk.setTrackID(truth_info.track_id_);
702 trk.setPdgID(truth_info.pdg_id_);
703 trk.setTruthProb(truth_info.truth_prob_);
704 }
705
706 // Adding the track candidate to the track collection
707 ldmx_log(debug)
708 << " > Adding the track candidate to the track collection";
709 tracks.push_back(trk);
710 ntracks_++;
711 } // // loop on tracksFromSeed (which usually has 1 element)
712 } // loop seed track parameters (i.e. track candidates)
713
714 ldmx_log(info) << "Number of CKF tracks " << tracks.size();
715
716 auto ckf_run = std::chrono::high_resolution_clock::now();
717 profiling_map_["ckf_run"] +=
718 std::chrono::duration<double, std::milli>(ckf_run - ckf_setup).count();
719
720 // Calculating Shared Hits
721 auto shared_hits = computeSharedHits(
722 tracks, measurements, tg, tracking::sim::utils::sourceLinkHash,
723 tracking::sim::utils::sourceLinkEquality);
724 for (std::size_t i_track = 0; i_track < shared_hits.size(); ++i_track) {
725 tracks[i_track].setNsharedHits(shared_hits[i_track].size());
726 for (auto idx : shared_hits[i_track]) {
727 tracks[i_track].addSharedIndex(idx);
728 }
729 }
730
731 auto result_loop = std::chrono::high_resolution_clock::now();
732 profiling_map_["result_loop"] +=
733 std::chrono::duration<double, std::milli>(result_loop - ckf_run).count();
734
735 // Add the tracks to the event
736 event.add(out_trk_collection_, tracks);
737
738 auto end = std::chrono::high_resolution_clock::now();
739 // long long microseconds =
740 // std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
741 auto diff = end - start;
742 processing_time_ += std::chrono::duration<double, std::milli>(diff).count();
743} // end of produce()
bool exists(const std::string &name, const std::string &passName, bool unique=true) const
Check for the existence of an object or collection with the given name and pass name in the event.
Definition Event.cxx:105
float getEdep() const
Class representing a simulated particle.
Definition SimParticle.h:24
Implementation of a track object.
Definition Track.h:53
void calibrate1d(const Acts::GeometryContext &, const Acts::CalibrationContext &, const Acts::SourceLink &genericSourceLink, typename traj_t::TrackStateProxy trackState) const
Find the measurement corresponding to the source link.
void calibrate(const Acts::GeometryContext &, const Acts::CalibrationContext &, const Acts::SourceLink &genericSourceLink, typename traj_t::TrackStateProxy trackState) const
Find the measurement corresponding to the source link.

References tracking::sim::LdmxMeasurementCalibrator::calibrate(), tracking::sim::LdmxMeasurementCalibrator::calibrate1d(), framework::Event::exists(), ldmx::Measurement::getEdep(), acts_examples::IndexSourceLink::index(), and nseeds_.

Member Data Documentation

◆ bfield_

double tracking::reco::CKFProcessor::bfield_ {0}
private

Definition at line 171 of file CKFProcessor.h.

171{0};

◆ ckf_

std::unique_ptr< const Acts::CombinatorialKalmanFilter<CkfPropagator, TrackContainer> > tracking::reco::CKFProcessor::ckf_
private

Definition at line 223 of file CKFProcessor.h.

◆ ckf_const_b_

std::unique_ptr< const Acts::CombinatorialKalmanFilter<CkfPropagator, TrackContainer> > tracking::reco::CKFProcessor::ckf_const_b_
private

Definition at line 241 of file CKFProcessor.h.

◆ ckf_zero_b_

std::unique_ptr< const Acts::CombinatorialKalmanFilter<CkfPropagator, TrackContainer> > tracking::reco::CKFProcessor::ckf_zero_b_
private

Definition at line 233 of file CKFProcessor.h.

◆ const_b_field_

bool tracking::reco::CKFProcessor::const_b_field_ {true}
private

Definition at line 173 of file CKFProcessor.h.

173{true};

◆ debug_acts_

bool tracking::reco::CKFProcessor::debug_acts_ {false}
private

Definition at line 166 of file CKFProcessor.h.

166{false};

◆ dumpobj_

bool tracking::reco::CKFProcessor::dumpobj_ {false}
private

Definition at line 154 of file CKFProcessor.h.

154{false};

◆ eventnr_

int tracking::reco::CKFProcessor::eventnr_
private

Definition at line 248 of file CKFProcessor.h.

◆ extrapolate_location_

std::vector<double> tracking::reco::CKFProcessor::extrapolate_location_ {0., 0., 0.}
private

Definition at line 190 of file CKFProcessor.h.

190{0., 0., 0.};

◆ field_map_

std::string tracking::reco::CKFProcessor::field_map_ {""}
private

Definition at line 213 of file CKFProcessor.h.

213{""};

◆ input_pass_name_

std::string tracking::reco::CKFProcessor::input_pass_name_ {""}
private

Definition at line 215 of file CKFProcessor.h.

215{""};

◆ map_offset_

std::vector<double> tracking::reco::CKFProcessor::map_offset_
private
Initial value:
{
0.,
0.,
0.,
}

Definition at line 265 of file CKFProcessor.h.

265 {
266 0.,
267 0.,
268 0.,
269 };

◆ measurement_collection_

std::string tracking::reco::CKFProcessor::measurement_collection_ {"TaggerMeasurements"}
private

Definition at line 194 of file CKFProcessor.h.

194{"TaggerMeasurements"};

◆ min_hits_

int tracking::reco::CKFProcessor::min_hits_ {7}
private

Definition at line 182 of file CKFProcessor.h.

182{7};

◆ n_constb_ckf_recovered_tagger_

int tracking::reco::CKFProcessor::n_constb_ckf_recovered_tagger_ {0}
private

Definition at line 253 of file CKFProcessor.h.

253{0};

◆ n_constb_target_extrap_recovered_tagger_

int tracking::reco::CKFProcessor::n_constb_target_extrap_recovered_tagger_ {0}
private

Definition at line 258 of file CKFProcessor.h.

258{0};

◆ n_fieldmap_ckf_failed_recoil_

int tracking::reco::CKFProcessor::n_fieldmap_ckf_failed_recoil_ {0}
private

Definition at line 252 of file CKFProcessor.h.

252{0};

◆ n_fieldmap_ckf_failed_tagger_

int tracking::reco::CKFProcessor::n_fieldmap_ckf_failed_tagger_ {0}
private

Definition at line 251 of file CKFProcessor.h.

251{0};

◆ n_fieldmap_ecal_extrap_failed_recoil_

int tracking::reco::CKFProcessor::n_fieldmap_ecal_extrap_failed_recoil_ {0}
private

Definition at line 261 of file CKFProcessor.h.

261{0};

◆ n_fieldmap_target_extrap_failed_recoil_

int tracking::reco::CKFProcessor::n_fieldmap_target_extrap_failed_recoil_ {0}
private

Definition at line 259 of file CKFProcessor.h.

259{0};

◆ n_fieldmap_target_extrap_failed_tagger_

int tracking::reco::CKFProcessor::n_fieldmap_target_extrap_failed_tagger_ {0}
private

Definition at line 257 of file CKFProcessor.h.

257{0};

◆ n_zerob_ckf_recovered_recoil_

int tracking::reco::CKFProcessor::n_zerob_ckf_recovered_recoil_ {0}
private

Definition at line 254 of file CKFProcessor.h.

254{0};

◆ n_zerob_ecal_extrap_recovered_recoil_

int tracking::reco::CKFProcessor::n_zerob_ecal_extrap_recovered_recoil_ {0}
private

Definition at line 262 of file CKFProcessor.h.

262{0};

◆ n_zerob_target_extrap_recovered_recoil_

int tracking::reco::CKFProcessor::n_zerob_target_extrap_recovered_recoil_ {0}
private

Definition at line 260 of file CKFProcessor.h.

260{0};

◆ nevents_

int tracking::reco::CKFProcessor::nevents_ {0}
private

Definition at line 158 of file CKFProcessor.h.

158{0};

◆ nseeds_

int tracking::reco::CKFProcessor::nseeds_
private

n seeds and n tracks

Definition at line 246 of file CKFProcessor.h.

Referenced by onNewRun(), onProcessEnd(), and produce().

◆ ntracks_

int tracking::reco::CKFProcessor::ntracks_
private

Definition at line 247 of file CKFProcessor.h.

◆ out_trk_collection_

std::string tracking::reco::CKFProcessor::out_trk_collection_ {"Tracks"}
private

Definition at line 207 of file CKFProcessor.h.

207{"Tracks"};

◆ outlier_pval_

double tracking::reco::CKFProcessor::outlier_pval_
private

Definition at line 204 of file CKFProcessor.h.

◆ pionstates_

int tracking::reco::CKFProcessor::pionstates_ {10}
private

Definition at line 156 of file CKFProcessor.h.

156{10};

◆ processing_time_

double tracking::reco::CKFProcessor::processing_time_ {0.}
private

Definition at line 161 of file CKFProcessor.h.

161{0.};

◆ profiling_map_

std::map<std::string, double> tracking::reco::CKFProcessor::profiling_map_
private

Definition at line 164 of file CKFProcessor.h.

◆ propagator_

std::unique_ptr<const CkfPropagator> tracking::reco::CKFProcessor::propagator_
private

Definition at line 218 of file CKFProcessor.h.

◆ propagator_const_b_

std::unique_ptr<const CkfPropagator> tracking::reco::CKFProcessor::propagator_const_b_
private

Definition at line 238 of file CKFProcessor.h.

◆ propagator_max_steps_

int tracking::reco::CKFProcessor::propagator_max_steps_ {1000}
private

Definition at line 186 of file CKFProcessor.h.

186{1000};

◆ propagator_step_size_

double tracking::reco::CKFProcessor::propagator_step_size_ {200.}
private

Definition at line 185 of file CKFProcessor.h.

185{200.};

◆ propagator_zero_b_

std::unique_ptr<const CkfPropagator> tracking::reco::CKFProcessor::propagator_zero_b_
private

Definition at line 230 of file CKFProcessor.h.

◆ remove_stereo_

bool tracking::reco::CKFProcessor::remove_stereo_ {false}
private

Definition at line 176 of file CKFProcessor.h.

176{false};

◆ seed_coll_name_

std::string tracking::reco::CKFProcessor::seed_coll_name_ {"seedTracks"}
private

Definition at line 210 of file CKFProcessor.h.

210{"seedTracks"};

◆ sim_particles_coll_name_

std::string tracking::reco::CKFProcessor::sim_particles_coll_name_
private

Definition at line 196 of file CKFProcessor.h.

◆ sim_particles_event_passname_

std::string tracking::reco::CKFProcessor::sim_particles_event_passname_
private

Definition at line 197 of file CKFProcessor.h.

◆ surf_rotation_

Acts::RotationMatrix3 tracking::reco::CKFProcessor::surf_rotation_
private

Definition at line 169 of file CKFProcessor.h.

◆ tagger_tracking_

bool tracking::reco::CKFProcessor::tagger_tracking_ {true}
private

Definition at line 272 of file CKFProcessor.h.

272{true};

◆ target_surface_

std::shared_ptr<Acts::PlaneSurface> tracking::reco::CKFProcessor::target_surface_
private

Definition at line 168 of file CKFProcessor.h.

◆ trk_extrap_

std::shared_ptr<tracking::reco::TrackExtrapolatorTool<CkfPropagator> > tracking::reco::CKFProcessor::trk_extrap_
private

Definition at line 227 of file CKFProcessor.h.

◆ trk_extrap_const_b_

std::shared_ptr<tracking::reco::TrackExtrapolatorTool<CkfPropagator> > tracking::reco::CKFProcessor::trk_extrap_const_b_
private

Definition at line 243 of file CKFProcessor.h.

◆ trk_extrap_zero_b_

std::shared_ptr<tracking::reco::TrackExtrapolatorTool<CkfPropagator> > tracking::reco::CKFProcessor::trk_extrap_zero_b_
private

Definition at line 235 of file CKFProcessor.h.

◆ use1_dmeasurements_

bool tracking::reco::CKFProcessor::use1_dmeasurements_ {true}
private

Definition at line 179 of file CKFProcessor.h.

179{true};

◆ use_extrapolate_location_

bool tracking::reco::CKFProcessor::use_extrapolate_location_ {true}
private

Definition at line 189 of file CKFProcessor.h.

189{true};

◆ use_seed_perigee_

bool tracking::reco::CKFProcessor::use_seed_perigee_ {false}
private

Definition at line 191 of file CKFProcessor.h.

191{false};

The documentation for this class was generated from the following files: