Skip to content

Add the far-field pedestal of the search areas (farbg_sum_col_val) - #185

Merged
kriboe90 merged 3 commits into
masterfrom
claude/farfield-pedestal
Nov 10, 2026
Merged

kriboe90 merged 3 commits into
masterfrom
claude/farfield-pedestal

Conversation

@kriboe90

Copy link
Copy Markdown
Contributor

Add the far-field pedestal of the search areas (farbg_sum_col_val)

The sum over a search area (sum_col_val) holds light that does not dim with the LED: the dark level of the sensor where it differs from the optical black, ambient light and light that smoke scatters into the line of sight. In dense smoke this pedestal saturates the extinction coefficients. This PR adds an optional estimate of the pedestal in step 3, taken from the far field of the LED strips, and writes the corrected sum as a new quantity.

What it does

[analyse_photo]
farfield_distances = 150 300

With this option in config.ini, step 3 estimates for every image and LED the level in two bands parallel to the strip, one on each side, over the length of the search area and 150 to 300 px across it. Pixels outside the image and closer than 150 px to any LED are left out, so neighbouring strips and the halo of the LEDs do not enter. The level of a band is the mean of its channel pixels. The levels of each side are smoothed along the strip (running median over 15 LEDs, then running mean over 5), and the lower side is taken as the pedestal per pixel. Step 3 writes two more columns behind max_col_val:

Column Content
farbg_sum_col_val sum minus N times the pedestal, N the number of channel pixels of the search area
farbg_pedestal N times the pedestal

reference_property = farbg_sum_col_val analyses the corrected sum. The analysis knows the new column layouts with and without the fit. With merged LED arrays the bands follow the strips of step 2.

Without the option, or with None, step 3 and its result files stay as they are. With the option, the existing columns of all 1638 result files of the Hasenheide test F2U are identical character by character to those of unpatched 0.13.0. Step 3 takes 17 to 32 % longer per image.

Validation

Seven data sets were evaluated with the linear solver of master: Duisburg TF1, TF2, TF4 and TF5, Hasenheide F2U, and Warsaw V008 (fog) and V009 (n-heptane). There are 34 comparison cells against the reference instruments (MIREX, LEM, SICK).

sum_col_val farbg_sum_col_val
mean of |ratio − 1| over 34 cells 0.108 0.068
median of |ratio − 1| 0.060 0.040
mean of |ratio − 1| over the 26 cells of the fire tests 0.080 0.077
V008, plateaus at 0.41 / 0.81 / 1.24 1/m 0.98 / 0.89–0.93 / 0.71–0.76 1.00–1.05
V008, plateau at 1.64 1/m 0.55–0.61 0.87–0.91
V008 with all LEDs off, remaining signal in % of I0 0.18–0.52 0.005–0.04

V008 is averaged over 21 images here, as in the earlier evaluation. With a threshold of 0.01, 16 cells get better, 12 stay the same and 6 get worse. Subtracting a pedestal can only raise the extinction coefficient, so cells where LEDSA already lies above the reference move away from it. Examples are TF4 against Mirex2 (1.038 → 1.081), F2U in the dense phase against LEM 1 (1.677 → 1.702) and V009 against LEM 2 (+0.011 to +0.013). No pedestal correction can meet the demand that every cell gets better or stays the same.

Limits

For the dark level of the sensor and for stray light that peaks at the strip, the far-field level is a lower bound of the pedestal. Ambient light on a background that is brighter beside the strip than behind the LEDs breaks this bound. The correction has been tested in dark rooms only.

It does not correct a search area that loses light of the LED when the image of the LED widens. That error has the opposite sign, and F2U against LEM 1 stays at 1.70 in the dense phase.

The nonlinear solver has not been tested. Neither have step 3 with fit and merged LED arrays on real images. The unit tests cover both.

In dense fog the read noise takes over once the pedestal is subtracted. The third commit corrects the README and the docstring of the linear solver accordingly.

Commits

  1. add the far-field pedestal of the search areas (farbg_sum_col_val): new module ledsa/data_extraction/farfield_background.py, step 3, config option, column layouts, README section, API docs and 56 unit tests.
  2. test the far-field pedestal on images with a pedestal: the acceptance test images can be wider and carry a uniform pedestal. The new suite 13_test_farfield_pedestal.robot checks the following.
    • Step 3 measures the pedestal (3.0 per pixel).
    • farbg_sum_col_val reproduces the input extinction coefficients (RMSE below 0.05 1/m).
    • sum_col_val comes out about 30 % too low.
  3. name the pedestal as what limits sum_col_val in dense fog: README and docstring now say that with sum_col_val the pedestal limits in V008 (21–27 % and 36–42 % too low in single images). The read noise limits only after the pedestal is subtracted (5–6 % and 24–26 %, or 13–17 % at 1.64 1/m with seven images averaged). This commit can be dropped if the PR should stay with the feature alone.

Tests

  • 455 unit tests pass (399 on master).
  • 31 acceptance tests pass, 3 of them new.
  • The encoding check of the CI passes.
  • The run used Python 3.12. The CI uses 3.10.

🤖 Generated with Claude Code

kriboe90 and others added 3 commits November 10, 2026 23:41
The sum over a search area holds light that does not dim with the LED: the dark level of the
sensor where it differs from the optical black, ambient light and light that smoke scatters into
the line of sight. In dense smoke this pedestal saturates the extinction coefficients.

With farfield_distances = <inner> <outer> in [analyse_photo] of config.ini, step 3 estimates the
pedestal of every image and LED in two bands parallel to the strip, one on each side, over the
length of the search area and from the inner to the outer distance across the strip. Pixels
outside the image and closer than the inner distance to any LED are left out. The level of a band
is the mean of its pixels of the channel. The levels of each side are smoothed along the strip
with a running median over 15 and a running mean over 5 LEDs, and the lower side is the pedestal
per pixel. Step 3 writes farbg_sum_col_val, the sum minus N times the pedestal with N the number
of channel pixels of the search area, and farbg_pedestal behind max_col_val, and the analysis
knows both layouts, with and without the fit. reference_property = farbg_sum_col_val analyses the
corrected sum. Merged LED arrays take the strips of step 2.

Without the option, or with None, step 3 and its result files stay as they were. The unit test
that writes a result file names the encoding on the line of write_text, where the encoding check
of the CI looks for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016cv6PgMB7utWgf5YHwHffz
The test images can be made wider than 50 px, with the strip down their middle, and get a pixel
value added everywhere, light that does not dim with the LEDs. On images 650 px wide with a
pedestal of 3, step 3 with farfield_distances = 150 300 measures 3.0 per pixel of every search
area, farbg_sum_col_val reproduces the input extinction coefficients (RMSE 0.019 to 0.040 1/m),
and sum_col_val gives them about 30 % too low. The defaults leave the images of the other
suites as they were.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016cv6PgMB7utWgf5YHwHffz
The README and the docstring of the linear solver put the extinction coefficients that came out
too low in the Warsaw fog test V008 down to the read noise, which leaves the LEDs with positive
noise only. For sum_col_val that does not hold: there the pedestal of the search areas keeps the
relative intensities above zero, only 0.3 to 3.8 % of the red LEDs are not positive in a single
image, and single images come out 21 to 27 % too low at 1.24 1/m and 36 to 42 % at 1.64 1/m.
The read noise limits once the pedestal is subtracted, with farbg_sum_col_val by 5 to 6 % and 24
to 26 %, and averaging seven images lowers this to 13 to 17 % at 1.64 1/m. V009 has no
extinction this high and is no longer named.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016cv6PgMB7utWgf5YHwHffz
@kriboe90
kriboe90 merged commit 8817598 into master Nov 10, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant