ras-commander 0.65.0__py3-none-any.whl → 0.67.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@ from typing import Union
4
4
  import logging
5
5
  import h5py
6
6
  import inspect
7
+ import pandas as pd
7
8
 
8
9
 
9
10
  def log_call(func):
@@ -43,17 +44,13 @@ def standardize_input(file_type: str = 'plan_hdf'):
43
44
  # Check if the function expects an hdf_path parameter
44
45
  sig = inspect.signature(func)
45
46
  param_names = list(sig.parameters.keys())
46
-
47
- # If first parameter is 'hdf_file', skip path processing
48
- if param_names and param_names[0] == 'hdf_file':
49
- return func(*args, **kwargs)
50
47
 
51
48
  # Handle both static method calls and regular function calls
52
49
  if args and isinstance(args[0], type):
53
50
  # Static method call, remove the class argument
54
51
  args = args[1:]
55
52
 
56
- hdf_input = kwargs.pop('hdf_path', None) or kwargs.pop('hdf_input', None) or (args[0] if args else None)
53
+ hdf_input = kwargs.pop('hdf_path', None) or (args[0] if args else None)
57
54
 
58
55
  # Import ras here to ensure we get the most current instance
59
56
  from .RasPrj import ras as ras
@@ -64,77 +61,120 @@ def standardize_input(file_type: str = 'plan_hdf'):
64
61
  if hdf_input is None:
65
62
  return func(*args, **kwargs)
66
63
 
67
- # NEW: If input is already a Path and exists, use it directly regardless of file_type
68
- if isinstance(hdf_input, Path) and hdf_input.is_file():
69
- logger.info(f"Using existing HDF file: {hdf_input}")
70
- new_args = (hdf_input,) + args[1:]
71
- return func(*new_args, **kwargs)
72
-
73
64
  hdf_path = None
74
65
 
75
- # If hdf_input is already an h5py.File object, use its filename
76
- if isinstance(hdf_input, h5py.File):
77
- hdf_path = Path(hdf_input.filename)
78
- # Handle Path objects
79
- elif isinstance(hdf_input, Path):
80
- if hdf_input.is_file():
66
+ # Clean and normalize string inputs
67
+ if isinstance(hdf_input, str):
68
+ # Clean the string (remove extra whitespace, normalize path separators)
69
+ hdf_input = hdf_input.strip()
70
+
71
+ # Check if it's a raw file path that exists
72
+ try:
73
+ test_path = Path(hdf_input)
74
+ if test_path.is_file():
75
+ hdf_path = test_path
76
+ logger.info(f"Using HDF file from direct string path: {hdf_path}")
77
+ except Exception as e:
78
+ logger.debug(f"Error converting string to path: {str(e)}")
79
+
80
+ # If a valid path wasn't created from string processing, continue with normal flow
81
+ if hdf_path is None:
82
+ # If hdf_input is already a Path and exists, use it directly
83
+ if isinstance(hdf_input, Path) and hdf_input.is_file():
81
84
  hdf_path = hdf_input
82
- # Handle string inputs
83
- elif isinstance(hdf_input, str):
84
- # Check if it's a file path
85
- if Path(hdf_input).is_file():
86
- hdf_path = Path(hdf_input)
87
- # Check if it's a number (with or without 'p' prefix)
88
- elif hdf_input.isdigit() or (len(hdf_input) > 1 and hdf_input[0] == 'p' and hdf_input[1:].isdigit()):
85
+ logger.info(f"Using existing Path object HDF file: {hdf_path}")
86
+ # If hdf_input is an h5py.File object, use its filename
87
+ elif isinstance(hdf_input, h5py.File):
88
+ hdf_path = Path(hdf_input.filename)
89
+ logger.info(f"Using HDF file from h5py.File object: {hdf_path}")
90
+ # Handle Path objects that might not be verified yet
91
+ elif isinstance(hdf_input, Path):
92
+ if hdf_input.is_file():
93
+ hdf_path = hdf_input
94
+ logger.info(f"Using verified Path object HDF file: {hdf_path}")
95
+ # Handle string inputs that are plan/geom numbers
96
+ elif isinstance(hdf_input, str) and (hdf_input.isdigit() or (len(hdf_input) > 1 and hdf_input[0] == 'p' and hdf_input[1:].isdigit())):
89
97
  try:
90
98
  ras_obj.check_initialized()
91
99
  except Exception as e:
92
100
  raise ValueError(f"RAS object is not initialized: {str(e)}")
93
101
 
94
- # Extract the numeric part and convert to integer for comparison
95
102
  number_str = hdf_input if hdf_input.isdigit() else hdf_input[1:]
96
103
  number_int = int(number_str)
97
104
 
98
105
  if file_type == 'plan_hdf':
99
- # Convert plan_number column to integers for comparison
100
- plan_info = ras_obj.plan_df[ras_obj.plan_df['plan_number'].astype(int) == number_int]
101
- if not plan_info.empty:
102
- hdf_path = Path(plan_info.iloc[0]['HDF_Results_Path'])
106
+ try:
107
+ # Convert plan_number column to integers for comparison
108
+ plan_info = ras_obj.plan_df[ras_obj.plan_df['plan_number'].astype(int) == number_int]
109
+ if not plan_info.empty:
110
+ # Make sure HDF_Results_Path is a string and not None
111
+ hdf_path_str = plan_info.iloc[0]['HDF_Results_Path']
112
+ if pd.notna(hdf_path_str):
113
+ hdf_path = Path(str(hdf_path_str))
114
+ except Exception as e:
115
+ logger.warning(f"Error retrieving plan HDF path: {str(e)}")
103
116
  elif file_type == 'geom_hdf':
104
- # Convert geom_number column to integers for comparison
105
- geom_info = ras_obj.geom_df[ras_obj.geom_df['geom_number'].astype(int) == number_int]
106
- if not geom_info.empty:
107
- hdf_path = Path(geom_info.iloc[0]['HDF_Path'])
117
+ try:
118
+ # Convert geom_number column to integers for comparison
119
+ geom_info = ras_obj.geom_df[ras_obj.geom_df['geom_number'].astype(int) == number_int]
120
+ if not geom_info.empty:
121
+ hdf_path_str = geom_info.iloc[0]['hdf_path']
122
+ if pd.notna(hdf_path_str):
123
+ hdf_path = Path(str(hdf_path_str))
124
+ except Exception as e:
125
+ logger.warning(f"Error retrieving geometry HDF path: {str(e)}")
108
126
  else:
109
127
  raise ValueError(f"Invalid file type: {file_type}")
110
- # Handle integer inputs (assuming they're plan or geom numbers)
111
- elif isinstance(hdf_input, int):
112
- try:
113
- ras_obj.check_initialized()
114
- except Exception as e:
115
- raise ValueError(f"RAS object is not initialized: {str(e)}")
116
-
117
- number_int = hdf_input
118
128
 
119
- if file_type == 'plan_hdf':
120
- # Convert plan_number column to integers for comparison
121
- plan_info = ras_obj.plan_df[ras_obj.plan_df['plan_number'].astype(int) == number_int]
122
- if not plan_info.empty:
123
- hdf_path = Path(plan_info.iloc[0]['HDF_Results_Path'])
124
- elif file_type == 'geom_hdf':
125
- # Convert geom_number column to integers for comparison
126
- geom_info = ras_obj.geom_df[ras_obj.geom_df['geom_number'].astype(int) == number_int]
127
- if not geom_info.empty:
128
- hdf_path = Path(geom_info.iloc[0]['HDF_Path'])
129
- else:
130
- raise ValueError(f"Invalid file type: {file_type}")
129
+ # Handle integer inputs (assuming they're plan or geom numbers)
130
+ elif isinstance(hdf_input, int):
131
+ try:
132
+ ras_obj.check_initialized()
133
+ except Exception as e:
134
+ raise ValueError(f"RAS object is not initialized: {str(e)}")
135
+
136
+ number_int = hdf_input
137
+
138
+ if file_type == 'plan_hdf':
139
+ try:
140
+ # Convert plan_number column to integers for comparison
141
+ plan_info = ras_obj.plan_df[ras_obj.plan_df['plan_number'].astype(int) == number_int]
142
+ if not plan_info.empty:
143
+ # Make sure HDF_Results_Path is a string and not None
144
+ hdf_path_str = plan_info.iloc[0]['HDF_Results_Path']
145
+ if pd.notna(hdf_path_str):
146
+ hdf_path = Path(str(hdf_path_str))
147
+ except Exception as e:
148
+ logger.warning(f"Error retrieving plan HDF path: {str(e)}")
149
+ elif file_type == 'geom_hdf':
150
+ try:
151
+ # Convert geom_number column to integers for comparison
152
+ geom_info = ras_obj.geom_df[ras_obj.geom_df['geom_number'].astype(int) == number_int]
153
+ if not geom_info.empty:
154
+ hdf_path_str = geom_info.iloc[0]['hdf_path']
155
+ if pd.notna(hdf_path_str):
156
+ hdf_path = Path(str(hdf_path_str))
157
+ except Exception as e:
158
+ logger.warning(f"Error retrieving geometry HDF path: {str(e)}")
159
+ else:
160
+ raise ValueError(f"Invalid file type: {file_type}")
131
161
 
132
- if hdf_path is None or not hdf_path.is_file():
162
+ # Final verification that the path exists
163
+ if hdf_path is None or not hdf_path.exists():
133
164
  error_msg = f"HDF file not found: {hdf_input}"
134
165
  logger.error(error_msg)
135
166
  raise FileNotFoundError(error_msg)
136
-
137
- logger.info(f"Using HDF file: {hdf_path}")
167
+
168
+ logger.info(f"Final validated HDF file path: {hdf_path}")
169
+
170
+ # Now try to validate the HDF file structure (but don't fail if validation fails)
171
+ try:
172
+ with h5py.File(hdf_path, 'r') as test_file:
173
+ # Just open to verify it's a valid HDF5 file
174
+ logger.debug(f"Successfully opened HDF file for validation: {hdf_path}")
175
+ except Exception as e:
176
+ logger.warning(f"Warning: Could not validate HDF file: {str(e)}")
177
+ # Continue anyway, let the function handle detailed validation
138
178
 
139
179
  # Pass all original arguments and keywords, replacing hdf_input with standardized hdf_path
140
180
  new_args = (hdf_path,) + args[1:]
ras_commander/HdfPlan.py CHANGED
@@ -11,25 +11,7 @@ The file has been forked and modified for use in RAS Commander.
11
11
 
12
12
  All of the methods in this class are static and are designed to be used without instantiation.
13
13
 
14
- List of Functions in HdfPlan:
15
- - get_simulation_start_time()
16
- - get_simulation_end_time()
17
- - get_unsteady_datetimes()
18
- - get_plan_info_attrs()
19
- - get_plan_parameters()
20
- - get_meteorology_precip_attrs()
21
- - get_geom_attrs()
22
-
23
-
24
- REVISIONS NEEDED:
25
14
 
26
- Use get_ prefix for functions that return data.
27
- Since we are extracting plan data, we should use get_plan_...
28
- BUT, we will never set results data, so we should use results_
29
-
30
- We need to shorten names where possible.
31
-
32
- List of Revised Functions in HdfPlan:
33
15
  - get_plan_start_time()
34
16
  - get_plan_end_time()
35
17
  - get_plan_timestamps_list()
@@ -283,7 +265,7 @@ class HdfPlan:
283
265
 
284
266
  @staticmethod
285
267
  @log_call
286
- @standardize_input(file_type='plan_hdf')
268
+ @standardize_input(file_type='geom_hdf')
287
269
  def get_geometry_information(hdf_path: Path) -> pd.DataFrame:
288
270
  """
289
271
  Get root level geometry attributes from the HDF plan file.