Merge branch 'shadow-6jgh-dimfield' into r4-integration
# Conflicts: # image_analysis/beam_stop/ShadowFinder.cpp
This commit is contained in:
commit
cff5fa0fdb
3 files changed
+140
-3
No files matched your search
@@ -383,6 +383,47 @@ TEST_CASE("ShadowFinder_APolarizedBackgroundIsNotAShadow", "[ShadowFinder]") {
|
||||
CHECK(mask_for(std::nullopt) > static_cast<long>(W) * H / 20);
|
||||
}
|
||||
|
||||
// The other side of that correction: a polarization factor that is not the beam's. Here the
|
||||
// background is unpolarized and the experiment states 0.99, so after the division every outer ring is
|
||||
// bright along x and dim along y - a smooth lobe below PENUMBRA_RATIO across the top and bottom of the
|
||||
// detector with nothing in the beam. On its own the lobe is never deep, but a small absorbing speck
|
||||
// inside it is, and the transmitting-hardware step joined the two into one piece "dim everywhere and
|
||||
// deep in places" and masked the whole lobe. The step compares a pixel with its ring's own second
|
||||
// harmonic, so the lobe is explained away and the speck, far below a shadow's size, stays unmasked.
|
||||
TEST_CASE("ShadowFinder_AWrongPolarizationFactorIsNotAnArm", "[ShadowFinder]") {
|
||||
constexpr float DISTANCE_MM = 6.0f;
|
||||
constexpr int LEVEL = 24;
|
||||
constexpr int SPECK_X = C, SPECK_Y = 20, SPECK_R = 11;
|
||||
|
||||
DiffractionExperiment x = TestExperiment();
|
||||
x.DetectorDistance_mm(DISTANCE_MM).PolarizationFactor(0.99f);
|
||||
const float pixel_mm = x.GetPixelSize_mm();
|
||||
|
||||
std::vector<int32_t> frame(static_cast<size_t>(W) * H);
|
||||
for (int y = 0; y < H; y++)
|
||||
for (int xi = 0; xi < W; xi++) {
|
||||
const double rho = std::hypot(xi - C, y - C) * pixel_mm;
|
||||
const double cos_2theta_sq = DISTANCE_MM * DISTANCE_MM / (DISTANCE_MM * DISTANCE_MM + rho * rho);
|
||||
frame[I(xi, y)] = static_cast<int32_t>(std::lround(LEVEL * 0.5 * (1.0 + cos_2theta_sq)));
|
||||
const int sx = xi - SPECK_X, sy = y - SPECK_Y;
|
||||
if (sx * sx + sy * sy <= SPECK_R * SPECK_R)
|
||||
frame[I(xi, y)] /= 10;
|
||||
}
|
||||
|
||||
const PixelMask pixel_mask(x);
|
||||
ShadowFinder finder(x, pixel_mask);
|
||||
std::vector<uint8_t> buffer;
|
||||
for (int f = 0; f < NFRAMES; f++) {
|
||||
DataMessage msg{};
|
||||
msg.image = CompressedImage(frame, W, H);
|
||||
finder.AddImage(msg, buffer);
|
||||
}
|
||||
const auto mask = finder.GetMask();
|
||||
CHECK(mask[I(C, 5)] == 0); // the dim lobe along y
|
||||
CHECK(mask[I(SPECK_X, SPECK_Y)] == 0); // the speck, too small to be a shadow
|
||||
CHECK(std::count(mask.begin(), mask.end(), 1u) == 0);
|
||||
}
|
||||
|
||||
// Inside the stop a whole ring is blocked, so its own median is blocked too and the per-pixel
|
||||
// comparison has nothing to work with; the walk that finds those rings is what covers the disk.
|
||||
// It decides by comparing a ring against what this detector's background typically is - and NOT
|
||||
|
||||
Reference in new issue
Block a user