Skip to main content

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 honoured

Set 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

KeyAction
/ , n / pprevious / next event
PgUp / PgDnjump ±10 events
g / Gfirst / last event
/ , j / kmove selection in the focused pane
Tabcycle focus: bank list → row table → cross-reference panel
bbookmark / unbookmark the current event
[ / ]previous / next bookmark
u / Ujump history: back / forward
/type a filter expression live (empty clears it)
m / Mnext / previous matching event
xtoggle the pindex cross-reference panel
vinspect the selected row — every column, arrays expanded one element per line
Center / leave column mode (see below)
:type an event number, Enter to jump
q / Escquit

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:

KeyAction
/ , h / lselect a column
-hide the selected column
+show every column again
ppin the selected column to the left
< / >move the selected column
0reset to the original arrangement
Cleave 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".

  • Tab into the row table and move with j/k to change which particle is selected — the panel updates.
  • Tab again focuses the panel itself; j/k then scroll it.
  • x hides 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"
FlagMeaning
--where Epreload the jump-to-match filter (repeatable, ANDed)
Navigation is by raw event index

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.