Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,18 @@ irspec follows the rules in the README's "Versioning" section. Newest first.
editor (keys: `title`, `axis`, `name`, `ymin`, `ymax`, `xmin`, `xmax`, `threshold`,
`prominence`, `distance`). Atomic write, order and layout kept, idempotent, prints the old and
new value (`--json`: one object), errors on stderr with exit 2 (1 for a missing manifest).
First slice of roadmap item 1a; peak editing and re-running the session are not in it, and
First slice of roadmap item 1a; re-running the session is not in it, and
`xmin`, `xmax` and `ymax` are stored but not yet read by the figures.
- `irspec edit DIR FILE peak add X ...`, `peak remove X ...`, `peak clear` and `peak auto`:
second slice of roadmap item 1a. `add` snaps each wavenumber to the nearest local band
(`find_peaks_manual`, through the code `session` itself uses, so the label heights are
session's), `remove` takes out the stored peak nearest X within 15 cm-1, `clear` leaves none,
`auto` picks again with the entry's `threshold`/`prominence`/`distance` and replaces hand
edits, saying what it dropped. Same conventions as `set`/`unset` (atomic, idempotent, old ->
new, `--json`, exit 2/1); the spectrum is read as `session` reads it, exit 2 when there is none.
- `"peaks": []` in the manifest now means "no peaks" (it used to be picked again by `session`,
as if the key were missing), so a cleared or emptied list survives a re-run. Delete the key to
pick again, as before.

## 0.1.0 (2026-10-16), the first release

Expand Down
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ re-run: your edits stay, new files are appended, vanished files are dropped.
|---|---|
| `file` | path of the spectrum, relative to the folder (`SPA/…`, `jdx/…`, `img/…`) |
| `title` | the caption under the figure, free text (`"Alcohol (stock)"` is fine). A new entry starts with the file's stem (an instrument spectrum), or with its compound name (`"METHYL_CINNAMATE_GAS"` gives "Methyl cinnamate gas"), or with the title inside the `.jdx`; change it here |
| `peaks` | `[wavenumber, label_y]` pairs, as picked; edit, add or delete here. A bare number is snapped to the nearest local band. Delete the key to pick again |
| `peaks` | `[wavenumber, label_y]` pairs, as picked; edit, add or delete here (or with `irspec edit … peak`). A bare number is snapped to the nearest local band. `[]` means no peaks. Delete the key to pick again |
| `axis` | y-axis label (default `Transmittance %`) |
| `ymin` | bottom of the y axis; the tool's suggestion is kept as it is, and may be negative for a strong band |
| `threshold`, `prominence`, `distance` | peak-picking sensitivity overrides, for a band at the plot edge or noise taken for bands |
Expand All @@ -226,6 +226,10 @@ folder afterwards to redraw (a re-run keeps what you set).
```
irspec edit my_lab_folder/ PHENACETIN_CRUDE_LR1-2 set title="Phenacetin (crude)" ymin=-5
irspec edit my_lab_folder/ SPA/PHENACETIN_CRUDE_LR1-2.SPA unset ymin
irspec edit my_lab_folder/ PHENACETIN_CRUDE_LR1-2 peak add 1720 3000 # snapped to the nearest band
irspec edit my_lab_folder/ PHENACETIN_CRUDE_LR1-2 peak remove 3253
irspec edit my_lab_folder/ PHENACETIN_CRUDE_LR1-2 peak clear # no peaks at all
irspec edit my_lab_folder/ PHENACETIN_CRUDE_LR1-2 peak auto # pick again, drop hand edits
irspec edit my_lab_folder/ show # every entry, as text
irspec edit my_lab_folder/ show PHENACETIN_CRUDE_LR1-2 --json
```
Expand All @@ -236,8 +240,20 @@ irspec edit my_lab_folder/ show PHENACETIN_CRUDE_LR1-2 --json
- **Which keys.** `set` and `unset` take `title`, `axis`, `name` (text) and `ymin`, `ymax`,
`xmin`, `xmax`, `threshold`, `prominence`, `distance` (numbers, stored as JSON numbers; a
value that is not a number is refused). Any other key is an error naming the allowed ones.
`xmin`, `xmax` and `ymax` are stored but the drawing code does not read them yet; `peaks`
still has to be edited by hand.
`xmin`, `xmax` and `ymax` are stored but the drawing code does not read them yet.
- **Peaks.** `peak add X ...` snaps each wavenumber to the nearest local band of that
spectrum (within 15 cm⁻¹) and adds it with the label height `session` gives a band named by
its wavenumber alone. `peak remove X ...` takes out the stored peak nearest X, if one is
within 15 cm⁻¹. `peak clear` leaves the figure with no peaks (`"peaks": []`). `peak auto`
picks again with the entry's `threshold`, `prominence` and `distance`, **replaces everything
stored, hand edits included**, and lists what it dropped. Each writes an explicit `peaks`
list, which `irspec session` keeps, so the redraw shows exactly these peaks. They start from
what the figure shows now (an entry with no `peaks` yet starts from the automatic list), a
peak already there or none near an X to remove changes nothing (a note goes to stderr, exit
0), and the changes print as `peak: old -> new` (`--json`: `{"key": "peak", "old": null,
"new": [1732.7, 93.6]}` for an added peak, the other way round for a removed one). The
spectrum is read as `session` reads it (an own `.SPA` from the file, a reference spectrum
from `plain/NAME.csv`); with no spectrum to read, exit 2.
- **What it writes.** The file is replaced atomically (a temporary file in the same folder,
then a rename). Entries and keys keep their order, a new key goes last, and the file keeps
its layout (the one `session` writes, else its own indentation, line endings and final
Expand Down Expand Up @@ -395,10 +411,10 @@ Anything that depends on irspec before 1.0 should pin the minor version

## Roadmap

The first release is out (PyPI, public repository). Planned, in this order; of this, only `irspec edit set`, `unset` and `show` exist so far:
The first release is out (PyPI, public repository). Planned, in this order; of this, only `irspec edit set`, `unset`, `show` and `peak` exist so far:

- **Editing from the command line** (`irspec edit set/unset/show` are in; still to come: add and
remove peaks, rename/remove/move, re-running the session for the figure),
- **Editing from the command line** (`irspec edit set/unset/show/peak` are in; still to come: rename/remove/move,
re-running the session for the figure),
`--json` output and a written description of the manifest, so scripts and AI agents can drive
everything a person can;
- **A preview in the terminal** (`irspec preview`, `session --preview`): the spectrum drawn in
Expand Down
22 changes: 14 additions & 8 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,20 @@ moves only if the manifest or `figures.json` format breaks; adding optional keys

### 1a. Editing: `irspec edit`

**Done (Unreleased, `src/irspec/edit.py`, `tests/test_edit.py`):** `set KEY=VALUE ...`,
`unset KEY ...` and `show [FILE] [--json]` on `manifest.json` only, for the keys `title`,
`axis`, `name`, `ymin`, `ymax`, `xmin`, `xmax`, `threshold`, `prominence`, `distance`; atomic
write, order and layout kept, idempotent, `--json` for the changes. **Not done:** `peak
add/remove/auto/clear`, `rename`/`remove`/`move`, re-running the session for the figure
(`--no-build`), and the per-figure `xmin`/`xmax`/`ymax` in the drawing code (the keys can be
stored today, nothing reads them). The command listing below is the original design; the three
done commands are exactly as written there.
**Done (Unreleased, `src/irspec/edit.py`, `tests/test_edit.py`, `tests/test_edit_peaks.py`):**
`set KEY=VALUE ...`, `unset KEY ...` and `show [FILE] [--json]` on `manifest.json` only, for the
keys `title`, `axis`, `name`, `ymin`, `ymax`, `xmin`, `xmax`, `threshold`, `prominence`,
`distance`; and `peak add X ...`, `peak remove X ...`, `peak clear`, `peak auto`. Atomic write,
order and layout kept, idempotent, `--json` for the changes. The peak commands run `session`'s own
peak code (`ir_organize._finish`/`resolve_peaks`, hence `find_peaks_manual`, `find_peaks_auto`,
`assign_label_y`), so `peak auto` on a fresh session changes nothing and a following `session`
keeps the edit; `remove` matches within 15 cm-1 (the snapping window). To make `clear` survive a
re-run, `"peaks": []` now means "no peaks" in `resolve_peaks` (it used to be picked again).
**Not done:** `rename`/`remove`/`move`, re-running the session for the figure (`--no-build`), a
`--prominence` etc. override on `peak auto` (it uses the entry's keys; `set` them first), and the
per-figure `xmin`/`xmax`/`ymax` in the drawing code (the keys can be stored today, nothing reads
them). The command listing below is the original design; the done commands are exactly as written
there.

**Decided.** Today the manifest is edited by hand in a text editor, which is the only "edit"
there is. It becomes commands (names provisional; `irspec peaks` is already the peak picker for a
Expand Down
2 changes: 1 addition & 1 deletion src/irspec/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
irspec session DIR a folder of spectra -> CSVs, peaks, figure PDF
irspec export PDF ... PNG/TIFF/SVG pictures from a figure PDF
irspec plot DIR ... the figures drawn by matplotlib or R, no TeX needed
irspec edit DIR ... change or show manifest.json (set/unset a key, show)
irspec edit DIR ... change or show manifest.json (set/unset a key, peak add/remove, show)
irspec spa ... OMNIC .SPA -> CSVs, peaks, legacy plots (spa_tool)
irspec jdx ... JCAMP-DX -> CSVs (jdx_tool)
irspec peaks ... peak-pick a .SPA, .jdx or CSV (spa_peaks)
Expand Down
Loading
Loading