Skip to content

Commit 646cb43

Browse files
committed
minor dir_paths cleanup
1 parent 3faaaee commit 646cb43

File tree

11 files changed

+111
-105
lines changed

11 files changed

+111
-105
lines changed

experiments/ClimaEarth/setup_run.jl

Lines changed: 29 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -143,40 +143,29 @@ function CoupledSimulation(config_dict::AbstractDict)
143143
) = get_coupler_args(config_dict)
144144

145145
#=
146-
### I/O Directory Setup `setup_output_dirs` returns `dir_paths.output =
147-
COUPLER_OUTPUT_DIR`, which is the directory where the output of the simulation
148-
will be saved, `dir_paths.artifacts` is the directory where the plots (from
149-
postprocessing and the conservation checks) of the simulation will be saved,
150-
#and `dir_paths.checkpoints`, where restart files are saved.
146+
### I/O Directory Setup
147+
`setup_output_dirs` returns a NamedTuple with the paths to
148+
output directories for each component and the coupler,
149+
as well as paths to artifacts, regrid, and checkpoints directories.
151150
=#
152-
153-
dir_paths =
154-
Utilities.setup_output_dirs(output_dir = output_dir_root, comms_ctx = comms_ctx)
155-
@info "Coupler output directory $(dir_paths.output)"
156-
@info "Coupler artifacts directory $(dir_paths.artifacts)"
157-
@info "Coupler checkpoint directory $(dir_paths.checkpoints)"
158-
159-
atmos_output_dir = joinpath(dir_paths.output, "clima_atmos")
160-
isdir(atmos_output_dir) || mkpath(atmos_output_dir)
161-
land_output_dir = joinpath(dir_paths.output, "clima_land")
162-
isdir(land_output_dir) || mkpath(land_output_dir)
163-
ocean_output_dir = joinpath(dir_paths.output, "clima_ocean")
164-
isdir(ocean_output_dir) || mkpath(ocean_output_dir)
165-
151+
dir_paths = Utilities.setup_output_dirs(
152+
output_dir_root = output_dir_root,
153+
comms_ctx = comms_ctx,
154+
)
166155

167156
## get component model dictionaries (if applicable)
168157
## Note this step must come after parsing the coupler config dictionary, since
169158
## some parameters are passed from the coupler config to the component model configs
170-
atmos_config_dict = get_atmos_config_dict(config_dict, atmos_output_dir)
159+
atmos_config_dict = get_atmos_config_dict(config_dict, dir_paths.atmos_output_dir)
171160

172161
## set unique random seed if desired, otherwise use default
173162
Random.seed!(random_seed)
174163
@info "Random seed set to $(random_seed)"
175164

176165
if detect_restart_files
177166
isnothing(restart_t) &&
178-
(restart_t = Checkpointer.t_start_from_checkpoint(dir_paths.checkpoints))
179-
isnothing(restart_dir) && (restart_dir = dir_paths.checkpoints)
167+
(restart_t = Checkpointer.t_start_from_checkpoint(dir_paths.checkpoints_dir))
168+
isnothing(restart_dir) && (restart_dir = dir_paths.checkpoints_dir)
180169
end
181170
should_restart = !isnothing(restart_t) && !isnothing(restart_dir)
182171
if should_restart
@@ -205,12 +194,6 @@ function CoupledSimulation(config_dict::AbstractDict)
205194

206195
tspan = (t_start, t_end)
207196

208-
#=
209-
## Data File Paths
210-
=#
211-
land_mask_data =
212-
joinpath(@clima_artifact("landsea_mask_60arcseconds", comms_ctx), "landsea_mask.nc")
213-
214197
#=
215198
## Component Model Initialization
216199
Here we set initial and boundary conditions for each component model. Each component model is required to have an `init` function that
@@ -275,6 +258,8 @@ function CoupledSimulation(config_dict::AbstractDict)
275258
=#
276259

277260
# Preprocess the file to be 1s and 0s before remapping into onto the grid
261+
land_mask_data =
262+
joinpath(@clima_artifact("landsea_mask_60arcseconds", comms_ctx), "landsea_mask.nc")
278263
land_fraction = SpaceVaryingInput(land_mask_data, "landsea", boundary_space)
279264
land_fraction = ifelse.(land_fraction .> eps(FT), FT(1), FT(0))
280265

@@ -325,7 +310,7 @@ function CoupledSimulation(config_dict::AbstractDict)
325310
dt = component_dt_dict["dt_land"],
326311
tspan,
327312
start_date,
328-
output_dir = land_output_dir,
313+
output_dir = dir_paths.land_output_dir,
329314
area_fraction = land_fraction,
330315
shared_surface_space,
331316
surface_elevation,
@@ -342,7 +327,7 @@ function CoupledSimulation(config_dict::AbstractDict)
342327
dt = component_dt_dict["dt_land"],
343328
tspan,
344329
start_date,
345-
output_dir = land_output_dir,
330+
output_dir = dir_paths.land_output_dir,
346331
area_fraction = land_fraction,
347332
shared_surface_space,
348333
land_spun_up_ic,
@@ -382,7 +367,7 @@ function CoupledSimulation(config_dict::AbstractDict)
382367
ocean_fraction,
383368
start_date,
384369
stop_date;
385-
output_dir = ocean_output_dir,
370+
output_dir = dir_paths.ocean_output_dir,
386371
comms_ctx,
387372
)
388373
else
@@ -410,7 +395,7 @@ function CoupledSimulation(config_dict::AbstractDict)
410395
dt = component_dt_dict["dt_land"],
411396
tspan,
412397
start_date,
413-
output_dir = land_output_dir,
398+
output_dir = dir_paths.land_output_dir,
414399
area_fraction = land_fraction,
415400
surface_elevation,
416401
land_temperature_anomaly,
@@ -450,9 +435,8 @@ function CoupledSimulation(config_dict::AbstractDict)
450435

451436
## coupler exchange fields
452437
coupler_field_names = Interfacer.default_coupler_fields()
453-
for sim in model_sims
454-
Interfacer.add_coupler_fields!(coupler_field_names, sim)
455-
end
438+
foreach(sim -> Interfacer.add_coupler_fields!(coupler_field_names, sim), model_sims)
439+
456440
# add coupler fields required to track conservation, if specified
457441
energy_check && push!(coupler_field_names, :P_net)
458442

@@ -500,11 +484,9 @@ function CoupledSimulation(config_dict::AbstractDict)
500484
=#
501485
if use_coupler_diagnostics
502486
@info "Using default coupler diagnostics"
503-
coupler_diags_path = joinpath(dir_paths.output, "coupler")
504-
isdir(coupler_diags_path) || mkpath(coupler_diags_path)
505487
diags_handler = coupler_diagnostics_setup(
506488
coupler_fields,
507-
coupler_diags_path,
489+
dir_paths.coupler_output_dir,
508490
start_date,
509491
tspan[1],
510492
diagnostics_dt,
@@ -631,28 +613,23 @@ end
631613
632614
Process the results after a simulation has completed, including generating
633615
plots, checking conservation, and other diagnostics.
616+
All postprocessing is performed using the root process only, if applicable.
634617
635618
When `conservation_softfail` is true, throw an error if conservation is not
636619
respected.
637620
638621
When `rmse_check` is true, compute the RMSE against observations and test
639622
that it is below a certain threshold.
623+
624+
The postprocessing includes:
625+
- Energy and water conservation checks (if running SlabPlanet with checks enabled)
626+
- Animations (if not running in MPI)
627+
- AMIP plots of the final state of the model
628+
- Error against observations
629+
- Optional additional atmosphere diagnostics plots
630+
- Plots of useful coupler and component model fields for debugging
640631
"""
641632
function postprocess(cs; conservation_softfail = false, rmse_check = false)
642-
#=
643-
## Postprocessing
644-
All postprocessing is performed using the root process only, if applicable.
645-
Our postprocessing consists of outputting a number of plots to visualize the model output.
646-
647-
The postprocessing includes:
648-
- Energy and water conservation checks (if running SlabPlanet with checks enabled)
649-
- Animations (if not running in MPI)
650-
- AMIP plots of the final state of the model
651-
- Error against observations
652-
- Optional additional atmosphere diagnostics plots
653-
- Plots of useful coupler and component model fields for debugging
654-
=#
655-
656633
if ClimaComms.iamroot(ClimaComms.context(cs)) && !isnothing(cs.diags_handler)
657634
postprocessing_vars = (; conservation_softfail, rmse_check)
658635
postprocess_sim(cs, postprocessing_vars)

experiments/ClimaEarth/test/component_model_tests/climaland_tests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ end
9797
Ref(-1), # prev_checkpoint_t
9898
model_sims,
9999
(;), # callbacks
100-
(;), # dirs
100+
(;), # dir_paths
101101
thermo_params, # thermo_params
102102
nothing, # diags_handler
103103
)

experiments/ClimaEarth/test/debug_plots_tests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ plot_field_names(sim::Interfacer.SurfaceStub) = (:stub_field,)
8787
Ref(-1), # prev_checkpoint_t
8888
model_sims, # model_sims
8989
(;), # callbacks
90-
(;), # dirs
90+
(;), # dir_paths
9191
nothing, # thermo_params
9292
nothing, # diags_handler
9393
)

experiments/ClimaEarth/test/restart.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ four_steps_reading = deepcopy(four_steps)
5959

6060
four_steps_reading["t_end"] = "900secs"
6161
four_steps_reading["detect_restart_files"] = true
62-
four_steps_reading["restart_dir"] = cs_four_steps.dirs.checkpoints
62+
four_steps_reading["restart_dir"] = cs_four_steps.dir_paths.checkpoints_dir
6363
four_steps_reading["restart_t"] = 720
6464
four_steps_reading["job_id"] = "four_steps_reading"
6565

experiments/ClimaEarth/user_io/postprocessing.jl

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,23 @@ conservation checks if enabled, and closing all diagnostics file writers.
1414
"""
1515
function postprocess_sim(cs, postprocessing_vars)
1616
(; conservation_softfail, rmse_check) = postprocessing_vars
17-
output_dir = cs.dirs.output
18-
artifact_dir = cs.dirs.artifacts
19-
coupler_output_dir = joinpath(output_dir, "coupler")
20-
atmos_output_dir = joinpath(output_dir, "clima_atmos")
21-
land_output_dir = joinpath(output_dir, "clima_land")
22-
ocean_output_dir = joinpath(output_dir, "clima_ocean")
17+
(;
18+
coupler_output_dir,
19+
atmos_output_dir,
20+
land_output_dir,
21+
ocean_output_dir,
22+
artifacts_dir,
23+
) = cs.dir_paths
2324

2425
# Plot generic diagnostics
2526
@info "Plotting diagnostics for coupler, atmos, land, and ocean"
26-
make_diagnostics_plots(coupler_output_dir, artifact_dir, output_prefix = "coupler_")
27-
make_diagnostics_plots(atmos_output_dir, artifact_dir, output_prefix = "atmos_")
28-
make_diagnostics_plots(land_output_dir, artifact_dir, output_prefix = "land_")
29-
make_ocean_diagnostics_plots(ocean_output_dir, artifact_dir, output_prefix = "ocean_")
27+
make_diagnostics_plots(coupler_output_dir, artifacts_dir, output_prefix = "coupler_")
28+
make_diagnostics_plots(atmos_output_dir, artifacts_dir, output_prefix = "atmos_")
29+
make_diagnostics_plots(land_output_dir, artifacts_dir, output_prefix = "land_")
30+
make_ocean_diagnostics_plots(ocean_output_dir, artifacts_dir, output_prefix = "ocean_")
3031

3132
# Plot all model states and coupler fields (useful for debugging)
32-
ClimaComms.context(cs) isa ClimaComms.SingletonCommsContext && debug(cs, artifact_dir)
33+
ClimaComms.context(cs) isa ClimaComms.SingletonCommsContext && debug(cs, artifacts_dir)
3334

3435
# If we have enough data (in time, but also enough variables), plot the leaderboard.
3536
# We need pressure to compute the leaderboard.
@@ -39,7 +40,7 @@ function postprocess_sim(cs, postprocessing_vars)
3940
times = CAN.times(get(simdir, first(CAN.available_vars(simdir))))
4041
t_end = times[end]
4142
if t_end > 84600 * 31 * 3 # 3 months for spin up
42-
leaderboard_base_path = artifact_dir
43+
leaderboard_base_path = artifacts_dir
4344
compute_leaderboard(leaderboard_base_path, atmos_output_dir, 3)
4445
rmse_check && test_rmse_thresholds(atmos_output_dir, 3)
4546
pressure_in_output &&
@@ -54,15 +55,15 @@ function postprocess_sim(cs, postprocessing_vars)
5455
cs.conservation_checks.energy,
5556
cs,
5657
conservation_softfail,
57-
figname1 = joinpath(cs.dirs.artifacts, "total_energy_bucket.png"),
58-
figname2 = joinpath(cs.dirs.artifacts, "total_energy_log_bucket.png"),
58+
figname1 = joinpath(artifacts_dir, "total_energy_bucket.png"),
59+
figname2 = joinpath(artifacts_dir, "total_energy_log_bucket.png"),
5960
)
6061
plot_global_conservation(
6162
cs.conservation_checks.water,
6263
cs,
6364
conservation_softfail,
64-
figname1 = joinpath(cs.dirs.artifacts, "total_water_bucket.png"),
65-
figname2 = joinpath(cs.dirs.artifacts, "total_water_log_bucket.png"),
65+
figname1 = joinpath(artifacts_dir, "total_water_bucket.png"),
66+
figname2 = joinpath(artifacts_dir, "total_water_log_bucket.png"),
6667
)
6768
end
6869

@@ -97,25 +98,29 @@ end
9798
"""
9899
save_sypd_walltime_to_disk(cs, walltime)
99100
100-
Save the computed `sypd`, `walltime_per_coupling_step`, and memory usage to text files.
101+
Save the computed `sypd`, `walltime_per_coupling_step`,
102+
and memory usage to text files in the `artifacts` directory.
101103
"""
102104
function save_sypd_walltime_to_disk(cs, walltime)
103105
if ClimaComms.iamroot(ClimaComms.context(cs))
104106
sypd = simulated_years_per_day(cs, walltime)
105107
walltime_per_step = walltime_per_coupling_step(cs, walltime)
106108

107-
open(joinpath(cs.dirs.artifacts, "sypd.txt"), "w") do sypd_filename
109+
open(joinpath(cs.dir_paths.artifacts_dir, "sypd.txt"), "w") do sypd_filename
108110
println(sypd_filename, "$sypd")
109111
end
110112

111113
open(
112-
joinpath(cs.dirs.artifacts, "walltime_per_step.txt"),
114+
joinpath(cs.dir_paths.artifacts_dir, "walltime_per_step.txt"),
113115
"w",
114116
) do walltime_per_step_filename
115117
println(walltime_per_step_filename, "$(walltime_per_step)")
116118
end
117119

118-
open(joinpath(cs.dirs.artifacts, "max_rss_cpu.txt"), "w") do cpu_max_rss_filename
120+
open(
121+
joinpath(cs.dir_paths.artifacts_dir, "max_rss_cpu.txt"),
122+
"w",
123+
) do cpu_max_rss_filename
119124
cpu_max_rss_GB = Utilities.show_memory_usage()
120125
println(cpu_max_rss_filename, cpu_max_rss_GB)
121126
end

src/Checkpointer.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ function checkpoint_sims(cs::Interfacer.CoupledSimulation)
134134
time = Int(round(float(cs.t[])))
135135
day = floor(Int, time / (60 * 60 * 24))
136136
sec = floor(Int, time % (60 * 60 * 24))
137-
output_dir = cs.dirs.checkpoints
137+
output_dir = cs.dir_paths.checkpoints_dir
138138
prev_checkpoint_t = cs.prev_checkpoint_t[]
139139
comms_ctx = ClimaComms.context(cs)
140140

src/Interfacer.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ struct CoupledSimulation{
7070
prev_checkpoint_t::CTT
7171
model_sims::NTMS
7272
callbacks::CALLBACKS
73-
dirs::NTP
73+
dir_paths::NTP
7474
thermo_params::TP
7575
diags_handler::DH
7676
end
@@ -83,7 +83,7 @@ function Base.show(io::IO, sim::CoupledSimulation)
8383
io,
8484
"Coupled Simulation\n",
8585
"├── Running on: $(device_type)\n",
86-
"├── Output folder: $(sim.dirs.output)\n",
86+
"├── Output folder: $(sim.dir_paths.output_dir_root)\n",
8787
"└── Current date: $(current_date(sim))\n",
8888
)
8989
end

0 commit comments

Comments
 (0)