Files
Jungfraujoch/image_analysis/SpotAnalyze.cpp
2025-09-21 19:27:51 +02:00

106 lines
4.5 KiB
C++

// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include "SpotAnalyze.h"
#include "geom_refinement/XtalOptimizer.h"
#include "spot_finding/SpotUtils.h"
#include "spot_finding/StrongPixelSet.h"
#include "bragg_integration/BraggIntegrate2D.h"
#include "indexing/AnalyzeIndexing.h"
void SpotAnalyze(const DiffractionExperiment &experiment,
const SpotFindingSettings &spot_finding_settings,
const std::vector<DiffractionSpot> &spots,
const CompressedImage &image,
IndexerThreadPool *indexer,
DataMessage &output) {
std::vector<SpotToSave> spots_out;
auto geom = experiment.GetDiffractionGeometry();
for (const auto &spot: spots)
spots_out.push_back(spot.Export(geom));
if (experiment.GetDatasetSettings().IsDetectIceRings() && spot_finding_settings.ice_ring_width_Q_recipA > 0.0f)
MarkIceRings(spots_out, spot_finding_settings.ice_ring_width_Q_recipA);
CountSpots(output, spots_out, spot_finding_settings.cutoff_spot_count_low_res);
FilterSpotsByCount(spots_out, experiment.GetMaxSpotCount());
output.spots = spots_out;
if ((indexer != nullptr) && spot_finding_settings.indexing) {
auto latt_f = indexer->Run(experiment, output);
auto latt = latt_f.get();
if (!latt)
output.indexing_result = false;
else {
bool beam_center_updated = false;
DiffractionExperiment experiment_copy(experiment);
XtalOptimizerData data{
.geom = experiment_copy.GetDiffractionGeometry(),
.latt = latt.value(),
.crystal_system = experiment.GetCrystalSystem(),
.centering = experiment.GetCentering(),
.min_spots = experiment.GetIndexingSettings().GetViableCellMinSpots()
};
switch (experiment.GetIndexingSettings().GetGeomRefinementAlgorithm()) {
case GeomRefinementAlgorithmEnum::None:
break;
case GeomRefinementAlgorithmEnum::BeamCenter:
// Settings below ensure that symmetry is not "touched" by the refinement routine
data.crystal_system = gemmi::CrystalSystem::Triclinic;
data.centering = 'P';
// Fall through!
case GeomRefinementAlgorithmEnum::BeamCenterSymmetry:
if (XtalOptimizer(data, output.spots)) {
experiment_copy.BeamX_pxl(data.geom.GetBeamX_pxl()).BeamY_pxl(data.geom.GetBeamY_pxl());
beam_center_updated = true;
}
break;
}
if (AnalyzeIndexing(output, experiment_copy, data.latt)) {
float ewald_dist_cutoff = 0.001f;
if (output.profile_radius)
ewald_dist_cutoff = output.profile_radius.value() * 2.0f;
if (experiment.GetBraggIntegrationSettings().GetFixedProfileRadius_recipA())
ewald_dist_cutoff = experiment.GetBraggIntegrationSettings().GetFixedProfileRadius_recipA().value() * 3.0f;
if (beam_center_updated) {
output.beam_corr_x = data.beam_corr_x;
output.beam_corr_y = data.beam_corr_y;
}
if (spot_finding_settings.quick_integration) {
auto res = BraggIntegrate2D(experiment_copy, image, data.latt,
ewald_dist_cutoff, output.number);
float res_estimate = sqrtf((res.b_factor.value_or(12.0f) - 12.0f) / 4.0f);
if (res_estimate > 1.0 && res_estimate < 4.0)
output.resolution_estimate = res_estimate;
constexpr size_t kMaxReflections = 10000;
if (res.reflections.size() > kMaxReflections) {
output.reflections.assign(res.reflections.begin(),
res.reflections.begin() + kMaxReflections);
} else
output.reflections = res.reflections;
output.b_factor = res.b_factor;
output.integration_Isigma = res.Isigma;
output.integration_logI = res.logI;
output.integration_one_over_d = res.one_over_d;
}
}
}
}
}