Skip to content

Commit

Permalink
Isolate run_amp.jl postprocessing
Browse files Browse the repository at this point in the history
This commit adds a new file,
experiments/ClimaEarth/user_io/postprocessing.jl, which contains
the `postprocess_sim` function. This function copies the if statements
previously at the end of run_amip.jl, but it uses dispatch for the simulation
mode.
  • Loading branch information
imreddyTeja committed Dec 12, 2024
1 parent 22fe7b7 commit fed5e27
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 76 deletions.
4 changes: 2 additions & 2 deletions experiments/ClimaEarth/Manifest.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is machine-generated - editing it directly is not advised

julia_version = "1.10.6"
julia_version = "1.10.7"
manifest_format = "2.0"
project_hash = "9d4daca72a27dd26a4e46ba913787d7e63971347"

Expand Down Expand Up @@ -326,7 +326,7 @@ uuid = "d934ef94-cdd4-4710-83d6-720549644b70"
version = "0.3.18"

[[deps.ClimaCoupler]]
deps = ["ClimaComms", "ClimaCore", "ClimaCoreTempestRemap", "Dates", "JLD2", "Logging", "NCDatasets", "SciMLBase", "StaticArrays", "SurfaceFluxes", "Thermodynamics"]
deps = ["ClimaComms", "ClimaCore", "ClimaCoreTempestRemap", "ClimaUtilities", "Dates", "JLD2", "Logging", "NCDatasets", "SciMLBase", "StaticArrays", "SurfaceFluxes", "Thermodynamics"]
path = "../.."
uuid = "4ade58fe-a8da-486c-bd89-46df092ec0c7"
version = "0.1.1"
Expand Down
87 changes: 13 additions & 74 deletions experiments/ClimaEarth/run_amip.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ We can additionally pass the configuration dictionary to the component model ini

include("cli_options.jl")
include("user_io/arg_parsing.jl")
include("user_io/postprocessing.jl")
config_dict = get_coupler_config()

# Select the correct timestep for each component model based on which are available
Expand Down Expand Up @@ -817,78 +818,16 @@ The postprocessing includes:
=#

if ClimaComms.iamroot(comms_ctx)

## energy check plots
if !isnothing(cs.conservation_checks) && cs.mode.type isa AbstractSlabPlanetModeType
@info "Conservation Check Plots"
plot_global_conservation(
cs.conservation_checks.energy,
cs,
conservation_softfail,
figname1 = joinpath(dir_paths.artifacts, "total_energy_bucket.png"),
figname2 = joinpath(dir_paths.artifacts, "total_energy_log_bucket.png"),
)
plot_global_conservation(
cs.conservation_checks.water,
cs,
conservation_softfail,
figname1 = joinpath(dir_paths.artifacts, "total_water_bucket.png"),
figname2 = joinpath(dir_paths.artifacts, "total_water_log_bucket.png"),
)
end

## plotting AMIP results
if cs.mode.type isa AMIP_mode
if use_coupler_diagnostics
## plot data that correspond to the model's last save_hdf5 call (i.e., last month)
@info "AMIP plots"

## ClimaESM
include("user_io/diagnostics_plots.jl")

# define variable names and output directories for each diagnostic
amip_short_names_atmos = ["ta", "ua", "hus", "clw", "pr", "ts", "toa_fluxes_net"]
amip_short_names_coupler = ["F_turb_energy"]
output_dir_coupler = dir_paths.output

# Check if all output variables are available in the specified directories
make_diagnostics_plots(
atmos_output_dir,
dir_paths.artifacts,
short_names = amip_short_names_atmos,
output_prefix = "atmos_",
)
make_diagnostics_plots(
output_dir_coupler,
dir_paths.artifacts,
short_names = amip_short_names_coupler,
output_prefix = "coupler_",
)
end

# Check this because we only want monthly data for making plots
if t_end > 84600 * 31 * 3 && output_default_diagnostics
include("leaderboard/leaderboard.jl")
leaderboard_base_path = dir_paths.artifacts
compute_leaderboard(leaderboard_base_path, atmos_output_dir)
compute_pfull_leaderboard(leaderboard_base_path, atmos_output_dir)
end
end
## plot extra atmosphere diagnostics if specified
if plot_diagnostics
@info "Plotting diagnostics"
include("user_io/diagnostics_plots.jl")
make_diagnostics_plots(atmos_output_dir, dir_paths.artifacts)
end

## plot all model states and coupler fields (useful for debugging)
!CA.is_distributed(comms_ctx) && debug(cs, dir_paths.artifacts)

# if isinteractive() #hide
# ## clean up for interactive runs, retain all output otherwise #hide
# rm(dir_paths.output; recursive = true, force = true) #hide
# end #hide

## close all AMIP diagnostics file writers
!isnothing(amip_diags_handler) && map(diag -> close(diag.output_writer), amip_diags_handler.scheduled_diagnostics)
postprocessing_vars = (;
dir_paths,
plot_diagnostics,
use_coupler_diagnostics,
output_default_diagnostics,
t_end,
conservation_softfail,
atmos_output_dir,
amip_diags_handler,
comms_ctx,
)
postprocess_sim(cs.mode.type, cs, postprocessing_vars)
end
123 changes: 123 additions & 0 deletions experiments/ClimaEarth/user_io/postprocessing.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
## helpers for user-specified IO
include("debug_plots.jl")
include("diagnostics_plots.jl")

"""
postprocess_sim(mode_type::AbstractSlabPlanetModeType, cs, postprocessing_vars)
If they exist, perform conservation checks, for any slabplanet simulation, and then call
`common_postprocessing` to perform common postprocessing tasks that are common to all simulation types.
"""
function postprocess_sim(mode_type::AbstractSlabPlanetModeType, cs, postprocessing_vars)
(;
dir_paths,
plot_diagnostics,
use_coupler_diagnostics,
output_default_diagnostics,
t_end,
conservation_softfail,
atmos_output_dir,
amip_diags_handler,
comms_ctx,
) = postprocessing_vars

if !isnothing(cs.conservation_checks)
@info "Conservation Check Plots"
plot_global_conservation(
cs.conservation_checks.energy,
cs,
conservation_softfail,
figname1 = joinpath(dir_paths.artifacts, "total_energy_bucket.png"),
figname2 = joinpath(dir_paths.artifacts, "total_energy_log_bucket.png"),
)
plot_global_conservation(
cs.conservation_checks.water,
cs,
conservation_softfail,
figname1 = joinpath(dir_paths.artifacts, "total_water_bucket.png"),
figname2 = joinpath(dir_paths.artifacts, "total_water_log_bucket.png"),
)
end
common_postprocessing(cs, postprocessing_vars)
end

"""
postprocess_sim(mode_type::AMIP_mode, cs, postprocessing_vars)
Conditionally plot AMIP diagnostics and call `common_postprocessing` to perform
postprocessing tasks that are common to all simulation types.
"""
function postprocess_sim(mode_type::AMIP_mode, cs, postprocessing_vars)
(;
dir_paths,
plot_diagnostics,
use_coupler_diagnostics,
output_default_diagnostics,
t_end,
conservation_softfail,
atmos_output_dir,
amip_diags_handler,
comms_ctx,
) = postprocessing_vars

if use_coupler_diagnostics
## plot data that correspond to the model's last save_hdf5 call (i.e., last month)
@info "AMIP plots"

## ClimaESM
include("user_io/diagnostics_plots.jl")

# define variable names and output directories for each diagnostic
amip_short_names_atmos = ["ta", "ua", "hus", "clw", "pr", "ts", "toa_fluxes_net"]
amip_short_names_coupler = ["F_turb_energy"]
output_dir_coupler = dir_paths.output

# Check if all output variables are available in the specified directories
make_diagnostics_plots(
atmos_output_dir,
dir_paths.artifacts,
short_names = amip_short_names_atmos,
output_prefix = "atmos_",
)
make_diagnostics_plots(
output_dir_coupler,
dir_paths.artifacts,
short_names = amip_short_names_coupler,
output_prefix = "coupler_",
)
end

# Check this because we only want monthly data for making plots
if t_end > 84600 * 31 * 3 && output_default_diagnostics
include("leaderboard/leaderboard.jl")
leaderboard_base_path = dir_paths.artifacts
compute_leaderboard(leaderboard_base_path, atmos_output_dir)
compute_pfull_leaderboard(leaderboard_base_path, atmos_output_dir)
end
common_postprocessing(cs, postprocessing_vars)
end

"""
common_postprocessing(cs, postprocessing_vars)
Perfrom postprocessing common to all simulation types.
"""
function common_postprocessing(cs, postprocessing_vars)
(; plot_diagnostics, comms_ctx, dir_paths, amip_diags_handler, atmos_output_dir) = postprocessing_vars
if plot_diagnostics
@info "Plotting diagnostics"
include("user_io/diagnostics_plots.jl")
make_diagnostics_plots(atmos_output_dir, dir_paths.artifacts)
end

## plot all model states and coupler fields (useful for debugging)
!CA.is_distributed(comms_ctx) && debug(cs, dir_paths.artifacts)

# if isinteractive() #hide
# ## clean up for interactive runs, retain all output otherwise #hide
# rm(dir_paths.output; recursive = true, force = true) #hide
# end #hide

## close all AMIP diagnostics file writers
!isnothing(amip_diags_handler) && map(diag -> close(diag.output_writer), amip_diags_handler.scheduled_diagnostics)
end

0 comments on commit fed5e27

Please sign in to comment.