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

1import warnings 

2from dataclasses import dataclass 

3from numbers import Number 

4from pathlib import Path 

5from typing import Dict, Union 

6 

7import numpy as np 

8 

9 

10@dataclass 

11class VariableMetaData: 

12 column_width: int 

13 min_value: Number 

14 max_value: Number 

15 dtype: type 

16 

17 

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

29 

30 converted_value = metadata.dtype(value) 

31 return format_string.format(converted_value) 

32 

33 

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. 

39 

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

51 

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