92 lines
3.1 KiB
C++
92 lines
3.1 KiB
C++
// Copyright (2019-2023) Paul Scherrer Institute
|
|
|
|
#include "RadialIntegrationProfile.h"
|
|
#include "../common/JFJochException.h"
|
|
|
|
inline float sum_to_count(int64_t sum, uint64_t count) {
|
|
if (count == 0)
|
|
return 0.0f;
|
|
else
|
|
return static_cast<float>(static_cast<double>(sum) / (static_cast<double>(count * (1LU<<24))));
|
|
}
|
|
|
|
RadialIntegrationProfile::RadialIntegrationProfile(RadialIntegrationMapping &mapping,
|
|
const DiffractionExperiment& experiment)
|
|
: bin_to_q(mapping.GetBinToQ()),
|
|
sum(mapping.GetBinNumber(), 0),
|
|
count(mapping.GetBinNumber(), 0){
|
|
}
|
|
|
|
void RadialIntegrationProfile::Add(const std::vector<int64_t> &in_sum, const std::vector<uint64_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> RadialIntegrationProfile::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;
|
|
}
|
|
|
|
void RadialIntegrationProfile::GetPlot(JFJochProtoBuf::Plot &plot) const {
|
|
std::unique_lock<std::mutex> ul(m);
|
|
|
|
std::vector<float> rad_int_profile = GetResult();
|
|
|
|
*plot.mutable_x() = {bin_to_q.begin(), bin_to_q.end()};
|
|
*plot.mutable_y() = {rad_int_profile.begin(), rad_int_profile.end()};
|
|
}
|
|
|
|
float RadialIntegrationProfile::GetMeanValueOfBins(uint16_t min_bin, uint16_t max_bin) const {
|
|
std::unique_lock<std::mutex> ul(m);
|
|
|
|
int64_t 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);
|
|
}
|
|
|
|
RadialIntegrationProfile &RadialIntegrationProfile::operator+=(const RadialIntegrationProfile &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 RadialIntegrationProfile::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;
|
|
}
|
|
} |