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

1import warnings 

2from dataclasses import dataclass 

3from pathlib import Path 

4from typing import Optional, Union 

5 

6import numpy as np 

7 

8 

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 

15 

16 

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") 

28 

29 converted_value = metadata.dtype(value) 

30 return format_string.format(converted_value) 

31 

32 

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. 

38 

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] = [] 

50 

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