Skip to main content

rootfileviewer

Inspect a ROOT or Parquet file's contents from the terminal — directory/object hierarchy, TTree branches or Parquet columns, and file-level stats — using uproot (bundled) and pyarrow (optional, for Parquet), with no PyROOT/ROOT installation required.

  • One-shot mode (default): prints a summary panel, an ASCII object tree, and per-TTree/per-Parquet-column tables, rendered with rich.
  • Interactive TUI (--tui): a navigable textual app — arrow keys to browse the object tree, select a node to see its details in a side panel. Selecting a 1D histogram (TH1*/TProfile) plots it as an ASCII bar chart in a panel below, via textual-plotext/plotext. 2D/3D histograms aren't plotted yet — the detail panel notes this instead. A TTree/TNtuple node (or a Parquet file's implicit table) expands into its branches/columns — selecting one plots its value distribution the same way (vector/jagged branches are flattened first; very large trees/columns are capped at 200,000 entries, noted in the detail panel).
  • Terse mode (--terse/-t): flat, tab-separated, no-color output — for piping into grep/awk/other scripts.

Parquet support is an optional extra (see Install) — a lean pip install rootfileviewer covers ROOT files only, so pointing it at a .parquet file without the extra prints clear install instructions instead of failing with an import error.

Install

pip install rootfileviewer

This installs rootfileviewer on PyPI, along with two shorter aliases for it: rfv (equivalent to rootfileviewer) and rfvt (equivalent to rootfileviewer --tui). So rfv examples/sample.root and rfvt examples/sample.root work anywhere the long forms do.

The base install only pulls in uproot (and rich/textual/plotext for rendering) — it does not require pyarrow, so it stays lean if you only ever open .root files. Parquet support is an optional extra:

pip install 'rootfileviewer[parquet]'   # adds pyarrow, for .parquet/.pq files
pip install 'rootfileviewer[all]'       # every optional format's dependencies

If you point a lean install at a .parquet file, it tells you exactly what to do instead of crashing:

$ rootfileviewer data.parquet
error: reading .parquet files needs: pyarrow
Install it with either:
    pip install 'rootfileviewer[parquet]'
or:
    pip install pyarrow
then re-run this command.

You can also install straight from GitHub:

pip install git+https://github.com/matplo/rootfileviewer.git

Or clone and install locally:

git clone https://github.com/matplo/rootfileviewer.git
cd rootfileviewer
pip install -e .

Examples

The ROOT examples below use examples/sample.root, committed in this repo (regenerate it with python examples/make_sample.py), containing:

  • a TTree events with branches pt, eta (double), n_jets (int32_t), 2,000 entries
  • a TH1D histogram pt_hist of the pt values, 25 bins
  • a subdirectory aux holding a second TTree, meta, with one branch run_number, 5 entries

The Parquet examples use examples/sample.parquet (regenerate it with python examples/make_sample_parquet.py) — the same pt/eta/n_jets columns and 2,000 rows as the events TTree above, so the two are directly comparable; Parquet has no histogram or subdirectory equivalent.

Clone the repo and run these directly:

git clone https://github.com/matplo/rootfileviewer.git
cd rootfileviewer
rootfileviewer examples/sample.root

One-shot mode

rootfileviewer examples/sample.root
╭───────── ROOT file summary ──────────╮
│ File: examples/sample.root           │
│ Size: 80.5 KB   Compression: ZLIB(1) │
│ uproot: 5.7.6                        │
│ Keys: 3   TTrees: 2   Histograms: 1  │
╰──────────────────────────────────────╯
sample.root
├── events (TTree) - 2,000 entries, 3 branches
├── pt_hist (TH1D) - 25 bins
└── aux (TDirectory)
    └── meta (TTree) - 5 entries, 1 branches
   TTree: events    
  (2,000 entries)   
┏━━━━━━━━┳━━━━━━━━━┓
┃ Branch ┃ Type    ┃
┡━━━━━━━━╇━━━━━━━━━┩
│ pt     │ double  │
│ eta    │ double  │
│ n_jets │ int32_t │
└────────┴─────────┘
  TTree: aux/meta  (5   
        entries)        
┏━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Branch     ┃ Type    ┃
┡━━━━━━━━━━━━╇━━━━━━━━━┩
│ run_number │ int32_t │
└────────────┴─────────┘

The same mode works for Parquet files, once the [parquet] extra is installed — the summary panel and per-column table use Parquet-appropriate wording instead of ROOT's:

rootfileviewer examples/sample.parquet
╭────────── Parquet file summary ──────────╮
│ File: examples/sample.parquet            │
│ Size: 38.4 KB                            │
│ pyarrow: 25.0.1                          │
│ Rows: 2,000   Columns: 3   Row groups: 1 │
╰──────────────────────────────────────────╯
sample.parquet
└── table (ParquetTable) - 2,000 entries, 3 columns
      Table:       
  sample.parquet   
  (2,000 entries)  
┏━━━━━━━━┳━━━━━━━━┓
┃ Column ┃ Type   ┃
┡━━━━━━━━╇━━━━━━━━┩
│ pt     │ double │
│ eta    │ double │
│ n_jets │ int32  │
└────────┴────────┘

Other one-shot flags:

rootfileviewer examples/sample.root --depth 0            # don't recurse into subdirectories
rootfileviewer examples/sample.root --filter 'events'    # only show keys matching a regex
rootfileviewer examples/sample.root --no-branches        # skip the per-TTree branch tables

For Parquet files, --filter matches column names instead (there's only one flat table, so there's nothing else to filter), --depth is a no-op (nothing to recurse into), and --no-branches skips the column table the same way:

rootfileviewer examples/sample.parquet --filter 'pt|eta'    # only pt/eta columns
rootfileviewer examples/sample.parquet --no-branches        # skip the column table

Interactive TUI

rootfileviewer examples/sample.root --tui
# or, equivalently:
rfvt examples/sample.root

Arrow keys navigate the tree on the left; Enter/click selects a node and updates the panel on the right. Expand events to see its branches; select pt_hist or the pt branch to plot it below. q quits.

┌─ rootfileviewer: sample.root ──────────────────────────────────────────────────┐
│ ┌─ tree ───────────────────┐ ┌─ detail ─────────────────────────────┐   │
│ │ ▼ sample.root             │ │ Field     Value                     │   │
│ │   ▼ events (TTree) - ...  │ │ branch    pt                        │   │
│ │   │  ▶ pt (double)      ◀ │ │ type      double                    │   │
│ │   │    eta (double)       │ │ sampled   2,000 entries             │   │
│ │   │    n_jets (int32_t)   │ │                                     │   │
│ │     pt_hist (TH1D) - ...  │ │                                     │   │
│ │   ▼ aux (TDirectory)      │ │                                     │   │
│ │       meta (TTree) - ...  │ │                                     │   │
│ └────────────────────────  ┘ └───────────────────────────────────  ┘   │
│ ┌─ histplot ────────────────────────────────────────────────────────┐   │
│ │                                     pt                             │   │
│ │ 208.0┤         ███████                                             │   │
│ │      │    ████████████████                                        │   │
│ │      │  █████████████████████████                                 │   │
│ │  0.0 ┤█████████████████████████████████████████████████████████  │   │
│ │      └────────────┬──────────────────┬─────────────────────────  │   │
│ │            18.5                65.7                               │   │
│ └─────────────────────────────────────────────────────────────────  ┘   │
│                                                                q Quit    │
└───────────────────────────────────────────────────────────────────────  ┘

The plot panel is the same plotext render whether you selected the pt_hist histogram or the pt branch directly (they happen to look similar here since pt_hist was built from pt) — actual captures below:

Selecting pt_hist (TH1D) — exact terminal capture
                                   pt_hist                              
     ┌─────────────────────────────────────────────────────────────────┐
248.0┤          ████                                                   │
     │        ███████████                                              │
206.7┤     ██████████████                                              │
     │     ██████████████                                              │
165.3┤     ██████████████                                              │
     │     ████████████████                                            │
124.0┤   █████████████████████                                         │
     │   █████████████████████                                         │
     │   ████████████████████████                                      │
 82.7┤   ████████████████████████                                      │
     │████████████████████████████████                                 │
 41.3┤██████████████████████████████████                               │
     │██████████████████████████████████████████                       │
  0.0┤█████████████████████████████████████████████████████████████████│
     └──────────────────────┬──────────────┬─────────────────────────┬─┘
               33.27650853248193   55.95309492725528 93.74740558521088  

(plotext's axis tick count/labels can shift slightly with terminal width — the bars themselves are what matters here.)

Selecting the pt branch under events — exact terminal capture
                                     pt                                 
     ┌─────────────────────────────────────────────────────────────────┐
208.0┤         ███████                                                 │
     │         █████████                                               │
173.3┤      ████████████                                               │
     │    ████████████████                                             │
138.7┤    ████████████████                                             │
     │    ████████████████                                             │
104.0┤    ████████████████████                                         │
     │  ██████████████████████                                         │
     │  █████████████████████████                                      │
 69.3┤  ███████████████████████████                                    │
     │█████████████████████████████████                                │
 34.7┤█████████████████████████████████                                │
     │██████████████████████████████████████████   ███                 │
  0.0┤█████████████████████████████████████████████████████████████████│
     └─────┬─────────────────────────┬──────────────────┬──────────────┘
     9.025159193627086       46.81946985158268    75.1652028450494      

Detail panel for this selection: branch: pt, type: double, sampled: 2,000 entries. On a tree with more than 200,000 entries the sampled row would instead read e.g. 200,000/5,000,000 entries — the plot is always built from a capped, uniformly-sampled prefix for responsiveness, and vector/jagged branches are flattened first (noted as ..., N values (flattened)).

For a Parquet file, the tree root expands directly into a single table node (the file's implicit flat table), which itself expands into its columns — same navigation, same plotting:

rootfileviewer examples/sample.parquet --tui
Selecting the pt column — exact terminal capture
                                      pt                                 
     ┌──────────────────────────────────────────────────────────────────┐
208.0┤         ███████                                                  │
     │       ███████████                                                │
173.3┤       ███████████                                                │
     │    █████████████████                                             │
138.7┤    █████████████████                                             │
104.0┤    █████████████████████                                         │
     │  ███████████████████████                                         │
 69.3┤  █████████████████████████                                       │
     │  ███████████████████████████                                     │
 34.7┤██████████████████████████████████                                │
     │██████████████████████████████████████████                        │
  0.0┤██████████████████████████████████████████████████████████████████│
     └─────────────────────┬──────────────┬──────────────┬──────────────┘
             31.071840410767848   53.11852162790862  75.1652028450494    
Selecting the n_jets column — exact terminal capture
                                    n_jets                               
     ┌──────────────────────────────────────────────────────────────────┐
351.0┤███                       ███          ███                        │
     │███          ███          ███          ███          ███        ███│
292.5┤███          ███          ███          ███          ███        ███│
     │███          ███          ███          ███          ███        ███│
234.0┤███          ███          ███          ███          ███        ███│
175.5┤███          ███          ███          ███          ███        ███│
     │███          ███          ███          ███          ███        ███│
117.0┤███          ███          ███          ███          ███        ███│
     │███          ███          ███          ███          ███        ███│
 58.5┤███          ███          ███          ███          ███        ███│
     │███          ███          ███          ███          ███        ███│
  0.0┤██           ██           ██           ██           ██         ███│
     └───┬──────┬─────┬──────┬─────┬──────┬──────────────┬──────────────┘
       0.25   0.75  1.25   1.75  2.25   2.75     3.9166666666666665

n_jets is a low-cardinality integer column, so each bar lands on its own narrow bucket — a good illustration that this is the exact same numpy.histogram-based binning used for ROOT branches, not a special-cased "categorical" plot.

Note the detail panel shows branch/type labels for a selected column (reused verbatim from the ROOT branch code path) rather than "column" — harmless, cosmetic, and left as-is.

Terse mode

--terse/-t prints flat, tab-separated lines instead of panels/trees/tables — each line starts with a record-type tag (summary/object/branch) so a consumer can pick out what it needs:

rootfileviewer examples/sample.root -t
summary	path	examples/sample.root
summary	format	root
summary	size_bytes	82443
summary	uproot_version	5.7.6
summary	compression	ZLIB(1)
summary	num_trees	2
summary	num_histograms	1
summary	total_keys	3
object	events	TTree	entries=2000	branches=3
object	pt_hist	TH1D	bins=25
object	aux	TDirectory
object	aux/meta	TTree	entries=5	branches=1
branch	events	pt	double
branch	events	eta	double
branch	events	n_jets	int32_t
branch	aux/meta	run_number	int32_t
rootfileviewer examples/sample.root -t | grep '^branch'
rootfileviewer examples/sample.root -t | awk -F'\t' '$1 == "branch" && $2 == "events" {print $3, $4}'
rootfileviewer examples/sample.root -t | awk -F'\t' '$1 == "object" && $3 == "TTree" {print $2}'

The same tags cover Parquet output — a script can tell the two apart via summary format or an object row's classname (ParquetTable vs TTree); the branch tag itself is reused for columns rather than introducing a separate column tag:

rootfileviewer examples/sample.parquet -t
summary	path	examples/sample.parquet
summary	format	parquet
summary	size_bytes	39340
summary	pyarrow_version	25.0.1
summary	num_rows	2000
summary	num_columns	3
summary	num_row_groups	1
summary	total_keys	1
object	table	ParquetTable	entries=2000	branches=3
branch	table	pt	double
branch	table	eta	double
branch	table	n_jets	int32

Options

Flag Description
--tui launch the interactive textual TUI instead of printing (same as running rfvt)
--terse, -t flat, tab-separated output with no borders/colors
--depth N limit directory recursion depth (ROOT only — no-op for Parquet, which has no subdirectories)
--filter REGEX only show keys whose name matches REGEX (ROOT) or column names matching REGEX (Parquet)
--no-branches skip per-TTree branch info / per-Parquet column info in one-shot/terse mode

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rootfileviewer-0.7.1.tar.gz (99.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rootfileviewer-0.7.1-py3-none-any.whl (19.4 kB view details)

Uploaded Python 3

File details

Details for the file rootfileviewer-0.7.1.tar.gz.

File metadata

  • Download URL: rootfileviewer-0.7.1.tar.gz
  • Upload date:
  • Size: 99.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for rootfileviewer-0.7.1.tar.gz
Algorithm Hash digest
SHA256 f1d7c596424f56d131b62419eb915912c33c4772d17f9dd41200f8b369bf1a51
MD5 b3a686694d7009f86a8dcce6f6f493e9
BLAKE2b-256 ab218f98c448ff30abdeb137a58bbc701fee6fc60720d2de57371cf7df484c89

See more details on using hashes here.

Provenance

The following attestation bundles were made for rootfileviewer-0.7.1.tar.gz:

Publisher: publish.yml on matplo/rootfileviewer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rootfileviewer-0.7.1-py3-none-any.whl.

File metadata

  • Download URL: rootfileviewer-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 19.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for rootfileviewer-0.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f2ecba76565453ddb20981dc478808a698ca292c968e449060f24778e305d32d
MD5 399976b94b5bb89110549181ebfa66ed
BLAKE2b-256 4549de82b9ffde372228a2310fcd212f43cde88e1f8074e57575d71ff51d5eb7

See more details on using hashes here.

Provenance

The following attestation bundles were made for rootfileviewer-0.7.1-py3-none-any.whl:

Publisher: publish.yml on matplo/rootfileviewer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.10.0

2 files

0.9.1

2 files

0.9.0

2 files

0.8.1

2 files

0.8.0

2 files

This release

0.7.1 This release

2 files

0.7.0

2 files

0.6.0

2 files

0.5.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page