e4b3064254
Reference dataset (a): LoadReferenceMtz adds column selection + cell/SG/resolution + a data-vs-reference consistency check; jfjoch_process/jfjoch_scale gain --reference-column; the viewer gets a Reference section in the MX settings dock (worker-owned, independent of the loaded dataset) that flows into reprocessing jobs. 3D combine (-P rot3d): Combine3D weight-sums a reflection's per-frame partials into one counting-limited full before merging (orthogonal ScalingSettings::combine_3d flag, not a partiality model), with a de-biased Poisson variance. Crystal 2: ISa 1.7->8.4, R-meas ~67%->18.9%, intensities unchanged (CCref held). Quality metrics (b): R-meas (Diederichs-Karplus) + redundancy columns in MergeStats; ISa logged. jfjoch fulls 18.9% vs XDS 4.5% (same ASU/run). Profile-fit integrator (experimental): ProfileIntegrate2D (--integrator gaussian|empirical) is a reference-free, rot3d-compatible profile-fit extraction (the decomposed PixelRefine intensity step). Gaussian: R-meas 18.9->14.6%, ISa ->9.5. Anisotropy/per-region add nothing (the discriminating info is in the discarded rocking direction). See NEXTGEN_INTEGRATOR.md. --dump-observations exports the unmerged fulls for XDS comparison. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
110 lines
3.6 KiB
C++
110 lines
3.6 KiB
C++
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#include <cmath>
|
|
|
|
#include "BraggIntegrationSettings.h"
|
|
#include "JFJochException.h"
|
|
|
|
#define check_max(param, val, max) if ((val) > (max)) throw JFJochException(JFJochExceptionCategory::InputParameterAboveMax, param)
|
|
#define check_min(param, val, min) if ((val) < (min)) throw JFJochException(JFJochExceptionCategory::InputParameterBelowMin, param)
|
|
#define check_finite(param, val) if (!std::isfinite(val)) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, param)
|
|
|
|
BraggIntegrationSettings &BraggIntegrationSettings::R1(float input) {
|
|
check_finite("Integration radius R1", input);
|
|
check_min("Integration radius R1", input, 0.1);
|
|
check_max("Integration radius R1", input, 20.0);
|
|
r_1 = input;
|
|
return *this;
|
|
}
|
|
|
|
BraggIntegrationSettings &BraggIntegrationSettings::R2(float input) {
|
|
check_finite("Background inner radius R2", input);
|
|
check_min("Background inner radius R2", input, 0.1);
|
|
check_max("Background inner radius R2", input, 30.0);
|
|
|
|
if (input <= r_1)
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"Background inner radius (R2) must be larger than integration radius (R1)");
|
|
|
|
r_2 = input;
|
|
return *this;
|
|
}
|
|
|
|
BraggIntegrationSettings &BraggIntegrationSettings::R3(float input) {
|
|
check_finite("Background outer radius R3", input);
|
|
check_min("Background outer radius R3", input, 0.1);
|
|
check_max("Background outer radius R3", input, 40.0);
|
|
|
|
if (input <= r_2)
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"Background outer radius (R3) must be larger than background inner radius (R2)");
|
|
|
|
r_3 = input;
|
|
return *this;
|
|
}
|
|
|
|
BraggIntegrationSettings &BraggIntegrationSettings::DMinLimit_A(float input) {
|
|
check_finite("Minimum d-spacing", input);
|
|
check_min("Minimum d-spacing", input, 0.5);
|
|
check_max("Minimum d-spacing", input, 100.0);
|
|
|
|
d_min_limit_A = input;
|
|
return *this;
|
|
}
|
|
|
|
BraggIntegrationSettings & BraggIntegrationSettings::FixedProfileRadius_recipA(std::optional<float> input) {
|
|
if (input) {
|
|
check_finite("Profile radius", input.value());
|
|
check_min("Profile radius [A^-1]", input.value(), 0.000001);
|
|
check_max("Profile radius [A^-1]", input.value(), 0.01);
|
|
}
|
|
fixed_profile_radius = input;
|
|
return *this;
|
|
|
|
}
|
|
|
|
std::optional<float> BraggIntegrationSettings::GetFixedProfileRadius_recipA() const {
|
|
return fixed_profile_radius;
|
|
}
|
|
|
|
BraggIntegrationSettings &BraggIntegrationSettings::Integrator(IntegratorMode input) {
|
|
integrator_mode = input;
|
|
return *this;
|
|
}
|
|
|
|
IntegratorMode BraggIntegrationSettings::GetIntegrator() const {
|
|
return integrator_mode;
|
|
}
|
|
|
|
float BraggIntegrationSettings::GetR1() const {
|
|
return r_1;
|
|
}
|
|
|
|
float BraggIntegrationSettings::GetProfileMultiplier() const {
|
|
return profile_multiplier;
|
|
}
|
|
|
|
BraggIntegrationSettings &BraggIntegrationSettings::ProfileMultiplier(float input) {
|
|
if (input <= 0.0f)
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Profile multiplier must be positive");
|
|
profile_multiplier = input;
|
|
return *this;
|
|
}
|
|
|
|
float BraggIntegrationSettings::GetR2() const {
|
|
return r_2;
|
|
}
|
|
|
|
float BraggIntegrationSettings::GetR3() const {
|
|
return r_3;
|
|
}
|
|
|
|
float BraggIntegrationSettings::GetDMinLimit_A() const {
|
|
return d_min_limit_A;
|
|
}
|
|
|
|
float BraggIntegrationSettings::GetMinimumSigmaInRegardsToI() const {
|
|
return minimum_sigma_in_regards_to_i;
|
|
}
|