"""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
[docs]
script_dir = os.path.abspath(os.path.dirname(__file__))
[docs]
cur_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
@dataclass
[docs]
class CellPyDataConfig:
"""Settings that can be unique for each CellpyCell instance."""
...
@dataclass
[docs]
class CellPyConfig:
"""Session settings (global)."""
[docs]
def keys(self):
return self.__dataclass_fields__.keys()
# If updating PathsClass, 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:
@dataclass
[docs]
class PathsClass(CellPyConfig):
"""Paths used in cellpy."""
[docs]
outdatadir: Union[Path, str] = wdir
_rawdatadir: Union[OtherPath, str] = op_wdir
_cellpydatadir: Union[OtherPath, str] = op_wdir
[docs]
db_path: Union[Path, str] = wdir # used for simple excel db reader
[docs]
filelogdir: Union[Path, str] = wdir
[docs]
examplesdir: Union[Path, str] = wdir
[docs]
notebookdir: Union[Path, str] = wdir
[docs]
templatedir: Union[Path, str] = wdir
[docs]
batchfiledir: Union[Path, str] = wdir
[docs]
instrumentdir: Union[Path, str] = wdir
[docs]
db_filename: str = "cellpy_db.xlsx" # used for simple excel db reader
[docs]
env_file: Union[Path, str] = user_dir / ".env_cellpy"
@property
[docs]
def rawdatadir(self) -> OtherPath:
return OtherPath(self._rawdatadir)
@rawdatadir.setter
def rawdatadir(self, value: Union[OtherPath, Path, str]):
self._rawdatadir = OtherPath(value)
@property
[docs]
def cellpydatadir(self) -> OtherPath:
return OtherPath(self._cellpydatadir)
@cellpydatadir.setter
def cellpydatadir(self, value: Union[OtherPath, Path, str]):
self._cellpydatadir = OtherPath(value)
@dataclass
[docs]
class BatchClass(CellPyConfig):
"""Settings for batch processing."""
[docs]
auto_use_file_list: bool = False
[docs]
template: str = "standard"
[docs]
fig_extension: str = "png"
[docs]
backend: str = "plotly"
[docs]
symbol_label: str = "simple"
[docs]
color_style_label: str = "seaborn-deep"
[docs]
summary_plot_width: int = 900
[docs]
summary_plot_height: int = 800
[docs]
summary_plot_height_fractions: List[float] = field(
default_factory=lambda: [0.2, 0.5, 0.3]
)
@dataclass
[docs]
class FileNamesClass(CellPyConfig):
"""Settings for file names and file handling."""
[docs]
raw_extension: str = "res"
[docs]
sub_folders: bool = True
[docs]
file_list_location: str = None
[docs]
file_list_type: str = None
[docs]
file_list_name: str = None
[docs]
cellpy_file_extension: str = "h5"
@dataclass
[docs]
class ReaderClass(CellPyConfig):
"""Settings for reading data."""
[docs]
diagnostics: bool = False
[docs]
filestatuschecker: str = "size"
[docs]
force_step_table_creation: bool = True
[docs]
force_all: bool = False # not used yet - should be used when saving
[docs]
cycle_mode: str = "anode"
[docs]
sorted_data: bool = True # finding step-types assumes sorted data
[docs]
select_minimal: bool = False
[docs]
limit_loaded_cycles: Optional[int] = (
None # limit loading cycles to given cycle number
)
[docs]
ensure_step_table: bool = False
[docs]
ensure_summary_table: bool = False
[docs]
voltage_interpolation_step: float = 0.01
[docs]
time_interpolation_step: float = 10.0
[docs]
capacity_interpolation_step: float = 2.0
[docs]
use_cellpy_stat_file: bool = False
[docs]
auto_dirs: bool = (
True # v2.0 search in prm-file for res and hdf5 dirs in cellpy.get()
)
[docs]
jupyter_executable: str = "jupyter"
@dataclass
[docs]
class DbClass(CellPyConfig):
"""Settings for the handling the simple database."""
[docs]
db_type: str = "simple_excel_reader"
[docs]
db_table_name: str = "db_table" # used for simple excel db reader
[docs]
db_unit_row: int = 1 # used for simple excel db reader
[docs]
db_data_start_row: int = 2 # used for simple excel db reader
[docs]
db_search_start_row: int = 2 # used for simple excel db reader
[docs]
db_search_end_row: int = -1 # used for simple excel db reader
[docs]
db_file_sqlite: str = "excel.db" # used when converting from Excel to sqlite
# database connection string - used for more advanced db readers:
[docs]
db_connection: Optional[str] = None
@dataclass
[docs]
class DbColsClass(CellPyConfig): # used for simple excel db reader
"""Names of the columns in the simple database."""
# 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.
[docs]
project: str = "project"
[docs]
selected: str = "selected"
[docs]
cell_name: str = "cell"
[docs]
cell_type: str = "cell_type"
[docs]
experiment_type: str = "experiment_type"
[docs]
mass_active: str = "mass_active_material"
[docs]
mass_total: str = "mass_total"
[docs]
loading: str = "loading_active_material"
[docs]
nom_cap: str = "nominal_capacity"
[docs]
file_name_indicator: str = "file_name_indicator"
[docs]
instrument: str = "instrument"
[docs]
raw_file_names: str = "raw_file_names"
[docs]
cellpy_file_name: str = "cellpy_file_name"
[docs]
argument: str = "argument"
[docs]
sub_batch_01: str = "b01"
[docs]
sub_batch_02: str = "b02"
[docs]
sub_batch_03: str = "b03"
[docs]
sub_batch_04: str = "b04"
[docs]
sub_batch_05: str = "b05"
[docs]
sub_batch_06: str = "b06"
[docs]
sub_batch_07: str = "b07"
@dataclass
[docs]
class DbColsUnitClass(CellPyConfig):
"""Unit of the columns in the simple database."""
# 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.
[docs]
experiment_type: str = "str"
[docs]
mass_active: str = "float"
[docs]
mass_total: str = "float"
[docs]
file_name_indicator: str = "str"
[docs]
instrument: str = "str"
[docs]
raw_file_names: str = "str"
[docs]
cellpy_file_name: str = "str"
[docs]
sub_batch_01: str = "str"
[docs]
sub_batch_02: str = "str"
[docs]
sub_batch_03: str = "str"
[docs]
sub_batch_04: str = "str"
[docs]
sub_batch_05: str = "str"
[docs]
sub_batch_06: str = "str"
[docs]
sub_batch_07: str = "str"
@dataclass
[docs]
class CellInfoClass(CellPyDataConfig):
"""Values used for setting the parameters related to the cell and the cycling"""
[docs]
voltage_lim_low: float = 0.0
[docs]
voltage_lim_high: float = 1.0
[docs]
active_electrode_area: float = 1.0
[docs]
active_electrode_thickness: float = 1.0
[docs]
electrolyte_volume: float = 1.0
[docs]
electrolyte_type: str = "standard"
[docs]
active_electrode_type: str = "standard"
[docs]
counter_electrode_type: str = "standard"
[docs]
reference_electrode_type: str = "standard"
[docs]
experiment_type: str = "cycling"
[docs]
cell_type: str = "standard"
[docs]
separator_type: str = "standard"
[docs]
active_electrode_current_collector: str = "standard"
[docs]
reference_electrode_current_collector: str = "standard"
@dataclass
[docs]
class MaterialsClass(CellPyDataConfig):
"""Default material-specific values used in processing the data."""
[docs]
cell_class: str = "Li-Ion"
[docs]
default_material: str = "silicon"
[docs]
default_mass: float = 1.0
[docs]
default_nom_cap: float = 1.0
[docs]
default_nom_cap_specifics: str = "gravimetric"
[docs]
FileNames = FileNamesClass()
[docs]
CellInfo = CellInfoClass()
[docs]
Materials = MaterialsClass()
[docs]
Batch = BatchClass(backend="plotly")
# ------------------------------------------------------------------------------
# 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
@dataclass
[docs]
class InstrumentsClass(CellPyConfig):
"""Settings for the instruments."""
[docs]
tester: Union[str, None]
[docs]
custom_instrument_definitions_file: Union[str, None]
# 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",
}
[docs]
Arbin = box.Box(_Arbin)
_Maccor = {"default_model": "one"}
[docs]
Maccor = box.Box(_Maccor)
_Neware = {"default_model": "one"}
[docs]
Neware = box.Box(_Neware)
[docs]
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 and super-users)
# ------------------------------------------------------------------------------
_github_repo_parent = "jepegit"
_github_repo = "cellpy"
_github_templates_repo = "cellpy_cookies.git"
_url_example_data = f"https://raw.githubusercontent.com/{_github_repo_parent}/{_github_repo}/master/examples/data/"
_url_example_data_download_with_progressbar = True
_example_data_in_example_folder_if_available = True
_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"
_date_time_format = "%Y-%m-%d %H:%M:%S:%f"
# templates
_standard_template_uri = (
f"https://github.com/{_github_repo_parent}/{_github_templates_repo}"
)
_registered_templates = {
"standard": (_standard_template_uri, "standard"), # (repository, name-of-folder)
"ife": (_standard_template_uri, "ife"),
"single": (_standard_template_uri, "single"),
}
# 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