Run the processor.
154 {
155 eventnr_++;
156
157 auto tg{geometry()};
158
159
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
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
179 propagator_options.loopProtection =
180 false;
181
182
183 auto& mInteractor =
184 propagator_options.actionList.get<Acts::MaterialInteractor>();
185 mInteractor.multipleScattering = true;
186 mInteractor.energyLoss = true;
187 mInteractor.recordInteractions = false;
188
189
190 auto& sLogger =
191 propagator_options.actionList.get<Acts::detail::SteppingLogger>();
192 sLogger.sterile = true;
193
194 propagator_options.stepping.maxStepSize =
195 propagator_step_size_ * Acts::UnitConstants::mm;
196 propagator_options.maxSteps = propagator_maxSteps_;
197
198
199
200
201
202
203
204
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 =
212
213
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";
220 truthMatchingTool = std::make_shared<tracking::sim::TruthMatchingTool>(
221 particleMap, measurements);
222 }
223
224
225
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
233
234
235
236 ldmx_log(debug) << "Retrieve the seeds::" << seed_coll_name_;
237
238 const std::vector<ldmx::Track> seed_tracks =
240
241 ldmx_log(debug) << "Number of seeds::" << seed_tracks.size();
242
243
244 std::vector<Acts::BoundTrackParameters> startParameters;
245
246
247 std::vector<int> seedPDGID;
248
249 for (auto& seed : seed_tracks) {
250
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
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
278 }
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
293
294
295 Acts::MeasurementSelector::Config measurementSelectorCfg = {
296
297 {Acts::GeometryIdentifier(), {{}, {outlier_pval_}, {1u}}},
298 };
299
300 Acts::MeasurementSelector measSel{measurementSelectorCfg};
301
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
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
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
353
354
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
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
392 if (seedPDGID.at(trackId) != 0) {
393
394 }
395
396
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 ,
404 false );
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
421
422
423 auto& tracksFromSeed = results.value();
424
425 ldmx_log(debug) << "number of entries in results " << tracksFromSeed.size();
426 for (auto& track : tracksFromSeed) {
427
428 Acts::smoothTrack(geometry_context(), track);
429
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
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
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";
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
503
504
505
506
507
508
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
516 const Acts::BoundVector& track_pars = track.parameters();
517
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);
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
542
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
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
559 const std::shared_ptr<Acts::PlaneSurface> ecal_surface =
560 Acts::Surface::makeShared<Acts::PlaneSurface>(surf_transform);
561
562
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";
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
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
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
605 if (trk.getNhits() > min_hits_ && abs(1. / trk.getQoP()) > 0.05) {
606 tracks.push_back(trk);
607 ntracks_++;
608 }
609 }
610 }
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
617 event.add(out_trk_collection_, tracks);
618
619 auto end = std::chrono::high_resolution_clock::now();
620
621
622 auto diff = end - start;
623 processing_time_ += std::chrono::duration<double, std::milli>(diff).count();
624}
constexpr Index index() const
Access the index.
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.
Class representing a simulated particle.
Implementation of a track object.
void setPerigeeParameters(const std::vector< double > &par)
d_0 z_0 phi_0 theta q/p t
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.