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

20 : 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 1016 of file CKFProcessor.cxx.

1019 {
1020 auto measurement_index_map =
1021 std::unordered_map<Acts::SourceLink, std::size_t, source_link_hash_t,
1022 source_link_equality_t>(0, sourceLinkHash,
1023 sourceLinkEquality);
1024
1025 std::vector<std::vector<std::size_t>> measurements_per_track;
1026 boost::container::flat_map<std::size_t,
1027 boost::container::flat_set<std::size_t>>
1028 tracks_per_measurement;
1029 std::vector<std::size_t> shared_measurements_per_track;
1030 auto number_of_tracks = 0;
1031
1032 // Iterate through all input tracks, collect their properties like measurement
1033 // count and chi2 and fill the measurement map in order to relate tracks to
1034 // each other if they have shared hits.
1035 for (const auto& track : tracks) {
1036 // Kick out tracks that do not fulfill our initial requirements
1037 // if (track.getNhits() < n_measurements_min_) {
1038 // continue;
1039 // }
1040
1041 std::vector<std::size_t> measurements;
1042 for (auto imeas : track.getMeasurementsIdxs()) {
1043 auto meas = meas_coll.at(imeas);
1044 const Acts::Surface* hit_surface = tg.getSurface(meas.getLayerID());
1045 // Store the index_ source link
1046 acts_examples::IndexSourceLink idx_sl(hit_surface->geometryId(), imeas);
1047 Acts::SourceLink source_link = Acts::SourceLink(idx_sl);
1048
1049 auto emplace = measurement_index_map.try_emplace(
1050 source_link, measurement_index_map.size());
1051 measurements.push_back(emplace.first->second);
1052 }
1053
1054 measurements_per_track.push_back(std::move(measurements));
1055
1056 ++number_of_tracks;
1057 }
1058
1059 // Now we relate measurements to tracks
1060 for (std::size_t i_track = 0; i_track < number_of_tracks; ++i_track) {
1061 for (auto i_measurement : measurements_per_track[i_track]) {
1062 tracks_per_measurement[i_measurement].insert(i_track);
1063 }
1064 }
1065
1066 // Finally, we can accumulate the number of shared measurements per track
1067 shared_measurements_per_track = std::vector<std::size_t>(number_of_tracks, 0);
1068
1069 std::vector<std::vector<std::size_t>> shared_measurement_idxs_per_track;
1070 for (std::size_t i_track = 0; i_track < number_of_tracks; ++i_track) {
1071 std::vector<std::size_t> shared_measurement_idxs;
1072 for (auto i_measurement : measurements_per_track[i_track]) {
1073 if (tracks_per_measurement[i_measurement].size() > 1) {
1074 ++shared_measurements_per_track[i_track];
1075 shared_measurement_idxs.push_back(i_measurement);
1076 }
1077 }
1078 shared_measurement_idxs_per_track.push_back(shared_measurement_idxs);
1079 }
1080 return shared_measurement_idxs_per_track;
1081}

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

922 {
923 dumpobj_ = parameters.get<bool>("dumpobj", 0);
924 pionstates_ = parameters.get<int>("pionstates", 0);
925
926 bfield_ = parameters.get<double>("bfield", -1.5);
927 const_b_field_ = parameters.get<bool>("const_b_field", false);
928 field_map_ = parameters.get<std::string>("field_map");
929 propagator_step_size_ = parameters.get<double>("propagator_step_size", 200.);
930 propagator_max_steps_ = parameters.get<int>("propagator_maxSteps", 10000);
931 measurement_collection_ = parameters.get<std::string>(
932 "measurement_collection", "TaggerMeasurements");
933 outlier_pval_ = parameters.get<double>("outlier_pval_", 3.84);
934
935 debug_acts_ = parameters.get<bool>("debug_acts", false);
936
937 remove_stereo_ = parameters.get<bool>("remove_stereo", false);
938 use1_dmeasurements_ = parameters.get<bool>("use1Dmeasurements", true);
939 min_hits_ = parameters.get<int>("min_hits", 7);
940
941 // Ckf specific options
942 use_extrapolate_location_ =
943 parameters.get<bool>("use_extrapolate_location", true);
944 extrapolate_location_ =
945 parameters.get<std::vector<double>>("extrapolate_location", {0., 0., 0.});
946 use_seed_perigee_ = parameters.get<bool>("use_seed_perigee", false);
947
948 // seeds from the event
949 seed_coll_name_ = parameters.get<std::string>("seed_coll_name", "seedTracks");
950
951 sim_particles_event_passname_ =
952 parameters.get<std::string>("sim_particles_event_passname");
953
954 // output track collection
955 out_trk_collection_ =
956 parameters.get<std::string>("out_trk_collection", "Tracks");
957
958 // keep track on which system tracking is running
959 tagger_tracking_ = parameters.get<bool>("taggerTracking", true);
960
961 // BField Systematics
962 map_offset_ =
963 parameters.get<std::vector<double>>("map_offset_", {0., 0., 0.});
964
965 input_pass_name_ = parameters.get<std::string>("input_pass_name");
966} // 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 968 of file CKFProcessor.cxx.

972 {
973 std::unordered_multimap<Acts::GeometryIdentifier,
975 geo_id_sl_map;
976
977 ldmx_log(debug) << "The makeGeoIdSourceLinkMap has " << measurements.size()
978 << " measurements";
979
980 // Check the hits associated to the surfaces
981 for (unsigned int i_meas = 0; i_meas < measurements.size(); i_meas++) {
982 ldmx::Measurement meas = measurements.at(i_meas);
983 unsigned int layerid = meas.getLayerID();
984
985 const Acts::Surface* hit_surface = tg.getSurface(layerid);
986
987 if (hit_surface) {
988 // Transform the ldmx space point from global to local and store the
989 // information
990
991 acts_examples::IndexSourceLink idx_sl(hit_surface->geometryId(), i_meas);
992 // mg aug 2024 ... these don't print statements
993 // don't compile using v36 in Acts...figure out later
994 /*
995 ldmx_log(debug)
996 << "Insert measurement on surface located at::"
997 << hit_surface->transform(geometry_context()).translation();
998 ldmx_log(debug) << "and geoId::" << hit_surface->geometryId();
999
1000 ldmx_log(debug) << "Surface info::"
1001 << std::tie(*hit_surface, geometry_context());
1002 */
1003 geo_id_sl_map.insert(std::make_pair(hit_surface->geometryId(), idx_sl));
1004
1005 } else
1006 ldmx_log(debug) << getName() << "::HIT " << i_meas << " at layer_"
1007 << (measurements.at(i_meas)).getLayerID()
1008 << " is not associated to any surface?!";
1009 }
1010
1011 return geo_id_sl_map;
1012}
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 22 of file CKFProcessor.cxx.

22 {
23 profiling_map_["setup"] = 0.;
24 profiling_map_["hits"] = 0.;
25 profiling_map_["seeds"] = 0.;
26 profiling_map_["ckf_setup"] = 0.;
27 profiling_map_["ckf_run"] = 0.;
28 profiling_map_["result_loop"] = 0.;
29
30 // Initialize counters
31 nseeds_ = 0;
32 ntracks_ = 0;
33 eventnr_ = 0;
34
35 // Generate a constant magnetic field
36 Acts::Vector3 b_field(0., 0., bfield_ * Acts::UnitConstants::T);
37
38 // Setup a constant magnetic field
39 const auto const_b_field = std::make_shared<Acts::ConstantBField>(b_field);
40
41 // Define the target surface - be careful:
42 // x - downstream
43 // y - left (when looking along x)
44 // z - up
45 // Passing identity here means that your target surface is oriented in the
46 // same way
47 surf_rotation_ = Acts::RotationMatrix3::Zero();
48 // u direction along +Y
49 surf_rotation_(1, 0) = 1;
50 // v direction along +Z
51 surf_rotation_(2, 1) = 1;
52 // w direction along +X
53 surf_rotation_(0, 2) = 1;
54
55 Acts::Vector3 target_pos(0., 0., 0.);
56 Acts::Translation3 target_translation(target_pos);
57 Acts::Transform3 target_transform(target_translation * surf_rotation_);
58
59 // Unbounded surface
60 target_surface_ =
61 Acts::Surface::makeShared<Acts::PlaneSurface>(target_transform);
62
63 // Custom transformation of the interpolated bfield map
64 bool debug_transform = false;
65 auto transform_pos = [this, debug_transform](const Acts::Vector3& pos_) {
66 Acts::Vector3 rot_pos;
67 rot_pos(0) = pos_(1);
68 rot_pos(1) = pos_(2);
69 rot_pos(2) = pos_(0) + DIPOLE_OFFSET;
70
71 // Systematic effect
72 rot_pos(0) += this->map_offset_[0];
73 rot_pos(1) += this->map_offset_[1];
74 rot_pos(2) += this->map_offset_[2];
75
76 // Apply A rotation around the center of the magnet. (I guess offset first
77 // and then rotation)
78
79 if (debug_transform) {
80 std::cout << "PF::DEFAULT3 TRANSFORM" << std::endl;
81 std::cout << "PF::Check:: transforming Pos" << std::endl;
82 std::cout << pos_ << std::endl;
83 std::cout << "TO" << std::endl;
84 std::cout << rot_pos << std::endl;
85 }
86
87 return rot_pos;
88 };
89
90 Acts::RotationMatrix3 rotation = Acts::RotationMatrix3::Identity();
91 double scale = 1.;
92
93 auto transform_b_field = [rotation, scale, debug_transform](
94 const Acts::Vector3& field,
95 const Acts::Vector3& /*pos_*/) {
96 // Rotate the field in tracking coordinates
97 Acts::Vector3 rot_field;
98 rot_field(0) = field(2);
99 rot_field(1) = field(0);
100 rot_field(2) = field(1);
101
102 // Scale the field
103 rot_field = scale * rot_field;
104
105 // Rotate the field
106 rot_field = rotation * rot_field;
107
108 // A distortion scaled by position.
109 if (debug_transform) {
110 std::cout << "PF::DEFAULT3 TRANSFORM" << std::endl;
111 std::cout << "PF::Check:: transforming" << std::endl;
112 std::cout << field << std::endl;
113 std::cout << "TO" << std::endl;
114 std::cout << rot_field << std::endl;
115 }
116
117 return rot_field;
118 };
119
120 // Setup a interpolated bfield map
121 const auto map = std::make_shared<InterpolatedMagneticField3>(
122 loadDefaultBField(field_map_,
123 // default_transformPos,
124 // default_transformBField));
125 transform_pos, transform_b_field));
126
127 auto acts_logging_level = Acts::Logging::FATAL;
128 if (debug_acts_) acts_logging_level = Acts::Logging::VERBOSE;
129
130 // Setup the steppers
131 const auto stepper = Acts::EigenStepper<>{map};
132 const auto const_stepper = Acts::EigenStepper<>{const_b_field};
133 const auto multi_stepper = Acts::MultiEigenStepperLoop{map};
134
135 // Setup the navigator
136 Acts::Navigator::Config nav_cfg{geometry().getTG()};
137 nav_cfg.resolveMaterial = true;
138 nav_cfg.resolvePassive = true;
139 nav_cfg.resolveSensitive = true;
140 const Acts::Navigator navigator(nav_cfg);
141
142 propagator_ = std::make_unique<CkfPropagator>(
143 stepper, navigator,
144 Acts::getDefaultLogger("CKF_PROP", acts_logging_level));
145
146 // Setup the finder / fitters
147 ckf_ = std::make_unique<std::decay_t<decltype(*ckf_)>>(
148 *propagator_, Acts::getDefaultLogger("CKF", acts_logging_level));
149 trk_extrap_ = std::make_shared<std::decay_t<decltype(*trk_extrap_)>>(
150 *propagator_, geometryContext(), magneticFieldContext());
151
152 // Setup zero-B CKF as fallback
153 Acts::ConstantBField zero_b_field(Acts::Vector3(0., 0., 0.));
154 const auto zero_b_stepper = Acts::EigenStepper<>{
155 std::make_shared<Acts::ConstantBField>(zero_b_field)};
156 propagator_zero_b_ =
157 std::make_unique<CkfPropagator>(zero_b_stepper, navigator);
158 ckf_zero_b_ = std::make_unique<std::decay_t<decltype(*ckf_zero_b_)>>(
159 *propagator_zero_b_,
160 Acts::getDefaultLogger("CKF_ZERO_B", acts_logging_level));
161 trk_extrap_zero_b_ =
162 std::make_shared<std::decay_t<decltype(*trk_extrap_zero_b_)>>(
163 *propagator_zero_b_, geometryContext(), magneticFieldContext());
164
165 // Setup const-B (1.5T) CKF as fallback for tagger
166 propagator_const_b_ =
167 std::make_unique<CkfPropagator>(const_stepper, navigator);
168 ckf_const_b_ = std::make_unique<std::decay_t<decltype(*ckf_const_b_)>>(
169 *propagator_const_b_,
170 Acts::getDefaultLogger("CKF_CONST_B", acts_logging_level));
171 trk_extrap_const_b_ =
172 std::make_shared<std::decay_t<decltype(*trk_extrap_const_b_)>>(
173 *propagator_const_b_, geometryContext(), magneticFieldContext());
174} // 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 836 of file CKFProcessor.cxx.

836 {
837 ldmx_log(info) << "--------------------------------- ";
838 ldmx_log(info) << "Found " << ntracks_ << " tracks / " << nseeds_
839 << " nseeds";
840 ldmx_log(info) << "AVG Time/Event: " << std::fixed << std::setprecision(1)
841 << processing_time_ / nevents_ << " ms";
842 ldmx_log(info) << "Breakdown::";
843 ldmx_log(info) << " setup Avg Time/Event = " << std::fixed
844 << std::setprecision(3) << profiling_map_["setup"] / nevents_
845 << " ms";
846 ldmx_log(info) << " hits Avg Time/Event = " << std::fixed
847 << std::setprecision(2) << profiling_map_["hits"] / nevents_
848 << " ms";
849 ldmx_log(info) << " seeds Avg Time/Event = " << std::fixed
850 << std::setprecision(3) << profiling_map_["seeds"] / nevents_
851 << " ms";
852 ldmx_log(info) << " ckf_setup Avg Time/Event = " << std::fixed
853 << std::setprecision(3)
854 << profiling_map_["ckf_setup"] / nevents_ << " ms";
855 ldmx_log(info) << " ckf_run Avg Time/Event = " << std::fixed
856 << std::setprecision(3) << profiling_map_["ckf_run"] / nevents_
857 << " ms";
858 ldmx_log(info) << " result_loop Avg Time/Event = " << std::fixed
859 << std::setprecision(1)
860 << profiling_map_["result_loop"] / nevents_ << " ms";
861
862 // CKF fallback statistics
863 ldmx_log(info) << "CKF Fallback Statistics::";
864 if (tagger_tracking_) {
865 ldmx_log(info) << " Tagger: Field-map CKF failed "
866 << n_fieldmap_ckf_failed_tagger_
867 << " times, const-B CKF recovered "
868 << n_constb_ckf_recovered_tagger_ << " ("
869 << (n_fieldmap_ckf_failed_tagger_ > 0
870 ? 100.0 * n_constb_ckf_recovered_tagger_ /
871 n_fieldmap_ckf_failed_tagger_
872 : 0.0)
873 << "%)";
874
875 // Extrapolation fallback statistics for tagger
876 ldmx_log(info) << "Extrapolation Fallback Statistics::";
877 ldmx_log(info) << " Tagger Target: Field-map extrap failed "
878 << n_fieldmap_target_extrap_failed_tagger_
879 << " times, const-B extrap recovered "
880 << n_constb_target_extrap_recovered_tagger_ << " ("
881 << (n_fieldmap_target_extrap_failed_tagger_ > 0
882 ? 100.0 * n_constb_target_extrap_recovered_tagger_ /
883 n_fieldmap_target_extrap_failed_tagger_
884 : 0.0)
885 << "%)";
886 }
887
888 if (!tagger_tracking_) {
889 ldmx_log(info) << " Recoil: Field-map CKF failed "
890 << n_fieldmap_ckf_failed_recoil_
891 << " times, zero-B CKF recovered "
892 << n_zerob_ckf_recovered_recoil_ << " ("
893 << (n_fieldmap_ckf_failed_recoil_ > 0
894 ? 100.0 * n_zerob_ckf_recovered_recoil_ /
895 n_fieldmap_ckf_failed_recoil_
896 : 0.0)
897 << "%)";
898
899 // Extrapolation fallback statistics
900 ldmx_log(info) << "Extrapolation Fallback Statistics::";
901 ldmx_log(info) << " Recoil Target: Field-map extrap failed "
902 << n_fieldmap_target_extrap_failed_recoil_
903 << " times, zero-B extrap recovered "
904 << n_zerob_target_extrap_recovered_recoil_ << " ("
905 << (n_fieldmap_target_extrap_failed_recoil_ > 0
906 ? 100.0 * n_zerob_target_extrap_recovered_recoil_ /
907 n_fieldmap_target_extrap_failed_recoil_
908 : 0.0)
909 << "%)";
910 ldmx_log(info) << " Recoil ECAL: Field-map extrap failed "
911 << n_fieldmap_ecal_extrap_failed_recoil_
912 << " times, zero-B extrap recovered "
913 << n_zerob_ecal_extrap_recovered_recoil_ << " ("
914 << (n_fieldmap_ecal_extrap_failed_recoil_ > 0
915 ? 100.0 * n_zerob_ecal_extrap_recovered_recoil_ /
916 n_fieldmap_ecal_extrap_failed_recoil_
917 : 0.0)
918 << "%)";
919 }
920}

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

828 {
829 if (use1_dmeasurements_)
830 ldmx_log(debug) << "Use1Dmeasurements = " << std::boolalpha
831 << use1_dmeasurements_;
832 if (remove_stereo_)
833 ldmx_log(debug) << "Remove_stereo = " << std::boolalpha << remove_stereo_;
834}

◆ produce()

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

Run the processor.

Parameters
eventThe event to process.

Implements framework::Producer.

Definition at line 176 of file CKFProcessor.cxx.

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

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_event_passname_

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

Definition at line 197 of file CKFProcessor.h.

◆ sim_particles_pass_name_

std::string tracking::reco::CKFProcessor::sim_particles_pass_name_
private

Definition at line 196 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: