Skip to content

Commit b6760cb

Browse files
committed
Add ql, qi
1 parent e8f87bc commit b6760cb

File tree

4 files changed

+85
-62
lines changed

4 files changed

+85
-62
lines changed

experiments/calibration/coarse_amip/observation_map.jl

+11-4
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,37 @@ function process_member_data(simdir::SimDir)
3939
cre = rsut + rlut - rsutcs - rlutcs
4040

4141
pr = process_outputvar(simdir, "pr")
42-
# shf = process_outputvar(simdir, "shf")
42+
shf = process_outputvar(simdir, "shf")
4343
ts = process_outputvar(simdir, "ts")
4444

4545
ta = process_outputvar(simdir, "ta")
4646
hur = process_outputvar(simdir, "hur")
4747
hus = process_outputvar(simdir, "hus")
48+
49+
ql = process_outputvar(simdir, "ql")
50+
qi = process_outputvar(simdir, "qi")
51+
4852
# Map over each year
4953
year_observations = map(1:4:length(rsut)) do year_start
5054
year_end = min(year_start + 3, length(rsut))
5155
yr_ind = year_start:year_end
5256

5357
net_rad_yr = mean(mean.(getproperty.(net_rad[yr_ind], :data)))
5458

55-
pr_yr = downsample_and_vectorize(pr[yr_ind])
5659
rsut_yr = downsample_and_vectorize(rsut[yr_ind])
5760
rlut_yr = downsample_and_vectorize(rlut[yr_ind])
5861
cre_yr = downsample_and_vectorize(cre[yr_ind])
62+
pr_yr = downsample_and_vectorize(pr[yr_ind])
63+
shf_yr = downsample_and_vectorize(shf[yr_ind])
5964
ts_yr = downsample_and_vectorize(ts[yr_ind])
6065

6166
ta_yr = downsample_and_vectorize(ta[yr_ind])
6267
hur_yr = downsample_and_vectorize(hur[yr_ind])
6368
hus_yr = downsample_and_vectorize(hus[yr_ind])
64-
# ql, qi
65-
vcat(net_rad_yr, rsut_yr, rlut_yr, cre_yr, pr_yr, ts_yr, ta_yr, hur_yr, hus_yr)
69+
ql_yr = downsample_and_vectorize(ql[yr_ind])
70+
qi_yr = downsample_and_vectorize(qi[yr_ind])
71+
72+
vcat(net_rad_yr, rsut_yr, rlut_yr, cre_yr, pr_yr, shf_yr, ts_yr, ta_yr, hur_yr, hus_yr, ql_yr, qi_yr)
6673
end
6774
return vcat(year_observations...)
6875
end

experiments/calibration/coarse_amip/observation_utils.jl

+72-56
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ function get_all_output_vars(obs_dir, diagnostic_var2d, diagnostic_var3d)
4848
# TOA net radiative flux
4949
net_rad = rlut + rsut - rsdt
5050
# For some reason we need to add the start date back in
51-
# TODO: Make PR in climaanalysis to do this
5251
net_rad.attributes["start_date"] = string(start_date)
5352

5453
# cloud radiative effect
@@ -76,18 +75,18 @@ function get_all_output_vars(obs_dir, diagnostic_var2d, diagnostic_var3d)
7675
hus = resample(era5_outputvar(joinpath(obs_dir, "era5_monthly_avg_pressure_level_q.nc")))
7776

7877
# # Cloud specific liquid water content
79-
# ql = era5_outputvar(joinpath(obs_dir, "era5_specific_cloud_liquid_water_content_1deg.nc"))
80-
# # Cloud specific ice water content
81-
# qi = era5_outputvar(joinpath(obs_dir, "era5_specific_cloud_ice_water_content_1deg.nc"))
82-
# foreach((ql, qi)) do var
83-
# # Convert from hPa to Pa in-place so we don't create more huge OutputVars
84-
# @assert var.dim_attributes[pressure_name(var)]["units"] == "hPa"
85-
# var.dims[pressure_name(var)] .*= 100.0
86-
# set_dim_units!(var, pressure_name(var), "Pa")
87-
# end
78+
ql = era5_outputvar(joinpath(obs_dir, "era5_specific_cloud_liquid_water_content_1deg.nc"))
79+
# Cloud specific ice water content
80+
qi = era5_outputvar(joinpath(obs_dir, "era5_specific_cloud_ice_water_content_1deg.nc"))
81+
foreach((ql, qi)) do var
82+
# Convert from hPa to Pa in-place so we don't create more huge OutputVars
83+
@assert var.dim_attributes[pressure_name(var)]["units"] == "hPa"
84+
var.dims[pressure_name(var)] .*= 100.0
85+
set_dim_units!(var, pressure_name(var), "Pa")
86+
end
8887
# TODO: determine where time is spent here
89-
# ql = resample(reverse_dim(reverse_dim(ql, latitude_name(ql)), pressure_name(ql)))
90-
# qi = resample(reverse_dim(reverse_dim(qi, latitude_name(qi)), pressure_name(qi)))
88+
ql = resample(reverse_dim(reverse_dim(ql, latitude_name(ql)), pressure_name(ql)))
89+
qi = resample(reverse_dim(reverse_dim(qi, latitude_name(qi)), pressure_name(qi)))
9190

9291
return (; rlut, rsut, rsutcs, rlutcs, pr, net_rad, cre, shf, ts, ta, hur, hus)#, ql, qi)
9392
end
@@ -143,23 +142,35 @@ function get_yearly_averages(var)
143142
return year_averaged_matrices
144143
end
145144

146-
# TODO: compute seasonal stdev properly
147-
function get_seasonal_stdev(output_var)
145+
function get_seasonal_stdevs(output_var)
148146
all_seasonal_averages = get_seasonal_averages(output_var)
149147
all_seasonal_averages = downsample.(all_seasonal_averages, 3)
150148

151-
# Determine dimensionality of the data
152-
dims = ndims(all_seasonal_averages[1]) + 1
153-
154-
seasonal_average_matrix = cat(all_seasonal_averages...; dims)
155-
interannual_stdev = std(seasonal_average_matrix; dims)
156-
return dropdims(interannual_stdev; dims)
149+
# Group the data by season and calculate standard deviation for each season
150+
num_seasons = 4
151+
return map(1:num_seasons) do season
152+
# Get all data for this season across years
153+
season_data = [all_seasonal_averages[i] for i in season:num_seasons:length(all_seasonal_averages)]
154+
155+
# Determine dimensionality of the data
156+
dims = ndims(season_data[1]) + 1
157+
season_matrix = cat(season_data...; dims=dims)
158+
# Calculate standard deviation for this season
159+
season_stdev = std(season_matrix; dims=dims)
160+
dropdims(season_stdev; dims=dims)
161+
end
157162
end
158163

159164
# Given an outputvar, compute the covariance for each season.
160165
function get_seasonal_covariance(output_var)
161-
stdev = get_seasonal_stdev(output_var)
162-
return Diagonal(vec(stdev) .^ 2)
166+
stdevs = get_seasonal_stdevs(output_var)
167+
stdev_vec = vcat(vec.(stdevs)...)
168+
# If 0.0 in diagonal, we need to add some small noise
169+
if 0.0 in stdev_vec
170+
mean_variance_without_zeros = mean(filter(x->x!=0, stdev_vec))
171+
replace!(stdev_vec, (0.0 => mean_variance_without_zeros))
172+
end
173+
return Diagonal(stdev_vec .^ 2)
163174
end
164175

165176
# Given a year, return the indices of that year within a seasonal array
@@ -188,7 +199,7 @@ function make_single_year_of_seasonal_observations(output_var, yr)
188199

189200
name = get(output_var.attributes, "CF_name", get(output_var.attributes, "long_name", ""))
190201
cov = get_seasonal_covariance(output_var)
191-
return EKP.Observation(obs_vec, Diagonal(repeat(cov.diag, 4)), "$(yr)_$name")
202+
return EKP.Observation(obs_vec, cov, "$(yr)_$name")
192203
end
193204

194205
"""
@@ -197,45 +208,50 @@ end
197208
Given a NamedTuple, produce a vector of `EKP.Observation`s, where each observation
198209
consists of seasonally averaged fields, with the exception of globally averaged yearly radiative balance
199210
"""
200-
function create_observation_vector(nt, yrs = 19)
211+
function create_observation_vector(nt, nyears = 19)
201212
# Starting year is 2000-12 to 2001-11
202213
t_start = Second(first_year_start_date - start_date).value
203-
rsut = window(nt.rsut, "time"; left = t_start)
204-
rlut = window(nt.rlut, "time"; left = t_start)
205-
rsutcs = window(nt.rsutcs, "time"; left = t_start)
206-
rlutcs = window(nt.rlutcs, "time"; left = t_start)
207-
cre = window(nt.cre, "time"; left = t_start)
214+
rsut = window(nt.rsut, "time"; left = t_start);
215+
rlut = window(nt.rlut, "time"; left = t_start);
216+
rsutcs = window(nt.rsutcs, "time"; left = t_start);
217+
rlutcs = window(nt.rlutcs, "time"; left = t_start);
218+
cre = window(nt.cre, "time"; left = t_start);
208219

209220
# Compute yearly net radiative flux separately
210221
net_rad = window(nt.net_rad, "time"; left = t_start) |> average_lat |> average_lon
211-
net_rad = get_yearly_averages(net_rad)
222+
net_rad = get_yearly_averages(net_rad);
212223
net_rad_stdev = std(cat(net_rad..., dims = 3), dims = 3)
213-
net_rad_covariance = Diagonal(vec(net_rad_stdev) .^ 2)
214-
215-
ts = window(nt.ts, "time"; left = t_start)
216-
pr = window(nt.pr, "time"; left = t_start)
217-
shf = window(nt.shf, "time"; left = t_start)
218-
219-
ta = window(nt.ta, "time"; left = t_start)
220-
hur = window(nt.hur, "time"; left = t_start)
221-
hus = window(nt.hus, "time"; left = t_start)
222-
223-
all_observations = map(1:yrs) do yr
224-
net_rad_obs = EKP.Observation(vec(net_rad[yr]), net_rad_covariance, "$(yr)_net_rad")
225-
226-
rsut_obs = make_single_year_of_seasonal_observations(rsut, yr)
227-
rlut_obs = make_single_year_of_seasonal_observations(rlut, yr)
228-
rsutcs_obs = make_single_year_of_seasonal_observations(rsutcs, yr)
229-
rlutcs_obs = make_single_year_of_seasonal_observations(rlutcs, yr)
230-
cre_obs = make_single_year_of_seasonal_observations(cre, yr)
231-
pr_obs = make_single_year_of_seasonal_observations(pr, yr)
232-
# shf_obs = make_single_year_of_seasonal_observations(shf, yr)
233-
ts_obs = make_single_year_of_seasonal_observations(ts, yr)
234-
235-
ta_obs = make_single_year_of_seasonal_observations(ta, yr)
236-
hur_obs = make_single_year_of_seasonal_observations(hur, yr)
237-
hus_obs = make_single_year_of_seasonal_observations(hus, yr)
238-
EKP.combine_observations([net_rad_obs, rsut_obs, rlut_obs, cre_obs, pr_obs, ts_obs, ta_obs, hur_obs, hus_obs])
224+
net_rad_covariance = Diagonal(vec(net_rad_stdev) .^ 2);
225+
226+
ts = window(nt.ts, "time"; left = t_start);
227+
pr = window(nt.pr, "time"; left = t_start);
228+
shf = window(nt.shf, "time"; left = t_start);
229+
230+
ta = window(nt.ta, "time"; left = t_start);
231+
hur = window(nt.hur, "time"; left = t_start);
232+
hus = window(nt.hus, "time"; left = t_start);
233+
234+
ql = window(nt.ql, "time"; left = t_start);
235+
qi = window(nt.qi, "time"; left = t_start);
236+
237+
all_observations = map(1:nyears) do yr
238+
@info "Creating observations for year $yr"
239+
net_rad_obs = EKP.Observation(vec(net_rad[yr]), net_rad_covariance, "$(yr)_net_rad");
240+
241+
rsut_obs = make_single_year_of_seasonal_observations(rsut, yr);
242+
rlut_obs = make_single_year_of_seasonal_observations(rlut, yr);
243+
cre_obs = make_single_year_of_seasonal_observations(cre, yr);
244+
pr_obs = make_single_year_of_seasonal_observations(pr, yr);
245+
shf_obs = make_single_year_of_seasonal_observations(shf, yr);
246+
ts_obs = make_single_year_of_seasonal_observations(ts, yr);
247+
248+
ta_obs = make_single_year_of_seasonal_observations(ta, yr);
249+
hur_obs = make_single_year_of_seasonal_observations(hur, yr);
250+
hus_obs = make_single_year_of_seasonal_observations(hus, yr);
251+
ql_obs = make_single_year_of_seasonal_observations(ql, yr);
252+
qi_obs = make_single_year_of_seasonal_observations(qi, yr);
253+
254+
EKP.combine_observations([net_rad_obs, rsut_obs, rlut_obs, cre_obs, pr_obs, shf_obs, ts_obs, ta_obs, hur_obs, hus_obs, ql_obs, qi_obs]);
239255
end
240256

241257
return all_observations # NOT an EKP.ObservationSeries

experiments/calibration/coarse_amip/run_calibration.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ priors = [
2929
constrained_gaussian("precipitation_timescale", 600, 400, 0, 1200),
3030
]
3131
prior = combine_distributions(priors)
32-
observation_path = joinpath(experiment_dir, "observations_3d.jld2")
32+
observation_path = joinpath(experiment_dir, "observations.jld2")
3333
observation_vec = JLD2.load_object(observation_path)
3434

3535
# Create the EKP.ObservationSeries

experiments/calibration/model_interface.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ function ClimaCalibrate.forward_model(iter, member)
99
output_dir_root = config_dict["coupler_output_dir"]
1010
# Set member parameter file
1111
sampled_parameter_file = ClimaCalibrate.parameter_path(output_dir_root, iter, member)
12-
config_dict["calibration_toml"] = sampled_parameter_file
12+
config_dict["coupler_toml"] = [sampled_parameter_file]
1313
# Set member output directory
1414
member_output_dir = ClimaCalibrate.path_to_ensemble_member(output_dir_root, iter, member)
1515
config_dict["coupler_output_dir"] = member_output_dir

0 commit comments

Comments
 (0)