diff --git a/.env.tpl b/.env.tpl new file mode 100644 index 0000000..17a6b89 --- /dev/null +++ b/.env.tpl @@ -0,0 +1 @@ +DB_URI=$DB_URI # NOTE: Don't use double quotes in this variable diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 769312c..1f55d00 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v4 - name: Build - run: docker build -t ADAnalise . + run: docker build -t adanalise . - - name: Test - run: docker run ADAnalise arg1 arg2 arg3 + # - name: Test + # run: docker run adanalise arg1 arg2 arg3 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb2f977 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +output/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..dc554da --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "AlertaDengueAnalise"] + path = AlertaDengueAnalise + url = https://github.com/AlertaDengue/AlertaDengueAnalise diff --git a/Dockerfile b/Dockerfile index 522b7a7..59e3c99 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,50 @@ FROM rocker/tidyverse:latest -RUN echo 'options(repos = c(CRAN = "https://cloud.r-project.org"))' >>"${R_HOME}/etc/Rprofile.site" -COPY . /app -WORKDIR /app +RUN apt-get update && apt-get install -y \ + libcurl4-openssl-dev \ + libssl-dev \ + libxml2-dev \ + libgmp-dev \ + libmpfr-dev \ + libxt-dev \ + libopenblas-dev \ + libudunits2-dev \ + libgdal-dev \ + libgeos-dev \ + libproj-dev \ + gdal-bin \ + proj-bin \ + liblzma-dev \ + libxt-dev \ + libpng-dev \ + libtiff-dev \ + zlib1g-dev \ + libjpeg-dev \ + libicu-dev \ + gfortran \ + liblapack-dev \ + libatlas-base-dev \ + libnlopt-dev \ + make + +RUN echo 'options(repos = c(CRAN = "https://cloud.r-project.org"))' >> "${R_HOME}/etc/Rprofile.site" -# Copy the dependencies file and the R script into the container -COPY dependencies.txt setup.R ./ -COPY your_script.R . +WORKDIR /app -# Install the R package dependencies -RUN R -e "install.packages(readLines('dependencies.txt'), repos='http://cran.rstudio.com/')" +COPY setup.R ./ RUN Rscript setup.R -# Command to run the R script -ENTRYPOINT ["Rscript", "your_script.R"] +COPY dependencies.txt ./ +RUN R -e "options(error = traceback); install.packages(readLines('dependencies.txt'), repos='http://cran.rstudio.com/')" + +RUN R -e "options(error = traceback); install.packages('units', repos='https://cloud.r-project.org')" +RUN R -e "options(error = traceback); install.packages('sf', repos='https://cloud.r-project.org')" + +RUN R -e 'options(error = traceback); install.packages("INLA",repos=c(getOption("repos"),INLA="https://inla.r-inla-download.org/R/stable"), dep=TRUE)' + +RUN R -e 'options(error = traceback); utils::install.packages("miceadds")' +RUN R -e "options(error = traceback); remotes::install_github('inlabru-org/fmesher', ref = 'stable')" + +COPY main.R ./ + +ENTRYPOINT ["Rscript", "main.R"] diff --git a/README.md b/README.md index 00ed382..814daab 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,14 @@ # r-script-container docker template to run R scripts -## Building the container -```bash -docker build -t r-script-container . -``` +## Create & populate .env file +See .env.tpl to check the required env variables in .env file -## Running the container in an interactive terminal +## Building the container ```bash -docker run -v $(pwd):/app -it r-script-container Rscript /app/your_script.R arg1 arg2 arg3 +docker build -t adanalise . ``` -## Running the container without a terminal +## Running the container (all UFs) ```bash -docker run r-script-container arg1 arg2 arg3 -``` +docker run --env-file .env --volume ./output:/app/output -i adanalise --disease dengue --epiweek 202501 # --uf RS SC PR diff --git a/main.R b/main.R new file mode 100644 index 0000000..cfaf76f --- /dev/null +++ b/main.R @@ -0,0 +1,181 @@ +pkgs <- c( + "foreign", + "tidyverse", + "forecast", + "RPostgreSQL", + "xtable", + "zoo", + "assertthat", + "DBI", + "futile.logger", + "lubridate", + "grid", + "INLA", + "cgwtools", + "fs", + "miceadds", + "AlertTools", + "parallel", + "argparse", + "httr" +) + +lapply(pkgs, library, character.only = TRUE, quietly = T) + +ufs <- data.frame( + estado = c( + "Acre", "Amazonas", "Amapá", "Pará", "Rondônia", "Roraima", "Tocantins", + "Alagoas", "Bahia", "Ceará", "Maranhão", "Piauí", "Pernambuco", "Paraíba", + "Rio Grande do Norte", "Sergipe", "Goiás", "Mato Grosso", + "Mato Grosso do Sul", "Distrito Federal", "Espírito Santo", "Minas Gerais", + "Rio de Janeiro", "São Paulo", "Paraná", "Rio Grande do Sul", + "Santa Catarina" + ), + sigla = c( + "AC", "AM", "AP", "PA", "RO", "RR", "TO", + "AL", "BA", "CE", "MA", "PI", "PE", "PB", "RN", "SE", + "GO", "MT", "MS", "DF", + "ES", "MG", "RJ", "SP", + "PR", "RS", "SC" + ) +) + +parser <- ArgumentParser() +parser$add_argument( + "--uf", + choices = ufs$sigla, + help = "Choose the UFs. Default to all UFs. Example: `--uf SP RJ MG`", + nargs = "+", + required = FALSE +) +parser$add_argument( + "--disease", + choices = c("dengue", "chik", "zika"), + help = "Specify the disease: dengue, chik, or zika", + default = "dengue" +) +parser$add_argument( + "--epiweek", + type = "character", + required = TRUE, + help = "Epidemiological week. Format: YYYYWW" +) + +uri <- parse_url(Sys.getenv("DB_URI")) + +args <- parser$parse_args() + +if (!is.null(args$uf)) { + ufs <- ufs[ufs$sigla %in% args$uf, ] +} + +disease <- args$disease +epiweek <- as.numeric(args$epiweek) +finalday <- seqSE(epiweek, epiweek)$Termino +output_dir <- "./output/" + +if (!dir.exists(paste0(output_dir, "sql/"))) { + dir.create(paste0(output_dir, "sql/"), recursive = TRUE) +} + +if (!dir.exists(paste0(output_dir, epiweek))) { + dir.create(paste0(output_dir, epiweek), recursive = TRUE) +} + +con <- dbConnect( + RPostgreSQL::PostgreSQL(), + dbname = sub("^/", "", uri$path), + host = uri$hostname, + port = uri$port, + user = uri$username, + password = uri$password +) + +t1 <- Sys.time() +for (i in seq_len(nrow(ufs))) { + print(i) + estado <- ufs$estado[i] + cid10 <- list(dengue = "A90", chik = "A92", zika = "A92.8") + filename <- paste0("ale-", ufs$sigla[i], "-", epiweek, ".RData") + cities <- getCidades(uf = estado)[, "municipio_geocodigo"] + + res <- list() + + res[[paste0("ale.", disease)]] <- pipe_infodengue( + cities, + cid10 = cid10[[disease]], + nowcasting = ifelse(disease == "dengue", "none", "bayesian"), + finalday = finalday, + narule = "arima", + iniSE = 201001, + dataini = "sinpri", + completetail = 0 + ) + + res[[paste0("restab.", disease)]] <- tabela_historico( + res[[paste0("ale.", disease)]], + iniSE = epiweek - 100 + ) + + save(res, file = paste0(output_dir, epiweek, "/", filename)) +} +t2 <- Sys.time() +message(paste("total time was", t2 - t1)) + +dbDisconnect(con) + +file_paths <- fs::dir_ls(paste0(output_dir, epiweek, "/")) + +j <- 1 +for (i in seq_along(file_paths)) { + load.Rdata(file_paths[i], "res") + assign(paste0("res", j), res) + j <- j + 1 + load(file_paths[i]) +} +rm(res) + +output_path <- paste0(output_dir, "sql/output_", disease, ".sql") + +lapply(seq_along(file_paths), function(j) { + restab <- eval(parse( + text = paste0("res", j, "[['restab.", disease, "']] %>% bind_rows()") + )) + data <- do.call(rbind, restab) + data <- as.data.frame(t(data)) # FIX: t() is an workaround + + if (!"casos_est_max" %in% names(data)) { + data$casos_est_max <- NA + } + + if (is.numeric(data$casos_est_max)) { + data$casos_est_max[data$casos_est_max > 10000] <- NA + } + + summary(data) + write_alerta(data, writetofile = TRUE, arq = output_path) +}) + +ale_data <- list() + +for (i in seq_along(file_paths)) { + data <- eval(parse( + text = paste0( + "transpose(res", i, "[['ale.", disease, "']])[[1]] %>% bind_rows()" + ) + )) + indices <- eval(parse( + text = paste0( + "transpose(res", i, "[['ale.", disease, "']])[[2]] %>% bind_rows()" + ) + )) + ale_data[[i]] <- cbind(data, indices) +} + +res <- do.call(rbind, ale_data) + +if (!dir.exists(paste0(output_dir, "BR"))) { + dir.create(paste0(output_dir, "BR")) +} + +save(res, file = paste0(output_dir, "BR/ale-BR-", epiweek, ".RData")) diff --git a/setup.R b/setup.R index 6b3c5a4..733f136 100644 --- a/setup.R +++ b/setup.R @@ -10,16 +10,23 @@ cran <- c( "devtools", "lubridate", "grid", - "INLA", "parallel", "cgwtools", "fs", + "brpop", + "argparse", + "futile.logger", + "units", + "sf", + "fmesher", "miceadds", - "brpop" + "RPostgres" ) +options(error = traceback) + install <- function(pkg) { - if (!require(pkg, character.only = TRUE)) { + if (!nzchar(system.file(package = pkg))) { install.packages(pkg, dependencies = TRUE) } } diff --git a/your_script.R b/your_script.R deleted file mode 100644 index 70718c5..0000000 --- a/your_script.R +++ /dev/null @@ -1,11 +0,0 @@ -library(ggplot2) - -#commandArgs picks up the variables you pass from the command line -args <- commandArgs(trailingOnly = TRUE) - -# Use the input argument -if (length(args) > 0) { - print(args) -} else { - cat("No argument was passed.\n") -}