Files & Restart#

Open summary.md for status and run.log for the complete pipeline output. Every calculation creates runs/<input-stem>/ by default; --output-dir selects another directory. The run command and sweep points use the same layout.

For result tables, energy diagrams and spectra, see Caspy Analysis.

Calculation Directory#

Interpret multiplet widths using the MPPT symmetry and convergence rules. MPPT reconstruction is not generally unitarily invariant; S and applicable L/J completeness, selection and retained states affect splitting. More selected determinants need not reduce it monotonically. Distinguish within-pair Kramers splitting from widths between pairs, and verify time-reversal conditions.

run-dir/
  summary.md                 # current status, energies and diagnostic links
  run.log                    # complete output, labelled by time/stage/attempt
  run.json                   # schema v2, layout_version 2, artifact identities
  input/
    original.yaml
    effective.yaml
    resources/
    generated/               # diagpt.inp, heffso.inp
  logs/
    pyscf.log
    cipsixx.log
    diagpt.log
    heffso.log
    report.log               # report generation; may be empty on success
    events.jsonl
    attempts/0001/           # earlier logs, generated inputs and metadata
  reports/
    cipsixx/                 # iteration/root-energy CSVs
    heffso/                  # occupation/configuration logs, Caspy outputs
  data/                      # shared HDF5, handoff, properties and eigenvectors
  checkpoints/               # Python and optional DIAGPT zeroth-order restart
  scratch/                   # temporary computational files

run.log includes stdout and stderr from PySCF, CIPSIXX, DIAGPT, HEFFSO and report generation. Raw stage logs preserve the programs’ text without added prefixes. The terminal shows concise progress by default; --full-output mirrors the complete stream without changing disk capture. Separate HEFFSO analysis tables remain in reports/heffso/ rather than being repeated in the process stream.

The PySCF log includes scientific reports: initial conditions, effective settings, whitespace energy/orbital tables, correlated CASSCF populations and timed substage progress.

Report stdout and stderr are captured once even with --full-output; console mirroring uses the original terminal stream rather than the report capture.

For --from-hdf5, run.json.external_hdf5 identifies the existing writable file. It stays in place during execution. The archive command explicitly copies it into the bundle’s logical data/ path.

PySCF Dump#

mppt.output_hdf5 defaults to pyscf_dump.h5, stored as data/pyscf_dump.h5 by the CLI. An already data/-qualified relative name is not prefixed twice. A fresh dump replaces its owned HDF5 file; keep a validated archive when preserving a previous scientific result.

The inventory follows the stages the runtime reaches. If --stop-after orbitals is requested without orbital preparation, execution continues through dump; the produced HDF5 is validated and included in the scientific archive. Downstream stages remain suppressed by the stop option.

Important content includes:

  • root orbital, energy, electron, and integral metadata;

  • /mppt/orbital_analysis final-orbital identity and weighted AO-subspace character;

  • one-electron, spin-orbit, compact J/K, and two-electron integral datasets;

  • selected-route datasets when N_select > 0;

  • /cipsixx/config and /cipsixx/integrals for native selection;

  • optional downstream model space and workflow stage groups after selection.

When molecule.so: false, intso is still present and contains zeros.

Orbital Analysis#

Every completed direct dump writes /mppt/orbital_analysis with schema mppt_orbital_analysis_v1. Its rows use final full-space MPPT order, including on the selected route. mppt_orbital_id is one-based; source_pyscf_index is the zero-based permutation back to the coefficient columns supplied by PySCF. selected_mppt_orbital_id contains the existing one-based selected-to-full map, or is empty for the full route.

The group stores source MO energies and occupations, the final-basis compact Fock diagonal, and the closed-shell reference occupations used downstream. When a PySCF CASSCF object has no separate mo_occ, source populations are computed from its final-basis one-particle density. The occupation_source attribute identifies the population provenance; unavailable marks legacy checkpoint compatibility vectors rather than physical correlated populations. Downstream default occupations use an occupied prefix of ceil(N_electrons/2), independent of how many active MOs have nonzero fractional population. Source energies are metadata from SCF or CASSCF; after requested orbital projections they are not claimed to be recanonicalized eigenvalues. The orbital_source attribute records the resolved scf or casscf source rather than the input policy auto.

When AVAS analysis, occupied, or virtual labels are configured, the group also stores their deduplicated display text, lossless JSON specifications, and raw projection_weight[label, orbital] values for the final coefficients. These AO-subspace projector weights are authoritative orbital-character data. Mulliken output remains a text diagnostic and does not replace the weights or force a mixed orbital into one categorical shell label. With no configured labels, both label datasets and the first projection-weight dimension are empty; orbital identities and numeric metadata remain present.

With independent AVAS reference bases, deduplication uses both the AO label and basis specification. label_display identifies explicitly chosen bases; optional projection_basis_spec_json stores each label’s JSON reference-basis overrides (null denotes working AOs). projection_weight is evaluated using those same projectors. Outputs without overrides retain the existing layout.

PySCF Checkpoints#

Direct-stage checkpoints are separate from the HDF5 workflow restart state:

checkpoints/
  input.normalized.json
  scf.npz
  casscf.npz
  orbitals.npz
  stage.json

They resume input normalization, SCF, CASSCF, and orbital preparation. The new casscf.npz payload also includes active one-particle densities, per-root weights and S², associated with its saved MO coefficients. Older checkpoints without these fields report correlated populations as unavailable. The integral HDF5 file is not copied into this directory. The low-level Python API restores the saved normalized input for PySCF stages and the saved work directory without comparing a scientific input fingerprint, external basis/ECP/GRPP contents, package version, or runtime environment. The newly supplied YAML must still parse and its mppt section controls any automatic downstream execution. A checkpoint recorded as complete through dump is accepted without checking that the HDF5 dump still exists or is unchanged. The CLI wraps this API with managed input, resource, checkpoint and HDF5 validation.

Managed Run State#

Every CLI point owns input/effective.yaml, run.json, run.log, a persistent .pyscf2mppt.lock, copied file resources, and a managed-input hash in a successfully validated HDF5 output. run.json records one current attempt, including the exact child command, absolute run directory, timestamps, return code, error, and planned, running, complete, failed, or interrupted status. Resume increments the attempt and appends to run.log. Previous raw logs and small input/metadata files are preserved under logs/attempts/<id>/ before replacement. Reused stages retain their raw logs and record the producing attempt when known. An external checkpoint can reuse its original selector log; if that log is unavailable, its replacement explicitly says so.

A fully reused Python checkpoint is also marked skipped: its current PySCF log and producing attempt are retained, along with the checkpoint energies. Partial continuation records the newly executed Python work as a new attempt.

Sweep roots contain their own lock, sweep.json, sweep.log, summary.csv, and point directories. The sweep manifest records the definition hash, ordered overrides and input hashes, point statuses, return codes, errors, and the current number of points whose status is interrupted. This count is recomputed after attempts rather than retained as cumulative event history. These manifests are orchestration records; scientific energies remain in each point’s normal calculation outputs.

HDF5 Workflow Checkpoints#

Downstream state is stored at:

/mppt/workflow
/mppt/workflow/stages/selection
/mppt/workflow/stages/diagpt
/mppt/workflow/stages/heffso

Each stage can record running, complete, or failed, plus its normalized fingerprint, update time, command, log path, message, and output fingerprint. Input-contract or executable-resolution failures that occur before the stage is marked running can leave no stage record. A stage is reusable only when its configuration/executable/consumed-input fingerprint and its separate durable output_fingerprint both validate. Executable identity currently uses resolved path, byte size, and nanosecond modification time rather than a binary-content hash.

Rerunning selection invalidates DIAGPT and HEFFSO. Rerunning DIAGPT invalidates HEFFSO. Failed or interrupted stages are never treated as complete.

Workflow Sidecars#

Generated native inputs and raw process logs are visible:

input/generated/diagpt.inp
input/generated/heffso.inp
logs/cipsixx.log
logs/diagpt.log
logs/heffso.log

Selection also writes reports/cipsixx/cipsixx_iterations.csv and reports/cipsixx/cipsixx_root_energies.csv by default. Configured report names are placed under reports/cipsixx/. Available CSVs are inventoried and archived, but are not durable reuse outputs. The selection algorithm defines the columns and their pre-growth timing. For DIAGPT, the validated HDF5 handoff is the reuse output.

Report names must remain distinct after relocation, including case aliases. For example, same.csv and reports/cipsixx/same.csv identify one final file and are rejected before the run starts.

Model Space#

The physical selector output is under /cipsixx/selected_determinants. The validated compatibility view consumed downstream is /mppt/model_space/quasi_restricted. It contains packed determinants, source ordering, dimensions, spin/electron metadata, and content hashes. See physical selection and model-space export for why its row count and ordering can differ from the physical selection.

Current preflight limits include metat <= 1000, DIAGPT ncf <= 46340, and HEFFSO ncf <= 35000, plus excitation rank at most eight. HEFFSO packed slots must not exceed 280001; DIAGPT also requires 2*norb + 1 and its packed slot count to fit signed 32-bit integers. Exceeding a compiled capacity is a preflight error, not a request to truncate the model space.

DIAGPT Outputs#

When DIAGPT or HEFFSO is enabled, the complete native prefix must fit 80 UTF-8 bytes, including data/ and the trailing underscore. A simple ASCII prefix without a trailing underscore can therefore contain at most 74 characters. Overlong prefixes are rejected before calculation rather than silently truncated.

mppt.prefix: Ce is normalized to the MPPT file prefix Ce_:

checkpoints/Ce_h0.1
data/Ce_heffso.h5

h0.1 is the optional zeroth-order restart file and is archived when enabled. The CASCI/selected-CI and MPPT2 Hamiltonian matrices are stored in the HDF5 handoff.

The target-state count satisfies 1 <= metat <= ncf; Caspy accepts a target subset and does not require one target per configuration.

The HDF5 handoff has schema mppt_heffso_handoff_v3. Its root attributes are norb, noca, metat, and ncf; determinant datasets are det_ne, det_nd, det_trou, and det_part. The effective Hamiltonians are pair-packed in h1_packed and h2_packed, with their dimensions and energy offsets recorded in the corresponding h1_* and h2_* attributes. Every handoff requires determinant_content_hash_fnv1a64; HEFFSO and Python preflight recompute it from the final ordered/remapped determinant payload before accepting the file. The required model_space_source attribute records the determinant source. For hdf5_quasi_restricted, model_space_content_hash_fnv1a64 is also required and must match a hash that HEFFSO recomputes from the shared model-space payload. The required scalar integer selected_remap attribute is 1 for a selected-route handoff and 0 for an unremapped handoff. When it is 1, the handoff also stores the normalized one-based signed-int64 selected_idx dataset and HEFFSO requires it to match the selected-orbital map in the shared HDF5 input. When it is 0, that dataset must be absent. The handoff filename is <prefix>heffso.h5.

HEFFSO Outputs#

For the same prefix, HEFFSO writes:

data/Ce_sovec
reports/heffso/Ce_heffso_occupancy_analysis.log
reports/heffso/Ce_heffso_configuration_analysis.log
data/Ce_heffso_properties.h5  # written by default; disable with properties: false

HEFFSO also uses anonymous compiler-managed unformatted sequential and stream scratch units internally. They have no stable filenames and are not durable outputs or workflow cleanup targets.

Workflow completion requires a nonempty Ce_sovec, fin heffso near the end of logs/heffso.log, both prefix-qualified analysis logs, and a complete ordered bounded primary report. The state table must have contiguous IDs and internally consistent Hartree, eV, and wavenumber columns. The occupancy log must contain either every state in every displayed horizontal block or the explicit no-varying-orbitals status. The configuration log must contain coefficient-consistent rows and a parsed summary for every state. A zero process exit without those durable markers is treated as failure. The workflow requires exactly the configured nvectw states across all three text artifacts; a HEFFSO run that emits fewer states is rejected rather than accepted as an automatic reduction. With the default mppt.heffso.properties: true, completion also requires a valid mppt_heffso_properties_v4 file with nvectw states and complete /solver, /determinant_identity, and /magnetic groups. Text solver diagnostics, energies, oscillator strengths, and angular values are cross-checked against the HDF5 values; line strengths are independently recomputed from the HDF5 dipole matrices. Every enabled HEFFSO stage fingerprint includes solver-relevant inherited environment variables. Properties runs also include intdip, intang, and their conventions. The separate output fingerprint covers the primary log, both analysis logs, eigenvectors, and the optional properties artifact. Disabled, rejected, failed, and rerun paths remove stale prefix-qualified outputs while retaining the current captured failure log and protecting the shared input HDF5 file.

The primary console log is a human-readable report whose lines are limited to 120 characters. With properties enabled it contains only these ordered sections:

  • SOLVER DIAGNOSTICS, with fixed-size PRIMME convergence, orthogonality, counter, and timing summaries;

  • SPIN-ORBIT STATES, with state, absolute Eh, dE / eV, dE / cm-1, S^2, J^2, and oscillator strength when properties are enabled;

  • ANGULAR PROPERTIES, with L2, S2, J2, Jz, and effective L, S, and J for every state;

  • MAGNETIC PROPERTIES, with time-reversal diagnostics, applicable principal g, and up to twenty doublets and twenty response rows;

  • PROPERTIES VALIDATION, with matrix residuals and their tolerances;

  • PROPERTIES SUMMARY.

With properties disabled, the primary report contains SOLVER DIAGNOSTICS and the four-column SPIN-ORBIT STATES section. Ce_heffso_occupancy_analysis.log contains one ACTIVE-ORBITAL OCCUPATIONS section, and Ce_heffso_configuration_analysis.log contains one DOMINANT CONFIGURATION WEIGHTS section. The latter prints every |c|^2 above the configured percentage and always prints at least the configured top-N coefficients. Full property matrices and the redundant complete E1 transition table are not printed in text: relative energies and oscillator strengths already appear in the primary state table, while complete line strengths remain in HDF5/Caspy. The report defines oscillator strength as the dimensionless electric-dipole strength from state 1. S^2 and J^2 use two digits after the decimal point. Oscillator strengths and magnetic residuals/response use scientific notation. Other energies, angular values, residuals, tolerances, occupations, coefficients, weights, and HEFFSO-owned solver diagnostics use fixed decimal notation. Angular values are derived from the stored HEFFSO-state matrices; they are not term-symbol or multiplet certification. Hermiticity, J = L + S, and the oscillator-strength formula are strict checks. A commutator residual above tolerance is reported as OPEN, because a finite retained state span need not close the angular-momentum algebra.

The v4 HDF5 artifact stores one-based state IDs, absolute energies, and split-complex Cartesian matrices. For n = state_count, required datasets are:

Dataset

Shape

Meaning

state_id

(n,)

contiguous IDs 1..n

state_energy_hartree

(n,)

absolute electronic energies in Hartree

oscillator_strength

(n,)

dimensionless oscillator strength from state 1

line_strength

(n,)

`sum_c

state_l2, state_s2, state_j2

(n,)

Cartesian retained-state matrix norms

state_jz

(n,)

real diagonal of the stored J_z matrix

state_l, state_s, state_j

(n,)

nonnegative q solving q(q+1)=q2

hermiticity_residual

(4,)

normalized residuals in l,s,j,dipole order

commutator_residual

(3,)

normalized residuals in l,s,j order

l_matrix_real, l_matrix_imag

(3,n,n)

orbital-angular-momentum matrices

s_matrix_real, s_matrix_imag

(3,n,n)

spin-angular-momentum matrices

j_matrix_real, j_matrix_imag

(3,n,n)

total-angular-momentum matrices, J = L + S

dipole_matrix_real, dipole_matrix_imag

(3,n,n)

bare length-gauge dipole matrices

The required root attributes identify schema version 4, one-based indexing, state count, absolute Hartree energy semantics, vacuum energy, x,y,z component order, (component,bra_state,ket_state) matrix axes, HEFFSO eigenstate basis, V_dagger_Q_V transform, dipole operator r, three-component dipole_origin_bohr, oscillator-strength and line-strength definitions and units, angular-value definitions, residual orders, scalar j_consistency_residual and oscillator_strength_formula_residual, and final write_complete=1.

The required /solver group has schema mppt_heffso_solver_diagnostics_v1. It stores PRIMME status, dimensions, counters, tolerances, convergence limit, bounded orthogonality metrics and timings; root_residual_norm_hartree has shape (n,). The required /determinant_identity group has schema mppt_heffso_determinant_identity_v1; its one-based IDs and signed-int64 alpha and beta bit matrices identify every final eigenvector row. The matrices have shape (ndet,nword) in HDF5 and cover only the smallest spatial-orbital window that differs from the closed-shell vacuum. An all-vacuum catalog uses shape (ndet,0). A signed-int64 little-endian FNV-1a hash binds all determinant metadata and content. Group completion markers precede the root completion marker.

Native magnetic properties#

The /magnetic group stores the zero-field model, doublet classification and requested field/thermal response. Magnetic properties use the magnetic-moment operator at zeroth order in the MPPT perturbation, projected into retained states. See the YAML input controls to request these outputs, and Magnetic Properties for formulas, units, applicability and approximation limits.

The required /magnetic group uses mppt_heffso_magnetic_v1, version 1, and a final write_complete=1. Its status is complete or explicitly disabled. Disabled groups contain no numerical model. Complete groups contain:

Group / datasets

h5py shapes

Meaning

model/h0_real, h0_imag

(n,n)

Relative zero-field Hamiltonian H(0), hartree

model/moment_real, moment_imag

(3,n,n)

Physical moment, μB/center

model/zeeman_real, zeeman_imag

(3,n,n)

Linear field derivatives, hartree/tesla

time_reversal/matrix_real, matrix_imag

(n,n)

U in the antiunitary operator U K

time_reversal/state_leakage

(n,)

Fraction outside retained states

doublets/state_status, state_ids

(n,), (d,2)

Applicability codes and one-based eligible pairs

doublets/principal_g, g_metric, principal_axes

(d,3), (d,3,3), (d,3,3)

Ascending g and column axes in input xyz

doublets/pair_splitting_hartree, isolation_gap_hartree, gap_known

(d,)

Original splitting, external separation and known-gap flag

response/fields_tesla, temperatures_kelvin

(f,3), (t,)

Explicit request grids

response/field_energy_hartree

(f,n)

Relative finite-field levels

response/magnetization_mu_B

(f,t,3)

Thermal physical moment, μB/center

response/susceptibility_mu_B_per_tesla

(f,t,3,3)

Optional differential dM/dB at fixed T

response/susceptibility_principal, susceptibility_axes

(f,t,3), (f,t,3,3)

Optional ascending χB eigenvalues and column axes

response/field_hamiltonian_real, field_hamiltonian_imag

(f,n,n)

Optional H(B) snapshots

Here n is the retained state count, d the eligible pair count, f the field count and t the temperature count. The zero-field Hamiltonian H(0) retains the original gaps relative to the lowest zero-field state; energy_reference_hartree stores the absolute reference. No pair splitting is reset to zero.

Model attributes record constants, units, Cartesian/matrix order and the approximation identifier bare_catalog_projection. This existing HDF5 value denotes the zeroth-order magnetic-moment operator in the MPPT perturbation, projected through the determinant catalog into retained SOC states. model/origin_bohr records the angular-momentum origin. Time-reversal attributes record missing determinant partners and square, energy and moment residuals. The response group also has its own completion marker and request switches.

An eligible pair spanning the entire model has gap_known=1 and a zero isolation_gap_hartree sentinel. Principal axes within repeated principal values are nonunique.

Magnetic state status#

doublets/state_status has one code for every retained state. The other doublet arrays contain eligible pairs only, using one-based state IDs.

Code

Meaning

0

Eligible isolated Kramers pair

1

Even-electron sector

2

Energy manifold is not a doublet

3

Pair is open under time reversal

4

Failed time-reversal square or odd-moment check

5

Unknown upper isolation gap at the retained-spectrum boundary

6

Insufficient separation from another manifold

7

Nonzero scalar moment trace

The g applicability rules define the residual-aware grouping and gap thresholds. A nonzero status does not by itself suppress field levels or thermal response.

Reading magnetic arrays#

Current readers require properties-v4. Regenerate older artifacts to use the magnetic contract. Caspy exposes result.magnetic_properties (or None when disabled); its hamiltonian(field_tesla) reconstructs H(B). Native thermal arrays are exposed as magnetization_mu_b and susceptibility_mu_b_per_tesla. Both consumers reject missing required model metadata, inconsistent physical units, malformed grids and incomplete magnetic groups.

Plot the stored native response with Caspy:

from caspy import read_heffso_properties
from caspy.heffso_magnetic_plot import write_magnetic_plot

result = read_heffso_properties("data/Ce_heffso_properties.h5")
if result.magnetic_properties is not None:
    write_magnetic_plot(result.magnetic_properties, "Ce-magnetic-properties-v1.png")

The overview shows eligible principal g, requested field levels, moment magnitude and principal susceptibility. It uses native stored values; fields are indexed because an arbitrary xyz list need not define a scalar sweep.

After completing the MPPT installation, activate mppt and run the following command from the repository root. It installs the optional Caspy helper as a regular, non-editable package. Managed HEFFSO reports reject editable or source-shadowed Caspy installations.

python -m pip install --no-cache-dir ./caspy

Read the typed contract without keeping the HDF5 file open:

from caspy import read_heffso_properties

result = read_heffso_properties("data/Ce_heffso_properties.h5")
print(result.state_energy_hartree)
print(result.oscillator_strength)
print(result.line_strength)
print(result.state_j)
print(result.commutator_residual)
print(result.solver.root_residual_norm_hartree)
print(result.determinant_identity.content_hash_fnv1a64)
print(result.l_matrix.shape)
print(result.dipole_matrix[:, 0, 1])

Caspy HEFFSO Report Bundle#

For magnetic analysis, use:

caspy-heffso-report --run-dir runs/ce --prefix Ce --magnetic

This reads data/Ce_heffso_properties.h5 and writes Ce_levels.csv, Ce_doublets.csv, Ce_field_levels.csv, Ce_magnetic_response.csv and Ce_magnetic.png under reports/heffso/. The tables retain all native levels, eligible principal g values and axes, field vectors, temperatures, moments and full susceptibility tensors. Susceptibility columns appear only when requested in the calculation. --properties-hdf5 selects another source and --output-dir selects another report directory. Magnetic analysis needs only the properties HDF5; the default spectroscopy report below uses the full run.

For installation, commands, energy diagrams and plot examples, start with Caspy: Tables And Plots. Its interaction interface is WIP and will change. The details below describe the current report artifact contract.

The supported exporter validates the shared HDF5, DIAGPT handoff, primary HEFFSO log, occupancy log, configuration log, and properties HDF5 before it writes any report output:

caspy-heffso-report \
  --run-dir runs/pr3-state-properties \
  --prefix Pr \
  --shared-hdf5 data/calculation.h5 \
  --top 20 \
  --spectrum-profile gaussian \
  --spectrum-fwhm-cm-1 100

For a managed run, Caspy reads the artifact map and shared-HDF5 location from run.json. Without a manifest it uses the layout above and data/pyscf_dump.h5. Reports default to reports/heffso/ below --run-dir; use --output-dir to place the bundle elsewhere. The --shared-hdf5, --handoff-hdf5, --primary-log, --occupancy-log, --configuration-log, and --properties-hdf5 overrides support unmanaged layouts; relative override paths are resolved below the run directory.

pyscf2mppt run ... --heffso-report performs the same validation and rendering before it can write terminal complete. Its schema-v2 run.json records the installed Caspy/report-interpreter identity and exact size, SHA-256, role, stage, and schema for all eight outputs. pyscf2mppt archive verifies those bytes without rendering again.

The fixed output set under reports/heffso/ is:

Pr_state_properties.csv
Pr_orbital_character.csv
Pr_dominant_configurations.csv
Pr_properties_summary.md
Pr_line_strength_stick_spectrum.png
Pr_line_strength_broadened_spectrum.png
Pr_oscillator_strength_stick_spectrum.png
Pr_oscillator_strength_broadened_spectrum.png

The state table contains all scalar state properties. The orbital table keeps every raw AO-subspace projector weight and adds an explicit assigned, mixed, or unassigned display policy. Assignment defaults to a dominant weight of at least 0.10 and a dominant-minus-runner-up margin of at least 0.05; change these with --label-min-weight and --label-min-margin. The dominant- configuration table joins the split coefficient log to exact alpha and beta occupations reconstructed from final determinant identity.

The four PNGs show separate state-1 E1 line-strength and oscillator-strength diagnostics on a wavenumber grid. The two stick plots are unbroadened. The two broadened plots use Gaussian or Lorentzian profiles normalized to unit area on the finite returned grid, so each curve preserves its corresponding integrated transition strength. A 4096-point base grid is augmented around every transition so narrow lines remain resolved across a wide energy range. Select the shared phenomenological profile with --spectrum-profile and its full width at half maximum in cm^-1 with --spectrum-fwhm-cm-1; command-line values replace the Gaussian and 100 cm^-1 fallbacks. These are theoretical state-1 diagnostics, not experimental absorption spectra. Temperature-dependent populations, concentration, physical linewidths, and instrument response are not inferred. --top limits only the Markdown table, not any spectrum.

Caspy independently recomputes both the final determinant hash and the source handoff determinant hash. It also cross-checks state and orbital counts, selected-orbital maps, closed-shell vacuum size, primary-log energies, and configuration IDs. Validation failure returns status 2 from the command and does not create the output directory. The full transition and angular matrices remain in HDF5; Markdown bounds only the strongest-transition table, while all four spectra include every positive-energy state-1 transition. No report output assigns term symbols or certifies complete multiplets.

The same operation is available as a Python API:

from caspy import heffso_report

outputs = heffso_report.generate_heffso_report(
    run_dir="runs/pr3-state-properties",
    prefix="Pr",
    top=20,
    spectrum_profile="gaussian",
    spectrum_fwhm_cm_1=100.0,
)
print(outputs.summary_markdown)

For energy diagrams that also need orbital occupations, pass the split analysis file explicitly:

analyze_mppt logs/heffso.log \
  --occupancy-log reports/heffso/Ce_heffso_occupancy_analysis.log