Source code for cellpy.parameters.prms

"""cellpy parameters"""
from __future__ import annotations
import os
import sys
from dataclasses import dataclass, field
from pathlib import Path
from typing import List, Tuple, Union, Optional, TYPE_CHECKING

# Using TYPE_CHECKING to avoid circular imports
# (this will only work without from __future__ import annotations for python 3.11 and above)
from cellpy.internals.core import OtherPath

import box

# When adding prms, please
#   1) check / update the internal_settings.py file as well to
#      ensure that copying / splitting cellpy objects
#      behaves properly.
#   2) check / update the .cellpy_prms_default.conf file

# locations etc. for reading custom parameters
script_dir = os.path.abspath(os.path.dirname(__file__))
cur_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
user_dir = Path.home()
wdir = Path(cur_dir)
op_wdir = str(wdir)


[docs]@dataclass class CellPyDataConfig: """Settings that can be unique for each CellpyCell instance.""" ...
[docs]@dataclass class CellPyConfig: """Session settings (global)."""
[docs] def keys(self): return self.__dataclass_fields__.keys()
# If updating this, you will have to do a lot of tweaks. # .cellpy_prms_default.conf # cli.py (_update_paths) # test_cli_setup_interactive (NUMBER_OF_DIRS) # test_prms.py (config_file_txt) # _convert_paths_to_dict # This can stay global:
[docs]@dataclass class PathsClass(CellPyConfig): outdatadir: Union[Path, str] = wdir _rawdatadir: Union[OtherPath, str] = op_wdir _cellpydatadir: Union[OtherPath, str] = op_wdir db_path: Union[Path, str] = wdir # used for simple excel db reader filelogdir: Union[Path, str] = wdir examplesdir: Union[Path, str] = wdir notebookdir: Union[Path, str] = wdir templatedir: Union[Path, str] = wdir batchfiledir: Union[Path, str] = wdir instrumentdir: Union[Path, str] = wdir db_filename: str = "cellpy_db.xlsx" # used for simple excel db reader env_file: Union[Path, str] = user_dir / ".env_cellpy" @property def rawdatadir(self) -> OtherPath: return OtherPath(self._rawdatadir) @rawdatadir.setter def rawdatadir(self, value: Union[OtherPath, Path, str]): self._rawdatadir = OtherPath(value) @property def cellpydatadir(self) -> OtherPath: return OtherPath(self._cellpydatadir) @cellpydatadir.setter def cellpydatadir(self, value: Union[OtherPath, Path, str]): self._cellpydatadir = OtherPath(value)
[docs]@dataclass class BatchClass(CellPyConfig): template: str = "standard" fig_extension: str = "png" backend: str = "bokeh" notebook: bool = True dpi: int = 300 markersize: int = 4 symbol_label: str = "simple" color_style_label: str = "seaborn-deep" figure_type: str = "unlimited" summary_plot_width: int = 900 summary_plot_height: int = 800 summary_plot_height_fractions: List[float] = field( default_factory=lambda: [0.2, 0.5, 0.3] )
[docs]@dataclass class FileNamesClass(CellPyConfig): file_name_format: str = "YYYYMMDD_[NAME]EEE_CC_TT_RR" raw_extension: str = "res" reg_exp: str = None sub_folders: bool = True file_list_location: str = None file_list_type: str = None file_list_name: str = None cellpy_file_extension: str = "h5"
[docs]@dataclass class ReaderClass(CellPyConfig): diagnostics: bool = False filestatuschecker: str = "size" force_step_table_creation: bool = True force_all: bool = False # not used yet - should be used when saving sep: str = ";" cycle_mode: str = "anode" sorted_data: bool = True # finding step-types assumes sorted data select_minimal: bool = False limit_loaded_cycles: Optional[ int ] = None # limit loading cycles to given cycle number ensure_step_table: bool = False ensure_summary_table: bool = False voltage_interpolation_step: float = 0.01 time_interpolation_step: float = 10.0 capacity_interpolation_step: float = 2.0 use_cellpy_stat_file: bool = False auto_dirs: bool = ( True # v2.0 search in prm-file for res and hdf5 dirs in cellpy.get() )
[docs]@dataclass class DbClass(CellPyConfig): db_type: str = "simple_excel_reader" db_table_name: str = "db_table" # used for simple excel db reader db_header_row: int = 0 # used for simple excel db reader db_unit_row: int = 1 # used for simple excel db reader db_data_start_row: int = 2 # used for simple excel db reader db_search_start_row: int = 2 # used for simple excel db reader db_search_end_row: int = -1 # used for simple excel db reader db_file_sqlite: str = "excel.db" # used when converting from Excel to sqlite # database connection string - used for more advanced db readers: db_connection: Optional[str] = None
[docs]@dataclass class DbColsClass(CellPyConfig): # used for simple excel db reader # Note to developers: # 1) This is ONLY for the excel-reader (dbreader.py)! More advanced # readers should get their own way of handling the db-columns. # 2) If you would like to change the names of the attributes, # you will have to change the names in the # a .cellpy_prms_default.conf # b. dbreader.py # c. test_dbreader.py # d. internal_settings.py (renaming when making sqlite from Excel) # As well as the DbColsTypeClass below. id: str = "id" exists: str = "exists" project: str = "project" label: str = "label" group: str = "group" selected: str = "selected" cell_name: str = "cell" cell_type: str = "cell_type" experiment_type: str = "experiment_type" mass_active: str = "mass_active_material" area: str = "area" mass_total: str = "mass_total" loading: str = "loading_active_material" nom_cap: str = "nominal_capacity" file_name_indicator: str = "file_name_indicator" instrument: str = "instrument" raw_file_names: str = "raw_file_names" cellpy_file_name: str = "cellpy_file_name" comment_slurry: str = "comment_slurry" comment_cell: str = "comment_cell" comment_general: str = "comment_general" freeze: str = "freeze" argument: str = "argument" batch: str = "batch" sub_batch_01: str = "b01" sub_batch_02: str = "b02" sub_batch_03: str = "b03" sub_batch_04: str = "b04" sub_batch_05: str = "b05" sub_batch_06: str = "b06" sub_batch_07: str = "b07"
[docs]@dataclass class DbColsUnitClass(CellPyConfig): # Note to developers: # 1) This is ONLY for the excel-reader (dbreader.py)! More advanced # readers should get their own way of handling the db-columns. id: str = "str" exists: str = "int" project: str = "str" label: str = "str" group: str = "str" selected: str = "int" cell_name: str = "str" cell_type: str = "str" experiment_type: str = "str" mass_active: str = "float" area: str = "float" mass_total: str = "float" loading: str = "float" nom_cap: str = "float" file_name_indicator: str = "str" instrument: str = "str" raw_file_names: str = "str" cellpy_file_name: str = "str" comment_slurry: str = "str" comment_cell: str = "str" comment_general: str = "str" freeze: str = "int" argument: str = "str" batch: str = "str" sub_batch_01: str = "str" sub_batch_02: str = "str" sub_batch_03: str = "str" sub_batch_04: str = "str" sub_batch_05: str = "str" sub_batch_06: str = "str" sub_batch_07: str = "str"
[docs]@dataclass class CellInfoClass(CellPyDataConfig): """Values used for setting the parameters related to the cell and the cycling""" voltage_lim_low: float = 0.0 voltage_lim_high: float = 1.0 active_electrode_area: float = 1.0 active_electrode_thickness: float = 1.0 electrolyte_volume: float = 1.0 electrolyte_type: str = "standard" active_electrode_type: str = "standard" counter_electrode_type: str = "standard" reference_electrode_type: str = "standard" experiment_type: str = "cycling" cell_type: str = "standard" separator_type: str = "standard" active_electrode_current_collector: str = "standard" reference_electrode_current_collector: str = "standard" comment: str = ""
[docs]@dataclass class MaterialsClass(CellPyDataConfig): """Default material-specific values used in processing the data.""" cell_class: str = "Li-Ion" default_material: str = "silicon" default_mass: float = 1.0 default_nom_cap: float = 1.0 default_nom_cap_specifics: str = "gravimetric"
Paths = PathsClass() FileNames = FileNamesClass() Reader = ReaderClass() Db = DbClass() DbCols = DbColsClass() CellInfo = CellInfoClass() Materials = MaterialsClass() Batch = BatchClass(summary_plot_height_fractions=[0.2, 0.5, 0.3]) # ------------------------------------------------------------------------------ # Instruments # # This should be updated - currently using dicts instead of subclasses of # dataclasses. I guess I could update this but is a bit challenging # so maybe replace later using e.g. pydantic # ------------------------------------------------------------------------------ # This can stay global: # remark! using box.Box for each instrument
[docs]@dataclass class InstrumentsClass(CellPyConfig): tester: Union[str, None] custom_instrument_definitions_file: Union[str, None] Arbin: box.Box Maccor: box.Box Neware: box.Box
# Pre-defined instruments: # These can stay global: Arbin = { "max_res_filesize": 150_000_000, "chunk_size": None, "max_chunks": None, "use_subprocess": False, "detect_subprocess_need": False, "sub_process_path": None, "office_version": "64bit", "SQL_server": r"localhost\SQLEXPRESS", "SQL_UID": "sa", "SQL_PWD": "ChangeMe123", "SQL_Driver": "SQL Server", } Arbin = box.Box(Arbin) Maccor = {"default_model": "one"} Maccor = box.Box(Maccor) Neware = {"default_model": "one"} Neware = box.Box(Neware) Instruments = InstrumentsClass( tester=None, # TODO: moving this to DataSetClass (deprecate) custom_instrument_definitions_file=None, Arbin=Arbin, Maccor=Maccor, Neware=Neware, ) # ------------------------------------------------------------------------------ # Other secret- or non-config (only for developers) # ------------------------------------------------------------------------------ _db_cols_unit = DbColsUnitClass() _debug = False _variable_that_is_not_saved_to_config = "Hei" _prm_default_name = ".cellpy_prms_default.conf" _prm_globtxt = ".cellpy_prms*.conf" _odbcs = ["pyodbc", "ado", "pypyodbc"] _odbc = "pyodbc" _search_for_odbc_driver = True _allow_multi_test_file = False _use_filename_cache = True _sub_process_path = Path(__file__) / "../../../bin/mdbtools-win/mdb-export" _sub_process_path = _sub_process_path.resolve() _sort_if_subprocess = True _cellpyfile_root = "CellpyData" _cellpyfile_raw = "/raw" _cellpyfile_step = "/steps" _cellpyfile_summary = "/summary" _cellpyfile_fid = "/fid" _cellpyfile_common_meta = "/info" _cellpyfile_test_dependent_meta = "/info_test_dependent" _cellpyfile_raw_unit_pre_id = "raw_unit_" _cellpyfile_raw_limit_pre_id = "" _cellpyfile_complevel = 1 _cellpyfile_complib = None # currently, defaults to "zlib" _cellpyfile_raw_format = "table" _cellpyfile_summary_format = "table" _cellpyfile_stepdata_format = "table" _cellpyfile_infotable_format = "fixed" _cellpyfile_fidtable_format = "fixed" # templates _standard_template_uri = "https://github.com/jepegit/cellpy_cookies.git" _registered_templates = { "standard": (_standard_template_uri, "standard"), # (repository, name-of-folder) "ife": (_standard_template_uri, "ife"), } # used as global variables _globals_status = "" _globals_errors = [] _globals_message = [] # general settings for loaders _minimum_columns_to_keep_for_raw_if_exists = [ "data_point_txt", "datetime_txt", "test_time_txt", "step_time_txt", "cycle_index_txt", "step_time_txt", "step_index_txt", "current_txt", "voltage_txt", "charge_capacity_txt", "discharge_capacity_txt", "power_txt", ] # used during development for testing new features _res_chunk = 0