121 const auto& measurements =
127 Acts::GainMatrixUpdater updater;
128 Acts::GsfExtensions<Acts::VectorMultiTrajectory> gsf_extensions;
129 gsf_extensions.updater.connect<
130 &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
132 gsf_extensions.calibrator
134 Acts::VectorMultiTrajectory>>(&calibrator);
137 struct SurfaceAccessor {
138 const Acts::TrackingGeometry* tracking_geometry_;
140 const Acts::Surface* operator()(
const Acts::SourceLink& sourceLink)
const {
141 const auto& index_source_link =
143 return tracking_geometry_->findSurface(index_source_link.geometryId());
147 SurfaceAccessor m_sl_surface_accessor{tg.getTG().get()};
149 gsf_extensions.surfaceAccessor.connect<&SurfaceAccessor::operator()>(
150 &m_sl_surface_accessor);
151 gsf_extensions.mixtureReducer.connect<&Acts::reduceMixtureLargestWeights>();
156 Acts::PropagatorOptions<Acts::StepperPlainOptions,
157 Acts::NavigatorPlainOptions, ActionList, AbortList>
158 propagator_options(geometryContext(), magneticFieldContext());
160 propagator_options.pathLimit = std::numeric_limits<double>::max();
163 propagator_options.loopProtection =
false;
168 propagator_options.actionList.get<Acts::MaterialInteractor>();
169 m_interactor.multipleScattering =
true;
170 m_interactor.energyLoss =
true;
171 m_interactor.recordInteractions =
false;
175 propagator_options.actionList.get<Acts::detail::SteppingLogger>();
176 s_logger.sterile =
true;
178 propagator_options.stepping.maxStepSize =
186 std::shared_ptr<const Acts::Surface> gsf_ref_surface;
187 Acts::GsfOptions<Acts::VectorMultiTrajectory> gsf_options{
188 geometryContext(), magneticFieldContext(), calibrationContext()};
189 gsf_options.extensions = gsf_extensions;
190 gsf_options.propagatorPlainOptions = propagator_options;
197 std::vector<ldmx::Track> out_tracks;
199 Acts::VectorTrackContainer vtc;
200 Acts::VectorMultiTrajectory mtj;
201 Acts::TrackContainer tc{vtc, mtj};
204 unsigned int itrk = 0;
205 ldmx_log(debug) <<
"Starting GSF processing of " << tracks.size()
208 for (
auto& track : tracks) {
209 ldmx_log(debug) <<
"Processing track " << itrk <<
" with "
210 << track.getMeasurementsIdxs().size() <<
" measurements";
212 std::vector<ldmx::Measurement> meas_on_track;
215 std::vector<Acts::SourceLink> fit_track_source_links;
217 for (
auto imeas : track.getMeasurementsIdxs()) {
218 auto meas = measurements.at(imeas);
219 meas_on_track.push_back(meas);
223 const Acts::Surface* hit_surface =
224 tg.geo::TrackingGeometry::getSurface(meas.getLayerID());
228 fit_track_source_links.push_back(Acts::SourceLink(idx_sl));
232 std::reverse(meas_on_track.begin(), meas_on_track.end());
233 std::reverse(fit_track_source_links.begin(), fit_track_source_links.end());
235 for (
auto m : meas_on_track) {
236 ldmx_log(trace) <<
" Measurement:\n" << m <<
"\n";
239 ldmx_log(debug) <<
" Track bound track parameters preparation:";
244 Acts::Vector3 perigee_acts = tracking::sim::utils::ldmx2Acts(Acts::Vector3(
245 track.getPerigeeX(), track.getPerigeeY(), track.getPerigeeZ()));
246 std::shared_ptr<Acts::PerigeeSurface> perigee =
247 Acts::Surface::makeShared<Acts::PerigeeSurface>(perigee_acts);
249 Acts::BoundTrackParameters trk_btp =
250 tracking::sim::utils::boundTrackParameters(track, perigee);
254 Acts::BoundTrackParameters trk_btp_fit_start = trk_btp;
256 if (tagger_tracking_) {
257 auto opt_beam_origin =
259 if (!opt_beam_origin) {
260 ldmx_log(warn) <<
"Failed extrapolating to beam origin for GSF start. "
264 trk_btp_fit_start = *opt_beam_origin;
267 ldmx_log(debug) <<
" Perigee surface (acts): (" << track.getPerigeeX()
268 <<
", " << track.getPerigeeY() <<
", "
269 << track.getPerigeeZ() <<
")";
271 const Acts::BoundVector& trkpars = trk_btp.parameters();
272 ldmx_log(debug) <<
" Perigee parameters (d0, z0, phi, theta, q/p)= ("
273 << trkpars[Acts::eBoundLoc0] <<
", "
274 << trkpars[Acts::eBoundLoc1] <<
", "
275 << trkpars[Acts::eBoundPhi] <<
", "
276 << trkpars[Acts::eBoundTheta] <<
", "
277 << trkpars[Acts::eBoundQOverP] <<
")";
279 const Acts::BoundVector& fit_start_pars = trk_btp_fit_start.parameters();
280 ldmx_log(debug) <<
" GSF start parameters (d0, z0, phi, theta, q/p)= ("
281 << fit_start_pars[Acts::eBoundLoc0] <<
", "
282 << fit_start_pars[Acts::eBoundLoc1] <<
", "
283 << fit_start_pars[Acts::eBoundPhi] <<
", "
284 << fit_start_pars[Acts::eBoundTheta] <<
", "
285 << fit_start_pars[Acts::eBoundQOverP] <<
")";
287 ldmx_log(debug) <<
" About to run GSF fit with "
288 << fit_track_source_links.size() <<
" source links";
291 if (tagger_tracking_) {
296 gsf_options.referenceSurface = &(*gsf_ref_surface);
298 auto gsf_refit_result =
299 gsf_->fit(fit_track_source_links.begin(), fit_track_source_links.end(),
300 trk_btp_fit_start, gsf_options, tc);
302 if (!gsf_refit_result.ok()) {
303 ldmx_log(warn) <<
"GSF re-fit failed: "
304 << gsf_refit_result.error().message();
308 ldmx_log(debug) <<
" GSF fit succeeded, tc.size() = " << tc.size();
310 if (tc.size() < 1)
continue;
312 auto gsftrk = tc.getTrack(0);
315 const Acts::BoundVector& perigee_pars = gsftrk.parameters();
316 const Acts::BoundMatrix& trk_cov = gsftrk.covariance();
317 const Acts::Surface& perigee_surface = gsftrk.referenceSurface();
320 <<
" Reference Surface (acts-x, acts-y, acts-z) = ("
321 << perigee_surface.transform(geometryContext()).translation()(0) <<
", "
322 << perigee_surface.transform(geometryContext()).translation()(1) <<
", "
323 << perigee_surface.transform(geometryContext()).translation()(2) <<
")";
325 ldmx_log(debug) <<
" Found track has " << gsftrk.nTrackStates()
328 ldmx_log(debug) <<
" Track parameters (d0, z0, phi, theta, q/p)= ("
329 << perigee_pars[Acts::eBoundLoc0] <<
", "
330 << perigee_pars[Acts::eBoundLoc1] <<
", "
331 << perigee_pars[Acts::eBoundPhi] <<
", "
332 << perigee_pars[Acts::eBoundTheta] <<
", "
333 << perigee_pars[Acts::eBoundQOverP] <<
") ";
341 ldmx_log(debug) <<
" GSF target extrapolation succeeded";
342 auto ts_at_target = tracking::sim::utils::makeTrackState(
343 geometryContext(), *opt_target, ldmx::AtTarget);
344 trk.addTrackState(ts_at_target);
346 trk.setPerigeeParameters(tracking::sim::utils::convertActsToLdmxPars(
347 opt_target->parameters()));
348 if (opt_target->covariance()) {
349 std::vector<double> cov_vec;
350 tracking::sim::utils::flatCov(*(opt_target->covariance()), cov_vec);
351 trk.setPerigeeCov(cov_vec);
353 Acts::Vector3 target_loc_ldmx = tracking::sim::utils::acts2Ldmx(
355 trk.setPerigeeLocation(target_loc_ldmx[0], target_loc_ldmx[1],
359 <<
" GSF target parameters (d0, z0, phi, theta, q/p)= ("
360 << opt_target->parameters()[Acts::eBoundLoc0] <<
", "
361 << opt_target->parameters()[Acts::eBoundLoc1] <<
", "
362 << opt_target->parameters()[Acts::eBoundPhi] <<
", "
363 << opt_target->parameters()[Acts::eBoundTheta] <<
", "
364 << opt_target->parameters()[Acts::eBoundQOverP] <<
")";
366 ldmx_log(debug) <<
" GSF target extrapolation failed, using GSF fit "
367 "parameters at reference surface";
368 trk.setPerigeeParameters(
369 tracking::sim::utils::convertActsToLdmxPars(perigee_pars));
370 std::vector<double> v_trk_cov;
371 tracking::sim::utils::flatCov(trk_cov, v_trk_cov);
372 trk.setPerigeeCov(v_trk_cov);
376 if (tagger_tracking_) {
377 auto opt_beam_origin =
380 trk.addTrackState(tracking::sim::utils::makeTrackState(
381 geometryContext(), *opt_beam_origin, ldmx::AtBeamOrigin));
383 ldmx_log(debug) <<
" ECAL extrapolation";
384 auto opt_ecal = trk_extrap_->extrapolate(gsftrk,
ecal_surface_);
386 trk.addTrackState(tracking::sim::utils::makeTrackState(
387 geometryContext(), *opt_ecal, ldmx::AtECAL));
390 trk.setChi2(gsftrk.chi2());
391 trk.setNhits(gsftrk.nMeasurements());
392 trk.setNdf(gsftrk.nMeasurements() - 5);
393 trk.setCharge(perigee_pars[Acts::eBoundQOverP] > 0 ? 1 : -1);
396 trk.setTrackID(track.getTrackID());
397 trk.setPdgID(track.getPdgID());
398 trk.setTruthProb(track.getTruthProb());
402 ldmx_log(debug) <<
" Added track to output, total tracks = "
403 << (out_tracks.size() + 1);
405 out_tracks.push_back(trk);