LDMX Software
SeedFinderProcessor.cxx
1#include "Tracking/Reco/SeedFinderProcessor.h"
2
3#include "Acts/Definitions/TrackParametrization.hpp"
4#include "Acts/Seeding/EstimateTrackParamsFromSeed.hpp"
5#include "Eigen/Dense"
6#include "Tracking/Sim/TrackingUtils.h"
7
8/* This processor takes in input a set of 3D space points and builds seedTracks
9 * using the ACTS algorithm which is based on the ATLAS 3-space point conformal
10 * fit.
11 *
12 */
13
14using Eigen::MatrixXd;
15using Eigen::VectorXd;
16
17namespace tracking {
18namespace reco {
19
21 framework::Process& process)
22 : TrackingGeometryUser(name, process) {
23 // TODO REMOVE FROM DEFAULT
24 /*
25 output_file_ = new TFile("seeder.root", "RECREATE");
26 output_tree_ = new TTree("seeder", "seeder");
27
28 output_tree_->Branch("nevents", &nevents_);
29 output_tree_->Branch("xhit", &xhit_);
30 output_tree_->Branch("yhit", &yhit_);
31 output_tree_->Branch("zhit", &zhit_);
32
33 output_tree_->Branch("b0", &b0_);
34 output_tree_->Branch("b1", &b1_);
35 output_tree_->Branch("b2", &b2_);
36 output_tree_->Branch("b3", &b3_);
37 output_tree_->Branch("b4", &b4_);
38 */
39}
40
42 truth_matching_tool_ = std::make_shared<tracking::sim::TruthMatchingTool>();
43}
44
46 // Output seed name
47 out_seed_collection_ = parameters.get<std::string>("out_seed_collection",
48 getName() + "SeedTracks");
49
50 // Input strip hits
52 parameters.get<std::string>("input_hits_collection", "TaggerSimHits");
53
54 // Tagger tracks - only for Recoil Seed finding
56 parameters.get<std::string>("tagger_trks_collection", "TaggerTracks");
57
59 parameters.get<std::vector<double>>("perigee_location", {-700, 0., 0.});
60 pmin_ = parameters.get<double>("pmin", 0.05 * Acts::UnitConstants::GeV);
61 pmax_ = parameters.get<double>("pmax", 8 * Acts::UnitConstants::GeV);
62 d0max_ = parameters.get<double>("d0max", -15. * Acts::UnitConstants::mm);
63 d0min_ = parameters.get<double>("d0min", -45. * Acts::UnitConstants::mm);
64 z0max_ = parameters.get<double>("z0max", 60. * Acts::UnitConstants::mm);
65 phicut_ = parameters.get<double>("phicut", 0.1);
66 thetacut_ = parameters.get<double>("thetacut", 0.2);
67 loc0cut_ = parameters.get<double>("loc0cut", 0.1);
68 loc1cut_ = parameters.get<double>("loc1cut", 0.3);
70 parameters.get<std::vector<std::string>>("strategies", {"0,1,2,3,4"});
71 inflate_factors_ = parameters.get<std::vector<double>>(
72 "inflate_factors", {10., 10., 10., 10., 10., 10.});
73 bfield_ = parameters.get<double>("bfield", 1.5);
74 input_pass_name_ = parameters.get<std::string>("input_pass_name");
75 sim_particles_coll_name_ =
76 parameters.get<std::string>("sim_particles_coll_name");
77 sim_particles_passname_ =
78 parameters.get<std::string>("sim_particles_passname");
79 tagger_trks_event_collection_passname_ =
80 parameters.get<std::string>("tagger_trks_event_collection_passname");
81 sim_particles_event_passname_ =
82 parameters.get<std::string>("sim_particles_event_passname");
83 u_error_ = parameters.get<double>("u_error");
84 v_error_ = parameters.get<double>("v_error");
85}
86
88 // tg is unused, should it be? FIXME
89 // const auto& tg{geometry()};
90 auto start = std::chrono::high_resolution_clock::now();
91 std::vector<ldmx::Track> seed_tracks;
92
93 nevents_++;
94
95 // check if SimParticleMap is available for truth matching
96 std::map<int, ldmx::SimParticle> particle_map;
97
98 const std::vector<ldmx::Measurement> measurements =
99 event.getCollection<ldmx::Measurement>(input_hits_collection_,
100 input_pass_name_);
101
102 std::vector<ldmx::Track> tagger_tracks;
104 tagger_trks_event_collection_passname_)) {
105 tagger_tracks = event.getCollection<ldmx::Track>(tagger_trks_collection_,
106 input_pass_name_);
107 }
108
109 // Create an unbound surface at the target
110 std::shared_ptr<Acts::Surface> tgt_surf =
111 tracking::sim::utils::unboundSurface(0.);
112
113 // Create the pseudomeasurements at the target
114
115 ldmx::Measurements target_pseudo_meas;
116
117 for (auto tagtrk : tagger_tracks) {
118 // For Track, the perigee parameters are stored at the target surface.
119 // Use d0/z0 as local position and the perigee covariance for the
120 // pseudo measurement. Only create the pseudo measurement if cov is
121 // available.
122
123 // The covariance matrix passed to the pseudo measurement is considered as
124 // uncorrelated. This is an approx that considers that loc-u and loc-v from
125 // the track have small correlation.
126
127 const auto& perigee_cov = tagtrk.getPerigeeCov();
128 if (!perigee_cov.empty()) {
129 Acts::BoundSquareMatrix cov =
130 tracking::sim::utils::unpackCov(perigee_cov);
131 double locu = tagtrk.getD0();
132 double locv = tagtrk.getZ0();
133 double covuu =
134 cov(Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc0);
135 double covvv =
136 cov(Acts::BoundIndices::eBoundLoc1, Acts::BoundIndices::eBoundLoc1);
137
138 ldmx::Measurement pseudo_meas;
139 pseudo_meas.setLocalPosition(locu, locv);
140 Acts::Vector3 dummy{0., 0., 0.};
141 Acts::Vector2 local_pos{locu, locv};
142 Acts::Vector3 global_pos =
143 tgt_surf->localToGlobal(geometryContext(), local_pos, dummy);
144
145 pseudo_meas.setGlobalPosition(global_pos(0), global_pos(1),
146 global_pos(2));
147 pseudo_meas.setTime(0.);
148 pseudo_meas.setLocalCovariance(covuu, covvv);
149
150 target_pseudo_meas.push_back(pseudo_meas);
151 }
152 }
153
154 if (event.exists(sim_particles_coll_name_, sim_particles_event_passname_)) {
155 particle_map = event.getMap<int, ldmx::SimParticle>(
156 sim_particles_coll_name_, sim_particles_passname_);
157 truth_matching_tool_->setup(particle_map, measurements);
158 }
159
160 ldmx_log(debug) << "Preparing the strategies";
161
162 groups_map_.clear();
163 // set the seeding strategy
164 // strategy is a list of layers from which to make the seed
165 // this must include 5 layers; layer_ numbering starts at 0.
166 // std::vector<int> strategy = {9,10,11,12,13};
167 std::vector<int> strategy = {0, 1, 2, 3, 4};
168 bool success = groupStrips(measurements, strategy);
169 if (success) findSeedsFromMap(seed_tracks, target_pseudo_meas);
170
171 // currently, we only use a single strategy but eventually
172 // we will use more. Below is an example of how to add them
173 /*
174 groups_map.clear();
175 strategy = {9,10,11,12,13};
176 success = GroupStrips(measurements,strategy);
177 if (success)
178 FindSeedsFromMap(seed_tracks, target_pseudo_meas);
179 */
180
181 groups_map_.clear();
182 // output_tree_->Fill();
183 ntracks_ += seed_tracks.size();
184 event.add(out_seed_collection_, seed_tracks);
185
186 auto end = std::chrono::high_resolution_clock::now();
187
188 // long long microseconds =
189 // std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
190
191 auto diff = end - start;
192 processing_time_ += std::chrono::duration<double, std::milli>(diff).count();
193
194 // Seed finding using 2D Hits
195 // - The hits should keep track if they are already associated to a track or
196 // not. This can be used for subsequent passes of seed-finding
197
198 // This should go into a digitization producer, which takes care of producing
199 // measurements from:
200 // - raw hits in data
201 // - sim hits in MC
202 // Step 0: Get the sim hits and project them on the surfaces to mimic 2d
203 // hits Step 1: Smear the hits and associate an uncertainty to those
204 // measurements.
205
206 xhit_.clear();
207 yhit_.clear();
208 zhit_.clear();
209
210 b0_.clear();
211 b1_.clear();
212 b2_.clear();
213 b3_.clear();
214 b4_.clear();
215
216} // produce
217
218// Seed finder from Robert's in HPS
219// https://github.com/JeffersonLab/hps-java/blob/47712878302eb0c0374d077a208a6f8f0e2c3dc6/tracking/src/main/java/org/hps/recon/tracking/kalman/SeedTrack.java
220// Adapted to possible 3D hit points.
221
222// yOrigin is the location along the beam about which we fit the seed helix
223// perigee_location is where the track parameters will be extracted
224
225// while this takes in a target measurement (from tagger, this is pmeas_tgt)
226// this code doesn't do anything with it yet.
227
228ldmx::Track SeedFinderProcessor::seedTracker(
229 const ldmx::Measurements& vmeas, double xOrigin,
230 const Acts::Vector3& perigee_location,
231 const ldmx::Measurements& pmeas_tgt) {
232 // Fit a straight line in the non-bending plane and a parabola in the bending
233 // plane
234
235 // Each measurement is treated as a 3D point, where the v direction is in the
236 // center of the strip with sigma equal to the length of the strip / sqrt(12).
237 // In this way it's easier to incorporate the tagger track extrapolation to
238 // the fit
239
240 Acts::ActsMatrix<5, 5> a = Acts::ActsMatrix<5, 5>::Zero();
241 Acts::ActsVector<5> y = Acts::ActsVector<5>::Zero();
242
243 for (auto meas : vmeas) {
244 double xmeas = meas.getGlobalPosition()[0] - xOrigin;
245
246 // Get the surface
247 const Acts::Surface* hit_surface = geometry().getSurface(meas.getLayerID());
248
249 // Get the global to local transformation
250 auto rot = hit_surface->transform(geometryContext()).rotation();
251 auto tr = hit_surface->transform(geometryContext()).translation();
252
253 auto rotl2g = rot.transpose();
254
255 // Only for saving purposes
256 Acts::Vector2 loc{meas.getLocalPosition()[0], 0.};
257
258 xhit_.push_back(xmeas);
259 yhit_.push_back(meas.getGlobalPosition()[1]);
260 zhit_.push_back(meas.getGlobalPosition()[2]);
261
262 Acts::ActsMatrix<2, 5> a_i;
263
264 a_i(0, 0) = rotl2g(0, 1);
265 a_i(0, 1) = rotl2g(0, 1) * xmeas;
266 a_i(0, 2) = rotl2g(0, 1) * xmeas * xmeas;
267 a_i(0, 3) = rotl2g(0, 2);
268 a_i(0, 4) = rotl2g(0, 2) * xmeas;
269
270 a_i(1, 0) = rotl2g(1, 1);
271 a_i(1, 1) = rotl2g(1, 1) * xmeas;
272 a_i(1, 2) = rotl2g(1, 1) * xmeas * xmeas;
273 a_i(1, 3) = rotl2g(1, 2);
274 a_i(1, 4) = rotl2g(1, 2) * xmeas;
275
276 // Fill the yprime vector
277 Acts::Vector2 offset = (rot.transpose() * tr).topRows<2>();
278 Acts::Vector2 xoffset = {rotl2g(0, 0) * xmeas, rotl2g(1, 0) * xmeas};
279
280 loc(0) = meas.getLocalPosition()[0];
281 loc(1) = 0.;
282 // weight matrix
283 Acts::ActsMatrix<2, 2> w_i = Acts::ActsMatrix<2, 2>::Zero();
284
285 w_i(0, 0) = 1. / (u_error_ * u_error_);
286 w_i(1, 1) = 1. / (v_error_ * v_error_);
287
288 Acts::Vector2 yprime_i = loc + offset - xoffset;
289 y += (a_i.transpose()) * w_i * yprime_i;
290
291 Acts::ActsMatrix<2, 5> wa_i = (w_i * a_i);
292 a += a_i.transpose() * wa_i;
293 }
294
295 Acts::ActsVector<5> b;
296 b = a.inverse() * y;
297
298 b0_.push_back(b(0));
299 b1_.push_back(b(1));
300 b2_.push_back(b(2));
301 b3_.push_back(b(3));
302 b4_.push_back(b(4));
303
304 // Acts::ActsVector<5> hlx = Acts::ActsVector<5>::Zero();
305 Acts::ActsVector<3> ref{0., 0., 0.};
306
307 double relative_perigee_x = perigee_location(0) - xOrigin;
308
309 std::shared_ptr<const Acts::PerigeeSurface> seed_perigee =
310 Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3(
311 relative_perigee_x, perigee_location(1), perigee_location(2)));
312
313 // in mm
314 Acts::Vector3 seed_pos{relative_perigee_x,
315 b(0) + b(1) * relative_perigee_x +
316 b(2) * relative_perigee_x * relative_perigee_x,
317 b(3) + b(4) * relative_perigee_x};
318 Acts::Vector3 dir{1, b(1) + 2 * b(2) * relative_perigee_x, b(4)};
319 dir /= dir.norm();
320
321 // Momentum at xmeas
322 // R in meters, p in GeV
323 double p = 0.3 * bfield_ * (1. / (2. * abs(b(2)))) * 0.001;
324 // std::cout<<"Momentum "<< p*dir << std::endl;
325
326 // Convert it to MeV since that's what TrackUtils assumes
327 Acts::Vector3 seed_mom = p * dir / Acts::UnitConstants::MeV;
328 Acts::ActsScalar q =
329 b(2) < 0 ? -1 * Acts::UnitConstants::e : +1 * Acts::UnitConstants::e;
330
331 // Linear intersection with the perigee line. TODO:: Use propagator instead
332 // Project the position on the surface.
333 // This is mainly necessary for the perigee surface, where
334 // the mean might not fulfill the perigee condition.
335
336 // mg Aug 2024 .. interect has changed, but just remove boundary check
337 // and change intersection to intersections
338 // auto intersection =
339 // (*seed_perigee).intersect(geometry_context(), seed_pos, dir, false);
340
341 // Acts::FreeVector seed_free = tracking::sim::utils::toFreeParameters(
342 // intersection.intersection.position, seed_mom, q);
343
344 auto intersection =
345 (*seed_perigee).intersect(geometryContext(), seed_pos, dir);
346
347 Acts::FreeVector seed_free = tracking::sim::utils::toFreeParameters(
348 intersection.intersections()[0].position(), seed_mom, q);
349
350 auto bound_params = Acts::transformFreeToBoundParameters(
351 seed_free, *seed_perigee, geometryContext())
352 .value();
353
354 ldmx_log(trace) << "bound parameters at perigee location" << bound_params;
355
356 Acts::BoundVector stddev;
357 // sigma set to 75% of momentum
358 double sigma_p = 0.75 * p * Acts::UnitConstants::GeV;
359 stddev[Acts::eBoundLoc0] =
360 inflate_factors_[Acts::eBoundLoc0] * 2 * Acts::UnitConstants::mm;
361 stddev[Acts::eBoundLoc1] =
362 inflate_factors_[Acts::eBoundLoc1] * 5 * Acts::UnitConstants::mm;
363 stddev[Acts::eBoundPhi] =
364 inflate_factors_[Acts::eBoundPhi] * 5 * Acts::UnitConstants::degree;
365 stddev[Acts::eBoundTheta] =
366 inflate_factors_[Acts::eBoundTheta] * 5 * Acts::UnitConstants::degree;
367 stddev[Acts::eBoundQOverP] =
368 inflate_factors_[Acts::eBoundQOverP] * (1. / p) * (1. / p) * sigma_p;
369 stddev[Acts::eBoundTime] =
370 inflate_factors_[Acts::eBoundTime] * 1000 * Acts::UnitConstants::ns;
371
372 ldmx_log(debug)
373 << "Making covariance matrix as diagonal matrix with inflated terms";
374 Acts::BoundSquareMatrix bound_cov = stddev.cwiseProduct(stddev).asDiagonal();
375
376 ldmx_log(debug) << "...now putting together the seed track ...";
377
378 ldmx::Track trk = ldmx::Track();
379 Acts::Vector3 perigee_ldmx =
380 tracking::sim::utils::acts2Ldmx(perigee_location);
381 trk.setPerigeeLocation(perigee_ldmx(0), perigee_ldmx(1), perigee_ldmx(2));
382 trk.setChi2(0.);
383 trk.setNhits(5);
384 trk.setNdf(0);
385 trk.setNsharedHits(0);
386 trk.setCharge(q < 0 ? -1 : 1);
387 std::vector<double> v_seed_params(
388 (bound_params).data(),
389 bound_params.data() + bound_params.rows() * bound_params.cols());
390 std::vector<double> v_seed_cov;
391 tracking::sim::utils::flatCov(bound_cov, v_seed_cov);
392 trk.setPerigeeParameters(v_seed_params);
393 trk.setPerigeeCov(v_seed_cov);
394
395 ldmx_log(debug)
396 << "...making the ParticleHypothesis ...assume electron for now";
397 auto part_hypo{Acts::SinglyChargedParticleHypothesis::electron()};
398
399 ldmx_log(debug) << "Making BoundTrackParameters seedParameters";
400 Acts::BoundTrackParameters seed_parameters(
401 seed_perigee, std::move(bound_params), bound_cov, part_hypo);
402
403 ldmx_log(debug) << "Returning seed track";
404 return trk;
405}
406
408 // output_file_->cd();
409 // output_tree_->Write();
410 // output_file_->Close();
411 ldmx_log(info) << "AVG Time/Event: " << std::fixed << std::setprecision(1)
412 << processing_time_ / nevents_ << " ms";
413 ldmx_log(info) << "Total Seeds/Events: " << ntracks_ << "/" << nevents_;
414 ldmx_log(info) << "Seeds discarded due to multiple hits on layers "
415 << ndoubles_;
416 ldmx_log(info) << "not enough seed points " << nmissing_;
417 ldmx_log(info) << " nfailpmin=" << nfailpmin_;
418 ldmx_log(info) << " nfailpmax=" << nfailpmax_;
419 ldmx_log(info) << " nfaild0max=" << nfaild0max_;
420 ldmx_log(info) << " nfaild0min=" << nfaild0min_;
421 ldmx_log(info) << " nfailphicut=" << nfailphi_;
422 ldmx_log(info) << " nfailthetacut=" << nfailtheta_;
423 ldmx_log(info) << " nfailz0max=" << nfailz0max_;
424}
425
426// Given a strategy, group the hits according to some options
427// Not a good algorithm. The best would be to organize all the hits in sensors
428// *first* then only select the hits that we are interested into. TODO!
429
430bool SeedFinderProcessor::groupStrips(
431 const std::vector<ldmx::Measurement>& measurements,
432 const std::vector<int> strategy) {
433 // std::cout<<"Using stratedy"<<std::endl;
434 // for (auto& e : strategy) {
435 // std::cout<<e<<" ";
436 //}
437 // std::cout<<std::endl;
438
439 for (auto& meas : measurements) {
440 ldmx_log(trace) << meas;
441
442 if (std::find(strategy.begin(), strategy.end(), meas.getLayer()) !=
443 strategy.end()) {
444 ldmx_log(debug) << "Adding measurement from layer_ = " << meas.getLayer();
445 groups_map_[meas.getLayer()].push_back(&meas);
446 }
447
448 } // loop meas
449
450 if (groups_map_.size() < 5)
451 return false;
452 else
453 return true;
454}
455
456// For each strategy, form all the possible combinatorics and form a seedTrack
457// for each of those This will reshuffle all points. (issue?) Will sort the
458// meas_for_seed vector
459
460void SeedFinderProcessor::findSeedsFromMap(std::vector<ldmx::Track>& seeds,
461 const ldmx::Measurements& pmeas) {
462 std::map<int, std::vector<const ldmx::Measurement*>>::iterator groups_iter =
463 groups_map_.begin();
464 // Vector of iterators
465 constexpr size_t k = 5;
466 std::vector<std::vector<const ldmx::Measurement*>::iterator> it;
467 it.reserve(k);
468
469 unsigned int ikey = 0;
470 for (auto& key : groups_map_) {
471 it[ikey] = key.second.begin();
472 ikey++;
473 }
474
475 // K vectors in an array v[0],v[1].... v[K-1]
476
477 // Loop over all combinations
478 while (it[0] != groups_iter->second.end()) {
479 // process the pointed-to elements
480
481 /*
482 for (int j=0; j<K; j++) {
483 const ldmx::Measurement* meas = (*(it[j]));
484 std::cout<<meas->getGlobalPosition()[0]<<","
485 <<meas->getGlobalPosition()[1]<<","
486 <<meas->getGlobalPosition()[2]<<","<<std::endl;
487 }
488 */
489
490 std::vector<ldmx::Measurement> meas_for_seeds;
491 meas_for_seeds.reserve(5);
492
493 ldmx_log(debug) << " Grouping ";
494
495 for (int j = 0; j < k; j++) {
496 const ldmx::Measurement* meas = (*(it[j]));
497 meas_for_seeds.push_back(*meas);
498 }
499
500 std::sort(meas_for_seeds.begin(), meas_for_seeds.end(),
501 [](const ldmx::Measurement& m1, const ldmx::Measurement& m2) {
502 return m1.getGlobalPosition()[0] < m2.getGlobalPosition()[0];
503 });
504
505 if (meas_for_seeds.size() < 5) {
506 nmissing_++;
507 return;
508 }
509
510 ldmx_log(debug) << "making seedTrack";
511
512 Acts::Vector3 perigee{perigee_location_[0], perigee_location_[1],
514
515 ldmx::Track seed_track =
516 seedTracker(meas_for_seeds, meas_for_seeds.at(2).getGlobalPosition()[0],
517 perigee, pmeas);
518
519 bool fail = false;
520
521 // Remove failed fits
522 if (1. / abs(seed_track.getQoP()) < pmin_) {
523 nfailpmin_++;
524 fail = true;
525 } else if (1. / abs(seed_track.getQoP()) > pmax_) {
526 nfailpmax_++;
527 fail = true;
528 }
529
530 // Remove large part of fake tracks and duplicates with the following cuts
531 // for various compatibility checks.
532
533 else if (abs(seed_track.getZ0()) > z0max_) {
534 nfailz0max_++;
535 fail = true;
536 } else if (seed_track.getD0() < d0min_) {
537 nfaild0min_++;
538 fail = true;
539 } else if (seed_track.getD0() > d0max_) {
540 nfaild0max_++;
541 fail = true;
542 } else if (abs(seed_track.getPhi()) > phicut_) {
543 fail = true;
544 nfailphi_++;
545 } else if (abs(seed_track.getTheta() - piover2_) > thetacut_) {
546 fail = true;
547 nfailtheta_++;
548 }
549
550 // If I didn't use the target pseudo measurements in the track finding
551 // I can use them for compatibility with the tagger track
552
553 // TODO this should protect against running this check on tagger seeder.
554 // This is true only if this seeder is not run twice on the tagger after
555 // already having tagger tracks available.
556 if (pmeas.size() > 0) {
557 // I can have multiple target pseudo measurements
558 // A seed is rejected if it is found incompatible with all the target
559 // extrapolations
560
561 // This is set but unused, eventually we will use tagger track position at
562 // target to inform recoil tracking bool tgt_compatible = false;
563 for (auto tgt_pseudomeas : pmeas) {
564 // The d0/z0 are in a frame with the same orientation of the target
565 // surface
566 double delta_loc0 =
567 seed_track.getD0() - tgt_pseudomeas.getLocalPosition()[0];
568 double delta_loc1 =
569 seed_track.getZ0() - tgt_pseudomeas.getLocalPosition()[1];
570
571 if (abs(delta_loc0) < loc0cut_ && abs(delta_loc1) < loc1cut_) {
572 // found at least 1 compatible target location
573 // tgt_compatible = true;
574 break;
575 }
576 }
577 } // pmeas > 0
578
579 if (!fail) {
580 if (truth_matching_tool_->configured()) {
581 auto truth_info = truth_matching_tool_->truthMatch(meas_for_seeds);
582 seed_track.setTrackID(truth_info.track_id_);
583 seed_track.setPdgID(truth_info.pdg_id_);
584 seed_track.setTruthProb(truth_info.truth_prob_);
585 }
586
587 seeds.push_back(seed_track);
588 }
589
590 else {
591 b0_.pop_back();
592 b1_.pop_back();
593 b2_.pop_back();
594 b3_.pop_back();
595 b4_.pop_back();
596 }
597
598 // Go to next combination
599 ldmx_log(debug) << "Go to the next combination";
600
601 ++it[k - 1];
602 for (int i = k - 1;
603 (i > 0) && (it[i] == (std::next(groups_iter, i))->second.end()); --i) {
604 it[i] = std::next(groups_iter, i)->second.begin();
605 ++it[i - 1];
606 }
607 }
608} // find seeds
609
610} // namespace reco
611} // namespace tracking
612
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
std::string getName() const
Get the processor name.
Implements an event buffer system for storing event data.
Definition Event.h:42
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
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
void setLocalPosition(const float &meas_u, const float &meas_v)
Set the local position i.e.
Definition Measurement.h:59
void setGlobalPosition(const float &meas_x, const float &meas_y, const float &meas_z)
Set the global position i.e.
Definition Measurement.h:40
void setLocalCovariance(const float &cov_uu, const float &cov_vv)
Set cov(U,U) and cov(V, V).
Definition Measurement.h:75
void setTime(const float &meas_t)
Set the measurement time in ns.
Definition Measurement.h:91
Class representing a simulated particle.
Definition SimParticle.h:24
Implementation of a track object.
Definition Track.h:53
SeedFinderProcessor(const std::string &name, framework::Process &process)
Constructor.
std::string out_seed_collection_
The name of the output collection of seeds to be stored.
double pmax_
Maximum cut on the momentum of the seeds.
std::vector< std::string > strategies_
List of stragies for seed finding.
std::string input_hits_collection_
The name of the input hits collection to use in finding seeds..
void onProcessEnd() override
Callback for the EventProcessor to take any necessary action when the processing of events finishes,...
void produce(framework::Event &event) override
Run the processor and create a collection of results which indicate if a charge particle can be found...
void onProcessStart() override
Callback for the EventProcessor to take any necessary action when the processing of events starts,...
double pmin_
Minimum cut on the momentum of the seeds.
std::string tagger_trks_collection_
The name of the tagger Tracks (only for Recoil Seeding)
std::vector< double > perigee_location_
Location of the perigee for the helix track parameters.
double d0max_
Max d0 allowed for the seeds.
void configure(framework::config::Parameters &parameters) override
Configure the processor using the given user specified parameters.
double d0min_
Min d0 allowed for the seeds.
double z0max_
Max z0 allowed for the seeds.
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...