20 bool debug_transform =
false;
21 auto transform_pos = [debug_transform](
const Acts::Vector3& pos_) {
22 Acts::Vector3 rot_pos;
25 rot_pos(2) = pos_(0) + DIPOLE_OFFSET;
30 if (debug_transform) {
31 std::cout <<
"PF::DEFAULT3 TRANSFORM\n";
32 std::cout <<
"PF::Check:: transforming Pos\n";
34 std::cout <<
"\nTO\n";
35 std::cout << rot_pos <<
"\n";
45 Acts::RotationMatrix3 rotation = Acts::RotationMatrix3::Identity();
48 auto transform_b_field = [rotation, scale, debug_transform](
49 const Acts::Vector3& field,
50 const Acts::Vector3& ) {
52 Acts::Vector3 rot_field;
53 rot_field(0) = field(2);
54 rot_field(1) = field(0);
55 rot_field(2) = field(1);
58 rot_field = scale * rot_field;
61 rot_field = rotation * rot_field;
65 if (debug_transform) {
66 std::cout <<
"PF::DEFAULT3 TRANSFORM\n";
67 std::cout <<
"PF::Check:: transforming\n";
69 std::cout <<
"\nTO\n";
70 std::cout << rot_field <<
"\n";
77 const auto map = std::make_shared<InterpolatedMagneticField3>(
81 transform_pos, transform_b_field));
83 auto acts_logging_level = Acts::Logging::FATAL;
85 if (
debug_) acts_logging_level = Acts::Logging::VERBOSE;
99 Acts::MultiEigenStepperLoop multi_stepper(map);
105 Acts::Navigator::Config nav_cfg{geometry().getTG()};
106 nav_cfg.resolveMaterial =
true;
107 nav_cfg.resolvePassive =
false;
108 nav_cfg.resolveSensitive =
true;
109 const Acts::Navigator navigator(nav_cfg);
111 auto gsf_propagator =
112 GsfPropagator(std::move(multi_stepper), std::move(navigator),
113 Acts::getDefaultLogger(
"GSF_PROP", acts_logging_level));
115 BetheHeitlerApprox bethe_heitler = Acts::makeDefaultBetheHeitlerApprox();
117 gsf_ = std::make_unique<std::decay_t<
decltype(*gsf_)>>(
118 std::move(gsf_propagator), std::move(bethe_heitler),
119 Acts::getDefaultLogger(
"GSF", acts_logging_level));
121 const auto stepper = Acts::EigenStepper<>{map};
124 Acts::getDefaultLogger(
"GSF_EXTRAP", acts_logging_level));
126 trk_extrap_ = std::make_shared<std::decay_t<
decltype(*trk_extrap_)>>(
127 *
propagator_, geometryContext(), magneticFieldContext());
183 Acts::GainMatrixUpdater updater;
184 Acts::GsfExtensions<Acts::VectorMultiTrajectory> gsf_extensions;
185 gsf_extensions.updater.connect<
186 &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
188 gsf_extensions.calibrator
190 Acts::VectorMultiTrajectory>>(&calibrator);
193 struct SurfaceAccessor {
194 const Acts::TrackingGeometry* tracking_geometry_;
196 const Acts::Surface* operator()(
const Acts::SourceLink& sourceLink)
const {
197 const auto& index_source_link =
199 return tracking_geometry_->findSurface(index_source_link.geometryId());
203 SurfaceAccessor m_sl_surface_accessor{tg.getTG().get()};
205 gsf_extensions.surfaceAccessor.connect<&SurfaceAccessor::operator()>(
206 &m_sl_surface_accessor);
207 gsf_extensions.mixtureReducer.connect<&Acts::reduceMixtureLargestWeights>();
212 Acts::PropagatorOptions<Acts::StepperPlainOptions,
213 Acts::NavigatorPlainOptions, ActionList, AbortList>
214 propagator_options(geometryContext(), magneticFieldContext());
216 propagator_options.pathLimit = std::numeric_limits<double>::max();
219 propagator_options.loopProtection =
false;
224 propagator_options.actionList.get<Acts::MaterialInteractor>();
225 m_interactor.multipleScattering =
true;
226 m_interactor.energyLoss =
true;
227 m_interactor.recordInteractions =
false;
231 propagator_options.actionList.get<Acts::detail::SteppingLogger>();
232 s_logger.sterile =
true;
234 propagator_options.stepping.maxStepSize =
242 std::shared_ptr<const Acts::Surface> gsf_ref_surface;
243 Acts::GsfOptions<Acts::VectorMultiTrajectory> gsf_options{
244 geometryContext(), magneticFieldContext(), calibrationContext()};
245 gsf_options.extensions = gsf_extensions;
246 gsf_options.propagatorPlainOptions = propagator_options;
253 std::vector<ldmx::Track> out_tracks;
255 Acts::VectorTrackContainer vtc;
256 Acts::VectorMultiTrajectory mtj;
257 Acts::TrackContainer tc{vtc, mtj};
260 unsigned int itrk = 0;
261 ldmx_log(debug) <<
"Starting GSF processing of " << tracks.size()
264 for (
auto& track : tracks) {
265 ldmx_log(debug) <<
"Processing track " << itrk <<
" with "
266 << track.getMeasurementsIdxs().size() <<
" measurements";
268 std::vector<ldmx::Measurement> meas_on_track;
271 std::vector<Acts::SourceLink> fit_track_source_links;
273 for (
auto imeas : track.getMeasurementsIdxs()) {
274 auto meas = measurements.at(imeas);
275 meas_on_track.push_back(meas);
279 const Acts::Surface* hit_surface =
280 tg.geo::TrackingGeometry::getSurface(meas.getLayerID());
284 fit_track_source_links.push_back(Acts::SourceLink(idx_sl));
288 std::reverse(meas_on_track.begin(), meas_on_track.end());
289 std::reverse(fit_track_source_links.begin(), fit_track_source_links.end());
291 for (
auto m : meas_on_track) {
292 ldmx_log(trace) <<
" Measurement:\n" << m <<
"\n";
295 ldmx_log(debug) <<
" Track bound track parameters preparation:";
300 Acts::Vector3 perigee_acts = tracking::sim::utils::ldmx2Acts(Acts::Vector3(
301 track.getPerigeeX(), track.getPerigeeY(), track.getPerigeeZ()));
302 std::shared_ptr<Acts::PerigeeSurface> perigee =
303 Acts::Surface::makeShared<Acts::PerigeeSurface>(perigee_acts);
305 Acts::BoundTrackParameters trk_btp =
306 tracking::sim::utils::boundTrackParameters(track, perigee);
310 Acts::BoundTrackParameters trk_btp_fit_start = trk_btp;
312 if (tagger_tracking_) {
313 auto opt_beam_origin =
315 if (!opt_beam_origin) {
316 ldmx_log(warn) <<
"Failed extrapolating to beam origin for GSF start. "
320 trk_btp_fit_start = *opt_beam_origin;
323 ldmx_log(debug) <<
" Perigee surface (acts): (" << track.getPerigeeX()
324 <<
", " << track.getPerigeeY() <<
", "
325 << track.getPerigeeZ() <<
")";
327 const Acts::BoundVector& trkpars = trk_btp.parameters();
328 ldmx_log(debug) <<
" Perigee parameters (d0, z0, phi, theta, q/p)= ("
329 << trkpars[Acts::eBoundLoc0] <<
", "
330 << trkpars[Acts::eBoundLoc1] <<
", "
331 << trkpars[Acts::eBoundPhi] <<
", "
332 << trkpars[Acts::eBoundTheta] <<
", "
333 << trkpars[Acts::eBoundQOverP] <<
")";
335 const Acts::BoundVector& fit_start_pars = trk_btp_fit_start.parameters();
336 ldmx_log(debug) <<
" GSF start parameters (d0, z0, phi, theta, q/p)= ("
337 << fit_start_pars[Acts::eBoundLoc0] <<
", "
338 << fit_start_pars[Acts::eBoundLoc1] <<
", "
339 << fit_start_pars[Acts::eBoundPhi] <<
", "
340 << fit_start_pars[Acts::eBoundTheta] <<
", "
341 << fit_start_pars[Acts::eBoundQOverP] <<
")";
343 ldmx_log(debug) <<
" About to run GSF fit with "
344 << fit_track_source_links.size() <<
" source links";
347 if (tagger_tracking_) {
352 gsf_options.referenceSurface = &(*gsf_ref_surface);
354 auto gsf_refit_result =
355 gsf_->fit(fit_track_source_links.begin(), fit_track_source_links.end(),
356 trk_btp_fit_start, gsf_options, tc);
358 if (!gsf_refit_result.ok()) {
359 ldmx_log(warn) <<
"GSF re-fit failed: "
360 << gsf_refit_result.error().message();
364 ldmx_log(debug) <<
" GSF fit succeeded, tc.size() = " << tc.size();
366 if (tc.size() < 1)
continue;
368 auto gsftrk = tc.getTrack(0);
371 const Acts::BoundVector& perigee_pars = gsftrk.parameters();
372 const Acts::BoundMatrix& trk_cov = gsftrk.covariance();
373 const Acts::Surface& perigee_surface = gsftrk.referenceSurface();
376 <<
" Reference Surface (acts-x, acts-y, acts-z) = ("
377 << perigee_surface.transform(geometryContext()).translation()(0) <<
", "
378 << perigee_surface.transform(geometryContext()).translation()(1) <<
", "
379 << perigee_surface.transform(geometryContext()).translation()(2) <<
")";
381 ldmx_log(debug) <<
" Found track has " << gsftrk.nTrackStates()
384 ldmx_log(debug) <<
" Track parameters (d0, z0, phi, theta, q/p)= ("
385 << perigee_pars[Acts::eBoundLoc0] <<
", "
386 << perigee_pars[Acts::eBoundLoc1] <<
", "
387 << perigee_pars[Acts::eBoundPhi] <<
", "
388 << perigee_pars[Acts::eBoundTheta] <<
", "
389 << perigee_pars[Acts::eBoundQOverP] <<
") ";
397 ldmx_log(debug) <<
" GSF target extrapolation succeeded";
398 auto ts_at_target = tracking::sim::utils::makeTrackState(
399 geometryContext(), *opt_target, ldmx::AtTarget);
400 trk.addTrackState(ts_at_target);
402 trk.setPerigeeParameters(tracking::sim::utils::convertActsToLdmxPars(
403 opt_target->parameters()));
404 if (opt_target->covariance()) {
405 std::vector<double> cov_vec;
406 tracking::sim::utils::flatCov(*(opt_target->covariance()), cov_vec);
407 trk.setPerigeeCov(cov_vec);
409 Acts::Vector3 target_loc_ldmx = tracking::sim::utils::acts2Ldmx(
411 trk.setPerigeeLocation(target_loc_ldmx[0], target_loc_ldmx[1],
415 <<
" GSF target parameters (d0, z0, phi, theta, q/p)= ("
416 << opt_target->parameters()[Acts::eBoundLoc0] <<
", "
417 << opt_target->parameters()[Acts::eBoundLoc1] <<
", "
418 << opt_target->parameters()[Acts::eBoundPhi] <<
", "
419 << opt_target->parameters()[Acts::eBoundTheta] <<
", "
420 << opt_target->parameters()[Acts::eBoundQOverP] <<
")";
422 ldmx_log(debug) <<
" GSF target extrapolation failed, using GSF fit "
423 "parameters at reference surface";
424 trk.setPerigeeParameters(
425 tracking::sim::utils::convertActsToLdmxPars(perigee_pars));
426 std::vector<double> v_trk_cov;
427 tracking::sim::utils::flatCov(trk_cov, v_trk_cov);
428 trk.setPerigeeCov(v_trk_cov);
432 if (tagger_tracking_) {
433 auto opt_beam_origin =
436 trk.addTrackState(tracking::sim::utils::makeTrackState(
437 geometryContext(), *opt_beam_origin, ldmx::AtBeamOrigin));
439 ldmx_log(debug) <<
" ECAL extrapolation";
440 auto opt_ecal = trk_extrap_->extrapolate(gsftrk,
ecal_surface_);
442 trk.addTrackState(tracking::sim::utils::makeTrackState(
443 geometryContext(), *opt_ecal, ldmx::AtECAL));
446 trk.setChi2(gsftrk.chi2());
447 trk.setNhits(gsftrk.nMeasurements());
448 trk.setNdf(gsftrk.nMeasurements() - 5);
449 trk.setCharge(perigee_pars[Acts::eBoundQOverP] > 0 ? 1 : -1);
452 trk.setTrackID(track.getTrackID());
453 trk.setPdgID(track.getPdgID());
454 trk.setTruthProb(track.getTruthProb());
458 ldmx_log(debug) <<
" Added track to output, total tracks = "
459 << (out_tracks.size() + 1);
461 out_tracks.push_back(trk);