diff --git a/process/JFJochProcess.cpp b/process/JFJochProcess.cpp index 9a6f424d..c9ada9e8 100644 --- a/process/JFJochProcess.cpp +++ b/process/JFJochProcess.cpp @@ -560,6 +560,11 @@ ProcessResult JFJochProcess::Run(JFJochProcessObserver *observer) { std::vector merged; MergeStatistics statistics; }; + // The reference path computes each image's G once (per-image scaling against the + // reference); the scaling loop below is skipped, so G is stable across the two passes. + // Smoothing it more than once would compound the correction, so do it only on the first + // pass. The no-reference path recomputes G from scratch each pass and re-smooths correctly. + bool reference_g_smoothed = false; auto scale_and_merge = [&](const std::string &label) -> ScaleMergeResult { // ScaleOnTheFly self-scaling is only for the no-reference path; with a reference each // image is already scaled against it during the per-image pass, so we merge directly. @@ -580,7 +585,8 @@ ProcessResult JFJochProcess::Run(JFJochProcessObserver *observer) { const double smooth_g_deg = experiment_.GetScalingSettings().GetSmoothGDegrees(); const auto gonio = experiment_.GetGoniometer(); const double osc_deg = gonio ? std::fabs(gonio->GetIncrement_deg()) : 0.0; - if (rot3d && smooth_g_deg > 0.0 && osc_deg > 1e-6) { + const bool reference_path = !config_.reference_data.empty(); + if (rot3d && smooth_g_deg > 0.0 && osc_deg > 1e-6 && !(reference_path && reference_g_smoothed)) { int window = std::max(1, static_cast(std::lround(smooth_g_deg / osc_deg))); if (window % 2 == 0) ++window; // odd window for a centered average @@ -588,6 +594,7 @@ ProcessResult JFJochProcess::Run(JFJochProcessObserver *observer) { logger.Info("Smoothing per-frame scale G over {:.2f} deg ({} frames at {:.3f} deg/frame)", smooth_g_deg, window, osc_deg); SmoothImageScaleG(indexer->GetIntegrationOutcome(), window, logger); + reference_g_smoothed = true; } std::vector combined; if (rot3d) {