EOS batch specification

An EOS specification is a strict, hand-written text file that describes an ordered BatchPlan. It is separate from the experimental data file: the data file contains measured values, units, and experimental provenance, while the specification contains analysis choices.

The file extension has no meaning. analysis.spec, analysis.txt, analysis.dat, and a file without a suffix are treated identically. Quantas recognizes the format from the required first non-empty line:

# QUANTAS EOS SPEC 1

Version 1 is deliberately small and strict. Unknown sections, unknown keys, duplicate sections, duplicate keys, invalid values, incompatible solver options, unavailable targets, and invalid model parameters are errors. No scientific option is ignored silently.

Running a specification

Pass the data file as the positional argument and the independent specification with --spec:

quantas eos run PV_topaz.dat --spec topaz.spec

The specification becomes the authority for scientific settings. Therefore it cannot be mixed with scientific command-line options such as --domain, --fit, --solver, --pv-eos, --fix, or input-unit overrides. Operational and presentation options remain available:

quantas eos run PV_topaz.dat --spec topaz.spec \
   --output topaz.hdf5 --report topaz.log --quiet

--verbosity extended, --show-uncertainties, and --max-data-rows may increase or override presentation detail without changing the scientific plan.

Generating the commented template

Create the complete version-1 template with:

quantas eos spec-template

The default destination is eos.spec. A path with any suffix, or no suffix, may be supplied as the optional positional argument:

quantas eos spec-template topaz-analysis.txt

The command never overwrites an existing file silently. Use --force only when replacement is intentional:

quantas eos spec-template topaz-analysis.txt --force

A synchronized copy is also available as eos.spec.

The generated file is deliberately verbose and self-documenting. It contains:

  • the mandatory signature and syntax rules;

  • every recognized section and ordinary key;

  • pressure, length, and temperature unit overrides;

  • all common solver and covariance controls;

  • P–V, V–T, and P–V–T model lists;

  • fixed, initial, and bounded parameter examples;

  • acceptance and replacement semantics;

  • short and extended presentation settings;

  • commented examples for homogeneous, heterogeneous, thermal, and coupled jobs.

Only one minimal P–V volume job is active. All larger examples are commented, so the template is a valid specification immediately after generation and can be checked safely with --dry-run. The distributed copy under examples/eos/eos.spec is generated from the same public template function used by the command.

Dry-run validation

Use --dry-run before a real batch:

quantas eos run PV_topaz.dat --spec topaz.spec --dry-run

A dry run:

  1. validates the signature and complete syntax;

  2. reads and normalizes the data using [input] declarations;

  3. resolves general and domain-specific defaults;

  4. expands targets = all against the quantities actually present;

  5. constructs typed EOS models, constraints, and solver options;

  6. validates every request against the selected data and uncertainties;

  7. prints the resolved plan and normalized requests;

  8. performs no fit and creates no HDF5 archive.

A plain-text report may still be requested during a dry run. This is useful for recording the exact resolved plan before launching a calculation.

Syntax rules

The syntax is INI-like, but it is parsed by Quantas rather than by a generic INI configuration service.

  • The first non-empty line must be exactly # QUANTAS EOS SPEC 1.

  • Section names use square brackets.

  • Entries use key = value.

  • Blank lines are ignored.

  • A line whose first non-whitespace character is # is a comment.

  • Section and ordinary-key names are case-insensitive.

  • Job names are retained as stable identifiers after normalization.

  • Parameter names follow the public EOS fitting contracts.

  • Duplicate keys and duplicate sections are errors.

  • Inline comments are not supported in version 1; place comments on their own lines.

Minimal example

A BM2 volume fit using effective variance requires only:

# QUANTAS EOS SPEC 1

[defaults]
solver = effective-variance

[job volume]
domain = pv
targets = volume
model = BM2

Unspecified values use documented Quantas defaults. The default solver is OLS, the default P–V model is BM3, the default V–T model is berman:quadratic, and the default P–V–T coupling is linear.

Sections

[metadata]

This optional section contains free-form textual provenance. Values are stored in the resolved batch manifest and native HDF5 archive.

[metadata]
title = Topaz pressure-volume analysis
description = Independent volume and axial fits
author = Research group name

Metadata does not modify the numerical calculation.

[input]

This optional section overrides input units before the data file is normalized. Recognized keys are:

pressure_unit

Pressure unit accepted by the Quantas unit converter. The normalized unit is GPa.

length_unit

Cell-length unit. The corresponding cubic unit is applied to absolute volumes. The normalized units are Angstrom and Angstrom cubed.

temperature_unit

K, C, or F. Temperatures and their uncertainties are normalized consistently to kelvin.

[input]
pressure_unit = kbar
length_unit = bohr
temperature_unit = C

The original values and original unit labels remain in the HDF5 input record. Relative V/V0 and L/L0 quantities remain dimensionless.

[batch]

The batch section currently accepts one key:

failure_policy

stop or continue. A failed numerical attempt is persisted before the policy is applied.

[batch]
failure_policy = continue

[defaults]

General defaults apply to every job unless a domain-specific default or job entry overrides the same key.

Common keys are:

General fit keys

Key

Meaning

solver

ols, wls, effective-variance, or odr.

covariance_scaling

absolute, reduced-chi-square, or inflate-only.

max_iterations

Positive solver iteration or evaluation limit.

ftol, xtol, gtol

Positive convergence tolerances where supported.

inner_max_iterations

Inner WLS evaluation limit for effective variance only.

odr_difference

central or forward for ODR only.

odr_ndigit

Positive number of reliable model digits for ODR only.

accept

yes or no; successful jobs are accepted by default.

replace_accepted

yes or no; replacement is never implicit.

selection_base

default respects input USE/* exclusions; all starts from every row.

groups or include_groups

Comma-separated positive group identifiers, or all for groups.

exclude_groups

Comma-separated positive group identifiers removed from the selection.

include_rows

Comma-separated one-based data-row identifiers retained after the base/group selection.

exclude_rows

Comma-separated one-based data-row identifiers removed last.

Example:

[defaults]
solver = effective-variance
covariance_scaling = inflate-only
max_iterations = 200
accept = yes
replace_accepted = no

[defaults.pv], [defaults.vt], and [defaults.pvt]

Domain defaults are applied after [defaults] and before the individual job. They may contain the common fit keys and parameter declarations.

P–V uses model:

[defaults.pv]
model = BM3
fix.KP = 4.0

V–T uses model:

[defaults.vt]
model = berman:quadratic

P–V–T uses an explicit composition:

[defaults.pvt]
pv_model = BM3
vt_model = berman:quadratic
coupling = linear

For coupling = thermal-pressure, vt_model must be omitted because the coupling supplies its own thermal-pressure formulation.

The subordinate thermal_pressure_model key selects holland-powell-einstein (the default), mgd, or mgd:q-compromise. mgd is the full model and exposes refinable theta_d0, gamma0, and q. mgd:q-compromise is the distinct EosFit-style compromise approximation: it omits q rather than assigning a hidden numerical value, and therefore should be selected explicitly when reproducing a q-compromise reference fit. A cell-volume MGD fit requires either atoms_per_cell or the pair formula and formula_units_per_cell.

[job naf-mgd]
domain = pvt
targets = volume
pv_model = BM4
coupling = thermal-pressure
thermal_pressure_model = mgd
volume_basis = cell
formula = NaF
formula_units_per_cell = 4
solver = effective-variance
fix.temperature_ref = 295
initial.theta_d0 = 459
bound.theta_d0 = 1 : 5000
initial.gamma0 = 1.5
bound.gamma0 = 0.01 : 10
initial.q = 1.0
bound.q = -10 : 10

This fit uses only pressure, volume, and temperature observations. Adiabatic bulk-modulus data and multi-observable objectives are outside the current MGD workflow.

Data selection and groups

Selection settings are valid in [defaults], domain defaults, and individual jobs. Resolution is deterministic:

  1. start from selection_base = default (the input USE and * mask) or selection_base = all;

  2. retain groups/include_groups when declared;

  3. remove exclude_groups;

  4. retain include_rows when declared;

  5. remove exclude_rows.

Rows are numbered from one in data-table order. groups and include_groups are aliases and cannot both appear in the same resolved job. Unknown groups, out-of-range rows, and an empty final selection are errors.

[job campaign-2]
domain = pv
targets = volume
model = BM3
groups = 2
exclude_rows = 17

By default, an input point marked USE=0 or with a trailing * cannot be re-enabled by a group selection because the base is default. Use selection_base = all explicitly when a job must reconsider every archived observation:

[job sensitivity-check]
domain = pv
targets = volume
model = BM3
selection_base = all
include_groups = 1, 2
exclude_rows = 4, 19
accept = no

The resolved boolean mask, selection counts, and per-group counts are stored in the request and HDF5 fit record. No data row is removed from the input dataset.

[presentation]

Presentation settings do not change fitted values or HDF5 scientific content. Detailed solver tracing is intentionally not a persistent specification setting: request it operationally with quantas eos run ... --verbosity debug so the same scientific specification can be used for normal and diagnostic executions.

detail

short or extended.

show_uncertainties

yes or no.

max_data_rows

A positive integer, all, or none. This limits display only.

[presentation]
detail = extended
show_uncertainties = yes
max_data_rows = 30

[job NAME]

Every specification must contain at least one named job section. Jobs are executed in file order. domain and targets are mandatory.

[job volume]
domain = pv
targets = volume
model = BM2

A job section may override inherited model, solver, constraint, acceptance, and presentation-independent numerical settings. note is persisted with the fit record.

When one section selects several targets, Quantas expands it into one job per target while retaining a stable identifier:

[job axes]
domain = pv
targets = a, b, c
model = PT3
solver = ols

The resolved identifiers are axes-a, axes-b, and axes-c.

Default precedence

For each job, settings are applied in the following order:

  1. internal Quantas defaults;

  2. [defaults];

  3. the matching [defaults.pv], [defaults.vt], or [defaults.pvt];

  4. [job NAME].

A later value replaces an earlier value with the same key. Version 1 has no inheritance between job sections and no conditional logic.

Targets

Recognized targets are volume, a, b, and c. Separate targets with commas:

targets = volume, a, b

targets = all expands to every supported quantity present in the data file. It cannot be mixed with explicit targets. P–V–T currently supports only targets = volume.

P–V models

Compact tags are recommended:

M

Murnaghan.

BM2, BM3, BM4

Birch–Murnaghan.

PT2, PT3, PT4 or NS2, NS3, NS4

Natural strain/Poirier–Tarantola.

V2, V3

Vinet.

T2, T3, T4

Tait.

The documented full family names and their normalized aliases are also valid. The compact tags above are preferred because they make the selected order immediately visible in a batch plan.

[job volume]
domain = pv
targets = volume
model = birch-murnaghan3

V–T models

Supported tags are:

  • berman:linear and berman:quadratic;

  • fei:linear and fei:inverse-square;

  • mhp:simplified and mhp:general;

  • salje;

  • khp.

[job thermal-volume]
domain = vt
targets = volume
model = berman:quadratic
solver = wls

P–V–T models

A P–V–T job declares each component explicitly:

[job pvt-volume]
domain = pvt
targets = volume
pv_model = BM3
vt_model = berman:quadratic
coupling = anderson-gruneisen
solver = effective-variance

Available couplings are linear, anderson-gruneisen, and thermal-pressure.

Parameter constraints

Constraint keys use the same names as the public fitting functions.

fix.NAME

Hold a parameter at the supplied finite value.

initial.NAME

Override the initial value of a free parameter.

bound.NAME

Set LOW : HIGH bounds for a free parameter. none denotes an open side. A bound declaration requires a matching initial.NAME.

initial.K0 = 160.0
bound.K0 = 1.0 : 500.0
fix.KP = 4.0

A fixed parameter cannot also declare an initial value or bounds. Parameters must exist in the selected model and target. Parameters implied by an EOS order cannot be made free or fixed; the dry run detects this when the complete parameter map is prepared.

For volumetric P–V fits, common names are K0, KP, KPP, and V0. For axial P–V fits, use M0, MP, MPP, and L0. For V–T fits, the reference quantity is always V0 for volume and L0 for a cell axis. Other thermal and P–V–T names follow the API, such as temperature_ref, alpha0, theta_e, dK0_dT, and delta. The historical X0 and generic value_ref names are rejected so that specification files have one stable public nomenclature.

Solver-specific validation

Method-specific keys are accepted only by the corresponding solver. For example, this is invalid:

solver = ols
odr_ndigit = 12

Likewise, WLS requires positive dependent-variable uncertainties, effective variance requires at least one usable uncertainty component, and ODR requires positive uncertainties for every fitted coordinate. These requirements are checked by --dry-run without invoking the ODR backend.

Acceptance and replacement

A successful job is accepted by default. Set accept = no to persist the attempt without making it the current result.

Two jobs may target the same scientific slot, but replacement must be explicit:

[job volume-bm2]
domain = pv
targets = volume
model = BM2
accept = yes

[job volume-bm3]
domain = pv
targets = volume
model = BM3
accept = yes
replace_accepted = yes

Both immutable records remain in the archive; the BM3 record becomes the current accepted result.

Complete example

# QUANTAS EOS SPEC 1

[metadata]
title = Topaz EOS analysis
description = Volume and axial fits with independent models

[input]
pressure_unit = GPa
length_unit = angstrom
temperature_unit = K

[batch]
failure_policy = continue

[defaults]
solver = effective-variance
covariance_scaling = inflate-only
max_iterations = 200
accept = yes
replace_accepted = no

[defaults.pv]
model = BM3

[presentation]
detail = extended
show_uncertainties = yes
max_data_rows = 30

[job volume]
domain = pv
targets = volume
model = BM2

[job axis-a]
domain = pv
targets = a
model = PT3
solver = odr
odr_difference = central
odr_ndigit = 12
initial.M0 = 450.0
initial.MP = 10.0
bound.M0 = 1.0 : 2000.0
bound.MP = 0.0 : 30.0

[job axes-bc]
domain = pv
targets = b, c
model = BM3
solver = ols

Error diagnostics

Diagnostics identify the source path, source line, and section whenever that information is available. Examples include:

  • unknown section [solver];

  • unknown key 'solvert';

  • unknown solver 'odl';

  • odr_ndigit is valid only for solver = odr;

  • parameter 'banana' is not available for pv/volume;

  • dataset does not contain target(s): c;

  • thermal-pressure coupling defines its own thermal model; remove vt_model.

Version 1 intentionally reports unknown names directly. Automatic did-you-mean suggestions are not part of the initial parser.

Python API

Parsing and dataset-dependent resolution are separate:

from quantas.api import eos

document = eos.read_spec("topaz.spec")
dataset = eos.read_input(
    "PV_topaz.dat",
    **document.input_options.as_dict(),
)
resolved = eos.resolve_spec(document, dataset)

plan = resolved.plan
report_options = resolved.report_options

The parser does not execute fits and does not depend on Click or Rich. The resolved plan is the same BatchPlan consumed by quantas.api.eos.run_batch().

Template generation API

The same commented template used by quantas eos spec-template can be written through quantas.api.eos.write_spec_template(). Template generation remains separate from parsing and resolution, so producing a starter file never executes or modifies a fitting plan.