Skip to content

irspec preview FILE: one spectrum as plain text - #3

Merged
aliperdehan merged 1 commit into
mainfrom
claude/preview
Oct 23, 2026
Merged

aliperdehan merged 1 commit into
mainfrom
claude/preview

Conversation

@aliperdehan

@aliperdehan aliperdehan commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

First part of roadmap 1c: irspec preview FILE [--width N] [--height N] [--ascii] [--json] for one .SPA, .jdx or CSV. Standard library plus the numpy and scipy the package already needs; nothing is written or asked.

What it prints

  • The plot. The wavenumber axis runs 4000 to 650 left to right (layout.XLIM), intensity up, with the y limits of the figure (layout.ylimits, with the ymin a session would write). Each picked peak has a symbol (1-9, A-Z, a-z) under its band (above it for an absorbance spectrum). A peak with no free cell near the curve is listed with - and not marked.
  • The block under it. File, detected axis (and the absorbance to %T conversion of a .jdx, said in words), points, ranges, ymin, and the peaks as wavenumber/label height.
  • Characters. Braille (2x4 dots) when stdout's encoding is UTF-8, otherwise or with --ascii the characters . : * |. The frame and labels are ASCII either way.
  • Width. The terminal's width when stdout is a terminal, 80 columns when it is not. --width and --height (default 20 rows) override. Minimum 30 and 3, else exit 2.
  • --json. One object, no plot: file, kind, axis, converted_from, points, range, ymin, peaks, peaks_from.
  • Errors. Exit 2 with the reason on stderr for a file that is missing, not what its name says, or a QUANT-IR file with no peak_a/cl to scale it. The CLI is registered as irspec preview, --help states the honest limit, and the README, CHANGELOG (Unreleased) and roadmap are updated. No version change.

It does not lie

There is no second picking or limit computation. Peaks, label heights and ymin come from ir_organize._finish, the code session runs. A .jdx is converted as the plain CSV session writes it (x to 3 and y to 4 decimals, fractional %T x 100, absorbance to %T). If the file is listed in a manifest.json in its folder or the folder above, that entry is used, so irspec edit ... peak remove followed by irspec preview shows the edit. tests/test_preview.py runs a real irspec session --build none and checks that the preview's peaks are the session's for the .SPA and both .jdx fixtures, and that ymin and the peaks equal figures.json. The absorbance .jdx has a tie (1446.3) that only matches because of the rounding mimic.

Tests

tests/test_preview.py has 32 tests: golden strings for the ASCII output (56 x 8) on the sample .SPA and both .jdx fixtures, a Braille golden, the 80-column default when piped, the terminal width when stdout is a tty (mocked), overrides, character sets under a UTF-8 and an ASCII stdout, --json, an absorbance spectrum (a generated archival CSV) drawn with bands up and symbols above them, QUANT-IR with and without a manifest scale, manifest entries, and unreadable files (missing, folder, wrong extension, garbage .SPA/.jdx/.csv, empty). Nothing is written.

Mutation check: 31 mutants of preview.py (constants, tty test, UTF-8 test, layout limits in the trace and the axis, Braille bit map, ASCII thresholds, symbol side, occupancy test, manifest lookup, ymin, --json, exit code, the rounding mimic, minimum sizes, label spacing, symbol order, axis override, step, QUANT-IR detection). Three survived: the --width minimum (the test used a width that fails anyway), the trace's use of layout.XLIM (the test accepted a symbol in the first column as the trace), and the manifest axis override on an SPA (untested). All three are fixed by tests and re-run killed. Three more mutants pointed at code that did nothing observable (a clip of .jdx rows below 650, a clip of y pixels, an axis override on a CSV, which a session never lists), and that code was deleted.

Full suite on Python 3.13 in a venv: 152 tests, OK, 19 skipped. lualatex and R are not installed here, which this slice does not use. Python 3.9 was not available here; the code uses nothing newer, but CI will say.

Not touched: version, tags, session.py, ir_organize.py, irspec-ir.sty. Not done, as the task says: --stack, --image, session --preview and --dry-run, curses or colour. Not merged.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GqBTMN8XHvB3aG8T6PmfYS

First part of roadmap 1c. Prints the trace in the figure's window (x from layout.XLIM, 4000 to
650 left to right; y limits from layout.ylimits), the picked peaks marked and numbered, and a
block with the detected axis (and the absorbance to %T conversion of a .jdx), points, ranges and
the peaks with their label heights. Braille on a UTF-8 stdout, `. : * |` otherwise or with
--ascii; the terminal's width on a terminal, 80 columns when piped; --width, --height, --json.
Peaks and ymin come from ir_organize._finish (session's own code) or the file's manifest entry,
and the .jdx conversions follow the plain CSV session writes, so the preview agrees with a
session byte for byte on the three fixtures. Exit 2 with the reason on stderr for an unreadable
file. Nothing is written. --stack, --image and session --preview are not in it.

Tests in tests/test_preview.py (golden strings, width, characters, --json, same peaks as a
session, manifest entries, unreadable files), mutation-checked. README, CHANGELOG (Unreleased)
and roadmap updated. No version change.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GqBTMN8XHvB3aG8T6PmfYS
@aliperdehan
aliperdehan merged commit 794f2fc into main Oct 23, 2026
4 checks passed
@aliperdehan
aliperdehan deleted the claude/preview branch October 23, 2026 19:25
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.

2 participants