Files
Jungfraujoch/image_analysis/AzimuthalIntegrationProfile.cpp

108 lines
3.5 KiB
C++

// Copyright (2019-2023) Paul Scherrer Institute
#include "AzimuthalIntegrationProfile.h"
#include "../common/JFJochException.h"
inline float sum_to_count(float sum, uint64_t count) {
if (count == 0)
return 0.0f;
else
return sum / (static_cast<float>(count));
}
AzimuthalIntegrationProfile::AzimuthalIntegrationProfile(const AzimuthalIntegrationMapping &mapping)
: bin_to_q(mapping.GetBinToQ()),
sum(mapping.GetBinNumber(), 0),
count(mapping.GetBinNumber(), 0){}
AzimuthalIntegrationProfile::AzimuthalIntegrationProfile(const AzimuthalIntegrationProfile &other)
: bin_to_q(other.bin_to_q),
sum(other.sum),
count(other.count) {}
AzimuthalIntegrationProfile::AzimuthalIntegrationProfile(AzimuthalIntegrationProfile &&other) noexcept {
bin_to_q = std::move(other.bin_to_q);
sum = std::move(other.sum);
count = std::move(other.count);
}
AzimuthalIntegrationProfile &AzimuthalIntegrationProfile::operator=(const AzimuthalIntegrationProfile &other) {
bin_to_q = other.bin_to_q;
sum = other.sum;
count = other.count;
return *this;
}
void AzimuthalIntegrationProfile::Add(const std::vector<float> &in_sum, const std::vector<uint32_t> &in_count) {
std::unique_lock<std::mutex> ul(m);
if ((in_sum.size() == sum.size()) && (in_count.size() == count.size())) {
for (int i = 0; i < sum.size(); i++) {
sum[i] += in_sum[i];
count[i] += in_count[i];
}
} else if (!in_sum.empty() && !in_count.empty())
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Mismatch in size of sum/count datasets");
}
std::vector<float> AzimuthalIntegrationProfile::GetResult() const {
std::vector<float> rad_int_profile(sum.size(), 0);
for (int i = 0; i < sum.size(); i++)
rad_int_profile[i] = sum_to_count(sum[i], count[i]);
return rad_int_profile;
}
Plot AzimuthalIntegrationProfile::GetPlot() const {
std::unique_lock<std::mutex> ul(m);
Plot ret;
ret.x = bin_to_q;
ret.y = GetResult();
return ret;
}
float AzimuthalIntegrationProfile::GetMeanValueOfBins(uint16_t min_bin, uint16_t max_bin) const {
std::unique_lock<std::mutex> ul(m);
float ret_sum = 0;
uint64_t ret_count = 0;
for (int i = std::min((uint16_t)sum.size(),min_bin);
i <= std::min((uint16_t)(sum.size()-1),max_bin);
i++) {
ret_sum += sum[i];
ret_count += count[i];
}
return sum_to_count(ret_sum, ret_count);
}
AzimuthalIntegrationProfile &AzimuthalIntegrationProfile::operator+=(const AzimuthalIntegrationProfile &other) {
std::unique_lock<std::mutex> ul(m);
// It is expected that "other" has exclusive access
if ((other.bin_to_q != bin_to_q) || (sum.size() != other.sum.size())) {
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Error combining two radial integration profiles");
}
for (int i = 0; i < sum.size(); i++) {
sum[i] += other.sum[i];
count[i] += other.count[i];
}
return *this;
}
void AzimuthalIntegrationProfile::Add(const DeviceOutput &result) {
std::unique_lock<std::mutex> ul(m);
if (sum.size() > FPGA_INTEGRATION_BIN_COUNT )
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Error in getting result from FPGA");
for (int i = 0; i < sum.size(); i++) {
sum[i] += result.integration_result[i].sum;
count[i] += result.integration_result[i].count;
}
}