v1.0.0-rc.41

This commit is contained in:
2025-06-10 18:14:04 +02:00
parent 72cdbd04a5
commit 41a3e671f4
244 changed files with 3064 additions and 705 deletions

View File

@@ -2,64 +2,60 @@
// SPDX-License-Identifier: GPL-3.0-only
#include "QuickIntegrate.h"
#include "BraggPrediction.h"
#include <iostream>
#include "IntegrationStats.h"
QuickIntegrate::QuickIntegrate(const DiffractionExperiment &in_experiment)
: experiment(in_experiment) {}
template<class T>
std::vector<Reflection> QuickIntegrate::IntegrateInternal(const CompressedImage &image, const CrystalLattice &latt,
int64_t special_value, int64_t saturation) {
QuickIntegrateResult QuickIntegrate::IntegrateInternal(const CompressedImage &image,
const CrystalLattice &latt,
int64_t special_value,
int64_t saturation,
float high_res_A) {
auto start = std::chrono::high_resolution_clock::now();
std::vector<uint8_t> buffer;
auto ptr = reinterpret_cast<const T*>(image.GetUncompressedPtr(buffer));
std::vector<Reflection> ret;
BraggPrediction prediction(experiment,latt, high_res_A, ewald_sphere_angle_cutoff);
auto refl = prediction.GetReflections(ewald_sphere_angle_cutoff);
Coord Astar = latt.Astar();
Coord Bstar = latt.Bstar();
Coord Cstar = latt.Cstar();
QuickIntegrateResult ret;
IntegrationStats stats(6.0, high_res_A, 10); // Wilson statistics is only linear in certain resolution range
DiffractionGeometry geom = experiment.GetDiffractionGeometry();
for (int h = -max_value; h < max_value; h++) {
for (int k = -max_value; k < max_value; k++) {
for (int l = -max_value; l < max_value; l++) {
Coord recip = Astar * h + Bstar * k + Cstar * l;
float d = 1.0f / recip.Length();
float dist_ewald_sphere = geom.DistFromEwaldSphere(recip);
if (d > d_min && dist_ewald_sphere < ewald_sphere_dist_cutoff) {
auto [x,y] = geom.RecipToDector(recip);
if ((x >= 0) && (x < image.GetWidth()) && (y >= 0) && (y < image.GetHeight())) {
Reflection r{.h = h, .k = k, .l = l, .center_x = x, .center_y = y, .d = d};
bool observed = IntegrateInternal(r, ptr, image.GetWidth(), image.GetHeight(),
x, y, special_value, saturation);
if (observed)
ret.push_back(r);
}
}
}
for (const auto &r_iter: refl) {
Reflection r = r_iter;
if (IntegrateInternal(r, ptr, image.GetWidth(), image.GetHeight(), special_value, saturation)) {
ret.reflections.push_back(r);
stats.AddReflection(r);
}
}
ret.b_factor = stats.BFactor();
return ret;
}
std::vector<Reflection> QuickIntegrate::Integrate(const CompressedImage& image, const CrystalLattice &latt) {
QuickIntegrateResult QuickIntegrate::Integrate(const CompressedImage& image,
const CrystalLattice &latt,
float high_res_A) {
if (image.GetCompressedSize() == 0)
return {};
switch (image.GetMode()) {
case CompressedImageMode::Int8:
return IntegrateInternal<int8_t>(image, latt, INT8_MIN, INT8_MAX);
return IntegrateInternal<int8_t>(image, latt, INT8_MIN, INT8_MAX, high_res_A);
case CompressedImageMode::Int16:
return IntegrateInternal<int16_t>(image, latt, INT16_MIN, INT16_MAX);
return IntegrateInternal<int16_t>(image, latt, INT16_MIN, INT16_MAX, high_res_A);
case CompressedImageMode::Int32:
return IntegrateInternal<int32_t>(image, latt, INT32_MIN, INT32_MAX);
return IntegrateInternal<int32_t>(image, latt, INT32_MIN, INT32_MAX, high_res_A);
case CompressedImageMode::Uint8:
return IntegrateInternal<uint8_t>(image, latt, UINT8_MAX, UINT8_MAX);
return IntegrateInternal<uint8_t>(image, latt, UINT8_MAX, UINT8_MAX, high_res_A);
case CompressedImageMode::Uint16:
return IntegrateInternal<uint16_t>(image, latt, UINT16_MAX, UINT16_MAX);
return IntegrateInternal<uint16_t>(image, latt, UINT16_MAX, UINT16_MAX, high_res_A);
case CompressedImageMode::Uint32:
return IntegrateInternal<uint16_t>(image, latt, UINT32_MAX, UINT32_MAX);
return IntegrateInternal<uint16_t>(image, latt, UINT32_MAX, UINT32_MAX, high_res_A);
default:
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Image mode not supported");
@@ -69,15 +65,14 @@ std::vector<Reflection> QuickIntegrate::Integrate(const CompressedImage& image,
template<class T>
bool QuickIntegrate::IntegrateInternal(Reflection &r, const T *image, size_t xpixel, size_t ypixel,
float center_x, float center_y,
int64_t special_value, int64_t saturation) {
r.I = 0;
r.bkg = 0;
int64_t x0 = std::floor(center_x - r_3 - 1.0);
int64_t x1 = std::ceil(center_x + r_3 + 1.0);
int64_t y0 = std::floor(center_y - r_3 - 1.0);
int64_t y1 = std::ceil(center_y + r_3 + 1.0);
int64_t x0 = std::floor(r.center_x_pxl - r_3 - 1.0);
int64_t x1 = std::ceil(r.center_x_pxl + r_3 + 1.0);
int64_t y0 = std::floor(r.center_y_pxl - r_3 - 1.0);
int64_t y1 = std::ceil(r.center_y_pxl + r_3 + 1.0);
if (x0 < 0)
x0 = 0;
if (y0 < 0)
@@ -94,7 +89,7 @@ bool QuickIntegrate::IntegrateInternal(Reflection &r, const T *image, size_t xpi
for (int64_t y = y0; y <= y1; y++) {
for (int64_t x = x0; x <= x1; x++) {
float dist_sq = (x - center_x) * (x - center_x) + (y - center_y) * (y - center_y);
float dist_sq = (x - r.center_x_pxl) * (x - r.center_x_pxl) + (y - r.center_y_pxl) * (y - r.center_y_pxl);
if (image[y * xpixel + x] == special_value || image[y * xpixel + x] == saturation) {
continue;
} else if (dist_sq < r_1_sq) {