ScalingResult: Dedicated data structure

This commit is contained in:
2026-05-10 17:41:12 +02:00
parent eea438185c
commit 440e54d588
8 changed files with 72 additions and 14 deletions
+1 -1
View File
@@ -276,7 +276,7 @@ std::optional<RotationIndexerResult> IndexAndRefine::Finalize() {
return {};
}
std::optional<ScaleResult> IndexAndRefine::ScaleAllImages(const ScaleMergeOptions &opts) {
std::optional<ScalingResult> IndexAndRefine::ScaleAllImages(const ScaleMergeOptions &opts) {
size_t nrefl = 0;
for (const auto &i: reflections)
nrefl += i.size();
+1 -1
View File
@@ -62,7 +62,7 @@ public:
void ProcessImage(DataMessage &msg, const SpotFindingSettings &settings, const CompressedImage &image, BraggPrediction &prediction);
std::optional<ScaleResult> ScaleAllImages(const ScaleMergeOptions &opts = {});
std::optional<ScalingResult> ScaleAllImages(const ScaleMergeOptions &opts = {});
/// Run scale-and-merge on accumulated reflections to refine per-image
/// mosaicity (and optionally B-factors / scale factors).
+2 -1
View File
@@ -6,5 +6,6 @@ ADD_LIBRARY(JFJochScaleMerge ScaleAll.cpp ScaleAll.h FrenchWilson.cpp FrenchWils
ScaleOnTheFly.cpp
ScaleOnTheFly.h
HKLKey.cpp
HKLKey.h)
HKLKey.h
ScalingResult.h)
TARGET_LINK_LIBRARIES(JFJochScaleMerge Ceres::ceres Eigen3::Eigen JFJochCommon)
+2 -2
View File
@@ -410,7 +410,7 @@ namespace {
}
}
ScaleResult ScaleAll(std::vector<std::vector<Reflection> > &observations,
ScalingResult ScaleAll(std::vector<std::vector<Reflection> > &observations,
const ScaleMergeOptions &opt) {
if (opt.image_cluster <= 0)
throw std::invalid_argument("image_cluster must be positive");
@@ -442,7 +442,7 @@ ScaleResult ScaleAll(std::vector<std::vector<Reflection> > &observations,
CalcCorrections(observations, opt, G, mosaicity, R_sq);
ScaleResult out{};
ScalingResult out{};
out.image_scale_g.resize(observations.size(), NAN);
out.mosaicity_deg.resize(observations.size(), NAN);
+2 -8
View File
@@ -4,13 +4,7 @@
#pragma once
#include "Merge.h"
#include "ScalingResult.h"
struct ScaleResult {
std::vector<float> image_scale_g;
std::vector<float> mosaicity_deg;
std::vector<float> image_bfactor_Ang2;
};
ScaleResult ScaleAll(std::vector<std::vector<Reflection>>& observations,
const ScaleMergeOptions& opt = {});
ScalingResult ScaleAll(std::vector<std::vector<Reflection>>& observations, const ScaleMergeOptions& opt = {});
@@ -3,6 +3,52 @@
#include "ScaleOnTheFly.h"
#include <ceres/ceres.h>
double SafeInv(double x, double fallback) {
if (!std::isfinite(x) || x == 0.0)
return fallback;
return 1.0 / x;
}
struct IntensityRotationResidual {
IntensityRotationResidual(const Reflection &r, double Itrue, double sigma)
: Iobs(r.I),
Itrue(Itrue),
weight(SafeInv(sigma, 1.0)),
delta_phi_deg(r.delta_phi_deg),
lp(SafeInv(r.rlp, 1.0)),
c1(r.zeta / std::sqrt(2.0)),
b_resolution_coeff(SafeInv(-r.d * r.d / 4.0, 0.0)) {
}
template<typename T>
bool operator()(const T *const G,
const T *const B,
const T *const mosaicity,
const T *const wedge,
T *residual) const {
const T partiality = T(1.0);
if (mosaicity > 0) {
const T half_wedge = wedge[0] / T(2.0);
const T arg_plus = T(delta_phi_deg + half_wedge) * T(c1) / mosaicity[0];
const T arg_minus = T(delta_phi_deg - half_wedge) * T(c1) / mosaicity[0];
partiality = (ceres::erf(arg_plus) - ceres::erf(arg_minus)) / T(2.0);
}
const T B_term = ceres::exp(T(B[0]) * b_resolution_coeff);
residual[0] = (G[0] * partiality * T(lp) * Itrue - T(Iobs)) * T(weight);
return true;
}
double Iobs;
double Itrue;
double weight;
double delta_phi_deg;
double lp;
double c1;
double b_resolution_coeff;
};
ScaleOnTheFly::ScaleOnTheFly(const std::vector<MergedReflection> &ref,
std::optional<gemmi::SpaceGroup> sg,
bool merge_friedel) : sg(sg), merge_friedel(merge_friedel) {
@@ -11,3 +57,7 @@ ScaleOnTheFly::ScaleOnTheFly(const std::vector<MergedReflection> &ref,
reference_data[key] = r.I;
}
}
std::optional<ScalingResult> ScaleOnTheFly::Scale(std::vector<Reflection> &reflections) {
}
+2 -1
View File
@@ -5,6 +5,7 @@
#include "HKLKey.h"
#include "Merge.h"
#include "ScalingResult.h"
#include <map>
@@ -14,6 +15,6 @@ class ScaleOnTheFly {
std::map<HKLKey, double> reference_data;
public:
ScaleOnTheFly(const std::vector<MergedReflection> &ref, std::optional<gemmi::SpaceGroup> sg, bool merge_friedel = true);
void Scale(std::vector<Reflection> &reflections);
std::optional<ScalingResult> Scale(std::vector<Reflection> &reflections);
};
@@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <vector>
struct ScalingResult {
std::vector<float> image_scale_g;
std::vector<float> mosaicity_deg;
std::vector<float> image_bfactor_Ang2;
};