ScalingResult: Dedicated data structure
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
Reference in New Issue
Block a user