Skip to content

Commit

Permalink
Merge pull request #34 from mdietze/master
Browse files Browse the repository at this point in the history
Update to v0.5
  • Loading branch information
mdietze committed Dec 30, 2022
2 parents 2ba23ed + a28bd77 commit 7045b4c
Show file tree
Hide file tree
Showing 4 changed files with 324 additions and 260 deletions.
9 changes: 4 additions & 5 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ jobs:

- uses: r-lib/actions/setup-pandoc@v1

- uses: r-lib/actions/setup-r@v1
- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}
http-user-agent: ${{ matrix.config.http-user-agent }}
use-public-rspm: true

- uses: r-lib/actions/setup-r-dependencies@v1
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: rcmdcheck

Expand All @@ -49,11 +49,10 @@ jobs:
done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "20.04"))')
- name: Install Python dependencies
run: reticulate::py_install(c("numpy", "matplotlib", "NetCDF4", "pandas", "dicttoxml"))
shell: Rscript {0}
run: |
reticulate::install_miniconda()
reticulate::py_install(c("matplotlib", "NetCDF4", "pandas", "numpy"))
reticulate::py_install(c("numpy", "matplotlib", "NetCDF4", "pandas", "dicttoxml"))
shell: Rscript {0}

- name: Check
run: rcmdcheck::rcmdcheck(args = "--no-manual", error_on = "error")
Expand Down
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ LazyData: true
RoxygenNote: 7.1.2
Imports:
EML,
purrr,
udunits2,
usethis
Suggests:
Expand Down
178 changes: 114 additions & 64 deletions R/forecast_validator.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,45 @@ forecast_validator <- function(eml){
check_exists(meta,"additionalMetadata")
AM <- extract_forecast_metadata(meta)

## get metadata version
check_exists(AM,"metadata_standard_version")
msv = as.character(AM$metadata_standard_version)
msv = as.numeric(gsub("[^0-9.]", "",msv))

## update variable names from older versions
if(msv < 0.4){

check_exists(AM,"forecast_horizon")
AM<- update_tag(AM,"forecast_horizon","horizon")

check_exists(AM,"forecast_iteration_id")
AM<- update_tag(AM,"forecast_iteration_id","iteration_id")

check_exists(AM,"forecast_model_id")
AM<- update_tag(AM,"forecast_model_id","model_id")

check_exists(AM,"forecast_project_id")
AM<- update_tag(AM,"forecast_project_id","project_id")

## check deprecated tags

check_exists(AM,"forecast_issue_time") ## need add check that this is a valid ISO datatime


}


## Check REQUIRED CORE EML elements

## Check REQUIRED FORECAST elements

check_parsable(AM,"timestep")
check_parsable(AM,"forecast_horizon")
check_exists(AM,"forecast_issue_time") ## need add check that this is a valid ISO datatime
check_exists(AM,"forecast_iteration_id")
check_exists(AM,"forecast_project_id")
check_exists(AM,"metadata_standard_version")
check_parsable(AM,"horizon")
check_exists(AM,"reference_datetime") ## need add check that this is a valid ISO datatime
check_exists(AM,"iteration_id")
check_exists(AM,"project_id")
check_exists(AM,"model_description")
check_exists(AM$model_description,"forecast_model_id")
check_exists(AM$model_description,"model_id")
check_exists(AM$model_description,"name")
check_exists(AM$model_description,"type")
check_exists(AM$model_description,"repository")
Expand All @@ -64,81 +91,92 @@ forecast_validator <- function(eml){
uqlist <- parent[[element]]

## Check UNCERTAINTY tag
check_exists(uqlist, "status")
uqunc <- uqlist[["status"]]
UQoptions <- c("absent", "present", "data_driven", "propagates", "assimilates")
if (!uqunc %in% UQoptions) {
usethis::ui_stop(sprintf(
"Invalid status/uncertainty class '%s'",
uqlist[["status"]]
))
} else{
usethis::ui_done(paste0(element," status/uncertainty class valid: ",uqlist[["status"]]))
if(msv > 0.4){
## check present and data_driven tags

check_exists(uqlist, "present")
present = uqlist$present

if(present){
check_exists(uqlist,"data_driven")
}

} else {
## check old STATUS tag
check_exists(uqlist, "status")
uqunc <- uqlist[["status"]]
UQoptions <- c("absent", "present", "data_driven", "propagates", "assimilates")
if (!uqunc %in% UQoptions) {
usethis::ui_stop(sprintf(
"Invalid status/uncertainty class '%s'",
uqlist[["status"]]
))
} else{
usethis::ui_done(paste0(element," status/uncertainty class valid: ",uqlist[["status"]]))
}

## Check CONDITIONALLY DEPENDENT tags
uqunc_f <- factor(uqunc, UQoptions, ordered = TRUE)

present <- uqunc_f >= "present"

}

## Check CONDITIONALLY DEPENDENT tags
uqunc_f <- factor(uqunc, UQoptions, ordered = TRUE)

if (uqunc_f >= "present") {
if (present) {
# Check complexity
check_whole(uqlist,"complexity",required = FALSE)


## ADD special cases for process_error [[ CURRENTLY SET TO RECOMMENDED]]
if(element == "process_error"){
# check_exists(uqlist,"covariance")
if(lexists(uqlist,"covariance")){
if(uqlist[["covariance"]]){ ## if TRUE (full cov matrix), check for localization
# check_exists(uqlist,"localization")
}
}
}
}
if (uqunc_f >= "propagates") {
# Check propagation method
#check_exists(uqlist,"propagation") ## RECOMMENDED
if(lexists(uqlist,"propagation")){
plist <- uqlist[["propagation"]]

## type
check_exists(plist,"type")
if (!tolower(plist[["type"]]) %in% c("ensemble","analytic")) {
usethis::ui_stop(sprintf(
"'%s' Invalid uncertainty <propagation> <type> '%s'",
element,plist[["type"]]
))
} else{
usethis::ui_done(paste0(element," propagation type valid: ",plist[["type"]]))
if(element == "process_error"){
# check_exists(uqlist,"covariance")
if(lexists(uqlist,"covariance")){
if(uqlist[["covariance"]]){ ## if TRUE (full cov matrix), check for localization
# check_exists(uqlist,"localization")
}
}
}
}

## ensemble size
if(tolower(plist[["type"]]) == "ensemble"){
check_whole(plist,"size")
} else {
if(lexists(uqlist,"propagation")){
plist <- uqlist[["propagation"]]

## type
check_exists(plist,"type")
if (!tolower(plist[["type"]]) %in% c("ensemble","analytic")) {
usethis::ui_stop(sprintf(
"'%s' Invalid uncertainty <propagation> <type> '%s'",
element,plist[["type"]]
))
} else{
usethis::ui_done(paste0(element," propagation type valid: ",plist[["type"]]))
}

## ensemble size
if(tolower(plist[["type"]]) == "ensemble"){
check_whole(plist,"size")
} else {

## ADD check on analytic <method>
}
} ## end propagation
} ## end propagates
}
} ## end propagation

if (uqunc_f >= "assimilates") {
# Check assimilation method
# check_exists(uqlist,"assimilation") ## RECOMMENDED
if(lexists(uqlist,"assimilation")){
alist <- uqlist[["assimilation"]]

## type
check_exists(alist,"type")
if(lexists(uqlist,"assimilation")){
alist <- uqlist[["assimilation"]]

## reference
check_exists(alist,"reference")
## type
check_exists(alist,"type")

## complexity
check_whole(alist,"complexity")
## reference
check_exists(alist,"reference")

## attributeName (optional)
check_whole(alist,"attributeName",required = FALSE)
}
## complexity
check_whole(alist,"complexity",required = FALSE)

## attributeName (optional)
check_whole(alist,"attributeName",required = FALSE)
}
}

Expand All @@ -163,6 +201,18 @@ extract_forecast_metadata <- function(meta){
AM[[1]]$metadata$forecast
}

update_tag <- function(meta,old,new){
## based on https://stackoverflow.com/questions/63074814/recursively-change-names-in-nested-lists-in-r
found <- names(meta) %in% old
names(meta)[found] <- new
meta %>% purrr::map(~{
if (is.list(.x)) {
update_tag(.x,old,new)
} else {
.x
}
})

}

#forecast_validator("forecast-eml.xml")
Loading

0 comments on commit 7045b4c

Please sign in to comment.