Dense per-pixel maps through the panel table (panel layout stage 1)
Every dense map that needs geometry now evaluates each image pixel at its place on the detector plane (DetectorModules), so it is right for a stacked panel layout and picks up refined module placements: - AzimuthalIntegrationMapping: bins, resolution, solid-angle/polarisation corrections built per pixel through the table; a pixel on no panel is left as a masked one. The geometry cache key now includes the panel table, so a mapping built after the stills module placement is rebuilt rather than served from the cache. ResolutionMaskBits follows (it is a lookup). - ROIMap / ExportROIMap: azimuthal ROIs on the plane (box and circle ROIs stay in image pixels). - ROIIntegration CPU+GPU: the weighted sums are taken per ROI and panel in image pixels and placed on the plane at the end (exact; the affine commutes with a weighted mean). - HotPixelFinder: ring/sector keys and the zeta of the persistence rule on the plane. - Background beam-centre walk CPU+GPU: pixels binned at their plane position; host and device share BackgroundPlanePoint so they stay bit-identical. New common/PanelRows.h: ForEachPixelInRows, ForEachPixel cut to a band of rows in index order, for the row-parallel builders. An empty table takes the old arithmetic in the old order: rotation sets and every single-panel input are unchanged. [PanelLayout] AzintMapping and ResolutionMask enabled (+ azimuthal ROI map and ROI centroid on the plane); new BeamCenterFromBackground_BinsOnThePlane and ROIIntegrationGPU_MatchesCPU_Panels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015CeEGgpKdfkCTJb3YNMJcu
This commit is contained in:
1 parent
c8fb472f4d
commit
dcad4104ce
22 files changed
+427
-134
No files matched your search
@@ -11,7 +11,7 @@
|
||||
// [PanelLayout] cases check what is already layout-correct. The [PanelLayoutTodo] cases are hidden: they
|
||||
// state the equivalence each later stage has to deliver, and fail until it does. A stage that converts a
|
||||
// consumer retags its case [PanelLayout]:
|
||||
// stage 1 - dense maps: PanelLayout_AzintMapping, PanelLayout_ResolutionMask
|
||||
// stage 1 - dense maps: PanelLayout_AzintMapping, PanelLayout_ResolutionMask (done)
|
||||
// stage 2 - sparse/Bragg: PanelLayout_BraggIntegration
|
||||
// stage 3 - per-panel spot finding: PanelLayout_SpotsNeverCrossPanels; the raster algorithms
|
||||
// (ShadowFinder, BeamCenterFFT, BeamCenterFromBackground, DiagnosticOutput) add their case here,
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "../common/Reflection.h"
|
||||
#include "../image_analysis/bragg_integration/BraggIntegrationEngineCPU.h"
|
||||
#include "../image_analysis/image_preprocessing/ImagePreprocessorBuffer.h"
|
||||
#include "../image_analysis/roi/ROIIntegrationCPU.h"
|
||||
#include "../image_analysis/spot_finding/ImageSpotFinderCPU.h"
|
||||
#include "../image_analysis/spot_finding/SpotUtils.h"
|
||||
|
||||
@@ -262,9 +263,10 @@ TEST_CASE("PanelLayout_IntegrationRoundTrip", "[PanelLayout]") {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO stage 1: the azimuthal-integration map built per stored pixel through the panel table - same bin,
|
||||
// resolution and correction as the assembled pixel it lands on.
|
||||
TEST_CASE("PanelLayout_AzintMapping", "[.][PanelLayoutTodo]") {
|
||||
// The azimuthal-integration map built per stored pixel through the panel table - same bin, resolution and
|
||||
// correction as the assembled pixel it lands on. The same for the azimuthal ROI map, and the ROI centre of
|
||||
// mass comes out on the plane.
|
||||
TEST_CASE("PanelLayout_AzintMapping", "[PanelLayout]") {
|
||||
const Scene scene(INTERIOR_SPOTS);
|
||||
const AzimuthalIntegrationMapping a(scene.assembled, scene.assembled_mask);
|
||||
const AzimuthalIntegrationMapping s(scene.stacked, scene.stacked_mask);
|
||||
@@ -278,10 +280,30 @@ TEST_CASE("PanelLayout_AzintMapping", "[.][PanelLayoutTodo]") {
|
||||
CHECK(bin == 0);
|
||||
CHECK(resolution == 0);
|
||||
CHECK(correction == 0);
|
||||
|
||||
DiffractionExperiment assembled = scene.assembled, stacked = scene.stacked;
|
||||
for (auto *x: {&assembled, &stacked})
|
||||
x->ROI().SetROI(ROIDefinition{.azimuthal = {ROIAzimuthal("ring", 3.0f, 8.0f, 20.0f, 250.0f)}});
|
||||
const auto a_roi = assembled.ExportROIMap(), s_roi = stacked.ExportROIMap();
|
||||
size_t roi = 0, in_roi = 0;
|
||||
scene.modules.ForEachPixel(PW, NPANELS * PH, [&](int64_t, size_t i, double px, double py) {
|
||||
roi += s_roi[i] != a_roi[Scene::AssembledIndex(px, py)];
|
||||
in_roi += s_roi[i] != 0;
|
||||
});
|
||||
CHECK(roi == 0);
|
||||
CHECK(in_roi > 1000);
|
||||
|
||||
std::map<std::string, ROIMessage> a_out, s_out;
|
||||
ROIIntegrationCPU(assembled).Run(scene.assembled_image, a_out);
|
||||
ROIIntegrationCPU(stacked).Run(scene.stacked_image, s_out);
|
||||
CHECK(s_out.at("ring").sum == a_out.at("ring").sum);
|
||||
CHECK(s_out.at("ring").pixels == a_out.at("ring").pixels);
|
||||
CHECK(s_out.at("ring").x_weighted == a_out.at("ring").x_weighted);
|
||||
CHECK(s_out.at("ring").y_weighted == a_out.at("ring").y_weighted);
|
||||
}
|
||||
|
||||
// TODO stage 1: the spot finders' resolution mask, per stored pixel through the panel table.
|
||||
TEST_CASE("PanelLayout_ResolutionMask", "[.][PanelLayoutTodo]") {
|
||||
// The spot finders' resolution mask, per stored pixel through the panel table.
|
||||
TEST_CASE("PanelLayout_ResolutionMask", "[PanelLayout]") {
|
||||
const Scene scene(INTERIOR_SPOTS);
|
||||
const auto a = AzimuthalIntegrationMapping(scene.assembled, scene.assembled_mask).ResolutionMaskBits(3.0f, 8.0f);
|
||||
const auto s = AzimuthalIntegrationMapping(scene.stacked, scene.stacked_mask).ResolutionMaskBits(3.0f, 8.0f);
|
||||
|
||||
Reference in new issue
Block a user