LDMX Software
LinearTrackFinder.cxx
1#include "Tracking/Reco/LinearTrackFinder.h"
2
3//--- C++ StdLib ---//
4#include <algorithm>
5#include <iostream>
6#include <map>
7#include <typeinfo>
8
9// eN files
10#include <fstream>
11
12namespace tracking {
13namespace reco {
14
16 framework::Process& process)
17 : TrackingGeometryUser(name, process) {}
18
20 // seeds from the event
21 seed_collection_ =
22 parameters.get<std::string>("seed_collection", "LinearRecoilSeedTracks");
23 // output track collection
24 out_trk_collection_ =
25 parameters.get<std::string>("out_trk_collection", "LinearRecoilTracks");
26
27 input_pass_name_ = parameters.get<std::string>("input_pass_name");
28
29} // configure
30
32 std::vector<ldmx::StraightTrack> straight_tracks;
33
34 auto start = std::chrono::high_resolution_clock::now();
35
36 n_events_++;
37 if (n_events_ % 1000 == 0) ldmx_log(info) << "events processed:" << n_events_;
38
39 ldmx_log(debug) << "Retrieve the seeds::" << seed_collection_;
40
41 const std::vector<ldmx::StraightTrack> seed_tracks =
42 event.getCollection<ldmx::StraightTrack>(seed_collection_,
43 input_pass_name_);
44
45 n_seeds_ = seed_tracks.size();
46 ldmx_log(debug) << "Number of seeds::" << n_seeds_;
47
48 if (n_seeds_ > 0) {
49 straight_tracks = findTracks(seed_tracks);
50 }
51
52 n_tracks_ += straight_tracks.size();
53
54 // Add the tracks to the event
55 event.add(out_trk_collection_, straight_tracks);
56
57 auto end = std::chrono::high_resolution_clock::now();
58 auto diff = end - start;
59 processing_time_ += std::chrono::duration<double, std::milli>(diff).count();
60
61 straight_tracks.clear();
62} // produce
63
65 ldmx_log(info) << "found " << n_tracks_ << " tracks / " << n_events_
66 << " events.";
67 ldmx_log(info) << "AVG Time/Event: " << std::fixed << std::setprecision(1)
68 << processing_time_ / n_events_ << " ms";
69} // onProcessEnd
70
71std::vector<ldmx::StraightTrack> LinearTrackFinder::findTracks(
72 const std::vector<ldmx::StraightTrack>& track_seeds) {
73 std::vector<ldmx::StraightTrack> best_tracks;
74 std::map<std::array<double, 3>, std::vector<ldmx::StraightTrack>>
75 seeds_by_rec_hit;
76
77 // Group seeds by their EcalRecHit point
78 for (const auto& seed : track_seeds) {
79 auto rec_hit_point = seed.getFirstLayerEcalRecHit();
80 seeds_by_rec_hit[rec_hit_point].push_back(seed);
81 }
82
83 // Track used sensor positions
84 std::set<std::tuple<float, float, float>> used_sensor_positions;
85
86 // Find the best seed for each RecHit
87 // numTracks <= number of RecHits
88 for (auto& entry : seeds_by_rec_hit) {
89 const auto& rec_hit_point = entry.first;
90 auto& seeds_with_same_rec_hit = entry.second;
91
92 ldmx_log(debug) << "Processing RecHit at: (" << rec_hit_point[0] << ", "
93 << rec_hit_point[1] << ", " << rec_hit_point[2] << ")\n";
94
95 // Main function to remove seeds with overlapping sensor positions
96 seeds_with_same_rec_hit.erase(
97 std::remove_if(
98 seeds_with_same_rec_hit.begin(), seeds_with_same_rec_hit.end(),
99 [&](const ldmx::StraightTrack& seed) {
100 for (const auto& measurement : seed.getAllSensorPoints()) {
101 // Check if this sensor's position is already used
102 if (isPositionUsed(measurement, used_sensor_positions)) {
103 // Mark this seed for removal
104 return true;
105 } // ifPositionUsed
106 } // for measurement
107 // Keep the seed if no position overlap
108 return false;
109 }),
110 seeds_with_same_rec_hit.end());
111
112 // If no valid seeds remain after filtering, skip to next RecHit
113 if (seeds_with_same_rec_hit.empty()) continue;
114
115 // Find the seed with the lowest chi2 for this RecHit, this is "best" seed
116 auto best_seed_it = std::min_element(
117 seeds_with_same_rec_hit.begin(), seeds_with_same_rec_hit.end(),
118 [](const ldmx::StraightTrack& trk_a, const ldmx::StraightTrack& trk_b) {
119 return trk_a.getChi2() < trk_b.getChi2();
120 });
121
122 // Store the best seed for this RecHit
123 ldmx::StraightTrack best_seed = *best_seed_it;
124 best_tracks.push_back(best_seed);
125
126 ldmx_log(debug) << "For RecHit at: (" << rec_hit_point[0] << ", "
127 << rec_hit_point[1] << ", " << rec_hit_point[2] << ")\n";
128
129 // Add best seed's sensor position to the global used positions set
130 auto best_seed_measurement = best_seed.getAllSensorPoints();
131
132 for (auto& position_object : best_seed_measurement) {
133 used_sensor_positions.insert(
134 std::make_tuple(position_object.getGlobalPosition()[0],
135 position_object.getGlobalPosition()[1],
136 position_object.getGlobalPosition()[2]));
137 ldmx_log(debug) << "We used the following point: ("
138 << position_object.getGlobalPosition()[0] << ", "
139 << position_object.getGlobalPosition()[1] << ", "
140 << position_object.getGlobalPosition()[2] << ")\n";
141 ldmx_log(debug) << "Which gave a track a distance: "
142 << best_seed.getDistanceToRecHit()
143 << " to the closest ECalRecHit\n";
144 } // for sensor points in "best" seed
145
146 } // for entry loop, everytime we loop onto a new RecHit, we will have fewer
147 // points to check
148
149 return best_tracks;
150
151} // findTracks
152
153bool LinearTrackFinder::isPositionUsed(
154 const ldmx::Measurement& measurement,
155 const std::set<std::tuple<float, float, float>>& used_sensor_positions) {
156 const auto& position = std::make_tuple(measurement.getGlobalPosition()[0],
157 measurement.getGlobalPosition()[1],
158 measurement.getGlobalPosition()[2]);
159
160 return used_sensor_positions.find(position) != used_sensor_positions.end();
161
162} // isPositionUsed
163
164} // namespace reco
165} // namespace tracking
166
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Implements an event buffer system for storing event data.
Definition Event.h:42
Class which represents the process under execution.
Definition Process.h:36
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:29
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
std::array< float, 3 > getGlobalPosition() const
Definition Measurement.h:48
void onProcessEnd() override
Output event statistics.
LinearTrackFinder(const std::string &name, framework::Process &process)
Constructor.
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.
a helper base class providing some methods to shorten access to common conditions used within the tra...
The measurement calibrator can be a function or a class/struct able to retrieve the sim hits containe...