diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 7c220bc4..bd3ca249 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -5,6 +5,8 @@ on: branches: [main, master] pull_request: branches: [main, master] + schedule: + - cron: '0 0 * * *' name: R-CMD-check diff --git a/DESCRIPTION b/DESCRIPTION index 90a30df1..585c2bf8 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -37,8 +37,8 @@ Imports: dplyr, fs, gh, - hubAdmin, - hubData, + hubAdmin (>= 0.1.0), + hubData (>= 0.1.0), hubUtils (>= 0.0.1), jsonlite, jsonvalidate, @@ -63,7 +63,8 @@ Remotes: Infectious-Disease-Modeling-Hubs/hubUtils, Infectious-Disease-Modeling-Hubs/hubData, Infectious-Disease-Modeling-Hubs/hubAdmin, - assignUser/octolog + assignUser/octolog, + apache/arrow/r@apache-arrow-15.0.2 Config/testthat/edition: 3 Config/Needs/website: pkgdown, Infectious-Disease-Modeling-Hubs/hubStyle Encoding: UTF-8 diff --git a/NEWS.md b/NEWS.md index 1b2d6182..e9da4fb6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,10 @@ +# hubValidations 0.0.1 + +* Release stable 0.0.1 version +* Enforce minimum dependence on latest `hubData` (0.1.0) & `hubAdmin` (0.1.0). This allows for successful validation of submissions to hubs with multiple model tasks, where a given model task might contain non relevant task IDs and both `required` and `optional` properties have been set to `null` in `tasks.json` (#75). See the [relevant section in `hubDocs` documentation](https://hubdocs.readthedocs.io/en/latest/quickstart-hub-admin/tasks-config.html#required-and-optional-elements) for more details. +* Improve formatting of current time print in `validate_submission_time()` message by removing decimal seconds and including local time zone. + + # hubValidations 0.0.0.9008 * Added new articles on: diff --git a/R/check_submission_time.R b/R/check_submission_time.R index 223e6cfe..d1b0c875 100644 --- a/R/check_submission_time.R +++ b/R/check_submission_time.R @@ -24,7 +24,9 @@ check_submission_time <- function(hub_path, file_path, ref_date_from = c( details <- NULL } else { details <- cli::format_inline( - "Current time {.val {Sys.time()}} is outside window {.val {submission_window}}." + "Current time {.val {format(Sys.time(), + format = '%Y-%m-%d %H:%M:%S', + usetz = TRUE)}} is outside window {.val {submission_window}}." ) } diff --git a/README.Rmd b/README.Rmd index 24793ec3..aea3cb31 100644 --- a/README.Rmd +++ b/README.Rmd @@ -31,6 +31,15 @@ You can install the development version of hubValidations like so: remotes::install_github("Infectious-Disease-Modeling-Hubs/hubValidations") ``` +> ##### 💡 TIP +> `hubValidations` has a dependency on the `arrow` package. For troubleshooting `arrow` installation problems, please consult the [`arrow` package documentation](https://arrow.apache.org/docs/r/#installation). +> +> You could also try installing the package from the [Apache R Universe repository](https://apache.r-universe.dev) with: +> +> ```r +> install.packages("arrow", repos = c("https://apache.r-universe.dev", "https://cran.r-project.org")) +> ``` + *** ## Code of Conduct diff --git a/README.md b/README.md index b68432a8..c812304e 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,20 @@ You can install the development version of hubValidations like so: remotes::install_github("Infectious-Disease-Modeling-Hubs/hubValidations") ``` +> ##### 💡 TIP +> +> `hubValidations` has a dependency on the `arrow` package. For +> troubleshooting `arrow` installation problems, please consult the +> [`arrow` package +> documentation](https://arrow.apache.org/docs/r/#installation). +> +> You could also try installing the package from the [Apache R Universe +> repository](https://apache.r-universe.dev) with: +> +> ``` r +> install.packages("arrow", repos = c("https://apache.r-universe.dev", "https://cran.r-project.org")) +> ``` + ------------------------------------------------------------------------ ## Code of Conduct diff --git a/hubValidations.Rproj b/hubValidations.Rproj index fd8dd284..69fafd4b 100644 --- a/hubValidations.Rproj +++ b/hubValidations.Rproj @@ -6,7 +6,7 @@ AlwaysSaveHistory: Default EnableCodeIndexing: Yes UseSpacesForTab: Yes -NumSpacesForTab: 4 +NumSpacesForTab: 2 Encoding: UTF-8 RnwWeave: Sweave diff --git a/tests/testthat/_snaps/validate_submission.md b/tests/testthat/_snaps/validate_submission.md index 0c11ba5b..69d611d7 100644 --- a/tests/testthat/_snaps/validate_submission.md +++ b/tests/testthat/_snaps/validate_submission.md @@ -426,7 +426,7 @@ "submission_time"]]) Output List of 4 - $ message : chr "Submission time must be within accepted submission window for round. \n Current time 2023-10-08 18:01:00 is out"| __truncated__ + $ message : chr "Submission time must be within accepted submission window for round. \n Current time \"2023-10-08 18:01:00 UTC\"| __truncated__ $ where : chr "team1-goodmodel/2022-10-08-team1-goodmodel.csv" $ call : chr "check_submission_time" $ use_cli_format: logi TRUE @@ -565,3 +565,269 @@ ..- attr(*, "class")= chr [1:5] "check_info" "hub_check" "rlang_message" "message" ... - attr(*, "class")= chr [1:2] "hub_validations" "list" +# File containing task ID with all null properties validate correctly + + Code + str(validate_submission(hub_path = test_path("testdata/hub-null"), file_path = "team-model/2023-11-26-team-model.parquet", + skip_submit_window_check = TRUE)) + Output + List of 19 + $ valid_config :List of 4 + ..$ message : chr "All hub config files are valid. \n " + ..$ where : chr "hub-null" + ..$ call : chr "check_config_hub_valid" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ file_exists :List of 4 + ..$ message : chr "File exists at path 'model-output/team-model/2023-11-26-team-model.parquet'. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_file_exists" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ file_name :List of 4 + ..$ message : chr "File name \"2023-11-26-team-model.parquet\" is valid. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_file_name" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ file_location :List of 4 + ..$ message : chr "File directory name matches `model_id`\n metadata in file name. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_file_location" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ round_id_valid :List of 4 + ..$ message : chr "`round_id` is valid. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_valid_round_id" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ file_format :List of 4 + ..$ message : chr "File is accepted hub format. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_file_format" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ metadata_exists :List of 4 + ..$ message : chr "Metadata file exists at path 'model-metadata/team-model.yaml'. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_submission_metadata_file_exists" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ file_read :List of 4 + ..$ message : chr "File could be read successfully. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_file_read" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ valid_round_id_col:List of 4 + ..$ message : chr "`round_id_col` name is valid. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_valid_round_id_col" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ unique_round_id :List of 4 + ..$ message : chr "`round_id` column \"origin_date\" contains a single, unique round ID value. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_tbl_unique_round_id" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ match_round_id :List of 4 + ..$ message : chr "All `round_id_col` \"origin_date\" values match submission `round_id` from file name. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_tbl_match_round_id" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ colnames :List of 4 + ..$ message : chr "Column names are consistent with expected round task IDs and std column names. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_tbl_colnames" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ col_types :List of 4 + ..$ message : chr "Column data types match hub schema. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_tbl_col_types" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ valid_vals :List of 5 + ..$ message : chr "`tbl` contains valid values/value combinations. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ error_tbl : NULL + ..$ call : chr "check_tbl_values" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ rows_unique :List of 4 + ..$ message : chr "All combinations of task ID column/`output_type`/`output_type_id` values are unique. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_tbl_rows_unique" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ req_vals :List of 5 + ..$ message : chr "Required task ID/output type/output type ID combinations all present. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ missing : tibble [0 x 7] (S3: tbl_df/tbl/data.frame) + .. ..$ origin_date : chr(0) + .. ..$ target : chr(0) + .. ..$ horizon : chr(0) + .. ..$ location : chr(0) + .. ..$ age_group : chr(0) + .. ..$ output_type : chr(0) + .. ..$ output_type_id: chr(0) + ..$ call : chr "check_tbl_values_required" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ value_col_valid :List of 4 + ..$ message : chr "Values in column `value` all valid with respect to modeling task config. \n " + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_tbl_value_col" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ value_col_non_desc:List of 5 + ..$ message : chr "Values in `value` column are non-decreasing as output_type_ids increase for all unique task ID\n value/outpu"| __truncated__ + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ error_tbl : NULL + ..$ call : chr "check_tbl_value_col_ascending" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ value_col_sum1 :List of 4 + ..$ message : chr "No pmf output types to check for sum of 1. Check skipped." + ..$ where : chr "team-model/2023-11-26-team-model.parquet" + ..$ call : chr "check_tbl_value_col_sum1" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_info" "hub_check" "rlang_message" "message" ... + - attr(*, "class")= chr [1:2] "hub_validations" "list" + +--- + + Code + str(validate_submission(hub_path = test_path("testdata/hub-null"), file_path = "team-model/2023-11-19-team-model.parquet", + skip_submit_window_check = TRUE)) + Output + List of 19 + $ valid_config :List of 4 + ..$ message : chr "All hub config files are valid. \n " + ..$ where : chr "hub-null" + ..$ call : chr "check_config_hub_valid" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ file_exists :List of 4 + ..$ message : chr "File exists at path 'model-output/team-model/2023-11-19-team-model.parquet'. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_file_exists" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ file_name :List of 4 + ..$ message : chr "File name \"2023-11-19-team-model.parquet\" is valid. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_file_name" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ file_location :List of 4 + ..$ message : chr "File directory name matches `model_id`\n metadata in file name. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_file_location" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ round_id_valid :List of 4 + ..$ message : chr "`round_id` is valid. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_valid_round_id" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ file_format :List of 4 + ..$ message : chr "File is accepted hub format. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_file_format" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ metadata_exists :List of 4 + ..$ message : chr "Metadata file exists at path 'model-metadata/team-model.yaml'. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_submission_metadata_file_exists" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ file_read :List of 4 + ..$ message : chr "File could be read successfully. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_file_read" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ valid_round_id_col:List of 4 + ..$ message : chr "`round_id_col` name is valid. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_valid_round_id_col" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ unique_round_id :List of 4 + ..$ message : chr "`round_id` column \"origin_date\" contains a single, unique round ID value. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_tbl_unique_round_id" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ match_round_id :List of 4 + ..$ message : chr "All `round_id_col` \"origin_date\" values match submission `round_id` from file name. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_tbl_match_round_id" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ colnames :List of 4 + ..$ message : chr "Column names are consistent with expected round task IDs and std column names. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_tbl_colnames" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ col_types :List of 4 + ..$ message : chr "Column data types match hub schema. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_tbl_col_types" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ valid_vals :List of 5 + ..$ message : chr "`tbl` contains valid values/value combinations. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ error_tbl : NULL + ..$ call : chr "check_tbl_values" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ rows_unique :List of 4 + ..$ message : chr "All combinations of task ID column/`output_type`/`output_type_id` values are unique. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_tbl_rows_unique" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ req_vals :List of 5 + ..$ message : chr "Required task ID/output type/output type ID combinations all present. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ missing : tibble [0 x 7] (S3: tbl_df/tbl/data.frame) + .. ..$ origin_date : chr(0) + .. ..$ target : chr(0) + .. ..$ horizon : chr(0) + .. ..$ location : chr(0) + .. ..$ age_group : chr(0) + .. ..$ output_type : chr(0) + .. ..$ output_type_id: chr(0) + ..$ call : chr "check_tbl_values_required" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ value_col_valid :List of 4 + ..$ message : chr "Values in column `value` all valid with respect to modeling task config. \n " + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_tbl_value_col" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ value_col_non_desc:List of 5 + ..$ message : chr "Values in `value` column are non-decreasing as output_type_ids increase for all unique task ID\n value/outpu"| __truncated__ + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ error_tbl : NULL + ..$ call : chr "check_tbl_value_col_ascending" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_success" "hub_check" "rlang_message" "message" ... + $ value_col_sum1 :List of 4 + ..$ message : chr "No pmf output types to check for sum of 1. Check skipped." + ..$ where : chr "team-model/2023-11-19-team-model.parquet" + ..$ call : chr "check_tbl_value_col_sum1" + ..$ use_cli_format: logi TRUE + ..- attr(*, "class")= chr [1:5] "check_info" "hub_check" "rlang_message" "message" ... + - attr(*, "class")= chr [1:2] "hub_validations" "list" + diff --git a/tests/testthat/test-validate_submission.R b/tests/testthat/test-validate_submission.R index 0630c57d..71c70037 100644 --- a/tests/testthat/test-validate_submission.R +++ b/tests/testthat/test-validate_submission.R @@ -158,3 +158,46 @@ test_that("validate_submission fails when csv cannot be parsed according to sche c("check_error", "hub_check", "rlang_error", "error", "condition") ) }) + +test_that("File containing task ID with all null properties validate correctly", { + expect_snapshot( + str( + validate_submission( + hub_path = test_path("testdata/hub-null"), + file_path = "team-model/2023-11-26-team-model.parquet", + skip_submit_window_check = TRUE + ) + ) + ) + expect_true( + suppressMessages( + check_for_errors( + validate_submission( + hub_path = test_path("testdata/hub-null"), + file_path = "team-model/2023-11-26-team-model.parquet", + skip_submit_window_check = TRUE + ) + ) + ) + ) + expect_snapshot( + str( + validate_submission( + hub_path = test_path("testdata/hub-null"), + file_path = "team-model/2023-11-19-team-model.parquet", + skip_submit_window_check = TRUE + ) + ) + ) + expect_true( + suppressMessages( + check_for_errors( + validate_submission( + hub_path = test_path("testdata/hub-null"), + file_path = "team-model/2023-11-19-team-model.parquet", + skip_submit_window_check = TRUE + ) + ) + ) + ) +}) diff --git a/tests/testthat/testdata/hub-null/hub-config/admin.json b/tests/testthat/testdata/hub-null/hub-config/admin.json new file mode 100644 index 00000000..0fdfb061 --- /dev/null +++ b/tests/testthat/testdata/hub-null/hub-config/admin.json @@ -0,0 +1,13 @@ +{ + "schema_version": "https://raw.githubusercontent.com/Infectious-Disease-Modeling-Hubs/schemas/main/v2.0.0/admin-schema.json", + "name": "US CDC FluSight", + "maintainer": "US CDC", + "contact": { + "name": "Joe Bloggs", + "email": "joe.blogs@cdc.gov" + }, + "repository_host": "GitHub", + "repository_url": "https://github.com/cdcepi/Flusight-forecast-data", + "file_format": ["csv", "parquet", "arrow"], + "timezone": "US/Eastern" +} diff --git a/tests/testthat/testdata/hub-null/hub-config/model-metadata-schema.json b/tests/testthat/testdata/hub-null/hub-config/model-metadata-schema.json new file mode 100644 index 00000000..823175c6 --- /dev/null +++ b/tests/testthat/testdata/hub-null/hub-config/model-metadata-schema.json @@ -0,0 +1,128 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Schema for Modeling Hub model metadata", + "description": "This is the schema for model metadata files, please refer to https://github.com/covid19-forecast-hub-europe/covid19-forecast-hub-europe/wiki/Metadata for more information.", + "type": "object", + "properties": { + "team_name": { + "description": "The name of the team submitting the model", + "type": "string" + }, + "team_abbr": { + "description": "Abbreviated name of the team submitting the model", + "type": "string", + "pattern": "^[a-zA-Z0-9_+]+$", + "maxLength": 16 + }, + "model_name": { + "description": "The name of the model", + "type": "string" + }, + "model_abbr": { + "description": "Abbreviated name of the model", + "type": "string", + "pattern": "^[a-zA-Z0-9_+]+$", + "maxLength": 16 + }, + "model_version": { + "description": "Identifier of the version of the model", + "type": "string" + }, + "model_contributors": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "affiliation": { + "type": "string" + }, + "email": { + "type": "string", + "format": "email" + }, + "orcid": { + "type": "string", + "pattern": "^\\d{4}\\-\\d{4}\\-\\d{4}\\-[\\dX]{4}$" + } + }, + "additionalProperties": false, + "required": ["name", "affiliation", "email"] + } + }, + "website_url": { + "description": "Public facing website for the model", + "type": "string", + "format": "uri" + }, + "repo_url": { + "description": "Repository containing code for the model", + "type": "string", + "format": "uri" + }, + "license": { + "description": "License for use of model output data", + "type": "string", + "enum": [ + "CC0-1.0", + "CC-BY-4.0", + "CC-BY_SA-4.0", + "PPDL", + "ODC-by", + "ODbL", + "OGL-3.0" + ] + }, + "designated_model": { + "description": "Team-specified indicator for whether the model should be eligible for inclusion in a Hub ensemble and public visualization. A team may designate up to two models.", + "type": "boolean" + }, + "citation": { + "description": "One or more citations for this model", + "type": "string", + "examples": ["Gibson GC , Reich NG , Sheldon D. Real-time mechanistic bayesian forecasts of Covid-19 mortality. medRxiv. 2020. https://doi.org/10.1101/2020.12.22.20248736"] + }, + "team_funding": { + "description": "Any information about funding source for the team or members of the team.", + "type": "string", + "examples": ["National Institutes of General Medical Sciences (R01GM123456). The content is solely the responsibility of the authors and does not necessarily represent the official views of NIGMS."] + }, + "data_inputs": { + "description": "List or description of data inputs used by the model", + "type": "string" + }, + "methods": { + "description": "A brief (200 char.) description of the methods used by this model", + "type": "string", + "maxLength": 200 + }, + "methods_long": { + "description": "A full description of the methods used by this model. Among other details, this should include whether spatial correlation is considered and how the model accounts for uncertainty.", + "type": "string" + }, + "ensemble_of_models": { + "description": "Indicator for whether this model is an ensemble of any separate component models", + "type": "boolean" + }, + "ensemble_of_hub_models": { + "description": "Indicator for whether this model is an ensemble specifically of other models submitted to this Hub", + "type": "boolean" + } + }, + "additionalProperties": true, + "required": [ + "team_name", + "team_abbr", + "model_name", + "model_abbr", + "model_contributors", + "license", + "data_inputs", + "methods", + "methods_long", + "ensemble_of_models", + "ensemble_of_hub_models" + ] +} diff --git a/tests/testthat/testdata/hub-null/hub-config/tasks.json b/tests/testthat/testdata/hub-null/hub-config/tasks.json new file mode 100644 index 00000000..3b62c751 --- /dev/null +++ b/tests/testthat/testdata/hub-null/hub-config/tasks.json @@ -0,0 +1,152 @@ +{ + "schema_version": "https://raw.githubusercontent.com/Infectious-Disease-Modeling-Hubs/schemas/main/v2.0.0/tasks-schema.json", + "rounds": [ + { + "round_id_from_variable": true, + "round_id": "origin_date", + "model_tasks": [ + { + "task_ids": { + "origin_date": { + "required": null, + "optional": [ + "2023-11-12", "2023-11-19", "2023-11-26" + ] + }, + "target": { + "required": null, + "optional": ["inc hosp"] + }, + "horizon": { + "required": [1, 2], + "optional": [0] + }, + "location": { + "required": null, + "optional": [ + "US", + "01", + "02" + ] + }, + "age_group":{ + "required":["0-130"], + "optional":["0-0.99","1-4","5-17","5-64","18-49","50-64","65-130"] + } + }, + "output_type": { + "quantile":{ + "output_type_id":{ + "required": [ + 0.01, + 0.025, + 0.05, + 0.1, + 0.15, + 0.2, + 0.25, + 0.3, + 0.35, + 0.4, + 0.45, + 0.5, + 0.55, + 0.6, + 0.65, + 0.7, + 0.75, + 0.8, + 0.85, + 0.9, + 0.95, + 0.975, + 0.99 + ], + "optional":null + }, + "value":{ + "type":"double", + "minimum":0 + + } + } + }, + "target_metadata": [ + { + "target_id": "inc hosp", + "target_name": "Weekly incident RSV hospitalizations", + "target_units": "count", + "target_keys": { + "target": ["inc hosp"] + }, + "target_type": "continuous", + "is_step_ahead": true, + "time_unit": "week" + } + ] + }, + { + "task_ids": { + "origin_date": { + "required": null, + "optional": [ + "2023-11-12", "2023-11-19", "2023-11-26" + ] + }, + "target": { + "required": ["peak time hosp"], + "optional": null + }, + "horizon": { + "required": null, + "optional": null + }, + "location": { + "required": null, + "optional": [ + "US", + "01", + "02" + ] + }, + "age_group":{ + "required":["0-130"], + "optional":["0-0.99","1-4","5-17","5-64","18-49","50-64","65-130"] + } + }, + "output_type": { + "cdf":{ + "output_type_id":{ + "required":[1], + "optional":null + }, + "value":{ + "type":"double", + "minimum":0, + "maximum":1 + } + } + }, + "target_metadata": [ + { + "target_id": "peak time hosp", + "target_name": "Peak timing of hospitalization", + "target_units": "population", + "target_keys": { + "target": ["peak time hosp"] + }, + "target_type": "discrete", + "is_step_ahead": true, + "time_unit": "week" + } + ] + } + ], + "submissions_due": { + "relative_to": "origin_date", + "start": -6, + "end": 100 + } + } + ] +} diff --git a/tests/testthat/testdata/hub-null/model-metadata/team-model.yaml b/tests/testthat/testdata/hub-null/model-metadata/team-model.yaml new file mode 100644 index 00000000..ac85f81a --- /dev/null +++ b/tests/testthat/testdata/hub-null/model-metadata/team-model.yaml @@ -0,0 +1,20 @@ +schema_version: "https://raw.githubusercontent.com/Infectious-Disease-Modeling-Hubs/schemas/main/v2.0.0/admin-schema.json" +team_name: "Team Sam" +team_abbr: "team" +model_name: "Model Ple" +model_abbr: "model" +model_contributors: [ + { + "name": "Smith J", + "affiliation": "Affiliation", + "email": "jbloggs@jh.edu" + }, +] +data_inputs: "Description of Data Inputs" +methods: "Short description of the model" +methods_long: "Long description of the model" +license: "MIT" +model_version: "1.0" +website_url: "https://url_to_team2_modelb_website.com" +team_funding: "funding information" +citation: "Gibson GC , Reich NG , Sheldon D. Real-time mechanistic bayesian forecasts of Covid-19 mortality. medRxiv. 2020. https://doi.org/10.1101/2020.12.22.20248736" diff --git a/tests/testthat/testdata/hub-null/model-output/team-model/2023-11-19-team-model.parquet b/tests/testthat/testdata/hub-null/model-output/team-model/2023-11-19-team-model.parquet new file mode 100644 index 00000000..75cb6fc8 Binary files /dev/null and b/tests/testthat/testdata/hub-null/model-output/team-model/2023-11-19-team-model.parquet differ diff --git a/tests/testthat/testdata/hub-null/model-output/team-model/2023-11-26-team-model.parquet b/tests/testthat/testdata/hub-null/model-output/team-model/2023-11-26-team-model.parquet new file mode 100644 index 00000000..0162db2d Binary files /dev/null and b/tests/testthat/testdata/hub-null/model-output/team-model/2023-11-26-team-model.parquet differ