kdub307 commited on
Commit
60efd26
·
verified ·
1 Parent(s): ee33499

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +173 -123
app.py CHANGED
@@ -88,23 +88,49 @@ def process_dem(dem_file):
88
  # Try to read the file directly to diagnose format issues
89
  try:
90
  with open(dem_file, 'r') as f:
91
- first_lines = [next(f) for _ in range(10) if _ < 10]
92
- print("First 10 lines of the DEM file:")
93
- for line in first_lines:
94
- print(line.strip())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  except Exception as file_read_e:
96
  print(f"Warning: Could not read the file directly: {file_read_e}")
 
97
 
98
  # Read the DEM file with landlab
99
  try:
100
  print(f"Attempting to read file with landlab.io.read_esri_ascii: {dem_file}")
101
- # Debug each line of the file to see what might be wrong
102
- with open(dem_file, 'r') as f:
103
- lines = f.readlines()
104
- for i, line in enumerate(lines[:10]):
105
- print(f"Line {i+1}: {line.strip()}")
106
-
107
- # Try to read with landlab
108
  try:
109
  (grid, elevation) = read_esri_ascii(dem_file)
110
  print(f"Successfully read DEM file with grid shape: {grid.shape}")
@@ -112,34 +138,84 @@ def process_dem(dem_file):
112
  except Exception as e:
113
  print(f"Error with read_esri_ascii: {e}")
114
 
115
- # Try a different approach if the header is invalid
 
 
 
 
116
  try:
117
  print("Trying to parse ASCII grid manually...")
118
  header = {}
119
- with open(dem_file, 'r') as f:
120
- # Parse header
121
- header['ncols'] = int(f.readline().split()[1])
122
- header['nrows'] = int(f.readline().split()[1])
123
- header['xllcorner'] = float(f.readline().split()[1])
124
- header['yllcorner'] = float(f.readline().split()[1])
125
- header['cellsize'] = float(f.readline().split()[1])
126
- header['nodata_value'] = float(f.readline().split()[1])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
- # Create empty grid
129
- mg = RasterModelGrid((header['nrows'], header['ncols']), header['cellsize'])
 
 
 
 
 
 
 
 
130
 
131
- # Read elevation data
132
- elevation = []
133
  for line in f:
134
- elevation.extend([float(val) for val in line.split()])
135
-
136
- # Set elevation field
137
- mg.add_field("topographic__elevation", np.array(elevation), at="node")
 
 
138
 
139
- print(f"Successfully parsed ASCII grid manually. Grid shape: {mg.shape}")
140
- return mg
 
 
 
 
 
 
 
 
 
 
 
 
141
  except Exception as manual_e:
 
142
  print(f"Error with manual parsing: {manual_e}")
 
 
143
  return setup_basic_grid("dome")
144
 
145
  except Exception as inner_e:
@@ -645,6 +721,49 @@ with demo:
645
  return f"Error: File not found at {file_path}"
646
 
647
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
648
  # Copy file to temp directory
649
  filename = os.path.basename(file_path)
650
  temp_path = os.path.join(TEMP_DIR, filename)
@@ -662,10 +781,13 @@ with demo:
662
 
663
  # Store path globally
664
  saved_dem_path = temp_path
665
- file_size = os.path.getsize(temp_path) / (1024*1024)
666
 
667
- return f"File processed and ready: {filename} ({file_size:.2f} MB)"
668
  except Exception as e:
 
 
 
669
  return f"Error processing file: {str(e)}"
670
 
671
  # Connect file upload button
@@ -856,8 +978,9 @@ with demo:
856
  print(f"Warning - Copy error (but continuing anyway): {str(copy_error)}")
857
  else:
858
  print(f"File does not exist at path: {dem_data}")
859
- progress_text.update("Error: Uploaded file not found")
860
- return [None] * 8
 
861
  else:
862
  print("No file provided directly. Checking temp directory for ASC files...")
863
 
@@ -875,7 +998,8 @@ with demo:
875
  dem_data = None
876
 
877
  # Run the landscape evolution simulation
878
- progress_text.update("Starting simulation. This may take several minutes...")
 
879
 
880
  try:
881
  outputs = run_landscape_evolution(
@@ -891,21 +1015,27 @@ with demo:
891
  save_animation=save_animation.value
892
  )
893
 
894
- progress_text.update("Simulation completed successfully!")
895
- return outputs
 
 
 
 
896
  except Exception as sim_error:
897
  import traceback
898
- print(f"Error in simulation: {str(sim_error)}")
 
899
  print(traceback.format_exc())
900
- progress_text.update(f"Error in simulation: {str(sim_error)}")
901
- return [None] * 8
902
 
903
  except Exception as e:
904
  import traceback
905
- print(f"Error setting up simulation: {str(e)}")
 
906
  print(traceback.format_exc())
907
- progress_text.update(f"Error setting up simulation: {str(e)}")
908
- return [None] * 8 # Return None for all outputs
909
 
910
  # Connect the run button to the simulation function using Gradio 5.24.0 syntax
911
  run_btn.click(
@@ -996,84 +1126,4 @@ with demo:
996
 
997
  # Launch the interface
998
  if __name__ == "__main__":
999
- # Create basic event handlers for the buttons
1000
-
1001
- # Simplified handler for simulation button - guaranteed to work
1002
- def simple_run_simulation():
1003
- try:
1004
- progress_text_val = "Starting simulation..."
1005
-
1006
- if saved_dem_path and os.path.exists(saved_dem_path):
1007
- print(f"Running simulation with file: {saved_dem_path}")
1008
- outputs = run_landscape_evolution(
1009
- dem_file=saved_dem_path,
1010
- grid_type=grid_type.value,
1011
- grid_rows=grid_rows.value,
1012
- grid_cols=grid_cols.value,
1013
- grid_resolution=grid_resolution.value,
1014
- simulation_steps=simulation_steps.value,
1015
- rainfall_rate=rainfall_rate.value,
1016
- erosion_rate=erosion_rate.value,
1017
- diffusion_rate=diffusion_rate.value,
1018
- save_animation=save_animation.value
1019
- )
1020
- progress_text_val = "Simulation completed successfully!"
1021
- else:
1022
- print("Using terrain generator (no DEM file)")
1023
- outputs = run_landscape_evolution(
1024
- dem_file=None,
1025
- grid_type=grid_type.value,
1026
- grid_rows=grid_rows.value,
1027
- grid_cols=grid_cols.value,
1028
- grid_resolution=grid_resolution.value,
1029
- simulation_steps=simulation_steps.value,
1030
- rainfall_rate=rainfall_rate.value,
1031
- erosion_rate=erosion_rate.value,
1032
- diffusion_rate=diffusion_rate.value,
1033
- save_animation=save_animation.value
1034
- )
1035
- progress_text_val = "Simulation completed successfully!"
1036
-
1037
- # Add progress text to outputs
1038
- return outputs + (progress_text_val,)
1039
-
1040
- except Exception as e:
1041
- import traceback
1042
- error_msg = f"Error in simulation: {str(e)}"
1043
- print(error_msg)
1044
- print(traceback.format_exc())
1045
- # Return None for all visual outputs plus the error message
1046
- return [None] * 8 + (error_msg,)
1047
-
1048
- # Simplified handler for debug button - guaranteed to work
1049
- def simple_debug():
1050
- if saved_dem_path:
1051
- return f"Saved DEM path: {saved_dem_path} (exists: {os.path.exists(saved_dem_path)})"
1052
- else:
1053
- temp_files = os.listdir(TEMP_DIR)
1054
- asc_files = [f for f in temp_files if f.endswith(".asc")]
1055
- return f"No saved DEM. Files in temp dir: {asc_files}"
1056
-
1057
- # Override the button handlers with simpler versions
1058
- run_btn.click(
1059
- fn=simple_run_simulation,
1060
- inputs=None,
1061
- outputs=[
1062
- initial_topo,
1063
- final_topo,
1064
- diff_topo,
1065
- flow_acc,
1066
- topo_3d,
1067
- evolution_animation,
1068
- report,
1069
- final_dem
1070
- ]
1071
- )
1072
-
1073
- debug_btn.click(
1074
- fn=simple_debug,
1075
- inputs=None,
1076
- outputs=progress_text
1077
- )
1078
-
1079
  demo.launch()
 
88
  # Try to read the file directly to diagnose format issues
89
  try:
90
  with open(dem_file, 'r') as f:
91
+ header_lines = []
92
+ for i in range(6): # ESRI ASCII files should have 6 header lines
93
+ try:
94
+ line = next(f).strip()
95
+ header_lines.append(line)
96
+ print(f"Header line {i+1}: {line}")
97
+ except StopIteration:
98
+ print(f"File too short, only {i} header lines")
99
+ break
100
+
101
+ # Check if the header looks correct
102
+ has_valid_header = (
103
+ len(header_lines) >= 6 and
104
+ header_lines[0].lower().startswith('ncols') and
105
+ header_lines[1].lower().startswith('nrows') and
106
+ header_lines[2].lower().startswith('xll') and
107
+ header_lines[3].lower().startswith('yll') and
108
+ header_lines[4].lower().startswith('cell') and
109
+ header_lines[5].lower().startswith('nodata')
110
+ )
111
+
112
+ if has_valid_header:
113
+ print("File has valid ESRI ASCII header format")
114
+ else:
115
+ print("File doesn't have valid ESRI ASCII header format")
116
+
117
+ # Read a few data lines
118
+ data_lines = []
119
+ for i in range(4): # Read 4 data lines
120
+ try:
121
+ line = next(f).strip()
122
+ data_lines.append(line)
123
+ print(f"Data line {i+1}: {line}")
124
+ except StopIteration:
125
+ break
126
  except Exception as file_read_e:
127
  print(f"Warning: Could not read the file directly: {file_read_e}")
128
+ has_valid_header = False
129
 
130
  # Read the DEM file with landlab
131
  try:
132
  print(f"Attempting to read file with landlab.io.read_esri_ascii: {dem_file}")
133
+
 
 
 
 
 
 
134
  try:
135
  (grid, elevation) = read_esri_ascii(dem_file)
136
  print(f"Successfully read DEM file with grid shape: {grid.shape}")
 
138
  except Exception as e:
139
  print(f"Error with read_esri_ascii: {e}")
140
 
141
+ # If there's no valid header or read_esri_ascii failed, try manual parsing
142
+ if not has_valid_header:
143
+ raise ValueError("Invalid ESRI ASCII header")
144
+
145
+ # Try a different approach if the header is invalid but seems to be in the right format
146
  try:
147
  print("Trying to parse ASCII grid manually...")
148
  header = {}
149
+
150
+ # Parse header from our previously read header lines
151
+ if len(header_lines) >= 6:
152
+ try:
153
+ header['ncols'] = int(header_lines[0].split()[1])
154
+ header['nrows'] = int(header_lines[1].split()[1])
155
+ header['xllcorner'] = float(header_lines[2].split()[1])
156
+ header['yllcorner'] = float(header_lines[3].split()[1])
157
+ header['cellsize'] = float(header_lines[4].split()[1])
158
+ header['nodata_value'] = float(header_lines[5].split()[1])
159
+ except (IndexError, ValueError) as parse_error:
160
+ print(f"Error parsing header lines: {parse_error}")
161
+ raise ValueError("Invalid header values")
162
+ else:
163
+ # If we don't have header lines, try to reopen the file
164
+ with open(dem_file, 'r') as f:
165
+ header['ncols'] = int(f.readline().split()[1])
166
+ header['nrows'] = int(f.readline().split()[1])
167
+ header['xllcorner'] = float(f.readline().split()[1])
168
+ header['yllcorner'] = float(f.readline().split()[1])
169
+ header['cellsize'] = float(f.readline().split()[1])
170
+ header['nodata_value'] = float(f.readline().split()[1])
171
+
172
+ # Validate the header values make sense
173
+ if header['ncols'] <= 0 or header['nrows'] <= 0 or header['cellsize'] <= 0:
174
+ raise ValueError("Invalid header values (negative or zero dimensions)")
175
+
176
+ if header['ncols'] > 10000 or header['nrows'] > 10000:
177
+ raise ValueError("Grid too large, dimensions exceed 10000")
178
 
179
+ print(f"Header parsed: ncols={header['ncols']}, nrows={header['nrows']}, cellsize={header['cellsize']}")
180
+
181
+ # Create empty grid
182
+ mg = RasterModelGrid((header['nrows'], header['ncols']), header['cellsize'])
183
+
184
+ # Read elevation data
185
+ with open(dem_file, 'r') as f:
186
+ # Skip header lines
187
+ for i in range(6):
188
+ f.readline()
189
 
190
+ # Read all data lines
191
+ data = []
192
  for line in f:
193
+ data.extend([float(val) for val in line.split()])
194
+
195
+ # Check if we have the right amount of data
196
+ expected_data_points = header['nrows'] * header['ncols']
197
+ if len(data) != expected_data_points:
198
+ print(f"Warning: Data length mismatch. Expected {expected_data_points}, got {len(data)}")
199
 
200
+ # Fill or truncate if needed
201
+ if len(data) < expected_data_points:
202
+ nodata = header['nodata_value']
203
+ data.extend([nodata] * (expected_data_points - len(data)))
204
+ print(f"Extended data with {expected_data_points - len(data)} nodata values")
205
+ else:
206
+ data = data[:expected_data_points]
207
+ print(f"Truncated data to {expected_data_points} values")
208
+
209
+ # Set elevation field
210
+ mg.add_field("topographic__elevation", np.array(data), at="node")
211
+
212
+ print(f"Successfully parsed ASCII grid manually. Grid shape: {mg.shape}")
213
+ return mg
214
  except Exception as manual_e:
215
+ import traceback
216
  print(f"Error with manual parsing: {manual_e}")
217
+ print(traceback.format_exc())
218
+ print("Falling back to default grid")
219
  return setup_basic_grid("dome")
220
 
221
  except Exception as inner_e:
 
721
  return f"Error: File not found at {file_path}"
722
 
723
  try:
724
+ # Check if file appears to be an ESRI ASCII Grid
725
+ file_size = os.path.getsize(file_path)
726
+ if file_size == 0:
727
+ return "Error: File is empty"
728
+
729
+ # Check first few lines to validate format
730
+ with open(file_path, 'r') as f:
731
+ try:
732
+ # Check header lines
733
+ header_valid = True
734
+ expected_headers = ["ncols", "nrows", "xll", "yll", "cell", "nodata"]
735
+
736
+ for i, expected in enumerate(expected_headers):
737
+ try:
738
+ line = f.readline().strip().lower()
739
+ if not line.startswith(expected):
740
+ header_valid = False
741
+ return f"Error: Invalid ESRI ASCII file format. Expected '{expected}' in line {i+1}, but got: '{line}'"
742
+ except Exception:
743
+ header_valid = False
744
+ return f"Error: File too short, missing required header line {i+1}"
745
+
746
+ # Try to parse a few data lines
747
+ data_lines_valid = True
748
+ for i in range(3): # Check first 3 data lines
749
+ try:
750
+ line = f.readline().strip()
751
+ # Check if line contains valid numbers
752
+ try:
753
+ [float(val) for val in line.split()]
754
+ except ValueError:
755
+ data_lines_valid = False
756
+ return f"Error: Line {i+7} contains non-numeric data: '{line}'"
757
+ except Exception:
758
+ if i == 0: # Must have at least one data line
759
+ return "Error: File contains header but no data lines"
760
+ break
761
+
762
+ except UnicodeDecodeError:
763
+ return "Error: File is not a valid text file. Please upload an ASCII file."
764
+ except Exception as e:
765
+ print(f"Warning during file validation: {str(e)}")
766
+
767
  # Copy file to temp directory
768
  filename = os.path.basename(file_path)
769
  temp_path = os.path.join(TEMP_DIR, filename)
 
781
 
782
  # Store path globally
783
  saved_dem_path = temp_path
784
+ file_size_mb = file_size / (1024*1024)
785
 
786
+ return f"File processed and ready: {filename} ({file_size_mb:.2f} MB)"
787
  except Exception as e:
788
+ import traceback
789
+ print(f"Error processing file: {str(e)}")
790
+ print(traceback.format_exc())
791
  return f"Error processing file: {str(e)}"
792
 
793
  # Connect file upload button
 
978
  print(f"Warning - Copy error (but continuing anyway): {str(copy_error)}")
979
  else:
980
  print(f"File does not exist at path: {dem_data}")
981
+ error_msg = "Error: Uploaded file not found"
982
+ progress_text.update(error_msg)
983
+ return [None] * 8 + [error_msg]
984
  else:
985
  print("No file provided directly. Checking temp directory for ASC files...")
986
 
 
998
  dem_data = None
999
 
1000
  # Run the landscape evolution simulation
1001
+ progress_msg = "Starting simulation. This may take several minutes..."
1002
+ progress_text.update(progress_msg)
1003
 
1004
  try:
1005
  outputs = run_landscape_evolution(
 
1015
  save_animation=save_animation.value
1016
  )
1017
 
1018
+ success_msg = "Simulation completed successfully!"
1019
+ progress_text.update(success_msg)
1020
+
1021
+ # Return the visualization outputs plus the status message
1022
+ return list(outputs) + [success_msg]
1023
+
1024
  except Exception as sim_error:
1025
  import traceback
1026
+ error_msg = f"Error in simulation: {str(sim_error)}"
1027
+ print(error_msg)
1028
  print(traceback.format_exc())
1029
+ progress_text.update(error_msg)
1030
+ return [None] * 8 + [error_msg]
1031
 
1032
  except Exception as e:
1033
  import traceback
1034
+ error_msg = f"Error setting up simulation: {str(e)}"
1035
+ print(error_msg)
1036
  print(traceback.format_exc())
1037
+ progress_text.update(error_msg)
1038
+ return [None] * 8 + [error_msg]
1039
 
1040
  # Connect the run button to the simulation function using Gradio 5.24.0 syntax
1041
  run_btn.click(
 
1126
 
1127
  # Launch the interface
1128
  if __name__ == "__main__":
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1129
  demo.launch()