#===============================================================================
# run_tzar.R
#===============================================================================
#-------------------------------------------------------------------------------
#' Run a function under normal tzar or tzar emulation
#'
#' If you're building a package rather than writing freestanding
#' R code, R will execute all ".R" files in the package's R directory
#' every time the package is built. This is a problem when using tzar
#' because tzar expects to find and run a file called model.R in the
#' directory with all the other R code for the project. If the code
#' that builds the package finds that file, it will try to run the code in
#' model.R and there will be code not encapsulated in a function and
#' the builder will blow up when it runs that code. For example,
#' you might need one or more library() calls in model.R and these
#' are not supposed to be executed inside package code.
#'
#' The way that run_tzar() is going to fake around this is to allow
#' you to to create a model.R by copying the code from some other
#' file into a file called model.R at the time tzar is run and then
#' remove it after tzar finishes. This behavior is primarily
#' controlled by the boolean argument "copy_model_dot_R_tzar_file".
#' If that flag is TRUE, then run_tzar() will look at other
#' arguments to the function to determine source and destination
#' locations and file names and take care of the copying and cleaning
#' up after the run.
#'
#' If you are working on your project outside of building a package,
#' then it's not a problem to have the model.R code in the same
#' directory as your other R code that tzar expects to run for the
#' project. In that case, just set the "copy_model_dot_R_tzar_file" to
#' FALSE and all the other arguments related to it will be ignored.
#'
#' NOTE: Leaving the copying flag turned on does NOT hurt runs
#' done outside of building a package, so it's recommended
#' to just leave it turned on and put the code you would
#' normally put in model.R in model.R.tzar instead and then
#' let the run_tzar() manage all of that. This way, you
#' can use the emulator with the least amount of installation
#' and management work for you when using the tzar package.
#' @param main_function name of function to call to run under tzar or tzar emulation
#' @param parameters_yaml_file_path Full path with file name for the
#' project.yaml file
#' @param tzar_emulation_yaml_file_path Full path with file name for the
#' yaml file containing control values for tzar emulation
#'
## @param emulating_tzar boolean with TRUE indicating main_function should be
## run under tzar emulation and FALSE indicating run under normal tzar
## @param main_function function to call to run under tzar or tzar emulation
## (NOTE: NOT a string), i.e., your main application code
## @param project_path path of R code and project.yaml file for project
## @param emulation_scratch_file_path path of scratch file for passing
## tzarEmulation flag and tzarOutputDir between tzar and mainline function
## @param tzar_jar_name_with_path Path to the jar file to use to run tzar
##
## @param copy_model_dot_R_tzar_file Boolean flag indicating whether model.R must
## be copied in (e.g., when running inside a package)
## @param model_dot_R_tzar_SRC_dir Path to directory holding the model.R file to
## use to run tzar
## @param model_dot_R_tzar_disguised_filename Name (without path) of the file
## containing the code to be run by tzar as model.R
## @param overwrite_existing_model_dot_R_dest Boolean flag indicating whether
## model.R being copied in should overwrite any existing model.R in destination
## @param required_model_dot_R_filename_for_tzar Name of file that tzar expects to
## find and execute to call user's application code from tzar (currently,
## it's always "model.R")
#'
#' @return Returns nothing #parameters list of parameters loaded from project.yaml file
#' @export
#'
#' @examples \dontrun{
#' # Most frequent use:
#' run_tzar ()
#'
#' # Use with specific project.yaml file other than ./project.yaml
#' run_tzar (parameters_yaml_file_path = "/Users/me/someplace/special_project.yaml")
#'}
#-------------------------------------------------------------------------------
run_tzar <- function (main_function,
parameters_yaml_file_path = "./project.yaml",
tzar_emulation_yaml_file_path = "./tzar_emulation.yaml")
{
#-----------------------------------------------------------------
# Get tzar emulation options from the tzar emulation yaml file.
# This yaml file is separate from the tzar project.yaml file
# because emulation parameters are irrelevant to tzar itself.
# Plus, the project.yaml file is not read until tzar is loaded
# and it may contain things like wildcards that the normal
# yaml reader couldn't easily handle reading it here.
#-----------------------------------------------------------------
tzar_em_params = yaml::yaml.load_file (normalizePath (tzar_emulation_yaml_file_path,
mustWork=TRUE))
emulating_tzar = as_boolean (tzar_em_params$emulating_tzar)
echo_console_to_temp_file = as_boolean (tzar_em_params$echo_console_to_temp_file)
console_out_file_name_with_path = tzar_em_params$console_out_file_name_with_path
copy_model_dot_R_tzar_file = as_boolean (tzar_em_params$copy_model_dot_R_tzar_file)
project_path = tzar_em_params$project_path
tzar_jar_name_with_path = tzar_em_params$tzar_jar_name_with_path
emulation_scratch_file_name_with_path = tzar_em_params$emulation_scratch_file_name_with_path
model_dot_R_tzar_SRC_dir =
tzar_em_params$model_dot_R_tzar_SRC_dir
model_dot_R_tzar_disguised_filename =
tzar_em_params$model_dot_R_tzar_disguised_filename
required_model_dot_R_filename_for_tzar =
tzar_em_params$required_model_dot_R_filename_for_tzar
overwrite_existing_model_dot_R_DEST =
as_boolean (tzar_em_params$overwrite_existing_model_dot_R_DEST)
if (emulating_tzar)
{
#---------------------------------------------------------------
# Get the full path to the emulation scratch file.
# Make sure the path is in canonical form
# for the platform in case there is any problem with it.
# Set mustWork=FALSE because the file should not be there and
# when a file is not there, normalizePath() gives a warning
# that we don't want to see.
#---------------------------------------------------------------
emulation_scratch_file_name_with_path =
normalizePath (emulation_scratch_file_name_with_path,
mustWork=FALSE)
#---------------------------------------------------------
# Often, a run will overflow the console buffer and
# important debugging output to the console output will
# be lost. One solution is to tee the console output
# to a sink file. If that option wass requested,
# open the sink file now.
#---------------------------------------------------------
if (echo_console_to_temp_file)
console_sink_file_info =
open_sink_file (console_out_file_name_with_path)
}
#-----------------------------------------------------------
# If there is no model.R file in the source code area,
# copy the template model.R file into the area.
# This may happen both with and without emulation,
# so be sure to keep this outside the "if(tzar_emulation)
# test above.
#
# Note however, this little bit of code does you no good
# when running tzar at the command line instead of from
# within this code. In that case, if the model.R code
# has been hidden by model.R.tzar, you'll need to copy
# it to model.R yourself because the bit of code here
# is never seen by command line tzar.
#-----------------------------------------------------------
if (copy_model_dot_R_tzar_file)
full_model_dot_R_DEST_path =
copy_model_dot_R_tzar_file_to_src_area (
model_dot_R_tzar_SRC_dir,
model_dot_R_tzar_disguised_filename,
project_path,
required_model_dot_R_filename_for_tzar,
overwrite_existing_model_dot_R_DEST)
#--------------------------------------------------------------------
#--------------------------------------------------------------------
# Ready to make the actual call to tzar from the command line now.
#--------------------------------------------------------------------
#--------------------------------------------------------------------
run_tzar_java_jar (tzar_jar_name_with_path, project_path)
#-------------------------------------------------------------------
# Tzar has now finished doing its run or crashed trying.
# There should be a fully laid out tzar output directory now.
#
# If this was a real tzar run (i.e., without emulation),
# then there's nothing left to do.
#
# If this is a tzar emulation run, it's now time to:
# - Collect parameters set by tzar so we can hand them to the
# real code.
# - Run the user's real code.
# - Clean up the emulation (e.g., renaming various things)
#-------------------------------------------------------------------
if (emulating_tzar)
{
cat ("\n\nIn run_tzar: Finished running dummy EMULATION code under tzar.\n",
" Ready to go back and run real code outside of tzar...")
#----------------------------------------------------------
# Collect parameters, including those built by tzar
# during the dummy run, e.g., output directory location.
#----------------------------------------------------------
parameters = emulate_running_tzar (project_path,
emulation_scratch_file_name_with_path)
#-------------------------------------------------------
# Finally, ready to run the user's code and clean up.
#
# Wrap this in a tryCatch in case there is a fatal
# error during the run.
# If that happens, you want to be able to save the
# console sink file and its important error-related
# information and random seed related information.
# This file is generally lost if there is no tryCatch
# call.
#-------------------------------------------------------
tryCatch (
{
main_function (parameters, emulating_tzar)
clean_up_after_tzar_emulation (parameters$tzar_in_progress_dir_name,
parameters$tzar_emulation_completed_dir_name,
copy_model_dot_R_tzar_file,
full_model_dot_R_DEST_path,
emulation_scratch_file_name_with_path,
echo_console_to_temp_file,
console_sink_file_info,
parameters$full_output_dir_with_slash)
cat ("\n\nIn run_tzar: Finished running tzar WITH emulation...\n")
},
error = function (err)
{
handle_error_clean_up_after_tzar_emulation_crash (
parameters$tzar_in_progress_dir_name,
emulation_scratch_file_name_with_path,
echo_console_to_temp_file,
console_sink_file_info,
parameters$full_output_dir_with_slash)
}
)
} else
{
cat ("\n\nIn run_tzar: Finished running tzar WITHOUT emulation...\n")
}
#----------------------------------------------------------------
# Make sure that model.R is removed if you're running inside a
# package Build.
# This applies even if you're not doing emulation but still
# calling tzar from this emulator code with the
# emulating_tzar flag set to FALSE.
# This has no effect however, if tzar is run from the command
# line instead of through this code.
#----------------------------------------------------------------
if (copy_model_dot_R_tzar_file) file.remove (full_model_dot_R_DEST_path)
}
#===============================================================================
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.