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