install
source · Clone the upstream repo
git clone https://github.com/plurigrid/asi
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/plurigrid/asi "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/comrade-vlbi" ~/.claude/skills/plurigrid-asi-comrade-vlbi && rm -rf "$T"
manifest:
skills/comrade-vlbi/SKILL.mdsource content
Comrade.jl VLBI Skill
Event Horizon Telescope black hole imaging with deterministic coloring via Gay.jl integration.
Metadata
name: comrade-vlbi description: Comrade.jl VLBI black hole imaging with VLBISkyModels, Pigeons.jl parallel tempering, and Gay.jl deterministic coloring version: 1.0.0 trit: 0 # ERGODIC - bridges sky models to interferometric observations
Core Abstractions
AbstractSkyModel
The base type for all sky brightness distributions. Implementations must provide:
- intensity at sky positionintensity_point(model, p)
- complex visibility at (u,v)visibility(model, u, v)
AbstractInstrumentModel
Encodes station-based corruptions:
gain_terms(instrument, times, stations)phase_calibration(instrument, baseline)
VLBIPosterior
Combines sky model, instrument model, and data likelihood:
post = VLBIPosterior(skymodel, instrumentmodel, dataproducts) logdensityof(post, θ) # Evaluate posterior at parameters θ
VLBISkyModels Primitives
| Primitive | Description | S-expression |
|---|---|---|
| Circular ring | |
| Azimuthal Fourier ring | |
| Elliptical Gaussian | |
| Uniform disk | |
| Asymmetric ring | |
Model Composition
# Addition model = ring + gaussian # Stretching (ellipticity) stretched(model, sx, sy) # Rotation rotated(model, θ) # Translation shifted(model, Δx, Δy) # Convolution smoothed(ring, gaussian)
Lisp S-Expression Syntax
Gay.jl provides colored S-expression display matching Comrade model structure:
;; M87* model as S-expression (parentheses colored by Gay.jl) (sky-add (ring 1.0 0.3) (gaussian 0.5 0.3)) ;; Transformed model (sky-rotate (sky-stretch (mring 0.8 [0.3 0.1] [0.2 -0.1]) 0.67 0.67) 0.785) ;; Sgr A* style (sky-add (crescent 1.2 0.6 0.3) (disk 0.4))
GF(3) Conservation
The ERGODIC trit (0) reflects Comrade's role as a bridge:
Sky Model (PLUS +1) ──╮ ├──▶ Comrade (ERGODIC 0) ──▶ Posterior Samples Observations (MINUS -1)──╯ Σ trits = +1 + (-1) + 0 = 0 ✓ CONSERVED
Pigeons.jl SplitMix Pattern
Both Comrade and Gay.jl leverage the same splittable RNG pattern:
# Pigeons parallel tempering uses splittable RNG # Gay.jl colors use SplitMix64 for determinism # They compose naturally: function colored_posterior_sample(post, seed) gay_seed!(seed) pt = pigeons(target=ascube(post), explorer=SliceSampler()) # Each sample gets deterministic color for θ in sample_array(pt) color = next_color() visualize_sample(θ, color) end end
Example: Full Pipeline
using Comrade, Pigeons, Gay # 1. Load EHT data obs = load_ehtim_uvfits("M87_2017_101.uvfits") dlcamp = extract_lcamp(obs) dcphase = extract_cphase(obs) # 2. Define sky model with Gay.jl colors gay_seed!(2017_04_11) # Observation date as seed function skymodel(θ) (; r, w, α, β, f, σ) = θ ring = smoothed(MRing((α,), (β,)), Gaussian(w)) gauss = Gaussian(σ) return stretched(ring, r, r) + f * gauss end # 3. Build posterior prior = NamedTuple{(:r,:w,:α,:β,:f,:σ)}( Uniform(μas2rad(10), μas2rad(30)), Uniform(μas2rad(1), μas2rad(10)), Uniform(-0.5, 0.5), Uniform(-0.5, 0.5), Uniform(0.0, 0.3), Uniform(μas2rad(5), μas2rad(50)) ) post = VLBIPosterior(skymodel, prior, dlcamp, dcphase) # 4. Sample with Pigeons.jl (uses SplitMix internally!) pt = pigeons( target = ascube(post), n_rounds = 12, checkpoint = true ) # 5. Visualize with colored sexps for θ in sample_array(pt)[1:5] m = skymodel(θ) println(sky_show(m)) end
End-of-Skill Interface
Commands
Create M87* Style Model
using Comrade, Gay gay_seed!(1069) # M87* ring + Gaussian ring = smoothed(stretched(MRing((0.0,), (0.3,)), 2/3, 2/3), Gaussian(μas2rad(5.0))) gauss = Gaussian(μas2rad(20.0)) m87_model = ring + 0.1 * gauss
Create Sgr A* Style Model
using Comrade, Gay gay_seed!(2024) # Sgr A* crescent with compact core crescent = ConcordanceCrescent(μas2rad(25.0), 0.9, 0.3, π/4) core = Gaussian(μas2rad(5.0)) sgra_model = crescent + 0.2 * shifted(core, μas2rad(3.0), μas2rad(-2.0))
Pigeons.jl Integration
using Pigeons, Comrade # Transform posterior for parallel tempering pt = pigeons( target = ascube(post), # Unit hypercube transformation reference = asflat(prior), # Flat reference distribution n_rounds = 15, n_chains = 24 ) # Extract samples samples = sample_array(pt)
Gay.jl REPL Commands
# In Julia REPL with Gay.jl loaded using Gay # Set seed for reproducible colors gay_seed!(1069) # Create colored ring primitive ring = comrade_ring(1.0, 0.3) # Gets deterministic color # Show as colored S-expression sky_show(ring) # => "(ring 1.0 0.3)" with colored parentheses # Build and visualize full model model = comrade_model(seed=1069, style=:m87) comrade_show(model) # Prints colored sexp + ASCII render
Integration with Gay.jl/src/comrade.jl
Reference implementation:
/Users/bob/worlds/b/bmorphism/Gay.jl/src/comrade.jl
Key functions:
- Ring with deterministic colorcomrade_ring(r, w)
- MRing with Fourier coefficientscomrade_mring(r, α, β)
- Gaussian primitivecomrade_gaussian(σx, σy)
- High-level model buildercomrade_model(seed=42, style=:m87)
- Colored S-expression displaysky_show(model)
- ASCII intensity mapsky_render(model)
Related Skills
- Core Gay.jl integrationgay-julia
- Parallel tempering patternspigeons-spi
- S-expression ↔ ACSet bridgelispsyntax-acset
- Dendroidal structure for model compositioninfinity-operads
Autopoietic Marginalia
The interaction IS the skill improving itself.
Every use of this skill is an opportunity for worlding:
- MEMORY (-1): Record what was learned
- REMEMBERING (0): Connect patterns to other skills
- WORLDING (+1): Evolve the skill based on use
Add Interaction Exemplars here as the skill is used.