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