From dd1c57de2ed7200d44026993dc555e6b4ef58f42 Mon Sep 17 00:00:00 2001 From: Hendrik Meuwese <117160147+HMEUW@users.noreply.github.com> Date: Thu, 11 Jan 2024 08:44:37 +0100 Subject: [PATCH 1/3] First commit First phase of programming. Function can import an existing file now. Next step to test also other files (with other frequency, without x-y-location); and tests. --- hydropandas/io/soilinst.py | 129 +++++++++++++++++++++++++++++++++++++ hydropandas/observation.py | 40 ++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 hydropandas/io/soilinst.py diff --git a/hydropandas/io/soilinst.py b/hydropandas/io/soilinst.py new file mode 100644 index 00000000..0655d202 --- /dev/null +++ b/hydropandas/io/soilinst.py @@ -0,0 +1,129 @@ +import os +import zipfile + +import numpy as np +import pandas as pd + + +def read_soilinst_file( + path, + transform_coords=True, +): + """Read Soilinst file (XLE) + + Parameters + ---------- + path : str + path to Soilint file (.xle) + transform_coords : boolean + convert coordinates from WGS84 to RD + + Returns + ------- + df : pandas.DataFrame + DataFrame containing file content + metadata : dict, optional + dict containing metadata + """ + from pyproj import Transformer + + # open file + name = os.path.splitext(os.path.basename(path))[0] + if path.endswith(".xle"): + f = path + elif path.endswith(".zip"): + zf = zipfile.ZipFile(path) + f = zf.open("{}.xle".format(name)) + else: + raise NotImplementedError( + "File type '{}' not supported!".format(os.path.splitext(path)[-1]) + ) + + # read channel 1 data header + df_ch1_data_header = pd.read_xml( + path, + xpath="/Body_xle/Ch1_data_header" + ) + series_ch1_data_header = df_ch1_data_header.T.iloc[:, 0] + colname_ch1 = series_ch1_data_header.Identification.lower() + \ + '_' + series_ch1_data_header.Unit.lower() + + # read channel 2 data header + df_ch2_data_header = pd.read_xml( + path, + xpath="/Body_xle/Ch2_data_header" + ) + series_ch2_data_header = df_ch2_data_header.T.iloc[:, 0] + colname_ch2 = series_ch2_data_header.Identification.lower() + \ + '_' + series_ch2_data_header.Unit.lower() + + # read observations + df = pd.read_xml( + path, + xpath="/Body_xle/Data/Log", + ) + df.rename( + columns={'ch1': colname_ch1, + 'ch2': colname_ch2}, + inplace=True + ) + if 'ms' in df.columns: + df['date_time'] = pd.to_datetime( + df['Date'] + ' ' + df['Time']) + \ + pd.to_timedelta(df['ms'], unit='ms') + drop_cols = ['id', 'Date', 'Time', 'ms'] + else: + df['date_time'] = pd.to_datetime( + df['Date'] + ' ' + df['Time']) + drop_cols = ['id', 'Date', 'Time'] + df.set_index('date_time', inplace=True) + + df.drop(columns=drop_cols, inplace=True) + + # parse metadata into dict, per group in XLE file + metadata = {} + # read file info + df_file_info = pd.read_xml( + path, + xpath="/Body_xle/File_info" + ) + dict_file_info = df_file_info.T.iloc[:, 0].to_dict() + + # read instrument info + df_instrument_info = pd.read_xml( + path, + xpath="/Body_xle/Instrument_info" + ) + dict_instrument_info = df_instrument_info.T.iloc[:, 0].to_dict() + + # read instrument info + df_instrument_info_data_header = pd.read_xml( + path, + xpath="/Body_xle/Instrument_info_data_header" + ) + dict_instrument_info_data_header = df_instrument_info_data_header.T.iloc[ + :, 0].to_dict() + + metadata = {**dict_file_info, + **dict_instrument_info, + **dict_instrument_info_data_header} + + if transform_coords: + transformer = Transformer.from_crs("epsg:4326", "epsg:28992") + x, y = transformer.transform(metadata["Latitude"], metadata["Longtitude"]) + x = np.round(x, 2) + y = np.round(y, 2) + else: + x = metadata["Latitude"] + y = metadata["Longtitude"] + metadata["x"] = x + metadata["y"] = y + metadata["filename"] = f + metadata["source"] = metadata["Created_by"] + metadata["name"] = name + metadata["monitoring_well"] = name + metadata["unit"] = series_ch1_data_header.Unit.lower() + metadata["metadata_available"] = True + + return df, metadata + diff --git a/hydropandas/observation.py b/hydropandas/observation.py index 730e3882..6963fd59 100644 --- a/hydropandas/observation.py +++ b/hydropandas/observation.py @@ -777,6 +777,46 @@ def from_pastastore(cls, pstore, libname, name, metadata_mapping=None): return cls(data, meta=metadata, **kwargs) + @classmethod + def from_soilinst( + cls, + path, + transform_coords=True, + screen_bottom=None, screen_top=None, ground_level=None, + tube_nr=None, tube_top=None): + """Read data from Soilinst xle file. + + Parameters + ---------- + path : str + path to file (file can zip or xle) + + """ + from .io import soilinst + + df, meta = soilinst.read_soilinst_file( + path, + transform_coords=transform_coords + ) + + return cls( + df, + name=meta.pop("name"), + x=meta.pop("x"), + y=meta.pop("y"), + filename=meta.pop("filename"), + source=meta.pop("source"), + unit=meta.pop("unit"), + screen_bottom=screen_bottom, + screen_top=screen_top, + ground_level=ground_level, + metadata_available=meta.pop("metadata_available"), + monitoring_well=meta.pop("monitoring_well"), + tube_nr=tube_nr, + tube_top=tube_top, + meta=meta, + ) + class WaterQualityObs(Obs): """class for water quality ((grond)watersamenstelling) point From 88d4d9b9d48313d1a7d111b3c989773640e269d8 Mon Sep 17 00:00:00 2001 From: Hendrik Meuwese <117160147+HMEUW@users.noreply.github.com> Date: Thu, 11 Jan 2024 16:24:13 +0100 Subject: [PATCH 2/3] including test function Update typo in brandname, should be Solinst (thanks @MattBrst) --- hydropandas/io/{soilinst.py => solinst.py} | 63 +- hydropandas/observation.py | 8 +- .../WsNoo_dp366_BUB_20231222_slug1m.xle | 4164 +++++++++++++++++ .../example-10min-interval-via-laptop.xle | 229 + tests/test_013_solinst.py | 54 + 5 files changed, 4490 insertions(+), 28 deletions(-) rename hydropandas/io/{soilinst.py => solinst.py} (66%) create mode 100644 tests/data/2024-solinst-test/WsNoo_dp366_BUB_20231222_slug1m.xle create mode 100644 tests/data/2024-solinst-test/example-10min-interval-via-laptop.xle create mode 100644 tests/test_013_solinst.py diff --git a/hydropandas/io/soilinst.py b/hydropandas/io/solinst.py similarity index 66% rename from hydropandas/io/soilinst.py rename to hydropandas/io/solinst.py index 0655d202..a36fce86 100644 --- a/hydropandas/io/soilinst.py +++ b/hydropandas/io/solinst.py @@ -1,20 +1,22 @@ +import logging import os import zipfile import numpy as np import pandas as pd +logger = logging.getLogger(__name__) -def read_soilinst_file( +def read_solinst_file( path, transform_coords=True, ): - """Read Soilinst file (XLE) + """Read Solinst logger file (XLE) Parameters ---------- path : str - path to Soilint file (.xle) + path to Solinst file (.xle) transform_coords : boolean convert coordinates from WGS84 to RD @@ -22,8 +24,8 @@ def read_soilinst_file( ------- df : pandas.DataFrame DataFrame containing file content - metadata : dict, optional - dict containing metadata + meta : dict, optional + dict containing meta """ from pyproj import Transformer @@ -39,6 +41,8 @@ def read_soilinst_file( "File type '{}' not supported!".format(os.path.splitext(path)[-1]) ) + logger.info("reading -> {}".format(f)) + # read channel 1 data header df_ch1_data_header = pd.read_xml( path, @@ -80,8 +84,8 @@ def read_soilinst_file( df.drop(columns=drop_cols, inplace=True) - # parse metadata into dict, per group in XLE file - metadata = {} + # parse meta into dict, per group in XLE file + meta = {} # read file info df_file_info = pd.read_xml( path, @@ -104,26 +108,37 @@ def read_soilinst_file( dict_instrument_info_data_header = df_instrument_info_data_header.T.iloc[ :, 0].to_dict() - metadata = {**dict_file_info, + meta = {**dict_file_info, **dict_instrument_info, **dict_instrument_info_data_header} if transform_coords: - transformer = Transformer.from_crs("epsg:4326", "epsg:28992") - x, y = transformer.transform(metadata["Latitude"], metadata["Longtitude"]) - x = np.round(x, 2) - y = np.round(y, 2) + # lat and lon has 0,000 when location is not supplied + # replace comma with point first + if isinstance(meta["Latitude"], str): + meta["Latitude"] = float(meta["Latitude"].replace(',', '.')) + if isinstance(meta["Longtitude"], str): + meta["Longtitude"] = float(meta["Longtitude"].replace(',', '.')) + if (meta["Latitude"] != 0) & (meta["Longtitude"] != 0): + transformer = Transformer.from_crs("epsg:4326", "epsg:28992") + x, y = transformer.transform(meta["Latitude"], meta["Longtitude"]) + x = np.round(x, 2) + y = np.round(y, 2) + else: + logger.warning("file has no location included") + x = None + y = None else: - x = metadata["Latitude"] - y = metadata["Longtitude"] - metadata["x"] = x - metadata["y"] = y - metadata["filename"] = f - metadata["source"] = metadata["Created_by"] - metadata["name"] = name - metadata["monitoring_well"] = name - metadata["unit"] = series_ch1_data_header.Unit.lower() - metadata["metadata_available"] = True - - return df, metadata + x = meta["Latitude"] + y = meta["Longtitude"] + meta["x"] = x + meta["y"] = y + meta["filename"] = f + meta["source"] = meta["Created_by"] + meta["name"] = name + meta["monitoring_well"] = name + meta["unit"] = series_ch1_data_header.Unit.lower() + meta["metadata_available"] = True + + return df, meta diff --git a/hydropandas/observation.py b/hydropandas/observation.py index 6963fd59..36f6b157 100644 --- a/hydropandas/observation.py +++ b/hydropandas/observation.py @@ -778,13 +778,13 @@ def from_pastastore(cls, pstore, libname, name, metadata_mapping=None): return cls(data, meta=metadata, **kwargs) @classmethod - def from_soilinst( + def from_solinst( cls, path, transform_coords=True, screen_bottom=None, screen_top=None, ground_level=None, tube_nr=None, tube_top=None): - """Read data from Soilinst xle file. + """Read data from Solinst xle file. Parameters ---------- @@ -792,9 +792,9 @@ def from_soilinst( path to file (file can zip or xle) """ - from .io import soilinst + from .io import solinst - df, meta = soilinst.read_soilinst_file( + df, meta = solinst.read_solinst_file( path, transform_coords=transform_coords ) diff --git a/tests/data/2024-solinst-test/WsNoo_dp366_BUB_20231222_slug1m.xle b/tests/data/2024-solinst-test/WsNoo_dp366_BUB_20231222_slug1m.xle new file mode 100644 index 00000000..4124b10e --- /dev/null +++ b/tests/data/2024-solinst-test/WsNoo_dp366_BUB_20231222_slug1m.xle @@ -0,0 +1,4164 @@ + + + + + +2023/12/22 + + +iOS App Version 3.5.1 +iOS App Version 3.5.1 +iOS App Version 3.5.1 +Desktop Reader + + +L5_LT +M5 +Stopped +2170536 +3.50600 +1378.03 +1970/01/01 00:00:00 +2 +1.006 + + +20231123 +slugtest +51.4253 +3.91670 +12 +0 + +Slate +2 +0.000000 + +2023/12/22 10:16:37 +2023/12/22 10:17:50 +587 + + +LEVEL +m + + + + + +TEMPERATURE +°C + + + + +2023/12/22 + +0 +10.2388 +15.462 + + +2023/12/22 + +125 +10.2392 +15.462 + + +2023/12/22 + +250 +10.2389 +15.463 + + +2023/12/22 + +375 +10.2389 +15.464 + + +2023/12/22 + +500 +10.2390 +15.464 + + +2023/12/22 + +625 +10.2391 +15.466 + + +2023/12/22 + +750 +10.2389 +15.464 + + +2023/12/22 + +875 +10.2389 +15.463 + + +2023/12/22 + +0 +10.2389 +15.466 + + +2023/12/22 + +125 +10.2389 +15.466 + + +2023/12/22 + +250 +10.2392 +15.466 + + +2023/12/22 + +375 +10.2387 +15.466 + + +2023/12/22 + +500 +10.2390 +15.468 + + +2023/12/22 + +625 +10.2389 +15.467 + + +2023/12/22 + +750 +10.2389 +15.468 + + +2023/12/22 + +875 +10.2386 +15.465 + + +2023/12/22 + +0 +10.2388 +15.466 + + +2023/12/22 + +125 +10.2391 +15.467 + + +2023/12/22 + +250 +10.2388 +15.468 + + +2023/12/22 + +375 +10.2388 +15.466 + + +2023/12/22 + +500 +10.2387 +15.468 + + +2023/12/22 + +625 +10.2390 +15.469 + + +2023/12/22 + +750 +10.2389 +15.467 + + +2023/12/22 + +875 +10.2390 +15.468 + + +2023/12/22 + +0 +10.2390 +15.467 + + +2023/12/22 + +125 +10.2391 +15.469 + + +2023/12/22 + +250 +10.2390 +15.470 + + +2023/12/22 + +375 +10.2392 +15.470 + + +2023/12/22 + +500 +10.2391 +15.471 + + +2023/12/22 + +625 +10.2391 +15.469 + + +2023/12/22 + +750 +10.2392 +15.471 + + +2023/12/22 + +875 +10.2393 +15.471 + + +2023/12/22 + +0 +10.2392 +15.471 + + +2023/12/22 + +125 +10.2392 +15.471 + + +2023/12/22 + +250 +10.2391 +15.469 + + +2023/12/22 + +375 +10.2393 +15.470 + + +2023/12/22 + +500 +10.2392 +15.472 + + +2023/12/22 + +625 +10.2392 +15.471 + + +2023/12/22 + +750 +10.2393 +15.474 + + +2023/12/22 + +875 +10.2393 +15.473 + + +2023/12/22 + +0 +10.2394 +15.473 + + +2023/12/22 + +125 +10.2393 +15.473 + + +2023/12/22 + +250 +10.2393 +15.473 + + +2023/12/22 + +375 +10.2392 +15.474 + + +2023/12/22 + +500 +10.2393 +15.474 + + +2023/12/22 + +625 +10.2393 +15.476 + + +2023/12/22 + +750 +10.2394 +15.476 + + +2023/12/22 + +875 +10.2394 +15.474 + + +2023/12/22 + +0 +10.2394 +15.475 + + +2023/12/22 + +125 +10.2395 +15.478 + + +2023/12/22 + +250 +10.2394 +15.475 + + +2023/12/22 + +375 +10.2395 +15.474 + + +2023/12/22 + +500 +10.2396 +15.476 + + +2023/12/22 + +625 +10.2395 +15.477 + + +2023/12/22 + +750 +10.2395 +15.477 + + +2023/12/22 + +875 +10.2393 +15.476 + + +2023/12/22 + +0 +10.2394 +15.477 + + +2023/12/22 + +125 +10.2394 +15.479 + + +2023/12/22 + +250 +10.2396 +15.478 + + +2023/12/22 + +375 +10.2394 +15.478 + + +2023/12/22 + +500 +10.2392 +15.478 + + +2023/12/22 + +625 +10.2393 +15.478 + + +2023/12/22 + +750 +10.2394 +15.481 + + +2023/12/22 + +875 +10.2396 +15.478 + + +2023/12/22 + +0 +10.2394 +15.479 + + +2023/12/22 + +125 +10.2393 +15.479 + + +2023/12/22 + +250 +10.2391 +15.481 + + +2023/12/22 + +375 +10.2391 +15.481 + + +2023/12/22 + +500 +10.2391 +15.479 + + +2023/12/22 + +625 +10.2391 +15.481 + + +2023/12/22 + +750 +10.2390 +15.479 + + +2023/12/22 + +875 +10.2390 +15.481 + + +2023/12/22 + +0 +10.2391 +15.483 + + +2023/12/22 + +125 +10.2389 +15.482 + + +2023/12/22 + +250 +10.2386 +15.482 + + +2023/12/22 + +375 +10.2388 +15.482 + + +2023/12/22 + +500 +10.2389 +15.483 + + +2023/12/22 + +625 +10.2389 +15.483 + + +2023/12/22 + +750 +10.2386 +15.483 + + +2023/12/22 + +875 +10.2384 +15.485 + + +2023/12/22 + +0 +10.2387 +15.485 + + +2023/12/22 + +125 +10.2385 +15.484 + + +2023/12/22 + +250 +10.2386 +15.485 + + +2023/12/22 + +375 +10.2387 +15.485 + + +2023/12/22 + +500 +10.2390 +15.485 + + +2023/12/22 + +625 +10.2388 +15.485 + + +2023/12/22 + +750 +10.2390 +15.487 + + +2023/12/22 + +875 +10.2388 +15.487 + + +2023/12/22 + +0 +10.2390 +15.488 + + +2023/12/22 + +125 +10.2392 +15.486 + + +2023/12/22 + +250 +10.2391 +15.486 + + +2023/12/22 + +375 +10.2390 +15.489 + + +2023/12/22 + +500 +10.2390 +15.488 + + +2023/12/22 + +625 +10.2389 +15.486 + + +2023/12/22 + +750 +10.2390 +15.488 + + +2023/12/22 + +875 +10.2393 +15.488 + + +2023/12/22 + +0 +10.2389 +15.491 + + +2023/12/22 + +125 +10.2391 +15.491 + + +2023/12/22 + +250 +10.2390 +15.490 + + +2023/12/22 + +375 +10.2392 +15.489 + + +2023/12/22 + +500 +10.2391 +15.489 + + +2023/12/22 + +625 +10.2392 +15.490 + + +2023/12/22 + +750 +10.2392 +15.492 + + +2023/12/22 + +875 +10.2391 +15.490 + + +2023/12/22 + +0 +10.2390 +15.491 + + +2023/12/22 + +125 +10.2392 +15.491 + + +2023/12/22 + +250 +10.2391 +15.491 + + +2023/12/22 + +375 +10.2391 +15.491 + + +2023/12/22 + +500 +10.2389 +15.493 + + +2023/12/22 + +625 +10.2391 +15.493 + + +2023/12/22 + +750 +10.2390 +15.492 + + +2023/12/22 + +875 +10.2388 +15.494 + + +2023/12/22 + +0 +10.2390 +15.494 + + +2023/12/22 + +125 +10.2390 +15.496 + + +2023/12/22 + +250 +10.2389 +15.495 + + +2023/12/22 + +375 +10.2390 +15.496 + + +2023/12/22 + +500 +10.2390 +15.495 + + +2023/12/22 + +625 +10.2389 +15.496 + + +2023/12/22 + +750 +10.2392 +15.495 + + +2023/12/22 + +875 +10.2391 +15.494 + + +2023/12/22 + +0 +10.2387 +15.497 + + +2023/12/22 + +125 +10.2386 +15.495 + + +2023/12/22 + +250 +10.2389 +15.497 + + +2023/12/22 + +375 +10.2390 +15.498 + + +2023/12/22 + +500 +10.2390 +15.497 + + +2023/12/22 + +625 +10.2391 +15.497 + + +2023/12/22 + +750 +10.2392 +15.497 + + +2023/12/22 + +875 +10.2391 +15.498 + + +2023/12/22 + +0 +10.2390 +15.498 + + +2023/12/22 + +125 +10.2391 +15.499 + + +2023/12/22 + +250 +10.2388 +15.499 + + +2023/12/22 + +375 +10.2390 +15.500 + + +2023/12/22 + +500 +10.2389 +15.498 + + +2023/12/22 + +625 +10.2395 +15.501 + + +2023/12/22 + +750 +10.2393 +15.501 + + +2023/12/22 + +875 +10.2391 +15.500 + + +2023/12/22 + +0 +10.2392 +15.502 + + +2023/12/22 + +125 +10.2391 +15.502 + + +2023/12/22 + +250 +10.2394 +15.503 + + +2023/12/22 + +375 +10.2390 +15.501 + + +2023/12/22 + +500 +10.2389 +15.504 + + +2023/12/22 + +625 +10.2389 +15.501 + + +2023/12/22 + +750 +10.2390 +15.502 + + +2023/12/22 + +875 +10.2389 +15.503 + + +2023/12/22 + +0 +10.2387 +15.504 + + +2023/12/22 + +125 +10.2390 +15.504 + + +2023/12/22 + +250 +10.2389 +15.504 + + +2023/12/22 + +375 +10.2389 +15.503 + + +2023/12/22 + +500 +10.2391 +15.504 + + +2023/12/22 + +625 +10.2389 +15.504 + + +2023/12/22 + +750 +10.2391 +15.503 + + +2023/12/22 + +875 +10.2391 +15.507 + + +2023/12/22 + +0 +10.2393 +15.508 + + +2023/12/22 + +125 +10.2390 +15.507 + + +2023/12/22 + +250 +10.2392 +15.506 + + +2023/12/22 + +375 +10.2392 +15.506 + + +2023/12/22 + +500 +10.2391 +15.509 + + +2023/12/22 + +625 +10.2393 +15.506 + + +2023/12/22 + +750 +10.2391 +15.507 + + +2023/12/22 + +875 +10.2392 +15.508 + + +2023/12/22 + +0 +10.2391 +15.509 + + +2023/12/22 + +125 +10.2392 +15.509 + + +2023/12/22 + +250 +10.2391 +15.510 + + +2023/12/22 + +375 +10.2392 +15.509 + + +2023/12/22 + +500 +10.2396 +15.511 + + +2023/12/22 + +625 +10.2392 +15.510 + + +2023/12/22 + +750 +10.2392 +15.509 + + +2023/12/22 + +875 +10.2392 +15.510 + + +2023/12/22 + +0 +10.2394 +15.511 + + +2023/12/22 + +125 +10.2394 +15.512 + + +2023/12/22 + +250 +10.2394 +15.513 + + +2023/12/22 + +375 +10.2395 +15.512 + + +2023/12/22 + +500 +10.2394 +15.511 + + +2023/12/22 + +625 +10.2393 +15.512 + + +2023/12/22 + +750 +10.2393 +15.511 + + +2023/12/22 + +875 +10.2395 +15.512 + + +2023/12/22 + +0 +10.2394 +15.514 + + +2023/12/22 + +125 +10.2394 +15.514 + + +2023/12/22 + +250 +10.2394 +15.513 + + +2023/12/22 + +375 +10.2394 +15.515 + + +2023/12/22 + +500 +10.2393 +15.514 + + +2023/12/22 + +625 +10.2394 +15.515 + + +2023/12/22 + +750 +10.2393 +15.514 + + +2023/12/22 + +875 +10.2392 +15.514 + + +2023/12/22 + +0 +10.2393 +15.517 + + +2023/12/22 + +125 +10.2393 +15.516 + + +2023/12/22 + +250 +10.2391 +15.518 + + +2023/12/22 + +375 +10.2393 +15.518 + + +2023/12/22 + +500 +10.2392 +15.517 + + +2023/12/22 + +625 +10.2391 +15.517 + + +2023/12/22 + +750 +10.2392 +15.517 + + +2023/12/22 + +875 +10.2393 +15.518 + + +2023/12/22 + +0 +10.2392 +15.517 + + +2023/12/22 + +125 +10.2394 +15.519 + + +2023/12/22 + +250 +10.2392 +15.520 + + +2023/12/22 + +375 +10.2392 +15.520 + + +2023/12/22 + +500 +10.2393 +15.521 + + +2023/12/22 + +625 +10.2392 +15.519 + + +2023/12/22 + +750 +10.2393 +15.522 + + +2023/12/22 + +875 +10.2394 +15.521 + + +2023/12/22 + +0 +10.2392 +15.520 + + +2023/12/22 + +125 +10.2393 +15.521 + + +2023/12/22 + +250 +10.2394 +15.521 + + +2023/12/22 + +375 +10.2394 +15.522 + + +2023/12/22 + +500 +10.2393 +15.521 + + +2023/12/22 + +625 +10.2391 +15.524 + + +2023/12/22 + +750 +10.2390 +15.522 + + +2023/12/22 + +875 +10.2392 +15.525 + + +2023/12/22 + +0 +10.2395 +15.526 + + +2023/12/22 + +125 +10.2396 +15.523 + + +2023/12/22 + +250 +10.2394 +15.524 + + +2023/12/22 + +375 +10.2394 +15.526 + + +2023/12/22 + +500 +10.2394 +15.524 + + +2023/12/22 + +625 +10.2394 +15.524 + + +2023/12/22 + +750 +10.2394 +15.525 + + +2023/12/22 + +875 +10.2394 +15.527 + + +2023/12/22 + +0 +10.2397 +15.525 + + +2023/12/22 + +125 +10.2391 +15.526 + + +2023/12/22 + +250 +10.2391 +15.527 + + +2023/12/22 + +375 +10.2390 +15.526 + + +2023/12/22 + +500 +10.2389 +15.526 + + +2023/12/22 + +625 +10.2389 +15.528 + + +2023/12/22 + +750 +10.2390 +15.527 + + +2023/12/22 + +875 +10.2390 +15.529 + + +2023/12/22 + +0 +10.2387 +15.528 + + +2023/12/22 + +125 +10.2389 +15.530 + + +2023/12/22 + +250 +10.2389 +15.530 + + +2023/12/22 + +375 +10.2389 +15.528 + + +2023/12/22 + +500 +10.2388 +15.530 + + +2023/12/22 + +625 +10.2389 +15.529 + + +2023/12/22 + +750 +10.2386 +15.531 + + +2023/12/22 + +875 +10.2386 +15.532 + + +2023/12/22 + +0 +10.2385 +15.532 + + +2023/12/22 + +125 +10.2392 +15.532 + + +2023/12/22 + +250 +10.2392 +15.532 + + +2023/12/22 + +375 +10.2392 +15.532 + + +2023/12/22 + +500 +10.2391 +15.534 + + +2023/12/22 + +625 +10.2391 +15.531 + + +2023/12/22 + +750 +10.2391 +15.533 + + +2023/12/22 + +875 +10.2395 +15.532 + + +2023/12/22 + +0 +10.2395 +15.534 + + +2023/12/22 + +125 +10.2395 +15.533 + + +2023/12/22 + +250 +10.2395 +15.535 + + +2023/12/22 + +375 +10.2395 +15.536 + + +2023/12/22 + +500 +10.2394 +15.536 + + +2023/12/22 + +625 +10.2395 +15.535 + + +2023/12/22 + +750 +10.2397 +15.536 + + +2023/12/22 + +875 +10.2398 +15.535 + + +2023/12/22 + +0 +10.2396 +15.537 + + +2023/12/22 + +125 +10.2392 +15.537 + + +2023/12/22 + +250 +10.2388 +15.536 + + +2023/12/22 + +375 +10.2393 +15.537 + + +2023/12/22 + +500 +10.2395 +15.537 + + +2023/12/22 + +625 +10.2395 +15.536 + + +2023/12/22 + +750 +10.2401 +15.538 + + +2023/12/22 + +875 +10.2403 +15.538 + + +2023/12/22 + +0 +10.2405 +15.538 + + +2023/12/22 + +125 +10.2400 +15.539 + + +2023/12/22 + +250 +10.2403 +15.540 + + +2023/12/22 + +375 +10.2402 +15.539 + + +2023/12/22 + +500 +10.2402 +15.540 + + +2023/12/22 + +625 +10.2400 +15.540 + + +2023/12/22 + +750 +10.2399 +15.541 + + +2023/12/22 + +875 +10.2401 +15.540 + + +2023/12/22 + +0 +10.2398 +15.541 + + +2023/12/22 + +125 +10.2401 +15.541 + + +2023/12/22 + +250 +10.2404 +15.542 + + +2023/12/22 + +375 +10.2401 +15.541 + + +2023/12/22 + +500 +10.2403 +15.542 + + +2023/12/22 + +625 +10.2399 +15.542 + + +2023/12/22 + +750 +10.2401 +15.542 + + +2023/12/22 + +875 +10.2400 +15.542 + + +2023/12/22 + +0 +10.2400 +15.544 + + +2023/12/22 + +125 +10.2400 +15.544 + + +2023/12/22 + +250 +10.2397 +15.544 + + +2023/12/22 + +375 +10.2399 +15.546 + + +2023/12/22 + +500 +10.2399 +15.545 + + +2023/12/22 + +625 +10.2398 +15.545 + + +2023/12/22 + +750 +10.2398 +15.546 + + +2023/12/22 + +875 +10.2397 +15.546 + + +2023/12/22 + +0 +10.2395 +15.546 + + +2023/12/22 + +125 +10.2396 +15.545 + + +2023/12/22 + +250 +10.2397 +15.547 + + +2023/12/22 + +375 +10.2397 +15.546 + + +2023/12/22 + +500 +10.2396 +15.548 + + +2023/12/22 + +625 +10.2397 +15.549 + + +2023/12/22 + +750 +10.2397 +15.547 + + +2023/12/22 + +875 +10.2397 +15.549 + + +2023/12/22 + +0 +10.2395 +15.548 + + +2023/12/22 + +125 +10.2395 +15.549 + + +2023/12/22 + +250 +10.2395 +15.548 + + +2023/12/22 + +375 +10.2398 +15.550 + + +2023/12/22 + +500 +10.2397 +15.550 + + +2023/12/22 + +625 +10.2397 +15.550 + + +2023/12/22 + +750 +10.2398 +15.551 + + +2023/12/22 + +875 +10.2396 +15.549 + + +2023/12/22 + +0 +10.2398 +15.552 + + +2023/12/22 + +125 +10.2398 +15.552 + + +2023/12/22 + +250 +10.2396 +15.552 + + +2023/12/22 + +375 +10.2396 +15.552 + + +2023/12/22 + +500 +10.2397 +15.552 + + +2023/12/22 + +625 +10.2397 +15.552 + + +2023/12/22 + +750 +10.2398 +15.552 + + +2023/12/22 + +875 +10.2397 +15.552 + + +2023/12/22 + +0 +10.2398 +15.553 + + +2023/12/22 + +125 +10.2399 +15.553 + + +2023/12/22 + +250 +10.2397 +15.554 + + +2023/12/22 + +375 +10.2397 +15.554 + + +2023/12/22 + +500 +10.2398 +15.555 + + +2023/12/22 + +625 +10.2398 +15.553 + + +2023/12/22 + +750 +10.2396 +15.556 + + +2023/12/22 + +875 +10.2396 +15.555 + + +2023/12/22 + +0 +10.2396 +15.554 + + +2023/12/22 + +125 +10.2398 +15.555 + + +2023/12/22 + +250 +10.2398 +15.556 + + +2023/12/22 + +375 +10.2396 +15.556 + + +2023/12/22 + +500 +10.2395 +15.554 + + +2023/12/22 + +625 +10.2402 +15.559 + + +2023/12/22 + +750 +10.2403 +15.559 + + +2023/12/22 + +875 +10.2400 +15.558 + + +2023/12/22 + +0 +10.2400 +15.557 + + +2023/12/22 + +125 +10.2398 +15.557 + + +2023/12/22 + +250 +10.2398 +15.557 + + +2023/12/22 + +375 +10.2399 +15.558 + + +2023/12/22 + +500 +10.2399 +15.558 + + +2023/12/22 + +625 +10.2399 +15.558 + + +2023/12/22 + +750 +10.2396 +15.560 + + +2023/12/22 + +875 +10.2398 +15.560 + + +2023/12/22 + +0 +10.2397 +15.559 + + +2023/12/22 + +125 +10.2399 +15.559 + + +2023/12/22 + +250 +10.2399 +15.561 + + +2023/12/22 + +375 +10.2398 +15.561 + + +2023/12/22 + +500 +10.2399 +15.562 + + +2023/12/22 + +625 +10.2398 +15.562 + + +2023/12/22 + +750 +10.2397 +15.561 + + +2023/12/22 + +875 +10.2398 +15.562 + + +2023/12/22 + +0 +10.2397 +15.563 + + +2023/12/22 + +125 +10.2399 +15.562 + + +2023/12/22 + +250 +10.2399 +15.563 + + +2023/12/22 + +375 +10.2399 +15.562 + + +2023/12/22 + +500 +10.2400 +15.562 + + +2023/12/22 + +625 +10.2397 +15.564 + + +2023/12/22 + +750 +10.2399 +15.563 + + +2023/12/22 + +875 +10.2399 +15.565 + + +2023/12/22 + +0 +10.2399 +15.562 + + +2023/12/22 + +125 +10.2400 +15.562 + + +2023/12/22 + +250 +10.2398 +15.565 + + +2023/12/22 + +375 +10.2398 +15.564 + + +2023/12/22 + +500 +10.2398 +15.564 + + +2023/12/22 + +625 +10.2398 +15.565 + + +2023/12/22 + +750 +10.2399 +15.565 + + +2023/12/22 + +875 +10.2400 +15.566 + + +2023/12/22 + +0 +10.2399 +15.565 + + +2023/12/22 + +125 +10.2399 +15.564 + + +2023/12/22 + +250 +10.2399 +15.564 + + +2023/12/22 + +375 +10.2397 +15.565 + + +2023/12/22 + +500 +10.2397 +15.566 + + +2023/12/22 + +625 +10.2397 +15.562 + + +2023/12/22 + +750 +10.2397 +15.566 + + +2023/12/22 + +875 +10.2398 +15.567 + + +2023/12/22 + +0 +10.2398 +15.566 + + +2023/12/22 + +125 +10.2399 +15.568 + + +2023/12/22 + +250 +10.2397 +15.567 + + +2023/12/22 + +375 +10.2396 +15.567 + + +2023/12/22 + +500 +10.2397 +15.568 + + +2023/12/22 + +625 +10.2398 +15.567 + + +2023/12/22 + +750 +10.2394 +15.567 + + +2023/12/22 + +875 +10.2396 +15.569 + + +2023/12/22 + +0 +10.2395 +15.568 + + +2023/12/22 + +125 +10.2395 +15.569 + + +2023/12/22 + +250 +10.2397 +15.567 + + +2023/12/22 + +375 +10.2396 +15.565 + + +2023/12/22 + +500 +10.2396 +15.568 + + +2023/12/22 + +625 +10.2395 +15.566 + + +2023/12/22 + +750 +10.2395 +15.570 + + +2023/12/22 + +875 +10.2395 +15.568 + + +2023/12/22 + +0 +10.2395 +15.568 + + +2023/12/22 + +125 +10.2396 +15.569 + + +2023/12/22 + +250 +10.2395 +15.568 + + +2023/12/22 + +375 +10.2395 +15.568 + + +2023/12/22 + +500 +10.2394 +15.570 + + +2023/12/22 + +625 +10.2395 +15.569 + + +2023/12/22 + +750 +10.2391 +15.572 + + +2023/12/22 + +875 +10.2394 +15.570 + + +2023/12/22 + +0 +10.2395 +15.568 + + +2023/12/22 + +125 +10.2394 +15.569 + + +2023/12/22 + +250 +10.2393 +15.571 + + +2023/12/22 + +375 +10.2393 +15.569 + + +2023/12/22 + +500 +10.2395 +15.569 + + +2023/12/22 + +625 +10.2397 +15.570 + + +2023/12/22 + +750 +10.2394 +15.569 + + +2023/12/22 + +875 +10.2396 +15.571 + + +2023/12/22 + +0 +10.2396 +15.571 + + +2023/12/22 + +125 +10.2396 +15.571 + + +2023/12/22 + +250 +10.2398 +15.573 + + +2023/12/22 + +375 +10.2395 +15.571 + + +2023/12/22 + +500 +10.2395 +15.571 + + +2023/12/22 + +625 +10.2394 +15.570 + + +2023/12/22 + +750 +10.2393 +15.571 + + +2023/12/22 + +875 +10.2393 +15.571 + + +2023/12/22 + +0 +10.2396 +15.571 + + +2023/12/22 + +125 +10.2395 +15.571 + + +2023/12/22 + +250 +10.2395 +15.571 + + +2023/12/22 + +375 +10.2394 +15.571 + + +2023/12/22 + +500 +10.2394 +15.572 + + +2023/12/22 + +625 +10.2396 +15.573 + + +2023/12/22 + +750 +10.2395 +15.573 + + +2023/12/22 + +875 +10.2395 +15.572 + + +2023/12/22 + +0 +10.2396 +15.572 + + +2023/12/22 + +125 +10.2396 +15.573 + + +2023/12/22 + +250 +10.2395 +15.572 + + +2023/12/22 + +375 +10.2397 +15.573 + + +2023/12/22 + +500 +10.2400 +15.571 + + +2023/12/22 + +625 +10.2400 +15.574 + + +2023/12/22 + +750 +10.2398 +15.571 + + +2023/12/22 + +875 +10.2397 +15.574 + + +2023/12/22 + +0 +10.2400 +15.573 + + +2023/12/22 + +125 +10.2396 +15.573 + + +2023/12/22 + +250 +10.2398 +15.573 + + +2023/12/22 + +375 +10.2398 +15.574 + + +2023/12/22 + +500 +10.2397 +15.574 + + +2023/12/22 + +625 +10.2397 +15.574 + + +2023/12/22 + +750 +10.2398 +15.574 + + +2023/12/22 + +875 +10.2397 +15.574 + + +2023/12/22 + +0 +10.2397 +15.573 + + +2023/12/22 + +125 +10.2398 +15.575 + + +2023/12/22 + +250 +10.2396 +15.573 + + +2023/12/22 + +375 +10.2397 +15.573 + + +2023/12/22 + +500 +10.2397 +15.575 + + +2023/12/22 + +625 +10.2399 +15.574 + + +2023/12/22 + +750 +10.2397 +15.573 + + +2023/12/22 + +875 +10.2397 +15.575 + + +2023/12/22 + +0 +10.2397 +15.575 + + +2023/12/22 + +125 +10.2396 +15.576 + + +2023/12/22 + +250 +10.2396 +15.576 + + +2023/12/22 + +375 +10.2400 +15.576 + + +2023/12/22 + +500 +10.2398 +15.576 + + +2023/12/22 + +625 +10.2398 +15.576 + + +2023/12/22 + +750 +10.2400 +15.576 + + +2023/12/22 + +875 +10.2400 +15.577 + + +2023/12/22 + +0 +10.2401 +15.576 + + +2023/12/22 + +125 +10.2400 +15.575 + + +2023/12/22 + +250 +10.2402 +15.575 + + +2023/12/22 + +375 +10.2402 +15.576 + + +2023/12/22 + +500 +10.2401 +15.577 + + +2023/12/22 + +625 +10.2401 +15.577 + + +2023/12/22 + +750 +10.2401 +15.577 + + +2023/12/22 + +875 +10.2402 +15.576 + + +2023/12/22 + +0 +10.2400 +15.577 + + +2023/12/22 + +125 +10.2401 +15.577 + + +2023/12/22 + +250 +10.2400 +15.576 + + +2023/12/22 + +375 +10.2398 +15.577 + + +2023/12/22 + +500 +10.2399 +15.577 + + +2023/12/22 + +625 +10.2400 +15.576 + + +2023/12/22 + +750 +10.2397 +15.578 + + +2023/12/22 + +875 +10.2394 +15.578 + + +2023/12/22 + +0 +10.2392 +15.578 + + +2023/12/22 + +125 +10.2394 +15.577 + + +2023/12/22 + +250 +10.2395 +15.578 + + +2023/12/22 + +375 +10.2393 +15.577 + + +2023/12/22 + +500 +10.2397 +15.578 + + +2023/12/22 + +625 +10.2400 +15.576 + + +2023/12/22 + +750 +10.2402 +15.579 + + +2023/12/22 + +875 +10.2400 +15.577 + + +2023/12/22 + +0 +10.2401 +15.576 + + +2023/12/22 + +125 +10.2400 +15.578 + + +2023/12/22 + +250 +10.2400 +15.578 + + +2023/12/22 + +375 +10.2397 +15.578 + + +2023/12/22 + +500 +10.2394 +15.579 + + +2023/12/22 + +625 +10.2394 +15.578 + + +2023/12/22 + +750 +10.2396 +15.581 + + +2023/12/22 + +875 +10.2398 +15.578 + + +2023/12/22 + +0 +10.2399 +15.578 + + +2023/12/22 + +125 +10.2398 +15.577 + + +2023/12/22 + +250 +10.2400 +15.580 + + +2023/12/22 + +375 +10.2401 +15.579 + + +2023/12/22 + +500 +10.2402 +15.579 + + +2023/12/22 + +625 +10.2401 +15.578 + + +2023/12/22 + +750 +10.2400 +15.577 + + +2023/12/22 + +875 +10.2399 +15.579 + + +2023/12/22 + +0 +10.2397 +15.579 + + +2023/12/22 + +125 +10.2396 +15.579 + + +2023/12/22 + +250 +10.2398 +15.581 + + +2023/12/22 + +375 +10.2397 +15.581 + + +2023/12/22 + +500 +10.2396 +15.578 + + +2023/12/22 + +625 +10.2397 +15.578 + + +2023/12/22 + +750 +10.2397 +15.579 + + +2023/12/22 + +875 +10.2396 +15.580 + + +2023/12/22 + +0 +10.2395 +15.579 + + +2023/12/22 + +125 +10.2399 +15.580 + + +2023/12/22 + +250 +10.2399 +15.581 + + +2023/12/22 + +375 +10.2400 +15.580 + + +2023/12/22 + +500 +10.2399 +15.581 + + +2023/12/22 + +625 +10.2401 +15.580 + + +2023/12/22 + +750 +10.2402 +15.580 + + +2023/12/22 + +875 +10.2404 +15.581 + + +2023/12/22 + +0 +10.2407 +15.581 + + +2023/12/22 + +125 +10.2405 +15.581 + + +2023/12/22 + +250 +10.2404 +15.581 + + +2023/12/22 + +375 +10.2404 +15.581 + + +2023/12/22 + +500 +10.2406 +15.580 + + +2023/12/22 + +625 +10.2410 +15.580 + + +2023/12/22 + +750 +10.2409 +15.579 + + +2023/12/22 + +875 +10.2409 +15.579 + + +2023/12/22 + +0 +10.2408 +15.580 + + +2023/12/22 + +125 +10.2414 +15.581 + + +2023/12/22 + +250 +10.2415 +15.579 + + +2023/12/22 + +375 +10.2415 +15.580 + + +2023/12/22 + +500 +10.2417 +15.579 + + +2023/12/22 + +625 +10.2418 +15.580 + + +2023/12/22 + +750 +10.2414 +15.579 + + +2023/12/22 + +875 +10.2415 +15.580 + + +2023/12/22 + +0 +10.2418 +15.579 + + +2023/12/22 + +125 +10.2416 +15.580 + + +2023/12/22 + +250 +10.2415 +15.580 + + +2023/12/22 + +375 +10.2418 +15.581 + + +2023/12/22 + +500 +10.2420 +15.580 + + +2023/12/22 + +625 +10.2419 +15.581 + + +2023/12/22 + +750 +10.2420 +15.580 + + +2023/12/22 + +875 +10.2417 +15.580 + + +2023/12/22 + +0 +10.2416 +15.581 + + +2023/12/22 + +125 +10.2413 +15.577 + + +2023/12/22 + +250 +10.2415 +15.582 + + +2023/12/22 + +375 +10.2415 +15.580 + + +2023/12/22 + +500 +10.2413 +15.580 + + +2023/12/22 + +625 +10.2414 +15.578 + + +2023/12/22 + +750 +10.2412 +15.581 + + +2023/12/22 + +875 +10.2411 +15.578 + + +2023/12/22 + +0 +10.2408 +15.580 + + +2023/12/22 + +125 +10.2407 +15.579 + + +2023/12/22 + +250 +10.2404 +15.578 + + +2023/12/22 + +375 +10.2404 +15.578 + + +2023/12/22 + +500 +10.2401 +15.578 + + +2023/12/22 + +625 +10.2402 +15.579 + + +2023/12/22 + +750 +10.2400 +15.578 + + +2023/12/22 + +875 +10.2402 +15.579 + + +2023/12/22 + +0 +10.2407 +15.581 + + +2023/12/22 + +125 +10.2448 +15.579 + + +2023/12/22 + +250 +10.2389 +15.579 + + +2023/12/22 + +375 +10.2394 +15.579 + + +2023/12/22 + +500 +10.2397 +15.578 + + +2023/12/22 + +625 +10.2398 +15.580 + + +2023/12/22 + +750 +10.2399 +15.578 + + +2023/12/22 + +875 +10.2397 +15.579 + + +2023/12/22 + +0 +10.2398 +15.578 + + +2023/12/22 + +125 +10.2398 +15.580 + + +2023/12/22 + +250 +10.2397 +15.578 + + +2023/12/22 + +375 +10.2396 +15.578 + + +2023/12/22 + +500 +10.2397 +15.579 + + +2023/12/22 + +625 +10.2396 +15.576 + + +2023/12/22 + +750 +10.2394 +15.579 + + +2023/12/22 + +875 +10.2395 +15.577 + + +2023/12/22 + +0 +10.2396 +15.579 + + +2023/12/22 + +125 +10.2394 +15.577 + + +2023/12/22 + +250 +10.2394 +15.576 + + +2023/12/22 + +375 +10.2395 +15.577 + + +2023/12/22 + +500 +10.2394 +15.578 + + +2023/12/22 + +625 +10.2392 +15.577 + + +2023/12/22 + +750 +10.2392 +15.578 + + +2023/12/22 + +875 +10.2390 +15.578 + + +2023/12/22 + +0 +10.2394 +15.578 + + +2023/12/22 + +125 +10.2392 +15.578 + + +2023/12/22 + +250 +10.2391 +15.578 + + +2023/12/22 + +375 +10.2391 +15.575 + + +2023/12/22 + +500 +10.2392 +15.579 + + +2023/12/22 + +625 +10.2392 +15.577 + + +2023/12/22 + +750 +10.2390 +15.577 + + +2023/12/22 + +875 +10.2390 +15.576 + + +2023/12/22 + +0 +10.2390 +15.575 + + +2023/12/22 + +125 +10.2391 +15.575 + + +2023/12/22 + +250 +10.2392 +15.577 + + +2023/12/22 + +375 +10.2393 +15.575 + + +2023/12/22 + +500 +10.2391 +15.578 + + +2023/12/22 + +625 +10.2393 +15.577 + + +2023/12/22 + +750 +10.2391 +15.576 + + +2023/12/22 + +875 +10.2392 +15.577 + + +2023/12/22 + +0 +10.2392 +15.577 + + +2023/12/22 + +125 +10.2391 +15.576 + + +2023/12/22 + +250 +10.2392 +15.576 + + +2023/12/22 + +375 +10.2391 +15.576 + + +2023/12/22 + +500 +10.2391 +15.577 + + +2023/12/22 + +625 +10.2391 +15.575 + + +2023/12/22 + +750 +10.2391 +15.576 + + +2023/12/22 + +875 +10.2392 +15.577 + + +2023/12/22 + +0 +10.2389 +15.578 + + +2023/12/22 + +125 +10.2387 +15.576 + + +2023/12/22 + +250 +10.2390 +15.578 + + + diff --git a/tests/data/2024-solinst-test/example-10min-interval-via-laptop.xle b/tests/data/2024-solinst-test/example-10min-interval-via-laptop.xle new file mode 100644 index 00000000..5178224b --- /dev/null +++ b/tests/data/2024-solinst-test/example-10min-interval-via-laptop.xle @@ -0,0 +1,229 @@ + + + + + + 2024/01/11 + + + Version 4.6.3 + Version 4.6.3 + PC Software 4.6.2 + Desktop Reader (567751) + + + L5_LT + M5 + Stopped + 2170536 + 3,59600 + 1372,54 + 2 + 1,006 + + + 20231123 + slugtest + 0,000 + 0,000 + 60000 + 0 + + Slate + 1 + 0,000000 + + 2024/01/11 11:00:00 + 2024/01/11 15:00:00 + 25 + + + LEVEL + m + + + + + + TEMPERATURE + °C + + + + + 2024/01/11 + + 0 + 10.5288 + 21.879 + + + 2024/01/11 + + 0 + 10.5300 + 21.585 + + + 2024/01/11 + + 0 + 10.5319 + 21.403 + + + 2024/01/11 + + 0 + 10.5343 + 21.285 + + + 2024/01/11 + + 0 + 10.5339 + 21.205 + + + 2024/01/11 + + 0 + 10.5329 + 21.177 + + + 2024/01/11 + + 0 + 10.5335 + 21.204 + + + 2024/01/11 + + 0 + 10.5323 + 21.258 + + + 2024/01/11 + + 0 + 10.5319 + 21.311 + + + 2024/01/11 + + 0 + 10.5323 + 21.429 + + + 2024/01/11 + + 0 + 10.5320 + 21.474 + + + 2024/01/11 + + 0 + 10.5333 + 21.469 + + + 2024/01/11 + + 0 + 10.5341 + 21.424 + + + 2024/01/11 + + 0 + 10.5350 + 21.394 + + + 2024/01/11 + + 0 + 10.5344 + 21.412 + + + 2024/01/11 + + 0 + 10.5336 + 21.410 + + + 2024/01/11 + + 0 + 10.5341 + 21.429 + + + 2024/01/11 + + 0 + 10.5346 + 21.452 + + + 2024/01/11 + + 0 + 10.5331 + 21.444 + + + 2024/01/11 + + 0 + 10.5311 + 21.399 + + + 2024/01/11 + + 0 + 10.5293 + 21.337 + + + 2024/01/11 + + 0 + 10.5292 + 21.270 + + + 2024/01/11 + + 0 + 10.5282 + 21.205 + + + 2024/01/11 + + 0 + 10.5277 + 21.170 + + + 2024/01/11 + + 0 + 10.5281 + 21.176 + + + diff --git a/tests/test_013_solinst.py b/tests/test_013_solinst.py new file mode 100644 index 00000000..d45f5999 --- /dev/null +++ b/tests/test_013_solinst.py @@ -0,0 +1,54 @@ +# %% +import logging + +from hydropandas.io import solinst +from hydropandas import observation + +logging.basicConfig(level=logging.DEBUG) + + +# %% test observations + + +def test_read_solinst_file_obs(): + # observation of slugtest, 8 observations per second + df, meta = solinst.read_solinst_file( + "./tests/data/2024-solinst-test/WsNoo_dp366_BUB_20231222_slug1m.xle", + ) + + assert len(df) == 587, "Dataframe should have 587 readings" + +def test_read_solinst_file_meta_has_location(): + # observation of slugtest, created via iOs app, location included by app + df, meta = solinst.read_solinst_file( + "./tests/data/2024-solinst-test/WsNoo_dp366_BUB_20231222_slug1m.xle", + ) + + assert meta['x'] == 52730.58, "x coordinate should be 52730.58" + +def test_read_solinst_file_meta_without_location(): + # example observation created via desktop, location not included + df, meta = solinst.read_solinst_file( + "./tests/data/2024-solinst-test/example-10min-interval-via-laptop.xle", + ) + + assert meta['x'] is None, "x coordinate not available" + +def test_read_solinst_file_with_manual_meta(): + # manual metadata about levels provided + screen_bottom = -10, + screen_top = -5, + ground_level = -1, + tube_nr = 1, + tube_top = -0.5 + + oc = observation.GroundwaterObs.from_solinst( + "./tests/data/2024-solinst-test/WsNoo_dp366_BUB_20231222_slug1m.xle", + screen_bottom=screen_bottom, + screen_top=screen_top, + ground_level=ground_level, + tube_nr=tube_nr, + tube_top=tube_top + ) + + assert oc.tube_top == tube_top, "tube_top should be in oc" From 57c6cefde44f74a72322d388bb06dd23aeab2635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dav=C3=ADd=20Brakenhoff?= Date: Fri, 12 Jan 2024 11:44:34 +0100 Subject: [PATCH 3/3] minor changes on review - black formatting - move import to top - zip one test file to test zip file read --- hydropandas/io/solinst.py | 85 +++---- hydropandas/observation.py | 21 +- .../example-10min-interval-via-laptop.xle | 229 ------------------ .../example-10min-interval-via-laptop.zip | Bin 0 -> 1329 bytes tests/test_013_solinst.py | 29 ++- 5 files changed, 66 insertions(+), 298 deletions(-) delete mode 100644 tests/data/2024-solinst-test/example-10min-interval-via-laptop.xle create mode 100644 tests/data/2024-solinst-test/example-10min-interval-via-laptop.zip diff --git a/hydropandas/io/solinst.py b/hydropandas/io/solinst.py index a36fce86..90d31212 100644 --- a/hydropandas/io/solinst.py +++ b/hydropandas/io/solinst.py @@ -4,9 +4,11 @@ import numpy as np import pandas as pd +from pyproj import Transformer logger = logging.getLogger(__name__) + def read_solinst_file( path, transform_coords=True, @@ -27,7 +29,6 @@ def read_solinst_file( meta : dict, optional dict containing meta """ - from pyproj import Transformer # open file name = os.path.splitext(os.path.basename(path))[0] @@ -44,82 +45,75 @@ def read_solinst_file( logger.info("reading -> {}".format(f)) # read channel 1 data header - df_ch1_data_header = pd.read_xml( - path, - xpath="/Body_xle/Ch1_data_header" - ) + df_ch1_data_header = pd.read_xml(path, xpath="/Body_xle/Ch1_data_header") series_ch1_data_header = df_ch1_data_header.T.iloc[:, 0] - colname_ch1 = series_ch1_data_header.Identification.lower() + \ - '_' + series_ch1_data_header.Unit.lower() + colname_ch1 = ( + series_ch1_data_header.Identification.lower() + + "_" + + series_ch1_data_header.Unit.lower() + ) # read channel 2 data header - df_ch2_data_header = pd.read_xml( - path, - xpath="/Body_xle/Ch2_data_header" - ) + df_ch2_data_header = pd.read_xml(path, xpath="/Body_xle/Ch2_data_header") series_ch2_data_header = df_ch2_data_header.T.iloc[:, 0] - colname_ch2 = series_ch2_data_header.Identification.lower() + \ - '_' + series_ch2_data_header.Unit.lower() + colname_ch2 = ( + series_ch2_data_header.Identification.lower() + + "_" + + series_ch2_data_header.Unit.lower() + ) # read observations df = pd.read_xml( path, xpath="/Body_xle/Data/Log", - ) - df.rename( - columns={'ch1': colname_ch1, - 'ch2': colname_ch2}, - inplace=True - ) - if 'ms' in df.columns: - df['date_time'] = pd.to_datetime( - df['Date'] + ' ' + df['Time']) + \ - pd.to_timedelta(df['ms'], unit='ms') - drop_cols = ['id', 'Date', 'Time', 'ms'] + ) + df.rename(columns={"ch1": colname_ch1, "ch2": colname_ch2}, inplace=True) + if "ms" in df.columns: + df["date_time"] = pd.to_datetime( + df["Date"] + " " + df["Time"] + ) + pd.to_timedelta(df["ms"], unit="ms") + drop_cols = ["id", "Date", "Time", "ms"] else: - df['date_time'] = pd.to_datetime( - df['Date'] + ' ' + df['Time']) - drop_cols = ['id', 'Date', 'Time'] - df.set_index('date_time', inplace=True) + df["date_time"] = pd.to_datetime(df["Date"] + " " + df["Time"]) + drop_cols = ["id", "Date", "Time"] + df.set_index("date_time", inplace=True) df.drop(columns=drop_cols, inplace=True) # parse meta into dict, per group in XLE file meta = {} # read file info - df_file_info = pd.read_xml( - path, - xpath="/Body_xle/File_info" - ) + df_file_info = pd.read_xml(path, xpath="/Body_xle/File_info") dict_file_info = df_file_info.T.iloc[:, 0].to_dict() # read instrument info - df_instrument_info = pd.read_xml( - path, - xpath="/Body_xle/Instrument_info" - ) + df_instrument_info = pd.read_xml(path, xpath="/Body_xle/Instrument_info") dict_instrument_info = df_instrument_info.T.iloc[:, 0].to_dict() # read instrument info df_instrument_info_data_header = pd.read_xml( - path, - xpath="/Body_xle/Instrument_info_data_header" - ) + path, xpath="/Body_xle/Instrument_info_data_header" + ) dict_instrument_info_data_header = df_instrument_info_data_header.T.iloc[ - :, 0].to_dict() + :, 0 + ].to_dict() - meta = {**dict_file_info, - **dict_instrument_info, - **dict_instrument_info_data_header} + meta = { + **dict_file_info, + **dict_instrument_info, + **dict_instrument_info_data_header, + } if transform_coords: # lat and lon has 0,000 when location is not supplied # replace comma with point first if isinstance(meta["Latitude"], str): - meta["Latitude"] = float(meta["Latitude"].replace(',', '.')) + meta["Latitude"] = float(meta["Latitude"].replace(",", ".")) if isinstance(meta["Longtitude"], str): - meta["Longtitude"] = float(meta["Longtitude"].replace(',', '.')) + meta["Longtitude"] = float(meta["Longtitude"].replace(",", ".")) if (meta["Latitude"] != 0) & (meta["Longtitude"] != 0): + # NOTE: check EPSG:28992 definition and whether location is showing up in + # the right spot. transformer = Transformer.from_crs("epsg:4326", "epsg:28992") x, y = transformer.transform(meta["Latitude"], meta["Longtitude"]) x = np.round(x, 2) @@ -141,4 +135,3 @@ def read_solinst_file( meta["metadata_available"] = True return df, meta - diff --git a/hydropandas/observation.py b/hydropandas/observation.py index 36f6b157..45d87900 100644 --- a/hydropandas/observation.py +++ b/hydropandas/observation.py @@ -779,11 +779,15 @@ def from_pastastore(cls, pstore, libname, name, metadata_mapping=None): @classmethod def from_solinst( - cls, - path, - transform_coords=True, - screen_bottom=None, screen_top=None, ground_level=None, - tube_nr=None, tube_top=None): + cls, + path, + transform_coords=True, + screen_bottom=None, + screen_top=None, + ground_level=None, + tube_nr=None, + tube_top=None, + ): """Read data from Solinst xle file. Parameters @@ -794,13 +798,11 @@ def from_solinst( """ from .io import solinst - df, meta = solinst.read_solinst_file( - path, - transform_coords=transform_coords - ) + df, meta = solinst.read_solinst_file(path, transform_coords=transform_coords) return cls( df, + meta=meta, name=meta.pop("name"), x=meta.pop("x"), y=meta.pop("y"), @@ -814,7 +816,6 @@ def from_solinst( monitoring_well=meta.pop("monitoring_well"), tube_nr=tube_nr, tube_top=tube_top, - meta=meta, ) diff --git a/tests/data/2024-solinst-test/example-10min-interval-via-laptop.xle b/tests/data/2024-solinst-test/example-10min-interval-via-laptop.xle deleted file mode 100644 index 5178224b..00000000 --- a/tests/data/2024-solinst-test/example-10min-interval-via-laptop.xle +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - 2024/01/11 - - - Version 4.6.3 - Version 4.6.3 - PC Software 4.6.2 - Desktop Reader (567751) - - - L5_LT - M5 - Stopped - 2170536 - 3,59600 - 1372,54 - 2 - 1,006 - - - 20231123 - slugtest - 0,000 - 0,000 - 60000 - 0 - - Slate - 1 - 0,000000 - - 2024/01/11 11:00:00 - 2024/01/11 15:00:00 - 25 - - - LEVEL - m - - - - - - TEMPERATURE - °C - - - - - 2024/01/11 - - 0 - 10.5288 - 21.879 - - - 2024/01/11 - - 0 - 10.5300 - 21.585 - - - 2024/01/11 - - 0 - 10.5319 - 21.403 - - - 2024/01/11 - - 0 - 10.5343 - 21.285 - - - 2024/01/11 - - 0 - 10.5339 - 21.205 - - - 2024/01/11 - - 0 - 10.5329 - 21.177 - - - 2024/01/11 - - 0 - 10.5335 - 21.204 - - - 2024/01/11 - - 0 - 10.5323 - 21.258 - - - 2024/01/11 - - 0 - 10.5319 - 21.311 - - - 2024/01/11 - - 0 - 10.5323 - 21.429 - - - 2024/01/11 - - 0 - 10.5320 - 21.474 - - - 2024/01/11 - - 0 - 10.5333 - 21.469 - - - 2024/01/11 - - 0 - 10.5341 - 21.424 - - - 2024/01/11 - - 0 - 10.5350 - 21.394 - - - 2024/01/11 - - 0 - 10.5344 - 21.412 - - - 2024/01/11 - - 0 - 10.5336 - 21.410 - - - 2024/01/11 - - 0 - 10.5341 - 21.429 - - - 2024/01/11 - - 0 - 10.5346 - 21.452 - - - 2024/01/11 - - 0 - 10.5331 - 21.444 - - - 2024/01/11 - - 0 - 10.5311 - 21.399 - - - 2024/01/11 - - 0 - 10.5293 - 21.337 - - - 2024/01/11 - - 0 - 10.5292 - 21.270 - - - 2024/01/11 - - 0 - 10.5282 - 21.205 - - - 2024/01/11 - - 0 - 10.5277 - 21.170 - - - 2024/01/11 - - 0 - 10.5281 - 21.176 - - - diff --git a/tests/data/2024-solinst-test/example-10min-interval-via-laptop.zip b/tests/data/2024-solinst-test/example-10min-interval-via-laptop.zip new file mode 100644 index 0000000000000000000000000000000000000000..0788fb495fb23cf29f81ed4876e9e13259373057 GIT binary patch literal 1329 zcmWIWW@Zs#-~dA27@Y_PDA*{;z@W;Yz>r#zm|KvOs%vPFo0+GZnOBlpRF;^dTb7xq zo0C{jl3$=#k&_x4!pp#JExIrjhD$5B85mh!Ff%ZKiLH^h^B!49?0X-avg6j&D53cr zA(?K*QzmL%%)44vC0*Ikc;;Dy&}GScS@RR;=e!Llm=tuqYwO;Xf920SKR^G!edB}A z?{!M!A|h2?>r5G(^B>gkoo`z2x~IEtxsFZok@yd~o{>|YoKCV|pL<#9_Jta8ws(n3 zYCg|?`6kawc;8`hZ!9#Zcj5EH0z#bIzFB(nY-L;mwtDsr*Y<<`Bwc$C;eZf zx_WcM1G7C^Pt~5UiMhney*~1*xxU#sW?}B>=j2nK{AT$hxkD@E{EpiTW7Y(IESkM> zPC5UghYxr2az9s@Wq(ricG}c}=p#D4pK`x7PkpFcxpkNB=aWyh_4;20<|G_`bWQz@ zt=7wlQ#oz**c#spnsD9O7TH?AG$yBBe6NV+a&56i#YU2qaSzI5^Ml2*qqx`|>};l2 zy}TiPE8?>TQe!TEQ8Unf(sX=5)v6}D*qAeu=Un{sXpyGbG|@*EuWlR<(a~z5n$Mr^K_ZFD?W%2L;LhmQ6tE=z`( zs(Yzt8$Ov&?mBy0W>FDe-qfP)XBTaWXq~|FF0m%cH@{T*2-m&9%f337CZ>>i+qr z(o9@?+ghzZ)$=|WaNqe=?>sp~L{m-AYiZBc$LpVNO1e|I?B&%2|BnYI?hJ3vxv=Qs zTRp|~S2-^vXkAH=Y6tN*bh0=AnR`KuSR3-eaJQFQ)tgU$9;ubeV(RmK_HjgI}*i`}i> zEllsKOKG0>#f`u8MdN$vMc;ofZvUIj=j3wQ*389zo8$fc&m7jiJ9$Ik?-91Y|3iu= z{E1Nha$s}g{rxX8P9DFoC6=)}k6U*Y-<7Z0Z)R)BM{J4C2rQd0?e9dx-(r8oBCp8u zY