Particle Analysis

An analysis bench for event-level physics data — the 2D counterpart to the Particle Event Display, and the plate that actually reads a table. Drop a CSV or TSV of events onto the canvas, or import one from the left panel, and it loads as a dataset with every column typed and summarised. The layout is a fixed split grid of eight regions, so nothing overlaps and everything reflows with the window: a yield-and-significance card, an invariant-mass histogram and an η–φ occupancy map across the top; a parallel-coordinates plot for cut optimisation beside an efficiency curve in the middle; the data table beside a classifier confusion matrix and a model-comparison table along the bottom. Every panel ships as an empty titled shell — no fabricated spectrum, no invented significance — and fills in when you bind it to your data. WHAT EACH PANEL IS FOR. The histogram takes a raw numeric array rather than a table column: `graph2d.histogram({values, bins})` bins the array itself, which is what you want for an invariant-mass or pT spectrum where the binning is the analysis choice. The occupancy map takes either a pre-binned `grid` of numbers or raw `points` of `{x, y, value?}` that it bins into a grid and averages per cell, so an η–φ map, a Dalitz plot or any 2D density is the same call. The parallel-coordinates plot is the cut-optimisation surface: one vertical axis per selection variable, one polyline per event, coloured by whichever field you name in `colorBy`, and `graph2d.brush({id, filters})` applies a range cut per axis, dims everything outside it and reports the surviving event indices. The cuts panel is already linked to the mass histogram, so a cut on the parallel plot shades the surviving mass bins; Clear cuts in the toolbar drops every cut at once. The card, confusion matrix and comparison table are `metrics` panels — yield and significance, a BDT or neural-net classifier's confusion matrix with real class labels, and one row per metric across several models with the best value highlighted. The efficiency curve is `chart2d`, which unlike `graph2d` can pull values live from a table column through a chart's `source: {table, x, y, agg}`, so an efficiency-versus-pT line re-reads the dataset on every redraw. THE DATA TOOLS ARE THE ANALYSIS. Everything in the toolbar operates on the active dataset: group by a column and aggregate, join two datasets, filter rows, add a derived column — this is where an invariant mass or a ΔR gets computed — run PCA for two principal components, remove duplicates, fill or drop missing values, drop or rename a column, show per-column summary statistics, and export the result as CSV. LIMITS, STATED RATHER THAN DISCOVERED. There is no drag-to-brush: `graph2d` draws onto a shared 2D canvas and registers no pointer handlers at all, so brushes are applied by action — from the assistant, from MCP, or from an interaction binding — and the rectangles you see are a rendering of the cut you set, not a handle you drag. The `graph2d:selection` event a brush emits has no listener anywhere in the engine yet, so a cut here cannot drive a 3D event display in another plate. The confusion matrix and comparison table are HTML scorecards, not statistical tests: nothing here computes a p-value, a limit or a fit. And this plate carries no 3D canvas at all — for the detector, the tracks and opening-angle measurement, use the Particle Event Display plate.

Supported file formats: CSV, TSV