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