89 lines
4.4 KiB
C++
89 lines
4.4 KiB
C++
// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#include "MXAnalysisWithoutFPGA.h"
|
|
|
|
#include "spot_finding/StrongPixelSet.h"
|
|
#include "../compression/JFJochDecompress.h"
|
|
|
|
#include "spot_finding/SpotUtils.h"
|
|
#include "spot_finding/ImageSpotFinderFactory.h"
|
|
#include "bragg_prediction/BraggPredictionFactory.h"
|
|
#include "image_preprocessing/ImagePreprocessorCPU.h"
|
|
|
|
MXAnalysisWithoutFPGA::MXAnalysisWithoutFPGA(const DiffractionExperiment &in_experiment,
|
|
const AzimuthalIntegration &in_integration,
|
|
const PixelMask &in_mask,
|
|
IndexAndRefine &in_indexer)
|
|
: experiment(in_experiment),
|
|
integration(in_integration),
|
|
npixels(experiment.GetPixelsNum()),
|
|
xpixels(experiment.GetXPixelsNum()),
|
|
spotFinder(CreateImageSpotFinder(experiment.GetXPixelsNum(), experiment.GetYPixelsNum())),
|
|
indexer(in_indexer),
|
|
prediction(CreateBraggPrediction(experiment.IsRotationIndexing())),
|
|
mask(in_mask),
|
|
mask_resolution(experiment.GetPixelsNum(), false),
|
|
mask_high_res(-1),
|
|
mask_low_res(-1) {
|
|
preprocessor = std::make_unique<ImagePreprocessorCPU>(in_experiment, in_integration, in_mask);
|
|
}
|
|
|
|
void MXAnalysisWithoutFPGA::Analyze(DataMessage &output,
|
|
AzimuthalIntegrationProfile &profile,
|
|
const SpotFindingSettings &spot_finding_settings) {
|
|
if ((output.image.GetWidth() != xpixels)
|
|
|| (output.image.GetWidth() * output.image.GetHeight() != npixels))
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"Mismatch in pixel size");
|
|
|
|
const auto compression_start_time = std::chrono::steady_clock::now();
|
|
const uint8_t *image_ptr = output.image.GetUncompressedPtr(decompression_buffer);
|
|
const auto compression_end_time = std::chrono::steady_clock::now();
|
|
if (output.image.GetCompressionAlgorithm() != CompressionAlgorithm::NO_COMPRESSION)
|
|
output.compression_time_s = std::chrono::duration<float>(compression_end_time - compression_start_time).count();
|
|
|
|
const auto preprocessing_start_time = std::chrono::steady_clock::now();
|
|
auto ret = preprocessor->Analyze(image_ptr, output.image.GetMode());
|
|
|
|
const auto preprocessing_end_time = std::chrono::steady_clock::now();
|
|
output.preprocessing_time_s = std::chrono::duration<float>(preprocessing_end_time - preprocessing_start_time).count();
|
|
|
|
if (spot_finding_settings.enable) {
|
|
// Update resolution mask
|
|
if (mask_high_res != spot_finding_settings.high_resolution_limit
|
|
|| mask_low_res != spot_finding_settings.low_resolution_limit)
|
|
UpdateMaskResolution(spot_finding_settings);
|
|
|
|
const auto spot_finding_start_time = std::chrono::steady_clock::now();
|
|
|
|
memcpy(spotFinder->GetInputBuffer().data(), preprocessor->GetProcessedImage().data(), npixels * sizeof(int32_t));
|
|
const std::vector<DiffractionSpot> spots = spotFinder->Run(spot_finding_settings, mask_resolution);
|
|
SpotAnalyze(experiment, spot_finding_settings, spots, output);
|
|
const auto spot_finding_end_time = std::chrono::steady_clock::now();
|
|
output.spot_finding_time_s = std::chrono::duration<float>(spot_finding_end_time - spot_finding_start_time).count();
|
|
|
|
if (spot_finding_settings.indexing)
|
|
indexer.ProcessImage(output, spot_finding_settings,
|
|
CompressedImage(preprocessor->GetProcessedImage(), experiment.GetXPixelsNum(), experiment.GetYPixelsNum()),
|
|
*prediction);
|
|
}
|
|
|
|
preprocessor->Update(profile);
|
|
|
|
output.max_viable_pixel_value = ret.max_value;
|
|
output.min_viable_pixel_value = ret.min_value;
|
|
output.error_pixel_count = ret.error_pixel_count;
|
|
output.saturated_pixel_count = ret.saturated_pixel_count;
|
|
output.az_int_profile = profile.GetResult();
|
|
output.bkg_estimate = profile.GetBkgEstimate(integration.Settings());
|
|
}
|
|
|
|
void MXAnalysisWithoutFPGA::UpdateMaskResolution(const SpotFindingSettings &settings) {
|
|
mask_low_res = settings.low_resolution_limit;
|
|
mask_high_res = settings.high_resolution_limit;
|
|
auto const &resolution_map = integration.Resolution();
|
|
for (int i = 0; i < mask_resolution.size(); i++)
|
|
mask_resolution[i] = (resolution_map[i] > mask_low_res) || (resolution_map[i] < mask_high_res);
|
|
}
|