diff --git a/image_analysis/MXAnalysisWithoutFPGA.cpp b/image_analysis/MXAnalysisWithoutFPGA.cpp index cbe26e6a..2adcf932 100644 --- a/image_analysis/MXAnalysisWithoutFPGA.cpp +++ b/image_analysis/MXAnalysisWithoutFPGA.cpp @@ -48,7 +48,7 @@ MXAnalysisWithoutFPGA::MXAnalysisWithoutFPGA(const DiffractionExperiment &in_exp roi = std::make_unique(experiment); #ifdef JFJOCH_USE_CUDA } else { - auto stream = std::make_shared(); + stream = std::make_shared(); preprocessor_buffer = std::make_unique(experiment.GetPixelsNum()); preprocessor = std::make_unique(in_experiment, in_mask, stream); spotFinder = std::make_unique(experiment.GetXPixelsNum(), experiment.GetYPixelsNum(), stream); @@ -115,6 +115,37 @@ void MXAnalysisWithoutFPGA::Analyze(DataMessage &output, output.bkg_estimate = profile.GetBkgEstimate(integration.Settings()); } +void MXAnalysisWithoutFPGA::RebuildROI() { + if (experiment.ROI().empty()) { + roi.reset(); + return; + } +#ifdef JFJOCH_USE_CUDA + if (stream) { + roi = std::make_unique(experiment, stream); + return; + } +#endif + roi = std::make_unique(experiment); +} + +void MXAnalysisWithoutFPGA::AnalyzeROIOnly(DataMessage &output) { + if ((output.image.GetWidth() != xpixels) + || (output.image.GetWidth() * output.image.GetHeight() != npixels)) + throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, + "Mismatch in pixel size"); + + const uint8_t *image_ptr = output.image.GetUncompressedPtr(decompression_buffer); + preprocessor->Analyze(*preprocessor_buffer, image_ptr, output.image.GetMode()); + RunROIOnly(output); +} + +void MXAnalysisWithoutFPGA::RunROIOnly(DataMessage &output) { + output.roi.clear(); + if (roi) + roi->Run(*preprocessor_buffer, output.roi); +} + void MXAnalysisWithoutFPGA::UpdateMaskResolution(const SpotFindingSettings &settings) { mask_low_res = settings.low_resolution_limit; mask_high_res = settings.high_resolution_limit; diff --git a/image_analysis/MXAnalysisWithoutFPGA.h b/image_analysis/MXAnalysisWithoutFPGA.h index 9d6bd0a9..b14d5f6f 100644 --- a/image_analysis/MXAnalysisWithoutFPGA.h +++ b/image_analysis/MXAnalysisWithoutFPGA.h @@ -19,6 +19,8 @@ #include "image_preprocessing/ImagePreprocessor.h" #include "image_preprocessing/ImagePreprocessorBuffer.h" +class CudaStream; + // MXAnalysisWithoutFPGA is not thread safe - it has to owned by a single thread class MXAnalysisWithoutFPGA { const DiffractionExperiment &experiment; @@ -43,10 +45,21 @@ class MXAnalysisWithoutFPGA { float mask_high_res; float mask_low_res; void UpdateMaskResolution(const SpotFindingSettings& settings); +#ifdef JFJOCH_USE_CUDA + std::shared_ptr stream; // kept so RebuildROI() can recreate the GPU ROI engine +#endif public: MXAnalysisWithoutFPGA(const DiffractionExperiment &experiment, const AzimuthalIntegrationMapping &integration, const PixelMask &mask, IndexAndRefine &indexer); void Analyze(DataMessage &output, AzimuthalIntegrationProfile &profile, const SpotFindingSettings &spot_finding_settings); + + // Surgical ROI-only paths used when a full re-analysis is not wanted: rebuild the + // ROI engine after the ROI set changes, recompute ROIs after preprocessing a new + // image (reanalyze off), or just rerun ROIs on the current preprocessed image (an + // interactive ROI move). A full Analyze() already computes ROIs, so needs nothing. + void RebuildROI(); + void AnalyzeROIOnly(DataMessage &output); + void RunROIOnly(DataMessage &output); };