Copy - Paste the script below. You will need to set the dates,
fcst_model, paths etc. Save it and run with
source("<script_file_name.R>")
or click on Source in
RStudio.
library(harp)
library(purrr)
# The following variables are expected to change for each user / use case
dttm <- seq_dttm(2018030800, 2018033100, "1d")
fcst_model <- c("REF", "SPP")
lead_time <- seq(0, 48, 3)
fcst_type <- "eps"
lags <- "0s"
fcst_path <- "/path/to/FCTABLE"
obs_path <- "/path/to/OBSTABLE"
verif_path <- "/path/to/verif"
grps <- "lead_time"
# Add more parameters below using the same format. For upper air parameters,
# don't forget the vc = "pressure"
params <- list(
# Parameter that won't work!
apple = list(
thresholds = seq(5, 50, 5)
),
T2m = list(
thresholds = c(-20, -10, seq(-5, 25, 5)),
scale_fcst = list(scaling = -273.15, new_units = "degC"),
scale_obs = list(scaling = -273.15, new_units = "degC")
),
S10m = list(
thresholds = seq(0, 25, 5)
),
T = list(
scale_fcst = list(scaling = -273.15, new_units = "degC"),
scale_obs = list(scaling = -273.15, new_units = "degC"),
vc = "pressure"
)
)
# Function that runs the verification
run_verif <- function(prm_info, prm_name) {
if (!is.null(prm_info$vc)) {
vertical_coordinate <- prm_info$vc
} else {
vertical_coordinate <- NA_character_
}
# Read the forecast
fcst <- read_point_forecast(
dttm = dttm,
fcst_model = fcst_model,
fcst_type = fcst_type,
parameter = prm_name,
lead_time = lead_time,
lags = lags,
file_path = fcst_path,
vertical_coordinate = vertical_coordinate
)
# Find the common cases - for upper air parmeters we need to ensure
# that the level column is included in the check
fcst <- switch(
vertical_coordinate,
"pressure" = common_cases(fcst, p),
"height" = common_cases(fcst, z),
common_cases(fcst)
)
# optional rescaling of forecasts using the scale_fcst part of the
# params list. We use do.call to call the scale_point_forecast
# function with a named list containing the arguments.
if (!is.null(prm_info$scale_fcst)) {
fcst <- do.call(
scale_param,
c(list(x = fcst), prm_info$scale_fcst))
}
# Read the observations getting the dates and stations from
# the forecast
obs <- read_point_obs(
dttm = unique_valid_dttm(fcst),
parameter = prm_name,
obs_path = obs_path,
stations = unique_stations(fcst),
vertical_coordinate = vertical_coordinate
)
# optional rescaling of observations using the scale_obs part of the
# params list. We use do.call to call the scale_point_forecast
# function with a named list containing the arguments.
if (!is.null(prm_info$scale_obs)) {
obs <- do.call(
scale_point_obs,
c(list(x = obs, col = {{prm_name}}), prm_info$scale_obs)
)
}
# Join observations to the forecast
fcst <- join_to_fcst(fcst, obs)
# Check for errors removing obs that are more than a certain number
# of standard deviations from the forecast. You could add a number
# of standard deviations to use in the params list
fcst <- check_obs_against_fcst(fcst, {{prm_name}})
# Make sure that grps is a list so that it adds on the vertical
# coordinate group correctly
if (!is.list(grps)) {
grps <- list(grps)
}
grps <- switch(
vertical_coordinate,
"pressure" = map(grps, ~c(.x, "p")),
"height" = map(grps, ~c(.x, "z")),
grps
)
# Do the verification
if (fcst_type == "eps") {
verif <- ens_verify(
fcst, prm_name, thresholds = prm_info$thresholds, groupings = grps
)
} else {
verif <- det_verify(
fcst, prm_name, thresholds = prm_info$thresholds, groupings = grps
)
}
# Save the scores
save_point_verif(verif, verif_path = verif_path)
# Return the data to the calling environment (normally global)
verif
}
# Use possibly from the purrr package to allow the script to continue
# if it fails for a parameter - it returns NULL if it fails. See
# ?safely and ?quietly if you want to retain the errors.
possible_run_verif <- possibly(run_verif, otherwise = NULL)
# Use imap from the purrr package to map each element of the params list
# to the possible_run_verif function. imap passes the element of the list
# as the first argument and the name of the element as the second.
verif <- imap(params, possible_run_verif)
# You can open the results in a shiny app using
# shiny_plot_point_verif(verif_path)
LS0tCnRpdGxlOiAiaGFycCBQb2ludCB2ZXJpZmljYXRpb24gc2NyaXB0IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgpDb3B5IC0gUGFzdGUgdGhlIHNjcmlwdCBiZWxvdy4gWW91IHdpbGwgbmVlZCB0byBzZXQgdGhlIGRhdGVzLCBmY3N0X21vZGVsLCBwYXRocyBldGMuIFNhdmUgaXQgYW5kIHJ1biB3aXRoIGBzb3VyY2UoIjxzY3JpcHRfZmlsZV9uYW1lLlI+IilgIG9yIGNsaWNrIG9uIFNvdXJjZSBpbiBSU3R1ZGlvLiAKCmBgYHtyfQpsaWJyYXJ5KGhhcnApCmxpYnJhcnkocHVycnIpCgojIFRoZSBmb2xsb3dpbmcgdmFyaWFibGVzIGFyZSBleHBlY3RlZCB0byBjaGFuZ2UgZm9yIGVhY2ggdXNlciAvIHVzZSBjYXNlCgpkdHRtICAgICAgIDwtIHNlcV9kdHRtKDIwMTgwMzA4MDAsIDIwMTgwMzMxMDAsICIxZCIpCmZjc3RfbW9kZWwgPC0gYygiUkVGIiwgIlNQUCIpCmxlYWRfdGltZSAgPC0gc2VxKDAsIDQ4LCAzKQpmY3N0X3R5cGUgIDwtICJlcHMiCmxhZ3MgICAgICAgPC0gIjBzIgpmY3N0X3BhdGggIDwtICIvcGF0aC90by9GQ1RBQkxFIgpvYnNfcGF0aCAgIDwtICIvcGF0aC90by9PQlNUQUJMRSIKdmVyaWZfcGF0aCA8LSAiL3BhdGgvdG8vdmVyaWYiCmdycHMgICAgICAgPC0gImxlYWRfdGltZSIKCiMgQWRkIG1vcmUgcGFyYW1ldGVycyBiZWxvdyB1c2luZyB0aGUgc2FtZSBmb3JtYXQuIEZvciB1cHBlciBhaXIgcGFyYW1ldGVycywKIyBkb24ndCBmb3JnZXQgdGhlIHZjID0gInByZXNzdXJlIgpwYXJhbXMgPC0gbGlzdCgKICAKICAjIFBhcmFtZXRlciB0aGF0IHdvbid0IHdvcmshCiAgYXBwbGUgPSBsaXN0KAogICAgdGhyZXNob2xkcyA9IHNlcSg1LCA1MCwgNSkKICApLAogIAogIFQybSA9IGxpc3QoCiAgICB0aHJlc2hvbGRzID0gYygtMjAsIC0xMCwgc2VxKC01LCAyNSwgNSkpLAogICAgc2NhbGVfZmNzdCA9IGxpc3Qoc2NhbGluZyA9IC0yNzMuMTUsIG5ld191bml0cyA9ICJkZWdDIiksCiAgICBzY2FsZV9vYnMgID0gbGlzdChzY2FsaW5nID0gLTI3My4xNSwgbmV3X3VuaXRzID0gImRlZ0MiKQogICksIAogIAogIFMxMG0gPSBsaXN0KAogICAgdGhyZXNob2xkcyA9IHNlcSgwLCAyNSwgNSkKICApLCAKICAKICBUID0gbGlzdCgKICAgIHNjYWxlX2Zjc3QgPSBsaXN0KHNjYWxpbmcgPSAtMjczLjE1LCBuZXdfdW5pdHMgPSAiZGVnQyIpLAogICAgc2NhbGVfb2JzICA9IGxpc3Qoc2NhbGluZyA9IC0yNzMuMTUsIG5ld191bml0cyA9ICJkZWdDIiksCiAgICB2YyAgICAgICAgID0gInByZXNzdXJlIgogICkKICAKKQoKIyBGdW5jdGlvbiB0aGF0IHJ1bnMgdGhlIHZlcmlmaWNhdGlvbgpydW5fdmVyaWYgPC0gZnVuY3Rpb24ocHJtX2luZm8sIHBybV9uYW1lKSB7CiAgCiAgaWYgKCFpcy5udWxsKHBybV9pbmZvJHZjKSkgewogICAgdmVydGljYWxfY29vcmRpbmF0ZSA8LSBwcm1faW5mbyR2YwogIH0gZWxzZSB7CiAgICB2ZXJ0aWNhbF9jb29yZGluYXRlIDwtIE5BX2NoYXJhY3Rlcl8KICB9CiAgCiAgIyBSZWFkIHRoZSBmb3JlY2FzdAogIGZjc3QgPC0gcmVhZF9wb2ludF9mb3JlY2FzdCgKICAgIGR0dG0gICAgICAgICAgPSBkdHRtLAogICAgZmNzdF9tb2RlbCAgICA9IGZjc3RfbW9kZWwsCiAgICBmY3N0X3R5cGUgICAgID0gZmNzdF90eXBlLAogICAgcGFyYW1ldGVyICAgICA9IHBybV9uYW1lLAogICAgbGVhZF90aW1lICAgICA9IGxlYWRfdGltZSwKICAgIGxhZ3MgICAgICAgICAgPSBsYWdzLAogICAgZmlsZV9wYXRoICAgICA9IGZjc3RfcGF0aCwKICAgIHZlcnRpY2FsX2Nvb3JkaW5hdGUgPSB2ZXJ0aWNhbF9jb29yZGluYXRlCiAgKQogIAogICMgRmluZCB0aGUgY29tbW9uIGNhc2VzIC0gZm9yIHVwcGVyIGFpciBwYXJtZXRlcnMgd2UgbmVlZCB0byBlbnN1cmUgCiAgIyB0aGF0IHRoZSBsZXZlbCBjb2x1bW4gIGlzIGluY2x1ZGVkIGluIHRoZSBjaGVjawogIGZjc3QgPC0gc3dpdGNoKAogICAgdmVydGljYWxfY29vcmRpbmF0ZSwKICAgICJwcmVzc3VyZSIgPSBjb21tb25fY2FzZXMoZmNzdCwgcCksCiAgICAiaGVpZ2h0IiAgID0gY29tbW9uX2Nhc2VzKGZjc3QsIHopLAogICAgY29tbW9uX2Nhc2VzKGZjc3QpCiAgKQogIAogICMgb3B0aW9uYWwgcmVzY2FsaW5nIG9mIGZvcmVjYXN0cyB1c2luZyB0aGUgc2NhbGVfZmNzdCBwYXJ0IG9mIHRoZQogICMgcGFyYW1zIGxpc3QuIFdlIHVzZSBkby5jYWxsIHRvIGNhbGwgdGhlIHNjYWxlX3BvaW50X2ZvcmVjYXN0IAogICMgZnVuY3Rpb24gd2l0aCBhIG5hbWVkIGxpc3QgY29udGFpbmluZyB0aGUgYXJndW1lbnRzLiAKICBpZiAoIWlzLm51bGwocHJtX2luZm8kc2NhbGVfZmNzdCkpIHsKICAgIGZjc3QgPC0gZG8uY2FsbCgKICAgICAgc2NhbGVfcGFyYW0sIAogICAgICBjKGxpc3QoeCA9IGZjc3QpLCBwcm1faW5mbyRzY2FsZV9mY3N0KSkKICB9CiAgCiAgIyBSZWFkIHRoZSBvYnNlcnZhdGlvbnMgZ2V0dGluZyB0aGUgZGF0ZXMgYW5kIHN0YXRpb25zIGZyb20gCiAgIyB0aGUgZm9yZWNhc3QKICBvYnMgPC0gcmVhZF9wb2ludF9vYnMoCiAgICBkdHRtICAgICAgID0gdW5pcXVlX3ZhbGlkX2R0dG0oZmNzdCksCiAgICBwYXJhbWV0ZXIgID0gcHJtX25hbWUsCiAgICBvYnNfcGF0aCAgID0gb2JzX3BhdGgsCiAgICBzdGF0aW9ucyAgID0gdW5pcXVlX3N0YXRpb25zKGZjc3QpLAogICAgdmVydGljYWxfY29vcmRpbmF0ZSA9IHZlcnRpY2FsX2Nvb3JkaW5hdGUKICApCiAgCiAgIyBvcHRpb25hbCByZXNjYWxpbmcgb2Ygb2JzZXJ2YXRpb25zIHVzaW5nIHRoZSBzY2FsZV9vYnMgcGFydCBvZiB0aGUKICAjIHBhcmFtcyBsaXN0LiBXZSB1c2UgZG8uY2FsbCB0byBjYWxsIHRoZSBzY2FsZV9wb2ludF9mb3JlY2FzdCAKICAjIGZ1bmN0aW9uIHdpdGggYSBuYW1lZCBsaXN0IGNvbnRhaW5pbmcgdGhlIGFyZ3VtZW50cy4KICBpZiAoIWlzLm51bGwocHJtX2luZm8kc2NhbGVfb2JzKSkgewogICAgb2JzIDwtIGRvLmNhbGwoCiAgICAgIHNjYWxlX3BvaW50X29icywgCiAgICAgIGMobGlzdCh4ID0gb2JzLCBjb2wgPSB7e3BybV9uYW1lfX0pLCBwcm1faW5mbyRzY2FsZV9vYnMpCiAgICApCiAgfQogIAogICMgSm9pbiBvYnNlcnZhdGlvbnMgdG8gdGhlIGZvcmVjYXN0CiAgZmNzdCA8LSBqb2luX3RvX2Zjc3QoZmNzdCwgb2JzKQogIAogICMgQ2hlY2sgZm9yIGVycm9ycyByZW1vdmluZyBvYnMgdGhhdCBhcmUgbW9yZSB0aGFuIGEgY2VydGFpbiBudW1iZXIgCiAgIyBvZiBzdGFuZGFyZCBkZXZpYXRpb25zIGZyb20gdGhlIGZvcmVjYXN0LiBZb3UgY291bGQgYWRkIGEgbnVtYmVyIAogICMgb2Ygc3RhbmRhcmQgZGV2aWF0aW9ucyB0byB1c2UgaW4gdGhlIHBhcmFtcyBsaXN0IAogIGZjc3QgPC0gY2hlY2tfb2JzX2FnYWluc3RfZmNzdChmY3N0LCB7e3BybV9uYW1lfX0pCiAgCiAgIyBNYWtlIHN1cmUgdGhhdCBncnBzIGlzIGEgbGlzdCBzbyB0aGF0IGl0IGFkZHMgb24gdGhlIHZlcnRpY2FsIAogICMgY29vcmRpbmF0ZSBncm91cCBjb3JyZWN0bHkKICBpZiAoIWlzLmxpc3QoZ3JwcykpIHsKICAgIGdycHMgPC0gbGlzdChncnBzKQogIH0KICAKICBncnBzIDwtIHN3aXRjaCgKICAgIHZlcnRpY2FsX2Nvb3JkaW5hdGUsCiAgICAicHJlc3N1cmUiID0gbWFwKGdycHMsIH5jKC54LCAicCIpKSwKICAgICJoZWlnaHQiICAgPSBtYXAoZ3JwcywgfmMoLngsICJ6IikpLAogICAgZ3JwcwogICkKICAKICAjIERvIHRoZSB2ZXJpZmljYXRpb24KICBpZiAoZmNzdF90eXBlID09ICJlcHMiKSB7CiAgICB2ZXJpZiA8LSBlbnNfdmVyaWZ5KAogICAgICBmY3N0LCBwcm1fbmFtZSwgdGhyZXNob2xkcyA9IHBybV9pbmZvJHRocmVzaG9sZHMsIGdyb3VwaW5ncyA9IGdycHMKICAgICkKICB9IGVsc2UgewogICAgdmVyaWYgPC0gZGV0X3ZlcmlmeSgKICAgICAgZmNzdCwgcHJtX25hbWUsIHRocmVzaG9sZHMgPSBwcm1faW5mbyR0aHJlc2hvbGRzLCBncm91cGluZ3MgPSBncnBzCiAgICApCiAgfQogIAogICMgU2F2ZSB0aGUgc2NvcmVzCiAgc2F2ZV9wb2ludF92ZXJpZih2ZXJpZiwgdmVyaWZfcGF0aCA9IHZlcmlmX3BhdGgpCiAgCiAgIyBSZXR1cm4gdGhlIGRhdGEgdG8gdGhlIGNhbGxpbmcgZW52aXJvbm1lbnQgKG5vcm1hbGx5IGdsb2JhbCkKICB2ZXJpZgogIAp9CgojIFVzZSBwb3NzaWJseSBmcm9tIHRoZSBwdXJyciBwYWNrYWdlIHRvIGFsbG93IHRoZSBzY3JpcHQgdG8gY29udGludWUKIyBpZiBpdCBmYWlscyBmb3IgYSBwYXJhbWV0ZXIgLSBpdCByZXR1cm5zIE5VTEwgaWYgaXQgZmFpbHMuIFNlZQojID9zYWZlbHkgYW5kID9xdWlldGx5IGlmIHlvdSB3YW50IHRvIHJldGFpbiB0aGUgZXJyb3JzLgpwb3NzaWJsZV9ydW5fdmVyaWYgPC0gcG9zc2libHkocnVuX3ZlcmlmLCBvdGhlcndpc2UgPSBOVUxMKQoKIyBVc2UgaW1hcCBmcm9tIHRoZSBwdXJyciBwYWNrYWdlIHRvIG1hcCBlYWNoIGVsZW1lbnQgb2YgdGhlIHBhcmFtcyBsaXN0CiMgdG8gdGhlIHBvc3NpYmxlX3J1bl92ZXJpZiBmdW5jdGlvbi4gaW1hcCBwYXNzZXMgdGhlIGVsZW1lbnQgb2YgdGhlIGxpc3QKIyBhcyB0aGUgZmlyc3QgYXJndW1lbnQgYW5kIHRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IGFzIHRoZSBzZWNvbmQuCnZlcmlmIDwtIGltYXAocGFyYW1zLCBwb3NzaWJsZV9ydW5fdmVyaWYpCgojIFlvdSBjYW4gb3BlbiB0aGUgcmVzdWx0cyBpbiBhIHNoaW55IGFwcCB1c2luZyAKIyBzaGlueV9wbG90X3BvaW50X3ZlcmlmKHZlcmlmX3BhdGgpCmBgYAoK