Parameters#

Parameters of a scene run: declared once, read from TOML, checked, resolved with provenance.

Every quantity has ONE home:

[observation]    wavelength, diameter                       (the observation)
[grid]           size, pixel_scale | sampling, fov, resample (the simulated image)
[star]           distance, radius, temperature | flux_jy     (the star / system)
[[source]]       kind + that module's own parameters only (input_* keys describe its file)
[[coronagraph]]  type + the optics' parameters
[method] [compute] [checks] [run] [display]

Modules declare the shared quantities they need (requires) and those they can supply (provides, e.g. a FITS header’s pixel scale); a shared key inside a [[source]] table is refused with a pointer to its home. Values are resolved user > provided > default, every disagreement is checked against a per-quantity rule (error / warning / resample), and the origin of each value is kept for the printed table and the params_used.toml file.

The steps:

load(path)        reads the file and its `include = [...]` files (_read_toml), then from_data()
from_data(data)   checks the layout ([[source]] / [[coronagraph]] lists, known sections), builds a
                  Component per [[source]] table, then make()
make(...)         checks the core sections and the coronagraphs, names the components, and returns
                  a Params after Params.check() (what is missing / unused)
Params.resolve()  the final shared values (user > provided by the sources > default), with the
                  conflict rules; Params.table() / used_toml() show them with their origins

Every function collects all the problems it finds and raises one ParamError listing them, one per line.

Everything users read is generated from these declarations by toycoronagraph.params_docs (example files, the JSON schema, the reference tables, describe, migrate). The old layout ([target], [telescope], a single [coronagraph]) is read and mapped to the new one (legacy_to_new).

class toycoronagraph.params.Param(name, default=None, unit=None, doc='', type='float', choices=(), min=None, max=None, exclusive_min=False, auto=False, auto_word=None, lambda_d=False, advanced=False, example=None, help='')[source]#

Bases: object

The declaration of one parameter: how it is checked (convert()) and documented (params_docs).

Variables:
  • name (str) – key in the TOML file.

  • default (object) – value when not set; None = no default (required when it is needed).

  • unit (str) – canonical unit (astropy syntax), or None; numbers are in this unit, strings with a unit (“3.22 pc”) are converted to it.

  • doc (str) – short description (the comment in generated files).

  • type (str) – “float”, “int”, “bool”, “str”, “int_list”, “float_list”, “str_list” or “table” (ignored when choices are given).

  • choices (tuple) – allowed values, if limited (compared with their type: 1 is not true).

  • min,​max (float) – bounds of a number, or None; min is exclusive if exclusive_min.

  • exclusive_min (bool) – the value must be > min (else >= min).

  • auto (bool) – “auto” is also allowed.

  • auto_word (str) – another allowed word (e.g. “all”), or None.

  • lambda_d (bool) – “32 lambda/D” is also allowed (read as a LambdaD, converted to arcsec when the wavelength and diameter are known).

  • advanced (bool) – commented out in generated files (or left out unless full=True).

  • example (object) – value written in generated files when there is no default.

  • help (str) – longer description (editor hover, describe()).

describe_type()[source]#

The allowed values in words, as shown in error messages and the docs.

Returns:

e.g. ‘“auto” or number [m]’, ‘one of “separate”, “together”’, ‘number [arcsec] or “N lambda/D”’.

Return type:

str

class toycoronagraph.params.LambdaD(x=0, /)[source]#

Bases: float

A size given in lambda/D (resolved to arcsec when the wavelength and diameter are known).

toycoronagraph.params.register_coronagraph(type_name, doc, params)[source]#

Declare the parameters of a new coronagraph type (with its optics backend).

Parameters:
  • type_name (str) – the value of type in [[coronagraph]] tables.

  • doc (str) – one line describing it.

  • params (iterable of Param) – its own parameters (besides CORONAGRAPH_COMMON’s type and name).

toycoronagraph.params.coronagraph_problems(ctype, values, refused=())[source]#

The checks of a coronagraph table that involve several keys (each value is checked on its own by convert()).

Parameters:
  • ctype (str) – the coronagraph type.

  • values (dict) – the checked values set in the table; unset keys are absent (their defaults are valid).

  • refused (iterable of str) – keys set in the table but refused by their own check (so absent from values, where they would read as their defaults): the checks involving them are left out.

Returns:

the problems, e.g. “charge = 3: a vortex charge must be even”; [] if none.

Return type:

list of str

toycoronagraph.params.convert(param, value, where)[source]#

Check one value against its declaration and return it in canonical form.

In order: “auto” (if allowed), the auto_word, the choices, then the type. A float (and each item of a float_list) may be a number, “N lambda/D” (if lambda_d; returned as a LambdaD, which converts to itself) or a string with a unit (converted to param.unit with astropy; “Msun” / “Rsun” are accepted). Numbers are then checked against min / max.

Parameters:
  • param (Param) – the declaration.

  • value (object) – the value as read from TOML (or given in Python).

  • where (str) – where it is set, starting the message (e.g. “[grid]”, “[[source]] #1 (wind)”).

Returns:

“auto”, the auto_word, the matching choice, a bool / str / dict, a list (float_list items as floats in param.unit), an int, a float in param.unit, or a LambdaD.

Return type:

object

Raises:

ValueError – ‘<where> <name> = <value>: <why> (expected <param.describe_type()>)’.

exception toycoronagraph.params.ParamError[source]#

Bases: ValueError

Problems in the parameters (all of them, one per line).

toycoronagraph.params.is_legacy(data)[source]#

Whether file content is in the old layout: [target], [telescope] or [resolved] (written back by old runs), or a single [coronagraph] table instead of a [[coronagraph]] list.

Parameters:

data (dict) – the parsed file.

Returns:

bool

class toycoronagraph.params.Component(source, name='auto', scale=1.0, enabled=True, method='auto')[source]#

Bases: object

One source module in a scene, and how it is used.

Variables:
  • source (Source) – the module instance (toycoronagraph.sources), holding its own settings.

  • name (str) – name in outputs; “auto” = the kind, numbered from the second of a kind (set by make()).

  • scale (float) – factor multiplying its image.

  • enabled (bool) – False leaves it out of the run.

  • method (str) – “auto”, “circular” or “spatial” (override of [method] method for this component).

toycoronagraph.params.load(path)[source]#

Read and check a parameter file (an old-layout file is mapped to the new layout).

Parameters:

path (str) – the TOML file (its include = [...] files are read too).

Returns:

checked values with their origins; Params.resolve() then fills in what the sources provide.

Return type:

Params

Raises:

ParamError – every problem found, one per line.

toycoronagraph.params.from_data(data, path=None, origins=None)[source]#

Check parameters given as a dict in the file layout (see load()).

Parameters:
  • data (dict) – the file content: {section: {key: value}}, “source” / “coronagraph”: lists of tables. An old-layout dict (is_legacy) is mapped with legacy_to_new() first (and a note added).

  • path (str) – the file, for messages, origins and relative paths in the old layout; None = given in Python (relative paths in the old layout are then in the working directory).

  • origins (dict) – {(section, key): file path} from _read_toml(); None = all from path.

Returns:

see make().

Return type:

Params

Raises:

ParamError – every problem found, one per line (the layout and [[source]] tables first; then those of make()).

toycoronagraph.params.make(sections, components, coronagraphs=(), path=None, origins=None, notes=())[source]#

Checked parameters from core sections, Components and [[coronagraph]] tables (used by from_data() and by scenes built in Python).

Components named “auto” are named here (in place): the kind, then kind_2, kind_3, … by position among the components of the same kind. Without coronagraphs, one vortex of charge 2 is used.

Parameters:
  • sections (dict) – {section name: {key: value}} for the core SECTIONS.

  • components (list of Component) – the scene’s components.

  • coronagraphs (list of dict) – [[coronagraph]] tables, {key: value} with “type” (default “vortex”).

  • path (str) – the parameter file, or None (built in Python).

  • origins (dict) – {(section, key): file path} from _read_toml(), or None.

  • notes (iterable of str) – notes from reading (e.g. the old layout).

Returns:

after Params.check().

Return type:

Params

Raises:

ParamError – every problem found, one per line (also those of Params.check()).

class toycoronagraph.params.Params(path, sections, components, coronagraphs, origins, notes)[source]#

Bases: object

Checked parameters: get() / origin() / used_by(); check() for what is missing or unused; resolve() for the final shared values, with what the sources provide.

Keys of the core sections are written “section.name”, e.g. “star.distance”.

Variables:
  • path (str) – the parameter file, or None (built in Python).

  • sections (dict) – {section: {key: checked value}}: only what the user set.

  • components (list of Component) – all components (enabled() for those used).

  • coronagraphs (list of SimpleNamespace) – type, name, values (see _coronagraph()).

  • load_notes (list of str) – notes from reading and check().

  • notes (list of str) – load_notes + the messages of the last resolve().

  • provided (list of tuple) – (key, value, origin) supplied by the sources (Source.inspect()), set before resolve().

  • resolved (dict) – {key: (value, origin)}: the final shared values, after resolve().

Store checked parameters (use make() to build them).

Parameters:
  • path (str) – the parameter file, or None.

  • sections (dict) – {section: {key: checked value}}.

  • components (list of Component) – with their final names.

  • coronagraphs (list of SimpleNamespace) – see _coronagraph().

  • origins (dict) – {(section, key): file path}.

  • notes (iterable of str) – notes from reading.

user_set(key)[source]#

Whether the user set a core key (even to “auto”).

Parameters:

key (str) – “section.name”.

Returns:

bool

get(key)[source]#

The value of a core key: resolved, else the user’s, else the default.

Parameters:

key (str) – “section.name”.

Returns:

the value (None if no value and no default).

Return type:

object

origin(key)[source]#

Where the value of a core key comes from.

Parameters:

key (str) – “section.name”.

Returns:

the resolved origin (e.g. “header PIXSCALE of x.fits”), else “set in <file name>” (or “set in parameters” when built in Python), else “default”.

Return type:

str

enabled()[source]#

The components used.

Returns:

those with enabled = True.

Return type:

list of Component

families()[source]#

The unit family of each enabled component.

Returns:

{component name: “physical”, “relative” or None (decided by the input)}.

Return type:

dict

star_flux_needed()[source]#

Whether the star’s flux density is needed to put the components and the output in one unit: the components are in different families, or [display] unit asks for another family.

Returns:

bool

used_by(key)[source]#

Who uses a shared quantity.

Parameters:

key (str) – “section.name”.

Returns:

names of the enabled components requiring it, plus “the PSFs” (wavelength, diameter), “the image grid” (grid.*) or “unit conversion” (the star keys needed for its flux).

Return type:

list of str

check()[source]#

Check that everything a component needs is given; note the [star] keys nobody uses.

A required shared key is given if it has a value (user or default) or an enabled component provides it. When the star’s flux is needed, temperature or flux_jy must be set (with temperature, radius and distance are needed too). Notes are appended to load_notes; notes is reset to load_notes.

Raises:

ParamError – everything missing, one per line.

provide(key, value, origin)[source]#

A source supplies a shared quantity (e.g. a header’s pixel scale), used by resolve().

Parameters:
  • key (str) – “section.name”, e.g. “grid.pixel_scale”.

  • value (float or int) – in the key’s canonical unit.

  • origin (str) – where it comes from, e.g. “header PIXSCALE of x.fits”.

resolve()[source]#

The final shared values: the user’s, else what a source provides, else the default.

For [observation] and [star]: the user’s value (not “auto”), else the first provided, else the default (wavelength: 1e-6 m assumed, with a note); the grid: see _resolve_grid(). Every disagreement is checked: over-specified settings (grid, temperature + flux_jy) and the provided values against the resolved ones (CONFLICT_RULES). Sets resolved and notes (load_notes + the messages).

Returns:

the messages (notes and warnings).

Return type:

list of str

Raises:

ParamError – conflicts and missing grid settings, one per line ([checks] on_conflict = “warn” turns the CONFLICT_RULES errors into warnings).

table()[source]#

The provenance table of the resolved values (after resolve()).

Returns:

aligned columns “quantity, value, from, used by”, one line per resolved key.

Return type:

str

used_toml(coronagraphs=None, method=None)[source]#

The values used, as a TOML file to save with the results.

The shared sections hold the resolved values (with unit and origin as comments), the other sections what the user set, then every component (with all its settings) and every coronagraph (with all its parameters).

Parameters:
  • coronagraphs (list of SimpleNamespace) – the coronagraphs a run used (type, name, values), or None for the parameters’.

  • method (dict) – [method] settings a run used instead of the parameters’ ({key: value}), or None.

Returns:

the TOML text (ends with a newline).

Return type:

str

write_used(path)[source]#

Write used_toml() (with the parameters’ coronagraphs and [method]) to a file.

Parameters:

path (str) – the file (overwritten).

toycoronagraph.params.blackbody_flux_jy(temperature, radius_rsun, distance_pc, wavelength_m)[source]#

Flux density of a blackbody star: pi B_nu(T) (R/d)^2.

Parameters:
  • temperature (float) – effective temperature in K.

  • radius_rsun (float) – stellar radius in R_sun.

  • distance_pc (float) – distance in pc.

  • wavelength_m (float) – wavelength in m.

Returns:

the flux density in Jy.

Return type:

float

toycoronagraph.params.legacy_to_new(data, base_dir='.')[source]#

Map the old layout ([target], [telescope], [coronagraph], [method], [compute]) to the new one.

[target] becomes one [[source]] (mcfost if input_format = “mcfost”, mcfost_* keys are set or the file looks like an MCFOST cube; else fits_image), [telescope] wavelength / diameter go to [observation], target_pixel / visual_range (lambda/D) to [grid] size / fov, the [coronagraph] table to one [[coronagraph]] (type vortex if not set), [target] unit to [display] label; [method] and [compute] are copied. “auto” values are left out.

Parameters:
  • data (dict) – the old-layout file content.

  • base_dir (str) – directory of the file (for relative FITS file names).

Returns:

the content in the new layout (to check with from_data()).

Return type:

dict