pycsamt.core.config#

Runtime configuration, adapter registration, and configuration contexts.

Functions

config_context(**overrides)

Context manager for temporary configuration overrides.

configure(**kwargs)

Update configuration fields with validation.

get_adapter(key)

Return the adapter factory for a key.

get_config()

Return the live CoreConfig singleton.

list_adapters()

List registered adapters with readable names.

register_adapter(key, factory)

Register a format adapter that yields an EDI object or collection.

reset_config()

Reset the global configuration to factory defaults.

to_dict()

Serialize the current configuration to a plain dict.

Classes

CoreConfig([empty, strict, ...])

Global configuration container for pycsamt.

StationNamePolicy([allow_pattern, maxlen, ...])

Rules to validate and synthesize station names.

class pycsamt.core.config.StationNamePolicy(allow_pattern='A-Za-z0-9_\\-', maxlen=32, prefix='S', pad=3, strip=True, custom_normalize=<function StationNamePolicy.<lambda>>)[source]#

Bases: object

Rules to validate and synthesize station names.

This policy is applied during inter-format conversion (AVG or Jones -> EDI). When a provided name is missing or invalid, a synthetic name is derived from the station id.

Parameters:
  • allow_pattern (str, optional) – Regex character class (without brackets) that defines the whitelist of allowed characters. The default accepts ASCII letters, digits, underscore and dash.

  • maxlen (int, optional) – Maximum length of a station name after normalization.

  • prefix (str, optional) – Prefix used when creating synthetic names.

  • pad (int, optional) – Zero-padding width for numeric station ids.

  • strip (bool, optional) – If True, strip leading and trailing whitespace first.

  • custom_normalize (Callable[[str], str], optional) – Hook called before validation. Can perform additional transliteration or case normalization.

Notes

Normalization runs as: strip → custom_normalize → filter by allow_pattern → truncate to maxlen. Empty results are treated as invalid.

Examples

>>> from pycsamt.core.config import StationNamePolicy
>>> pol = StationNamePolicy(prefix=\"S\", pad=4)
>>> pol.ensure(\" Site-1  \", station_id=None)
'Site-1'
>>> pol.ensure(None, station_id=7)
'S0007'
allow_pattern: str = 'A-Za-z0-9_\\-'#
maxlen: int = 32#
prefix: str = 'S'#
pad: int = 3#
strip: bool = True#
static custom_normalize(s)#
validate(name)[source]#

Validate and normalize a name.

Parameters:

name (str or None) – Candidate station name.

Returns:

Normalized name if valid; otherwise None.

Return type:

str or None

Notes

The method does not synthesize names. Use ensure for a name-or-fallback behavior.

synthesize(station_id)[source]#

Create a deterministic synthetic name from a station id.

Parameters:

station_id (Any or None) – Station identifier. Numeric ids are zero-padded. Non- numeric ids are compacted by removing non-word chars.

Returns:

Synthetic station name.

Return type:

str

Examples

>>> StationNamePolicy().synthesize(12)
'S012'
>>> StationNamePolicy(prefix='X').synthesize('AB-01')
'AB01'
ensure(name, station_id)[source]#

Return a valid station name, validating or synthesizing.

Parameters:
  • name (str or None) – Provided station name.

  • station_id (Any or None) – Station identifier used if name is invalid.

Returns:

Validated name or a synthetic fallback.

Return type:

str

See also

validate

Validate only, without fallback.

synthesize

Create a name from the station id only.

class pycsamt.core.config.CoreConfig(empty=1e+32, strict=False, case_sensitive_sections=False, on_duplicate_station='replace', target_format='edi', log_level='WARNING', freq_order='desc', freq_tol=1e-09, compute_res_from_z=True, compute_z_from_res=True, load_spectra=True, load_time_series=False, station_policy=<factory>, error_fill_value=nan, infer_errors=True, encoding='utf-8', newline='\n', backend=<factory>)[source]#

Bases: object

Global configuration container for pycsamt.

The object stores defaults for parsing, conversion, and population of EDI data structures. Use configure() for updates or config_context() for temporary overrides.

Parameters:
  • empty (float) – Sentinel used in legacy files to mark missing values.

  • strict (bool) – If True, raise on recoverable parse issues; otherwise, degrade gracefully when possible.

  • case_sensitive_sections (bool) – Treat section names as case-sensitive when reading.

  • on_duplicate_station ({'replace', 'keep', 'error'}) – Policy when collection loaders encounter duplicate station ids.

  • target_format ({'edi'}) – Preferred internal representation for processing. Keep as ‘edi’ to normalize all inputs to EDI objects.

  • log_level (str) – Default logging level for package loggers.

  • freq_order ({'asc', 'desc'}) – Preferred order for frequency vectors after normalization.

  • freq_tol (float) – Relative tolerance for de-duplicating near-equal frequencies.

  • compute_res_from_z (bool) – Compute (rho, phase) from Z when absent.

  • compute_z_from_res (bool) – Reconstruct Z from (rho, phase) when Z is missing.

  • load_spectra (bool) – If True, preserve spectra sections when available.

  • load_time_series (bool) – If True, preserve time-series sections when available.

  • station_policy (StationNamePolicy) – Validation and synthesis rules for station names.

  • error_fill_value (float) – Fill value used when error arrays are required by a consumer but not available.

  • infer_errors (bool) – If True, allow simple heuristics to infer missing errors from weights or coherency measures when present.

  • encoding (str) – Default text encoding for reading legacy files.

  • newline (str) – Line terminator to use when writing files.

  • backend (dict) – Reserved space for per-backend knobs.

Notes

The instance stored in this module is mutable by design. Use configure() or config_context() instead of assigning attributes directly, so validation is applied.

Examples

>>> from pycsamt.core.config import configure, get_config
>>> _ = configure(freq_order='desc', strict=False)
>>> get_config().freq_order
'desc'
empty: float = 1e+32#
strict: bool = False#
case_sensitive_sections: bool = False#
on_duplicate_station: str = 'replace'#
target_format: str = 'edi'#
log_level: str = 'WARNING'#
freq_order: str = 'desc'#
freq_tol: float = 1e-09#
compute_res_from_z: bool = True#
compute_z_from_res: bool = True#
load_spectra: bool = True#
load_time_series: bool = False#
station_policy: StationNamePolicy#
error_fill_value: float = nan#
infer_errors: bool = True#
encoding: str = 'utf-8'#
newline: str = '\n'#
backend: dict[str, Any]#
copy()[source]#

Return a deep copy of the configuration.

Returns:

A detached copy that can be safely mutated.

Return type:

CoreConfig

Notes

Used internally by config_context() to restore the previous state atomically.

pycsamt.core.config.get_config()[source]#

Return the live CoreConfig singleton.

Returns:

The active configuration object.

Return type:

CoreConfig

Notes

The returned instance is mutable. Prefer configure() or config_context() for controlled updates.

pycsamt.core.config.configure(**kwargs)[source]#

Update configuration fields with validation.

Parameters:

**kwargs (Any) – Field names and values to set on the global config.

Returns:

The updated configuration object.

Return type:

CoreConfig

Raises:

Notes

Also aligns the package logger level to log_level, if that logger has been created.

Examples

>>> from pycsamt.core.config import configure
>>> _ = configure(freq_order='asc', infer_errors=False)
pycsamt.core.config.reset_config()[source]#

Reset the global configuration to factory defaults.

Notes

A new CoreConfig instance replaces the existing singleton. Any references to the previous instance will not reflect subsequent changes.

Return type:

None

pycsamt.core.config.config_context(**overrides)[source]#

Context manager for temporary configuration overrides.

Parameters:

**overrides (Any) – Field names and temporary values.

Yields:

CoreConfig – The active configuration during the context.

Return type:

Iterator[CoreConfig]

Notes

On exit, the previous configuration is restored atomically, even if an exception is raised.

Examples

>>> from pycsamt.core.config import config_context, get_config
>>> with config_context(strict=True):
...     assert get_config().strict is True
>>> assert get_config().strict is False
pycsamt.core.config.to_dict()[source]#

Serialize the current configuration to a plain dict.

Returns:

A JSON-serializable mapping of all fields.

Return type:

dict

Examples

>>> from pycsamt.core.config import to_dict
>>> d = to_dict()
>>> 'freq_order' in d
True
pycsamt.core.config.register_adapter(key, factory)[source]#

Register a format adapter that yields an EDI object or collection.

Parameters:
  • key (str) – Format key, e.g. 'avg' or 'j'.

  • factory (Callable[..., Any]) – Callable that accepts a source object and returns an EDI object or an EDICollection.

Raises:

ValueError – If key is not a non-empty string.

Return type:

None

Notes

Adapters are resolved lazily at call time, which avoids heavy imports and circular dependencies.

See also

get_adapter

Retrieve a registered adapter.

list_adapters

Inspect the registry.

pycsamt.core.config.get_adapter(key)[source]#

Return the adapter factory for a key.

Parameters:

key (str) – Format key used during registration.

Returns:

The factory callable if found, else None.

Return type:

Callable or None

pycsamt.core.config.list_adapters()[source]#

List registered adapters with readable names.

Returns:

Mapping {key: 'qualname'} for registered factories.

Return type:

dict

Examples

>>> from pycsamt.core.config import list_adapters
>>> isinstance(list_adapters(), dict)
True