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 ()
 
- 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 972 of file CKFProcessor.cxx.

975 {
976 auto measurement_index_map =
977 std::unordered_map<Acts::SourceLink, std::size_t, source_link_hash_t,
978 source_link_equality_t>(0, sourceLinkHash,
979 sourceLinkEquality);
980
981 std::vector<std::vector<std::size_t>> measurements_per_track;
982 boost::container::flat_map<std::size_t,
983 boost::container::flat_set<std::size_t>>
984 tracks_per_measurement;
985 std::vector<std::size_t> shared_measurements_per_track;
986 auto number_of_tracks = 0;
987
988 // Iterate through all input tracks, collect their properties like measurement
989 // count and chi2 and fill the measurement map in order to relate tracks to
990 // each other if they have shared hits.
991 for (const auto& track : tracks) {
992 // Kick out tracks that do not fulfill our initial requirements
993 // if (track.getNhits() < n_measurements_min_) {
994 // continue;
995 // }
996
997 std::vector<std::size_t> measurements;
998 for (auto imeas : track.getMeasurementsIdxs()) {
999 auto meas = meas_coll.at(imeas);
1000 const Acts::Surface* hit_surface = tg.getSurface(meas.getLayerID());
1001 // Store the index_ source link
1002 acts_examples::IndexSourceLink idx_sl(hit_surface->geometryId(), imeas);
1003 Acts::SourceLink source_link = Acts::SourceLink(idx_sl);
1004
1005 auto emplace = measurement_index_map.try_emplace(
1006 source_link, measurement_index_map.size());
1007 measurements.push_back(emplace.first->second);
1008 }
1009
1010 measurements_per_track.push_back(std::move(measurements));
1011
1012 ++number_of_tracks;
1013 }
1014
1015 // Now we relate measurements to tracks
1016 for (std::size_t i_track = 0; i_track < number_of_tracks; ++i_track) {
1017 for (auto i_measurement : measurements_per_track[i_track]) {
1018 tracks_per_measurement[i_measurement].insert(i_track);
1019 }
1020 }
1021
1022 // Finally, we can accumulate the number of shared measurements per track
1023 shared_measurements_per_track = std::vector<std::size_t>(number_of_tracks, 0);
1024
1025 std::vector<std::vector<std::size_t>> shared_measurement_idxs_per_track;
1026 for (std::size_t i_track = 0; i_track < number_of_tracks; ++i_track) {
1027 std::vector<std::size_t> shared_measurement_idxs;
1028 for (auto i_measurement : measurements_per_track[i_track]) {
1029 if (tracks_per_measurement[i_measurement].size() > 1) {
1030 ++shared_measurements_per_track[i_track];
1031 shared_measurement_idxs.push_back(i_measurement);
1032 }
1033 }
1034 shared_measurement_idxs_per_track.push_back(shared_measurement_idxs);
1035 }
1036 return shared_measurement_idxs_per_track;
1037}

◆ 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 876 of file CKFProcessor.cxx.

876 {
877 dumpobj_ = parameters.get<bool>("dumpobj", 0);
878 pionstates_ = parameters.get<int>("pionstates", 0);
879
880 bfield_ = parameters.get<double>("bfield", -1.5);
881 const_b_field_ = parameters.get<bool>("const_b_field", false);
882 field_map_ = parameters.get<std::string>("field_map");
883 propagator_step_size_ = parameters.get<double>("propagator_step_size", 200.);
884 propagator_max_steps_ = parameters.get<int>("propagator_max_steps", 10000);
885 measurement_collection_ = parameters.get<std::string>(
886 "measurement_collection", "TaggerMeasurements");
887 outlier_pval_ = parameters.get<double>("outlier_pval_", 3.84);
888
889 debug_acts_ = parameters.get<bool>("debug_acts", false);
890
891 remove_stereo_ = parameters.get<bool>("remove_stereo", false);
892 use1_dmeasurements_ = parameters.get<bool>("use1Dmeasurements", true);
893 min_hits_ = parameters.get<int>("min_hits", 7);
894
895 // Ckf specific options
896 use_extrapolate_location_ =
897 parameters.get<bool>("use_extrapolate_location", true);
898 extrapolate_location_ =
899 parameters.get<std::vector<double>>("extrapolate_location", {0., 0., 0.});
900 use_seed_perigee_ = parameters.get<bool>("use_seed_perigee", false);
901
902 // seeds from the event
903 seed_coll_name_ = parameters.get<std::string>("seed_coll_name", "seedTracks");
904
905 sim_particles_coll_name_ =
906 parameters.get<std::string>("sim_particles_coll_name");
907 sim_particles_event_passname_ =
908 parameters.get<std::string>("sim_particles_event_passname");
909
910 // output track collection
911 out_trk_collection_ =
912 parameters.get<std::string>("out_trk_collection", "Tracks");
913
914 // keep track on which system tracking is running
915 tagger_tracking_ = parameters.get<bool>("tagger_tracking", true);
916
917 // BField Systematics
918 map_offset_ =
919 parameters.get<std::vector<double>>("map_offset_", {0., 0., 0.});
920
921 input_pass_name_ = parameters.get<std::string>("input_pass_name");
922} // 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 924 of file CKFProcessor.cxx.

928 {
929 std::unordered_multimap<Acts::GeometryIdentifier,
931 geo_id_sl_map;
932
933 ldmx_log(debug) << "The makeGeoIdSourceLinkMap has " << measurements.size()
934 << " measurements";
935
936 // Check the hits associated to the surfaces
937 for (unsigned int i_meas = 0; i_meas < measurements.size(); i_meas++) {
938 ldmx::Measurement meas = measurements.at(i_meas);
939 unsigned int layerid = meas.getLayerID();
940
941 const Acts::Surface* hit_surface = tg.getSurface(layerid);
942
943 if (hit_surface) {
944 // Transform the ldmx space point from global to local and store the
945 // information
946
947 acts_examples::IndexSourceLink idx_sl(hit_surface->geometryId(), i_meas);
948 // mg aug 2024 ... these don't print statements
949 // don't compile using v36 in Acts...figure out later
950 /*
951 ldmx_log(debug)
952 << "Insert measurement on surface located at::"
953 << hit_surface->transform(geometry_context()).translation();
954 ldmx_log(debug) << "and geoId::" << hit_surface->geometryId();
955
956 ldmx_log(debug) << "Surface info::"
957 << std::tie(*hit_surface, geometry_context());
958 */
959 geo_id_sl_map.insert(std::make_pair(hit_surface->geometryId(), idx_sl));
960
961 } else
962 ldmx_log(debug) << getName() << "::HIT " << i_meas << " at layer_"
963 << (measurements.at(i_meas)).getLayerID()
964 << " is not associated to any surface?!";
965 }
966
967 return geo_id_sl_map;
968}
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 // Custom transformation of the interpolated bfield map
65 bool debug_transform = false;
66 auto transform_pos = [this, debug_transform](const Acts::Vector3& pos_) {
67 Acts::Vector3 rot_pos;
68 rot_pos(0) = pos_(1);
69 rot_pos(1) = pos_(2);
70 rot_pos(2) = pos_(0) + DIPOLE_OFFSET;
71
72 // Systematic effect
73 rot_pos(0) += this->map_offset_[0];
74 rot_pos(1) += this->map_offset_[1];
75 rot_pos(2) += this->map_offset_[2];
76
77 // Apply A rotation around the center of the magnet. (I guess offset first
78 // and then rotation)
79
80 if (debug_transform) {
81 std::cout << "PF::DEFAULT3 TRANSFORM" << std::endl;
82 std::cout << "PF::Check:: transforming Pos" << std::endl;
83 std::cout << pos_ << std::endl;
84 std::cout << "TO" << std::endl;
85 std::cout << rot_pos << std::endl;
86 }
87
88 return rot_pos;
89 };
90
91 Acts::RotationMatrix3 rotation = Acts::RotationMatrix3::Identity();
92 double scale = 1.;
93
94 auto transform_b_field = [rotation, scale, debug_transform](
95 const Acts::Vector3& field,
96 const Acts::Vector3& /*pos_*/) {
97 // Rotate the field in tracking coordinates
98 Acts::Vector3 rot_field;
99 rot_field(0) = field(2);
100 rot_field(1) = field(0);
101 rot_field(2) = field(1);
102
103 // Scale the field
104 rot_field = scale * rot_field;
105
106 // Rotate the field
107 rot_field = rotation * rot_field;
108
109 // A distortion scaled by position.
110 if (debug_transform) {
111 std::cout << "PF::DEFAULT3 TRANSFORM" << std::endl;
112 std::cout << "PF::Check:: transforming" << std::endl;
113 std::cout << field << std::endl;
114 std::cout << "TO" << std::endl;
115 std::cout << rot_field << std::endl;
116 }
117
118 return rot_field;
119 };
120
121 // Setup a interpolated bfield map
122 const auto map = std::make_shared<InterpolatedMagneticField3>(
123 loadDefaultBField(field_map_,
124 // default_transformPos,
125 // default_transformBField));
126 transform_pos, transform_b_field));
127
128 auto acts_logging_level = Acts::Logging::FATAL;
129 if (debug_acts_) acts_logging_level = Acts::Logging::VERBOSE;
130
131 // Setup the steppers
132 const auto stepper = Acts::EigenStepper<>{map};
133 const auto const_stepper = Acts::EigenStepper<>{const_b_field};
134 const auto multi_stepper = Acts::MultiEigenStepperLoop{map};
135
136 // Setup the navigator
137 Acts::Navigator::Config nav_cfg{geometry().getTG()};
138 nav_cfg.resolveMaterial = true;
139 nav_cfg.resolvePassive = true;
140 nav_cfg.resolveSensitive = true;
141 const Acts::Navigator navigator(nav_cfg);
142
143 propagator_ = std::make_unique<CkfPropagator>(
144 stepper, navigator,
145 Acts::getDefaultLogger("CKF_PROP", acts_logging_level));
146
147 // Setup the finder / fitters
148 ckf_ = std::make_unique<std::decay_t<decltype(*ckf_)>>(
149 *propagator_, Acts::getDefaultLogger("CKF", acts_logging_level));
150 trk_extrap_ = std::make_shared<std::decay_t<decltype(*trk_extrap_)>>(
151 *propagator_, geometryContext(), magneticFieldContext());
152
153 // Setup zero-B CKF as fallback
154 Acts::ConstantBField zero_b_field(Acts::Vector3(0., 0., 0.));
155 const auto zero_b_stepper = Acts::EigenStepper<>{
156 std::make_shared<Acts::ConstantBField>(zero_b_field)};
157 propagator_zero_b_ =
158 std::make_unique<CkfPropagator>(zero_b_stepper, navigator);
159 ckf_zero_b_ = std::make_unique<std::decay_t<decltype(*ckf_zero_b_)>>(
160 *propagator_zero_b_,
161 Acts::getDefaultLogger("CKF_ZERO_B", acts_logging_level));
162 trk_extrap_zero_b_ =
163 std::make_shared<std::decay_t<decltype(*trk_extrap_zero_b_)>>(
164 *propagator_zero_b_, geometryContext(), magneticFieldContext());
165
166 // Setup const-B (1.5T) CKF as fallback for tagger
167 propagator_const_b_ =
168 std::make_unique<CkfPropagator>(const_stepper, navigator);
169 ckf_const_b_ = std::make_unique<std::decay_t<decltype(*ckf_const_b_)>>(
170 *propagator_const_b_,
171 Acts::getDefaultLogger("CKF_CONST_B", acts_logging_level));
172 trk_extrap_const_b_ =
173 std::make_shared<std::decay_t<decltype(*trk_extrap_const_b_)>>(
174 *propagator_const_b_, geometryContext(), magneticFieldContext());
175} // end of CKFProcessor::onNewRun()
int nseeds_
n seeds and n tracks

References 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 790 of file CKFProcessor.cxx.

790 {
791 ldmx_log(info) << "--------------------------------- ";
792 ldmx_log(info) << "Found " << ntracks_ << " tracks / " << nseeds_
793 << " nseeds";
794 ldmx_log(info) << "AVG Time/Event: " << std::fixed << std::setprecision(1)
795 << processing_time_ / nevents_ << " ms";
796 ldmx_log(info) << "Breakdown::";
797 ldmx_log(info) << " setup Avg Time/Event = " << std::fixed
798 << std::setprecision(3) << profiling_map_["setup"] / nevents_
799 << " ms";
800 ldmx_log(info) << " hits Avg Time/Event = " << std::fixed
801 << std::setprecision(2) << profiling_map_["hits"] / nevents_
802 << " ms";
803 ldmx_log(info) << " seeds Avg Time/Event = " << std::fixed
804 << std::setprecision(3) << profiling_map_["seeds"] / nevents_
805 << " ms";
806 ldmx_log(info) << " ckf_setup Avg Time/Event = " << std::fixed
807 << std::setprecision(3)
808 << profiling_map_["ckf_setup"] / nevents_ << " ms";
809 ldmx_log(info) << " ckf_run Avg Time/Event = " << std::fixed
810 << std::setprecision(3) << profiling_map_["ckf_run"] / nevents_
811 << " ms";
812 ldmx_log(info) << " result_loop Avg Time/Event = " << std::fixed
813 << std::setprecision(1)
814 << profiling_map_["result_loop"] / nevents_ << " ms";
815
816 // CKF fallback statistics
817 ldmx_log(info) << "CKF Fallback Statistics::";
818 if (tagger_tracking_) {
819 ldmx_log(info) << " Tagger: Field-map CKF failed "
820 << n_fieldmap_ckf_failed_tagger_
821 << " times, const-B CKF recovered "
822 << n_constb_ckf_recovered_tagger_ << " ("
823 << (n_fieldmap_ckf_failed_tagger_ > 0
824 ? 100.0 * n_constb_ckf_recovered_tagger_ /
825 n_fieldmap_ckf_failed_tagger_
826 : 0.0)
827 << "%)";
828
829 // Extrapolation fallback statistics for tagger
830 ldmx_log(info) << "Extrapolation Fallback Statistics::";
831 ldmx_log(info) << " Tagger Target: Field-map extrap failed "
832 << n_fieldmap_target_extrap_failed_tagger_
833 << " times, const-B extrap recovered "
834 << n_constb_target_extrap_recovered_tagger_ << " ("
835 << (n_fieldmap_target_extrap_failed_tagger_ > 0
836 ? 100.0 * n_constb_target_extrap_recovered_tagger_ /
837 n_fieldmap_target_extrap_failed_tagger_
838 : 0.0)
839 << "%)";
840 }
841
842 if (!tagger_tracking_) {
843 ldmx_log(info) << " Recoil: Field-map CKF failed "
844 << n_fieldmap_ckf_failed_recoil_
845 << " times, zero-B CKF recovered "
846 << n_zerob_ckf_recovered_recoil_ << " ("
847 << (n_fieldmap_ckf_failed_recoil_ > 0
848 ? 100.0 * n_zerob_ckf_recovered_recoil_ /
849 n_fieldmap_ckf_failed_recoil_
850 : 0.0)
851 << "%)";
852
853 // Extrapolation fallback statistics
854 ldmx_log(info) << "Extrapolation Fallback Statistics::";
855 ldmx_log(info) << " Recoil Target: Field-map extrap failed "
856 << n_fieldmap_target_extrap_failed_recoil_
857 << " times, zero-B extrap recovered "
858 << n_zerob_target_extrap_recovered_recoil_ << " ("
859 << (n_fieldmap_target_extrap_failed_recoil_ > 0
860 ? 100.0 * n_zerob_target_extrap_recovered_recoil_ /
861 n_fieldmap_target_extrap_failed_recoil_
862 : 0.0)
863 << "%)";
864 ldmx_log(info) << " Recoil ECAL: Field-map extrap failed "
865 << n_fieldmap_ecal_extrap_failed_recoil_
866 << " times, zero-B extrap recovered "
867 << n_zerob_ecal_extrap_recovered_recoil_ << " ("
868 << (n_fieldmap_ecal_extrap_failed_recoil_ > 0
869 ? 100.0 * n_zerob_ecal_extrap_recovered_recoil_ /
870 n_fieldmap_ecal_extrap_failed_recoil_
871 : 0.0)
872 << "%)";
873 }
874}

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 782 of file CKFProcessor.cxx.

782 {
783 if (use1_dmeasurements_)
784 ldmx_log(debug) << "Use1Dmeasurements = " << std::boolalpha
785 << use1_dmeasurements_;
786 if (remove_stereo_)
787 ldmx_log(debug) << "Remove_stereo = " << std::boolalpha << remove_stereo_;
788}

◆ produce()

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

Run the processor.

Parameters
eventThe event to process.

Implements framework::Producer.

Definition at line 177 of file CKFProcessor.cxx.

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