Files
Jungfraujoch/common/BraggIntegrationSettings.cpp
T
leonarski_fandClaude Opus 4.8 3aec235f67
Build Packages / Unit tests (push) Successful in 59m53s
Build Packages / build:windows:nocuda (push) Successful in 18m24s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 14m30s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 14m33s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 14m54s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 14m20s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 15m2s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 15m29s
Build Packages / build:rpm (rocky8) (push) Successful in 14m37s
Build Packages / build:rpm (rocky9) (push) Successful in 12m44s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 12m10s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 11m21s
Build Packages / DIALS test (push) Successful in 12m22s
Build Packages / XDS test (durin plugin) (push) Successful in 7m34s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 7m41s
Build Packages / XDS test (neggia plugin) (push) Successful in 7m52s
Build Packages / Generate python client (push) Successful in 24s
Build Packages / Build documentation (push) Successful in 1m0s
Build Packages / Create release (push) Skipped
Build Packages / build:windows:cuda (push) Successful in 16m53s
integration: add --reciprocal-profile dial (global reciprocal-space width)
The per-shell profile width is learned in pixels, so it varies ~4x with resolution
(mostly the geometric projection of a near-constant reciprocal-space relrod) and must
be binned per shell -> it starves at high resolution / on sparse data. The new
--reciprocal-profile flag instead learns ONE global width in reciprocal space,
sigma2_q,tan = A + B|q| + C|q|^2: the Jacobian g_tan=cos(2theta) removes the geometric
projection, and C|q|^2 is the crystal mosaicity relrod (variance ~(eta|q|)^2). Applied
per reflection as sigma2_tan,px = (A + B|q| + C|q|^2)/g_tan^2 (B,C clamped >=0;
quadratic->linear->constant fallback).

Off by default. On the sharp HEWL test crystal (mosaicity 0.091deg, so C fits to ~0 and
it reduces to the validated linear form) it is metric-neutral: ISa 16.2->16.3, anomalous
0.92x unchanged, CCref band 90.0->89.9, CC1/2 a touch lower (per-shell isn't starved at
23k spots/shell, and a global fit is less flexible). So: simpler + more transferable at a
small CC1/2 cost, ISa/anomalous held. Its payoff is on MOSAIC crystals (large C|q|^2),
where per-shell starves on the wide weak high-res spots and 6 shells are too coarse; both
lyso test crystals are sharp, so it ships as a dial to try on mosaic data elsewhere.
A separate radial relrod fit was tried and dropped (no gain). See NEXTGEN_INTEGRATOR.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 14:26:08 +02:00

108 lines
3.4 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;
}
BraggIntegrationSettings &BraggIntegrationSettings::ReciprocalProfile(bool input) {
reciprocal_profile = input;
return *this;
}
bool BraggIntegrationSettings::GetReciprocalProfile() const {
return reciprocal_profile;
}
float BraggIntegrationSettings::GetR1() const {
return r_1;
}
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;
}