Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 6 additions & 12 deletions .buildkite/longruns/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -184,21 +184,15 @@ steps:
- group: "Calibration experiments"

steps:
- label: "Perfect model calibration test"
key: "amip_pm_calibration"
- label: "Subseasonal calibration test"
key: "subseasonal_calibration"
command:
- "julia --color=yes --project=experiments/ClimaEarth experiments/calibration/run_calibration.jl"
artifact_paths: "experiments/calibration/output/*"
env:
CLIMACOMMS_DEVICE: "CUDA"
CLIMACOMMS_CONTEXT: "MPI"
- julia --color=yes --project=experiments/ClimaEarth experiments/calibration/subseasonal/generate_observations.jl
- julia --color=yes --project=experiments/ClimaEarth experiments/calibration/subseasonal/run_calibration.jl
artifact_paths: "experiments/calibration/subseasonal/output/*"
agents:
queue: clima
slurm_mem: 96GB
slurm_ntasks: 3
slurm_gpus_per_task: 1
slurm_cpus_per_task: 4
slurm_time: 05:00:00
slurm_time: 24:00:00

- wait

Expand Down
2 changes: 1 addition & 1 deletion .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ steps:
- label: "Perfect model calibration test"
key: "amip_pm_calibration"
command:
- "julia --color=yes --project=experiments/ClimaEarth experiments/calibration/run_calibration.jl"
- "julia --color=yes --project=experiments/ClimaEarth experiments/calibration/test/run_calibration.jl"
artifact_paths: "experiments/calibration/output/*"
env:
CLIMACOMMS_DEVICE: "CUDA"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ docs/src/generated/
# Experiments
!experiments/ClimaEarth/**/Manifest.toml
!experiments/ClimaCore/**/Manifest.toml
experiments/calibration/coarse_amip/output*/

# Output
output/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe instead we can change this to:

Suggested change
output/
*output*

so we don't have a path in the gitignore that depends on a run name?

Expand Down
9 changes: 5 additions & 4 deletions config/atmos_configs/climaatmos_wx_diagedmf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ insolation: "timevarying"
rad: allskywithclear
dt_cloud_fraction: "1hours"
dt_rad: "1hours"
# time_varying_trace_gases: ["O3"]
# prescribed_aerosols: ["CB1", "CB2", "DST01", "OC1", "OC2", "SO4", "SSLT01"]
aerosol_radiation: true
time_varying_trace_gases: ["CO2", "O3"]
prescribed_aerosols: ["CB1", "CB2", "DST01", "DST02", "DST03", "DST04", "DST05", "OC1", "OC2", "SO4", "SSLT01", "SSLT02", "SSLT03", "SSLT04", "SSLT05"]
turbconv: diagnostic_edmfx
implicit_diffusion: true
approximate_linear_solve_iters: 2
prognostic_tke: true
edmfx_upwinding: first_order
h_elem: 15
z_max: 48000.0
h_elem: 16
z_max: 60000.0
z_elem: 63
dz_bottom: 30.0
edmfx_entr_model: "Generalized"
Expand Down
32 changes: 15 additions & 17 deletions config/subseasonal_configs/wxquest_diagedmf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,34 @@ FLOAT_TYPE: "Float32"
albedo_model: "CouplerAlbedo"
atmos_config_file: "config/atmos_configs/climaatmos_wx_diagedmf.yml"
coupler_toml: ["toml/amip_diagedmf.toml"]
mode_name: "subseasonal"
era5_initial_condition_dir: "/net/sampo/data1/wxquest_data/initial_conditions"
initial_condition: "WeatherModel"
checkpoint_dt: "7days"
dt: "30secs"
dt_cpl: "30secs"
dt: "120secs"
dt_cpl: "120secs"
dt_cloud_fraction: "1hours"
dt_rad: "1hours"
energy_check: false
h_elem: 16
land_fraction_source: "era5"
binary_area_fraction: false

### integrated land ###
# land_model: "integrated"

### bucket land ###
mode_name: "subseasonal"
era5_initial_condition_dir: "/net/sampo/data1/wxquest_data/initial_conditions"
land_model: "bucket"
bucket_albedo_type: "map_temporal"
bucket_initial_condition: "/net/sampo/data1/wxquest_data/initial_conditions/era5_bucket_processed_20250907_0000.nc"

land_spun_up_ic: false
land_temperature_anomaly: "nothing"
use_land_diagnostics: true
radiation_reset_rng_seed: true
start_date: "20250907"
start_date: "20180901"
surface_setup: "PrescribedSurface"
topo_smoothing: true
topography: "Earth"
t_end: "7days"
netcdf_output_at_levels: true
output_default_diagnostics: false
use_coupler_diagnostics: false
use_land_diagnostics: false
strict_params: false
insolation: "timevarying"
extra_atmos_diagnostics:
- short_name: [tas, mslp, pr, ua, va, rhoa, pfull, hur, hus, clw, cli, clivi, clwvi, cl, arup, tke]
period: 1hours
reduction_time: average
- short_name: [hfls, hfss, rsus, rlus]
period: 1months
reduction_time: average
7 changes: 7 additions & 0 deletions experiments/ClimaEarth/Artifacts.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,10 @@ git-tree-sha1 = "7f14ef1c7859da1363b8973743b2a376c008f29f"
[[era5_land_fraction.download]]
sha256 = "1d6acf98656b50f1a324ee3daa267281fb017314d2169dbfda25208299f44870"
url = "https://caltech.box.com/shared/static/glqlyb626j3szcjltyuwp534yzzhf770.gz"

[era5_monthly_averages_surface_single_level_1979_2024]
git-tree-sha1 = "6cddb07eeee2dd46dc5a19e9b2f706302ddba2c9"

[[era5_monthly_averages_surface_single_level_1979_2024.download]]
sha256 = "46b422722d98c89c6bc0b8641bff259db1caee253f45389ddf9eb9c2d31ed605"
url = "https://caltech.box.com/shared/static/jbgtyt6oq9lxvk8il5zzck6k581q7f3k.gz"
6 changes: 3 additions & 3 deletions experiments/ClimaEarth/Manifest-v1.11.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

julia_version = "1.11.8"
manifest_format = "2.0"
project_hash = "3fd2c8b8c3ebb502a89202b3f7285e40572f38a0"
project_hash = "c4f04d4e37057155b5f15db984f87880058617e1"

[[deps.ADTypes]]
git-tree-sha1 = "f7304359109c768cf32dc5fa2d371565bb63b68a"
Expand Down Expand Up @@ -453,9 +453,9 @@ version = "0.34.0"

[[deps.ClimaCalibrate]]
deps = ["Dates", "Distributed", "Distributions", "EnsembleKalmanProcesses", "JLD2", "Logging", "Random", "TOML", "YAML"]
git-tree-sha1 = "0d7ff225f8cfe2f6adad34ed7ed6f32438d4a772"
git-tree-sha1 = "a0c8232f78f6136f223629cfc4abf7df5c292374"
uuid = "4347a170-ebd6-470c-89d3-5c705c0cacc2"
version = "0.1.4"
version = "0.2.0"

[deps.ClimaCalibrate.extensions]
CESExt = "CalibrateEmulateSample"
Expand Down
2 changes: 1 addition & 1 deletion experiments/ClimaEarth/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"

[compat]
CUDA = "5"
ClimaCalibrate = "0.1"
ClimaCalibrate = "0.2"
ClimaLand = "1.4"
ClimaOcean = "0.8.6"
ClimaParams = "1.0"
Expand Down
23 changes: 9 additions & 14 deletions experiments/calibration/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
# ClimaCoupler Calibration Experiments

This folder contains a trivial perfect-model calibration of the atmosphere coupled with the bucket model.
The calibration uses 30-day and lat/lon averages of top-of-atmosphere shortwave
radiation to calibrate the `total_solar_irradiance` parameter in a perfect model setting.
The current run script uses the `ClimaCalibrate.SlurmManager` to add Slurm workers
which run each ensemble member in parallel.

To run this calibration on a Slurm cluster, ensure that `run_calibration.sh` is
configured for your cluster and run `sbatch run_calibration.sh`. The output will
be generated in `experiments/calibration/output`.
Comment on lines -9 to -11
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you keep this information? I think it's helpful to explain a little bit how to run the experiments

This folder contains pipelines to reproduce coupled calibration experiments.
Each pipeline has its own subfolder:

Components:
- run_calibration.sh: SBATCH script used to instantiate the project and run the calibration on a Slurm cluster.
- run_calibration.jl: Julia script for the overall calibration and postprocessing. Contains the expriment configuration, such as ensemble size and number of iterations.
- model_interface.jl: Contains `forward_model`, the function that gets run during calibration. This basically just uses the `setup_run` function.
- model_config.yml: Contains the configuration for the coupler
-
- perfect_model: A trivial perfect-model calibration of the atmosphere coupled
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be more clear if we rename the test/ folder to perfect_model/

with the bucket model. The calibration uses 30-day and lat/lon averages of
top-of-atmosphere shortwave radiation to calibrate the `total_solar_irradiance`
parameter in a perfect model setting. The current run script uses the
`ClimaCalibrate.SlurmManager` to add Slurm workers which run each ensemble
member in parallel.
- subseasonal: Calibrates the inverse entrainment timescale to ERA5 October monthly surface fluxes and surface temperature from 2018 to 2024.
154 changes: 154 additions & 0 deletions experiments/calibration/api.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import Dates

"""
struct CalibrateConfig{SPINUP <: Dates.Period, EXTEND <: Dates.Period}
short_names::Vector{String}
minibatch_size::Int64
n_iterations::Int64
sample_date_ranges::Vector{NTuple{2, DATE}}
extend::EXTEND
spinup::SPINUP
nelements::Tuple{Int64, Int64}
output_dir::String
rng_seed::Int64
end
A configuration struct for keeping track of multiple fields that are of interest
to a user running calibration, or that are needed in multiple places (e.g., for
ensemble members and generating observations).
"""
struct CalibrateConfig{SPINUP <: Dates.Period, EXTEND <: Dates.Period}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been trying to move more code out of experiments/ and into src/ and ext/. A lot of the calibration-related code is for experiments so it probably does belong here, but maybe something like this could go in ClimaCouplerClimaCalibrateExt (it wouldn't have to be in this PR). What do you think?

"Configuration file to use for ClimaCoupler simulation"
config_file::String

"The short names of the observations used for calibration. The short names
should match the same names used for the diagnostics."
short_names::Vector{String}

"The size of the minibatch for each iteration"
minibatch_size::Int64

"The number of iterations to run the calibration for"
n_iterations::Int64

"The date ranges of the samples for calibration and used to determine the
start and end dates of a simulation for each iteration of calibration"
sample_date_ranges::Vector{NTuple{2, Dates.DateTime}}

"The amount of time to run a simulation after the last date of the
minibatch"
extend::EXTEND

"The amount of time to run a simulation before the first date of the
minibatch"
spinup::SPINUP

"The directory to store the iterations and members of the calibration."
output_dir::String

"An integer value for ensuring calibrations are the same between multiple
calibrations with the same settings"
rng_seed::Int64
end

"""
CalibrateConfig(;
config_file,
short_names,
sample_date_ranges,
extend,
spinup = Dates.Month(3),
minibatch_size,
n_iterations,
output_dir = "calibration/weatherquest",,
rng_seed = 42,
)
Initializes a CalibrateConfig, which is of interest to a user running
calibration or contains values needed in multiple places during calibration.
Keyword arguments
=====================
- `config_file`: Configuration file to use for ClimaCoupler simulation.
- `short_names`: Short names of the observations. The currently supported short
names are `pr`, `tas`, and `mslp`.
- `minibatch_size`: The size of the minibatch for each iteration.
- `n_iterations`: The number of iterations to run the calibration for.
- `sample_date_ranges`: The date ranges for each sample. The dates should be the
same as found in the time series data of the observations.
- `extend`: The amount of time to run the simulation after the end date
determined by `sample_date_ranges`. For seasonal averages, `extend` should be
`Dates.Month(3)` and for monthly averages, `extend` should be
`Dates.Month(1)`.
- `spinup`: The amount of time to run the simulation before the start date
determined by `sample_date_ranges`.
- `nelements`: The resolution of the model. This is also used to determine the
mask of the observations.
- `output_dir`: The location to save the calibration at.
- `rng_seed`: An integer to ensure that calibration runs with the same settings
are the same.
"""
function CalibrateConfig(;
config_file,
short_names,
minibatch_size,
n_iterations,
sample_date_ranges,
extend,
spinup = Dates.Month(3),
output_dir = "calibration/weatherquest",
rng_seed = 42,
)
isempty(short_names) && error("Cannot run calibration with no short names")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
isempty(short_names) && error("Cannot run calibration with no short names")
isempty(short_names) && error("Cannot run calibration with no observation short names")

isempty(sample_date_ranges) &&
error("Cannot run calibration with no date ranges for the samples")

sample_date_ranges = [
(Dates.DateTime(date_pair[1]), Dates.DateTime(date_pair[2])) for
date_pair in sample_date_ranges
]

for (start_date, stop_date) in sample_date_ranges
start_date <= stop_date || error(
"The start date ($start_date) should be before the stop date ($stop_date)",
)
end
issorted(sample_date_ranges) ||
error("The samples in $sample_date_ranges should be sorted")

minibatch_size > 0 || error("The minibatch size ($minibatch_size) should be positive")
n_iterations > 0 || error("The number of iterations ($n_iterations) should be positive")

num_samples = length(sample_date_ranges)
minibatch_size > num_samples && error(
"The minibatch size is $minibatch_size, but the number of samples is $num_samples",
)

remaining = num_samples % minibatch_size
remaining == 0 || @warn(
"Number of samples is not divisible by the minibatch size; the last $remaining samples may be missing when running the calibration"
)

return CalibrateConfig(
config_file,
short_names,
minibatch_size,
n_iterations,
sample_date_ranges,
extend,
spinup,
output_dir,
rng_seed,
)

end
13 changes: 0 additions & 13 deletions experiments/calibration/run_calibration.sh

This file was deleted.

Loading
Loading