120 lines
4.2 KiB
C++
120 lines
4.2 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::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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
AzimuthalIntegrationSettings &AzimuthalIntegrationSettings::PolarizationCorrection(bool input) {
|
|
polarization_correction = input;
|
|
return *this;
|
|
}
|
|
|
|
bool AzimuthalIntegrationSettings::IsPolarizationCorrection() const {
|
|
return polarization_correction;
|
|
}
|
|
|
|
AzimuthalIntegrationSettings &AzimuthalIntegrationSettings::AzimuthalBinCount(int32_t input) {
|
|
check_min("Azimuthal bin count", input, 1);
|
|
check_max("Azimuthal bin count", input, 512);
|
|
azim_bins = input;
|
|
return *this;
|
|
}
|
|
|
|
int32_t AzimuthalIntegrationSettings::GetQBinCount() const {
|
|
return std::ceil((high_q_recipA - low_q_recipA) / q_spacing);
|
|
}
|
|
|
|
int32_t AzimuthalIntegrationSettings::GetAzimuthalBinCount() const {
|
|
return azim_bins;
|
|
}
|
|
|
|
int32_t AzimuthalIntegrationSettings::GetBinCount() const {
|
|
return GetQBinCount() * GetAzimuthalBinCount();
|
|
}
|
|
|
|
uint16_t AzimuthalIntegrationSettings::QToBin(float q) const {
|
|
return std::min<uint16_t>(GetBinCount() - 1, std::floor(std::max(0.0f, (q - GetLowQ_recipA()) / GetQSpacing_recipA())));
|
|
}
|
|
|
|
uint16_t AzimuthalIntegrationSettings::GetBin(float q, float phi_deg) const {
|
|
if (q < low_q_recipA || q >= high_q_recipA)
|
|
return UINT16_MAX;
|
|
if (phi_deg < 0.0 || phi_deg >= 360)
|
|
return UINT16_MAX;
|
|
|
|
int16_t q_bin = std::floor((q - low_q_recipA) / q_spacing);
|
|
int16_t phi_bin = std::floor(phi_deg / 360.0f * azim_bins);
|
|
return q_bin + phi_bin * GetQBinCount();
|
|
}
|