// Copyright (2019-2024) Paul Scherrer Institute #include "MXAnalyzer.h" #include "CPUSpotFinder.h" #include "../common/DiffractionGeometry.h" MXAnalyzer::MXAnalyzer(const DiffractionExperiment &in_experiment) : experiment(in_experiment) { auto uc = experiment.GetUnitCell(); if (uc) { do_indexing = true; indexer.Setup(uc.value()); } if (experiment.IsSpotFindingEnabled()) find_spots = true; } void MXAnalyzer::ReadFromFPGA(const DeviceOutput *output, const SpotFindingSettings &settings, size_t module_number) { if (!find_spots || !settings.enable) return; StrongPixelSet strong_pixel_set; strong_pixel_set.ReadFPGAOutput(experiment, *output); strong_pixel_set.FindSpots(experiment, settings, spots, module_number); } void MXAnalyzer::ReadFromCPU(const int16_t *image, const SpotFindingSettings &settings, size_t module_number) { if (!find_spots) return; std::vector d_map(RAW_MODULE_SIZE); DeviceOutput output{}; memcpy(output.pixels, image, RAW_MODULE_SIZE * sizeof(int16_t)); CalcSpotFinderResolutionMap(d_map.data(), experiment, module_number); FindSpots(output, settings, d_map.data()); ReadFromFPGA(&output, settings, module_number); } bool MXAnalyzer::Process(DataMessage &message, const SpotFindingSettings& settings) { message.indexing_result = 0; if (!find_spots) return false; bool indexed = false; std::vector spots_out; FilterSpotsByCount(experiment, spots, spots_out); for (const auto &spot: spots_out) message.spots.push_back(spot); if (do_indexing && settings.indexing) { std::vector recip; for (const auto &i: spots_out) recip.push_back(i.ReciprocalCoord(experiment)); auto indexer_result = indexer.Run(recip); if (!indexer_result.empty()) { message.indexing_result = 1; for (int i = 0; i < recip.size(); i++) message.spots[i].indexed = indexer_result[0].indexed_spots[i]; indexer_result[0].l.Save(message.indexing_lattice); message.indexing_unit_cell = indexer_result[0].l.GetUnitCell(); indexed = true; } } spots.clear(); return indexed; }