Files
Jungfraujoch/common/AzimuthalIntegrationSettings.cpp
2025-03-24 12:16:33 +01:00

99 lines
3.6 KiB
C++

// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include <cmath>
#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<float> &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<float> 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())));
}