Commit Graph
8 Commits
Author SHA1 Message Date
menzelandClaude Opus 5 8007a8c8ea debug: recover the scan command from the file itself
CI for csaxs_bec / test (push) Successful in 1m44s
Asked where the scan command can be recovered reliably. It is in the master
file: the file writer stores the whole scan metadata under
/entry/collection/metadata/bec (file_writer.py:255), including request_inputs,
which holds the arguments the scan was actually called with -- arg_bundle,
inputs and kwargs.

That beats notebooks, logbooks and recollection, because it is written by the
component that ran the scan rather than by anyone describing it afterwards.
It also settles the open question directly: whether S00473 was 0.65 um or
6.5 um is answerable from the file, not from the email thread.

--command prints it and stops, request_inputs first.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 12:27:25 +02:00
menzelandClaude Opus 5 f0f8f620de debug: report the achieved geometry, and catch stalls that keep a full span
CI for csaxs_bec / test (push) Successful in 1m45s
The first clean run said both scans were fine, which conflicts with scan 473
being classified as having the artefact. Two gaps explain how that verdict
could be wrong.

**The file was never checked against the intended scan.** Measured fast-axis
travel implies roughly 6.2 um per point in S00473 and 9.2 um in S00254, while
the scans were run at 0.65 um and 1.00 um -- both about 9.3x larger. Until that
is resolved the analysis rests on an unverified assumption about which axis is
which and in what units. The check now prints the fast and slow axis ranges,
the per-line slow step, and the implied step size, so the file can be compared
directly against the scan command. A mismatch means the wrong axis, the wrong
units, or motion that was not commanded, and all three matter more than
anything downstream.

**Whole-line spans cannot see a partial stall.** An axis that freezes part-way
through a line and then continues still covers its full range, so the span test
passes. Since the report describes intermittent motion loss rather than whole
lines going missing, that is the more likely shape of the fault. Lines are now
also scanned for runs of consecutive position samples that did not advance,
reported with the same start/middle/end distribution.

Verified against a file whose stalls leave every span intact: the span test
sees nothing, the new one finds all eight and places them in the final tenth.

Note the sampling limit still applies -- 74 position samples against 428 data
points in S00473, and about 8 against 205 in S00254. A stall shorter than the
sampling interval remains invisible, so a clean result here is not proof.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 12:24:01 +02:00
menzelandClaude Opus 5 95409036bb debug: measure lines against the slow axis, and stop hiding the MCS
CI for csaxs_bec / test (push) Successful in 1m42s
Two faults visible in the run against S00473 and S00254.

**Bug 1 reported nothing at all.** Candidates were restricted to the
`monitored` readout group, but the MCS channels -- which are the per-point scan
data, 203 x 428 = 86884 for S00473 -- are not in it. The filter excluded exactly
the arrays the check exists to examine, so both tables came out empty. The
restriction is gone; positions are still skipped, by ramp shape rather than by
group membership.

**Bug 2 could not find a line structure in S00473.** The monitored stream is
sampled while the line runs, so samples per line vary and the trace does not
reshape into a rectangle; requiring the sample count to divide evenly rejected
it outright. Segmentation now works from the boundaries themselves and tolerates
ragged lines.

That fix alone was not enough, and the reason matters. A line whose motion
failed produces no flyback, so it merges into its neighbour and the merged
segment shows a full, healthy span: **the stall erases the evidence of itself.**
Testing against ragged data with four stalls, the fast axis yielded 103 segments
for 107 lines and pronounced them all consistent.

So lines are now delimited by the **slow** axis, which steps once per line
whatever the fast axis did and stays a valid ruler across a stall. With that,
the same file gives exactly 107 segments and all four stalls, correctly reported
as clustering in the final tenth of the scan.

Where several positioner traces exist, the one with the largest travel per line
is taken as the fast axis and the runners-up are listed with their spans, so a
wrong pick is visible rather than silent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 12:14:31 +02:00
menzelandClaude Opus 5 1b99ffeee9 debug: analyse the scan grid, the real motor, and where faults cluster
CI for csaxs_bec / test (push) Successful in 1m53s
The first run against real files produced numbers that were entirely wrong,
in three separate ways. The metadata now reads correctly (num_lines,
frames_per_trigger), which is what exposed them.

**Wrong arrays.** These files hold two populations: the MCS channels, which
are the per-point scan data, and the monitored devices, sampled opportunistically
while a line runs. The monitored set has more signals, so "the length shared by
the most signals" landed on it -- and it is not on the scan grid at all. S00473
was analysed as 881x17 when the metadata says 203 x 428 = 86884, exactly the
MCS length. The grid length is now taken from the metadata when it matches an
array present in the file.

**Wrong axis.** The fast axis was chosen by how monotonically a signal ramps,
and picked `curr` -- the SLS ring current, which decays smoothly through any
window and beats the motor at its own metric. Positioners are now identified
structurally, by having a `<dev>_user_setpoint` sibling, which is what actually
makes a device a motor.

**Wrong assumption that both checks share one array.** They do not. Intensity
lives on the scan grid; motor position lives in the monitored stream at its own
rate and with its own line boundaries. The two checks now read their own data
and say so. This also surfaces a real limitation: cont_grid records roughly 8
position samples per line in S00254 against 205 data points, so a partial stall
can hide between samples. The script warns when sampling is that sparse rather
than reporting a confident negative.

**Truncated reporting hid the reported symptom.** The artefacts are said to
appear towards the end of scans, and the flagged-line list was cut after 25
entries with "... and 221 more" -- which is precisely where an end-of-scan
cluster would be lost. Flagged lines are now summarised by tenth of the scan,
with an explicit verdict on whether they cluster at the start, the end, or not
at all, and both ends of the list are printed. Bug 1 gains a matching
across-scan trend, since end-of-scan degradation is a different question from
end-of-line.

Verified against a file shaped like the real ones: MCS grid plus a sparse motor
stream, an end-of-line intensity drop, and stalls confined to the last tenth.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 12:09:32 +02:00
menzelandClaude Opus 5 52fed5a008 debug: --list shows per-point arrays first, not scalar configuration
CI for csaxs_bec / test (push) Successful in 1m58s
A --list on a real master file was unreadable: entry/collection/configuration
holds hundreds of scalar per-device settings, it sorts before the actual data,
and piping through head never reached anything useful.

Now arrays are listed largest first and scalars are counted rather than
printed, so the per-point data is visible immediately. Says so explicitly if a
file contains no arrays at all, since that would itself explain an empty
analysis.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 11:56:04 +02:00
menzelandClaude Opus 5 e53f59a0f1 debug: recover the scan geometry from the data, not from metadata
CI for csaxs_bec / test (push) Successful in 1m43s
The previous version still could not analyse the real files: inferring the line
geometry required num_lines / frames_per_trigger, and those keys are simply not
present in these master files. Better diagnostics did not help, because no
amount of reporting turns absent metadata into a geometry.

So stop depending on it. A scanned axis carries its own structure: a raster fast
axis ramps and snaps back, so line boundaries are the few steps far larger than
a typical one; a snake axis reverses instead, so they are where the step changes
sign. Both are tried, and the number of lines follows.

One subtlety decided the implementation. The first attempt required the detected
segments to be evenly sized, which failed on raster data -- because a line whose
motion never happened produces neither a flyback nor a reversal, so its boundary
is missing and its segment measures double. That is exactly the defect this
script looks for, so the check was rejecting the files that matter. It now takes
the *median* spacing between boundaries as the points-per-line, which survives
missing boundaries as long as most are present.

Verified against synthetic raster and snake files with no metadata whatsoever,
both carrying dead lines, at 205 x 107 -- the factorisation the real S00254
implies. Metadata is still preferred when present, and --lines/--points still
override; the output now says which of the three determined the geometry, so a
wrong guess is visible rather than silent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 10:09:32 +02:00
menzelandClaude Opus 5 90358f5222 debug: make the scan check work out its own geometry, or say why it cannot
CI for csaxs_bec / test (push) Successful in 1m47s
First run against real data (S00473, S00254) found the files but stopped at
"metadata: none of the expected keys found" and "could not work out the line
geometry". Two wrong assumptions, both now fixed.

**Metadata location.** It was looked up at two hard-coded paths. BEC nests this
differently across versions, so it is now found by searching the tree for the
keys by basename, attributes included. Verified against metadata one level
deeper than the original code expected.

**Which signal defines the geometry.** The point count was taken from the
*longest* signal. Real files hold signals of several lengths -- S00473 has
86884 points in something while the per-point arrays are shorter -- so a
monitor on its own clock hijacked the calculation. It now takes the length
shared by the most signals, since per-point data outnumbers everything else.

When the geometry still cannot be inferred, the script no longer just gives up
and asks for --list. It now prints every signal grouped by length, and the
factor pairs that could plausibly be (lines x points-per-line). That turns a
dead end into a readable diagnosis in one run rather than a round trip. If a
length does not factor usefully at all it says so explicitly, because a padded
or truncated per-point array is itself a finding.

Also wires up --lines/--points, which were declared but never reached the
analysis.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 09:59:03 +02:00
menzelandClaude Opus 5 a5035d91cb debug: add a desk check for the July 2026 scan artefacts
CI for csaxs_bec / test (push) Successful in 1m48s
Read-only analysis of BEC master files, to test two user reports from the
15-20 July commissioning beamtime without needing beam.

**End-of-line intensity** (Andreas Apseros): reshapes each monitored signal
into lines and reports the last point and the first point against the interior
mean. It only calls it the reported bug when the *last* point is short and the
first is not -- if both ends are low that is a different mechanism, and the
script says so rather than confirming what we went looking for.

**Dropped line motion** (Kazu Hirosawa's reading, that the stage intermittently
stopped scanning in one direction): reshapes the fast-axis readback and reports
the travel per line. A collapsed span is motion that did not happen while the
scan still reported success -- the same shape as the silent-completion defects
already recorded against ccm_energy and the ECMC limit writes. It also reports
start/end scatter per line, since scatter at one end only would instead point
at the return move racing the next line.

Verified against synthetic files with both artefacts injected and a clean
control. That test caught a real flaw in the first version: the fast axis was
picked by within-line range, and a noisy diode channel out-ranged the axis and
was selected instead, breaking both checks. It now scores signals by how
monotonically they ramp within a line, which separates an axis from an
intensity regardless of scale.

Lives on a debug branch, not main: it is a diagnostic for one investigation,
not plugin code. bin/debug/README.md says what that means.

Caveat carried in both the docstring and the README: the motion check reads the
readback, so on an open-loop stepper without an encoder a healthy span proves
nothing. That is the same question as Ana Diaz's micro-stepping point and needs
settling before the null result means anything.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-25 09:24:27 +02:00