Source code for cellpy.readers.instruments.configurations

""" Very simple implementation of a plugin-like infrastructure"""
from dataclasses import dataclass, field
from importlib import import_module
from pathlib import Path

from ruamel import yaml

# TODO: make tests.
# TODO: move this into its own module (not __init__).
# TODO: document for devs.
# TODO: Bonus - make a python package/pre-commit hook that
# turns TODO-statements into issues.

HARD_CODED_MODULE_PATH = "cellpy.readers.instruments.configurations"
OPTIONAL_DICTIONARY_ATTRIBUTE_NAMES = [
    "file_info",
    "formatters",
    "prefixes",
    "pre_processors",
    "post_processors",
    "meta_keys",
    "incremental_unit_labels",
    "not_implemented_in_cellpy_yet_renaming_dict",
    "raw_units",
    "raw_limits",
    "states",
    "unit_labels",
]
OPTIONAL_LIST_ATTRIBUTE_NAMES = [
    "columns_to_keep",
]


RAW_LIMITS = {
    "current_hard": 0.000_000_000_000_1,
    "current_soft": 0.000_01,
    "stable_current_hard": 2.0,
    "stable_current_soft": 4.0,
    "stable_voltage_hard": 2.0,
    "stable_voltage_soft": 4.0,
    "stable_charge_hard": 0.001,
    "stable_charge_soft": 5.0,
    "ir_change": 0.00001,
}


[docs]@dataclass class ModelParameters: """Dataclass to store sub-model specific parameters.""" name: str # The unit labels are only used when generating new headers # (normal_headers_renaming_dict) # with units (post_processor: get_column_names): file_info: dict = field(default_factory=dict) unit_labels: dict = field(default_factory=dict) incremental_unit_labels: dict = field(default_factory=dict) normal_headers_renaming_dict: dict = field(default_factory=dict) not_implemented_in_cellpy_yet_renaming_dict: dict = field(default_factory=dict) columns_to_keep: list = field(default_factory=list) states: dict = field(default_factory=dict) raw_units: dict = field(default_factory=dict) raw_limits: dict = field(default_factory=dict) formatters: dict = field(default_factory=dict) meta_keys: dict = field(default_factory=dict) pre_processors: dict = field(default_factory=dict) post_processors: dict = field(default_factory=dict) # used for defining e.g. M, k, etc. - probably not needed: prefixes: dict = field(default_factory=dict)
[docs]def register_local_configuration_from_yaml_file(instrument) -> ModelParameters: """register a module (.yml file) and return it. This function will dynamically import the given module from the cellpy.readers.instruments.configurations module and return it. Returns: ModelParameters """ yml = yaml.YAML() with open(instrument, "r") as ff: settings = yml.load(ff.read()) name = Path(instrument).name optional_dictionary_attributes = { key: settings.get(key, dict()) for key in OPTIONAL_DICTIONARY_ATTRIBUTE_NAMES } optional_list_attributes = { key: settings.get(key, list()) for key in OPTIONAL_LIST_ATTRIBUTE_NAMES } # special hacks # -- raw limits (this should be moved to internal settings, prms or something like that raw_limits = optional_dictionary_attributes["raw_limits"] if not raw_limits: raw_limits = RAW_LIMITS model_01 = ModelParameters( name=name, file_info=optional_dictionary_attributes["file_info"], normal_headers_renaming_dict=settings["normal_headers_renaming_dict"], unit_labels=optional_dictionary_attributes["unit_labels"], prefixes=optional_dictionary_attributes["prefixes"], incremental_unit_labels=optional_dictionary_attributes[ "incremental_unit_labels" ], not_implemented_in_cellpy_yet_renaming_dict=optional_dictionary_attributes[ "not_implemented_in_cellpy_yet_renaming_dict" ], columns_to_keep=optional_list_attributes["columns_to_keep"], states=optional_dictionary_attributes["states"], raw_units=optional_dictionary_attributes["raw_units"], raw_limits=raw_limits, meta_keys=optional_dictionary_attributes["meta_keys"], formatters=optional_dictionary_attributes["formatters"], pre_processors=optional_dictionary_attributes["pre_processors"], post_processors=optional_dictionary_attributes["post_processors"], ) return model_01
[docs]def register_configuration_from_module( name: str = "one", module: str = "maccor_txt_one", _module_path=None, _m=None, ) -> ModelParameters: """register a python module (.py file) and return it. This function will dynamically import the given module from the cellpy.readers.instruments.configurations module and return it. Returns: ModelParameters """ if _m is None: if _module_path is None: _m = import_module(f"{HARD_CODED_MODULE_PATH}.{module}") else: _m = import_module(f"{_module_path}.{module}") optional_dictionary_attributes = { key: getattr(_m, key, dict()) for key in OPTIONAL_DICTIONARY_ATTRIBUTE_NAMES } optional_list_attributes = { key: getattr(_m, key, list()) for key in OPTIONAL_LIST_ATTRIBUTE_NAMES } # special hacks # -- raw limits (this should be moved to internal settings, prms or something like that raw_limits = optional_dictionary_attributes["raw_limits"] if not raw_limits: raw_limits = RAW_LIMITS return ModelParameters( name=name, file_info=optional_dictionary_attributes["file_info"], normal_headers_renaming_dict=_m.normal_headers_renaming_dict, unit_labels=optional_dictionary_attributes["unit_labels"], prefixes=optional_dictionary_attributes["prefixes"], incremental_unit_labels=optional_dictionary_attributes[ "incremental_unit_labels" ], not_implemented_in_cellpy_yet_renaming_dict=optional_dictionary_attributes[ "not_implemented_in_cellpy_yet_renaming_dict" ], columns_to_keep=optional_list_attributes["columns_to_keep"], states=optional_dictionary_attributes["states"], raw_units=optional_dictionary_attributes["raw_units"], raw_limits=raw_limits, meta_keys=optional_dictionary_attributes["meta_keys"], formatters=optional_dictionary_attributes["formatters"], pre_processors=optional_dictionary_attributes["pre_processors"], post_processors=optional_dictionary_attributes["post_processors"], )