LDMX Software
CKFProcessor.cxx
1#include "Tracking/Reco/CKFProcessor.h"
2
3#include "Acts/EventData/TrackContainer.hpp"
4#include "Acts/Utilities/TrackHelpers.hpp"
5#include "SimCore/Event/SimParticle.h"
6#include "Tracking/Reco/TruthMatchingTool.h"
7#include "Tracking/Sim/GeometryContainers.h"
8
9//--- C++ StdLib ---//
10#include <algorithm> //std::vector reverse
11#include <iostream>
12#include <typeinfo>
13// eN files
14#include <fstream>
15
16namespace tracking {
17namespace reco {
18
19CKFProcessor::CKFProcessor(const std::string& name, framework::Process& process)
20 : TrackingGeometryUser(name, process) {}
21
23
25 profiling_map_["setup"] = 0.;
26 profiling_map_["hits"] = 0.;
27 profiling_map_["seeds"] = 0.;
28 profiling_map_["ckf_setup"] = 0.;
29 profiling_map_["ckf_run"] = 0.;
30 profiling_map_["result_loop"] = 0.;
31
32 // Generate a constant magnetic field
33 Acts::Vector3 b_field(0., 0., bfield_ * Acts::UnitConstants::T);
34
35 // Setup a constant magnetic field
36 const auto constBField = std::make_shared<Acts::ConstantBField>(b_field);
37
38 // Define the target surface - be careful:
39 // x - downstream
40 // y - left (when looking along x)
41 // z - up
42 // Passing identity here means that your target surface is oriented in the
43 // same way
44 surf_rotation = Acts::RotationMatrix3::Zero();
45 // u direction along +Y
46 surf_rotation(1, 0) = 1;
47 // v direction along +Z
48 surf_rotation(2, 1) = 1;
49 // w direction along +X
50 surf_rotation(0, 2) = 1;
51
52 Acts::Vector3 target_pos(0., 0., 0.);
53 Acts::Translation3 target_translation(target_pos);
54 Acts::Transform3 target_transform(target_translation * surf_rotation);
55
56 // Unbounded surface
57 target_surface =
58 Acts::Surface::makeShared<Acts::PlaneSurface>(target_transform);
59
60 // Custom transformation of the interpolated bfield map
61 bool debugTransform = false;
62 auto transformPos = [this, debugTransform](const Acts::Vector3& pos) {
63 Acts::Vector3 rot_pos;
64 rot_pos(0) = pos(1);
65 rot_pos(1) = pos(2);
66 rot_pos(2) = pos(0) + DIPOLE_OFFSET;
67
68 // Systematic effect
69 rot_pos(0) += this->map_offset_[0];
70 rot_pos(1) += this->map_offset_[1];
71 rot_pos(2) += this->map_offset_[2];
72
73 // Apply A rotation around the center of the magnet. (I guess offset first
74 // and then rotation)
75
76 if (debugTransform) {
77 std::cout << "PF::DEFAULT3 TRANSFORM" << std::endl;
78 std::cout << "PF::Check:: transforming Pos" << std::endl;
79 std::cout << pos << std::endl;
80 std::cout << "TO" << std::endl;
81 std::cout << rot_pos << std::endl;
82 }
83
84 return rot_pos;
85 };
86
87 Acts::RotationMatrix3 rotation = Acts::RotationMatrix3::Identity();
88 double scale = 1.;
89
90 auto transformBField = [rotation, scale, debugTransform](
91 const Acts::Vector3& field,
92 const Acts::Vector3& /*pos*/) {
93 // Rotate the field in tracking coordinates
94 Acts::Vector3 rot_field;
95 rot_field(0) = field(2);
96 rot_field(1) = field(0);
97 rot_field(2) = field(1);
98
99 // Scale the field
100 rot_field = scale * rot_field;
101
102 // Rotate the field
103 rot_field = rotation * rot_field;
104
105 // A distortion scaled by position.
106 if (debugTransform) {
107 std::cout << "PF::DEFAULT3 TRANSFORM" << std::endl;
108 std::cout << "PF::Check:: transforming" << std::endl;
109 std::cout << field << std::endl;
110 std::cout << "TO" << std::endl;
111 std::cout << rot_field << std::endl;
112 }
113
114 return rot_field;
115 };
116
117 // Setup a interpolated bfield map
118 const auto map = std::make_shared<InterpolatedMagneticField3>(
119 loadDefaultBField(field_map_,
120 // default_transformPos,
121 // default_transformBField));
122 transformPos, transformBField));
123
124 auto acts_loggingLevel = Acts::Logging::FATAL;
125 if (debug_acts_) acts_loggingLevel = Acts::Logging::VERBOSE;
126
127 // Setup the steppers
128 const auto stepper = Acts::EigenStepper<>{map};
129 const auto const_stepper = Acts::EigenStepper<>{constBField};
130 const auto multi_stepper = Acts::MultiEigenStepperLoop{map};
131
132 // Setup the navigator
133 Acts::Navigator::Config navCfg{geometry().getTG()};
134 navCfg.resolveMaterial = true;
135 navCfg.resolvePassive = true;
136 navCfg.resolveSensitive = true;
137 const Acts::Navigator navigator(navCfg);
138
139 // Setup the propagators
140 propagator_ =
141 const_b_field_
142 ? std::make_unique<CkfPropagator>(const_stepper, navigator)
143 : std::make_unique<CkfPropagator>(
144 stepper, navigator,
145 Acts::getDefaultLogger("ACTS_PROP", acts_loggingLevel));
146
147 // Setup the finder / fitters
148 ckf_ = std::make_unique<std::decay_t<decltype(*ckf_)>>(
149 *propagator_, Acts::getDefaultLogger("CKF", acts_loggingLevel));
150 trk_extrap_ = std::make_shared<std::decay_t<decltype(*trk_extrap_)>>(
151 *propagator_, geometry_context(), magnetic_field_context());
152}
153
155 eventnr_++;
156 // get the tracking geometry from conditions
157 auto tg{geometry()};
158
159 // TODO use global variable instead and call clear;
160
161 std::vector<ldmx::Track> tracks;
162
163 auto start = std::chrono::high_resolution_clock::now();
164
165 nevents_++;
166 if (nevents_ % 1000 == 0) ldmx_log(info) << "events processed:" << nevents_;
167
168 auto loggingLevel = Acts::Logging::DEBUG;
169 ACTS_LOCAL_LOGGER(
170 Acts::getDefaultLogger("LDMX Tracking Geometry Maker", loggingLevel));
171
172 // Move this at the start of the producer
173 Acts::PropagatorOptions<Acts::StepperPlainOptions,
174 Acts::NavigatorPlainOptions, ActionList, AbortList>
175 propagator_options(geometry_context(), magnetic_field_context());
176
177 propagator_options.pathLimit = std::numeric_limits<double>::max();
178 // Activate loop protection at some pt value
179 propagator_options.loopProtection =
180 false; //(startParameters.transverseMomentum() < cfg.ptLoopers);
181
182 // Switch the material interaction on/off & eventually into logging mode
183 auto& mInteractor =
184 propagator_options.actionList.get<Acts::MaterialInteractor>();
185 mInteractor.multipleScattering = true;
186 mInteractor.energyLoss = true;
187 mInteractor.recordInteractions = false;
188
189 // The logger can be switched to sterile, e.g. for timing logging
190 auto& sLogger =
191 propagator_options.actionList.get<Acts::detail::SteppingLogger>();
192 sLogger.sterile = true;
193 // Set a maximum step size
194 propagator_options.stepping.maxStepSize =
195 propagator_step_size_ * Acts::UnitConstants::mm;
196 propagator_options.maxSteps = propagator_maxSteps_;
197
198 // #######################//
199 // Kalman Filter algorithm//
200 // #######################//
201
202 // Step 1 - Form the source links
203
204 // a) Loop over the sim Hits
205
206 auto setup = std::chrono::high_resolution_clock::now();
207 profiling_map_["setup"] +=
208 std::chrono::duration<double, std::milli>(setup - start).count();
209
210 const std::vector<ldmx::Measurement> measurements =
211 event.getCollection<ldmx::Measurement>(measurement_collection_);
212
213 // check if SimParticleMap is available for truth matching
214 std::shared_ptr<tracking::sim::TruthMatchingTool> truthMatchingTool = nullptr;
215 std::map<int, ldmx::SimParticle> particleMap;
216
217 if (event.exists("SimParticles")) {
218 ldmx_log(debug) << "Setting up track truth matching tool";
219 particleMap = event.getMap<int, ldmx::SimParticle>("SimParticles");
220 truthMatchingTool = std::make_shared<tracking::sim::TruthMatchingTool>(
221 particleMap, measurements);
222 }
223
224 // The mapping between the geometry identifier
225 // and the IndexsourceLink that points to the hit
226 const auto geoId_sl_map = makeGeoIdSourceLinkMap(tg, measurements);
227
228 auto hits = std::chrono::high_resolution_clock::now();
229 profiling_map_["hits"] +=
230 std::chrono::duration<double, std::milli>(hits - setup).count();
231
232 // ============ Setup the CKF ============
233
234 // Retrieve the seeds
235
236 ldmx_log(debug) << "Retrieve the seeds::" << seed_coll_name_;
237
238 const std::vector<ldmx::Track> seed_tracks =
239 event.getCollection<ldmx::Track>(seed_coll_name_);
240
241 ldmx_log(debug) << "Number of seeds::" << seed_tracks.size();
242
243 // Run the CKF on each seed and produce a track candidate
244 std::vector<Acts::BoundTrackParameters> startParameters;
245
246 // Tune the reconstruction for different PDG ID
247 std::vector<int> seedPDGID;
248
249 for (auto& seed : seed_tracks) {
250 // Transform the seed track to bound parameters
251 std::shared_ptr<Acts::PerigeeSurface> perigeeSurface =
252 Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3(
253 seed.getPerigeeX(), seed.getPerigeeY(), seed.getPerigeeZ()));
254
255 Acts::BoundVector paramVec;
256 paramVec << seed.getD0(), seed.getZ0(), seed.getPhi(), seed.getTheta(),
257 seed.getQoP(), seed.getT();
258
259 Acts::BoundSquareMatrix covMat =
260 tracking::sim::utils::unpackCov(seed.getPerigeeCov());
261
262 ldmx_log(debug) << "perigee" << std::endl
263 << seed.getPerigeeX() << " " << seed.getPerigeeY() << " "
264 << seed.getPerigeeZ() << std::endl
265 << "start Parameters" << std::endl
266 << paramVec;
267
268 ldmx_log(debug) << "cov matrix" << std::endl << covMat << std::endl;
269
270 // need to set particle hypothesis...set to electron for now...
271 auto partHypo{Acts::SinglyChargedParticleHypothesis::electron()};
272 startParameters.push_back(
273 Acts::BoundTrackParameters(perigeeSurface, paramVec, covMat, partHypo));
274
275 seedPDGID.push_back(seed.getPdgID());
276
277 nseeds_++;
278 } // loop on seeds
279
280 if (startParameters.size() < 1) {
281 std::vector<ldmx::Track> empty;
282 event.add(out_trk_collection_, empty);
283 return;
284 }
285
286 auto seeds = std::chrono::high_resolution_clock::now();
287 profiling_map_["seeds"] +=
288 std::chrono::duration<double, std::milli>(seeds - hits).count();
289
290 Acts::GainMatrixUpdater kfUpdater;
291
292 // configuration for the measurement selector. Empty geometry identifier means
293 // applicable to all the detector elements
294
295 Acts::MeasurementSelector::Config measurementSelectorCfg = {
296 // global default: no chi2 cut, only one measurement per surface
297 {Acts::GeometryIdentifier(), {{}, {outlier_pval_}, {1u}}},
298 };
299
300 Acts::MeasurementSelector measSel{measurementSelectorCfg};
301
302 tracking::sim::LdmxMeasurementCalibrator calibrator{measurements};
303
304 Acts::CombinatorialKalmanFilterExtensions<TrackContainer> ckf_extensions;
305
306 if (use1Dmeasurements_)
307 ckf_extensions.calibrator
309 Acts::VectorMultiTrajectory>>(&calibrator);
310
311 else
312 ckf_extensions.calibrator
314 Acts::VectorMultiTrajectory>>(&calibrator);
315
316 ckf_extensions.updater.connect<
317 &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
318 &kfUpdater);
319
320 ckf_extensions.measurementSelector
321 .connect<&Acts::MeasurementSelector::select<Acts::VectorMultiTrajectory>>(
322 &measSel);
323
324 ldmx_log(debug) << "SourceLinkAccessor..." << std::endl;
325
326 // Create source link accessor and connect delegate
327 struct SourceLinkAccIt {
328 using BaseIt = decltype(geoId_sl_map.begin());
329 BaseIt it;
330
331#pragma GCC diagnostic push
332#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
333
334 using difference_type = typename BaseIt::difference_type;
335 using iterator_category = typename BaseIt::iterator_category;
336 // using value_type = typename BaseIt::value_type::second_type;
337 using value_type = Acts::SourceLink;
338 using pointer = typename BaseIt::pointer;
339 using reference = value_type&;
340#pragma GCC diagnostic pop
341
342 SourceLinkAccIt& operator++() {
343 ++it;
344 return *this;
345 }
346 bool operator==(const SourceLinkAccIt& other) const {
347 return it == other.it;
348 }
349 bool operator!=(const SourceLinkAccIt& other) const {
350 return !(*this == other);
351 }
352 // const value_type& operator*() const { return it->second; }
353
354 // by value
355 value_type operator*() const { return value_type{it->second}; }
356 };
357
358 auto sourceLinkAccessor = [&](const Acts::Surface& surface)
359 -> std::pair<SourceLinkAccIt, SourceLinkAccIt> {
360 auto [begin, end] = geoId_sl_map.equal_range(surface.geometryId());
361 return {SourceLinkAccIt{begin}, SourceLinkAccIt{end}};
362 };
363
364 Acts::SourceLinkAccessorDelegate<SourceLinkAccIt> sourceLinkAccessorDelegate;
365 sourceLinkAccessorDelegate.connect<&decltype(sourceLinkAccessor)::operator(),
366 decltype(sourceLinkAccessor)>(
367 &sourceLinkAccessor);
368
369 ldmx_log(debug) << "Surfaces..." << std::endl;
370
371 std::shared_ptr<const Acts::PerigeeSurface> origin_surface =
372 Acts::Surface::makeShared<Acts::PerigeeSurface>(
373 Acts::Vector3(0., 0., 0.));
374
375 ldmx_log(debug) << "About to run CKF..." << std::endl;
376
377 // run the CKF for all initial track states
378 auto ckf_setup = std::chrono::high_resolution_clock::now();
379 profiling_map_["ckf_setup"] +=
380 std::chrono::duration<double, std::milli>(ckf_setup - seeds).count();
381
382 auto ckf_run = std::chrono::high_resolution_clock::now();
383 profiling_map_["ckf_run"] +=
384 std::chrono::duration<double, std::milli>(ckf_run - ckf_setup).count();
385
386 Acts::VectorTrackContainer vtc;
387 Acts::VectorMultiTrajectory mtj;
388 Acts::TrackContainer tc{vtc, mtj};
389
390 for (size_t trackId = 0u; trackId < startParameters.size(); ++trackId) {
391 // The seed has a track PdgID associated
392 if (seedPDGID.at(trackId) != 0) {
393 // int pdgID = seedPDGID.at(trackId);
394 }
395
396 // Define the CKF options here:
397 const Acts::CombinatorialKalmanFilterOptions<SourceLinkAccIt,
398 TrackContainer>
399 ckfOptions(TrackingGeometryUser::geometry_context(),
400 TrackingGeometryUser::magnetic_field_context(),
401 TrackingGeometryUser::calibration_context(),
402 sourceLinkAccessorDelegate, ckf_extensions,
403 propagator_options, true /* multiple scattering */,
404 false /* energy loss */);
405
406 ldmx_log(debug) << "Running CKF on seed params "
407 << startParameters.at(trackId).parameters().transpose()
408 << std::endl;
409 ldmx_log(debug) << "Checking options: multiple scattering = "
410 << ckfOptions.multipleScattering
411 << " energy loss = " << ckfOptions.energyLoss;
412 auto results =
413 ckf_->findTracks(startParameters.at(trackId), ckfOptions, tc);
414 ldmx_log(debug) << "findTracks returned ... checking if ok";
415 if (not results.ok()) {
416 ldmx_log(debug) << "CKF Fit failed" << std::endl;
417 continue;
418 }
419
420 // No track found
421 // if (tc.size() < trackId + 1) continue;
422
423 auto& tracksFromSeed = results.value();
424
425 ldmx_log(debug) << "number of entries in results " << tracksFromSeed.size();
426 for (auto& track : tracksFromSeed) {
427 // do the track smoothing...this is not done in the CKF code anymore
428 Acts::smoothTrack(geometry_context(), track); // from TrackHelpers
429 // make the empty ldmx::Track() and track state at target
430 ldmx::Track trk = ldmx::Track();
431 ldmx::Track::TrackState tsAtTarget;
432 ldmx_log(debug) << "Found track: nMeas " << track.nMeasurements();
433 ldmx_log(debug) << "Track states " << track.nTrackStates();
434 ldmx_log(debug) << "chi2 " << track.chi2();
435
436 for (const auto ts : track.trackStatesReversed()) {
437 // Check TrackStates Quality
438 ldmx_log(debug) << "Checking Track State at location "
439 << ts.referenceSurface()
440 .transform(geometry_context())
441 .translation()
442 .transpose()
443 << std::endl;
444
445 ldmx_log(debug) << "Smoothed? " << ts.hasSmoothed() << std::endl;
446 if (ts.hasSmoothed()) {
447 ldmx_log(debug) << "Parameters \n"
448 << ts.smoothed().transpose() << std::endl;
449 ldmx_log(debug) << "Covariance \n"
450 << ts.smoothedCovariance() << std::endl;
451 }
452
453 // Check if the track state is a measurement
454 auto typeFlags = ts.typeFlags();
455
456 if (typeFlags.test(Acts::TrackStateFlag::MeasurementFlag) &&
457 ts.hasUncalibratedSourceLink()) {
458 ldmx_log(debug) << " getting source link for this measurement";
459
461 ts.getUncalibratedSourceLink()
462 .template get<ActsExamples::IndexSourceLink>();
463
464 ldmx_log(debug) << " looking up this index in measurements list";
465 ldmx::Measurement ldmx_meas = measurements.at(sl.index());
466 ldmx_log(debug) << "SourceLink Index::" << sl.index();
467 ldmx_log(debug) << "Measurement:\n" << ldmx_meas << "\n";
468 ldmx_log(debug) << " adding measurement to ldmx::track";
469 trk.addMeasurementIndex(sl.index());
470 }
471 }
472 bool success = trk_extrap_->TrackStateAtSurface(
473 track, target_surface, tsAtTarget, ldmx::TrackStateType::AtTarget);
474 ldmx_log(debug) << "target extrapolation success??? " << success;
475 if (success) {
476 ldmx_log(debug) << "Successfully obtained TS at target";
477 ldmx_log(debug) << "Parameters At Target: \n"
478 << tsAtTarget.params[0] << " " << tsAtTarget.params[1]
479 << " " << tsAtTarget.params[2] << " "
480 << tsAtTarget.params[3] << " " << tsAtTarget.params[4];
481
482 trk.addTrackState(tsAtTarget);
483 } else {
484 ldmx_log(info)
485 << "Could not extrapolate to target? Printing track states: ";
486 ldmx_log(info) << " nhits = " << track.nMeasurements();
487 for (const auto ts : track.trackStatesReversed()) {
488 ldmx_log(info) << "Smoothed? " << ts.hasSmoothed() << std::endl;
489 if (ts.hasSmoothed()) {
490 ldmx_log(info) << "momentum for track state = "
491 << 1 / ts.smoothed()[Acts::eBoundQOverP];
492 ldmx_log(info) << "Parameters \n"
493 << ts.smoothed().transpose() << std::endl;
494 } else {
495 ldmx_log(info) << "Track state not smoothed?";
496 }
497 }
498 ldmx_log(info) << "...skipping this track...";
499 continue;
500 }
501
502 // get the BoundTrackParameters at the target
503 // ...use to fill in the Acts::TrackProxy object
504 // This isn't really necessary, since we can take
505 // most everything for making the ldmx::track
506 // from tsAtTarget...maybe useful for something?
507 // -->one thing this does is allow Acts to
508 // calculate the momentum 3-vector for you
509 Acts::BoundTrackParameters boundStateAtTarget =
510 tracking::sim::utils::btp(tsAtTarget, target_surface, 11);
511 track.setReferenceSurface(target_surface);
512 track.parameters() = boundStateAtTarget.parameters();
513
514 ldmx_log(debug) << typeid(track).name();
515 // These are the parameters at the target surface
516 const Acts::BoundVector& track_pars = track.parameters();
517 // const Acts::BoundMatrix& trk_cov = track.covariance();
518 const Acts::Surface& track_surface = track.referenceSurface();
519 ldmx_log(debug) << "Got the parameters, covariance, and perigee surface";
520
521 ldmx_log(debug) << track_pars[Acts::eBoundLoc0];
522 ldmx_log(debug) << track_pars[Acts::eBoundLoc1];
523 ldmx_log(debug) << track_pars[Acts::eBoundTheta];
524 ldmx_log(debug) << track_pars[Acts::eBoundPhi];
525 ldmx_log(debug)
526 << "Reference Surface" << std::endl
527 << " " << track_surface.transform(geometry_context()).translation()(0)
528 << " " << track_surface.transform(geometry_context()).translation()(1)
529 << " "
530 << track_surface.transform(geometry_context()).translation()(2);
531
532 trk.setPerigeeLocation(
533 0, 0, 0); // the target...it's not really perigee anymore.
534 trk.setPerigeeParameters(tsAtTarget.params);
535 trk.setPerigeeCov(tsAtTarget.cov);
536
537 ldmx_log(debug) << "setting chi2 and nHits: " << track.chi2() << " "
538 << track.nMeasurements();
539 trk.setChi2(track.chi2());
540 trk.setNhits(track.nMeasurements());
541 // trk.setNdf(track.nDoF());
542 // TODO Switch back to nDoF when Acts is fixed.
543 trk.setNdf(track.nMeasurements() - 5);
544 trk.setNsharedHits(track.nSharedHits());
545
546 ldmx_log(debug) << "setting track momentum: " << track.momentum();
547 trk.setMomentum(track.momentum()[0], track.momentum()[1],
548 track.momentum()[2]);
549
550 ldmx_log(debug) << "starting extrapolations";
551 // Extrapolations
552
553 const double ECAL_SCORING_PLANE = 240.5;
554 Acts::Vector3 pos(ECAL_SCORING_PLANE, 0., 0.);
555 Acts::Translation3 surf_translation(pos);
556 Acts::Transform3 surf_transform(surf_translation * surf_rotation);
557
558 // Unbounded surface
559 const std::shared_ptr<Acts::PlaneSurface> ecal_surface =
560 Acts::Surface::makeShared<Acts::PlaneSurface>(surf_transform);
561
562 // Beam Origin unbounded surface
563 const std::shared_ptr<Acts::Surface> beamOrigin_surface =
564 tracking::sim::utils::unboundSurface(-700);
565
566 if (taggerTracking_) {
567 ldmx_log(debug) << "Beam Origin Extrapolation";
568 ldmx::Track::TrackState tsAtBeamOrigin;
569 success = trk_extrap_->TrackStateAtSurface(
570 track, beamOrigin_surface, tsAtBeamOrigin,
571 ldmx::TrackStateType::AtBeamOrigin);
572
573 if (success) {
574 trk.addTrackState(tsAtBeamOrigin);
575 ldmx_log(debug) << "Successfully obtained TS at beam origin";
576 }
577 }
578
579 // Recoil Extrapolation to ECAL only
580 if (!taggerTracking_) {
581 ldmx_log(debug) << "Ecal Extrapolation";
583 success = trk_extrap_->TrackStateAtSurface(
584 track, ecal_surface, tsAtEcal, ldmx::TrackStateType::AtECAL);
585
586 if (success) {
587 trk.addTrackState(tsAtEcal);
588 ldmx_log(debug) << "Successfully obtained TS at Ecal";
589 ldmx_log(debug) << "Parameters At Ecal: \n"
590 << tsAtEcal.params[0] << " " << tsAtEcal.params[1]
591 << " " << tsAtEcal.params[2] << " "
592 << tsAtEcal.params[3] << " " << tsAtEcal.params[4];
593 }
594 }
595
596 // Truth matching
597 if (truthMatchingTool) {
598 auto truthInfo = truthMatchingTool->TruthMatch(trk);
599 trk.setTrackID(truthInfo.trackID);
600 trk.setPdgID(truthInfo.pdgID);
601 trk.setTruthProb(truthInfo.truthProb);
602 }
603
604 // At least min_hits_ hits and p > 50 MeV
605 if (trk.getNhits() > min_hits_ && abs(1. / trk.getQoP()) > 0.05) {
606 tracks.push_back(trk);
607 ntracks_++;
608 }
609 }
610 } // loop seed track parameters
611
612 auto result_loop = std::chrono::high_resolution_clock::now();
613 profiling_map_["result_loop"] +=
614 std::chrono::duration<double, std::milli>(result_loop - ckf_run).count();
615
616 // Add the tracks to the event
617 event.add(out_trk_collection_, tracks);
618
619 auto end = std::chrono::high_resolution_clock::now();
620 // long long microseconds =
621 // std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
622 auto diff = end - start;
623 processing_time_ += std::chrono::duration<double, std::milli>(diff).count();
624}
625
627 if (use1Dmeasurements_)
628 ldmx_log(info) << "use1Dmeasurements = " << std::boolalpha
629 << use1Dmeasurements_;
630 if (remove_stereo_)
631 ldmx_log(info) << "remove_stereo = " << std::boolalpha << remove_stereo_;
632}
633
635 ldmx_log(info) << "found " << ntracks_ << " tracks / " << nseeds_
636 << " nseeds";
637 ldmx_log(info) << "AVG Time/Event: " << std::fixed << std::setprecision(1)
638 << processing_time_ / nevents_ << " ms";
639 ldmx_log(info) << "Breakdown::";
640 ldmx_log(info) << "setup Avg Time/Event = " << std::fixed
641 << std::setprecision(3) << profiling_map_["setup"] / nevents_
642 << " ms";
643 ldmx_log(info) << "hits Avg Time/Event = " << std::fixed
644 << std::setprecision(2) << profiling_map_["hits"] / nevents_
645 << " ms";
646 ldmx_log(info) << "seeds Avg Time/Event = " << std::fixed
647 << std::setprecision(3) << profiling_map_["seeds"] / nevents_
648 << " ms";
649 ldmx_log(info) << "cf_setup Avg Time/Event = " << std::fixed
650 << std::setprecision(3)
651 << profiling_map_["ckf_setup"] / nevents_ << " ms";
652 ldmx_log(info) << "ckf_run Avg Time/Event = " << std::fixed
653 << std::setprecision(3) << profiling_map_["ckf_run"] / nevents_
654 << " ms";
655 ldmx_log(info) << "result_loop Avg Time/Event = " << std::fixed
656 << std::setprecision(1)
657 << profiling_map_["result_loop"] / nevents_ << " ms";
658}
659
661 dumpobj_ = parameters.getParameter<bool>("dumpobj", 0);
662 pionstates_ = parameters.getParameter<int>("pionstates", 0);
663
664 bfield_ = parameters.getParameter<double>("bfield", -1.5);
665 const_b_field_ = parameters.getParameter<bool>("const_b_field", false);
666 field_map_ = parameters.getParameter<std::string>("field_map");
667 propagator_step_size_ =
668 parameters.getParameter<double>("propagator_step_size", 200.);
669 propagator_maxSteps_ =
670 parameters.getParameter<int>("propagator_maxSteps", 10000);
671 measurement_collection_ = parameters.getParameter<std::string>(
672 "measurement_collection", "TaggerMeasurements");
673 outlier_pval_ = parameters.getParameter<double>("outlier_pval_", 3.84);
674
675 debug_acts_ = parameters.getParameter<bool>("debug_acts", false);
676
677 remove_stereo_ = parameters.getParameter<bool>("remove_stereo", false);
678 use1Dmeasurements_ = parameters.getParameter<bool>("use1Dmeasurements", true);
679 min_hits_ = parameters.getParameter<int>("min_hits", 7);
680
681 // Ckf specific options
682 use_extrapolate_location_ =
683 parameters.getParameter<bool>("use_extrapolate_location", true);
684 extrapolate_location_ = parameters.getParameter<std::vector<double>>(
685 "extrapolate_location", {0., 0., 0.});
686 use_seed_perigee_ = parameters.getParameter<bool>("use_seed_perigee", false);
687
688 ldmx_log(debug) << " use_extrapolate_location ? "
689 << use_extrapolate_location_;
690 ldmx_log(debug) << " use_seed_perigee ? " << use_seed_perigee_;
691
692 // seeds from the event
693 seed_coll_name_ =
694 parameters.getParameter<std::string>("seed_coll_name", "seedTracks");
695
696 // output track collection
697 out_trk_collection_ =
698 parameters.getParameter<std::string>("out_trk_collection", "Tracks");
699
700 // keep track on which system tracking is running
701 taggerTracking_ = parameters.getParameter<bool>("taggerTracking", true);
702
703 // BField Systematics
704 map_offset_ =
705 parameters.getParameter<std::vector<double>>("map_offset_", {0., 0., 0.});
706}
707
708auto CKFProcessor::makeGeoIdSourceLinkMap(
710 const std::vector<ldmx::Measurement>& measurements)
711 -> std::unordered_multimap<Acts::GeometryIdentifier,
713 std::unordered_multimap<Acts::GeometryIdentifier,
715 geoId_sl_map;
716
717 ldmx_log(debug) << "makeGeoIdSourceLinkMap::Available measurements = "
718 << measurements.size();
719
720 // Check the hits associated to the surfaces
721 for (unsigned int i_meas = 0; i_meas < measurements.size(); i_meas++) {
722 ldmx::Measurement meas = measurements.at(i_meas);
723 unsigned int layerid = meas.getLayerID();
724
725 const Acts::Surface* hit_surface = tg.getSurface(layerid);
726
727 if (hit_surface) {
728 // Transform the ldmx space point from global to local and store the
729 // information
730
731 ActsExamples::IndexSourceLink idx_sl(hit_surface->geometryId(), i_meas);
732 // mg aug 2024 ... these don't print statements
733 // don't compile using v36 in Acts...figure out later
734 /*
735 ldmx_log(debug)
736 << "Insert measurement on surface located at::"
737 << hit_surface->transform(geometry_context()).translation();
738 ldmx_log(debug) << "and geoId::" << hit_surface->geometryId()
739 << std::endl;
740
741 ldmx_log(debug) << "Surface info::"
742 << std::tie(*hit_surface, geometry_context());
743 */
744 geoId_sl_map.insert(std::make_pair(hit_surface->geometryId(), idx_sl));
745
746 } else
747 std::cout << getName() << "::HIT " << i_meas << " at layer"
748 << (measurements.at(i_meas)).getLayerID()
749 << " is not associated to any surface?!" << std::endl;
750 }
751
752 return geoId_sl_map;
753}
754
755} // namespace reco
756} // namespace tracking
757
758DECLARE_PRODUCER_NS(tracking::reco, CKFProcessor)
#define DECLARE_PRODUCER_NS(NS, CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Implements an event buffer system for storing event data.
Definition Event.h:41
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:27
T getParameter(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:89
int getLayerID() const
Run-specific configuration and data stored in its own output TTree alongside the event TTree in the o...
Definition RunHeader.h:54
Class representing a simulated particle.
Definition SimParticle.h:23
Implementation of a track object.
Definition Track.h:52
void setPerigeeParameters(const std::vector< double > &par)
d_0 z_0 phi_0 theta q/p t
Definition Track.h:144
void produce(framework::Event &event) override
Run the processor.
void configure(framework::config::Parameters &parameters) override
Configure the processor using the given user specified parameters.
void onNewRun(const ldmx::RunHeader &rh) override
onNewRun is the first function called for each processor after the conditions are fully configured an...
CKFProcessor(const std::string &name, framework::Process &process)
Constructor.
int nseeds_
n seeds and n tracks
void onProcessStart() override
Callback for the EventProcessor to take any necessary action when the processing of events starts,...
void onProcessEnd() override
Callback for the EventProcessor to take any necessary action when the processing of events finishes,...
a helper base class providing some methods to shorten access to common conditions used within the tra...
void calibrate_1d(const Acts::GeometryContext &, const Acts::CalibrationContext &, const Acts::SourceLink &genericSourceLink, typename traj_t::TrackStateProxy trackState) const
Find the measurement corresponding to the source link.
void calibrate(const Acts::GeometryContext &, const Acts::CalibrationContext &, const Acts::SourceLink &genericSourceLink, typename traj_t::TrackStateProxy trackState) const
Find the measurement corresponding to the source link.
The measurement calibrator can be a function or a class/struct able to retrieve the sim hits containe...