Files
Jungfraujoch/image_analysis/scale_merge/Merge.h
T

104 lines
3.4 KiB
C++

// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <map>
#include <random>
#include <vector>
#include "../../common/Logger.h"
#include "../../common/DiffractionExperiment.h"
#include "../../common/Reflection.h"
#include "HKLKey.h"
struct MergeStatisticsShell {
float d_min = 0.0f;
float d_max = 0.0f;
float mean_one_over_d2 = 0;
int total_observations = 0;
int unique_reflections = 0;
int possible_unique_reflections = 0;
double mean_i_over_sigma = 0.0;
double cc_half = 0.0f;
double cc_ref = NAN;
};
struct MergeStatistics {
std::vector<MergeStatisticsShell> shells;
MergeStatisticsShell overall;
};
std::ostream &operator<<(std::ostream &output, const MergeStatisticsShell &in);
std::ostream &operator<<(std::ostream &output, const MergeStatistics &in);
struct MergeAccum {
int32_t h = 0;
int32_t k = 0;
int32_t l = 0;
float d = NAN;
double sum_wI = 0.0;
double sum_w = 0.0;
double sum_wI_half[2] = {0.0, 0.0};
double sum_w_half[2] = {0.0, 0.0};
size_t n_half[2] = {0, 0};
};
class MergeOnTheFly {
mutable std::mutex merged_mutex;
ScalingSettings scaling_settings;
IndexingSettings indexing_settings;
std::optional<UnitCell> reference_cell;
std::optional<double> high_resolution_limit;
std::optional<double> image_cc_limit;
double min_partiality = 0.02;
HKLKeyGenerator generator;
// To select images for half-datasets to calculate CC1/2, I use a random number generator with a fixed seed.
// This makes sure that images are selected randomly, but in a fully reproducible manner (at least for the same binary)
std::mt19937 rng{123456789u};
std::bernoulli_distribution half_dist{0.5};
std::map<uint64_t, MergeAccum> accumulator;
void ProcessImage_i(const std::vector<Reflection> &v, int half);
public:
MergeOnTheFly(const DiffractionExperiment &x);
MergeOnTheFly& ReferenceCell(const std::optional<UnitCell> &cell);
void AddAll(const std::vector<std::vector<Reflection> > &reflections,
const std::vector<uint8_t> &merge_mask = {});
void AddImage(const std::vector<Reflection> &v, double image_cc, const UnitCell &cell);
std::vector<MergedReflection> ExportReflections();
};
size_t CalcMergeMaskCC(const DiffractionExperiment &x,
const std::vector<float> &scale_cc,
std::vector<uint8_t> &result_mask);
size_t CalcMergeMaskUnitCell(const DiffractionExperiment &x,
const UnitCell &reference_cell,
const std::vector<std::optional<UnitCell> > &unit_cells,
std::vector<uint8_t> &mask);
std::vector<MergedReflection> MergeAll(const DiffractionExperiment &x,
const std::vector<std::vector<Reflection> > &reflections,
const std::vector<uint8_t> &merge_mask = {});
MergeStatistics MergeStats(const DiffractionExperiment &x,
const std::vector<MergedReflection> &merged,
const std::vector<std::vector<Reflection> > &reflections,
const UnitCell &cell,
const std::vector<uint8_t> &merge_mask = {},
const std::vector<MergedReflection> &reference = {});