Serialization

MCMCChains supports saving and loading Chains objects in multiple formats:

  • JSON - Full round-trip with metadata preservation
  • CSV - Simple tabular data export
  • StanCSV - Stan-compatible format for interoperability with Stan ecosystem tools

JSON

The JSON format preserves all chain data including metadata, parameter sections, and iteration information.

using MCMCChains, JSON

chn = Chains(rand(100, 2, 2), [:a, :b])

# Serialize to string
json_str = JSON.json(chn)

# Save to file
JSON.json("chains.json", chn)

# Load from file
chn_loaded = JSON.parsefile("chains.json", Chains)

# Parse from string
chn_from_str = JSON.parse(json_str, Chains)

What Gets Saved

  • Parameter values across all iterations and chains
  • Parameter names and section groupings (:parameters, :internals)
  • Iteration range and thinning information
  • Log evidence (if available)
  • Chain metadata (info field)

CSV

MCMCChains implements the Tables.jl interface, which allows you to use CSV.jl directly for simple data export.

using MCMCChains, CSV

chn = Chains(rand(100, 2, 2), [:a, :b])

# Save (includes iteration and chain columns)
CSV.write("chains.csv", chn)

# Load
chn_loaded = Chains(CSV.File("chains.csv"))
Note

Simple CSV export flattens all chains into rows and adds iteration and chain columns. On reload, the multi-chain structure is reconstructed from these columns, but other metadata (parameter sections, info, log evidence) is not preserved.

StanCSV Format

For interoperability with Stan ecosystem tools (CmdStan, ArviZ, etc.), MCMCChains provides dedicated StanCSV functions that handle the Stan-specific format including comment headers, parameter name conventions, and column ordering.

CmdStan Compatibility

StanCSV support has been tested with CmdStan v2.38. The Stan CSV format is not formally versioned and may change in future CmdStan releases. If you encounter issues with a newer version, please open an issue.

Stan CSV Format Features

  • Adaptation comments: Step size and mass matrix info
  • Timing comments: Elapsed time for warmup/sampling
  • Parameter naming: theta[1,2] is converted to theta.1.2 (indexing and commas are replaced with full stops)
  • Column ordering: Sampler parameters (lp__, accept_stat__, etc.) appear first
  • Internals detection: Parameters ending in __ are auto-classified as internals
Parameter Name Conversion

The name conversion handles Stan's numeric-index dot notation (e.g. theta.1.2 <–> theta[1,2]). Parameter names containing non-numeric dot segments (e.g. a.b) are left unchanged. This means the conversion is not fully invertible for arbitrary Julia symbol names — it is designed for Stan-generated output only.

Writing StanCSV

using MCMCChains, CSV

chn = Chains(rand(100, 3, 2), [:mu, :sigma, :lp__], 
             Dict(:internals => [:lp__]))

# Write single chain
write_stancsv("chain_1.csv", chn; chain_id=1)

# Write all chains to separate files (chain_1.csv, chain_2.csv, ...)
write_stancsv("chain.csv", chn, Val(:all))

# Write without comments (plain CSV with Stan column naming)
write_stancsv("chain.csv", chn; include_adaptation=false, include_timing=false)

Reading StanCSV

using MCMCChains, CSV

# Read single file (handles CmdStan output directly)
chn = read_stancsv("output.csv")

# Read multiple chain files
chn = read_stancsv(["chain_1.csv", "chain_2.csv", "chain_3.csv"])

The reader:

  • Skips all comment lines (starting with #)
  • Converts Stan parameter names back to Julia format (theta.1.2theta[1,2])
  • Extracts metadata from comments (model name, seed, warmup, step size)
  • Classifies parameters ending in __ as internals

Example Output

# Adaptation terminated
# Step size = 0.8
# Diagonal elements of inverse mass matrix:
# 1.0
lp__,mu,sigma
-6.74827,0.247195,1.5
-6.74827,0.280619,1.3
...
#
#  Elapsed Time: 0.01 seconds (Warm-up)
#                0.02 seconds (Sampling)
#                0.03 seconds (Total)
#

Format Comparison

FeatureJSONCSVStanCSV
Full metadataPartial
Section infoAuto-detected
Iteration range
Stan compatible
Human readable
Multi-chain in one file
Requires packageJSON.jlCSV.jlCSV.jl