Bragg integration: a CCD rotation sweep's sigmas at the measured gain, intensities in photons
The pre-scan measures the gain of an SMV/marCCD detector (background variance per unit mean) but the
integrator used it only for the background clip: sigma, var_bkg, the strong-spot flag (I/sigma >= 5)
and the profile-vs-box-sum guard (10 box sigmas) all treated one ADU as one photon, so on a Saturn
(g 4.7-5.8) the guard sat at ~4.5 true sigma. The new BraggIntegrationSettings::PixelGain (set by
rugnux from the same measurement, rotation only, at max(1, g)) takes every variance the engine forms
at the gain, and Finalize converts I, sigma, bkg and var_bkg to photons, which is what the merge's
variance model (var_bkg + I) assumes. CPU and CUDA engines; Metal runs the CPU code for this. Gain 1
(every photon-counting input, ADSC/marCCD whose measured ratio is below 1, and stills) is bit-identical.
Battery --only, 12 open-arm CCD/background-dominated sets vs the base build (987e812e2), GPU:
the six Saturn sets (g 4.7-5.8) all improve - guard fallbacks 4.1-17.3% -> 1.2-6.1%,
anomalous peak height 3mc4 x1.10, 3p85 x1.02, 3r6o x1.06, 5cc8 x1.03, 5uth x1.05, 5vml x1.04;
R_meas 0.880-0.993x on all six; R_model shell-scaled better on 5/6 (5cc8 +0.0005); ISa 5uth +1.5%,
5vml +15%, 3p85 +3%, the twinned 3mc4/3r6o -5%/-1%. 6cee, 6i3j, 6v2r, 7kcn, 8v4j, 9jzo unchanged.
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
b6f4973908
commit
46da7fb359
9 files changed
+114
-19
No files matched your search
@@ -150,13 +150,15 @@ double CompareCpuVsGpu(IntegratorMode mode, std::optional<float> bandwidth_fwhm,
|
||||
float r1 = 0.0f, float r2 = 0.0f, float r3 = 0.0f,
|
||||
OverlapMode overlap = OverlapMode::Off, float companion_dx = 0.0f,
|
||||
bool clip_spots = false, float odd_partiality = 1.0f,
|
||||
const SpotFootprint *footprint = nullptr) {
|
||||
const SpotFootprint *footprint = nullptr, float pixel_gain = 1.0f) {
|
||||
DiffractionExperiment experiment =
|
||||
MakeExperiment(mode, bandwidth_fwhm, clip_nsigma, radial, DetJF(2), stencil_k, r1, r2, r3,
|
||||
overlap);
|
||||
if (footprint) {
|
||||
{
|
||||
BraggIntegrationSettings settings = experiment.GetBraggIntegrationSettings();
|
||||
settings.Footprint(*footprint);
|
||||
if (footprint)
|
||||
settings.Footprint(*footprint);
|
||||
settings.PixelGain(pixel_gain);
|
||||
experiment.ImportBraggIntegrationSettings(settings);
|
||||
}
|
||||
const size_t width = experiment.GetXPixelsNum();
|
||||
@@ -324,6 +326,16 @@ TEST_CASE("BraggIntegrationEngineGPU_MatchesCPU") {
|
||||
CompareCpuVsGpu(IntegratorMode::ProfileGaussian, std::nullopt, 4.0f, false, 8, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, OverlapMode::Off, 0.0f, false, 0.01f);
|
||||
}
|
||||
// A CCD's gain: every variance at it, so the strong flag and the guard decide in photons, and the
|
||||
// reflections leave in photons - computed independently in the two engines.
|
||||
SECTION("ProfileGaussian pixel gain") {
|
||||
CompareCpuVsGpu(IntegratorMode::ProfileGaussian, std::nullopt, 4.0f, false, 60, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, OverlapMode::Off, 0.0f, false, 1.0f, nullptr, 4.0f);
|
||||
}
|
||||
SECTION("BoxSum pixel gain") {
|
||||
CompareCpuVsGpu(IntegratorMode::BoxSum, std::nullopt, 4.0f, false, 60, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, OverlapMode::Off, 0.0f, false, 1.0f, nullptr, 4.0f);
|
||||
}
|
||||
SECTION("ProfileGaussian mono trim") { CompareCpuVsGpu(IntegratorMode::ProfileGaussian, std::nullopt, 0.0f); }
|
||||
// Unreadable pixels inside the signal disks themselves: the MINPK rescue keeps the reflection and
|
||||
// fits it over what is left, and the peak-loss rule throws back the ones that lost the profile's
|
||||
|
||||
Reference in new issue
Block a user