Skip to content

Commit

Permalink
Add an option to downgrade the instrument scaling error to a warning
Browse files Browse the repository at this point in the history
  • Loading branch information
ml-evs committed Feb 25, 2024
1 parent 596c0d3 commit b3ca37d
Showing 1 changed file with 29 additions and 11 deletions.
40 changes: 29 additions & 11 deletions NewareNDA/NewareNDA.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from .NewareNDAx import read_ndax


def read(file, software_cycle_number=True, cycle_mode='chg'):
def read(file, software_cycle_number=True, cycle_mode='chg', error_on_missing: bool = True) -> pd.DataFrame:
"""
Read electrochemical data from an Neware nda or ndax binary file.
Expand All @@ -27,19 +27,23 @@ def read(file, software_cycle_number=True, cycle_mode='chg'):
'chg': (Default) Sets new cycles with a Charge step following a Discharge.
'dchg': Sets new cycles with a Discharge step following a Charge.
'auto': Identifies the first non-rest state as the incremental state.
error_on_missing: In cases where an instrument is unsupported or an optional
feature is used (e.g., automatic scaling of data), the default is to return
an error, but setting this value to `False` will downgrade this to a warning.
Returns:
df (pd.DataFrame): DataFrame containing all records in the file
"""
_, ext = os.path.splitext(file)
if ext == '.nda':
return read_nda(file, software_cycle_number, cycle_mode)
return read_nda(file, software_cycle_number, cycle_mode, error_on_missing=error_on_missing)
elif ext == '.ndax':
return read_ndax(file, software_cycle_number, cycle_mode)
else:
raise TypeError("File type not supported!")
raise TypeError(f"File type {ext=} not supported!")


def read_nda(file, software_cycle_number, cycle_mode='chg'):
def read_nda(file, software_cycle_number, cycle_mode='chg', error_on_missing: bool = True):
"""
Function read electrochemical data from a Neware nda binary file.
Expand All @@ -51,6 +55,9 @@ def read_nda(file, software_cycle_number, cycle_mode='chg'):
'chg': (Default) Sets new cycles with a Charge step following a Discharge.
'dchg': Sets new cycles with a Discharge step following a Charge.
'auto': Identifies the first non-rest state as the incremental state.
error_on_missing: In cases where an instrument is unsupported or an optional
feature is used (e.g., automatic scaling of data), the default is to return
an error, but setting this value to `False` will downgrade this to a warning.
Returns:
df (pd.DataFrame): DataFrame containing all records in the file
"""
Expand Down Expand Up @@ -78,7 +85,7 @@ def read_nda(file, software_cycle_number, cycle_mode='chg'):

# version specific settings
if nda_version < 130:
output, aux = _read_nda(mm)
output, aux = _read_nda(mm, error_on_missing=error_on_missing)
else:
output, aux = _read_nda_130(mm)

Expand Down Expand Up @@ -109,7 +116,7 @@ def read_nda(file, software_cycle_number, cycle_mode='chg'):
return df


def _read_nda(mm):
def _read_nda(mm, error_on_missing: bool = True):
"""Helper function for older nda verions < 130"""
mm_size = mm.size()

Expand All @@ -129,14 +136,22 @@ def _read_nda(mm):
# Read data records
output = []
aux = []
warn_on_missing_multiplier = True
while mm.tell() < mm_size:
bytes = mm.read(record_len)
if len(bytes) == record_len:

# Check for a data record
if (bytes[0:2] == b'\x55\x00'
and bytes[82:87] == b'\x00\x00\x00\x00'):
output.append(_bytes_to_list(bytes))
# catch warnings for missing multiplier to only emit once
with warnings.catch_warnings(record=True) as w:
output.append(_bytes_to_list(bytes, error_on_missing=error_on_missing, warn_on_missing=warn_on_missing_multiplier))
if w:
for warning in w:
warnings.warn(warning.message, category=warning.category)
if warning.category is RuntimeWarning and "Instrument range" in str(warning.message):
warn_on_missing_multiplier = False

# Check for an auxiliary record
elif (bytes[0:1] == b'\x65'
Expand Down Expand Up @@ -187,7 +202,7 @@ def _valid_record(bytes):
return (Status != 0)


def _bytes_to_list(bytes):
def _bytes_to_list(bytes, error_on_missing: bool = True, warn_on_missing: bool = True):
"""Helper function for interpreting a byte string"""

# Extract fields from byte string
Expand All @@ -205,11 +220,14 @@ def _bytes_to_list(bytes):
return []

if Range not in multiplier_dict:
warnings.warn(
f"""Instrument range {Range=} not a recognized value; the data cannot be automatically scaled for this instrument, disabling scaling.
message = f"""Instrument range {Range=} not a recognized value; the data cannot be automatically scaled for this instrument, disabling scaling.
For support for this instrument, please raise an issue on GitHub at https://github.com/Solid-Energy-Systems/NewareNDA/issues.
""")
"""
multiplier = 1.0
if error_on_missing:
raise RuntimeError(message)
if warn_on_missing:
warnings.warn(message, category=RuntimeWarning)
else:
multiplier = multiplier_dict[Range]

Expand Down

0 comments on commit b3ca37d

Please sign in to comment.