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 outputFile_ = new TFile("seeder.root", "RECREATE");
26 outputTree_ = new TTree("seeder", "seeder");
27
28 outputTree_->Branch("nevents", &nevents_);
29 outputTree_->Branch("xhit", &xhit_);
30 outputTree_->Branch("yhit", &yhit_);
31 outputTree_->Branch("zhit", &zhit_);
32
33 outputTree_->Branch("b0", &b0_);
34 outputTree_->Branch("b1", &b1_);
35 outputTree_->Branch("b2", &b2_);
36 outputTree_->Branch("b3", &b3_);
37 outputTree_->Branch("b4", &b4_);
38 */
39}
40
42 truthMatchingTool_ = std::make_shared<tracking::sim::TruthMatchingTool>();
43}
44
46 // Output seed name
47 out_seed_collection_ = parameters.getParameter<std::string>(
48 "out_seed_collection", getName() + "SeedTracks");
49
50 // Input strip hits
51 input_hits_collection_ = parameters.getParameter<std::string>(
52 "input_hits_collection", "TaggerSimHits");
53
54 // Tagger tracks - only for Recoil Seed finding
55 tagger_trks_collection_ = parameters.getParameter<std::string>(
56 "tagger_trks_collection", "TaggerTracks");
57
58 perigee_location_ = parameters.getParameter<std::vector<double>>(
59 "perigee_location", {-700, 0., 0.});
60 pmin_ =
61 parameters.getParameter<double>("pmin", 0.05 * Acts::UnitConstants::GeV);
62 pmax_ = parameters.getParameter<double>("pmax", 8 * Acts::UnitConstants::GeV);
63 d0max_ =
64 parameters.getParameter<double>("d0max", -15. * Acts::UnitConstants::mm);
65 d0min_ =
66 parameters.getParameter<double>("d0min", -45. * Acts::UnitConstants::mm);
67 z0max_ =
68 parameters.getParameter<double>("z0max", 60. * Acts::UnitConstants::mm);
69
70 phicut_ = parameters.getParameter<double>("phicut", 0.1);
71 thetacut_ = parameters.getParameter<double>("thetacut", 0.2);
72
73 loc0cut_ = parameters.getParameter<double>("loc0cut", 0.1);
74 loc1cut_ = parameters.getParameter<double>("loc1cut", 0.3);
75
76 strategies_ = parameters.getParameter<std::vector<std::string>>(
77 "strategies", {"0,1,2,3,4"});
78
79 inflate_factors_ = parameters.getParameter<std::vector<double>>(
80 "inflate_factors", {10., 10., 10., 10., 10., 10.});
81
82 bfield_ = parameters.getParameter<double>("bfield", 1.5);
83
84 input_pass_name_ =
85 parameters.getParameter<std::string>("input_pass_name", "");
86}
87
89 // tg is unused, should it be? FIXME
90 // const auto& tg{geometry()};
91 auto start = std::chrono::high_resolution_clock::now();
92 ldmx::Tracks seed_tracks;
93
94 nevents_++;
95
96 // check if SimParticleMap is available for truth matching
97 std::map<int, ldmx::SimParticle> particleMap;
98
99 const std::vector<ldmx::Measurement> measurements =
100 event.getCollection<ldmx::Measurement>(input_hits_collection_,
101 input_pass_name_);
102
103 std::vector<ldmx::Track> tagger_tracks;
104 if (event.exists(tagger_trks_collection_)) {
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 auto ts = tagtrk.getTrackState(ldmx::TrackStateType::AtTarget);
119
120 // The covariance matrix passed to the pseudo measurement is considered as
121 // uncorrelated. This is an approx that considers that loc-u and loc-v from
122 // the track have small correlation.
123
124 if (ts.has_value()) {
125 auto trackState = ts.value();
126
127 Acts::BoundSquareMatrix cov =
128 tracking::sim::utils::unpackCov(trackState.cov);
129 double locu = trackState.params[0];
130 double locv = trackState.params[1];
131 double covuu =
132 cov(Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc0);
133 double covvv =
134 cov(Acts::BoundIndices::eBoundLoc1, Acts::BoundIndices::eBoundLoc1);
135
136 ldmx::Measurement pseudo_meas;
137 pseudo_meas.setLocalPosition(locu, locv);
138 Acts::Vector3 dummy{0., 0., 0.};
139 Acts::Vector2 local_pos{locu, locv};
140 Acts::Vector3 global_pos =
141 tgt_surf->localToGlobal(geometry_context(), local_pos, dummy);
142
143 pseudo_meas.setGlobalPosition(global_pos(0), global_pos(1),
144 global_pos(2));
145 pseudo_meas.setTime(0.);
146 pseudo_meas.setLocalCovariance(covuu, covvv);
147
148 target_pseudo_meas.push_back(pseudo_meas);
149 }
150 }
151
152 if (event.exists("SimParticles")) {
153 particleMap = event.getMap<int, ldmx::SimParticle>("SimParticles");
154 truthMatchingTool_->setup(particleMap, measurements);
155 }
156
157 ldmx_log(debug) << "Preparing the strategies";
158
159 groups_map.clear();
160 // set the seeding strategy
161 // strategy is a list of layers from which to make the seed
162 // this must include 5 layers; layer numbering starts at 0.
163 // std::vector<int> strategy = {9,10,11,12,13};
164 std::vector<int> strategy = {0, 1, 2, 3, 4};
165 bool success = GroupStrips(measurements, strategy);
166 if (success) FindSeedsFromMap(seed_tracks, target_pseudo_meas);
167
168 // currently, we only use a single strategy but eventually
169 // we will use more. Below is an example of how to add them
170 /*
171 groups_map.clear();
172 strategy = {9,10,11,12,13};
173 success = GroupStrips(measurements,strategy);
174 if (success)
175 FindSeedsFromMap(seed_tracks, target_pseudo_meas);
176 */
177
178 groups_map.clear();
179 // outputTree_->Fill();
180 ntracks_ += seed_tracks.size();
181 event.add(out_seed_collection_, seed_tracks);
182
183 auto end = std::chrono::high_resolution_clock::now();
184
185 // long long microseconds =
186 // std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
187
188 auto diff = end - start;
189 processing_time_ += std::chrono::duration<double, std::milli>(diff).count();
190
191 // Seed finding using 2D Hits
192 // - The hits should keep track if they are already associated to a track or
193 // not. This can be used for subsequent passes of seed-finding
194
195 // This should go into a digitization producer, which takes care of producing
196 // measurements from:
197 // - raw hits in data
198 // - sim hits in MC
199 // Step 0: Get the sim hits and project them on the surfaces to mimic 2d hits
200 // Step 1: Smear the hits and associate an uncertainty to those 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(geometry_context()).rotation();
247 auto tr = hit_surface->transform(geometry_context()).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 double uError = sqrt(vmeas[0].getLocalCovariance()[0]);
279
280 // TODO Fix vError for measurements
281 double vError = 40. / sqrt(12);
282
283 Acts::ActsMatrix<2, 2> W_i =
284 Acts::ActsMatrix<2, 2>::Zero(); // weight matrix
285
286 W_i(0, 0) = 1. / (uError * uError);
287 W_i(1, 1) = 1. / (vError * vError);
288
289 Acts::Vector2 Yprime_i = loc + offset - xoffset;
290 Y += (A_i.transpose()) * W_i * Yprime_i;
291
292 Acts::ActsMatrix<2, 5> WA_i = (W_i * A_i);
293 A += A_i.transpose() * WA_i;
294 }
295
296 Acts::ActsVector<5> B;
297 B = A.inverse() * Y;
298
299 b0_.push_back(B(0));
300 b1_.push_back(B(1));
301 b2_.push_back(B(2));
302 b3_.push_back(B(3));
303 b4_.push_back(B(4));
304
305 // Acts::ActsVector<5> hlx = Acts::ActsVector<5>::Zero();
306 Acts::ActsVector<3> ref{0., 0., 0.};
307
308 double relativePerigeeX = perigee_location(0) - xOrigin;
309
310 std::shared_ptr<const Acts::PerigeeSurface> seed_perigee =
311 Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3(
312 relativePerigeeX, perigee_location(1), perigee_location(2)));
313
314 // in mm
315 Acts::Vector3 seed_pos{relativePerigeeX,
316 B(0) + B(1) * relativePerigeeX +
317 B(2) * relativePerigeeX * relativePerigeeX,
318 B(3) + B(4) * relativePerigeeX};
319 Acts::Vector3 dir{1, B(1) + 2 * B(2) * relativePerigeeX, B(4)};
320 dir /= dir.norm();
321
322 // Momentum at xmeas
323 double p =
324 0.3 * bfield_ * (1. / (2. * abs(B(2)))) * 0.001; // R in meters, p in GeV
325 // std::cout<<"Momentum "<< p*dir << std::endl;
326
327 // Convert it to MeV since that's what TrackUtils assumes
328 Acts::Vector3 seed_mom = p * dir / Acts::UnitConstants::MeV;
329 Acts::ActsScalar q =
330 B(2) < 0 ? -1 * Acts::UnitConstants::e : +1 * Acts::UnitConstants::e;
331
332 // Linear intersection with the perigee line. TODO:: Use propagator instead
333 // Project the position on the surface.
334 // This is mainly necessary for the perigee surface, where
335 // the mean might not fulfill the perigee condition.
336
337 // mg Aug 2024 .. interect has changed, but just remove boundary check
338 // and change intersection to intersections
339 // auto intersection =
340 // (*seed_perigee).intersect(geometry_context(), seed_pos, dir, false);
341
342 // Acts::FreeVector seed_free = tracking::sim::utils::toFreeParameters(
343 // intersection.intersection.position, seed_mom, q);
344
345 auto intersection =
346 (*seed_perigee).intersect(geometry_context(), seed_pos, dir);
347
348 Acts::FreeVector seed_free = tracking::sim::utils::toFreeParameters(
349 intersection.intersections()[0].position(), seed_mom, q);
350
351 auto bound_params = Acts::transformFreeToBoundParameters(
352 seed_free, *seed_perigee, geometry_context())
353 .value();
354
355 ldmx_log(trace) << "bound parameters at perigee location" << bound_params;
356
357 Acts::BoundVector stddev;
358 // sigma set to 75% of momentum
359 double sigma_p = 0.75 * p * Acts::UnitConstants::GeV;
360 stddev[Acts::eBoundLoc0] =
361 inflate_factors_[Acts::eBoundLoc0] * 2 * Acts::UnitConstants::mm;
362 stddev[Acts::eBoundLoc1] =
363 inflate_factors_[Acts::eBoundLoc1] * 5 * Acts::UnitConstants::mm;
364 stddev[Acts::eBoundPhi] =
365 inflate_factors_[Acts::eBoundPhi] * 5 * Acts::UnitConstants::degree;
366 stddev[Acts::eBoundTheta] =
367 inflate_factors_[Acts::eBoundTheta] * 5 * Acts::UnitConstants::degree;
368 stddev[Acts::eBoundQOverP] =
369 inflate_factors_[Acts::eBoundQOverP] * (1. / p) * (1. / p) * sigma_p;
370 stddev[Acts::eBoundTime] =
371 inflate_factors_[Acts::eBoundTime] * 1000 * Acts::UnitConstants::ns;
372
373 ldmx_log(debug)
374 << "Making covariance matrix as diagonal matrix with inflated terms";
375 Acts::BoundSquareMatrix bound_cov = stddev.cwiseProduct(stddev).asDiagonal();
376
377 ldmx_log(debug) << "...now putting together the seed track ...";
378
379 ldmx::Track trk = ldmx::Track();
380 trk.setPerigeeLocation(perigee_location(0), perigee_location(1),
381 perigee_location(2));
382 trk.setChi2(0.);
383 trk.setNhits(5);
384 trk.setNdf(0);
385 trk.setNsharedHits(0);
386 std::vector<double> v_seed_params(
387 (bound_params).data(),
388 bound_params.data() + bound_params.rows() * bound_params.cols());
389 std::vector<double> v_seed_cov;
390 tracking::sim::utils::flatCov(bound_cov, v_seed_cov);
391 trk.setPerigeeParameters(v_seed_params);
392 trk.setPerigeeCov(v_seed_cov);
393
394 // Store the global position and momentum at the perigee
395 // TODO:: The eFreePos0 is wrong due to the linear intersection.
396 // YZ are ~ correct
397 trk.setPosition(seed_free[Acts::eFreePos0], seed_free[Acts::eFreePos1],
398 seed_free[Acts::eFreePos2]);
399 trk.setMomentum(seed_free[Acts::eFreeDir0], seed_free[Acts::eFreeDir1],
400 seed_free[Acts::eFreeDir2]);
401
402 ldmx_log(debug)
403 << "...making the ParticleHypothesis ...assume electron for now";
404 auto partHypo{Acts::SinglyChargedParticleHypothesis::electron()};
405
406 ldmx_log(debug) << "Making BoundTrackParameters seedParameters";
407 Acts::BoundTrackParameters seedParameters(
408 seed_perigee, std::move(bound_params), bound_cov, partHypo);
409
410 ldmx_log(debug) << "Returning seed track";
411 return trk;
412}
413
415 // outputFile_->cd();
416 // outputTree_->Write();
417 // outputFile_->Close();
418 ldmx_log(info) << "AVG Time/Event: " << std::fixed << std::setprecision(1)
419 << processing_time_ / nevents_ << " ms";
420 ldmx_log(info) << "Total Seeds/Events: " << ntracks_ << "/" << nevents_;
421 ldmx_log(info) << "Seeds discarded due to multiple hits on layers "
422 << ndoubles_;
423 ldmx_log(info) << "not enough seed points " << nmissing_;
424 ldmx_log(info) << " nfailpmin=" << nfailpmin_;
425 ldmx_log(info) << " nfailpmax=" << nfailpmax_;
426 ldmx_log(info) << " nfaild0max=" << nfaild0max_;
427 ldmx_log(info) << " nfaild0min=" << nfaild0min_;
428 ldmx_log(info) << " nfailphicut=" << nfailphi_;
429 ldmx_log(info) << " nfailthetacut=" << nfailtheta_;
430 ldmx_log(info) << " nfailz0max=" << nfailz0max_;
431}
432
433// Given a strategy, group the hits according to some options
434// Not a good algorithm. The best would be to organize all the hits in sensors
435// *first* then only select the hits that we are interested into. TODO!
436
437bool SeedFinderProcessor::GroupStrips(
438 const std::vector<ldmx::Measurement>& measurements,
439 const std::vector<int> strategy) {
440 // std::cout<<"Using stratedy"<<std::endl;
441 // for (auto& e : strategy) {
442 // std::cout<<e<<" ";
443 //}
444 // std::cout<<std::endl;
445
446 for (auto& meas : measurements) {
447 ldmx_log(trace) << meas;
448
449 if (std::find(strategy.begin(), strategy.end(), meas.getLayer()) !=
450 strategy.end()) {
451 ldmx_log(debug) << "Adding measurement from layer = " << meas.getLayer();
452 groups_map[meas.getLayer()].push_back(&meas);
453 }
454
455 } // loop meas
456
457 if (groups_map.size() < 5)
458 return false;
459 else
460 return true;
461}
462
463// For each strategy, form all the possible combinatorics and form a seedTrack
464// for each of those This will reshuffle all points. (issue?) Will sort the
465// meas_for_seed vector
466
467void SeedFinderProcessor::FindSeedsFromMap(ldmx::Tracks& seeds,
468 const ldmx::Measurements& pmeas) {
469 std::map<int, std::vector<const ldmx::Measurement*>>::iterator groups_iter =
470 groups_map.begin();
471 // Vector of iterators
472 constexpr size_t K = 5;
473 std::vector<std::vector<const ldmx::Measurement*>::iterator> it;
474 it.reserve(K);
475
476 unsigned int ikey = 0;
477 for (auto& key : groups_map) {
478 it[ikey] = key.second.begin();
479 ikey++;
480 }
481
482 // K vectors in an array v[0],v[1].... v[K-1]
483
484 while (it[0] != groups_iter->second.end()) {
485 // process the pointed-to elements
486
487 /*
488 for (int j=0; j<K; j++) {
489 const ldmx::Measurement* meas = (*(it[j]));
490 std::cout<<meas->getGlobalPosition()[0]<<","
491 <<meas->getGlobalPosition()[1]<<","
492 <<meas->getGlobalPosition()[2]<<","<<std::endl;
493 }
494 */
495
496 std::vector<ldmx::Measurement> meas_for_seeds;
497 meas_for_seeds.reserve(5);
498
499 ldmx_log(debug) << " Grouping ";
500
501 for (int j = 0; j < K; j++) {
502 const ldmx::Measurement* meas = (*(it[j]));
503 meas_for_seeds.push_back(*meas);
504 }
505
506 std::sort(meas_for_seeds.begin(), meas_for_seeds.end(),
507 [](const ldmx::Measurement& m1, const ldmx::Measurement& m2) {
508 return m1.getGlobalPosition()[0] < m2.getGlobalPosition()[0];
509 });
510
511 if (meas_for_seeds.size() < 5) {
512 nmissing_++;
513 return;
514 }
515
516 ldmx_log(debug) << "making seedTrack";
517
518 Acts::Vector3 perigee{perigee_location_[0], perigee_location_[1],
520
521 ldmx::Track seedTrack =
522 SeedTracker(meas_for_seeds, meas_for_seeds.at(2).getGlobalPosition()[0],
523 perigee, pmeas);
524
525 bool fail = false;
526
527 // Remove failed fits
528 if (1. / abs(seedTrack.getQoP()) < pmin_) {
529 nfailpmin_++;
530 fail = true;
531 } else if (1. / abs(seedTrack.getQoP()) > pmax_) {
532 nfailpmax_++;
533 fail = true;
534 }
535
536 // Remove large part of fake tracks and duplicates with the following cuts
537 // for various compatibility checks.
538
539 else if (abs(seedTrack.getZ0()) > z0max_) {
540 nfailz0max_++;
541 fail = true;
542 } else if (seedTrack.getD0() < d0min_) {
543 nfaild0min_++;
544 fail = true;
545 } else if (seedTrack.getD0() > d0max_) {
546 nfaild0max_++;
547 fail = true;
548 } else if (abs(seedTrack.getPhi()) > phicut_) {
549 fail = true;
550 nfailphi_++;
551 } else if (abs(seedTrack.getTheta() - piover2_) > thetacut_) {
552 fail = true;
553 nfailtheta_++;
554 }
555
556 // If I didn't use the target pseudo measurements in the track finding
557 // I can use them for compatibility with the tagger track
558
559 // TODO this should protect against running this check on tagger seeder.
560 // This is true only if this seeder is not run twice on the tagger after
561 // already having tagger tracks available.
562 if (pmeas.size() > 0) {
563 // I can have multiple target pseudo measurements
564 // A seed is rejected if it is found incompatible with all the target
565 // extrapolations
566
567 // This is set but unused, eventually we will use tagger track position at
568 // target to inform recoil tracking bool tgt_compatible = false;
569 for (auto tgt_pseudomeas : pmeas) {
570 // The d0/z0 are in a frame with the same orientation of the target
571 // surface
572 double delta_loc0 =
573 seedTrack.getD0() - tgt_pseudomeas.getLocalPosition()[0];
574 double delta_loc1 =
575 seedTrack.getZ0() - tgt_pseudomeas.getLocalPosition()[1];
576
577 if (abs(delta_loc0) < loc0cut_ && abs(delta_loc1) < loc1cut_) {
578 // found at least 1 compatible target location
579 // tgt_compatible = true;
580 break;
581 }
582 }
583 } // pmeas > 0
584
585 if (!fail) {
586 if (truthMatchingTool_->configured()) {
587 auto truthInfo = truthMatchingTool_->TruthMatch(meas_for_seeds);
588 seedTrack.setTrackID(truthInfo.trackID);
589 seedTrack.setPdgID(truthInfo.pdgID);
590 seedTrack.setTruthProb(truthInfo.truthProb);
591 }
592
593 seeds.push_back(seedTrack);
594 }
595
596 else {
597 b0_.pop_back();
598 b1_.pop_back();
599 b2_.pop_back();
600 b3_.pop_back();
601 b4_.pop_back();
602 }
603
604 // Go to next combination
605 ldmx_log(debug) << "Go to the next combination";
606
607 ++it[K - 1];
608 for (int i = K - 1;
609 (i > 0) && (it[i] == (std::next(groups_iter, i))->second.end()); --i) {
610 it[i] = std::next(groups_iter, i)->second.begin();
611 ++it[i - 1];
612 }
613 }
614} // find seeds
615
616} // namespace reco
617} // namespace tracking
618
619DECLARE_PRODUCER_NS(tracking::reco, SeedFinderProcessor)
#define DECLARE_PRODUCER_NS(NS, 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
void setTime(const float &t)
Set the measurement time in ns.
Definition Measurement.h:90
void setGlobalPosition(const float &x, const float &y, const float &z)
Set the global position i.e.
Definition Measurement.h:40
void setLocalPosition(const float &u, const float &v)
Set the local position i.e.
Definition Measurement.h:58
void setLocalCovariance(const float &cov_uu, const float &cov_vv)
Set cov(U,U) and cov(V, V).
Definition Measurement.h:74
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...