Skip to content

Commit a7df349

Browse files
committed
write inputfile debug gui button added.
1 parent c4d6da9 commit a7df349

File tree

3 files changed

+62
-9
lines changed

3 files changed

+62
-9
lines changed

aeolis/gui/application.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,19 @@ def create_input_file_tab(self, tab_control):
210210
command=self.browse_save_location)
211211
save_browse_button.grid(row=3, column=2, sticky=W, pady=5, padx=5)
212212

213-
# Save button
213+
# Save button (diffs only)
214214
save_config_button = ttk.Button(file_ops_frame, text="Save Configuration",
215-
command=self.save_config_file)
215+
command=self.save_config_file)
216216
save_config_button.grid(row=4, column=1, sticky=W, pady=10, padx=10)
217+
save_config_desc = ttk.Label(file_ops_frame, text="Writes only parameters that differ from defaults.")
218+
save_config_desc.grid(row=4, column=2, sticky=W, pady=10, padx=5)
219+
220+
# Save full button (all params)
221+
save_full_config_button = ttk.Button(file_ops_frame, text="Save Full Configuration",
222+
command=self.save_full_config_file)
223+
save_full_config_button.grid(row=5, column=1, sticky=W, pady=5, padx=10)
224+
save_full_config_desc = ttk.Label(file_ops_frame, text="Writes every parameter, including defaults.")
225+
save_full_config_desc.grid(row=5, column=2, sticky=W, pady=5, padx=5)
217226

218227
def create_domain_tab(self, tab_control):
219228
# Create the 'Domain' tab
@@ -460,6 +469,31 @@ def save_config_file(self):
460469
messagebox.showerror("Error", error_msg)
461470
print(error_msg)
462471

472+
def save_full_config_file(self):
473+
"""Save the full configuration (including defaults) to a file"""
474+
save_path = self.save_config_entry.get()
475+
476+
if not save_path:
477+
messagebox.showwarning("Warning", "Please specify a file path to save the configuration.")
478+
return
479+
480+
try:
481+
# Update dictionary with current entry values
482+
for field, entry in self.entries.items():
483+
value = entry.get()
484+
self.dic[field] = None if value.strip() == '' else value
485+
486+
# Write the full configuration file
487+
aeolis.inout.write_configfile(save_path, self.dic, include_defaults=True)
488+
489+
messagebox.showinfo("Success", f"Full configuration saved to:\n{save_path}")
490+
491+
except Exception as e:
492+
import traceback
493+
error_msg = f"Failed to save full config file: {str(e)}\n\n{traceback.format_exc()}"
494+
messagebox.showerror("Error", error_msg)
495+
print(error_msg)
496+
463497
def toggle_color_limits(self):
464498
"""Enable or disable colorbar limit entries based on auto limits checkbox"""
465499
if self.auto_limits_var.get():

aeolis/hydro.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def interpolate(s, p, t):
6767
if p['process_tide']:
6868
# Check if SWL or zs are not provided by some external model
6969
# In that case, skip initialization
70-
if not p['external_vars'] or('zs' not in p['external_vars']) :
70+
if not p['external_vars'] or ('zs' not in p['external_vars']) :
7171

7272
if p['tide_file'] is not None:
7373
s['SWL'][:,:] = interp_circular(t,
@@ -159,7 +159,7 @@ def interpolate(s, p, t):
159159

160160
if p['process_runup']:
161161
ny = p['ny']
162-
if ('Hs' in p['external_vars']):
162+
if p['external_vars'] and ('Hs' in p['external_vars']):
163163

164164
eta, sigma_s, R = calc_runup_stockdon(s['Hs'], s['Tp'], p['beach_slope'])
165165
s['R'][:] = R

aeolis/inout.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def read_configfile(configfile, parse_files=True, load_defaults=True):
121121
return p
122122

123123

124-
def write_configfile(configfile, p=None):
124+
def write_configfile(configfile, p=None, include_defaults=False):
125125
'''Write model configuration file
126126
127127
Writes model configuration to file. If no model configuration is
@@ -138,6 +138,9 @@ def write_configfile(configfile, p=None):
138138
Model configuration file
139139
p : dict, optional
140140
Dictionary with model configuration parameters
141+
include_defaults : bool, optional
142+
If True, write all parameters including defaults; if False, skip
143+
parameters equal to the default values
141144
142145
Returns
143146
-------
@@ -154,6 +157,22 @@ def write_configfile(configfile, p=None):
154157
if p is None:
155158
p = DEFAULT_CONFIG.copy()
156159

160+
# Helper: safely determine if a value equals the default without broadcasting errors
161+
def _is_default_value(key, value):
162+
if key not in DEFAULT_CONFIG:
163+
return False
164+
165+
default = DEFAULT_CONFIG[key]
166+
167+
try:
168+
return np.array_equal(np.asarray(value, dtype=object),
169+
np.asarray(default, dtype=object))
170+
except Exception:
171+
try:
172+
return value == default
173+
except Exception:
174+
return False
175+
157176
# Parse constants.py to extract section headers, order, and comments
158177
import aeolis.constants
159178
constants_file = aeolis.constants.__file__
@@ -239,8 +258,8 @@ def write_configfile(configfile, p=None):
239258
for key in section_keys:
240259
value = p[key]
241260

242-
# Skip this key if its value matches the default
243-
if key in DEFAULT_CONFIG and np.all(value == DEFAULT_CONFIG[key]) :
261+
# Skip this key if its value matches the default and skipping is allowed
262+
if not include_defaults and _is_default_value(key, value):
244263
continue
245264

246265
comment = comments.get(key, '')
@@ -263,8 +282,8 @@ def write_configfile(configfile, p=None):
263282
for key in sorted(remaining_keys):
264283
value = p[key]
265284

266-
# Skip this key if its value matches the default
267-
if key in DEFAULT_CONFIG and np.all(value == DEFAULT_CONFIG[key]):
285+
# Skip this key if its value matches the default and skipping is allowed
286+
if not include_defaults and _is_default_value(key, value):
268287
continue
269288

270289
comment = comments.get(key, '')

0 commit comments

Comments
 (0)