tui
An interactive terminal event explorer built on ratatui. When you want to click around a file instead of querying it, this is the view.
hipoq tui rec.hipo
It uses random access (Chain::event(idx)) under the hood, so only one event
is ever in memory — it opens huge files instantly and pages without loading
them.
Layout
Two panes:
- left — the banks present in the current event;
- right — the selected bank's rows, with the same scalar/array formatting as
scan.
A status bar shows the event index, total, and any active filter. Paging through events keeps you on the same bank and row, so you can watch one quantity evolve event to event.
╭ banks ───────────────────╮╭ REC::Calorimeter ─────────────────────────────╮
│▏ REC::Calorimeter 3 ││event row pindex energy sector │
│ REC::Event 1 ││0 0 0 0.8 1 │
│ REC::Particle 2 ││0 1 0 0.9 4 │
╰──────────────────────────╯╰───────────────────────────────────────────────╯
0/99 REC::Calorimeter 3 rows w.hipo
←/→ event · ↑/↓ row · tab pane · b mark · / filter · x xref · v row · : goto
Reading the colours
One accent colour (cyan) means "this is where your keys go", and nothing else uses it:
- the focused pane's border, while the other pane's border is dimmed;
- the row cursor in that pane. An unfocused pane keeps its selection visible but only in bold — the bank list's selection decides what the table shows even when the table has focus, so hiding it would be wrong;
- column headers, so a label never looks quieter than the numbers under it;
- the leading position chip in the status bar, and the keys in the hint line.
Everything secondary — row counts, the filename, hint text — is dimmed.
NO_COLOR is honouredSet NO_COLOR and the TUI drops the hue entirely. Focus
stays legible: the focused pane keeps a bold title while the unfocused one is
dimmed, which is how it looked before the colours existed. Worth knowing if you
run it over a link that mangles escape sequences, or pipe a session to a file.
Keys
| Key | Action |
|---|---|
← / →, n / p | previous / next event |
PgUp / PgDn | jump ±10 events |
g / G | first / last event |
↑ / ↓, j / k | move selection in the focused pane |
Tab | cycle focus: bank list → row table → cross-reference panel |
b | bookmark / unbookmark the current event |
[ / ] | previous / next bookmark |
u / U | jump history: back / forward |
/ | type a filter expression live (empty clears it) |
m / M | next / previous matching event |
x | toggle the pindex cross-reference panel |
v | inspect the selected row — every column, arrays expanded one element per line |
C | enter / leave column mode (see below) |
: | type an event number, Enter to jump |
q / Esc | quit |
Column mode — wide banks
CLAS12 banks are wide: REC::Particle has 14 columns, REC::Traj more. At a
terminal width they run off the right edge, and the two you want side by side —
pid against chi2pid — are rarely adjacent.
Press C to enter column mode, then:
| Key | Action |
|---|---|
← / →, h / l | select a column |
- | hide the selected column |
+ | show every column again |
p | pin the selected column to the left |
< / > | move the selected column |
0 | reset to the original arrangement |
C | leave column mode |
It is behind a toggle because h and l already mean previous/next event, and
taking those permanently would break the primary navigation. The pane title shows
[columns 3/14] while active, and [N hidden] whenever columns are withheld —
a narrower table with nothing to explain it reads as a bank with fewer columns.
The arrangement is per bank, so setting up REC::Particle does not rearrange
REC::Calorimeter, and switching away and back keeps it. Hiding a column and
showing it again restores its position rather than appending it at the end. The
event and row columns are held out of the arrangement — hiding the row number
everything else is read against is not a useful thing to be able to do.
The cross-reference panel
Press x while on REC::Particle to open a panel at the bottom that lists the
detector rows (REC::Calorimeter, REC::Scintillator, …) whose pindex
points at the selected particle — "which detectors did this particle hit".
Tabinto the row table and move withj/kto change which particle is selected — the panel updates.Tabagain focuses the panel itself;j/kthen scroll it.xhides it again.
This is the interactive form of the pindex link: the panel walks the reverse (gather) direction, from a particle to the detector rows that reference it.
Live filtering and jump-to-match
Press / and type any --where expression to set a
match filter live; an empty filter clears it. Then m / M jump to the
next / previous matching event.
You can also preload the filter at launch:
# open already primed to jump between electron events (m / M)
hipoq tui rec.hipo --where "REC::Particle.pid == 11"
| Flag | Meaning |
|---|---|
--where E | preload the jump-to-match filter (repeatable, ANDed) |
A global -r/--require does not narrow the
explorer. To move between matching events, set a filter with / (or
tui --where) and use m / M.
Array columns
A fixed-length array column (cov/F#6) cannot fit a whole vector into a table
cell, so the row table abbreviates it — [0.0,0.1,0.2,0.3,…+2] keeps the
head and says how many elements were left out. Previously the cell was simply
cut at the column width, which lost the closing bracket and read like a
truncated number rather than an array.
Press v for the full values. The inspector lists every column of the
selected row and expands each array one element per line:
REC::Track row 0 — v to close
id = 7
cov (6 elements)
cov[0] = 0
cov[1] = 1.5
cov[2] = 2.5
...
The subscripts are written the way --where
accepts them, so the answer to "how do I cut on this element?" is on screen.