Skip to content

Commit

Permalink
electrochem: Fix mpt float parsing using locales. (#99)
Browse files Browse the repository at this point in the history
* Fix mpt parsing using locales.

* Fix locale ordering.

* Try fix locale-gen.

* black
  • Loading branch information
PeterKraus committed Dec 27, 2022
1 parent 4239d2c commit 776c634
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 5 deletions.
9 changes: 7 additions & 2 deletions .github/workflows/test-job/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ description: "Test the package with pytest."
runs:
using: "composite"
steps:
- run: yadg --version
- name: Prepare locales
run: sudo locale-gen de_DE.UTF-8 || echo windows
shell: bash
- run: pytest -vv
- name: Print yadg version
run: yadg --version
shell: bash
- name: Run pytest
run: pytest -vv
shell: bash
27 changes: 24 additions & 3 deletions src/yadg/parsers/electrochem/eclabmpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"""
import re
import logging
import locale
from collections import defaultdict
from ...dgutils.dateutils import str_to_uts
from .eclabtechniques import get_resolution, technique_params, param_from_key
Expand Down Expand Up @@ -154,14 +155,29 @@ def _process_header(lines: list[str], timezone: str) -> tuple[dict, list, dict]:
settings_lines = sections[2].split("\n")
technique, params_keys = technique_params(technique, settings_lines)
params = settings_lines[-len(params_keys) :]

# Get the locale
old_loc = locale.getlocale(category=locale.LC_NUMERIC)
ewe_ctrl_re = re.compile(r"Ewe ctrl range : min = (?P<min>.+), max = (?P<max>.+)")
ewe_ctrl_match = ewe_ctrl_re.search("\n".join(settings_lines))
for loc in [old_loc, "de_DE.UTF-8", "en_GB.UTF-8", "en_US.UTF-8"]:
try:
locale.setlocale(locale.LC_NUMERIC, locale=loc)
locale.atof(ewe_ctrl_match["min"].split()[0])
locale.atof(ewe_ctrl_match["max"].split()[0])
logging.debug(f"The locale of the current file is '{loc}'.")
break
except ValueError:
logging.debug(f"Could not parse Ewe ctrl using locale '{loc}'.")

# The sequence param columns are always allocated 20 characters.
n_sequences = int(len(params[0]) / 20)
params_values = []
for seq in range(1, n_sequences):
values = []
for param in params:
try:
val = float(param[seq * 20 : (seq + 1) * 20])
val = locale.atof(param[seq * 20 : (seq + 1) * 20])
except ValueError:
val = param[seq * 20 : (seq + 1) * 20].strip()
values.append(val)
Expand Down Expand Up @@ -192,6 +208,7 @@ def _process_header(lines: list[str], timezone: str) -> tuple[dict, list, dict]:
loops = {"n_loops": n_loops, "indexes": indexes}
settings = {
"posix_timestamp": uts,
"locale": loc,
"technique": technique,
"raw": "\n".join(lines),
}
Expand Down Expand Up @@ -228,7 +245,7 @@ def _process_data(lines: list[str], Eranges: list[float], Iranges: list[float])
datapoint = {}
for col, val, unit in list(zip(columns, values, units)):
if unit is None:
ival = int(float(val))
ival = int(locale.atof(val))
if col == "I Range":
datapoint[col] = param_from_key("I_range", ival)
Irange = param_from_key("I_range", ival, to_str=False)
Expand All @@ -252,7 +269,7 @@ def _process_data(lines: list[str], Eranges: list[float], Iranges: list[float])
Irange = param_from_key("I_range", Irstr, to_str=False)
for col, val, unit in list(zip(columns, values, units)):
try:
val = float(val)
val = locale.atof(val)
except ValueError:
val = val.strip()
if unit is None:
Expand Down Expand Up @@ -299,6 +316,8 @@ def process(
header_lines = lines[: nb_header_lines - 3]
data_lines = lines[nb_header_lines - 3 :]
settings, params, loops = {}, [], {}
# Store current LC_NUMERIC before we do anything:
old_loc = locale.getlocale(category=locale.LC_NUMERIC)
if nb_header_lines <= 3:
logger.warning("Header contains no settings and hence no timestamp.")
start_time = 0.0
Expand Down Expand Up @@ -352,4 +371,6 @@ def process(
uts = start_time + d["time"]["n"]
d["technique"] = settings["technique"]
timesteps.append({"fn": fn, "uts": uts, "raw": d})
# reset to original LC_NUMERIC
locale.setlocale(category=locale.LC_NUMERIC, locale=old_loc)
return timesteps, metadata, fulldate
17 changes: 17 additions & 0 deletions tests/test_electrochem.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,23 @@
},
},
),
( # ts21 - mb_67.mpt
{
"case": "mb_67.mpt",
"encoding": "windows-1252",
"parameters": {"filetype": "eclab.mpt"},
},
{
"nsteps": 1,
"step": 0,
"nrows": 33,
"point": 0,
"pars": {
"uts": {"value": 1670510213.355},
"Ewe": {"value": 2.3278546, "unit": "V", "sigma": 7.5e-05},
},
},
),
],
)
def test_datagram_from_eclab(input, ts, datadir):
Expand Down
Loading

0 comments on commit 776c634

Please sign in to comment.