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