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 auto& seed_tracks = event.getCollection<ldmx::StraightTrack>(
42 seed_collection_, input_pass_name_);
43
44 n_seeds_ = seed_tracks.size();
45 ldmx_log(debug) << "Number of seeds::" << n_seeds_;
46
47 if (n_seeds_ > 0) {
48 straight_tracks = findTracks(seed_tracks);
49 }
50
51 n_tracks_ += straight_tracks.size();
52
53 // Add the tracks to the event
54 event.add(out_trk_collection_, straight_tracks);
55
56 auto end = std::chrono::high_resolution_clock::now();
57 auto diff = end - start;
58 processing_time_ += std::chrono::duration<double, std::milli>(diff).count();
59
60 straight_tracks.clear();
61} // produce
62
64 ldmx_log(info) << "found " << n_tracks_ << " tracks / " << n_events_
65 << " events.";
66 ldmx_log(info) << "AVG Time/Event: " << std::fixed << std::setprecision(1)
67 << processing_time_ / n_events_ << " ms";
68} // onProcessEnd
69
70std::vector<ldmx::StraightTrack> LinearTrackFinder::findTracks(
71 const std::vector<ldmx::StraightTrack>& track_seeds) {
72 std::vector<ldmx::StraightTrack> best_tracks;
73 std::map<std::array<double, 3>, std::vector<ldmx::StraightTrack>>
74 seeds_by_rec_hit;
75
76 // Group seeds by their EcalRecHit point
77 for (const auto& seed : track_seeds) {
78 auto rec_hit_point = seed.getFirstLayerEcalRecHit();
79 seeds_by_rec_hit[rec_hit_point].push_back(seed);
80 }
81
82 // Track used sensor positions
83 std::set<std::tuple<float, float, float>> used_sensor_positions;
84
85 // Find the best seed for each RecHit
86 // numTracks <= number of RecHits
87 for (auto& entry : seeds_by_rec_hit) {
88 const auto& rec_hit_point = entry.first;
89 auto& seeds_with_same_rec_hit = entry.second;
90
91 ldmx_log(debug) << "Processing RecHit at: (" << rec_hit_point[0] << ", "
92 << rec_hit_point[1] << ", " << rec_hit_point[2] << ")\n";
93
94 // Main function to remove seeds with overlapping sensor positions
95 seeds_with_same_rec_hit.erase(
96 std::remove_if(
97 seeds_with_same_rec_hit.begin(), seeds_with_same_rec_hit.end(),
98 [&](const ldmx::StraightTrack& seed) {
99 for (const auto& measurement : seed.getAllSensorPoints()) {
100 // Check if this sensor's position is already used
101 if (isPositionUsed(measurement, used_sensor_positions)) {
102 // Mark this seed for removal
103 return true;
104 } // ifPositionUsed
105 } // for measurement
106 // Keep the seed if no position overlap
107 return false;
108 }),
109 seeds_with_same_rec_hit.end());
110
111 // If no valid seeds remain after filtering, skip to next RecHit
112 if (seeds_with_same_rec_hit.empty()) continue;
113
114 // Find the seed with the lowest chi2 for this RecHit, this is "best" seed
115 auto best_seed_it = std::min_element(
116 seeds_with_same_rec_hit.begin(), seeds_with_same_rec_hit.end(),
117 [](const ldmx::StraightTrack& trk_a, const ldmx::StraightTrack& trk_b) {
118 return trk_a.getChi2() < trk_b.getChi2();
119 });
120
121 // Store the best seed for this RecHit
122 ldmx::StraightTrack best_seed = *best_seed_it;
123 best_tracks.push_back(best_seed);
124
125 ldmx_log(debug) << "For RecHit at: (" << rec_hit_point[0] << ", "
126 << rec_hit_point[1] << ", " << rec_hit_point[2] << ")\n";
127
128 // Add best seed's sensor position to the global used positions set
129 auto best_seed_measurement = best_seed.getAllSensorPoints();
130
131 for (auto& position_object : best_seed_measurement) {
132 used_sensor_positions.insert(
133 std::make_tuple(position_object.getGlobalPosition()[0],
134 position_object.getGlobalPosition()[1],
135 position_object.getGlobalPosition()[2]));
136 ldmx_log(debug) << "We used the following point: ("
137 << position_object.getGlobalPosition()[0] << ", "
138 << position_object.getGlobalPosition()[1] << ", "
139 << position_object.getGlobalPosition()[2] << ")\n";
140 ldmx_log(debug) << "Which gave a track a distance: "
141 << best_seed.getDistanceToRecHit()
142 << " to the closest ECalRecHit\n";
143 } // for sensor points in "best" seed
144
145 } // for entry loop, everytime we loop onto a new RecHit, we will have fewer
146 // points to check
147
148 return best_tracks;
149
150} // findTracks
151
152bool LinearTrackFinder::isPositionUsed(
153 const ldmx::Measurement& measurement,
154 const std::set<std::tuple<float, float, float>>& used_sensor_positions) {
155 const auto& position = std::make_tuple(measurement.getGlobalPosition()[0],
156 measurement.getGlobalPosition()[1],
157 measurement.getGlobalPosition()[2]);
158
159 return used_sensor_positions.find(position) != used_sensor_positions.end();
160
161} // isPositionUsed
162
163} // namespace reco
164} // namespace tracking
165
#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:37
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:49
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...