// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include #include "AzimuthalIntegrationSettings.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) AzimuthalIntegrationSettings &AzimuthalIntegrationSettings::SolidAngleCorrection(bool input) { solid_angle_correction = input; return *this; } AzimuthalIntegrationSettings &AzimuthalIntegrationSettings::PolarizationFactor(const std::optional &input) { if (input.has_value()) { check_finite("Polarization factor", input.value()); check_min("Polarization factor", input.value(), -1.0); check_max("Polarization factor", input.value(), 1.0); } polarization_factor = input; return *this; } AzimuthalIntegrationSettings &AzimuthalIntegrationSettings::QRange_recipA(float low, float high) { check_finite("Low Q for azimuthal integration", low); check_finite("High Q for azimuthal integration", high); check_max("High Q for azimuthal integration", high, 10.0); check_min("Low Q for azimuthal integration", low, 0.001); if (high <= low) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "High Q must be higher than low Q"); high_q_recipA = high; low_q_recipA = low; return *this; } AzimuthalIntegrationSettings &AzimuthalIntegrationSettings::QSpacing_recipA(float input) { check_finite("Q spacing for azimuthal integration", input); check_min("Q spacing for azimuthal integration", input, 0.00999); q_spacing = input; return *this; } bool AzimuthalIntegrationSettings::IsSolidAngleCorrection() const { return solid_angle_correction; } std::optional AzimuthalIntegrationSettings::GetPolarizationFactor() const { return polarization_factor; } float AzimuthalIntegrationSettings::GetHighQ_recipA() const { return high_q_recipA; } float AzimuthalIntegrationSettings::GetLowQ_recipA() const { return low_q_recipA; } float AzimuthalIntegrationSettings::GetQSpacing_recipA() const { return q_spacing; } float AzimuthalIntegrationSettings::GetBinNumber() const { return std::ceil((high_q_recipA - low_q_recipA) / q_spacing); } AzimuthalIntegrationSettings &AzimuthalIntegrationSettings::BkgEstimateQRange_recipA(float low, float high) { check_finite("Low Q for azimuthal integration", low); check_finite("High Q for azimuthal integration", high); check_max("High Q for azimuthal integration", high, 10.0); check_min("Low Q for azimuthal integration", low, 0.001); if (high <= low) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "High Q must be higher than low Q"); bkg_estimate_low_q_recipA = low; bkg_estimate_high_q_recipA = high; return *this; } float AzimuthalIntegrationSettings::GetBkgEstimateLowQ_recipA() const { return bkg_estimate_low_q_recipA; } float AzimuthalIntegrationSettings::GetBkgEstimateHighQ_recipA() const { return bkg_estimate_high_q_recipA; } uint16_t AzimuthalIntegrationSettings::QToBin(float q) const { return std::floor(std::min(GetBinNumber(), std::max(0.0f, (q - GetLowQ_recipA()) / GetQSpacing_recipA()))); }