kipe.options module
Options of the kipe study file.
A study file is a YAML file with one section per concern: output, forward_solver,
parameters, measurements, synthesis and estimation (StudyOptions).
Each command reads the sections it needs. Relative paths are relative to the working directory
kipe is run from.
The dataclasses of this module are the only definition of the study file: pydantic validates study files against them, unknown keys are an error, and the documentation’s study file reference is generated from them, with their attribute docstrings as the descriptions.
See examples/fitzhugh_nagumo/study.yaml for a complete study file.
- exception kipe.options.StudyFileError[source]
Bases:
ExceptionThe study file cannot be read, or is not a YAML mapping of sections.
- class kipe.options.OutputOptions(path: str, log_level: Literal['debug', 'info', 'warning', 'error'] = 'info')[source]
Bases:
objectWhere and how kipe writes its results.
- path: str
Directory for all results. Subcommands write into subdirectories.
- log_level: Literal['debug', 'info', 'warning', 'error'] = 'info'
Minimum level of the log messages kipe writes.
- class kipe.options.ForwardSolverOptions(factory: str, arguments: dict[str, ~typing.Any]=<factory>)[source]
Bases:
objectHow to construct the forward solver.
kipe imports
factoryand calls it withargumentsas keyword arguments. The factory can be a class or a function; it must return an object that conforms tokipe.forward_solver.ForwardSolver.- factory: str
Import path of the factory,
"module:name", e.g.,"kipe.examples.fitzhugh_nagumo:Solver".
- arguments: dict[str, Any]
Keyword arguments passed to the factory, as given (no path resolution).
- type kipe.options.Reparameterization = Literal['log', 'multiplicative', 'additive']
- class kipe.options.ParameterPrior(initial: float | None = None, relative_stddev: float | None = None, stddev: float | None = None, reparameterization: Reparameterization | None = None)[source]
Bases:
objectInitial estimate of one estimated parameter and its uncertainty.
The two define the prior (Gaussian in the estimated parameter \(\theta\)) and the starting state of the filter: the standard deviation sets the initial size of the sigma-point stencil used for the derivative-free linearization, and the initial weight against the measurement noise.
logandmultiplicativetake arelative_stddev,additivean absolutestddev.- initial: float | None = None
Initial estimate (prior mean), as physical value. The solver’s nominal value if not given.
- relative_stddev: float | None = None
Standard deviation relative to
initial, e.g.,0.3for 30%. Forlogandmultiplicative.Converted to the standard deviation of \(\theta\), to first order around
initial: \(\sigma_\theta\) =relative_stddev/ ln 2 forlog, \(\sigma_\theta\) =relative_stddevformultiplicative. So both give the same prior as long asrelative_stddevis small. For large values they differ:logkeeps the parameter positive, at the price of an asymmetric distribution.kipe list-parametersshows the resulting 1σ range.
- stddev: float | None = None
Absolute standard deviation, in the parameter’s physical unit. For
additive.
- reparameterization: Reparameterization | None = None
Overrides the section’s
reparameterizationfor this parameter.
- class kipe.options.ParametersOptions(reparameterization: Reparameterization, select: dict[str, ParameterPrior])[source]
Bases:
objectSelection, initial estimate and reparameterization of the estimated parameters.
kipe list-parametersshows the names the forward solver accepts.- reparameterization: Reparameterization
How the estimated parameter \(\theta\) relates to the physical value \(\phi\), relative to the initial estimate \(\phi_0\). Default for all parameters in
select, each can override it.Available reparameterizations:
log: \(\phi = \phi_0 2^\theta\), starting at \(\theta = 0\), with arelative_stddev. Keeps \(\phi\) positive; the initial estimate must be positive.multiplicative: \(\phi = \phi_0 \theta\), starting at \(\theta = 1\), with arelative_stddev. The initial estimate must not be zero; \(\phi\) can change sign.additive: \(\phi = \phi_0 + \theta\), starting at \(\theta = 0\), with an absolutestddev. \(\theta\) is the deviation from the initial estimate, in the parameter’s physical unit. Accepts any initial estimate, including zero.
- select: dict[str, ParameterPrior]
parameter name -> initial estimate and uncertainty. All other parameters keep their nominal values.
- Type:
Estimated parameters
- class kipe.options.TimeRange(start: float, stop: float, step: float)[source]
Bases:
objectEquidistant times from
starttostop, both included.- start: float
First time.
- stop: float
Last time, included (up to round-off).
- step: float
Distance between successive times.
- class kipe.options.NumpyDataOptions(type: Literal['numpy'], path: str)[source]
Bases:
objectMeasurement data in a numpy
.npzfile.The file holds the arrays
times, shape(n,), andvalues, shape(n, m): m values at each of the n times.- type: Literal['numpy']
Data format.
- path: str
Path to the
.npzfile. With several noise realizations (synthesis.realizations), it contains the placeholder{realization}, e.g.,"data/r{realization}/u.npz"or"data/u_{realization:02d}.npz": each realization has its own file. In quotes, since YAML reads braces in{type: ..., path: ...}as a mapping.
- class kipe.options.ArraySamplingOptions(type: Literal['array'] = 'array')[source]
Bases:
objectSample all entries of the observed fields, concatenated in the order of
fields.- type: Literal['array'] = 'array'
Kind of spatial sampling.
- class kipe.options.DifferenceModelOptions(type: Literal['difference'] = 'difference')[source]
Bases:
objectMeasured data are the sampled fields; innovation = measured - predicted.
- type: Literal['difference'] = 'difference'
Kind of measurement model.
- class kipe.options.NoiseOptions(stddev: float, seed: int | None = None)[source]
Bases:
objectMeasurement noise: assumed by
estimation, added bysynthesis.synthesis.noisecan set another noise for synthesis to add, e.g., none.- stddev: float
Standard deviation of the noise, in the unit of the data.
- seed: int | None = None
Seed of the noise added by
synthesis(required there, unless it adds none, seesynthesis.noise). The noise of the k-th time of the measurement is drawn fromnumpy.random.default_rng([seed, k]), so it does not depend on the other times. Measurements must have different seeds.
- class kipe.options.MeshSamplingOptions(type: Literal['fenicsx.mesh'], mesh: str, mesh_name: str = 'mesh', element: Literal['P1', 'DG0'] = 'P1', projection: list[float] | Literal['surface_normal'] | None = None, padding: float = 0.0)[source]
Bases:
objectInterpolate the observed field onto a measurement mesh (FEniCSx backend).
The field must be a distributed field whose function space the forward solver provides (
kipe.fenicsx.forward_solver.SupportsFunctionSpaces). The measurement mesh need not match the solver’s mesh. The data are in the order of the mesh file: by vertex forP1, by cell forDG0, independent of the number of ranks; for a vector field without projection, the components of each vertex or cell one after another.- type: Literal['fenicsx.mesh']
Kind of spatial sampling.
- mesh: str
Path to the measurement mesh, an XDMF file.
- mesh_name: str = 'mesh'
meshas dolfinx writes it; meshio writesGrid.- Type:
Name of the mesh in the XDMF file (its grid)
- element: Literal['P1', 'DG0'] = 'P1'
vertex values (
P1) or cell values (DG0).- Type:
Finite element on the measurement mesh
- projection: list[float] | Literal['surface_normal'] | None = None
What is measured of a vector field; all components if not given. A direction, e.g.,
[0, 0, 1]for the z component (normalized by kipe), orsurface_normal: the component along the cell normal of a surface mesh (needselement: DG0, one normal per cell). The normal’s orientation follows the order of each cell’s vertices in the mesh file, asufl.CellNormal: the right-hand rule for triangles in 3D, the tangent rotated by +90° for lines in 2D; it is outward only if the mesh’s cells are oriented that way.
- padding: float = 0.0
Distance, in mesh units, by which a measurement point may lie outside the solver’s mesh, e.g., where a surface mesh cuts slightly across the solver’s boundary. Such a point takes the value of the field in the nearest cell, extrapolated; a point farther out is an error.
- class kipe.options.PointSamplingOptions(type: Literal['fenicsx.points'], points: list[list[float]])[source]
Bases:
objectEvaluate the observed field at given points (FEniCSx backend).
The field must be a distributed field whose function space the forward solver provides (
kipe.fenicsx.forward_solver.SupportsFunctionSpaces). The data are in the order ofpoints; for a vector field, the components of each point one after another.- type: Literal['fenicsx.points']
Kind of spatial sampling.
- points: list[list[float]]
Coordinates of the measurement points, one list per point, e.g.,
[[0.5, 0.5], [0.2, 0.8]]in 2D. Each point must lie in the solver’s mesh.
- type kipe.options.SpatialSamplingOptions = ArraySamplingOptions | MeshSamplingOptions | PointSamplingOptions
- class kipe.options.MeasurementOptions(fields: list[str], data: ~kipe.options.NumpyDataOptions, noise: ~kipe.options.NoiseOptions, times: list[float] | ~kipe.options.TimeRange | None = None, spatial_sampling: ~kipe.options.SpatialSamplingOptions = <factory>, model: ~kipe.options.DifferenceModelOptions = <factory>)[source]
Bases:
objectOne measurement: which fields it observes, its data, and how to compare them.
- fields: list[str]
State fields the measurement observes.
- data: NumpyDataOptions
read by
estimation, written bysynthesis.- Type:
Where the measured data are
- noise: NoiseOptions
Measurement noise.
- times: list[float] | TimeRange | None = None
a list or a range. Required by
synthesis(the times to generate); forestimationa selection from the times in the data, all if not given.- Type:
Measurement times
- spatial_sampling: SpatialSamplingOptions
How the observed fields are brought to the measurement locations; the kind is selected by
type,arrayby default.
- model: DifferenceModelOptions
How predicted data are computed from the sampled fields and compared with the data.
- class kipe.options.RunTruthOptions(type: Literal['run'] = 'run')[source]
Bases:
objectGenerate the data by running the forward solver with its nominal parameters.
- type: Literal['run'] = 'run'
Source of the true state.
- class kipe.options.CheckpointsTruthOptions(type: Literal['checkpoints'], path: str)[source]
Bases:
objectGenerate the data from the checkpoints of an earlier run of the forward solver.
The solver reads the true states at the measurement times from the checkpoints at
path; it needskipe.forward_solver.SupportsCheckpoints. The run may differ from the model of theforward_solversection (e.g., in its time step or parameters), as long as the solver can read its checkpoints into the model’s state.- type: Literal['checkpoints']
Source of the true state.
- path: str
Location of the checkpoints, as the solver understands it (e.g., the output directory of the run).
- type kipe.options.TruthOptions = RunTruthOptions | CheckpointsTruthOptions
- class kipe.options.SynthesisNoiseOptions(stddev: float)[source]
Bases:
objectNoise that synthesis adds to the data of a measurement.
- stddev: float
Standard deviation of the noise, in the unit of the data; 0 for noise-free data.
- class kipe.options.SynthesisOptions(truth: TruthOptions = <factory>, noise: dict[str, ~kipe.options.SynthesisNoiseOptions]=<factory>, realizations: int = 1)[source]
Bases:
objectGeneration of synthetic measurement data.
- truth: TruthOptions
a run of the forward solver, or its checkpoints.
- Type:
Source of the true state the data are generated from
- noise: dict[str, SynthesisNoiseOptions]
Noise synthesis adds to the data of the listed measurements (measurement name -> noise), instead of their
noise.stddev, which estimation assumes: for noise-free data (stddev: 0) or studies with misspecified noise. Measurements not listed get theirnoise.stddev.
- realizations: int = 1
Number of noise realizations, e.g., for the statistics of the estimates over the noise. Synthesis computes the true state once and writes the data of realizations \(r = 0, \dots, n - 1\), each to the
data.pathof the measurements with{realization}replaced by \(r\);kipe estimation --realization restimates from one of them. Realization 0 has the noise of a study without realizations.
- type kipe.options.SigmaPoints = Literal['simplex', 'canonical', 'unique']
- class kipe.options.EstimationOptions(sigma_points: SigmaPoints = 'simplex', iterations: int = 1)[source]
Bases:
objectParameter estimation with the reduced-order unscented Kalman filter (ROUKF).
- sigma_points: SigmaPoints = 'simplex'
Sigma-point stencil, the pattern along which the estimates are perturbed. Each sigma point costs one forward run per measurement time:
simplex: \(p + 1\) sigma points, the cheapest.canonical: \(2p\) sigma points, \(\pm\) along each parameter.unique: one sigma point at the estimate, no spread: no correction. A sanity check of the whole pipeline (with the true parameters, the innovations are pure noise).
- iterations: int = 1
Number of passes over the measurements. Each pass after the first starts from the previous estimate, with the initial uncertainty.
- class kipe.options.StudyOptions(output: OutputOptions, forward_solver: ForwardSolverOptions, parameters: ParametersOptions | None = None, measurements: dict[str, ~kipe.options.MeasurementOptions] | None=None, synthesis: SynthesisOptions = <factory>, estimation: EstimationOptions = <factory>)[source]
Bases:
objectAll sections of a study file.
- output: OutputOptions
Output location and logging.
- forward_solver: ForwardSolverOptions
Construction of the forward solver.
- parameters: ParametersOptions | None = None
Estimated parameters.
- measurements: dict[str, MeasurementOptions] | None = None
name -> measurement. The names appear in logs, output and errors.
- Type:
Measurements
- synthesis: SynthesisOptions
Generation of synthetic measurement data.
- estimation: EstimationOptions
Parameter estimation.
- kipe.options.data_path(measurement: MeasurementOptions, realization: int = 0) str[source]
Return the path to a measurement’s data of one noise realization.
- Parameters:
measurement – the measurement options
realization – number of the noise realization
- Returns:
data.path, with{realization}replaced
- kipe.options.estimation_directory(study: StudyOptions, realization: int = 0) Path[source]
Return the output directory of an estimation.
- Parameters:
study – the study options
realization – number of the noise realization the estimation uses
- Returns:
<output.path>/estimation; with several realizations, its subdirectory of the realization, e.g.,r07, numbered with as many digits as the largest number- Raises:
StudyFileError – if the study has no such realization
- kipe.options.load_study(path: str | Path) StudyOptions[source]
Read and validate a study file.
- Parameters:
path – path to the YAML study file
- Returns:
validated study options
- Raises:
StudyFileError – if the file cannot be read, is not valid YAML or is not a mapping
pydantic.ValidationError – if the options are invalid
- kipe.options.study_schema() dict[str, Any][source]
Return the JSON schema of the study file, e.g., for editors (
kipe schema).It is pydantic’s schema of
StudyOptions, in JSON Schema draft 2020-12, with the options’ docstrings as descriptions.- Returns:
the JSON schema, as a mapping that
json.dumps()writes
- kipe.options.dump_study(study: StudyOptions, path: str | Path) None[source]
Write study options as a study file, which
load_study()reads back.All options are written, defaults included,
nullfor those not set. Useful to generate study files from Python, e.g., for a sweep over noise seeds.- Parameters:
study – the study options
path – where to write the study file