FPGA receiver: index only
MXAnalysisAfterFPGA indexes each image (IndexAndRefine::IndexFrameOnly) and no longer predicts or integrates; its Bragg prediction and CPU integration engine go. Per-image reflections, integrated-reflection counts and B factors are now left unset on this path - integration is rugnux's. jfjoch_fpga_test loses -Q and the receiver-test helper its quick_integrate parameter. The two processing tests that integrated now check that indexing happens and integration does not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HVeDQsU5a8AJUdJPgWevAK
This commit is contained in:
1 parent
3d631d2f69
commit
68ec8a7f9f
6 files changed
+21
-45
No files matched your search
@@ -9,7 +9,6 @@
|
|||||||
#include "../common/CUDAWrapper.h"
|
#include "../common/CUDAWrapper.h"
|
||||||
#include "../common/JFJochException.h"
|
#include "../common/JFJochException.h"
|
||||||
#include "spot_finding/SpotUtils.h"
|
#include "spot_finding/SpotUtils.h"
|
||||||
#include "bragg_prediction/BraggPredictionFactory.h"
|
|
||||||
|
|
||||||
double stddev(const std::vector<float> &v) {
|
double stddev(const std::vector<float> &v) {
|
||||||
if (v.size() <= 1)
|
if (v.size() <= 1)
|
||||||
@@ -34,13 +33,7 @@ MXAnalysisAfterFPGA::MXAnalysisAfterFPGA(const DiffractionExperiment &in_experim
|
|||||||
IndexAndRefine &indexer)
|
IndexAndRefine &indexer)
|
||||||
: experiment(in_experiment),
|
: experiment(in_experiment),
|
||||||
integration(in_integration),
|
integration(in_integration),
|
||||||
indexer(indexer),
|
indexer(indexer) {
|
||||||
prediction(CreateBraggPrediction(experiment.IsRotationIndexing())),
|
|
||||||
// No pixel mask reaches this path: the FPGA image marks its own masked pixels, so only a
|
|
||||||
// saturated pixel is read as an overload here. The edge mask is taken in the image's own layout,
|
|
||||||
// which is the raw one when the geometry is not transformed.
|
|
||||||
bragg_engine(std::make_unique<BraggIntegrationEngineCPU>(
|
|
||||||
in_experiment, PixelMask(PixelMask(in_experiment).GetMask(in_experiment)))) {
|
|
||||||
if (experiment.IsSpotFindingEnabled())
|
if (experiment.IsSpotFindingEnabled())
|
||||||
find_spots = true;
|
find_spots = true;
|
||||||
|
|
||||||
@@ -151,11 +144,9 @@ void MXAnalysisAfterFPGA::Process(DataMessage &message, const SpotFindingSetting
|
|||||||
const auto t1 = std::chrono::steady_clock::now();
|
const auto t1 = std::chrono::steady_clock::now();
|
||||||
spot_finding_time_total += (t1 - t0);
|
spot_finding_time_total += (t1 - t0);
|
||||||
|
|
||||||
|
// Indexing only: integration is rugnux's (live or offline), not the FPGA receiver's.
|
||||||
if (spot_finding_settings.indexing)
|
if (spot_finding_settings.indexing)
|
||||||
indexer.ProcessImage(message, spot_finding_settings, *prediction,
|
indexer.IndexFrameOnly(message, spot_finding_settings);
|
||||||
[this, &message](const std::vector<Reflection> &predicted, size_t npredicted, int64_t image_number) {
|
|
||||||
return bragg_engine->Run(message.image, predicted, npredicted, image_number);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spot_finding_timing_active) {
|
if (spot_finding_timing_active) {
|
||||||
|
|||||||
@@ -4,8 +4,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../common/DiffractionExperiment.h"
|
#include "../common/DiffractionExperiment.h"
|
||||||
#include "bragg_prediction/BraggPrediction.h"
|
|
||||||
#include "bragg_integration/BraggIntegrationEngineCPU.h"
|
|
||||||
#include "indexing/IndexerThreadPool.h"
|
#include "indexing/IndexerThreadPool.h"
|
||||||
#include "spot_finding/StrongPixelSet.h"
|
#include "spot_finding/StrongPixelSet.h"
|
||||||
#include "azint/AzIntEngineCPU.h"
|
#include "azint/AzIntEngineCPU.h"
|
||||||
@@ -16,13 +14,8 @@ class MXAnalysisAfterFPGA {
|
|||||||
const DiffractionExperiment &experiment;
|
const DiffractionExperiment &experiment;
|
||||||
const AzimuthalIntegrationMapping &integration;
|
const AzimuthalIntegrationMapping &integration;
|
||||||
IndexAndRefine &indexer;
|
IndexAndRefine &indexer;
|
||||||
std::unique_ptr<BraggPrediction> prediction;
|
|
||||||
std::unique_ptr<AzIntEngineCPU> cpu_azint;
|
std::unique_ptr<AzIntEngineCPU> cpu_azint;
|
||||||
|
|
||||||
// The FPGA host has no usable GPU bandwidth for integration, so Bragg integration here is always on
|
|
||||||
// the CPU, reading the assembled detector image straight (only the reflection disks - no copy).
|
|
||||||
std::unique_ptr<BraggIntegrationEngineCPU> bragg_engine;
|
|
||||||
|
|
||||||
bool find_spots = false;
|
bool find_spots = false;
|
||||||
std::vector<DiffractionSpot> spots;
|
std::vector<DiffractionSpot> spots;
|
||||||
constexpr static const float spot_distance_threshold_pxl = 2.0f;
|
constexpr static const float spot_distance_threshold_pxl = 2.0f;
|
||||||
|
|||||||
@@ -38,8 +38,7 @@ bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
|
|||||||
const DiffractionExperiment &x,
|
const DiffractionExperiment &x,
|
||||||
const PixelMask &pixel_mask,
|
const PixelMask &pixel_mask,
|
||||||
uint16_t nthreads,
|
uint16_t nthreads,
|
||||||
size_t send_buf_size_MiB,
|
size_t send_buf_size_MiB) {
|
||||||
bool quick_integrate) {
|
|
||||||
|
|
||||||
std::vector<uint16_t> raw_expected_image(RAW_MODULE_SIZE * x.GetModulesNum());
|
std::vector<uint16_t> raw_expected_image(RAW_MODULE_SIZE * x.GetModulesNum());
|
||||||
|
|
||||||
@@ -47,7 +46,7 @@ bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
|
|||||||
raw_expected_image[i] = i % 65536;
|
raw_expected_image[i] = i % 65536;
|
||||||
|
|
||||||
return JFJochReceiverTest(output, logger, aq_devices, x, pixel_mask, raw_expected_image, nthreads,
|
return JFJochReceiverTest(output, logger, aq_devices, x, pixel_mask, raw_expected_image, nthreads,
|
||||||
send_buf_size_MiB, quick_integrate);
|
send_buf_size_MiB);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
|
bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
|
||||||
@@ -56,8 +55,7 @@ bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
|
|||||||
const PixelMask &pixel_mask,
|
const PixelMask &pixel_mask,
|
||||||
const std::vector<uint16_t> &raw_expected_image,
|
const std::vector<uint16_t> &raw_expected_image,
|
||||||
uint16_t nthreads,
|
uint16_t nthreads,
|
||||||
size_t send_buf_size_MiB,
|
size_t send_buf_size_MiB) {
|
||||||
bool quick_integrate) {
|
|
||||||
std::vector<uint16_t> raw_expected_image_with_mask = raw_expected_image;
|
std::vector<uint16_t> raw_expected_image_with_mask = raw_expected_image;
|
||||||
if (x.IsApplyPixelMask()) {
|
if (x.IsApplyPixelMask()) {
|
||||||
for (int i = 0; i < raw_expected_image_with_mask.size(); i++)
|
for (int i = 0; i < raw_expected_image_with_mask.size(); i++)
|
||||||
@@ -86,7 +84,6 @@ bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
|
|||||||
settings.photon_count_threshold = 5;
|
settings.photon_count_threshold = 5;
|
||||||
settings.min_pix_per_spot = 1;
|
settings.min_pix_per_spot = 1;
|
||||||
settings.max_pix_per_spot = 200;
|
settings.max_pix_per_spot = 200;
|
||||||
settings.quick_integration = quick_integrate;
|
|
||||||
|
|
||||||
service.SetSpotFindingSettings(settings);
|
service.SetSpotFindingSettings(settings);
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
|
|||||||
const DiffractionExperiment &x,
|
const DiffractionExperiment &x,
|
||||||
const PixelMask &pixel_mask,
|
const PixelMask &pixel_mask,
|
||||||
uint16_t nthreads,
|
uint16_t nthreads,
|
||||||
size_t send_buf_size_MiB = 1024,
|
size_t send_buf_size_MiB = 1024);
|
||||||
bool quick_integrate = false);
|
|
||||||
|
|
||||||
bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
|
bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
|
||||||
AcquisitionDeviceGroup &aq_devices,
|
AcquisitionDeviceGroup &aq_devices,
|
||||||
@@ -22,5 +21,4 @@ bool JFJochReceiverTest(JFJochReceiverOutput &output, Logger &logger,
|
|||||||
const PixelMask &pixel_mask,
|
const PixelMask &pixel_mask,
|
||||||
const std::vector<uint16_t> &data,
|
const std::vector<uint16_t> &data,
|
||||||
uint16_t nthreads,
|
uint16_t nthreads,
|
||||||
size_t send_buf_size_MiB = 1024,
|
size_t send_buf_size_MiB = 1024);
|
||||||
bool quick_integrate = false);
|
|
||||||
@@ -283,7 +283,7 @@ TEST_CASE("JFJochIntegrationTest_ZMQ_crystal_spot_and_index_refinement_tetragona
|
|||||||
REQUIRE_NOTHROW(writer_future.get());
|
REQUIRE_NOTHROW(writer_future.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("JFJochIntegrationTest_ZMQ_crystal_spot_index_and_integrate", "[JFJochReceiver]") {
|
TEST_CASE("JFJochIntegrationTest_ZMQ_crystal_spot_index_no_integration", "[JFJochReceiver]") {
|
||||||
Logger logger(Catch::getResultCapture().getCurrentTestName());
|
Logger logger(Catch::getResultCapture().getCurrentTestName());
|
||||||
|
|
||||||
RegisterHDF5Filter();
|
RegisterHDF5Filter();
|
||||||
@@ -322,7 +322,7 @@ TEST_CASE("JFJochIntegrationTest_ZMQ_crystal_spot_index_and_integrate", "[JFJoch
|
|||||||
settings.max_pix_per_spot = 200;
|
settings.max_pix_per_spot = 200;
|
||||||
settings.high_resolution_limit = 2.0;
|
settings.high_resolution_limit = 2.0;
|
||||||
settings.low_resolution_limit = 50.0;
|
settings.low_resolution_limit = 50.0;
|
||||||
settings.quick_integration = true;
|
settings.quick_integration = true; // asked for, and still not done
|
||||||
std::vector<CardImage> images;
|
std::vector<CardImage> images;
|
||||||
images.push_back(Int16Image(experiment, pixel_mask, image_raw_geom, settings));
|
images.push_back(Int16Image(experiment, pixel_mask, image_raw_geom, settings));
|
||||||
AcquisitionDeviceGroup aq_devices = MockDevices(experiment, images);
|
AcquisitionDeviceGroup aq_devices = MockDevices(experiment, images);
|
||||||
@@ -367,16 +367,19 @@ TEST_CASE("JFJochIntegrationTest_ZMQ_crystal_spot_index_and_integrate", "[JFJoch
|
|||||||
|
|
||||||
// No progress value at the end of measurement
|
// No progress value at the end of measurement
|
||||||
REQUIRE(!service.GetProgress().has_value());
|
REQUIRE(!service.GetProgress().has_value());
|
||||||
auto b_factor = service.GetDataProcessingPlot(
|
|
||||||
PlotRequest{.type = PlotType::BFactor, .binning = 1});
|
|
||||||
|
|
||||||
REQUIRE(b_factor.GetPlots().size() == 1);
|
// The FPGA receiver indexes each image and integrates none, even when the settings ask for it:
|
||||||
REQUIRE(b_factor.GetPlots()[0].x.size() == experiment.GetImageNum());
|
// integration is rugnux's.
|
||||||
logger.Info("B-factor {}", b_factor.GetPlots()[0].y[0]);
|
REQUIRE(receiver_out.scan_result.images.size() == experiment.GetImageNum());
|
||||||
|
for (const auto &i: receiver_out.scan_result.images) {
|
||||||
|
CHECK(i.uc.has_value());
|
||||||
|
CHECK(!i.integrated_reflections.has_value());
|
||||||
|
CHECK(!i.b_factor.has_value());
|
||||||
|
}
|
||||||
REQUIRE_NOTHROW(writer_future.get());
|
REQUIRE_NOTHROW(writer_future.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("JFJochIntegrationTest_ZMQ_crystal_spot_index_and_integrate_no_spots", "[JFJochReceiver]") {
|
TEST_CASE("JFJochIntegrationTest_ZMQ_crystal_spot_index_no_spots", "[JFJochReceiver]") {
|
||||||
Logger logger(Catch::getResultCapture().getCurrentTestName());
|
Logger logger(Catch::getResultCapture().getCurrentTestName());
|
||||||
|
|
||||||
RegisterHDF5Filter();
|
RegisterHDF5Filter();
|
||||||
@@ -415,7 +418,6 @@ TEST_CASE("JFJochIntegrationTest_ZMQ_crystal_spot_index_and_integrate_no_spots",
|
|||||||
settings.max_pix_per_spot = 200;
|
settings.max_pix_per_spot = 200;
|
||||||
settings.high_resolution_limit = 2.0;
|
settings.high_resolution_limit = 2.0;
|
||||||
settings.low_resolution_limit = 50.0;
|
settings.low_resolution_limit = 50.0;
|
||||||
settings.quick_integration = true;
|
|
||||||
std::vector<CardImage> images;
|
std::vector<CardImage> images;
|
||||||
images.push_back(Int16Image(experiment, pixel_mask, image_raw_geom, settings));
|
images.push_back(Int16Image(experiment, pixel_mask, image_raw_geom, settings));
|
||||||
AcquisitionDeviceGroup aq_devices = MockDevices(experiment, images);
|
AcquisitionDeviceGroup aq_devices = MockDevices(experiment, images);
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ void print_usage(Logger &logger) {
|
|||||||
logger.Info(" -X<txt> Indexing (none|fft|ffbidx), ffbidx is default");
|
logger.Info(" -X<txt> Indexing (none|fft|ffbidx), ffbidx is default");
|
||||||
logger.Info(" -t<num> Indexing thread pool size (default: 4)");
|
logger.Info(" -t<num> Indexing thread pool size (default: 4)");
|
||||||
logger.Info(" -f<num> FFT indexing search vectors");
|
logger.Info(" -f<num> FFT indexing search vectors");
|
||||||
logger.Info(" -Q Quick integration");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
@@ -56,7 +55,6 @@ int main(int argc, char **argv) {
|
|||||||
bool force_32bit = false;
|
bool force_32bit = false;
|
||||||
bool force_8bit = false;
|
bool force_8bit = false;
|
||||||
bool apply_pixel_mask = false;
|
bool apply_pixel_mask = false;
|
||||||
bool quick_integrate = false;
|
|
||||||
std::optional<int64_t> eiger_bit_depth;
|
std::optional<int64_t> eiger_bit_depth;
|
||||||
DetectorType detector_type = DetectorType::JUNGFRAU;
|
DetectorType detector_type = DetectorType::JUNGFRAU;
|
||||||
bool hls_simulation = false;
|
bool hls_simulation = false;
|
||||||
@@ -71,7 +69,7 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
while ((opt = getopt(argc, argv, "s:i:m:N:P:vRIS:E::HB:q:T:cM0ZX:t:f:Q")) != -1) {
|
while ((opt = getopt(argc, argv, "s:i:m:N:P:vRIS:E::HB:q:T:cM0ZX:t:f:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case '0':
|
case '0':
|
||||||
compr = CompressionAlgorithm::NO_COMPRESSION;
|
compr = CompressionAlgorithm::NO_COMPRESSION;
|
||||||
@@ -148,9 +146,6 @@ int main(int argc, char **argv) {
|
|||||||
case 'f':
|
case 'f':
|
||||||
fft_num_vectors = atol(optarg);
|
fft_num_vectors = atol(optarg);
|
||||||
break;
|
break;
|
||||||
case 'Q':
|
|
||||||
quick_integrate = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* '?' */
|
default: /* '?' */
|
||||||
print_usage(logger);
|
print_usage(logger);
|
||||||
@@ -246,7 +241,7 @@ int main(int argc, char **argv) {
|
|||||||
std::thread run_thread([&] {
|
std::thread run_thread([&] {
|
||||||
try {
|
try {
|
||||||
ret = JFJochReceiverTest(output, logger, aq_devices, x, mask, input, nthreads,
|
ret = JFJochReceiverTest(output, logger, aq_devices, x, mask, input, nthreads,
|
||||||
send_buffer_size_MiB, quick_integrate);
|
send_buffer_size_MiB);
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
logger.Error(e.what());
|
logger.Error(e.what());
|
||||||
ret = false;
|
ret = false;
|
||||||
|
|||||||
Reference in new issue
Block a user