Skip to content

Commit

Permalink
eliminate parallel packages in SIMrun
Browse files Browse the repository at this point in the history
  • Loading branch information
mnneely committed Apr 19, 2024
1 parent 36fde5d commit bdda1ee
Show file tree
Hide file tree
Showing 49 changed files with 86 additions and 100 deletions.
2 changes: 1 addition & 1 deletion .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ compile.*
.vscode
^_pkgdown\.yml$
^docs$
^doc$
^pkgdown$
^\.github$
^Meta$
Expand All @@ -18,3 +17,4 @@ compile.*
^man-roxygen
^README\.Rmd$
logo.png
^vignettes/articles$
54 changes: 49 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,57 @@
.Rproj.user
# History files
.Rhistory
.Rapp.history

# Session Data files
.RData
.RDataTmp

# User-specific files
.Ruserdata

# Example code in package build process
*-Ex.R

# Output files from R CMD build
/*.tar.gz

# Output files from R CMD check
/*.Rcheck/

# RStudio files
.Rproj.user/

# produced vignettes
vignettes/*.html
vignettes/*.pdf

# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
.httr-oauth

# knitr and R markdown default cache directories
*_cache/
/cache/

# Temporary files created by R markdown
*.utf8.md
*.knit.md

# R Environment Variables
.Renviron

# pkgdown site
docs/

# translation temp files
po/*~

# RStudio Connect folder
rsconnect/
docs

# other
.DS_Store
Pmetrics.Rcheck/
#build
Archived
PACKAGES.gz
PACKAGES.rds
Expand All @@ -15,16 +62,13 @@ src/registerDynamicSymbol.o
src/Pmetrics.dll
PmetricsGit.Rproj
inst/compiledFortran/
.DS_Store
src/symbols.rds
tests/testthat/Runs/
..Rcheck/
.vscode/
.Rd2pdf65996/
other/
.Rprofile
Examples
.Rdata
.httr-oauth
inst/rust/template/*
inst/options/PMoptions.json
Expand Down
3 changes: 0 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,11 @@ Suggests:
curl,
data.table,
devtools,
doParallel,
foreach,
ggpubr,
htmltools,
knitr,
mclust,
pandoc,
parallel,
patchwork,
PmetricsData,
progress,
Expand Down
116 changes: 31 additions & 85 deletions R/SIMparse.R
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@
#' will be a list of PMsim objects, which can be plotted or otherwise accessed using standard list
#' referencing, e.g. `simlist[[1]]`, `simlist[[2]]`, etc.
#' @param quiet Suppress messages
#' @param parallel Runs in parallel mode. Defaults to true if multiple files are to be parsed, otherwise false.
#' Can be overridden by specifying \code{TRUE} or \code{FALSE}.
#' @return If one file is parsed or multiple files are parsed and combined, the return will be a list with five items, of class \emph{PMsim}.
#' If multiple files are parsed and not combined, then the return will be a *PM_simlist* of \emph{PMsim} objects.
#' \item{obs }{An data frame of simulated observations with 4 columns: id, time, out, outeq.
Expand All @@ -57,28 +55,28 @@
#' @seealso [PM_result], [PM_sim], [SIMrun]
#' @export

SIMparse <- function(file, include, exclude, combine = F, quiet = F, parallel) {
SIMparse <- function(file, include, exclude, combine = F, quiet = F) {
processfile <- function(n) {
out <- readLines(allfiles[n])
nsim <- as.numeric(strparse("[[:digit:]]+", out[grep(" THE NO. OF SIMULATED SUBJECTS", out)]))
nout <- as.numeric(strparse("[[:digit:]]+", out[grep(" THE NO. OF OUTPUT EQUATIONS", out)]))
nobs <- as.numeric(strparse("[[:digit:]]+", out[grep(" VALUES FOR EACH OUTPUT EQUATION", out)]))
nsim <- as.numeric(stringr::str_extract(out[grep(" THE NO. OF SIMULATED SUBJECTS", out)], "[[:digit:]]+"))
nout <- as.numeric(stringr::str_extract(out[grep(" THE NO. OF OUTPUT EQUATIONS", out)], "[[:digit:]]+"))
nobs <- as.numeric(stringr::str_extract(out[grep(" VALUES FOR EACH OUTPUT EQUATION", out)], "[[:digit:]]+"))
i <- grep("CONTAIN THE SIMULATED OBSERVED$", out)
times <- as.numeric(scan(allfiles[n], skip = i + 6, n = nobs + 1, what = "character", quiet = T)[-1])


# get compartment amounts and outeq concentrations for each output
# places for compartment amounts
amtlines <- grep("COMPARTMENT NO", out) + 1
# number of compartments
ncomp <- length(amtlines)


# places for observations
obslines <- grep("OUTPUT EQUATION NO", out) + 1
# skip observed assay noise
obslines <- obslines[-(1:nout)]

# id is a block of 1:nsim repeated for each observation, all repeated for each compartment
# time is a block of the times repeated for each subject, all repeated for each compartment
# amt all amounts
Expand All @@ -95,7 +93,7 @@ SIMparse <- function(file, include, exclude, combine = F, quiet = F, parallel) {
} else {
amt <- NA
}

# id is a block of 1:nsim repeated for each observation, all repeated for each output
# time is a block of the times repeated for each subject, all repeated for each output
# out is all observations
Expand All @@ -109,10 +107,10 @@ SIMparse <- function(file, include, exclude, combine = F, quiet = F, parallel) {
outeq = rep(1:nout, each = nsim * nobs)
)
obs$out[obs$out == -99] <- NA


# get simulated parameter values

i <- grep("PARAMETER VALUES FOR ALL THE SUBJECTS.", out)
parNames <- unlist(strsplit(out[i + 2], " +"))[-1]
parValues <- t(sapply(
Expand All @@ -122,10 +120,10 @@ SIMparse <- function(file, include, exclude, combine = F, quiet = F, parallel) {
parValues <- data.frame(parValues)
names(parValues) <- parNames
names(parValues)[names(parValues) == "SUBJ."] <- "id"


# get means and covariances of entire simulated set

i <- grep("BECAUSE OF PARAMETER BOUNDARY RESTRICTIONS", out)
if (length(i) > 0) {
totalSets <- as.numeric(scan(allfiles[1], what = "character", skip = i, nlines = 1, quiet = T, strip.white = T)[1])
Expand All @@ -152,29 +150,29 @@ SIMparse <- function(file, include, exclude, combine = F, quiet = F, parallel) {
}
names(totalMeans) <- parNames[-1]
if (length(parValues) > 2) dimnames(totalCov) <- list(parNames[-1], parNames[-1])

return(list(obs = obs, amt = amt, parValues = parValues, totalSets = totalSets, totalMeans = totalMeans, totalCov = totalCov))
} # end of processfile function

# starttime <- proc.time()

if (missing(file)) {
cat("Please provide filename of Pmetrics simulation output file(s).\n")
return()
}

# extract pattern from strings
strparse <- function(pattern, x) {
match <- regexpr(pattern, x, perl = T) # perl=T required for the lookahead
start <- match[1]
stop <- match[1] + attr(match, "match.length") - 1
return(substr(x, start, stop))
}

# separate files if more than one
files <- unlist(strsplit(file, ","))
# remove leading and trailing spaces
files <- sub("^[[:blank:]]*", "", files)
files <- sub("[[:blank:]]*$", "", files)

# check that wildcard-generated list does not include outdated files
# if out-of-order files are found, the user has the option to include them, exclude them, or abort
nfilepar <- length(files)
Expand Down Expand Up @@ -209,7 +207,7 @@ SIMparse <- function(file, include, exclude, combine = F, quiet = F, parallel) {
} # end of check list of files generated by wildcard block
} # end of IF wildcard used block
} # end of filecheck cycle

allfiles <- unique(Sys.glob(files)) # unique to exclude duplicates
simnum <- as.numeric(sapply(allfiles, function(x) strparse("([[:digit:]]+)(?!.*[[:digit:]])", x)))
# new reg exp matches the last number in filename rather than the first; "run5out1.txt" will now return 1 rather than 5
Expand All @@ -221,73 +219,24 @@ SIMparse <- function(file, include, exclude, combine = F, quiet = F, parallel) {
allfiles <- allfiles[-exclude]
}
allfiles <- setdiff(allfiles, tobeignored) # delete files that are to be ignored from the date check

nfiles <- length(allfiles)
if (nfiles == 0) {
stop("No files found.\n")
}
if (missing(parallel)) {
if (nfiles > 1) {
parallel <- T
} else {
parallel <- F
}
}

if (parallel) {
no_cores <- parallel::detectCores()
}


# process return objects

# initialize return objects
simlist <- list()
if (!quiet) {
cat(paste("\nProcessing ", nfiles, " simulated data file(s)", sep = ""))
if (parallel) cat(" in parallel on ", no_cores, " cores.", sep = "")
cat("\n")
cat(paste("\nProcessing ", nfiles, " simulated data file(s).\n", sep = ""))
flush.console()
}
if (!quiet & !parallel) {
pb <- txtProgressBar(min = 0, max = nfiles, style = 3)
}


par1 <- requireNamespace("doParallel", quietly = TRUE)
par2 <- requireNamespace("foreach", quietly = TRUE)
par3 <- requireNamespace("parallel", quietly = TRUE)

if(!all(c(par1, par2, par3))){ #if any above packages are missing

cat(paste0(crayon::green("NOTE: "), "Install the following package(s) for parallel processing: ",
crayon::blue(paste(c("doParallel", "foreach", "parallel")[c(!par1, !par2, !par3)], collapse = ", ")),
".\n"))

parallel <- FALSE

}

#map through files in pseudo-parallel; full parallel removed as actually longer
simlist <- purrr::pmap(list(1:nfiles), processfile, .progress = list(type = "tasks", name = "Files") )



if (parallel) {
cl <- parallel::makeCluster(no_cores, setup_timeout = 0.5)
# May 8, 2020 remove the second argument when bug fixed in Rstudio
doParallel::registerDoParallel(cl)
simlist <- foreach::foreach(n = 1:nfiles, .verbose = F) %dopar% {
processfile(n)
}
parallel::stopCluster(cl)
} else {
for (n in 1:nfiles) {
simlist[[n]] <- processfile(n)
if (!quiet) {
setTxtProgressBar(pb, n)
}
}
if (!quiet) {
close(pb)
}
}

# combine obs if requested
if (combine & nfiles > 1) {
if (!quiet) {
Expand All @@ -299,7 +248,7 @@ SIMparse <- function(file, include, exclude, combine = F, quiet = F, parallel) {
simlist[[x]]$obs$id <- paste(simlist[[x]]$obs$id, sprintf("%02d", x), sep = ".")
simlist[[x]]
})

obs <- do.call(rbind, lapply(simlist, function(x) x$obs))
amt <- do.call(rbind, lapply(simlist, function(x) x$amt))
parValues <- do.call(rbind, lapply(simlist, function(x) x$parValues))
Expand All @@ -309,7 +258,7 @@ SIMparse <- function(file, include, exclude, combine = F, quiet = F, parallel) {
totalCov <- Reduce("+", lapply(simlist, function(x) x$totalCov * x$totalSets)) / totalSets
simlist <- list(obs = obs, amt = amt, parValues = parValues, totalSets = totalSets, totalMeans = totalMeans, totalCov = totalCov)
}

# return simlist
if (nfiles > 1) { # more than one file
if (combine) { # combined
Expand All @@ -329,9 +278,6 @@ SIMparse <- function(file, include, exclude, combine = F, quiet = F, parallel) {
message <- paste(paste("\nThe following file was successfully parsed: ", paste(allfiles, collapse = ", "), "\n", sep = ""))
}

utils::Rprof(NULL)
# runningtime <- proc.time()-starttime
if (!quiet) cat(message)
# if(!quiet) cat(message,"Running time: ", runningtime[3], sep="")
return(simlist)
}
6 changes: 4 additions & 2 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ home:
reference:
- title: R6 objects
desc: Create Pmetrics R6 objects
- contents:
- contents:
- starts_with("PM_")
- ab
- additive
Expand All @@ -53,6 +53,7 @@ reference:
- msd
- proportional
- build_model
- build_plot
- title: Make functions
desc: Functions for making Pmetrics objects
- contents:
Expand All @@ -65,7 +66,7 @@ reference:
- MM_opt
- title: Plot
desc: Functions for plotting Pmetrics output
- contents:
- contents:
- starts_with("plot")
- ab_line
- add_shapes
Expand Down Expand Up @@ -129,6 +130,7 @@ reference:
- editPMoptions
- movePMoptions
- update_gfortran
- getPMdata
- title: Reference
desc: Reference functions
- contents:
Expand Down
5 changes: 1 addition & 4 deletions man/SIMparse.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 comments on commit bdda1ee

Please sign in to comment.