Stills keep an overloaded observation as a lower bound instead of dropping it
The stills merge dropped every observation with a saturated pixel. On a still the saturated observations are the fully recorded ones of the strongest low-resolution reflections, so what survived were their partial observations, whose partiality correction then set the merged intensity: on clipped CCD stills the merged low-resolution intensities came out at 0.4-0.6x of the deposited ones, a ramp no Wilson B absorbs, invisible to CC1/2 and R_split. The pixels are really clipped (flat-topped plateaus a few per mille wide, a pile-up in the pixel-value histogram from the per-pixel ADC limit), so the auto ceiling is right; the drop was the defect. A still now keeps the observation: the box sum with every saturated pixel counted at the saturation limit, unflagged and marked clipped, counted in BraggIntegrationCounts and reported as OVERLOADED_REFLECTIONS_KEPT. Rotation data (IsRotationIndexing) are unchanged and keep the flag for the rocking-event drop. Measured on a clipped-CCD stills subset (dimple R-free, deposited free set): dropped 0.247, lower bound 0.230 (same as switching saturation off). A Kabsch fit to the unsaturated wings read lower than the lower bound (0.237), and inflating the lower bound's sigma lost (0.255). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
987e812e23
commit
72cc542d78
15 files changed
+152
-20
No files matched your search
@@ -281,6 +281,8 @@ std::vector<Reflection> BraggIntegrationEngineCPU::RunImpl(const Sampler &img,
|
||||
if (px == INT32_MAX
|
||||
|| (px == INT32_MIN && on && !static_masked(static_cast<size_t>(y) * W + x)))
|
||||
s.overloaded = 1;
|
||||
if (px == INT32_MAX)
|
||||
++s.n_saturated;
|
||||
if (!valid(px)) continue;
|
||||
s.I_sum += px;
|
||||
s.I_sum_x += static_cast<int64_t>(x) * px;
|
||||
@@ -368,6 +370,7 @@ void BraggIntegrationEngineCPU::FinishPassA(PassA &a, size_t i, const Reflection
|
||||
out.r_bin = std::clamp(static_cast<int>(std::lround(st.r0)), 0, a.n_rad - 1);
|
||||
out.k_bin = BraggStencilKernelIndex(st, n_kern);
|
||||
out.overloaded = s.overloaded != 0;
|
||||
out.saturated = s.n_saturated;
|
||||
|
||||
if (overlap != OverlapMode::Off && s.n_own < s.n_disk) {
|
||||
++counts.overlapped;
|
||||
@@ -635,7 +638,7 @@ std::vector<Reflection> BraggIntegrationEngineCPU::ProfilePasses(const Sampler &
|
||||
if (overlap == OverlapMode::Reject && rh.n_own < overlap_min_peak * rh.n_disk) continue;
|
||||
results[i] = {static_cast<float>(rh.I), static_cast<float>(rh.sigma), static_cast<float>(rh.bkg),
|
||||
static_cast<float>(rh.obs_x), static_cast<float>(rh.obs_y),
|
||||
static_cast<float>(rh.var_bkg), true, rh.has_obs, rh.overloaded};
|
||||
static_cast<float>(rh.var_bkg), true, rh.has_obs, rh.overloaded, rh.saturated};
|
||||
}
|
||||
return Finalize(predicted, npredicted, panels, results, image_number);
|
||||
}
|
||||
@@ -751,13 +754,14 @@ std::vector<Reflection> BraggIntegrationEngineCPU::ProfilePasses(const Sampler &
|
||||
fs = {};
|
||||
if (!rh.ok) continue;
|
||||
// An overloaded reflection is not measured by any fit - its brightest pixels are what is
|
||||
// missing. It is passed on with its box sum and the flag, for the merge to drop its rocking
|
||||
// event (Reflection::overloaded); the missing-peak cut below would otherwise drop just this
|
||||
// frame and leave the event to be extrapolated from its flanks.
|
||||
// missing. It is passed on with its box sum and the flag, for a rotation merge to drop its
|
||||
// rocking event (Reflection::overloaded) and for a still to be kept as a lower bound
|
||||
// (Finalize); the missing-peak cut below would otherwise drop just this frame and leave the
|
||||
// event to be extrapolated from its flanks.
|
||||
if (rh.overloaded) {
|
||||
results[i] = {static_cast<float>(rh.I), static_cast<float>(rh.sigma), static_cast<float>(rh.bkg),
|
||||
static_cast<float>(rh.obs_x), static_cast<float>(rh.obs_y),
|
||||
static_cast<float>(rh.var_bkg), true, false, true};
|
||||
static_cast<float>(rh.var_bkg), true, false, true, rh.saturated};
|
||||
continue;
|
||||
}
|
||||
const int sh = rh.shell < 0 ? 0 : rh.shell;
|
||||
@@ -866,7 +870,7 @@ std::vector<Reflection> BraggIntegrationEngineCPU::ProfilePasses(const Sampler &
|
||||
results[i] = {static_cast<float>(I), static_cast<float>(sigma),
|
||||
static_cast<float>(rh.bkg),
|
||||
static_cast<float>(rh.obs_x), static_cast<float>(rh.obs_y),
|
||||
static_cast<float>(var_bkg), true, rh.has_obs, rh.overloaded};
|
||||
static_cast<float>(var_bkg), true, rh.has_obs, rh.overloaded, rh.saturated};
|
||||
}
|
||||
|
||||
return Finalize(predicted, npredicted, panels, results, image_number);
|
||||
|
||||
Reference in new issue
Block a user