Repository navigation
Planned Chamber
Planned, not yet implemented. Specified in docs/briefs/views-2026-10.md and tracked in issue #42.
The chamber view is specified as a bubble chamber photograph that keeps developing: a round dark window with fiducial crosses and thin tracks of white bubbles. Each busy process circles its own stable home on a Larmor circle whose radius follows its CPU; processes that wind down curl into tight inward spirals; forks appear as V-shaped vertices, exits as small curling delta rays, and the local timer interrupt as a bundle of straight beam tracks. Tilting the camera shows that every track is a helix. This page is the physics of the instrument (track curvature, ionisation, delta rays, neutral decays) and then the design as written in issue #42. Nothing here is implemented yet: isotop --list-views does not list chamber.

The reference mockup (docs/mockups/chamber.jpg), rendered in Python by docs/mockups/code/chamber.py from synthetic data. It is the visual target, not an isotop render.
A bubble chamber is a vessel of liquid held just above its boiling point under pressure. Shortly before an accelerator pulse arrives, a piston expands the liquid and drops its pressure, leaving it superheated: it wants to boil but has no seed. A charged particle crossing it ionises atoms along its path; the freed electrons, and especially the energetic knock-on electrons called delta rays, deposit heat in tiny spots, and each spot nucleates a bubble. The bubbles grow for a few milliseconds while a flash photographs the chamber from several angles; then the liquid is recompressed and the cycle repeats. The photograph is a record of every charged track in the pulse, and a strong magnet around the vessel bends each track in proportion to its momentum. Donald Glaser invented the instrument in 1952 (Nobel Prize in Physics, 1960), and the large hydrogen chambers that Luis Alvarez's group built made the 1950s and 1960s the age of the bubble chamber. The Omega-minus hyperon was identified in a 1964 Brookhaven chamber photograph (Barnes et al.), and CERN's Gargamelle chamber recorded the first neutrino interactions without a charged lepton, the weak neutral currents, in 1973 (Hasert et al.).
What a physicist reads off such a photograph:
- a charged particle leaves a track; a neutral one leaves nothing, and shows itself only through what it does: a vertex out of nowhere, a "V" of two tracks (a V0);
- the curvature of a track gives its momentum, and the sense of the curl gives the sign of its charge;
- the bubble density along a track gives its ionisation, which at a given momentum depends on its mass, so that density plus curvature identifies the particle;
- a track that loses energy curls tighter until it stops: slow electrons make the small tight spirals;
- delta rays are short curling spurs that leave a track at its side, and a vertex is where something was produced or decayed.
That is also exactly the vocabulary of a process table: busy things that move, quiet things that do not, births and deaths at points, parents and children. The metaphor is therefore a mapping of structure, not of units: nothing about a process has a momentum or a charge in the physical sense, and the view says which measured quantity plays each role.
The instrument in the mockup has an older sibling. C. T. R. Wilson, working in Cambridge, had spent time at the Ben Nevis observatory and was struck by the optical effects of sunlight on cloud; he tried to make clouds in the laboratory by expanding moist air in a sealed vessel, and found that droplets formed even when the air had been cleared of dust. Early in 1911 he photographed, for the first time, the tracks of individual alpha and beta particles and electrons as lines of droplets, and the fuller account followed in 1912. The cloud chamber found the positron (Carl Anderson, 1932) and showed the recoil electrons of the Compton effect. Wilson shared the 1927 Nobel Prize in Physics with Arthur Compton, for the chamber.
A cloud chamber is sparse: its working medium is a gas, so few particles interact in it. Donald Glaser's insight of 1952 was to use a superheated liquid, which is dense enough to stop and to make secondary particles, and which, being a liquid, can be pulsed quickly. He received the 1960 Nobel Prize in Physics. The popular story that the idea came from the bubbles in a glass of beer is not Glaser's: in a 2006 talk he disputed it. He did test beer, in 1953, to check a calculation that the chamber should work with water, and the smell is said to have caused trouble in the department.
From there the instrument scaled. Luis Alvarez's group built the large hydrogen chambers of the 1950s and 1960s. The Omega-minus (1964) and the neutral currents (1973) are the two results from chamber photographs that the page above names.
A particle of charge
This holds relativistically because
A 1 GeV/$c$ particle in a 1.5 T field circles with
Left: $r = p/(0.3B)$ for B = 0.5, 1.5 and 3.5 T. Middle: B out of the page; blue is q = +1 (clockwise), orange is q = -1 (anticlockwise); radius is proportional to $p$. Right: with a longitudinal momentum the circle becomes a helix. Script: docs/figures/chamber-larmor-helix.py.
The mean energy a heavy charged particle (charge
with
- At low speed the factor
$1/\beta^2$ dominates: a slow particle spends longer near each atom and ionises more. This is why a slowing track ends in a dense, dark blob. - Near
$\beta\gamma \approx 3$ to$4$ the loss has a shallow minimum ("minimum ionising"). - At high speed the logarithm gives a slow relativistic rise, which in dense media saturates through
$\delta$ .
For liquid hydrogen (
At fixed momentum, mass sets
Left: the Bethe loss relative to its minimum (blue) and the view's specified bubble density $\min(1/\beta^2, 8)$ (orange, dashed). The clamped $1/\beta^2$ keeps the low-speed rise and drops the minimum and the relativistic rise. Right: loss against momentum for three masses. Script: docs/figures/chamber-bethe.py. Formula as printed; shell and density corrections left out.
A collision can hand an electron an energy up to
Script: docs/figures/chamber-spirals.py. Left, physics (anticlockwise: negative charge, B out of the page). Right, the specified integration of issue #42 with CPU = 0.05 + 1.6 exp(-t/14 s) and 1 GiB.
A neutral particle leaves no track. A neutral kaon
Script: docs/figures/chamber-v0.py. Left: a 0.4 GeV/$c$ $K^0_S$ decaying at the origin in 1.5 T. Middle: the three ellipses at a parent momentum of 2 GeV/$c$. Right: survival probability, with the mean decay lengths. Masses and lifetimes from memory of the standard tables.
The view is specified so that each visual element is a measurement or is declared decorative. The measured sources are Process and Snapshot fields; building block B4 is on main (Snapshot::interrupts).
| Visual element | Measured quantity (source) | Transform |
|---|---|---|
| Guiding centre of a track (its home) | the process's stable seat, layout::Seats
|
sunflower point at radius |
| Whether there is a track | smoothed Process.cpu
|
below 0.10 cores the process is neutral and leaves none; the legend counts the neutrals |
| Larmor radius |
CPU as the momentum |
|
| Sense of the curl (charge sign) |
Process.system_share (utime/stime split, P5) |
|
| Speed along the track | CPU and memory |
Process.memory; speed |
| Bubble density per unit length |
|
|
| Helix pitch (visible when tilted) | memory growth rate |
|
| Fork vertex | fork events (Snapshot::life, B3) |
child's track starts at the parent's track head; parent's heading kinks by 0.35 rad; a neutral parent gives a V0 |
| Exec marker | exec events | a ring that fades over 3 s |
| Delta rays at an exit | exit events and Process.threads at the last sample |
one negative-curling spiral per thread, capped at 16 |
| Beam tracks | local timer interrupt delta (B4: LOC on x86, the timer row on arm64) |
|
| Cosmic tracks | all other interrupts (B4) | one per 20,000, capped at 4, remainder carried |
| Bubble flash and fade | the sample tick | one expansion per sample; bubbles brightness |
| Scan sheet (top 11 tracks: q, p, beta, r) | the same figures | listed through stage.places, follows the global l toggle |
| Film grain, flange, fiducial crosses, frame counter | none | decorative |
The figure below plots the mapping from CPU and memory to radius, speed and bubble density, and shows where each clamp binds: the radius clamp at 1.71 cores, and the density clamp below 0.45 cores for a 1 GiB process and below 1.81 cores for a 4 GiB process.
Script: docs/figures/chamber-mapping.py; grey band: neutral, below 0.10 cores.
Everything in this section is the specification of issue #42; none of it exists in the source.
Module and registry. A new module src/chamber.rs with #[derive(Default)] pub struct Chamber implementing views::ViewModule, and one registry row: Backdrop::Void, pressure haze off, links drawn by the view (none), the generic birth and death flash off, default pitch top-down. It is built as ViewInfo::new("chamber", "CHAMBER", Backdrop::Void, build) with build a views::Build closure, sets haze and flash off, links to LinkRule::DrawnByView and pitch to top-down, and names the sources it needs in sources (Source::LifeEvents, and Source::Interrupts for the timer row), so they are read only while the view is shown. The scene builds the view from its row and owns its state. There is no plugin system: views are compile-time modules.
Dependencies. Status in the current source tree:
| Item | Provides | Status |
|---|---|---|
| P1 (#17), P2 (#18) | registry row, picker, smoke list | merged |
| P5 (#21) |
Process.system_share (utime/stime split), syscall_io
|
merged |
| B3 (#30) | fork, exec and exit events (Snapshot::life, Source::LifeEvents, isotop-events thread) |
merged |
| S1 (#22), S2 (#23), S4 (#25), S6 (#27) | parity check, FixedStep, demo births and exits, source demand |
merged |
| P3 (#19) | field primitive for the window backdrop (src/render/field.rs) |
merged |
| B4 (#31) |
/proc/interrupts, /proc/softirqs, oom_kill (Snapshot::interrupts, Source::Interrupts; src/platform/linux/counters.rs, src/model/kernel.rs) |
merged |
Every prerequisite is on main; the view itself is what is missing.
Simulation. simulation::FixedStep at H = 1/120 s on wall-clock time. Each step turns the heading of every track by N over cap. A test asserts the same path at 10 and at 60 frames per second.
Stable homes. Every admitted process, neutral ones included, gets a layout::Seats seat. The issue writes pack::Seats and render::GOLDEN_ANGLE; in the tree these are layout::Seats and layout::GOLDEN_ANGLE. The home is the sunflower (golden-angle) point of its seat, so a process keeps its place when CPU, memory or the population change.
Forks, exits, execs. On a fork the child's track starts at the parent's track head and relaxes to the child's home; the parent's heading kinks by 0.35 rad away from the child. If the parent was neutral the vertex has no incoming track: a V0. An exec draws a ring marker. An exit emits one delta ray per thread from Process.threads at the last sample, capped at 16, each a negative-curling spiral seeded from the Identity (Rng::for_identity).
Bubbles. At each sample tick bubbles form along the motion since the previous tick, using at most the last 2 s of motion. Each is a world-space white Glow of 1.5 to 3 px. At most 40,000 are kept, oldest dropped first; one window-sized Glow of 0.25 s is the expansion flash.
Rendering and picking. The backdrop is one field (P3: grain plus a liquid gradient), not triangles. The head of every charged track is a small Sphere whose pick is the process index; neutral processes are not drawn and cannot be picked. The view-local key p (ViewKey::Local, delivered to ViewModule::key) switches the window to a printed look (paper grey, dark bubbles), and appears on the ? help line. The global t key tilts the camera and so reveals the helices; it is unchanged.
Degradation.
- Linux: full. The event sources are whatever B3 reports (proc connector, taskstats, or sample diffing); the status line names the active ones.
- macOS: available, degraded. Life events come from sample diffing, and there are no interrupt counters, so there are no beam or cosmic tracks; the legend shows
no beam: macOS has no interrupt counters. Live values are never synthesized.
Demo. With DemoOptions { churn: true, kernel_counters: true, ..DemoOptions::NONE } on the registry row (S4 churn and B4's synthesized counters), at --demo --time 12 the frame must contain the utime/stime split, interrupt deltas, a fork from a neutral parent, an exit of a process with 4 or more threads, and one process whose CPU decays through the neutral threshold.
Legend (specified): N tracks | M neutral | beam K = X LOC/s | <sources> | track = busy process circling its home | radius = CPU | curl + user, - system | bubbles ~ 1/beta^2 | V = fork | curls = exit.
- Momentum is CPU. The radius is a scaled CPU load clamped to a fixed range; it is not an energy. The clamp at 18 units hides every difference above 1.7 cores.
- Charge is a coarse dichotomy. The sense of the curl says whether the last interval was user-dominated or system-dominated, and flips between samples when the two are close.
-
A missing track is information too. The
M neutralcount includes every process below 0.10 cores, which on an ordinary machine is nearly all of them. Neutral parents of forks reveal themselves only by a vertex. -
Bubble density is relative. It encodes
$\beta$ , hence CPU relative to memory: a large idle process leaves a dense track, a small busy one a sparse track. - Delta ray counts are thread counts at the last sample before the exit, not at the moment of death.
- Timing is quantised by the sample interval. Bubbles form once per tick over at most the last 2 s of motion; events between samples reach the view through B3 (exact on Linux with the proc connector, inferred by diffing otherwise).
- Pitch is rare and small. It is visible only when the camera is tilted and only for processes whose memory changes.
None of these work yet: chamber is not registered.
# Once the view lands (issue #42).
./target/release/isotop --demo --view chamber --time 12 --width 1600 --output /tmp/chamber.png
./target/release/isotop --demo --view chamber --renderer cpu --width 1920 --benchmark 120Keys planned: p toggles the printed (negative) look, t tilts, l toggles labels. The figures regenerate from the repository root with python3 docs/figures/chamber-larmor-helix.py and the other chamber-*.py scripts.
- Existing:
src/views.rs(REGISTRY,ViewModule),src/simulation.rs(FixedStep,Rng::for_identity),src/layout.rs(Seats,GOLDEN_ANGLE),src/render.rs(Stage,Item::Glow,Item::Sphere,ring_bounds),src/model.rs(Process.system_share,Process.threads,Snapshot::life),src/platform/mod.rs(LifeEvent,Cause,ExitRecord,LifeQueue),src/platform/linux/events.rsandsrc/platform/macos/events.rs(theisotop-eventsthread). - Also existing, which the design uses:
src/render/field.rs(P3),src/model/kernel.rsandsrc/platform/linux/counters.rs(B4). - Planned:
src/chamber.rsand a registry row. - Prototype, reference only:
docs/mockups/code/chamber.py(constants and integration scheme).
-
A momentum measurement from the picture. Fit a circle to a short arc of a drawn track and recover CPU from
$r$ : how well does the visual encoding survive the clamp and the sample interval? - A field that breathes. B could follow the load average, shrinking all radii when the machine is busy.
-
Pair production. A parent that exits at the moment two children are born could draw an
$e^+e^-$ pair, the classic gamma-conversion spirals. - An identification plot. A scan-sheet panel of bubble density against momentum, one point per track, would reproduce the particle-identification plot in which families fall on separate curves of constant mass.
-
Armenteros-Podolanski for forks. Plot parent and child CPU in the same variables and see whether
makechildren cluster like a decay. - Both detectors. Where an exit is drawn here as a spray of spirals, View-Necropolis draws the same exit as a grave. A view that kept both would record every death twice, which is how experiments are usually kept.
-
Delta ray energy spectrum. The view draws one ray per thread; a spectrum
$\propto 1/T^2$ would make many short spurs and a few long ones.
- D. A. Glaser, "Some effects of ionizing radiation on the formation of bubbles in liquids", Physical Review 87, 665 (1952).
- V. E. Barnes et al., "Observation of a hyperon with strangeness minus three", Physical Review Letters 12, 204 (1964).
- F. J. Hasert et al., "Observation of neutrino-like interactions without muon or electron in the Gargamelle neutrino experiment", Physics Letters B 46, 138 (1973).
- Particle Data Group, "Passage of particles through matter" (Review of Particle Physics): the Bethe formula,
$T_{\max}$ and the electron stopping power used above. - J. Podolanski, R. Armenteros, "Analysis of V-events", Philosophical Magazine 45, 13 (1954).
isotop — maximalism for its own sake. Source: tfpickard/isotop. This wiki is published from wiki/ in the repository; edit it there. This footer is decorative.
Philosophy · Gallery · Glossary
Theory
Overview
Sampling: Linux
Sampling: macOS
Background sampler
Model and rates
Life events
History
Journal
Scene and display list
Camera and projection
Rasterization
GPU and parity
Picking
Terminal graphics
Stable layout
Determinism
Simulation toolkit
Colour
Text safety
Mathematics
Fourier epicycles
Wave equation
Flocking
Spatial hashing
Stellar photometry
Lorentz and Schlegel
Reaction-diffusion
Spiking neurons
Schwarzschild
Views
City · Orbit · Ripple
Flow · Cores · Cells
Strata · Globe · Reef
Coop · Matrix
Ptolemy · Tesseract
Necropolis · Cortex
Horizon · Murmuration
Arbor · HR
Hive · Switchboard
Armorial · Lights
Planned
Mold · Chamber
Anthill · Plumbing
Morph · Ouija
Canyon · Die
Guides
Writing a view
Recipes
Headless renders
Contributing to the wiki