ras-commander 0.68.0__py3-none-any.whl → 0.71.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.
- ras_commander/RasCmdr.py +189 -40
- ras_commander/RasGeo.py +257 -15
- ras_commander/RasPlan.py +41 -26
- ras_commander/RasPrj.py +224 -78
- ras_commander/RasUnsteady.py +162 -68
- ras_commander/__init__.py +1 -1
- {ras_commander-0.68.0.dist-info → ras_commander-0.71.0.dist-info}/METADATA +15 -5
- {ras_commander-0.68.0.dist-info → ras_commander-0.71.0.dist-info}/RECORD +11 -14
- {ras_commander-0.68.0.dist-info → ras_commander-0.71.0.dist-info}/WHEEL +1 -1
- ras_commander/RasGpt.py +0 -27
- ras_commander/RasMapper.py +0 -24
- ras_commander/RasToGo.py +0 -37
- {ras_commander-0.68.0.dist-info → ras_commander-0.71.0.dist-info/licenses}/LICENSE +0 -0
- {ras_commander-0.68.0.dist-info → ras_commander-0.71.0.dist-info}/top_level.txt +0 -0
ras_commander/RasPlan.py
CHANGED
@@ -87,7 +87,7 @@ class RasPlan:
|
|
87
87
|
@log_call
|
88
88
|
def set_geom(plan_number: Union[str, int], new_geom: Union[str, int], ras_object=None) -> pd.DataFrame:
|
89
89
|
"""
|
90
|
-
Set the geometry for the specified plan.
|
90
|
+
Set the geometry for the specified plan by updating only the plan file.
|
91
91
|
|
92
92
|
Parameters:
|
93
93
|
plan_number (Union[str, int]): The plan number to update.
|
@@ -101,7 +101,8 @@ class RasPlan:
|
|
101
101
|
updated_geom_df = RasPlan.set_geom('02', '03')
|
102
102
|
|
103
103
|
Note:
|
104
|
-
This function updates the
|
104
|
+
This function updates the Geom File= line in the plan file and
|
105
|
+
updates the ras object's dataframes without modifying the PRJ file.
|
105
106
|
"""
|
106
107
|
ras_obj = ras_object or ras
|
107
108
|
ras_obj.check_initialized()
|
@@ -112,16 +113,37 @@ class RasPlan:
|
|
112
113
|
# Update all dataframes
|
113
114
|
ras_obj.plan_df = ras_obj.get_plan_entries()
|
114
115
|
ras_obj.geom_df = ras_obj.get_geom_entries()
|
115
|
-
ras_obj.flow_df = ras_obj.get_flow_entries()
|
116
|
-
ras_obj.unsteady_df = ras_obj.get_unsteady_entries()
|
117
116
|
|
118
117
|
if new_geom not in ras_obj.geom_df['geom_number'].values:
|
119
118
|
logger.error(f"Geometry {new_geom} not found in project.")
|
120
119
|
raise ValueError(f"Geometry {new_geom} not found in project.")
|
121
120
|
|
122
|
-
#
|
121
|
+
# Get the plan file path
|
122
|
+
plan_file_path = ras_obj.project_folder / f"{ras_obj.project_name}.p{plan_number}"
|
123
|
+
if not plan_file_path.exists():
|
124
|
+
logger.error(f"Plan file not found: {plan_file_path}")
|
125
|
+
raise ValueError(f"Plan file not found: {plan_file_path}")
|
126
|
+
|
127
|
+
# Read the plan file and update the Geom File line
|
128
|
+
try:
|
129
|
+
with open(plan_file_path, 'r') as file:
|
130
|
+
lines = file.readlines()
|
131
|
+
|
132
|
+
for i, line in enumerate(lines):
|
133
|
+
if line.startswith("Geom File="):
|
134
|
+
lines[i] = f"Geom File=g{new_geom}\n"
|
135
|
+
logger.info(f"Updated Geom File in plan file to g{new_geom} for plan {plan_number}")
|
136
|
+
break
|
137
|
+
|
138
|
+
with open(plan_file_path, 'w') as file:
|
139
|
+
file.writelines(lines)
|
140
|
+
except Exception as e:
|
141
|
+
logger.error(f"Error updating plan file: {e}")
|
142
|
+
raise
|
143
|
+
# Update the plan_df without reinitializing
|
123
144
|
mask = ras_obj.plan_df['plan_number'] == plan_number
|
124
145
|
ras_obj.plan_df.loc[mask, 'geom_number'] = new_geom
|
146
|
+
ras_obj.plan_df.loc[mask, 'geometry_number'] = new_geom # Update geometry_number column
|
125
147
|
ras_obj.plan_df.loc[mask, 'Geom File'] = f"g{new_geom}"
|
126
148
|
geom_path = ras_obj.project_folder / f"{ras_obj.project_name}.g{new_geom}"
|
127
149
|
ras_obj.plan_df.loc[mask, 'Geom Path'] = str(geom_path)
|
@@ -130,27 +152,8 @@ class RasPlan:
|
|
130
152
|
logger.debug("Updated plan DataFrame:")
|
131
153
|
logger.debug(ras_obj.plan_df)
|
132
154
|
|
133
|
-
# Update project file and reinitialize
|
134
|
-
RasUtils.update_file(ras_obj.prj_file, RasPlan._update_geom_in_file, plan_number, new_geom)
|
135
|
-
ras_obj.initialize(ras_obj.project_folder, ras_obj.ras_exe_path)
|
136
|
-
|
137
155
|
return ras_obj.plan_df
|
138
156
|
|
139
|
-
@staticmethod
|
140
|
-
def _update_geom_in_file(lines, plan_number, new_geom):
|
141
|
-
plan_pattern = re.compile(rf"^Plan File=p{plan_number}", re.IGNORECASE)
|
142
|
-
geom_pattern = re.compile(r"^Geom File=g\d+", re.IGNORECASE)
|
143
|
-
|
144
|
-
for i, line in enumerate(lines):
|
145
|
-
if plan_pattern.match(line):
|
146
|
-
for j in range(i+1, len(lines)):
|
147
|
-
if geom_pattern.match(lines[j]):
|
148
|
-
lines[j] = f"Geom File=g{new_geom}\n"
|
149
|
-
logger.info(f"Updated Geom File in project file to g{new_geom} for plan {plan_number}")
|
150
|
-
break
|
151
|
-
break
|
152
|
-
return lines
|
153
|
-
|
154
157
|
@staticmethod
|
155
158
|
@log_call
|
156
159
|
def set_steady(plan_number: str, new_steady_flow_number: str, ras_object=None):
|
@@ -249,7 +252,19 @@ class RasPlan:
|
|
249
252
|
raise FileNotFoundError(f"Plan file not found: {plan_number}")
|
250
253
|
|
251
254
|
try:
|
252
|
-
|
255
|
+
# Read the plan file
|
256
|
+
with open(plan_file_path, 'r') as f:
|
257
|
+
lines = f.readlines()
|
258
|
+
|
259
|
+
# Update the Flow File line
|
260
|
+
for i, line in enumerate(lines):
|
261
|
+
if line.startswith("Flow File="):
|
262
|
+
lines[i] = f"Flow File=u{new_unsteady_flow_number}\n"
|
263
|
+
break
|
264
|
+
|
265
|
+
# Write back to the plan file
|
266
|
+
with open(plan_file_path, 'w') as f:
|
267
|
+
f.writelines(lines)
|
253
268
|
|
254
269
|
# Update all dataframes
|
255
270
|
ras_obj.plan_df = ras_obj.get_plan_entries()
|
@@ -957,7 +972,7 @@ class RasPlan:
|
|
957
972
|
return None
|
958
973
|
|
959
974
|
|
960
|
-
|
975
|
+
|
961
976
|
|
962
977
|
|
963
978
|
@staticmethod
|
ras_commander/RasPrj.py
CHANGED
@@ -118,22 +118,25 @@ class RasPrj:
|
|
118
118
|
@log_call
|
119
119
|
def initialize(self, project_folder, ras_exe_path, suppress_logging=True):
|
120
120
|
"""
|
121
|
-
Initialize a RasPrj instance.
|
121
|
+
Initialize a RasPrj instance with project folder and RAS executable path.
|
122
122
|
|
123
|
-
|
124
|
-
|
125
|
-
extracts boundary conditions.
|
123
|
+
IMPORTANT: External users should use init_ras_project() function instead of this method.
|
124
|
+
This method is intended for internal use only.
|
126
125
|
|
127
126
|
Args:
|
128
127
|
project_folder (str or Path): Path to the HEC-RAS project folder.
|
129
128
|
ras_exe_path (str or Path): Path to the HEC-RAS executable.
|
130
|
-
suppress_logging (bool): If True, suppresses initialization logging messages.
|
129
|
+
suppress_logging (bool, default=True): If True, suppresses initialization logging messages.
|
131
130
|
|
132
131
|
Raises:
|
133
132
|
ValueError: If no HEC-RAS project file is found in the specified folder.
|
134
133
|
|
135
134
|
Note:
|
136
|
-
This method
|
135
|
+
This method sets up the RasPrj instance by:
|
136
|
+
1. Finding the project file (.prj)
|
137
|
+
2. Loading project data (plans, geometries, flows)
|
138
|
+
3. Extracting boundary conditions
|
139
|
+
4. Setting the initialization flag
|
137
140
|
"""
|
138
141
|
self.suppress_logging = suppress_logging # Store suppress_logging state
|
139
142
|
self.project_folder = Path(project_folder)
|
@@ -143,10 +146,14 @@ class RasPrj:
|
|
143
146
|
raise ValueError(f"No HEC-RAS project file found in {self.project_folder}")
|
144
147
|
self.project_name = Path(self.prj_file).stem
|
145
148
|
self.ras_exe_path = ras_exe_path
|
146
|
-
|
147
|
-
|
149
|
+
|
150
|
+
# Set initialized to True before loading project data
|
148
151
|
self.initialized = True
|
149
152
|
|
153
|
+
# Now load the project data
|
154
|
+
self._load_project_data()
|
155
|
+
self.boundaries_df = self.get_boundary_conditions()
|
156
|
+
|
150
157
|
if not suppress_logging:
|
151
158
|
logger.info(f"Initialization complete for project: {self.project_name}")
|
152
159
|
logger.info(f"Plan entries: {len(self.plan_df)}, Flow entries: {len(self.flow_df)}, "
|
@@ -159,8 +166,13 @@ class RasPrj:
|
|
159
166
|
"""
|
160
167
|
Load project data from the HEC-RAS project file.
|
161
168
|
|
162
|
-
This method
|
163
|
-
|
169
|
+
This internal method:
|
170
|
+
1. Initializes DataFrames for plan, flow, unsteady, and geometry entries
|
171
|
+
2. Ensures all required columns are present with appropriate default values
|
172
|
+
3. Sets file paths for all components (geometries, flows, plans)
|
173
|
+
|
174
|
+
Raises:
|
175
|
+
Exception: If there's an error loading or processing project data.
|
164
176
|
"""
|
165
177
|
try:
|
166
178
|
# Load data frames
|
@@ -632,10 +644,14 @@ class RasPrj:
|
|
632
644
|
@log_call
|
633
645
|
def check_initialized(self):
|
634
646
|
"""
|
635
|
-
Ensure that the RasPrj instance has been initialized.
|
647
|
+
Ensure that the RasPrj instance has been initialized before operations.
|
636
648
|
|
637
649
|
Raises:
|
638
|
-
RuntimeError: If the project has not been initialized.
|
650
|
+
RuntimeError: If the project has not been initialized with init_ras_project().
|
651
|
+
|
652
|
+
Note:
|
653
|
+
This method is called by other methods to validate the project state before
|
654
|
+
performing operations. Users typically don't need to call this directly.
|
639
655
|
"""
|
640
656
|
if not self.initialized:
|
641
657
|
raise RuntimeError("Project not initialized. Call init_ras_project() first.")
|
@@ -646,11 +662,23 @@ class RasPrj:
|
|
646
662
|
"""
|
647
663
|
Find the appropriate HEC-RAS project file (.prj) in the given folder.
|
648
664
|
|
649
|
-
|
650
|
-
|
665
|
+
This method uses several strategies to locate the correct project file:
|
666
|
+
1. If only one .prj file exists, it is selected
|
667
|
+
2. If multiple .prj files exist, it tries to match with .rasmap file names
|
668
|
+
3. As a last resort, it scans files for "Proj Title=" content
|
669
|
+
|
670
|
+
Args:
|
671
|
+
folder_path (str or Path): Path to the folder containing HEC-RAS files.
|
651
672
|
|
652
673
|
Returns:
|
653
|
-
|
674
|
+
Path: The full path of the selected .prj file or None if no suitable file is found.
|
675
|
+
|
676
|
+
Example:
|
677
|
+
>>> project_file = RasPrj.find_ras_prj("/path/to/ras_project")
|
678
|
+
>>> if project_file:
|
679
|
+
... print(f"Found project file: {project_file}")
|
680
|
+
... else:
|
681
|
+
... print("No project file found")
|
654
682
|
"""
|
655
683
|
folder_path = Path(folder_path)
|
656
684
|
prj_files = list(folder_path.glob("*.prj"))
|
@@ -677,13 +705,17 @@ class RasPrj:
|
|
677
705
|
@log_call
|
678
706
|
def get_project_name(self):
|
679
707
|
"""
|
680
|
-
Get the name of the HEC-RAS project.
|
708
|
+
Get the name of the HEC-RAS project (without file extension).
|
681
709
|
|
682
710
|
Returns:
|
683
711
|
str: The name of the project.
|
684
712
|
|
685
713
|
Raises:
|
686
714
|
RuntimeError: If the project has not been initialized.
|
715
|
+
|
716
|
+
Example:
|
717
|
+
>>> project_name = ras.get_project_name()
|
718
|
+
>>> print(f"Working with project: {project_name}")
|
687
719
|
"""
|
688
720
|
self.check_initialized()
|
689
721
|
return self.project_name
|
@@ -693,14 +725,26 @@ class RasPrj:
|
|
693
725
|
"""
|
694
726
|
Get entries of a specific type from the HEC-RAS project.
|
695
727
|
|
728
|
+
This method extracts files of the specified type from the project file,
|
729
|
+
parses their content, and returns a structured DataFrame.
|
730
|
+
|
696
731
|
Args:
|
697
|
-
entry_type (str): The type of entry to retrieve (
|
732
|
+
entry_type (str): The type of entry to retrieve ('Plan', 'Flow', 'Unsteady', or 'Geom').
|
698
733
|
|
699
734
|
Returns:
|
700
|
-
pd.DataFrame: A DataFrame containing the requested entries.
|
735
|
+
pd.DataFrame: A DataFrame containing the requested entries with appropriate columns.
|
701
736
|
|
702
737
|
Raises:
|
703
738
|
RuntimeError: If the project has not been initialized.
|
739
|
+
|
740
|
+
Example:
|
741
|
+
>>> # Get all geometry files in the project
|
742
|
+
>>> geom_entries = ras.get_prj_entries('Geom')
|
743
|
+
>>> print(f"Project contains {len(geom_entries)} geometry files")
|
744
|
+
|
745
|
+
Note:
|
746
|
+
This is a generic method. For specific file types, use the dedicated methods:
|
747
|
+
get_plan_entries(), get_flow_entries(), get_unsteady_entries(), get_geom_entries()
|
704
748
|
"""
|
705
749
|
self.check_initialized()
|
706
750
|
return self._get_prj_entries(entry_type)
|
@@ -709,12 +753,23 @@ class RasPrj:
|
|
709
753
|
def get_plan_entries(self):
|
710
754
|
"""
|
711
755
|
Get all plan entries from the HEC-RAS project.
|
756
|
+
|
757
|
+
Returns a DataFrame containing all plan files (.p*) in the project
|
758
|
+
with their associated properties, paths and settings.
|
712
759
|
|
713
760
|
Returns:
|
714
|
-
pd.DataFrame: A DataFrame
|
761
|
+
pd.DataFrame: A DataFrame with columns including 'plan_number', 'full_path',
|
762
|
+
'unsteady_number', 'geometry_number', etc.
|
715
763
|
|
716
764
|
Raises:
|
717
765
|
RuntimeError: If the project has not been initialized.
|
766
|
+
|
767
|
+
Example:
|
768
|
+
>>> plan_entries = ras.get_plan_entries()
|
769
|
+
>>> print(f"Project contains {len(plan_entries)} plan files")
|
770
|
+
>>> # Display the first plan's properties
|
771
|
+
>>> if not plan_entries.empty:
|
772
|
+
... print(plan_entries.iloc[0])
|
718
773
|
"""
|
719
774
|
self.check_initialized()
|
720
775
|
return self._get_prj_entries('Plan')
|
@@ -723,12 +778,22 @@ class RasPrj:
|
|
723
778
|
def get_flow_entries(self):
|
724
779
|
"""
|
725
780
|
Get all flow entries from the HEC-RAS project.
|
781
|
+
|
782
|
+
Returns a DataFrame containing all flow files (.f*) in the project
|
783
|
+
with their associated properties and paths.
|
726
784
|
|
727
785
|
Returns:
|
728
|
-
pd.DataFrame: A DataFrame
|
786
|
+
pd.DataFrame: A DataFrame with columns including 'flow_number', 'full_path', etc.
|
729
787
|
|
730
788
|
Raises:
|
731
789
|
RuntimeError: If the project has not been initialized.
|
790
|
+
|
791
|
+
Example:
|
792
|
+
>>> flow_entries = ras.get_flow_entries()
|
793
|
+
>>> print(f"Project contains {len(flow_entries)} flow files")
|
794
|
+
>>> # Display the first flow file's properties
|
795
|
+
>>> if not flow_entries.empty:
|
796
|
+
... print(flow_entries.iloc[0])
|
732
797
|
"""
|
733
798
|
self.check_initialized()
|
734
799
|
return self._get_prj_entries('Flow')
|
@@ -737,12 +802,22 @@ class RasPrj:
|
|
737
802
|
def get_unsteady_entries(self):
|
738
803
|
"""
|
739
804
|
Get all unsteady flow entries from the HEC-RAS project.
|
805
|
+
|
806
|
+
Returns a DataFrame containing all unsteady flow files (.u*) in the project
|
807
|
+
with their associated properties and paths.
|
740
808
|
|
741
809
|
Returns:
|
742
|
-
pd.DataFrame: A DataFrame
|
810
|
+
pd.DataFrame: A DataFrame with columns including 'unsteady_number', 'full_path', etc.
|
743
811
|
|
744
812
|
Raises:
|
745
813
|
RuntimeError: If the project has not been initialized.
|
814
|
+
|
815
|
+
Example:
|
816
|
+
>>> unsteady_entries = ras.get_unsteady_entries()
|
817
|
+
>>> print(f"Project contains {len(unsteady_entries)} unsteady flow files")
|
818
|
+
>>> # Display the first unsteady file's properties
|
819
|
+
>>> if not unsteady_entries.empty:
|
820
|
+
... print(unsteady_entries.iloc[0])
|
746
821
|
"""
|
747
822
|
self.check_initialized()
|
748
823
|
return self._get_prj_entries('Unsteady')
|
@@ -750,11 +825,26 @@ class RasPrj:
|
|
750
825
|
@log_call
|
751
826
|
def get_geom_entries(self):
|
752
827
|
"""
|
753
|
-
Get geometry entries from the project
|
828
|
+
Get all geometry entries from the HEC-RAS project.
|
829
|
+
|
830
|
+
Returns a DataFrame containing all geometry files (.g*) in the project
|
831
|
+
with their associated properties, paths and HDF links.
|
754
832
|
|
755
833
|
Returns:
|
756
|
-
pd.DataFrame: DataFrame
|
834
|
+
pd.DataFrame: A DataFrame with columns including 'geom_number', 'full_path',
|
835
|
+
'hdf_path', etc.
|
836
|
+
|
837
|
+
Raises:
|
838
|
+
RuntimeError: If the project has not been initialized.
|
839
|
+
|
840
|
+
Example:
|
841
|
+
>>> geom_entries = ras.get_geom_entries()
|
842
|
+
>>> print(f"Project contains {len(geom_entries)} geometry files")
|
843
|
+
>>> # Display the first geometry file's properties
|
844
|
+
>>> if not geom_entries.empty:
|
845
|
+
... print(geom_entries.iloc[0])
|
757
846
|
"""
|
847
|
+
self.check_initialized()
|
758
848
|
geom_pattern = re.compile(r'Geom File=(\w+)')
|
759
849
|
geom_entries = []
|
760
850
|
|
@@ -780,11 +870,28 @@ class RasPrj:
|
|
780
870
|
@log_call
|
781
871
|
def get_hdf_entries(self):
|
782
872
|
"""
|
783
|
-
Get
|
873
|
+
Get all plan entries that have associated HDF results files.
|
874
|
+
|
875
|
+
This method identifies which plans have been successfully computed
|
876
|
+
and have HDF results available for further analysis.
|
784
877
|
|
785
878
|
Returns:
|
786
879
|
pd.DataFrame: A DataFrame containing plan entries with HDF results.
|
787
|
-
|
880
|
+
Returns an empty DataFrame if no results are found.
|
881
|
+
|
882
|
+
Raises:
|
883
|
+
RuntimeError: If the project has not been initialized.
|
884
|
+
|
885
|
+
Example:
|
886
|
+
>>> hdf_entries = ras.get_hdf_entries()
|
887
|
+
>>> if hdf_entries.empty:
|
888
|
+
... print("No computed results found. Run simulations first.")
|
889
|
+
... else:
|
890
|
+
... print(f"Found results for {len(hdf_entries)} plans")
|
891
|
+
|
892
|
+
Note:
|
893
|
+
This is useful for identifying which plans have been successfully computed
|
894
|
+
and can be used for further results analysis.
|
788
895
|
"""
|
789
896
|
self.check_initialized()
|
790
897
|
|
@@ -798,7 +905,23 @@ class RasPrj:
|
|
798
905
|
|
799
906
|
@log_call
|
800
907
|
def print_data(self):
|
801
|
-
"""
|
908
|
+
"""
|
909
|
+
Print a comprehensive summary of all RAS Object data for this instance.
|
910
|
+
|
911
|
+
This method outputs:
|
912
|
+
- Project information (name, folder, file paths)
|
913
|
+
- Summary of plans, flows, geometries, and unsteady files
|
914
|
+
- HDF results availability
|
915
|
+
- Boundary conditions
|
916
|
+
|
917
|
+
Useful for debugging, validation, and exploring project structure.
|
918
|
+
|
919
|
+
Raises:
|
920
|
+
RuntimeError: If the project has not been initialized.
|
921
|
+
|
922
|
+
Example:
|
923
|
+
>>> ras.print_data() # Displays complete project overview
|
924
|
+
"""
|
802
925
|
self.check_initialized()
|
803
926
|
logger.info(f"--- Data for {self.project_name} ---")
|
804
927
|
logger.info(f"Project folder: {self.project_folder}")
|
@@ -821,33 +944,37 @@ class RasPrj:
|
|
821
944
|
@log_call
|
822
945
|
def get_boundary_conditions(self) -> pd.DataFrame:
|
823
946
|
"""
|
824
|
-
Extract boundary conditions from unsteady flow files
|
947
|
+
Extract boundary conditions from unsteady flow files into a structured DataFrame.
|
825
948
|
|
826
|
-
This method
|
827
|
-
|
828
|
-
|
949
|
+
This method:
|
950
|
+
1. Parses all unsteady flow files to extract boundary condition information
|
951
|
+
2. Creates a structured DataFrame with boundary locations, types and parameters
|
952
|
+
3. Links boundary conditions to their respective unsteady flow files
|
829
953
|
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
954
|
+
Supported boundary condition types include:
|
955
|
+
- Flow Hydrograph
|
956
|
+
- Stage Hydrograph
|
957
|
+
- Normal Depth
|
958
|
+
- Lateral Inflow Hydrograph
|
959
|
+
- Uniform Lateral Inflow Hydrograph
|
960
|
+
- Gate Opening
|
837
961
|
|
838
962
|
Returns:
|
839
|
-
pd.DataFrame: A DataFrame containing detailed boundary condition information
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
963
|
+
pd.DataFrame: A DataFrame containing detailed boundary condition information.
|
964
|
+
Returns an empty DataFrame if no unsteady flow files are present.
|
965
|
+
|
966
|
+
Example:
|
967
|
+
>>> boundaries = ras.get_boundary_conditions()
|
968
|
+
>>> if not boundaries.empty:
|
969
|
+
... print(f"Found {len(boundaries)} boundary conditions")
|
970
|
+
... # Show flow hydrographs only
|
971
|
+
... flow_hydrographs = boundaries[boundaries['bc_type'] == 'Flow Hydrograph']
|
972
|
+
... print(f"Project has {len(flow_hydrographs)} flow hydrographs")
|
973
|
+
|
974
|
+
Note:
|
975
|
+
To see unparsed boundary condition lines for debugging, set logging to DEBUG:
|
845
976
|
import logging
|
846
|
-
getLogger().setLevel(logging.DEBUG)
|
847
|
-
|
848
|
-
boundaries_df = ras_project.get_boundary_conditions()
|
849
|
-
linked to the unsteady flow files. Returns an empty DataFrame if
|
850
|
-
no unsteady flow files are present.
|
977
|
+
logging.getLogger().setLevel(logging.DEBUG)
|
851
978
|
"""
|
852
979
|
boundary_data = []
|
853
980
|
|
@@ -1117,27 +1244,38 @@ ras = RasPrj()
|
|
1117
1244
|
@log_call
|
1118
1245
|
def init_ras_project(ras_project_folder, ras_version=None, ras_object=None):
|
1119
1246
|
"""
|
1120
|
-
Initialize a RAS project.
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
If None, the global 'ras' object
|
1134
|
-
|
1135
|
-
|
1247
|
+
Initialize a RAS project for use with the ras-commander library.
|
1248
|
+
|
1249
|
+
This is the primary function for setting up a HEC-RAS project. It:
|
1250
|
+
1. Finds the project file (.prj) in the specified folder
|
1251
|
+
2. Identifies the appropriate HEC-RAS executable
|
1252
|
+
3. Loads project data (plans, geometries, flows)
|
1253
|
+
4. Creates dataframes containing project components
|
1254
|
+
|
1255
|
+
Args:
|
1256
|
+
ras_project_folder (str or Path): The path to the RAS project folder.
|
1257
|
+
ras_version (str, optional): The version of RAS to use (e.g., "6.6").
|
1258
|
+
Can also be a full path to the Ras.exe file.
|
1259
|
+
If None, will attempt to use a default path.
|
1260
|
+
ras_object (RasPrj, optional): If None, updates the global 'ras' object.
|
1261
|
+
If a RasPrj instance, updates that instance.
|
1262
|
+
If any other value, creates and returns a new RasPrj instance.
|
1136
1263
|
|
1137
1264
|
Returns:
|
1138
|
-
|
1139
|
-
|
1140
|
-
|
1265
|
+
RasPrj: An initialized RasPrj instance.
|
1266
|
+
|
1267
|
+
Raises:
|
1268
|
+
FileNotFoundError: If the specified project folder doesn't exist.
|
1269
|
+
ValueError: If no HEC-RAS project file is found in the folder.
|
1270
|
+
|
1271
|
+
Example:
|
1272
|
+
>>> # Initialize using the global 'ras' object (most common)
|
1273
|
+
>>> init_ras_project("/path/to/project", "6.6")
|
1274
|
+
>>> print(f"Initialized project: {ras.project_name}")
|
1275
|
+
>>>
|
1276
|
+
>>> # Create a new RasPrj instance
|
1277
|
+
>>> my_project = init_ras_project("/path/to/project", "6.6", "new")
|
1278
|
+
>>> print(f"Created project instance: {my_project.project_name}")
|
1141
1279
|
"""
|
1142
1280
|
if not Path(ras_project_folder).exists():
|
1143
1281
|
logger.error(f"The specified RAS project folder does not exist: {ras_project_folder}")
|
@@ -1171,23 +1309,31 @@ def get_ras_exe(ras_version=None):
|
|
1171
1309
|
"""
|
1172
1310
|
Determine the HEC-RAS executable path based on the input.
|
1173
1311
|
|
1312
|
+
This function attempts to find the HEC-RAS executable in the following order:
|
1313
|
+
1. If ras_version is a valid file path to an .exe file, use that path
|
1314
|
+
2. If ras_version is a known version number, use default installation path
|
1315
|
+
3. If global 'ras' object has ras_exe_path, use that
|
1316
|
+
4. As a fallback, return a default path (which may not exist)
|
1317
|
+
|
1174
1318
|
Args:
|
1175
1319
|
ras_version (str, optional): Either a version number or a full path to the HEC-RAS executable.
|
1176
|
-
If None, the function will first check the global 'ras' object for a path.
|
1177
|
-
or a default path.
|
1178
1320
|
|
1179
1321
|
Returns:
|
1180
1322
|
str: The full path to the HEC-RAS executable.
|
1181
1323
|
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1324
|
+
Note:
|
1325
|
+
- HEC-RAS version numbers include: "6.6", "6.5", "6.4.1", "6.3", etc.
|
1326
|
+
- The default installation path follows: C:/Program Files (x86)/HEC/HEC-RAS/{version}/Ras.exe
|
1327
|
+
- Returns a default path ("Ras.exe") if no valid path is found
|
1328
|
+
- This allows the library to function even without HEC-RAS installed
|
1329
|
+
|
1330
|
+
Example:
|
1331
|
+
>>> # Get path for specific version
|
1332
|
+
>>> ras_path = get_ras_exe("6.6")
|
1333
|
+
>>> print(f"HEC-RAS 6.6 executable: {ras_path}")
|
1334
|
+
>>>
|
1335
|
+
>>> # Provide direct path to executable
|
1336
|
+
>>> custom_path = get_ras_exe("C:/My_Programs/HEC-RAS/Ras.exe")
|
1191
1337
|
"""
|
1192
1338
|
if ras_version is None:
|
1193
1339
|
if hasattr(ras, 'ras_exe_path') and ras.ras_exe_path:
|