image_analysis: surgical ROI-only entry points in MXAnalysisWithoutFPGA

Add three entry points so ROI statistics can be (re)computed without a
full re-analysis, in support of interactive ROI editing in the viewer:

- RebuildROI(): recreate the ROI engine after the ROI set changes (the
  CudaStream is now kept as a member so the GPU engine can be rebuilt).
- AnalyzeROIOnly(): decompress + preprocess + ROI, skipping azimuthal
  integration, spot finding and indexing (a new image when re-analysis
  is off).
- RunROIOnly(): rerun only the ROI integration on the already-preprocessed
  image (an interactive ROI move). A full Analyze() still computes ROIs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-19 13:56:09 +02:00
co-authored by Claude Opus 4.8
parent 3996595606
commit a433399106
2 changed files with 45 additions and 1 deletions
+32 -1
View File
@@ -48,7 +48,7 @@ MXAnalysisWithoutFPGA::MXAnalysisWithoutFPGA(const DiffractionExperiment &in_exp
roi = std::make_unique<ROIIntegrationCPU>(experiment);
#ifdef JFJOCH_USE_CUDA
} else {
auto stream = std::make_shared<CudaStream>();
stream = std::make_shared<CudaStream>();
preprocessor_buffer = std::make_unique<ImagePreprocessorBufferGPU>(experiment.GetPixelsNum());
preprocessor = std::make_unique<ImagePreprocessorGPU>(in_experiment, in_mask, stream);
spotFinder = std::make_unique<ImageSpotFinderGPU>(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<ROIIntegrationGPU>(experiment, stream);
return;
}
#endif
roi = std::make_unique<ROIIntegrationCPU>(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;