Coverage for C:\src\imod-python\imod\msw\fixed_format.py: 51%
45 statements
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-08 14:15 +0200
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-08 14:15 +0200
1import warnings
2from dataclasses import dataclass
3from pathlib import Path
4from typing import Optional, Union
6import numpy as np
9@dataclass
10class VariableMetaData:
11 column_width: int
12 min_value: Optional[Union[int, float]]
13 max_value: Optional[Union[int, float]]
14 dtype: type
17def format_fixed_width(value, metadata):
18 if metadata.dtype == str:
19 format_string = "{:" + f"{metadata.column_width}" + "}"
20 elif metadata.dtype == int:
21 format_string = "{:" + f"{metadata.column_width}d" + "}"
22 elif metadata.dtype == float:
23 whole_number_digits = len(str(int(abs(value))))
24 decimal_number_width = max(0, metadata.column_width - whole_number_digits - 2)
25 format_string = "{:" + f"{metadata.column_width}.{decimal_number_width}f" + "}"
26 else:
27 raise TypeError(f"dtype {metadata.dtype} is not supported")
29 converted_value = metadata.dtype(value)
30 return format_string.format(converted_value)
33def fixed_format_parser(
34 file: Union[str, Path], metadata_dict: dict[str, VariableMetaData]
35):
36 """
37 Read fixed format file, using a metadata_dict from a MetaSWAP package.
39 Parameters
40 ----------
41 file: str or Path
42 Fixed format file to read, likely a MetaSWAP input file
43 metadata_dict: dict
44 Dictionary with the VariableMetaData. Access this dictionary in a
45 package by calling <pkg>._metadata_dict
46 """
47 results: dict[str, list] = {}
48 for key in metadata_dict:
49 results[key] = []
51 with open(file) as f:
52 lines = f.readlines()
53 for line in lines:
54 if line == "\n":
55 continue
56 troublesome = set()
57 for varname, metadata in metadata_dict.items():
58 # Take first part of line
59 value = line[: metadata.column_width]
60 # Convert to correct type
61 try:
62 converted_value = metadata.dtype(value)
63 except ValueError:
64 troublesome.add(varname)
65 converted_value = np.nan
66 # Add to results
67 results[varname].append(converted_value)
68 # Truncate line
69 line = line[metadata.column_width :]
70 if len(troublesome) > 0:
71 warnings.warn(
72 f"Had trouble reading the variables: {troublesome}",
73 UserWarning,
74 )
75 return results