R/run_archimed.R

Defines functions run_archimed

Documented in run_archimed

#' Run ARCHIMED
#'
#' @param exe    Path to the ARCHIMED executable file including its name
#' @param memory The memory allocated to the JVM (Java Virtual Machine) in megabytes (see details)
#' @param config The configuration file. The function tries to find it if not provided. If the function
#' finds no configuration file, or several, it exits and returns `FALSE`.
#' @param args   Further arguments to pass to the ARCHIMED app
#' @param java   Java path (optionnal, see details)
#'
#' @details The `memory` actually used to run ARCHIMED is the minimum between the input `memory` and
#' the available memory on the system (see `get_free_ram()`). The `java` argument can be a path to the java
#' executable if the user needs a particular version (for example if the default Java used is the Open JDK,
#' because ARCHIMED is only compatible with the Oracle version).
#'
#' @return The function prints the model outputs to the console and returns
#' `TRUE` if ARCHIMED ran successfully, or an error code if any problem occured
#' @export
#'
#' @note If you are using a version of ARCHIMED prior to 2018, you need to pass
#' `Archimed` in the configuration file, such as
#' `run_archimed(path= "archimed.jar", config= "Archimed app_parameters/ArchimedConfiguration.properties")`
#'
#' @examples
#' \dontrun{
#' run_archimed(path= "Archimed/archimed.jar", config= "app_parameters/config.properties")
#' }
run_archimed= function(exe= file.path(getwd(),'archimed.jar'),
                       memory= 4096, config= NULL,
                       args= NULL,java=NULL){
  .= NULL
  wd= getwd()
  on.exit(setwd(wd))

  if(is.null(java)){
    java= "java"
  }

  if(is.null(config)){
    config=
      list.files(getwd(),recursive = TRUE)%>%
      .[grep(".properties",.)]
    if(length(config)!=1){
      message(crayon::red("Failed")," to guess the configuration file, please set it as argument")
      return(FALSE)
    }
  }
  setwd(dirname(exe))

  mem= min(memory,get_free_ram()-1000)
  if(mem<memory){
    warning(paste("Not enough memory available on the system. Requested:",crayon::red(memory),
                  "Mo, memory actually allocated to ARCHIMED:"),crayon::red(mem)," Mo")
  }
  if(mem<1024){stop("Not enough memory available on the system to run ARCHIMED")}

  # Test if there are some white spaces in the config path, and if so double quote it:
  if(grepl(" ",config)){
    config= paste0("\"",config,"\"")
  }

  out= system2(command = java,
               args = c(paste0('-Xmx',min(memory,get_free_ram()),'m'),'-jar',
                        basename(exe), config, paste0("--",args)))
  if(out==0){
    TRUE
  }else{
    message("Error: ARCHIMED call ",crayon::red("failed"))
    return(out)
  }
}





#' Get available RAM
#'
#' @description Get the RAM available on the system
#'
#' @details The function calls wmic for windows and awk for Linux. It is not
#' compatible with Mac OS yet.
#'
#' @return The amount of RAM available on the system in megabytes
#' @export
#'
#' @examples
#' get_free_ram()
get_free_ram <- function(){
  gc()
  if(Sys.info()[["sysname"]] == "Windows"){
    x <- system2("wmic", args =  "OS get FreePhysicalMemory /Value", stdout = TRUE)
    x <- x[grepl("FreePhysicalMemory", x)]
    x <- gsub("FreePhysicalMemory=", "", x, fixed = TRUE)
    x <- gsub("\r", "", x, fixed = TRUE)
    as.integer(as.integer(x)*10^-3)
  } else if(Sys.info()[["sysname"]] == "Linux"){
    as.integer(as.numeric(system("awk '/MemFree/ {print $2}' /proc/meminfo",
                                 intern=TRUE))*10^-3)
  }else{
    stop("Cannot guess free memory from this OS")
  }
}
VEZY/archimedR documentation built on Feb. 28, 2020, 6:36 p.m.