diff --git a/.Rbuildignore b/.Rbuildignore index 8cc694c..6b9c8ad 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,3 +1,4 @@ +^codemeta\.json$ ^codecov\.yml$ ^\.travis\.yml$ ^Meta$ @@ -11,4 +12,5 @@ PET.Rcheck readme.md paper.md paper.bib -contributing.md \ No newline at end of file +contributing.md +docs diff --git a/.gitignore b/.gitignore index 19685b3..ad56434 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +doc Meta analysis scratch diff --git a/DESCRIPTION b/DESCRIPTION index 52e167e..e429364 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,13 +1,21 @@ Package: tacmagic Type: Package Title: tacmagic: PET Analysis in R -Version: 0.1.9 +Version: 0.2.0 Authors@R: c(person("Eric", "Brown", role = c("aut", "cre"), email = "eb@ericebrown.com", comment = c(ORCID = "0000-0002-1575-2606")), person("Ariel", "Graff-Guerrero", - role = c("dgs"))) + role = "dgs"), + person("Jon", "Clayden", + role = c("rev"), + comment = c(ORCID = "0000-0002-6608-0619", + "Jon Clayden reviewed the package for ropensci, see ")), + person("Brandon", "Hurr", + role = c("rev"), + comment = c(ORCID = "0000-0003-2576-4544", + "Brandon Hurr reviewed the package for ropensci, see "))) Description: To faciliate analysis of positron emission tomography (PET) time activity curve (TAC) data, and to encourage open science and replicability, this package supports data loading and analysis of multiple TAC file diff --git a/NAMESPACE b/NAMESPACE index f12d5b5..ce4f90d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,22 +1,26 @@ # Generated by roxygen2: do not edit by hand +S3method(as.data.frame,tac) +S3method(plot,ref_Logan) +S3method(plot,tac) +S3method(summary,tac) export(DVR_all_ref_Logan) export(DVR_ref_Logan) +export(as.tac) export(batch_load) export(batch_tm) export(batch_voistat) export(cutoff_aiz) +export(dvr) export(load_tac) export(load_voistat) export(load_vol) -export(plot_ref_Logan) -export(plot_tac) export(pos_anyroi) -export(references) export(roi_ham_full) export(roi_ham_pib) export(roi_ham_stand) export(save_tac) +export(split_pvc) export(suvr) export(suvr_auc) export(tac_roi) @@ -34,6 +38,7 @@ importFrom(stats,lm) importFrom(stats,quantile) importFrom(stats,sd) importFrom(stats,weighted.mean) +importFrom(tools,file_ext) importFrom(utils,head) importFrom(utils,read.csv) importFrom(utils,read.delim) diff --git a/R/ROI_definitions.R b/R/ROI_definitions.R index fb1495d..7c6e1a4 100755 --- a/R/ROI_definitions.R +++ b/R/ROI_definitions.R @@ -7,14 +7,18 @@ # ROI definitions file. - #' Return a list of merged ROIs made up of the atomic ROIs in the Hammer's -#' atlas (see references()$Hammers_2003). +#' atlas. #' #'@export #'@return A list of lists, where each list is an ROI (e.g.) frontal lobe that #' specifies the atomic ROIs from the atlas that make it up. #'@family ROI definitions +#'@references Hammers, Alexander, Richard Allom, Matthias J. Koepp, Samantha L. Free, +#' Ralph Myers, Louis Lemieux, Tejal N. Mitchell, David J. Brooks, and John S. +#' Duncan. 2003. Three-dimensional Maximum Probability Atlas of the Human +#' Brain, with Particular Reference to the Temporal Lobe. Human Brain Mapping +#' 19 (4): 224-247. doi:10.1002/hbm.10123 #'@examples #' roi_ham_stand() roi_ham_stand <- function() { @@ -77,6 +81,11 @@ roi_ham_stand <- function() { #'@return A list of lists, where each list is an ROI (e.g.) frontal lobe that #' specifies the atomic ROIs from the atlas that make it up. #'@family ROI definitions +#'@references Hammers, Alexander, Richard Allom, Matthias J. Koepp, Samantha L. Free, +#' Ralph Myers, Louis Lemieux, Tejal N. Mitchell, David J. Brooks, and John S. +#' Duncan. 2003. Three-dimensional Maximum Probability Atlas of the Human +#' Brain, with Particular Reference to the Temporal Lobe. Human Brain Mapping +#' 19 (4): 224-247. doi:10.1002/hbm.10123 #'@examples roi_ham_full() roi_ham_full <- function() { @@ -107,6 +116,11 @@ roi_ham_full <- function() { #'@return A list of lists, where each list is an ROI (e.g.) frontal lobe that #' specifies the atomic ROIs from the atlas that make it up. #'@family ROI definitions +#'@references Hammers, Alexander, Richard Allom, Matthias J. Koepp, Samantha L. Free, +#' Ralph Myers, Louis Lemieux, Tejal N. Mitchell, David J. Brooks, and John S. +#' Duncan. 2003. Three-dimensional Maximum Probability Atlas of the Human +#' Brain, with Particular Reference to the Temporal Lobe. Human Brain Mapping +#' 19 (4): 224-247. doi:10.1002/hbm.10123 #'@examples #' roi_ham_pib() roi_ham_pib <- function() { diff --git a/R/SUVR.R b/R/SUVR.R index 20fbf3e..51c385f 100755 --- a/R/SUVR.R +++ b/R/SUVR.R @@ -13,9 +13,8 @@ #'@export #'@param tac The time-activity curve data from tac_roi() #'@param SUVR_def a vector of start times for window to be used in SUVR -#'@param ref a string, e.g. "cerbellum", to specify reference region -#'@param params a list of paramters passed from the batch_tm function and is -#' not needed when calling for individual participants. +#'@param ref a string, e.g. "cerebellum", to specify reference region +#'@param ... When called from tm_batch, unused parameters may be supplied #'@return A data.frame of SUVR values for the specified ROIs #'@family SUVR functions #'@examples @@ -28,25 +27,12 @@ #' #' AD06_SUVR <- suvr(AD06, SUVR_def=c(3000,3300,3600), ref="cerebellum") #' -suvr <- function(tac, SUVR_def=NULL, ref=NULL, params=NULL) { +suvr <- function(tac, SUVR_def, ref, ...) { - if (!(is.null(params))) { - if(!is.null(c(SUVR_def, ref))) { - stop("Only provide either params argument or both SUVR_def and ref.") - } - if ( is.null(params$SUVR_def) | is.null(params$ref) ) { - stop("Both SUVR_def and ref are needed to calculate SUVR.") - } - - ref <- params$ref - SUVR_def <- params$SUVR - } - - #TODO: validate that SUVR_def is suitable + validate_suvr_params(tac, SUVR_def, ref) SUVRtable <- new_table(tac, "SUVR") - # TODO validate that t1$start and t2$end are numeric frames <- match(SUVR_def, tac$start) frame_weights <- tac$end[frames] - tac$start[frames] @@ -67,7 +53,8 @@ suvr <- function(tac, SUVR_def=NULL, ref=NULL, params=NULL) { #'@export #'@param tac The time-activity curve data from tac_roi() #'@param SUVR_def a vector of start times for window to be used in SUVR -#'@param ref is a string, e.g. "cerbellum", to specify reference region +#'@param ref is a string, e.g. "cerebellum", to specify reference region +#'@param ... When called from tm_batch, unused parameters may be supplied #'@family SUVR functions #'@return A data.frame of SUVR values for the specified ROIs #' #' f <- system.file("extdata", "AD06.tac", package="tacmagic") @@ -79,19 +66,37 @@ suvr <- function(tac, SUVR_def=NULL, ref=NULL, params=NULL) { #' #' AD06_SUVR <- suvr_auc(AD06, SUVR_def=c(3000,3300,3600), ref="cerebellum") #' -suvr_auc <- function(tac, SUVR_def, ref) { +suvr_auc <- function(tac, SUVR_def, ref, ...) { - SUVRtable <- new_table(tac, "SUVR") + validate_suvr_params(tac, SUVR_def, ref) + + SUVRtable <- new_table(tac, "SUVR") - tac$mid <- (tac$start + tac$end) / 2 + tac$mid <- (tac$start + tac$end) / 2 - for (ROI in names(tac)[-c(1:2, length(tac))]) { - rich <- pracma::trapz(tac[(tac$start %in% SUVR_def),][,"mid"], - tac[(tac$start %in% SUVR_def),][,ROI]) - poor <- pracma::trapz(tac[(tac$start %in% SUVR_def),][,"mid"], - tac[(tac$start %in% SUVR_def),][,ref]) - SUVRtable[ROI, "SUVR"] <- rich/poor - } + for (ROI in names(tac)[-c(1:2, length(tac))]) { + rich <- pracma::trapz(tac[(tac$start %in% SUVR_def),][,"mid"], + tac[(tac$start %in% SUVR_def),][,ROI]) + poor <- pracma::trapz(tac[(tac$start %in% SUVR_def),][,"mid"], + tac[(tac$start %in% SUVR_def),][,ref]) + SUVRtable[ROI, "SUVR"] <- rich/poor + } return(SUVRtable) } + + +# Checks to ensure SUVR parameters are appropriate and throws error if not. +#' @noRd +validate_suvr_params <- function(tac, SUVR_def, ref) { + + if(!validate_tac(tac)) stop("Supplied tac file did not validate.") + + if (!all(SUVR_def %in% tac$start)) { + stop("The SUVR definition must refer to valid start times in the tac") + } + + if(!(ref %in% names(tac))) { + stop("The reference region (ref) must be in the supplied tac.") + } +} diff --git a/R/batch_models.R b/R/batch_models.R index fe108a9..dffb9b6 100644 --- a/R/batch_models.R +++ b/R/batch_models.R @@ -31,7 +31,7 @@ model_definitions <- function() { #'@param params Parameters passed from batch_tm() #'@return A data.frame of SUVR values for the ROIs for all participants #'@noRd -model_batch <- function(all_tacs, model=NULL, params) { +model_batch <- function(all_tacs, model=NULL, ...) { # Specify function to use (except Logan, which needs different params) ------ if (class(model) == "function") { @@ -55,7 +55,7 @@ model_batch <- function(all_tacs, model=NULL, params) { #message(paste("Working on...", participants[i])) tac_data <- all_tacs[[i]] - VALUE <- suppressMessages(model_fn(tac_data, params=params)) + VALUE <- suppressMessages(model_fn(tac_data, ...)) master[participants[i], ] <- t(VALUE) } diff --git a/R/batches.R b/R/batches.R index 9607599..2ba64b0 100644 --- a/R/batches.R +++ b/R/batches.R @@ -19,12 +19,9 @@ #'@export #'@param all_tacs A list by participant, of tac data (load_batch()) #'@param models A vector of names of the models to calculate -#'@param ref The name of the reference region for DVR/SUVR calculation -#'@param SUVR_def is a vector of the start times for window to be used in SUVR -#'@param k2prime Fixed k2' for DVR calculation -#'@param t_star Change from 0 to manually specify a t* for DVR calculation #'@param custom_model A function that can be run like other models (advanced) -#'@param custom_params To pass to custom_model as params$custom_params +#'@param ... The arguments that get passed to the specified models/custom model, +#' many are required; please check with model desired. #'@return A table of SUVR values for the specified ROIs for all participants #'@family Batch functions #'@examples @@ -33,19 +30,16 @@ #' system.file("extdata", "AD08.tac", package="tacmagic")) #' #' tacs <- batch_load(participants, tac_file_suffix="") -#' for (i in 1:3) tacs[[i]][,1:80] # to remove the PVC values for this example +#' +#' # Keeps only the ROIs without partial-volume correction (PMOD convention) +#' tacs <- lapply(tacs, split_pvc, FALSE) #' #' batch <- batch_tm(tacs, models=c("SUVR", "Logan"), ref="Cerebellum_r", #' SUVR_def=c(3000,3300,3600), k2prime=0.2, t_star=23) #' -batch_tm <- function(all_tacs, models=c("SUVR", "Logan"), ref, SUVR_def=NULL, - k2prime=NULL, t_star=NULL, - custom_model=NULL, custom_params=NULL) { +batch_tm <- function(all_tacs, models, custom_model=NULL, ...) { #---------------------------------------------------------------------------- - params <- list(ref=ref, SUVR_def=SUVR_def, k2prime=k2prime, - t_star=t_star, custom_params=custom_params) - all_models <- names(model_definitions()) if (!(all(models %in% all_models))) stop("Invalid model name(s) supplied.") @@ -53,14 +47,14 @@ batch_tm <- function(all_tacs, models=c("SUVR", "Logan"), ref, SUVR_def=NULL, # Run each model from available models -------------------------------------- for (this_model in models) { - MOD <- model_batch(all_tacs, model=this_model, params=params) + MOD <- model_batch(all_tacs, model=this_model, ...) names(MOD) <- lapply(names(MOD), paste0, "_", this_model) if (is.null(master)) master <- MOD else master <- data.frame(master, MOD) } # Run the custom model if one was specified --------------------------------- if(!is.null(custom_model)) { - MOD <- model_batch(all_tacs, params=params, model=custom_model) + MOD <- model_batch(all_tacs, model=custom_model, ...) names(MOD) <- lapply(names(MOD), paste0, "_custom") if (is.null(master)) master <- MOD else master <- data.frame(master, MOD) } @@ -81,7 +75,8 @@ batch_tm <- function(all_tacs, models=c("SUVR", "Logan"), ref, SUVR_def=NULL, #'@param dir A directory and/or file name prefix for the tac/volume files #'@param tac_format Format of tac files provided: See load_tac() #'@param tac_file_suffix How participant IDs corresponds to the TAC files -#'@param roi_m T if you want to merge atomic ROIs into larger ROIs +#'@param roi_m TRUE if you want to merge atomic ROIs into larger ROIs (and if +#' not, the following parameters are not used) #'@param vol_format The file format that includes volumes: See load_vol() #'@param vol_file_suffix How participant IDs correspond to volume files #'@param ROI_def Object that defines combined ROIs, see ROI_definitions.R @@ -96,11 +91,19 @@ batch_tm <- function(all_tacs, models=c("SUVR", "Logan"), ref, SUVR_def=NULL, #' system.file("extdata", "AD08.tac", package="tacmagic")) #' #' tacs <- batch_load(participants, tac_file_suffix="") -batch_load <- function(participants, PVC=FALSE, dir="", tac_format="PMOD", - tac_file_suffix=".tac", roi_m=FALSE, +batch_load <- function(participants, dir="", tac_file_suffix=".tac", + tac_format="PMOD", roi_m=FALSE, PVC=NULL, vol_file_suffix=NULL, vol_format=NULL, merge=NULL, ROI_def=NULL) { + if (!roi_m) { + if (!all(c(is.null(vol_format), is.null(vol_file_suffix), is.null(ROI_def), + is.null(PVC)))) { + warning("You specified parameters used for volume-based ROI merging, but + roi_m is FALSE so those parameters will not be used.") + } + } + r <- lapply(participants, load_tacs, dir=dir, tac_format=tac_format, roi_m=roi_m, tac_file_suffix=tac_file_suffix, vol_file_suffix=vol_file_suffix, @@ -125,7 +128,7 @@ batch_load <- function(participants, PVC=FALSE, dir="", tac_format="PMOD", #'@param ROI_def Object that defines combined ROIs, see ROI_definitions.R #'@param dir Directory and/or filename prefix of the files #'@param filesuffix Optional filename characters between ID and ".voistat" -#'@param varname The name of the variable being exctracted, e.g. "SRTM" +#'@param varname The name of the variable being extracted, e.g. "SRTM" #'@return A table of values for the specified ROIs for all participants #'@family Batch functions #'@examples diff --git a/R/cutoff.R b/R/cutoff.R index 0819eb7..94ca1d4 100755 --- a/R/cutoff.R +++ b/R/cutoff.R @@ -5,17 +5,18 @@ ## Beta version--check all work ## ################################## - -#' Cutoff value caluclation using method described in Aizenstein et al. 2008 +#' Cutoff value calculation using method described in Aizenstein et al. 2008 #' -#' See references()$Aizenstein. The authors proposed a standardized method of -#' calculating PIB+ cutoff values to classify participants as PIB+ or PIB-. They -#' used the DVR from several ROIs associated with amyloid deposition. The steps -#' are summarized below. cutoff_aiz() implements 1-3, returning cutoff values -#' for each ROI. It can be used to dichotomize participants, with pos_anyroi(). +#' See the reference below and the tacmagic walkthrough vignette. Aizenstein et +#' al. (2008) proposed a standardized method of calculating Pittsburg Compound +#' B (PIB) cutoff values to classify participants as PIB+ or PIB-. They used the +#' distribution volume ratio (DVR) from several ROIs associated with amyloid +#' deposition. The steps are summarized below. cutoff_aiz() implements 1-3, +#' returning cutoff valuesfor each ROI. It can be used to dichotomize +#' participants, with pos_anyroi(). #' #' 1. Remove outliers from a group of cognitively normal individuals. An outlier -#' is defined as having any ROI with DVR > upper inner fence of that ROI (= 3rd +#' is defined as having any ROI with DVR > upper inner fence of that ROI (= 3rd #' quartile + (1.5 * IQR). #' 2. Iterate step 1 as needed until there are no more outlying participants. #' 3. From this subset of the group with outliers removed, the cutoff value for @@ -28,6 +29,11 @@ #' @param ROIs list of variables (ROIs) to use for cutoff detection #' @return Cutoff values for each ROI based on the above method #' @family Cutoff functions +#' @references Aizenstein HJ, Nebes RD, Saxton JA, et al. 2008. Frequent amyloid +#' deposition without significant cognitive impairment among the elderly. +#' Arch Neurol 65: 1509-1517. +#' @examples +#' cutoff_aiz(fake_DVR, c("ROI1_DVR", "ROI2_DVR", "ROI3_DVR", "ROI4_DVR")) cutoff_aiz <- function(modelstats, ROIs) { if (length(ROIs) < 2) stop("You must specify at least 2 ROIs.") @@ -61,18 +67,21 @@ cutoff_aiz <- function(modelstats, ROIs) { #' Dichotomize participants based on ROI cutoff values #' -#' See references()$Aizenstein. The authors proposed a standardized method of -#' calculating PIB+ cutoff values to classify participants as PIB+ or PIB-. -#' They used the DVR from 7 ROIs associated with amyloid deposition. This -#' function takes the ROI-based cutoff-values, e.g. from cutoff_aiz(), and -#' returns a table specifying which participants are positive, i.e. which have -#' at least one ROI greater than the cutoff. +#' Aizenstein et al. (2008) proposed a standardized method of calculating PIB+ +#' cutoff values to classify participants as PIB+ or PIB-. They used the DVR +#' from 7 ROIs associated with amyloid deposition. This function takes the +#' ROI-based cutoff values, e.g. from cutoff_aiz(), and returns a table +#' specifying which participants are positive, i.e. which have at least one ROI +#' greater than the cutoff. #' #' @export #' @param modelstats SUVR or DVR data for group of participants from batch_tm() #' @param cutoff cutoffs for ROIs as from cutoff_aiz() #' @return data.frame of participants and positive/negative status #' @family Cutoff functions +#' @references Aizenstein HJ, Nebes RD, Saxton JA, et al. 2008. Frequent amyloid +#' deposition without significant cognitive impairment among the elderly. +#' Arch Neurol 65: 1509-1517. pos_anyroi <- function(modelstats, cutoff) { pos_tab <- modelstats pos_tab[,] <- NA diff --git a/R/dvr.R b/R/dvr.R new file mode 100644 index 0000000..5191c83 --- /dev/null +++ b/R/dvr.R @@ -0,0 +1,59 @@ +################################## +## tacmagic - PET Analysis in R ## +## dvr.R ## +## (C) Eric E. Brown 2018 ## +## Beta version--check all work ## +################################## + +#' Distribution volume ratio (DVR) for one or more ROIs +#' +#' This calculates the DVR using the non-invasive reference Logan method for +#' all TACs in a supplied tac file. It uses DVR_ref_Logan if a target ROI is +#' specified, otherwise will calculate DVR for all ROIs with DVR_ref_all_Logan() +#' +#' For other model paramters, directly call DVR_ref_Logan(). +#' +#'@export +#'@param tac The time-activity curve data from load_tac() or tac_roi() +#'@param model Only model currently available is "logan" +#'@param target Optional - otherwise will calculate DVR for all regions +#'@param ref Required -- The reference region, e.g. "cerebellum" +#'@param k2prime Required -- A fixed value for k2' must be specified (e.g. 0.2) +#'@param t_star Required -- If 0, t* will be calculated using find_t_star() +#'@param error For find_t_star() +#'@param method Method of integration, "trapz" or "integrate" +#'@return Data frame with calculated DVRs +#'@family Logan plot functions +#'@references Logan, J., Fowler, J. S., Volkow, N. D., Wang, G.-J., +#' Ding, Y.-S., & Alexoff, D. L. (1996). Distribution Volume Ratios without +#' Blood Sampling from Graphical Analysis of PET Data. Journal of Cerebral +#' Blood Flow & Metabolism, 16(5), 834-840. +#' https://doi.org/10.1097/00004647-199609000-00008 +#'@examples +#' f <- system.file("extdata", "AD06.tac", package="tacmagic") +#' fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") +#' AD06_tac <- load_tac(f, format="PMOD") +#' AD06_volume <- load_vol(fv, format="voistat") +#' AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), +#' merge=FALSE, PVC=FALSE) +#' +#' AD06_DVRs <- dvr(AD06, ref="cerebellum", k2prime=0.2, t_star=23) +#' +#' AD06_DVR <- dvr(AD06, target="frontal", ref="cerebellum", +#' k2prime=0.2, t_star=23) +dvr <- function(tac, model="logan", target=NULL, ref, k2prime, t_star, + error=0.10, method="trapz") { + + if (model != "logan") stop("Only the Logan reference model is available") + + if (is.null(target)) { + dvrs <- DVR_all_ref_Logan(tac_data=tac, ref=ref, k2prime=k2prime, + t_star=t_star, error=error, method=method) + } else { + ref_logan <- DVR_ref_Logan(tac_data=tac, target=target, ref=ref, + k2prime=k2prime, t_star=t_star, error=error, + method=method) + dvrs <- ref_logan$DVR + } + return(dvrs) +} diff --git a/R/loading.R b/R/loading.R index c2153c8..1f856e3 100644 --- a/R/loading.R +++ b/R/loading.R @@ -24,7 +24,7 @@ #' \item "voistat": PMOD TAC .voistat files used in combination with PMOD #' .acqtimes file for start/stop times. #' \item "magia": magia pipeline .mat tac file -#' \item "DFF": Turku PET Centre's DFT format +#' \item "DFT": Turku PET Centre's DFT format #' } #' #'@export @@ -36,7 +36,7 @@ #' "minutes" if not in file or to override file #'@param activity_unit NULL if in file (e.g. PMOD .tac), or set to "kBq/cc", #' "Bq/cc", "nCi/cc" -#'@return data.frame with loaded TAC data +#'@return tac object #'@family Loading functions #'@examples #' f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") @@ -47,13 +47,23 @@ load_tac <- function(filename, format="PMOD", acqtimes=NULL, time_unit=NULL, if (format == "PMOD") { - if (!(is.null(time_unit) & is.null(activity_unit))) { - warning("Your specified units will override any data in the files.") + if (tools::file_ext(filename) != "tac") { + warning("PMOD format was specified, + but filename did not end in .tac") } + + if (!(is.null(time_unit) & is.null(activity_unit))) { + warning("Your specified units will override any data in the files.") + } - tac <- load_tac_PMOD(filename) + tac <- load_tac_PMOD(filename) + + } else if (format == "voistat") { - } else if (format == "voistat") { + if (tools::file_ext(filename) != "voistat") { + warning("PMOD voistat format was specified, + but filename did not end in .voistat") + } if (!(is.null(time_unit) & is.null(activity_unit))) { warning("Your specified units will override any data in the files.") @@ -67,17 +77,27 @@ load_tac <- function(filename, format="PMOD", acqtimes=NULL, time_unit=NULL, stop("You must specify both time and activity units.") } + if (tools::file_ext(filename) != "mat") { + warning("magia format was specified, but filename did not end in .mat") + } + tac <- load_tac_magia(filename) } else if (format == "DFT") { + if (tools::file_ext(filename) != "dft") { + warning("DFT format was specified, + but filename did not end in .dft") + } + tac <- load_tac_DFT(filename) } else stop("Specified format for tac not supported.") - attributes(tac)$tm_type <- "tac" + class(tac) <- c("tac", "data.frame") if (!is.null(time_unit)) attributes(tac)$time_unit <- time_unit if (!is.null(activity_unit)) attributes(tac)$activity_unit <- activity_unit + if (!(validate_tac(tac))) stop("TAC object created by load_tac was invalid.") return(tac) } @@ -100,10 +120,18 @@ load_tac <- function(filename, format="PMOD", acqtimes=NULL, time_unit=NULL, #'@family Loading functions load_vol <- function(filename, format="voistat") { if (format == "voistat") { - volumes <- volumesFromVoistatTAC(filename) + if (tools::file_ext(filename) != "voistat") { + warning("voistat format was specified, + but filename did not end in .voistat") + } + volumes <- load_vol_vstac(filename) } else if (format == "BPndPaste") { - volumes <- volumesFromBPndPaste(filename) + volumes <- load_vol_bpndpaste(filename) } else if (format == "DFT") { + if (tools::file_ext(filename) != "dft") { + warning("DFT format was specified, + but filename did not end in .dft") + } volumes <- load_vol_DFT(filename) } else stop("Specified format for volume data not supported.") @@ -133,6 +161,11 @@ load_vol <- function(filename, format="voistat") { #' vs <- load_voistat(f, ROI_def=roi_ham_pib(), model="Logan") load_voistat <- function(filename, ROI_def=NULL, model="VALUE") { + + if (tools::file_ext(filename) != "voistat") { + warning(".voistat filename extension was expected.") + } + voistat <- read.csv(filename, sep="\t", skip=6, header=TRUE, stringsAsFactors=FALSE) diff --git a/R/loading_utilities.R b/R/loading_utilities.R index 1e1b552..339cf45 100644 --- a/R/loading_utilities.R +++ b/R/loading_utilities.R @@ -5,15 +5,17 @@ ## Beta version--check all work ## ################################## - - # General tac file validation #' @noRd validate_tac <- function(tac) { - # are first 2 variables "start" and "end" + + if(!is.tac(tac)) { + stop("An object of class c(\"tac\", \"data.frame\") was not provided.") + } status <- TRUE + # are first 2 variables "start" and "end" if (FALSE == (startsWith(names(tac)[1], "start") && startsWith(names(tac)[2], "end"))) { message("The first two columns of the TAC file should be start and end @@ -21,12 +23,11 @@ validate_tac <- function(tac) { status <- FALSE } - # Are the correct attributes set - if (!(attributes(tac)$tm_type == "tac")) { - message("TAC data should have attribute tm_type=tac") - status <- FALSE + if (!all(apply(as.data.frame(tac), 2, is.numeric))) { + message("All tac columns should be numeric. Check input data.") } + # Are the correct attributes set if (!(attributes(tac)$time_unit %in% c("seconds", "minutes"))) { message("TAC data missing attribute time_unit") status <- FALSE @@ -48,7 +49,7 @@ validate_tac <- function(tac) { #' @noRd load_tac_PMOD <- function(tac_file) { - tac <- read.csv(tac_file, sep="") + tac <- read.csv(tac_file, sep="", comment.char="#") if (names(tac)[1] == "start.seconds.") { attributes(tac)$time_unit <- "seconds" @@ -75,7 +76,7 @@ load_tac_voistat <- function(voistat_file, acqtimes) { voistat <- read.csv(voistat_file, sep="\t", skip=6, header=TRUE, stringsAsFactors=FALSE) - voistat_type <- validateTACvoistat(voistat) + voistat_type <- validate_tac_vs(voistat) if (voistat_type == "invalid") stop("Invalid voistat TAC file.") @@ -103,7 +104,7 @@ load_tac_voistat <- function(voistat_file, acqtimes) { } startend <- load_acq(acqtimes) - if (checkACQtimes(startend$start, startend$end, tac$time)) { + if (check_times(startend$start, startend$end, tac$time)) { tac <- data.frame(startend, tac) } else stop("Supplied acqtimes do not match midframe time data.") @@ -130,7 +131,7 @@ load_acq <- function(acqtimes_file) { # TAC .voistat files contain volume information for each ROI. This extracts it #' @noRd -volumesFromVoistatTAC <- function(voistat_file) { +load_vol_vstac <- function(voistat_file) { voistat <- read.csv(voistat_file, sep="\t", skip=6, header=TRUE, stringsAsFactors=FALSE) # create a list of each unique ROI name @@ -146,7 +147,8 @@ volumesFromVoistatTAC <- function(voistat_file) { # BPnd data can be copied from PNEURO and saved as a CSV. It contains ROI # volume information. This extracts that. Not needed unless volume information # is otherwise unavailable. -volumesFromBPndPaste <- function(BPnd_file) { +#' @noRd +load_vol_bpndpaste <- function(BPnd_file) { BPnd <- read.csv(BPnd_file, header=TRUE, row.names=1) return(BPnd["Volume..ccm."]) } @@ -157,7 +159,7 @@ volumesFromBPndPaste <- function(BPnd_file) { # Ensures consistency between start/end and mid-frame times. #' @noRd -checkACQtimes <- function(start, end, mid) { +check_times <- function(start, end, mid) { return(all(mid == ((start + end) / 2))) } @@ -165,7 +167,7 @@ checkACQtimes <- function(start, end, mid) { # and returns C if there is a PVC value, NC if not, and invalid if headers # are not as expected. #' @noRd -validateTACvoistat <- function(voistat) { +validate_tac_vs <- function(voistat) { PVC <- c("X...Component..string.", "File..string.", "PatientName..string.", "PatientID..string.", "PatientInfo..string.", @@ -186,7 +188,7 @@ validateTACvoistat <- function(voistat) { #### Magia file types --------------------------------------------------------- # Loads tac data from a .mat file, the output of the magia pipelines -# magia information is found at references()$magia +# magia information is found at http://aivo.utu.fi/magia/ #' @noRd load_tac_magia <- function(filename) { matlab <- R.matlab::readMat(filename) @@ -199,8 +201,6 @@ load_tac_magia <- function(filename) { } - - #### Turku PET Centre DFT file type # File type specifications: @@ -212,10 +212,13 @@ load_tac_DFT <- function(f) { header <- load_header_DFT(f) ROIs <- load_ROIs_DFT(header) - if (header[3,1] == "kBq/ml") { + if (header[3,1] %in% c("kBq/ml", "kBq/mL", "kBq/cc")) { activity_unit <- "kBq/cc" + } else if (header[3,1] %in% c("Bq/ml", "Bq/mL", "Bq/cc")) { + activity_unit <- "Bq/cc" } else { - stop(paste("Was expecting activity units kBq/ml but got", header[3,1])) + stop(paste("Was expecting activity units kBq or Bq / ml or cc but got", + header[3,1])) } if (header[4,2] %in% c("(min)")) { @@ -248,7 +251,7 @@ load_header_DFT <- function(f) { header <- read.delim(f, nrows=4, header=FALSE, sep="", stringsAsFactors=FALSE) - if (header[1,1] != "DFT") stop("Bad DFT file: no \"DFT\" string") + if (!startsWith(header[1,1], "DFT")) stop("Bad DFT file: no \"DFT\" string") # This is expected format when there are start and stop times if (header[4,1] != "Times") stop("Bad DFT file: expected \"Times\" at 4,1") @@ -277,17 +280,3 @@ load_ROIs_DFT <- function(header) { return(paste(vars, secvars, sep="_")) } - - -# Used by the plot, or any function that needs 2 tacs, to ensure their overall -# form and attributes are equal (except the ROIs) -compare_tac_form <- function(tac, tac2) { - if (!all.equal(tac$start, tac2$start)) stop("tac start times not equal") - if (!all.equal(tac$end, tac2$end)) stop("tac end times not equal") - a1 <- attributes(tac) - a2 <- attributes(tac2) - if (!all.equal(a1$time_unit, a2$time_unit)) stop("tac time units not equal") - if (!all.equal(a1$activity_unit, a2$activity_unit)) stop("tac start times - not equal") - return(TRUE) -} diff --git a/R/logan.R b/R/logan.R index 0dfaa0d..77c8e80 100644 --- a/R/logan.R +++ b/R/logan.R @@ -5,9 +5,6 @@ ## Beta version--check all work ## ################################## - -# See references()$Logan_1996 - # On testing, produces results equivalent to using Turku PET Centre's # logan 0.6.17 with the settings -C -mid=y (traditional regression model and # mid-frame times) @@ -24,9 +21,14 @@ #'@param k2prime A fixed value for k2' must be specified (e.g. 0.2) #'@param t_star If 0, t* will be calculated using find_t_star() #'@param error For find_t_star() -#'@param method Method of inntegration, "trapz" or "integrate" +#'@param method Method of integration, "trapz" or "integrate" #'@return Data frame with calculate DVRs for all ROIs #'@family Logan plot functions +#'@references Logan, J., Fowler, J. S., Volkow, N. D., Wang, G.-J., +#' Ding, Y.-S., & Alexoff, D. L. (1996). Distribution Volume Ratios without +#' Blood Sampling from Graphical Analysis of PET Data. Journal of Cerebral +#' Blood Flow & Metabolism, 16(5), 834-840. +#' https://doi.org/10.1097/00004647-199609000-00008 #'@examples #' f <- system.file("extdata", "AD06.tac", package="tacmagic") #' fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") @@ -40,11 +42,18 @@ #' DVR_ref_Logan <- function(tac_data, target, ref, k2prime, t_star, error=0.10, method="trapz") { - model <- ref_Logan_lm(tac_data=tac_data, target=target, ref=ref, - k2prime=k2prime, t_star=t_star, error=error, - method=method) - DVR <- model$coefficients[[2]] - return(DVR) + logan_model <- ref_Logan_lm(tac_data=tac_data, target=target, ref=ref, + k2prime=k2prime, t_star=t_star, error=error, + method=method) + tac <- as.data.frame(tac_data)[,c("start", "end", target, ref)] + attributes(tac) <- copy_tac_attributes(tac_data, tac) + out <- list(DVR=logan_model$model$coefficients[[2]], + model=logan_model$model, + xy=logan_model$xy, + t_star=logan_model$t_star, + tac=tac) + class(out) <- "ref_Logan" + return(out) } @@ -59,11 +68,15 @@ DVR_ref_Logan <- function(tac_data, target, ref, k2prime, t_star, error=0.10, #'@param k2prime Required -- A fixed value for k2' must be specified (e.g. 0.2) #'@param t_star Required -- If 0, t* will be calculated using find_t_star() #'@param error For find_t_star() -#'@param method Method of inntegration, "trapz" or "integrate" -#'@param params Used by batch_tm (not for calling individually) to pass model -#' parameters -#'@return Data frame with calculate DVRs for all ROIs +#'@param method Method of integration, "trapz" or "integrate" +#'@param ... When called from tm_batch, unused parameters may be supplied +#'@return Data frame with calculated DVRs for all ROIs #'@family Logan plot functions +#'@references Logan, J., Fowler, J. S., Volkow, N. D., Wang, G.-J., +#' Ding, Y.-S., & Alexoff, D. L. (1996). Distribution Volume Ratios without +#' Blood Sampling from Graphical Analysis of PET Data. Journal of Cerebral +#' Blood Flow & Metabolism, 16(5), 834-840. +#' https://doi.org/10.1097/00004647-199609000-00008 #'@examples #' f <- system.file("extdata", "AD06.tac", package="tacmagic") #' fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") @@ -74,23 +87,10 @@ DVR_ref_Logan <- function(tac_data, target, ref, k2prime, t_star, error=0.10, #' #' AD06_DVR <- DVR_all_ref_Logan(AD06, ref="cerebellum", k2prime=0.2, t_star=23) #' -DVR_all_ref_Logan <- function(tac_data, - ref=NULL, k2prime=NULL, t_star=NULL, - error=0.10, method="trapz", params=NULL) { - - if (!is.null(params)) { - if(!is.null(c(ref, k2prime, t_star))) { - stop("Provide EITHER params or ALL of ref, k2prime and t_star") - } - if (any(is.null(params$ref), is.null(params$k2prime), - is.null(params$t_star))) { - stop("Provide ALL of ref, k2prime and t_star") - } - ref <- params$ref - k2prime <- params$k2prime - t_star <- params$t_star - } - +DVR_all_ref_Logan <- function(tac_data, ref, k2prime, t_star, + error=0.10, method="trapz", ...) { + + validate_ref_Logan_params(tac_data, ref, k2prime, t_star, error, method) DVRtable <- new_table(tac_data, "DVR") ROIs <- names(tac_data)[3:length(names(tac_data))] @@ -104,7 +104,7 @@ DVR_all_ref_Logan <- function(tac_data, error=error, method=method)) if (class(attempt) == "try-error") { attempt <- NA - } + } else attempt <- attempt$DVR } DVRtable[ROI, "DVR"] <- attempt @@ -112,149 +112,3 @@ DVR_all_ref_Logan <- function(tac_data, return(DVRtable) } - - -#' Non-invasive reference Logan plot -#' -#' This plots the non-invasive Logan plot. -#' -#'@export -#'@param tac_data The time-activity curve data from tac_roi() -#'@param target The name of the receptor-rich region, e.g. "frontal" -#'@param ref The reference region, e.g. "cerebellum" -#'@param k2prime A fixed value for k2' must be specified (e.g. 0.2) -#'@param t_star If 0, t* will be calculated using find_t_star() -#'@param error For find_t_star() -#'@param method Method of inntegration, "trapz" or "integrate" -#'@family Logan plot functions -#'@return No return -#' f <- system.file("extdata", "AD06.tac", package="tacmagic") -#' fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") -#' AD06_tac <- load_tac(f, format="PMOD") -#' AD06_volume <- load_vol(fv, format="voistat") -#' AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), -#' merge=FALSE, PVC=FALSE) -#' -#' plot_ref_Logan(AD06, target="frontal", ref="cerebellum", -#' k2prime=0.2, t_star=0) -#' -plot_ref_Logan <- function(tac_data, target, ref, k2prime, t_star=0, error=0.1, - method="trapz") { - model <- ref_Logan_lm(tac_data=tac_data, target=target, ref=ref, - k2prime=k2prime, t_star=t_star, error=error, - method=method) - xy <- ref_Logan_xy(tac=tac_data, target=target, ref=ref, - k2prime=k2prime, method=method) - x <- xy$x - y <- xy$y - if (t_star == 0) t_star <- find_t_star(x, y, error=error) - - par(mfrow=c(1,2)) - - plot_tac(tac_data, ROIs=c(target,ref)) - - plot(y~x, main="Logan plot") - abline(model) - abline(v=x[t_star]) -} - - -## Helper functions------------------------------------------------------------ - -# The non-invasive reference Logan method -#' @noRd -ref_Logan_xy <- function(tac, target, ref, k2prime, method) { - - if (!(validate_tac(tac))) stop("Invalid tac object provided.") - - mid_time <- (tac$start + tac$end) / 2 - if (attributes(tac)$time_unit == "seconds") { - mid_time <- mid_time / 60 # needed because k2' is units 1/min (not seconds) - } - - # Derive functions for TACs by interpolation. - target_tac <- approxfun(x=mid_time, y=tac[,target], method="linear", rule=2) - ref_tac <- approxfun(x=mid_time, y=tac[,ref], method = "linear", rule=2) - - if (!is.null(k2prime)) k2r <- (tac[,ref] / k2prime) else k2r <- 0 - - if (method == "trapz") { - frames <- seq_along(mid_time) - yA <- vapply(frames, FUN=vAUC, FUN.VALUE=0, x=mid_time, y=tac[,target]) - xA <- vapply(frames, FUN=vAUC, FUN.VALUE=0, x=mid_time, y=tac[,ref]) + k2r - } else if (method == "integrate") { - yA <- vapply(mid_time, FUN=vintegrate, FUN.VALUE=0, lower=mid_time[1], - f=target_tac) - xA <- vapply(mid_time, FUN=vintegrate, FUN.VALUE=0, lower=mid_time[1], - f=ref_tac) + k2r - } - - y <- yA / tac[,target] - x <- xA / tac[,target] - - output <- data.frame(x,y) - - return(output) -} - - -# The non-invasive reference Logan method -- linear model starting from t* -#' @noRd -ref_Logan_lm <- function(tac_data, target, ref, k2prime, t_star, error, - method) { - - xy <- ref_Logan_xy(tac_data, target=target, ref=ref, k2prime=k2prime, - method=method) - - x <- xy$x - y <- xy$y - - if (t_star == 0) { - t_star <- find_t_star(x, y, error=error) - message(paste("t* is", t_star)) - } - - model <- lm(y[t_star:length(y)] ~ x[t_star:length(x)]) - return(model) -} - - -# The Logan graphical analysis method finds the slope after a point t*; this -# function calculates t* as the earliest time in which all residuals are less -# than the specified proportion (default 0.1 or 10%) of the actual value. -#' @noRd -find_t_star <- function(x, y, error=0.1) { - - frames <- length(y) - t_star <- 0 - - for (i in 1:(frames - 2)) { - linear_model <- lm(y[i:frames]~x[i:frames]) - if (all(abs(linear_model$residuals / y[i:frames]) < error )) { - t_star <- i - break - } - } - - if (t_star == 0) stop("No suitable t* found.") - - return(t_star) -} - - -# Helper function to use integrate() with vapply(), simply re-arranging the -# arguments of integrate() so that upper is the first argument, and returns -# just the integrate() value. -#' @noRd -vintegrate <- function(upper, lower, fn) { - v <- integrate(fn, lower=lower, upper=upper, stop.on.error=FALSE, - subdivisions=10000L) - return(v$value) -} - - -#' @noRd -vAUC <- function(frames,x,y) { - AUC <- pracma::trapz(x[1:frames], y[1:frames]) - return(AUC) -} diff --git a/R/logan_utilities.R b/R/logan_utilities.R new file mode 100644 index 0000000..1f95b8a --- /dev/null +++ b/R/logan_utilities.R @@ -0,0 +1,130 @@ +################################## +## tacmagic - PET Analysis in R ## +## logan_utilities.R ## +## (C) Eric E. Brown 2018 ## +## Beta version--check all work ## +################################## + +# The non-invasive reference Logan method +#' @noRd +ref_Logan_xy <- function(tac, target, ref, k2prime, method) { + + if (!(validate_tac(tac))) stop("Invalid tac object provided.") + + mid_time <- (tac$start + tac$end) / 2 + if (attributes(tac)$time_unit == "seconds") { + mid_time <- mid_time / 60 # needed because k2' is units 1/min (not seconds) + } + + # Derive functions for TACs by interpolation. + target_tac <- approxfun(x=mid_time, y=tac[,target], method="linear", rule=2) + ref_tac <- approxfun(x=mid_time, y=tac[,ref], method = "linear", rule=2) + + if (!is.null(k2prime)) k2r <- (tac[,ref] / k2prime) else k2r <- 0 + + if (method == "trapz") { + frames <- seq_along(mid_time) + yA <- vapply(frames, FUN=wrap_auc, FUN.VALUE=0, x=mid_time, y=tac[,target]) + xA <- vapply(frames, FUN=wrap_auc, FUN.VALUE=0, x=mid_time, y=tac[,ref]) + + k2r + } else if (method == "integrate") { + yA <- vapply(mid_time, FUN=wrap_integrate, FUN.VALUE=0, lower=mid_time[1], + f=target_tac) + xA <- vapply(mid_time, FUN=wrap_integrate, FUN.VALUE=0, lower=mid_time[1], + f=ref_tac) + k2r + } + + y <- yA / tac[,target] + x <- xA / tac[,target] + + output <- data.frame(x,y) + + return(output) +} + + +# The non-invasive reference Logan method -- linear model starting from t* +#' @noRd +ref_Logan_lm <- function(tac_data, target, ref, k2prime, t_star, error, + method) { + + xy <- ref_Logan_xy(tac_data, target=target, ref=ref, k2prime=k2prime, + method=method) + + x <- xy$x + y <- xy$y + + if (t_star == 0) { + t_star <- find_t_star(x, y, error=error) + message(paste("t* is", t_star)) + } + + model <- lm(y[t_star:length(y)] ~ x[t_star:length(x)]) + + ref_logan <- list(model=model, xy=xy, t_star=t_star) + + return(ref_logan) +} + + +# The Logan graphical analysis method finds the slope after a point t*; this +# function calculates t* as the earliest time in which all residuals are less +# than the specified proportion (default 0.1 or 10%) of the actual value. +#' @noRd +find_t_star <- function(x, y, error=0.1) { + + frames <- length(y) + t_star <- 0 + + for (i in 1:(frames - 2)) { + linear_model <- lm(y[i:frames]~x[i:frames]) + if (all(abs(linear_model$residuals / y[i:frames]) < error )) { + t_star <- i + break + } + } + + if (t_star == 0) stop("No suitable t* found.") + + return(t_star) +} + + +## Helper functions------------------------------------------------------------ + +# Helper function to use integrate() with vapply(), simply re-arranging the +# arguments of integrate() so that upper is the first argument, and returns +# just the integrate() value. +#' @noRd +wrap_integrate <- function(upper, lower, fn) { + v <- integrate(fn, lower=lower, upper=upper, stop.on.error=FALSE, + subdivisions=10000L) + return(v$value) +} + +#' @noRd +wrap_auc <- function(frames,x,y) { + AUC <- pracma::trapz(x[1:frames], y[1:frames]) + return(AUC) +} + +## Utilities ------------------------------------------------------------------ + +#'@noRd +is.ref_logan <- function(x) { + return (class(x) == "ref_Logan") +} + +#'@noRd +validate_ref_Logan_params <- function(tac_data, ref, k2prime, t_star, + error=0.10, method="trapz") { + if (!is.tac(tac_data)) stop("tac_data is not a tac object.") + if (!(ref %in% names(tac_data))) stop("ref is not in tac_data") + if (!(is.numeric(k2prime) | is.null(k2prime))) stop("k2prime not NULL or + numeric") + if (!is.numeric(t_star)) stop("t_star is not numeric") + if (t_star %% 1 != 0) stop("t_star is not an integer") + if (t_star > length(tac_data[,1])) stop("t_star is greater than frames") + if (error > 1 | error < 0) stop("error must be between 0 and 1") + if (!(method %in% c("trapz", "integrate"))) stop("invalid method name") +} diff --git a/R/plot.R b/R/plot.R new file mode 100644 index 0000000..32d3b39 --- /dev/null +++ b/R/plot.R @@ -0,0 +1,146 @@ +################################## +## tacmagic - PET Analysis in R ## +## plot.R ## +## (C) Eric E. Brown 2018 ## +## Beta version--check all work ## +################################## + +#' Plots time activity curves from 1 or 2 participants or groups. +#' +#'@export +#'@param x A tac object containing time-activity curves to plot, e.g. from +#' tac_roi() or load_tac() +#'@param tac2 An optional, second TAC, to plot for comparison +#'@param ROIs A vector of ROIs to plot, names matching the TAC headers +#'@param ymax The maximum value on the y-axis +#'@param time "seconds" or "minutes" depending on desired x-axis, converts tac +#'@param title A title for the plot +#'@param colors If null, rainbow palette is used, otherwise another palette can +#' be specified (heat.colors, terrain.colors, topo.colors, cm.colors +#'@param ... Additional arguments +#'@return Creates a plot +#'@family tac functions +#'@examples +#' # f_raw_tac and f_raw_vol are the filenames of PMOD-generated files +#' f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") +#' f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") +#' +#' tac <- load_tac(f_raw_tac) +#' vol <- load_vol(f_raw_vol) +#' AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=FALSE, PVC=FALSE) +#' plot(AD06_tac_nc, ROIs=c("frontal", "cerebellum"), title="Example Plot") +plot.tac <- function(x, tac2=NULL, ROIs, ymax=25, + time="minutes", title="", colors=rainbow, ...) { + tac1 <- x + + if (!all(ROIs %in% names(tac1))) stop("ROIs are not in TACtable1") + if (!validate_tac(tac1)) stop("The 1st tac object did not validate.") + if (!is.null(tac2)) { + if (!validate_tac(tac2)) stop("The 2nd tac object did not validate.") + compare_tac_form(tac1, tac2) + if (!all(ROIs %in% names(tac2))) stop("ROIs are not in tac2") + col <- colors(length(ROIs) * 2) + } else { + col <- colors(length(ROIs)) + } + + if (!(time %in% c("seconds", "minutes"))) stop("Time must be \"seconds\" or + \"minutes\"") + + if (time == "minutes") { + if (attributes(tac1)$time_unit == "minutes") time_conversion <- 1 + if (attributes(tac1)$time_unit == "seconds") time_conversion <- 60 + } + + if (time == "seconds") { + if (attributes(tac1)$time_unit == "seconds") time_conversion <- 1 + if (attributes(tac1)$time_unit == "minutes") time_conversion <- 1/60 + } + + plot(1,type='n', + xlim=c(tac1$start[1], + tac1$start[length(tac1$start)]/time_conversion), + ylim=c(0,ymax), + xlab=paste0("Time (", time, ")"), + ylab=paste0("Activity (", + attributes(tac1)$activity_unit, ")"), + main=title) + + # Plots the ROIs as specified in the ROIs argument + for (ROI in seq_along(ROIs)) { + + lines(x=tac1$start/time_conversion, + y=tac1[,ROIs[ROI]], + type='o', + col=col[ROI], + lwd=2) + + if (is.tac(tac2)) { + lines(x=tac2$start/time_conversion, + y=tac2[,ROIs[ROI]], + type='o', + col=col[ROI + length(ROIs)], + lwd=2) + } + } + + legend("topright", legend=ROIs, col=col[seq_along(ROIs)], pch=1) + if (is.tac(tac2)) { + legend("bottomright", legend=ROIs, + col=col[(length(ROIs)+1):(2*length(ROIs))], pch=1) + } +} + + +#' Non-invasive reference Logan plot +#' +#' This plots the non-invasive Logan plot. +#' +#'@export +#'@param x Reference Logan model data object from DVR_ref_Logan() +#'@param ... Additional parameters than can be passed to plotting function +#'@family Logan plot functions +#'@return No return +#' f <- system.file("extdata", "AD06.tac", package="tacmagic") +#' fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") +#' AD06_tac <- load_tac(f, format="PMOD") +#' AD06_volume <- load_vol(fv, format="voistat") +#' AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), +#' merge=FALSE, PVC=FALSE) +#' AD06_DVR_fr <- DVR_ref_Logan(AD06, target="frontal", ref="cerebellum", +#' k2prime=0.2, t_star=0) +#' plot(AD06_DVR_fr) +plot.ref_Logan <- function(x, ...) { + if (!is.ref_logan(x)) stop("x must be object from DVR_ref_Logan()") + + ref_logan <- x + model <- ref_logan$model + xy <- ref_logan$xy + x <- xy$x + y <- xy$y + + par(mfrow=c(1,2)) + + plot(ref_logan$tac, ROIs=names(ref_logan$tac)[-c(1,2)], + title="Time-activity curves", ...) + + plot(y~x, main="Logan plot") + abline(model) + abline(v=x[ref_logan$t_star]) +} + + +# Utility functions ----------------------------------------------------------- + +# Used by the plot, or any function that needs 2 tacs, to ensure their overall +# form and attributes are equal (except the ROIs) +compare_tac_form <- function(tac, tac2) { + if (!identical(tac$start, tac2$start)) stop("tac start times not equal") + if (!identical(tac$end, tac2$end)) stop("tac end times not equal") + a1 <- attributes(tac) + a2 <- attributes(tac2) + if (!identical(a1$time_unit, a2$time_unit)) stop("tac time units not equal") + if (!identical(a1$activity_unit, a2$activity_unit)) stop( + "activity units not equal") + return(TRUE) +} diff --git a/R/references.R b/R/references.R deleted file mode 100644 index abd4435..0000000 --- a/R/references.R +++ /dev/null @@ -1,46 +0,0 @@ -################################## -## tacmagic - PET Analysis in R ## -## references.R ## -## (C) Eric E. Brown 2018 ## -## Beta version--check all work ## -################################## - -#' Print and return a list of references for this package. -#' -#'@export -#'@return List of references. -#'@examples -#' references() -references <- function() { - - ref_list <- list( - - Aizenstein_2008= - "# Aizenstein HJ, Nebes RD, Saxton JA, et al. 2008. Frequent amyloid - deposition without significant cognitive impairment among the elderly. - Arch Neurol 65: 1509-1517.", - - Hammers_2003= - "Hammers, Alexander, Richard Allom, Matthias J. Koepp, Samantha L. Free, - Ralph Myers, Louis Lemieux, Tejal N. Mitchell, David J. Brooks, and John S. - Duncan. 2003. Three-dimensional Maximum Probability Atlas of the Human - Brain, with Particular Reference to the Temporal Lobe. Human Brain Mapping - 19 (4): 224-247. doi:10.1002/hbm.10123", - - Klunk_2015="Klunk W.E., Koeppe R.A., Price J.C., Benzinger T.L., - Devous M.D., Sr., Jagust W.J., Johnson K.A., Mathis C.A., Minhas D., - Pontecorvo M.J., Rowe C.C., Skovronsky D.M., Mintun M.A. The Centiloid - Project: standardizing quantitative amyloid plaque estimation by PET. - Alzheimers Dement. 2015;11", - - Logan_1996="Logan, J., Fowler, J. S., Volkow, N. D., Wang, G.-J., - Ding, Y.-S., & Alexoff, D. L. (1996). Distribution Volume Ratios without - Blood Sampling from Graphical Analysis of PET Data. Journal of Cerebral - Blood Flow & Metabolism, 16(5), 834-840. - https://doi.org/10.1097/00004647-199609000-00008", - - magia="http://aivo.utu.fi/magia/" - ) - - return(ref_list) -} diff --git a/R/saving.R b/R/saving.R index c4a0976..618e197 100644 --- a/R/saving.R +++ b/R/saving.R @@ -5,7 +5,6 @@ ## Beta version--check all work ## ################################## - #' Save a tac object as a .tac file #' #' Saves a tac object, created by load_tac(), tac_roi() or manually, and @@ -29,7 +28,7 @@ save_tac <- function(tac, outfile) { names(tac)[1] <- paste0("start[", attributes(tac)$time_unit, "]") names(tac)[2] <- paste0("end[", attributes(tac)$activity_unit, "]") - write.table(tac, file = outfile, append = FALSE, quote = TRUE, sep = "\t", + write.table(tac, file = outfile, append = FALSE, quote = FALSE, sep = "\t", eol = "\n", na = "NaN", dec = ".", row.names = FALSE, col.names = TRUE, qmethod = c("escape", "double"), fileEncoding = "") diff --git a/R/tac.R b/R/tac.R index ab6a1c4..5da513c 100644 --- a/R/tac.R +++ b/R/tac.R @@ -47,14 +47,12 @@ tac_roi <- function(tac, volumes, ROI_def, merge, PVC) { } if (merge) { - calculated_TACs <- data.frame(tac, calculated_TACs) + calculated_TACs <- data.frame(as.data.frame(tac), calculated_TACs) } else { - calculated_TACs <- data.frame(tac[1:2], calculated_TACs) + calculated_TACs <- data.frame(as.data.frame(tac)[1:2], calculated_TACs) } - attributes(calculated_TACs)$time_unit <- attributes(tac)$time_unit - attributes(calculated_TACs)$activity_unit <- attributes(tac)$activity_unit - attributes(calculated_TACs)$tm_type <- "tac" + attributes(calculated_TACs) <- copy_tac_attributes(tac, calculated_TACs) if(!validate_tac(calculated_TACs)) stop("Merged ROI tac file did not validate.") @@ -62,88 +60,36 @@ tac_roi <- function(tac, volumes, ROI_def, merge, PVC) { return(calculated_TACs) } -#' Plots time activity curves from 1 or 2 participants or groups. +#' Subset PMOD tacs with or without PVC +#' +#' When partial volume correction (PVC) is used in PMOD, the saved tac files +#' have ROIs with and without PVC. When loaded with load_tac()) it may be +#' desirable to keep only either the PVC or non-PVC tacs. This returns a tac +#' object that is a subset of the input tac object with only the PVC or non-PVC +#' tacs. This relies on PMOD's convention of labelling tac columns with "_C". #' #'@export -#'@param TACtable1 (e.g. from tac_roi() or load_tac()) -#'@param TACtable2 An optional, second TAC, to plot for comparison -#'@param ROIs A vector of ROIs to plot, names matching the TAC headers -#'@param ymax The maximum value on the y-axis -#'@param time "seconds" or "minutes" depending on desired x-axis, converts tac -#'@param title A title for the plot -#'@return Creates a plot +#'@param tac The time-activity curve data from loading function (PMOD) +#'@param PVC If TRUE, includes columns with "_C", if FALSE, ones without "_C" #'@family tac functions -#'@examples +#'@return Time-activity curve object +#'@examples #' # f_raw_tac and f_raw_vol are the filenames of PMOD-generated files #' f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") -#' f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") #' #' tac <- load_tac(f_raw_tac) -#' vol <- load_vol(f_raw_vol) -#' AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=FALSE, PVC=FALSE) -#' plot_tac(AD06_tac_nc, ROIs=c("frontal", "cerebellum"), title="Example Plot") -plot_tac <- function(TACtable1, TACtable2=NULL, ROIs, ymax=25, - time="minutes", title="") { - - if (!all(ROIs %in% names(TACtable1))) stop("ROIs are not in TACtable1") +#' tac_pvc <- split_pvc(tac, TRUE) +#' tac_nc <- split_pvc(tac, FALSE) +split_pvc <- function(tac, PVC=TRUE) { - if (!validate_tac(TACtable1)) stop("The 1st tac object did not validate.") - if (!is.null(TACtable2)) { - if (!validate_tac(TACtable2)) stop("The 2nd tac object did not validate.") - } - - if (!(time %in% c("seconds", "minutes"))) stop("Time must be \"seconds\" or - \"minutes\"") + validate_tac(tac) + class(tac) <- "data.frame" + subset <- cbind(tac[1:2], + tac[,3:length(tac)][endsWith(names(tac[,3:length(tac)]), + "_C") == PVC]) + attributes(subset) <- copy_tac_attributes(tac, subset) + validate_tac(subset) - if (time == "minutes") { - if (attributes(TACtable1)$time_unit == "minutes") time_conversion <- 1 - if (attributes(TACtable1)$time_unit == "seconds") time_conversion <- 60 - } + return(subset) - if (time == "seconds") { - if (attributes(TACtable1)$time_unit == "seconds") time_conversion <- 1 - if (attributes(TACtable1)$time_unit == "minutes") time_conversion <- 1/60 - } - - # Sets up the plot using the frame start from the TAC file for the x axis - # and converting to minutes if chosen. - - plot(1,type='n', - xlim=c(TACtable1$start[1], - TACtable1$start[length(TACtable1$start)]/time_conversion), - ylim=c(0,ymax), - xlab=paste0("Time (", time, ")"), - ylab=paste0("Activity (", - attributes(TACtable1)$activity_unit, ")"), - main=title) - - # Separate colour ranges for each group of TACs - colour1 <- rainbow(length(ROIs), start=0, end=0.25) - colour2 <- rainbow(length(ROIs), start=0.5, end=0.8) - - # Plots the ROIs as specified in the ROIs argument - for (ROI in seq_along(ROIs)) { - - lines(x=TACtable1$start/time_conversion, - y=TACtable1[,ROIs[ROI]], - type='o', - col=colour1[ROI], - lwd=2) - - # Only if 2nd TAC table is provided, plots second on same plot - if (is.data.frame(TACtable2)) { - if (!all(ROIs %in% names(TACtable2))) stop("ROIs are not in TACtable2") - compare_tac_form(TACtable1, TACtable2) - lines(x=TACtable2$start/time_conversion, - y=TACtable2[,ROIs[ROI]], - type='o', - col=colour2[ROI], - lwd=2) - } - } - - legend("topright", legend=ROIs, col=colour1, pch=1) - if (is.data.frame(TACtable2)) { - legend("bottomright", legend=ROIs, col=colour2, pch=1) - } -} +} diff --git a/R/tac_methods.R b/R/tac_methods.R new file mode 100644 index 0000000..cc287d5 --- /dev/null +++ b/R/tac_methods.R @@ -0,0 +1,80 @@ +################################## +## tacmagic - PET Analysis in R ## +## tac_methods.R ## +## (C) Eric E. Brown 2018 ## +## Beta version--check all work ## +################################## + +#'@export +#'@noRd +summary.tac <- function(object, ...) { + + if (!validate_tac(object)) { + stop("Invalid tac object.") + } + + else { + cat("tac object\n", + "Activity unit: ", attributes(object)$activity_unit, "\n", + "Time unit: ", attributes(object)$time_unit, "\n", + "Number of ROIs: ", length(names(object)) - 2, "\n", + "Number of frames: ", length(object$start), "\n", + "Time span: ", object$start[1], "-", + object$end[length(object$end)], + attributes(object)$time_unit, "\n", + "Unique frame durations: ", unique(object$end - object$start), + attributes(object)$time_unit, "\n" + ) + } +} + +#' Creates a tac object from a data.frame +#' +#' tac objects can be created from data.frame objects with `as.tac()`. The time +#' and activity units must be specified as arguments if not already set as +#' attributes in the data.frame. The columns of the data frame are the regional +#' time activity curves, with the column names the names of the ROIs. +#' +#' If the time_unit and activity_unit attributes are already in the data.frame, +#' they do not need to be set again, but otherwise they will need to be +#' specified in the input parameters. +#' +#'@export +#'@param x data.frame with start, end time and tac data +#'@param time_unit NULL if in data.frame or set to "seconds" or "minutes" +#'@param activity_unit NULL if in data.frame or set to "kBq/cc", "Bq/cc", +#' "nCi/cc" +#'@return tac object +#'@family Loading functions +#'@examples +#' manual <- data.frame(start=c(0:4), end=c(2:6), +#' ROI1=c(10.1:14.2), ROI2=c(11:15)) +#' manual_tac <- as.tac(manual, time_unit="minutes", activity_unit="kBq/cc") +as.tac <- function(x, time_unit=NULL, activity_unit=NULL) { + + if (!is.data.frame(x)) stop("Can only convert data.frames to tac object") + if (is.null(time_unit) == is.null(x$time_unit)) stop("Time unit must be + specified in exactly one of: supplied data.frame, or time_unit argument") + if (is.null(activity_unit) == is.null(x$activity_unit)) stop("Activity unit + must be in exactly one of: supplied data.frame or activity_unit argument") + + if (!is.null(time_unit)) attributes(x)$time_unit <- time_unit + if (!is.null(activity_unit)) attributes(x)$activity_unit <- activity_unit + class(x) <- c("tac", "data.frame") + + validate_tac(x) + + return(x) +} + +#'@export +#'@noRd +as.data.frame.tac <- function(x, ...) { + class(x) <- "data.frame" + return(x) +} + +#'@noRd +is.tac <- function(x) { + return (all(class(x) == c("tac", "data.frame"))) +} diff --git a/R/tacmagic.R b/R/tacmagic.R index d580bb0..5e95012 100644 --- a/R/tacmagic.R +++ b/R/tacmagic.R @@ -12,4 +12,5 @@ #' @importFrom utils head read.csv read.delim read.table write.csv write.table #' @importFrom grDevices rainbow #' @importFrom R.matlab readMat +#' @importFrom tools file_ext NULL diff --git a/R/utilities.R b/R/utilities.R index 7c1b12d..56be819 100644 --- a/R/utilities.R +++ b/R/utilities.R @@ -13,3 +13,13 @@ new_table <- function(tac, varname="VALUE") { names(VALUEtable) <- varname return(VALUEtable) } + +#' Copies the time and activity unit attributes from origin to destination; +#' and assigns tm_type as "tac" +#'@noRd +copy_tac_attributes <- function(origin, destination) { + attributes(destination)$time_unit <- attributes(origin)$time_unit + attributes(destination)$activity_unit <- attributes(origin)$activity_unit + attributes(destination)$class <- c("tac", "data.frame") + return(attributes(destination)) +} diff --git a/codemeta.json b/codemeta.json new file mode 100644 index 0000000..3e60c45 --- /dev/null +++ b/codemeta.json @@ -0,0 +1,153 @@ +{ + "@context": [ + "https://doi.org/10.5063/schema/codemeta-2.0", + "http://schema.org" + ], + "@type": "SoftwareSourceCode", + "identifier": "tacmagic", + "description": "To faciliate analysis of positron emission tomography (PET) time\n activity curve (TAC) data, and to encourage open science and replicability,\n this package supports data loading and analysis of multiple TAC file \n formats. Functions are available to analyze loaded tac data for individual \n participants or in batches. Major functionality includes weighted TAC \n merging by region of interest (ROI), calculating models including SUVR and\n DVR, basic plotting functions and calculation of cut-off values. Please see\n the walkthrough vignette for a detailed overview of tacmagic functions.", + "name": "tacmagic: tacmagic: PET Analysis in R", + "codeRepository": "https://github.com/eebrown/PET", + "issueTracker": "https://github.com/eebrown/PET/issues", + "license": "https://spdx.org/licenses/GPL-3.0", + "version": "0.2.0", + "programmingLanguage": { + "@type": "ComputerLanguage", + "name": "R", + "version": "3.5.0", + "url": "https://r-project.org" + }, + "runtimePlatform": "R version 3.5.0 (2018-04-23)", + "author": [ + { + "@type": "Person", + "givenName": "Eric", + "familyName": "Brown", + "email": "eb@ericebrown.com", + "@id": "https://orcid.org/0000-0002-1575-2606" + } + ], + "maintainer": [ + { + "@type": "Person", + "givenName": "Eric", + "familyName": "Brown", + "email": "eb@ericebrown.com", + "@id": "https://orcid.org/0000-0002-1575-2606" + } + ], + "softwareSuggestions": [ + { + "@type": "SoftwareApplication", + "identifier": "testthat", + "name": "testthat", + "provider": { + "@id": "https://cran.r-project.org", + "@type": "Organization", + "name": "Comprehensive R Archive Network (CRAN)", + "url": "https://cran.r-project.org" + }, + "sameAs": "https://CRAN.R-project.org/package=testthat" + }, + { + "@type": "SoftwareApplication", + "identifier": "knitr", + "name": "knitr", + "provider": { + "@id": "https://cran.r-project.org", + "@type": "Organization", + "name": "Comprehensive R Archive Network (CRAN)", + "url": "https://cran.r-project.org" + }, + "sameAs": "https://CRAN.R-project.org/package=knitr" + }, + { + "@type": "SoftwareApplication", + "identifier": "rmarkdown", + "name": "rmarkdown", + "provider": { + "@id": "https://cran.r-project.org", + "@type": "Organization", + "name": "Comprehensive R Archive Network (CRAN)", + "url": "https://cran.r-project.org" + }, + "sameAs": "https://CRAN.R-project.org/package=rmarkdown" + }, + { + "@type": "SoftwareApplication", + "identifier": "covr", + "name": "covr", + "provider": { + "@id": "https://cran.r-project.org", + "@type": "Organization", + "name": "Comprehensive R Archive Network (CRAN)", + "url": "https://cran.r-project.org" + }, + "sameAs": "https://CRAN.R-project.org/package=covr" + } + ], + "softwareRequirements": [ + { + "@type": "SoftwareApplication", + "identifier": "R", + "name": "R", + "version": ">= 3.4" + }, + { + "@type": "SoftwareApplication", + "identifier": "graphics", + "name": "graphics" + }, + { + "@type": "SoftwareApplication", + "identifier": "grDevices", + "name": "grDevices" + }, + { + "@type": "SoftwareApplication", + "identifier": "pracma", + "name": "pracma", + "provider": { + "@id": "https://cran.r-project.org", + "@type": "Organization", + "name": "Comprehensive R Archive Network (CRAN)", + "url": "https://cran.r-project.org" + }, + "sameAs": "https://CRAN.R-project.org/package=pracma" + }, + { + "@type": "SoftwareApplication", + "identifier": "utils", + "name": "utils" + }, + { + "@type": "SoftwareApplication", + "identifier": "R.matlab", + "name": "R.matlab", + "provider": { + "@id": "https://cran.r-project.org", + "@type": "Organization", + "name": "Comprehensive R Archive Network (CRAN)", + "url": "https://cran.r-project.org" + }, + "sameAs": "https://CRAN.R-project.org/package=R.matlab" + } + ], + "readme": "https://github.com/ropensci/tacmagic/blob/master/readme.md", + "contIntegration": [ + "https://travis-ci.org/ropensci/tacmagic", + "https://codecov.io/github/ropensci/tacmagic?branch=master" + ], + "keywords": [ + "positron-emission-tomography", + "pet", + "pet-mr", + "neuroimaging", + "r", + "statistics", + "positron", + "mri", + "neuroscience", + "neuroscience-methods" + ] +} diff --git a/doc/walkthrough.R b/doc/walkthrough.R index 48c8358..d566b0e 100644 --- a/doc/walkthrough.R +++ b/doc/walkthrough.R @@ -13,6 +13,9 @@ filename <- system.file("extdata", "AD06.tac", package="tacmagic") AD06_tac <- load_tac(filename, format="PMOD") +## ------------------------------------------------------------------------ +summary(AD06_tac) + AD06_tac[1:5,1:5] # the first 5 frames of the first 3 ROIs ## ------------------------------------------------------------------------ @@ -28,8 +31,15 @@ f_magia <- system.file("extdata", "AD06_tac_magia.mat", package="tacmagic") AD06_tac_magia <- load_tac(f_magia, format="magia", time_unit="seconds", activity_unit="kBq/cc") + AD06_tac_magia[1:5,1:5] +## ------------------------------------------------------------------------ +manual <- data.frame(start=c(0:4), end=c(2:6), ROI1=c(10.1:14.2), ROI2=c(11:15)) +manual_tac <- as.tac(manual, time_unit="minutes", activity_unit="kBq/cc") + +summary(manual_tac) + ## ------------------------------------------------------------------------ AD06_volume <- load_vol(filename_voistat, format="voistat") @@ -45,11 +55,11 @@ AD06 <- tac_roi(tac=AD06_tac, # The tac file we loaded above. AD06[1:5,1:5] ## ---- fig.show='hold', fig.height=4.5, fig.width=6.5, fig.align='center'---- -plot_tac(AD06, # tac data - ROIs=c("frontal", "temporal", "parietal", "cerebellum"), # ROIs to plot - time="minutes", # Convert x axis from seconds to minutes - title="PIB time activity curves for AD06" # A title for the plot - ) +plot(AD06, # tac data + ROIs=c("frontal", "temporal", "parietal", "cerebellum"), # ROIs to plot + time="minutes", # Convert x axis from seconds to minutes + title="PIB time activity curves for AD06" # A title for the plot + ) ## ------------------------------------------------------------------------ AD06_SUVR <- suvr(AD06, # tac data @@ -74,17 +84,11 @@ AD06_DVR_fr <- DVR_ref_Logan(AD06, t_star=0, # 0 to find, or can specify frame ) - -AD06_DVR_fr +AD06_DVR_fr$DVR ## ---- fig.show='hold', fig.height=4.5, fig.width=6.5, fig.align='center'---- -plot_ref_Logan(AD06, - target="frontal", - ref="cerebellum", - k2prime=0.2, - t_star=0, - ) +plot(AD06_DVR_fr) ## ------------------------------------------------------------------------ @@ -93,6 +97,29 @@ AD06_DVR <- DVR_all_ref_Logan(AD06, ref="cerebellum", k2prime=0.2, t_star=23) AD06_DVR +## ------------------------------------------------------------------------ +ADO6_frontal_DVR <- dvr(AD06, target="frontal", ref="cerebellum", k2prime=0.2, + t_star=23) + + +## ------------------------------------------------------------------------ + +participants <- c(system.file("extdata", "AD06.tac", package="tacmagic"), + system.file("extdata", "AD07.tac", package="tacmagic"), + system.file("extdata", "AD08.tac", package="tacmagic")) + +tacs <- batch_load(participants, dir="", tac_file_suffix="") + +# Since the PMOD tac files used here have 2 copies of ROIs, with and without +# PVC, we can use split_pvc to keep the PVC-corrected verions. If we had used +# roi_m here to combine ROIs, we could have specified to use the PVC versions +# in batch_load() with PVC = TRUE. +tacs <- lapply(tacs, split_pvc, PVC=TRUE) + +batch <- batch_tm(tacs, models=c("SUVR", "Logan"), ref="Cerebellum_r_C", + SUVR_def=c(3000,3300,3600), k2prime=0.2, t_star=23) + + ## ------------------------------------------------------------------------ fake_DVR[1:5,] diff --git a/doc/walkthrough.Rmd b/doc/walkthrough.Rmd index 574a399..00cd6ac 100644 --- a/doc/walkthrough.Rmd +++ b/doc/walkthrough.Rmd @@ -19,21 +19,29 @@ knitr::opts_chunk$set( ) ``` -There are two approaches to using the tacmagic package to analyze PET time-activity curve data: either by loading participant data individually and using the various functions to analyze it, or via the batch functions to list and analyze data from multiple participants. Here, we illustrate the main features of tacmagic, by walking through the analysis of a single participant. We provide an explanation of the batch mode at the end. - ## Background -[Positron emission tomography](https://en.wikipedia.org/wiki/Positron_emission_tomography) (PET) is a research and clinical imaging modality that uses radioactive tracers that bind to target molecules of interest. A PET scanner identifies the tracer location by virtue of the tracer's radioactive decay, providing information to determine the location of the target in the body. As the spatial resolution of PET is relatively poor, analysis is frequently combined with higher resolution imaging such as magnetic resonance imaging (MRI), which can be spatially co-registered to the PET image. Subsequently, radiotracer activity (over time) can be identified by spatial region of interest (ROI). The resulting analysis produces time-activity curves (**tac**) which can be further analyzed to answer important clinical and research questions (**magic**). +[Positron emission tomography](https://en.wikipedia.org/wiki/Positron_emission_tomography) (PET) is a research and clinical imaging modality that uses radioactive tracers that bind to target molecules of interest. A PET scanner identifies the tracer location by virtue of the tracer's radioactive decay, providing information to determine the location of the target in the body. As the spatial resolution of PET is relatively poor, analysis is frequently combined with higher resolution imaging such as magnetic resonance imaging (MRI), which can be spatially co-registered to the PET image. Subsequently, radiotracer activity (over time) can be identified by spatial region of interest (ROI). + +An image anaylsis pipeline is required to extract regional time activity curves (tacs) from a dynamic PET image. There are various pipelines available including widely-used commercial solutions (e.g. [PMOD](https://www.pmod.com/web/)) and newer open-source options (e.g. [magia](http://aivo.utu.fi/magia/)). Pipelines generally implement the following steps: + +* Dynamic PET pre-processing (e.g. motion correction, decay-correction) +* PET image co-registration with structural MRI +* MRI segmentation and normalization to atlas + +Various pipelines save tac, volume and related data in various formats. This package enables the loading and analysis of tac and ROI volume data from image analysis pipelines for further analysis in R. -The sample data for this analysis uses an anonymized scans of a participant with Alzheimer's dementia, data from http://www.gaain.org which was generously made available for unrestricted use.^[Klunk, William E., Robert A. Koeppe, Julie C. Price, Tammie L. Benzinger, Michael D. Devous, William J. Jagust, Keith A. Johnson, et al. “The Centiloid Project: Standardizing Quantitative Amyloid Plaque Estimation by PET.” Alzheimer’s & Dementia 11, no. 1 (January 2015): 1-15.e4. https://doi.org/10.1016/j.jalz.2014.07.003.] The radiotracer used is Pittsburgh Compound B (PIB) which binds to beta-amyloid, a protein found in high concentration in the brains of individuals with Alzheimer's dementia. +## Vignette data +The sample data for this vignette uses an anonymized scans of a participant with Alzheimer's dementia, data from http://www.gaain.org which was generously made available for unrestricted use.^[Klunk, William E., Robert A. Koeppe, Julie C. Price, Tammie L. Benzinger, Michael D. Devous, William J. Jagust, Keith A. Johnson, et al. “The Centiloid Project: Standardizing Quantitative Amyloid Plaque Estimation by PET.” Alzheimer’s & Dementia 11, no. 1 (January 2015): 1-15.e4. https://doi.org/10.1016/j.jalz.2014.07.003.] The radiotracer used is Pittsburgh Compound B (PIB) which binds to beta-amyloid, a protein found in high concentration in the brains of individuals with Alzheimer's dementia. +There are two approaches to using the **tacmagic** package to analyze PET time-activity curve data: either by loading participant data individually and using the various functions to analyze it, or via the batch functions to list and analyze data from multiple participants. Here, we illustrate the main features of tacmagic, by walking through the analysis of a single participant. We provide an explanation of the batch mode at the end. ## Time-activity curve operations ### Data loading -Time-activity curve (TAC) data is loaded via `load_tac()`, which is a wrapper for format-specific functions. To specify which file format the tac data is stored as, use the `format` parameter. Supported formats can be viewed in `help(load_tac())`. +Time-activity curve (TAC) data is loaded via `load_tac()`, which is a wrapper for format-specific functions. To specify which file format the tac data is stored as, use the `format` parameter. Supported formats can be viewed in `help(load_tac)`. The minimal amount of information required is the TAC data for one or more ROI, including the start and stop times of each frame, the time units and the activity units. This information may be in 1 or more files depending on the format and software that created it. @@ -48,6 +56,12 @@ filename <- system.file("extdata", "AD06.tac", package="tacmagic") # format that is not yet supported. AD06_tac <- load_tac(filename, format="PMOD") +``` + +A tac object is a data frame with extra attributes including time and activity units. A summary can be printed with the generic `print()` function. + +```{r} +summary(AD06_tac) AD06_tac[1:5,1:5] # the first 5 frames of the first 3 ROIs ``` @@ -63,17 +77,28 @@ tac2 <- load_tac(filename_voistat, format="voistat", acqtimes=filename_acq) all.equal(AD06_tac, tac2) ``` -We also used Turku's [magia](http://aivo.utu.fi/magia/) pipeline to process the same data. It can be loaded similarly, though with units explicitly entered because the information -is not encoded in the .mat file: +We also used Turku's [magia](http://aivo.utu.fi/magia/) pipeline to process the same data. It can be loaded similarly, though with units explicitly entered because the information is not encoded in the .mat file: ```{r} f_magia <- system.file("extdata", "AD06_tac_magia.mat", package="tacmagic") AD06_tac_magia <- load_tac(f_magia, format="magia", time_unit="seconds", activity_unit="kBq/cc") + AD06_tac_magia[1:5,1:5] ``` +#### Manually-created tac objects + +For other data sources, **tacmagic** tac objects can be created from data.frame objects with `as.tac()`. The time and activity units must be specified as arguments if not already set as attributes in the data.frame. The columns of the data.frame are the regional tacs, with the column names the names of the ROIs. + +```{r} +manual <- data.frame(start=c(0:4), end=c(2:6), ROI1=c(10.1:14.2), ROI2=c(11:15)) +manual_tac <- as.tac(manual, time_unit="minutes", activity_unit="kBq/cc") + +summary(manual_tac) +``` + ### ROI merging Often it is desirable to combine tac ROIs into larger ROIs. For example, if the PET analysis pipeline created tacs for each atlas ROI, your analysis may call for merging these atomic ROIs into larger regions, such as merging all of the atlas ROIs that make up the frontal lobe into a single frontal lobe ROI. @@ -101,18 +126,17 @@ AD06[1:5,1:5] ### Plotting -Basic tac plotting is done with `plot_tac`, which accepts tac data from 2 participants (or group means). The ROIs to plot are specified as a vector of ROI names as they appear in the tac object. As the tac object contains time unit information, the plot can conver to desired units, which can be specified with the `time` argument. +Basic tac plotting can be done by calling `plot`, which accepts two tac objects, e.g. from 2 participants or group means. The ROIs to plot are specified as a vector of ROI names as they appear in the tac object. As the tac object contains time unit information, the plot can convert to desired units, which can be specified with the `time` argument. ```{r, fig.show='hold', fig.height=4.5, fig.width=6.5, fig.align='center'} -plot_tac(AD06, # tac data - ROIs=c("frontal", "temporal", "parietal", "cerebellum"), # ROIs to plot - time="minutes", # Convert x axis from seconds to minutes - title="PIB time activity curves for AD06" # A title for the plot - ) +plot(AD06, # tac data + ROIs=c("frontal", "temporal", "parietal", "cerebellum"), # ROIs to plot + time="minutes", # Convert x axis from seconds to minutes + title="PIB time activity curves for AD06" # A title for the plot + ) ``` - ## Model calculation ### SUVR @@ -165,20 +189,14 @@ AD06_DVR_fr <- DVR_ref_Logan(AD06, t_star=0, # 0 to find, or can specify frame ) - -AD06_DVR_fr +AD06_DVR_fr$DVR ``` To visually confirm that the model behaved as expected with linearity, there is a plotting function: ```{r, fig.show='hold', fig.height=4.5, fig.width=6.5, fig.align='center'} -plot_ref_Logan(AD06, - target="frontal", - ref="cerebellum", - k2prime=0.2, - t_star=0, - ) +plot(AD06_DVR_fr) ``` @@ -195,6 +213,14 @@ AD06_DVR For this data, the DVR calculation has been shown to produce equivalent results as an existing tool.^[https://gitlab.utu.fi/vesoik/tpcclib] +A wrapper function `dvr()` is available to conveniently calculate DVR for a target ROI or all ROIs, and currently defaults to using the Logan reference method: + +```{r} +ADO6_frontal_DVR <- dvr(AD06, target="frontal", ref="cerebellum", k2prime=0.2, + t_star=23) + +``` + ## Batch analysis In most cases, a project will involve the analysis of multiple participants. The above workflow can be used to test and visualize an analysis, but a batch workflow will likely be preferred to analyze multiple participants. @@ -203,7 +229,7 @@ All analyses can be run using 2 steps: a batch data loading step and a batch ana ### Batch loading -Data loading is done by `batch_load()`. See `help(batch_load()` for the required arguements. +Data loading is done by `batch_load()`. See `help(batch_load)` for the required arguments. The first argument is a vector of participant IDs that corresponds to file names, e.g.: @@ -211,12 +237,37 @@ The first argument is a vector of participant IDs that corresponds to file names `my_data <- batch_load(participants, dir="/mypath/", tac_format="PMOD", roi_m=T, vol_file_suffix="_TAC.voistat", vol_format="voistat", ROI_def=roi_ham_stand(), merge=F)` -The above would load the appropriate tac and voistat files, perform the ROI merging specified by `ROI_def` because `roi_m=T`, and would return a list where each element represents a participants, e.g. the first participant would be `my_data$participant1`. +The above would load the appropriate tac and voistat files, perform the ROI merging specified by `ROI_def`, because `roi_m = TRUE`, and would return a list where each element represents a participants, e.g. the first participant would be `my_data$participant1`. ### Batch analysis Once the tac data is loaded, all analyses can be run using `batch_tm()`. The output from `batch_load()` is the first argument for `batch_tm()`. The models implemented in tacmagic can be specified using the `models` argument, e.g. `models = c("SUVR", "Logan")` to calculate both SUVR and Logan DVR. The relevant model parameters will also need to be specified, so see `help(batch_tm)` for all possible arguments. +### Batch example + +For the purpose of the vignette, the list of participants will be a list of the full tac filenames (hence tac_file_suffix=""). In real-world data, the participants parameter can be a list of participant IDs that correspond to the actual filenames, i.e. the filename is made up of dir + participant + tac_file_suffix. + +We will also choose not to use the roi_m option in batch_load(), which could be used to combine ROIs as outlined above. + +```{r} + +participants <- c(system.file("extdata", "AD06.tac", package="tacmagic"), + system.file("extdata", "AD07.tac", package="tacmagic"), + system.file("extdata", "AD08.tac", package="tacmagic")) + +tacs <- batch_load(participants, dir="", tac_file_suffix="") + +# Since the PMOD tac files used here have 2 copies of ROIs, with and without +# PVC, we can use split_pvc to keep the PVC-corrected verions. If we had used +# roi_m here to combine ROIs, we could have specified to use the PVC versions +# in batch_load() with PVC = TRUE. +tacs <- lapply(tacs, split_pvc, PVC=TRUE) + +batch <- batch_tm(tacs, models=c("SUVR", "Logan"), ref="Cerebellum_r_C", + SUVR_def=c(3000,3300,3600), k2prime=0.2, t_star=23) + +``` + ## Cut-off calculations In the analysis of PIB/amyloid PET data, often researchers want to dichotomize patients into PIB+ vs. PIB-, i.e. to identify those with significant AD-related amyloid pathology (PIB+). diff --git a/doc/walkthrough.html b/doc/walkthrough.html index 0f4c2cb..26ff567 100644 --- a/doc/walkthrough.html +++ b/doc/walkthrough.html @@ -12,7 +12,7 @@ - + Analysis with tacmagic @@ -20,41 +20,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
+

All vignettes

+

+ + +
+
+
+ +
+ + +
+

Site built with pkgdown 1.3.0.

+
+
+
+ + + + + + diff --git a/docs/articles/walkthrough.html b/docs/articles/walkthrough.html new file mode 100644 index 0000000..7a9de0e --- /dev/null +++ b/docs/articles/walkthrough.html @@ -0,0 +1,483 @@ + + + + + + + +Analysis with tacmagic • tacmagic + + + + + + + + + +
+
+ + + +
+
+ + + + +
+

+Background

+

Positron emission tomography (PET) is a research and clinical imaging modality that uses radioactive tracers that bind to target molecules of interest. A PET scanner identifies the tracer location by virtue of the tracer’s radioactive decay, providing information to determine the location of the target in the body. As the spatial resolution of PET is relatively poor, analysis is frequently combined with higher resolution imaging such as magnetic resonance imaging (MRI), which can be spatially co-registered to the PET image. Subsequently, radiotracer activity (over time) can be identified by spatial region of interest (ROI).

+

An image anaylsis pipeline is required to extract regional time activity curves (tacs) from a dynamic PET image. There are various pipelines available including widely-used commercial solutions (e.g. PMOD) and newer open-source options (e.g. magia). Pipelines generally implement the following steps:

+
    +
  • Dynamic PET pre-processing (e.g. motion correction, decay-correction)
  • +
  • PET image co-registration with structural MRI
  • +
  • MRI segmentation and normalization to atlas
  • +
+

Various pipelines save tac, volume and related data in various formats. This package enables the loading and analysis of tac and ROI volume data from image analysis pipelines for further analysis in R.

+
+
+

+Vignette data

+

The sample data for this vignette uses an anonymized scans of a participant with Alzheimer’s dementia, data from http://www.gaain.org which was generously made available for unrestricted use.1 The radiotracer used is Pittsburgh Compound B (PIB) which binds to beta-amyloid, a protein found in high concentration in the brains of individuals with Alzheimer’s dementia.

+

There are two approaches to using the tacmagic package to analyze PET time-activity curve data: either by loading participant data individually and using the various functions to analyze it, or via the batch functions to list and analyze data from multiple participants. Here, we illustrate the main features of tacmagic, by walking through the analysis of a single participant. We provide an explanation of the batch mode at the end.

+
+
+

+Time-activity curve operations

+
+

+Data loading

+

Time-activity curve (TAC) data is loaded via load_tac(), which is a wrapper for format-specific functions. To specify which file format the tac data is stored as, use the format parameter. Supported formats can be viewed in help(load_tac).

+

The minimal amount of information required is the TAC data for one or more ROI, including the start and stop times of each frame, the time units and the activity units. This information may be in 1 or more files depending on the format and software that created it.

+

For example, PMOD’s .tac files contain all of the information, but the TAC .voistat files do not contain start and stop times, but this information could be specified using a .acqtimes file. Support is also available for DFT format, which contains both TAC and volume data.

+

We processed the PIB PET and T1 MRI data with the PMOD PNEURO software suite to produce a .tac file with tacs for all ROIs in the Hammer’s atlas. The .tac file can be loaded with load_tac():

+ +

A tac object is a data frame with extra attributes including time and activity units. A summary can be printed with the generic print() function.

+ +

PMOD’s suite also produces .voistat and .acqtimes formats, than can be used to produce the same data if you do not have .tac files:

+
filename_acq <- system.file("extdata", "AD06.acqtimes", package="tacmagic")
+filename_voistat <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic")
+
+tac2 <- load_tac(filename_voistat, format="voistat", acqtimes=filename_acq)
+
+all.equal(AD06_tac, tac2)
+#> [1] TRUE
+

We also used Turku’s magia pipeline to process the same data. It can be loaded similarly, though with units explicitly entered because the information is not encoded in the .mat file:

+ +
+

+Manually-created tac objects

+

For other data sources, tacmagic tac objects can be created from data.frame objects with as.tac(). The time and activity units must be specified as arguments if not already set as attributes in the data.frame. The columns of the data.frame are the regional tacs, with the column names the names of the ROIs.

+ +
+
+
+

+ROI merging

+

Often it is desirable to combine tac ROIs into larger ROIs. For example, if the PET analysis pipeline created tacs for each atlas ROI, your analysis may call for merging these atomic ROIs into larger regions, such as merging all of the atlas ROIs that make up the frontal lobe into a single frontal lobe ROI.

+

If this is done, the means should be weighted for the relative volumes of the atomic ROIs. If volume information is available, tac_roi() provides this functionality.

+

In PMOD’s software, volume information is available in .voistat files. Units do not matter because it is the relative volume information that is needed.

+

In addition to tac and volume information, we must specify which atomic ROIs make up the merged ROI. This is done by providing a named list, where the names are the merged ROIs and the list items are themselves lists of the atomic ROIs that make up each merged ROI. For the Hammer’s atlas, and as an example, typical data is provided in roi_ham_stand(), roi_ham_full(), or roi_ham_pib().

+ +
+
+

+Plotting

+

Basic tac plotting can be done by calling plot, which accepts two tac objects, e.g. from 2 participants or group means. The ROIs to plot are specified as a vector of ROI names as they appear in the tac object. As the tac object contains time unit information, the plot can convert to desired units, which can be specified with the time argument.

+
plot(AD06,                                                    # tac data
+     ROIs=c("frontal", "temporal", "parietal", "cerebellum"), # ROIs to plot
+     time="minutes",                   # Convert x axis from seconds to minutes
+     title="PIB time activity curves for AD06"        # A title for the plot
+     )
+

+
+
+
+

+Model calculation

+
+

+SUVR

+

The standardized uptake value ratio (\(SUVR\)) is a simple quantification of PET activity that is commonly used from many tracers including PIB. It is the ratio of the tracer activity over a specified time period (\(Ct\)) in a target ROI to a reference region. Using a ratio allows factors that are normally required to calculate an \(SUV\) to cancel out, namely tracer dose and patient body weight, and therefore \(SUVR\) can be calculated from tac data alone:

+

\[SUVR = \frac{SUV_{TARGET}}{SUV_{REF}} = \frac{Ct_{TARGET}}{Ct_{REF}}\]

+

In the literature, SUVR is variably described and calculated using the mean of activity for the frames of the specified time period, or the area under the curve. For PIB, the mean/summed activity has been used, and the time windows have varied from starting at 40-50 minutes and ending at 60-90 minutes.2

+

The suvr() function calculates SUVR for all regions in a tac file based on the provided time information (as a vector of frame start times) and the specified reference region (a string). If the frames used are of different durations, the weighted mean is used.

+ +

An alternative method, using the area under the curve with the mid-frame times as the x-axis is available with suvr_auc() and should provide very similar results.

+
AD06_altSUVR <- suvr_auc(AD06, SUVR_def=c(3000,3300,3600), ref="cerebellum")
+
+all.equal(AD06_SUVR, AD06_altSUVR) # Should be similar but not exact
+#> [1] "Component \"SUVR\": Mean relative difference: 0.007765957"
+
+
+

+DVR

+

The Distribution Volume Ratio (DVR) is a method of quantifying tracer uptake that is used as an alternative to the SUVR in PIB studies, for example. Like SUVR, it can be calculated from tac data without the need for arterial blood sampling, by making use of a reference region. In this case, it is called the non-invasive Logan plot method. It is calculated with a graphical analysis technique described by Logan et al.3

+

In addition to the tac data, depending on the tracer, a value for k’ may need to be specified. For PIB, this has limited effect on the result, but can be specified, and a value of 0.2 has been recommended.4

+

The non-invasive Logan plot works by finding the slope of the line of the following equation after time \(t*\) where linearity has been reached:

+

\[\frac{\int_0^{T}C_{roi}(t)dt}{C_{roi}(t)} = DVR[\frac{\int_0^{T}C_{cer}(t)dt + C_{cer}(t) / k2`}{C_{roi}(T)}] + int \]

+
+

+Find t*

+

The time, \(t*\) (t_star), after which the relationship is linear can be found by testing the point after which the error is below a certain threshold (default is 10%). If t_star=0, then tacmagic can find the suitable value.

+ +

To visually confirm that the model behaved as expected with linearity, there is a plotting function:

+
plot(AD06_DVR_fr)
+

+

The right plot shows the Logan model, with the vertical line representing the identified \(t*\), and the linear model fitted to the points after that time. In this case, the line after \(t*\) can be seen to fit well. The slope of that line is the DVR.

+

Similarly, DVR can be calculated for all ROIs, either by setting t_star manually or to 0 as before. If 0, a different value will be identified for each ROI.

+ +

For this data, the DVR calculation has been shown to produce equivalent results as an existing tool.5

+

A wrapper function dvr() is available to conveniently calculate DVR for a target ROI or all ROIs, and currently defaults to using the Logan reference method:

+
ADO6_frontal_DVR <- dvr(AD06, target="frontal", ref="cerebellum", k2prime=0.2, 
+                        t_star=23)
+
+
+
+
+

+Batch analysis

+

In most cases, a project will involve the analysis of multiple participants. The above workflow can be used to test and visualize an analysis, but a batch workflow will likely be preferred to analyze multiple participants.

+

All analyses can be run using 2 steps: a batch data loading step and a batch analysis step.

+
+

+Batch loading

+

Data loading is done by batch_load(). See help(batch_load) for the required arguments.

+

The first argument is a vector of participant IDs that corresponds to file names, e.g.:

+

participants <- c("participant01", "participant02") if the files are located e.g. /mypath/participant01.tac and /mypath/participant01_TAC.voistat. In this case, the function call might look like:

+

my_data <- batch_load(participants, dir="/mypath/", tac_format="PMOD", roi_m=T, vol_file_suffix="_TAC.voistat", vol_format="voistat", ROI_def=roi_ham_stand(), merge=F)

+

The above would load the appropriate tac and voistat files, perform the ROI merging specified by ROI_def, because roi_m = TRUE, and would return a list where each element represents a participants, e.g. the first participant would be my_data$participant1.

+
+
+

+Batch analysis

+

Once the tac data is loaded, all analyses can be run using batch_tm(). The output from batch_load() is the first argument for batch_tm(). The models implemented in tacmagic can be specified using the models argument, e.g. models = c("SUVR", "Logan") to calculate both SUVR and Logan DVR. The relevant model parameters will also need to be specified, so see help(batch_tm) for all possible arguments.

+
+
+

+Batch example

+

For the purpose of the vignette, the list of participants will be a list of the full tac filenames (hence tac_file_suffix=""). In real-world data, the participants parameter can be a list of participant IDs that correspond to the actual filenames, i.e. the filename is made up of dir + participant + tac_file_suffix.

+

We will also choose not to use the roi_m option in batch_load(), which could be used to combine ROIs as outlined above.

+

+participants <- c(system.file("extdata", "AD06.tac", package="tacmagic"),
+                   system.file("extdata", "AD07.tac", package="tacmagic"),
+                   system.file("extdata", "AD08.tac", package="tacmagic"))
+
+tacs <- batch_load(participants, dir="", tac_file_suffix="")
+
+# Since the PMOD tac files used here have 2 copies of ROIs, with and without 
+# PVC, we can use split_pvc to keep the PVC-corrected verions. If we had used 
+# roi_m here to combine ROIs, we could have specified to use the PVC versions 
+# in batch_load() with PVC = TRUE.
+tacs <- lapply(tacs, split_pvc, PVC=TRUE)
+ 
+batch <- batch_tm(tacs, models=c("SUVR", "Logan"), ref="Cerebellum_r_C",
+                  SUVR_def=c(3000,3300,3600), k2prime=0.2, t_star=23)
+
+
+
+

+Cut-off calculations

+

In the analysis of PIB/amyloid PET data, often researchers want to dichotomize patients into PIB+ vs. PIB-, i.e. to identify those with significant AD-related amyloid pathology (PIB+).

+

There are a number of approaches to this depending on the available data. We have implemented a method described by Aizenstein et al.6 which uses a group of participants with normal cognition to establish a cutoff value above which participants are unlikely to have minimal amyloid pathology.

+

The method identifies a group of participants out of the normal cognition group with higher-PIB outliers removed. An outlier is a participant with any ROI with a DVR higher than the upper inner fence, from a set of ROIs known to be associated with amyloid deposition. Such participants are removed from the group, and this process is done iteratively until no more outliers are removed. Then, cutoff values are determined from this new group for each ROI, set again as the upper inner fence. Then these cutoff values are applied to all participants, and a participant is deemed PIB+ if they have at least 1 ROI above its cutoff.

+

To demonstrate, a fake dataset of DVR values for 50 fake participants was generated and is available as fake_DVR. This would be equivalent to using batch_tm() on a group of participants with the "Logan" model specified.

+ +

To calculate the cutoff values using this iterative method, cutoff_aiz() takes 2 arguments: the DVR data, and the names of the variables of the ROI DVRs to use (and there must be at least 2 for this method).

+ +

The final step is to apply the cutoffs to the full set of participants. We will use the same sample data:

+ +

The algorithm identified 11 PIB+ participants. In the generation of the sample data, the DVRs from the first 10 participants were drawn from a normal distribution with mean 1.9, sd 0.6 and for the latter 40 participants, from mean 1.3, sd 0.3; thus this pattern is in line with what we would expect: all 10 of the first participants are PIB+, and just 1 of the latter 40 was (by chance).

+
+
+
+
    +
  1. Klunk, William E., Robert A. Koeppe, Julie C. Price, Tammie L. Benzinger, Michael D. Devous, William J. Jagust, Keith A. Johnson, et al. “The Centiloid Project: Standardizing Quantitative Amyloid Plaque Estimation by PET.” Alzheimer’s & Dementia 11, no. 1 (January 2015): 1-15.e4. https://doi.org/10.1016/j.jalz.2014.07.003.

  2. +
  3. Lopresti, B. J., W. E. Klunk, C. A. Mathis, J. A. Hoge, S. K. Ziolko, X. Lu, C. C. Meltzer, et al. “Simplified Quantification of Pittsburgh Compound B Amyloid Imaging PET Studies: A Comparative Analysis.” J Nucl Med 46 (2005): 1959–72.

  4. +
  5. Logan, J., Fowler, J. S., Volkow, N. D., Wang, G.-J., Ding, Y.-S., & Alexoff, D. L. (1996). Distribution Volume Ratios without Blood Sampling from Graphical Analysis of PET Data. Journal of Cerebral Blood Flow & Metabolism, 16(5), 834-840. https://doi.org/10.1097/00004647-199609000-00008

  6. +
  7. http://www.turkupetcentre.net/petanalysis/analysis_11c-pib.html

  8. +
  9. https://gitlab.utu.fi/vesoik/tpcclib

  10. +
  11. Aizenstein HJ, Nebes RD, Saxton JA, et al. 2008. Frequent amyloid deposition without significant cognitive impairment among the elderly. Arch Neurol 65: 1509-1517.

  12. +
+
+
+ + + +
+ + +
+ +
+

Site built with pkgdown 1.3.0.

+
+
+
+ + + + + diff --git a/docs/articles/walkthrough_files/figure-html/unnamed-chunk-11-1.png b/docs/articles/walkthrough_files/figure-html/unnamed-chunk-11-1.png new file mode 100644 index 0000000..8220ed4 Binary files /dev/null and b/docs/articles/walkthrough_files/figure-html/unnamed-chunk-11-1.png differ diff --git a/docs/articles/walkthrough_files/figure-html/unnamed-chunk-5-1.png b/docs/articles/walkthrough_files/figure-html/unnamed-chunk-5-1.png new file mode 100644 index 0000000..ebf753f Binary files /dev/null and b/docs/articles/walkthrough_files/figure-html/unnamed-chunk-5-1.png differ diff --git a/docs/articles/walkthrough_files/figure-html/unnamed-chunk-7-1.png b/docs/articles/walkthrough_files/figure-html/unnamed-chunk-7-1.png new file mode 100644 index 0000000..03a9e81 Binary files /dev/null and b/docs/articles/walkthrough_files/figure-html/unnamed-chunk-7-1.png differ diff --git a/docs/articles/walkthrough_files/figure-html/unnamed-chunk-9-1.png b/docs/articles/walkthrough_files/figure-html/unnamed-chunk-9-1.png new file mode 100644 index 0000000..daf2bc4 Binary files /dev/null and b/docs/articles/walkthrough_files/figure-html/unnamed-chunk-9-1.png differ diff --git a/docs/authors.html b/docs/authors.html new file mode 100644 index 0000000..cbf0d83 --- /dev/null +++ b/docs/authors.html @@ -0,0 +1,153 @@ + + + + + + + + +Authors • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
    +
  • +

    Eric Brown. Author, maintainer. ORCID +

    +
  • +
  • +

    Ariel Graff-Guerrero. Degree supervisor. +

    +
  • +
  • +

    Jon Clayden. Reviewer. ORCID +
    Jon Clayden reviewed the package for ropensci, see

    +
  • +
  • +

    Brandon Hurr. Reviewer. ORCID +
    Brandon Hurr reviewed the package for ropensci, see

    +
  • +
+ +
+ +
+ + +
+ + +
+

Site built with pkgdown 1.3.0.

+
+
+
+ + + + + + diff --git a/docs/contributing.html b/docs/contributing.html new file mode 100644 index 0000000..fc71eac --- /dev/null +++ b/docs/contributing.html @@ -0,0 +1,157 @@ + + + + + + + + +Contributing • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
+ +

A primary purpose of tacmagic is to foster open and reproducible in PET neuroimaging research. Therefore, the package is released under a GPL licence and contributions are welcome.

+

Please suggest changes or report bugs using the Issues page of this repository. In addition to bugs and feature requests.

+

Expanded funcitonality could be considered in the following areas:

+
    +
  1. Additional file format support for loading TAC and related data.
  2. +
  3. Implementation of additional kinetic models
  4. +
  5. Implementation or improvement of plotting functions
  6. +
  7. Implementation or improvmeent of cutoff calculation algorithms
  8. +
+
+

+File formats

+

To propose additional file format support, a sample file is required for testing. Preferably, the file could be generated from the same PET data used for other formats. If a file format specification document is available, it should be referenced.

+
+
+

+Kinetic models

+

At a minimum, proposals to expand the supported models should include the R code, a refence describing the model, and the expected results using an exisiting tool for testing purposes. If possible, the existing example tac data would be used if possible.

+
+
+ +
+ +
+ + +
+ + +
+

Site built with pkgdown 1.3.0.

+
+
+
+ + + + + + diff --git a/docs/docsearch.css b/docs/docsearch.css new file mode 100644 index 0000000..e5f1fe1 --- /dev/null +++ b/docs/docsearch.css @@ -0,0 +1,148 @@ +/* Docsearch -------------------------------------------------------------- */ +/* + Source: https://github.com/algolia/docsearch/ + License: MIT +*/ + +.algolia-autocomplete { + display: block; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1 +} + +.algolia-autocomplete .ds-dropdown-menu { + width: 100%; + min-width: none; + max-width: none; + padding: .75rem 0; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .1); + box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175); +} + +@media (min-width:768px) { + .algolia-autocomplete .ds-dropdown-menu { + width: 175% + } +} + +.algolia-autocomplete .ds-dropdown-menu::before { + display: none +} + +.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-] { + padding: 0; + background-color: rgb(255,255,255); + border: 0; + max-height: 80vh; +} + +.algolia-autocomplete .ds-dropdown-menu .ds-suggestions { + margin-top: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion { + padding: 0; + overflow: visible +} + +.algolia-autocomplete .algolia-docsearch-suggestion--category-header { + padding: .125rem 1rem; + margin-top: 0; + font-size: 1.3em; + font-weight: 500; + color: #00008B; + border-bottom: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--wrapper { + float: none; + padding-top: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column { + float: none; + width: auto; + padding: 0; + text-align: left +} + +.algolia-autocomplete .algolia-docsearch-suggestion--content { + float: none; + width: auto; + padding: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--content::before { + display: none +} + +.algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header { + padding-top: .75rem; + margin-top: .75rem; + border-top: 1px solid rgba(0, 0, 0, .1) +} + +.algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column { + display: block; + padding: .1rem 1rem; + margin-bottom: 0.1; + font-size: 1.0em; + font-weight: 400 + /* display: none */ +} + +.algolia-autocomplete .algolia-docsearch-suggestion--title { + display: block; + padding: .25rem 1rem; + margin-bottom: 0; + font-size: 0.9em; + font-weight: 400 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--text { + padding: 0 1rem .5rem; + margin-top: -.25rem; + font-size: 0.8em; + font-weight: 400; + line-height: 1.25 +} + +.algolia-autocomplete .algolia-docsearch-footer { + width: 110px; + height: 20px; + z-index: 3; + margin-top: 10.66667px; + float: right; + font-size: 0; + line-height: 0; +} + +.algolia-autocomplete .algolia-docsearch-footer--logo { + background-image: url("data:image/svg+xml;utf8,"); + background-repeat: no-repeat; + background-position: 50%; + background-size: 100%; + overflow: hidden; + text-indent: -9000px; + width: 100%; + height: 100%; + display: block; + transform: translate(-8px); +} + +.algolia-autocomplete .algolia-docsearch-suggestion--highlight { + color: #FF8C00; + background: rgba(232, 189, 54, 0.1) +} + + +.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { + box-shadow: inset 0 -2px 0 0 rgba(105, 105, 105, .5) +} + +.algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content { + background-color: rgba(192, 192, 192, .15) +} diff --git a/docs/docsearch.js b/docs/docsearch.js new file mode 100644 index 0000000..b35504c --- /dev/null +++ b/docs/docsearch.js @@ -0,0 +1,85 @@ +$(function() { + + // register a handler to move the focus to the search bar + // upon pressing shift + "/" (i.e. "?") + $(document).on('keydown', function(e) { + if (e.shiftKey && e.keyCode == 191) { + e.preventDefault(); + $("#search-input").focus(); + } + }); + + $(document).ready(function() { + // do keyword highlighting + /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ + var mark = function() { + + var referrer = document.URL ; + var paramKey = "q" ; + + if (referrer.indexOf("?") !== -1) { + var qs = referrer.substr(referrer.indexOf('?') + 1); + var qs_noanchor = qs.split('#')[0]; + var qsa = qs_noanchor.split('&'); + var keyword = ""; + + for (var i = 0; i < qsa.length; i++) { + var currentParam = qsa[i].split('='); + + if (currentParam.length !== 2) { + continue; + } + + if (currentParam[0] == paramKey) { + keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); + } + } + + if (keyword !== "") { + $(".contents").unmark({ + done: function() { + $(".contents").mark(keyword); + } + }); + } + } + }; + + mark(); + }); +}); + +/* Search term highlighting ------------------------------*/ + +function matchedWords(hit) { + var words = []; + + var hierarchy = hit._highlightResult.hierarchy; + // loop to fetch from lvl0, lvl1, etc. + for (var idx in hierarchy) { + words = words.concat(hierarchy[idx].matchedWords); + } + + var content = hit._highlightResult.content; + if (content) { + words = words.concat(content.matchedWords); + } + + // return unique words + var words_uniq = [...new Set(words)]; + return words_uniq; +} + +function updateHitURL(hit) { + + var words = matchedWords(hit); + var url = ""; + + if (hit.anchor) { + url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; + } else { + url = hit.url + '?q=' + escape(words.join(" ")); + } + + return url; +} diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..5b41bbd --- /dev/null +++ b/docs/index.html @@ -0,0 +1,190 @@ + + + + + + + +tacmagic: PET Analysis in R • tacmagic + + + + + + + + + +
+
+ + + +
+
+
+ + +

To foster openness, replicability, and efficiency, tacmagic facilitates loading and analysis of positron emission tomography data in R.

+

As a tacmagic is a new package, we strongly recommend checking all work against existing analyses to confirm the results are as expected.

+
+

+Installation

+

Currently, the package can be installed within R from the github repository. The devtools package is required for installation:

+ +
+
+

+Features

+

The features of tacmagic are demonstrated in the package’s walkthrough vignette, which is highly recommended for first-time uses.

+
+

+Data loading and weighted-averages

+

Time-activity curve (TAC) and/or region of interest (ROI) volume data can be loaded from various file formats including PMOD .tac and .voistat files, a .mat file from the magia pipeline, and Turku PET Centre’s .DFT format.

+

This package is not affiliated with any of the above pipelines.

+
+
+

+Time-activity curve plotting

+

Basic plotting of one or more TAC from one or more participants is available.

+
+
+

+Binding potential models

+

Non-invasive models are implemented including the standardize uptake volume ratio (SUVR) and the non-invasive Logan reference method.

+
+
+

+Batch and group-wise analysis

+

Loading and analysis functions can be run as a batch or by individual participant.

+
+
+ +
+
+ + +
+ +
+ +
+

Site built with pkgdown 1.3.0.

+
+
+
+ + + + + diff --git a/docs/link.svg b/docs/link.svg new file mode 100644 index 0000000..88ad827 --- /dev/null +++ b/docs/link.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/docs/paper.html b/docs/paper.html new file mode 100644 index 0000000..3bc3fe2 --- /dev/null +++ b/docs/paper.html @@ -0,0 +1,178 @@ + + + + + + + + +Background • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + + +
+

title: ‘tacmagic: Positron emission tomography analysis in R’ authors:

+
    +
  • affiliation: “1, 2” name: Eric E. Brown orcid: 0000-0002-1575-2606 date: “25 January 2019” bibliography: paper.bib tags:
  • +
  • positron emission tomography
  • +
  • biomedical imaging
  • +
  • neuroimaging
  • +
  • neuroscience
  • +
  • neuroinformatics affiliations:
  • +
  • index: 1 name: Department of Psychiatry and Institute of Medical Science, University of Toronto, Toronto, Canada
  • +
  • index: 2 name: Centre for Addiction and Mental Health, Toronto, Canada —
  • +
+
+ +

Positron emission tomography (PET) is a research and clinical imaging modality that uses radioactive tracers that bind to target molecules of interest. A PET scanner identifies the tracer location by virtue of the tracer’s radioactive decay, providing information about the distribution of target in the body. Analysis pipelines are used to calculate radiotracer activity over time within a spatial region of interest (ROI). The resulting time-activity curves (TAC) are analyzed to answer important clinical and research questions using kinetic models [@Dierckx:2014].

+
+
+

+The tacmagic R package

+

By supporting multiple source data formats, tacmagic provides an open R [@R] platform for the analysis of PET TAC data that has been produced by existing image analysis pipelines. The data loading functions provide a common format for subsequent analysis in R. We have also implemented basic non-invasive models commonly used in PET research [@Lopresti:2005; @Logan:1996], which have been tested against existing tools [@tpcclib]. The goal is to facilitate open, explicit and reproducible research.

+

The major features of tacmagic are documented in a walkthrough vignette that is included with the package. The features include:

+
    +
  1. loading TAC and volume data to analyze in R,
  2. +
  3. merging regional TAC data into larger ROIs weighted by volume,
  4. +
  5. basic TAC plotting,
  6. +
  7. calculation of standardized uptake value ratio (SUVR) [@Lopresti:2005;@Dierckx:2014],
  8. +
  9. calculation and plotting of the non-invasive reference region Logan DVR model [@Logan:1996;@tpcclib] and
  10. +
  11. calculation of cut-off values for dichotomizing data [@Aizenstein:2008].
  12. +
+

The package is published with an open source licence, enabling future collaboration and expansion of the package’s functions, which may include future support for additional data formats, kinetic models, plotting and cut-off calculation.

+
+
+

+Acknowledgments

+

Many thanks are due to the kind mentorship of Ariel Graff-Guerrero, Philip Gerretsen and Bruce Pollock, as well as to Fernando Caravaggio, Jun Chung, and Tiffany Chow for their guidance in PET analysis techniques prior to the development of this package.

+

Development of parts of this package involved work supported by the Canadian Institute for Health Research Canada Graduate Scholarship, the Ontario Graduate Scholarship, and the Clinician Scientist Program of the University of Toronto’s Department of Psychiatry.

+
+
+

+References

+
+ + +
+ +
+ + +
+ + +
+

Site built with pkgdown 1.3.0.

+
+
+
+ + + + + + diff --git a/docs/pkgdown.css b/docs/pkgdown.css new file mode 100644 index 0000000..c03fb08 --- /dev/null +++ b/docs/pkgdown.css @@ -0,0 +1,236 @@ +/* Sticky footer */ + +/** + * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ + * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css + * + * .Site -> body > .container + * .Site-content -> body > .container .row + * .footer -> footer + * + * Key idea seems to be to ensure that .container and __all its parents__ + * have height set to 100% + * + */ + +html, body { + height: 100%; +} + +body > .container { + display: flex; + height: 100%; + flex-direction: column; + + padding-top: 60px; +} + +body > .container .row { + flex: 1 0 auto; +} + +footer { + margin-top: 45px; + padding: 35px 0 36px; + border-top: 1px solid #e5e5e5; + color: #666; + display: flex; + flex-shrink: 0; +} +footer p { + margin-bottom: 0; +} +footer div { + flex: 1; +} +footer .pkgdown { + text-align: right; +} +footer p { + margin-bottom: 0; +} + +img.icon { + float: right; +} + +img { + max-width: 100%; +} + +/* Fix bug in bootstrap (only seen in firefox) */ +summary { + display: list-item; +} + +/* Typographic tweaking ---------------------------------*/ + +.contents .page-header { + margin-top: calc(-60px + 1em); +} + +/* Section anchors ---------------------------------*/ + +a.anchor { + margin-left: -30px; + display:inline-block; + width: 30px; + height: 30px; + visibility: hidden; + + background-image: url(./link.svg); + background-repeat: no-repeat; + background-size: 20px 20px; + background-position: center center; +} + +.hasAnchor:hover a.anchor { + visibility: visible; +} + +@media (max-width: 767px) { + .hasAnchor:hover a.anchor { + visibility: hidden; + } +} + + +/* Fixes for fixed navbar --------------------------*/ + +.contents h1, .contents h2, .contents h3, .contents h4 { + padding-top: 60px; + margin-top: -40px; +} + +/* Static header placement on mobile devices */ +@media (max-width: 767px) { + .navbar-fixed-top { + position: absolute; + } + .navbar { + padding: 0; + } +} + + +/* Sidebar --------------------------*/ + +#sidebar { + margin-top: 30px; +} +#sidebar h2 { + font-size: 1.5em; + margin-top: 1em; +} + +#sidebar h2:first-child { + margin-top: 0; +} + +#sidebar .list-unstyled li { + margin-bottom: 0.5em; +} + +.orcid { + height: 16px; + vertical-align: middle; +} + +/* Reference index & topics ----------------------------------------------- */ + +.ref-index th {font-weight: normal;} + +.ref-index td {vertical-align: top;} +.ref-index .icon {width: 40px;} +.ref-index .alias {width: 40%;} +.ref-index-icons .alias {width: calc(40% - 40px);} +.ref-index .title {width: 60%;} + +.ref-arguments th {text-align: right; padding-right: 10px;} +.ref-arguments th, .ref-arguments td {vertical-align: top;} +.ref-arguments .name {width: 20%;} +.ref-arguments .desc {width: 80%;} + +/* Nice scrolling for wide elements --------------------------------------- */ + +table { + display: block; + overflow: auto; +} + +/* Syntax highlighting ---------------------------------------------------- */ + +pre { + word-wrap: normal; + word-break: normal; + border: 1px solid #eee; +} + +pre, code { + background-color: #f8f8f8; + color: #333; +} + +pre code { + overflow: auto; + word-wrap: normal; + white-space: pre; +} + +pre .img { + margin: 5px 0; +} + +pre .img img { + background-color: #fff; + display: block; + height: auto; +} + +code a, pre a { + color: #375f84; +} + +a.sourceLine:hover { + text-decoration: none; +} + +.fl {color: #1514b5;} +.fu {color: #000000;} /* function */ +.ch,.st {color: #036a07;} /* string */ +.kw {color: #264D66;} /* keyword */ +.co {color: #888888;} /* comment */ + +.message { color: black; font-weight: bolder;} +.error { color: orange; font-weight: bolder;} +.warning { color: #6A0366; font-weight: bolder;} + +/* Clipboard --------------------------*/ + +.hasCopyButton { + position: relative; +} + +.btn-copy-ex { + position: absolute; + right: 0; + top: 0; + visibility: hidden; +} + +.hasCopyButton:hover button.btn-copy-ex { + visibility: visible; +} + +/* mark.js ----------------------------*/ + +mark { + background-color: rgba(255, 255, 51, 0.5); + border-bottom: 2px solid rgba(255, 153, 51, 0.3); + padding: 1px; +} + +/* vertical spacing after htmlwidgets */ +.html-widget { + margin-bottom: 10px; +} diff --git a/docs/pkgdown.js b/docs/pkgdown.js new file mode 100644 index 0000000..eb7e83d --- /dev/null +++ b/docs/pkgdown.js @@ -0,0 +1,115 @@ +/* http://gregfranko.com/blog/jquery-best-practices/ */ +(function($) { + $(function() { + + $("#sidebar") + .stick_in_parent({offset_top: 40}) + .on('sticky_kit:bottom', function(e) { + $(this).parent().css('position', 'static'); + }) + .on('sticky_kit:unbottom', function(e) { + $(this).parent().css('position', 'relative'); + }); + + $('body').scrollspy({ + target: '#sidebar', + offset: 60 + }); + + $('[data-toggle="tooltip"]').tooltip(); + + var cur_path = paths(location.pathname); + var links = $("#navbar ul li a"); + var max_length = -1; + var pos = -1; + for (var i = 0; i < links.length; i++) { + if (links[i].getAttribute("href") === "#") + continue; + // Ignore external links + if (links[i].host !== location.host) + continue; + + var nav_path = paths(links[i].pathname); + + var length = prefix_length(nav_path, cur_path); + if (length > max_length) { + max_length = length; + pos = i; + } + } + + // Add class to parent
  • , and enclosing
  • if in dropdown + if (pos >= 0) { + var menu_anchor = $(links[pos]); + menu_anchor.parent().addClass("active"); + menu_anchor.closest("li.dropdown").addClass("active"); + } + }); + + function paths(pathname) { + var pieces = pathname.split("/"); + pieces.shift(); // always starts with / + + var end = pieces[pieces.length - 1]; + if (end === "index.html" || end === "") + pieces.pop(); + return(pieces); + } + + // Returns -1 if not found + function prefix_length(needle, haystack) { + if (needle.length > haystack.length) + return(-1); + + // Special case for length-0 haystack, since for loop won't run + if (haystack.length === 0) { + return(needle.length === 0 ? 0 : -1); + } + + for (var i = 0; i < haystack.length; i++) { + if (needle[i] != haystack[i]) + return(i); + } + + return(haystack.length); + } + + /* Clipboard --------------------------*/ + + function changeTooltipMessage(element, msg) { + var tooltipOriginalTitle=element.getAttribute('data-original-title'); + element.setAttribute('data-original-title', msg); + $(element).tooltip('show'); + element.setAttribute('data-original-title', tooltipOriginalTitle); + } + + if(ClipboardJS.isSupported()) { + $(document).ready(function() { + var copyButton = ""; + + $(".examples, div.sourceCode").addClass("hasCopyButton"); + + // Insert copy buttons: + $(copyButton).prependTo(".hasCopyButton"); + + // Initialize tooltips: + $('.btn-copy-ex').tooltip({container: 'body'}); + + // Initialize clipboard: + var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { + text: function(trigger) { + return trigger.parentNode.textContent; + } + }); + + clipboardBtnCopies.on('success', function(e) { + changeTooltipMessage(e.trigger, 'Copied!'); + e.clearSelection(); + }); + + clipboardBtnCopies.on('error', function() { + changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); + }); + }); + } +})(window.jQuery || window.$) diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml new file mode 100644 index 0000000..2469b25 --- /dev/null +++ b/docs/pkgdown.yml @@ -0,0 +1,6 @@ +pandoc: 2.2.3.2 +pkgdown: 1.3.0 +pkgdown_sha: ~ +articles: + walkthrough: walkthrough.html + diff --git a/docs/readme.html b/docs/readme.html new file mode 100644 index 0000000..7b88312 --- /dev/null +++ b/docs/readme.html @@ -0,0 +1,189 @@ + + + + + + + + +tacmagic: PET Analysis in R • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Build Status Coverage status

    +

    To foster openness, replicability, and efficiency, tacmagic facilitates loading and analysis of positron emission tomography data in R.

    +

    As a tacmagic is a new package, we strongly recommend checking all work against existing analyses to confirm the results are as expected.

    +
    +

    +Installation

    +

    Currently, the package can be installed within R from the github repository. The devtools package is required for installation:

    + +
    +
    +

    +Features

    +

    The features of tacmagic are demonstrated in the package’s walkthrough vignette, which is highly recommended for first-time uses.

    +
    +

    +Data loading and weighted-averages

    +

    Time-activity curve (TAC) and/or region of interest (ROI) volume data can be loaded from various file formats including PMOD .tac and .voistat files, a .mat file from the magia pipeline, and Turku PET Centre’s .DFT format.

    +

    This package is not affiliated with any of the above pipelines.

    +
    +
    +

    +Time-activity curve plotting

    +

    Basic plotting of one or more TAC from one or more participants is available.

    +
    +
    +

    +Binding potential models

    +

    Non-invasive models are implemented including the standardize uptake volume ratio (SUVR) and the non-invasive Logan reference method.

    +
    +
    +

    +Batch and group-wise analysis

    +

    Loading and analysis functions can be run as a batch or by individual participant.

    +
    +
    + +
    + +
    + +
    + + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/DVR_all_ref_Logan.html b/docs/reference/DVR_all_ref_Logan.html new file mode 100644 index 0000000..533a395 --- /dev/null +++ b/docs/reference/DVR_all_ref_Logan.html @@ -0,0 +1,224 @@ + + + + + + + + +Non-invasive reference Logan method for all ROIs in tac data — DVR_all_ref_Logan • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    This calculates the DVR using the non-invasive reference Logan method for +all TACs in a supplied tac file. It uses DVR_ref_Logan.

    + +
    + +
    DVR_all_ref_Logan(tac_data, ref, k2prime, t_star, error = 0.1,
    +  method = "trapz", ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    tac_data

    The time-activity curve data from tac_roi()

    ref

    Required -- The reference region, e.g. "cerebellum"

    k2prime

    Required -- A fixed value for k2' must be specified (e.g. 0.2)

    t_star

    Required -- If 0, t* will be calculated using find_t_star()

    error

    For find_t_star()

    method

    Method of integration, "trapz" or "integrate"

    ...

    When called from tm_batch, unused parameters may be supplied

    + +

    Value

    + +

    Data frame with calculated DVRs for all ROIs

    + +

    References

    + +

    Logan, J., Fowler, J. S., Volkow, N. D., Wang, G.-J., +Ding, Y.-S., & Alexoff, D. L. (1996). Distribution Volume Ratios without +Blood Sampling from Graphical Analysis of PET Data. Journal of Cerebral +Blood Flow & Metabolism, 16(5), 834-840. +https://doi.org/10.1097/00004647-199609000-00008

    + +

    See also

    + +

    Other Logan plot functions: DVR_ref_Logan, + dvr, plot.ref_Logan

    + + +

    Examples

    +
    f <- system.file("extdata", "AD06.tac", package="tacmagic") +fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") +AD06_tac <- load_tac(f, format="PMOD") +AD06_volume <- load_vol(fv, format="voistat") +AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), + merge=FALSE, PVC=FALSE) + +AD06_DVR <- DVR_all_ref_Logan(AD06, ref="cerebellum", k2prime=0.2, t_star=23)
    #> Trying leftfrontal
    #> Trying rightfrontal
    #> Trying lefttemporal
    #> Trying righttemporal
    #> Trying leftparietal
    #> Trying rightparietal
    #> Trying leftoccipital
    #> Trying rightoccipital
    #> Trying leftcingulate
    #> Trying rightcingulate
    #> Trying frontal
    #> Trying temporal
    #> Trying parietal
    #> Trying occipital
    #> Trying cingulate
    #> Trying cerebellum
    #> Trying totalcortical
    #> Trying leftdeep
    #> Trying rightdeep
    #> Trying deep
    #> Trying ventricles
    #> Trying whitematter
    #> Trying amyloidcomp
    +
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/DVR_ref_Logan.html b/docs/reference/DVR_ref_Logan.html new file mode 100644 index 0000000..b0fa0ff --- /dev/null +++ b/docs/reference/DVR_ref_Logan.html @@ -0,0 +1,225 @@ + + + + + + + + +Non-invasive reference Logan method — DVR_ref_Logan • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    This calculates the coefficient from the non-invasive Logan method, which +is equal to DVR. Works for a single tac (target).

    + +
    + +
    DVR_ref_Logan(tac_data, target, ref, k2prime, t_star, error = 0.1,
    +  method = "trapz")
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    tac_data

    The time-activity curve data from tac_roi()

    target

    The name of the target ROI, e.g. "frontal"

    ref

    The reference region, e.g. "cerebellum"

    k2prime

    A fixed value for k2' must be specified (e.g. 0.2)

    t_star

    If 0, t* will be calculated using find_t_star()

    error

    For find_t_star()

    method

    Method of integration, "trapz" or "integrate"

    + +

    Value

    + +

    Data frame with calculate DVRs for all ROIs

    + +

    References

    + +

    Logan, J., Fowler, J. S., Volkow, N. D., Wang, G.-J., +Ding, Y.-S., & Alexoff, D. L. (1996). Distribution Volume Ratios without +Blood Sampling from Graphical Analysis of PET Data. Journal of Cerebral +Blood Flow & Metabolism, 16(5), 834-840. +https://doi.org/10.1097/00004647-199609000-00008

    + +

    See also

    + +

    Other Logan plot functions: DVR_all_ref_Logan, + dvr, plot.ref_Logan

    + + +

    Examples

    +
    f <- system.file("extdata", "AD06.tac", package="tacmagic") +fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") +AD06_tac <- load_tac(f, format="PMOD") +AD06_volume <- load_vol(fv, format="voistat") +AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), + merge=FALSE, PVC=FALSE) + +AD06_DVR_fr <- DVR_ref_Logan(AD06, target="frontal", ref="cerebellum", + k2prime=0.2, t_star=0)
    #> t* is 23
    +
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/as.tac.html b/docs/reference/as.tac.html new file mode 100644 index 0000000..6c2c745 --- /dev/null +++ b/docs/reference/as.tac.html @@ -0,0 +1,204 @@ + + + + + + + + +Creates a tac object from a data.frame — as.tac • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    tac objects can be created from data.frame objects with `as.tac()`. The time +and activity units must be specified as arguments if not already set as +attributes in the data.frame. The columns of the data frame are the regional +time activity curves, with the column names the names of the ROIs.

    + +
    + +
    as.tac(x, time_unit = NULL, activity_unit = NULL)
    + +

    Arguments

    + + + + + + + + + + + + + + +
    x

    data.frame with start, end time and tac data

    time_unit

    NULL if in data.frame or set to "seconds" or "minutes"

    activity_unit

    NULL if in data.frame or set to "kBq/cc", "Bq/cc", +"nCi/cc"

    + +

    Value

    + +

    tac object

    + +

    Details

    + +

    If the time_unit and activity_unit attributes are already in the data.frame, +they do not need to be set again, but otherwise they will need to be +specified in the input parameters.

    + +

    See also

    + +

    Other Loading functions: load_tac, + load_voistat, load_vol

    + + +

    Examples

    +
    manual <- data.frame(start=c(0:4), end=c(2:6), + ROI1=c(10.1:14.2), ROI2=c(11:15)) +manual_tac <- as.tac(manual, time_unit="minutes", activity_unit="kBq/cc")
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/batch_load.html b/docs/reference/batch_load.html new file mode 100644 index 0000000..230db42 --- /dev/null +++ b/docs/reference/batch_load.html @@ -0,0 +1,234 @@ + + + + + + + + +Load (+/- merge) ROIs for batch of participants — batch_load • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    For a vector of participant IDs and correspondingly named tac files, +this loads the tac files. If roi_m = T, then can also merge ROIs into +larger ROIs based on the optional parameters that follow.

    + +
    + +
    batch_load(participants, dir = "", tac_file_suffix = ".tac",
    +  tac_format = "PMOD", roi_m = FALSE, PVC = NULL,
    +  vol_file_suffix = NULL, vol_format = NULL, merge = NULL,
    +  ROI_def = NULL)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    participants

    A vector of participant IDs

    dir

    A directory and/or file name prefix for the tac/volume files

    tac_file_suffix

    How participant IDs corresponds to the TAC files

    tac_format

    Format of tac files provided: See load_tac()

    roi_m

    TRUE if you want to merge atomic ROIs into larger ROIs (and if +not, the following parameters are not used)

    PVC

    For PVC, true where the data is stored as _C in same tac file

    vol_file_suffix

    How participant IDs correspond to volume files

    vol_format

    The file format that includes volumes: See load_vol()

    merge

    Passes value to tac_roi(); T to also incl. original atomic ROIs

    ROI_def

    Object that defines combined ROIs, see ROI_definitions.R

    + +

    Value

    + +

    A list of data.frames, each is a participant's TACs

    + +

    Details

    + +

    See load_tac() for specifics.

    + +

    See also

    + +

    Other Batch functions: batch_tm, + batch_voistat

    + + +

    Examples

    +
    # For the working example, the participants are full filenames. +participants <- c(system.file("extdata", "AD06.tac", package="tacmagic"), + system.file("extdata", "AD07.tac", package="tacmagic"), + system.file("extdata", "AD08.tac", package="tacmagic")) + +tacs <- batch_load(participants, tac_file_suffix="")
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/batch_tm.html b/docs/reference/batch_tm.html new file mode 100644 index 0000000..daff057 --- /dev/null +++ b/docs/reference/batch_tm.html @@ -0,0 +1,212 @@ + + + + + + + + +Calculate one or more models for a batch of participants — batch_tm • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    For a list of tac data (from load_batch) this calculates specified models +and saves in a tidy data.frame. Current model options are "SUVR", "Logan".

    + +
    + +
    batch_tm(all_tacs, models, custom_model = NULL, ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + +
    all_tacs

    A list by participant, of tac data (load_batch())

    models

    A vector of names of the models to calculate

    custom_model

    A function that can be run like other models (advanced)

    ...

    The arguments that get passed to the specified models/custom model, +many are required; please check with model desired.

    + +

    Value

    + +

    A table of SUVR values for the specified ROIs for all participants

    + +

    Details

    + +

    For further details about how the models are calculated, see the indiviudal +functions that they rely on. "SUVR" uses suvr(), "Logan" uses +DVR_all_ref_Logan().

    + +

    See also

    + +

    Other Batch functions: batch_load, + batch_voistat

    + + +

    Examples

    +
    participants <- c(system.file("extdata", "AD06.tac", package="tacmagic"), + system.file("extdata", "AD07.tac", package="tacmagic"), + system.file("extdata", "AD08.tac", package="tacmagic")) + +tacs <- batch_load(participants, tac_file_suffix="") + +# Keeps only the ROIs without partial-volume correction (PMOD convention) +tacs <- lapply(tacs, split_pvc, FALSE) + +batch <- batch_tm(tacs, models=c("SUVR", "Logan"), ref="Cerebellum_r", + SUVR_def=c(3000,3300,3600), k2prime=0.2, t_star=23)
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/batch_voistat.html b/docs/reference/batch_voistat.html new file mode 100644 index 0000000..b983aa9 --- /dev/null +++ b/docs/reference/batch_voistat.html @@ -0,0 +1,216 @@ + + + + + + + + +Obtain values from voistat files (using load_voistat() for a batch. — batch_voistat • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    For a vector of participant IDs and correspondingly named .voistat files, +this extracts the value from the files for the specified ROIs. +participants can also be a vector of filenames, in which case set dir="" and +filesuffix="", as in the example.

    + +
    + +
    batch_voistat(participants, ROI_def, dir = "", filesuffix = ".voistat",
    +  varname = "VALUE")
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + +
    participants

    A vector of participant IDs

    ROI_def

    Object that defines combined ROIs, see ROI_definitions.R

    dir

    Directory and/or filename prefix of the files

    filesuffix

    Optional filename characters between ID and ".voistat"

    varname

    The name of the variable being extracted, e.g. "SRTM"

    + +

    Value

    + +

    A table of values for the specified ROIs for all participants

    + +

    Details

    + +

    See load_voistat() for specifics.

    + +

    See also

    + +

    Other Batch functions: batch_load, + batch_tm

    + + +

    Examples

    +
    participants <- c(system.file("extdata", "AD06_BPnd_BPnd_Logan.voistat", + package="tacmagic"), + system.file("extdata", "AD07_BPnd_BPnd_Logan.voistat", + package="tacmagic"), + system.file("extdata", "AD08_BPnd_BPnd_Logan.voistat", + package="tacmagic")) + +batchtest <- batch_voistat(participants=participants, ROI_def=roi_ham_pib(), + dir="", filesuffix="", varname="Logan")
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/cutoff_aiz.html b/docs/reference/cutoff_aiz.html new file mode 100644 index 0000000..aff5504 --- /dev/null +++ b/docs/reference/cutoff_aiz.html @@ -0,0 +1,216 @@ + + + + + + + + +Cutoff value calculation using method described in Aizenstein et al. 2008 — cutoff_aiz • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    See the reference below and the tacmagic walkthrough vignette. Aizenstein et +al. (2008) proposed a standardized method of calculating Pittsburg Compound +B (PIB) cutoff values to classify participants as PIB+ or PIB-. They used the +distribution volume ratio (DVR) from several ROIs associated with amyloid +deposition. The steps are summarized below. cutoff_aiz() implements 1-3, +returning cutoff valuesfor each ROI. It can be used to dichotomize +participants, with pos_anyroi().

    + +
    + +
    cutoff_aiz(modelstats, ROIs)
    + +

    Arguments

    + + + + + + + + + + +
    modelstats

    SUVR or DVR data for group of participants from batch_tm()

    ROIs

    list of variables (ROIs) to use for cutoff detection

    + +

    Value

    + +

    Cutoff values for each ROI based on the above method

    + +

    Details

    + +

    1. Remove outliers from a group of cognitively normal individuals. An outlier +is defined as having any ROI with DVR > upper inner fence of that ROI (= 3rd +quartile + (1.5 * IQR). +2. Iterate step 1 as needed until there are no more outlying participants. +3. From this subset of the group with outliers removed, the cutoff value for +each ROI is set as the upper inner fence. +4. For all participants, if there is any ROI above the cutoff for that +region, then the participant is deemed to be PIB+.

    + +

    References

    + +

    Aizenstein HJ, Nebes RD, Saxton JA, et al. 2008. Frequent amyloid +deposition without significant cognitive impairment among the elderly. +Arch Neurol 65: 1509-1517.

    + +

    See also

    + +

    Other Cutoff functions: pos_anyroi

    + + +

    Examples

    +
    cutoff_aiz(fake_DVR, c("ROI1_DVR", "ROI2_DVR", "ROI3_DVR", "ROI4_DVR"))
    #> Iteration: 1 Removed: 10
    #> Iteration: 2 Removed: 1
    #> Iteration: 3 Removed: 0
    #> ROI1_DVR ROI2_DVR ROI3_DVR ROI4_DVR +#> 1.370899 1.332725 1.330504 1.273470
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/dvr.html b/docs/reference/dvr.html new file mode 100644 index 0000000..a6a4ba6 --- /dev/null +++ b/docs/reference/dvr.html @@ -0,0 +1,237 @@ + + + + + + + + +Distribution volume ratio (DVR) for one or more ROIs — dvr • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    This calculates the DVR using the non-invasive reference Logan method for +all TACs in a supplied tac file. It uses DVR_ref_Logan if a target ROI is +specified, otherwise will calculate DVR for all ROIs with DVR_ref_all_Logan()

    + +
    + +
    dvr(tac, model = "logan", target = NULL, ref, k2prime, t_star,
    +  error = 0.1, method = "trapz")
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    tac

    The time-activity curve data from load_tac() or tac_roi()

    model

    Only model currently available is "logan"

    target

    Optional - otherwise will calculate DVR for all regions

    ref

    Required -- The reference region, e.g. "cerebellum"

    k2prime

    Required -- A fixed value for k2' must be specified (e.g. 0.2)

    t_star

    Required -- If 0, t* will be calculated using find_t_star()

    error

    For find_t_star()

    method

    Method of integration, "trapz" or "integrate"

    + +

    Value

    + +

    Data frame with calculated DVRs

    + +

    Details

    + +

    For other model paramters, directly call DVR_ref_Logan().

    + +

    References

    + +

    Logan, J., Fowler, J. S., Volkow, N. D., Wang, G.-J., +Ding, Y.-S., & Alexoff, D. L. (1996). Distribution Volume Ratios without +Blood Sampling from Graphical Analysis of PET Data. Journal of Cerebral +Blood Flow & Metabolism, 16(5), 834-840. +https://doi.org/10.1097/00004647-199609000-00008

    + +

    See also

    + +

    Other Logan plot functions: DVR_all_ref_Logan, + DVR_ref_Logan, plot.ref_Logan

    + + +

    Examples

    +
    f <- system.file("extdata", "AD06.tac", package="tacmagic") +fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") +AD06_tac <- load_tac(f, format="PMOD") +AD06_volume <- load_vol(fv, format="voistat") +AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), + merge=FALSE, PVC=FALSE) + +AD06_DVRs <- dvr(AD06, ref="cerebellum", k2prime=0.2, t_star=23)
    #> Trying leftfrontal
    #> Trying rightfrontal
    #> Trying lefttemporal
    #> Trying righttemporal
    #> Trying leftparietal
    #> Trying rightparietal
    #> Trying leftoccipital
    #> Trying rightoccipital
    #> Trying leftcingulate
    #> Trying rightcingulate
    #> Trying frontal
    #> Trying temporal
    #> Trying parietal
    #> Trying occipital
    #> Trying cingulate
    #> Trying cerebellum
    #> Trying totalcortical
    #> Trying leftdeep
    #> Trying rightdeep
    #> Trying deep
    #> Trying ventricles
    #> Trying whitematter
    #> Trying amyloidcomp
    +AD06_DVR <- dvr(AD06, target="frontal", ref="cerebellum", + k2prime=0.2, t_star=23)
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/fake_DVR.html b/docs/reference/fake_DVR.html new file mode 100644 index 0000000..6a44902 --- /dev/null +++ b/docs/reference/fake_DVR.html @@ -0,0 +1,173 @@ + + + + + + + + +Fake DVR data for vignette and package testing — fake_DVR • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    A fake dataset of 50 simulated participants in the format that the function +tm_batch() would be expected to produce with the "Logan" model specified. +The data itself was generated as follows:

    + +
    + +
    fake_DVR
    + +

    Format

    + +

    A data frame with 50 rows and 4 variables representing ROIs

    + +

    Details

    + +

    higher <- matrix(rnorm(40, 1.9, 0.6), ncol=4, nrow=10) +lower <- matrix(rnorm(160, 1.3, 0.3), ncol=4, nrow=40) +fake_data <- as.data.frame(rbind(higher, lower)) +row.names(fake_data) <- paste0("p", 1:50) +colnames(fake_data) <- c("ROI1_DVR", "ROI2_DVR", "ROI3_DVR", "ROI4_DVR") +save(fake_data, "fake_DVR.Rda")

    + + +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/index.html b/docs/reference/index.html new file mode 100644 index 0000000..d8c419d --- /dev/null +++ b/docs/reference/index.html @@ -0,0 +1,302 @@ + + + + + + + + +Function reference • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    All functions

    +

    +
    +

    DVR_all_ref_Logan()

    +

    Non-invasive reference Logan method for all ROIs in tac data

    +

    DVR_ref_Logan()

    +

    Non-invasive reference Logan method

    +

    as.tac()

    +

    Creates a tac object from a data.frame

    +

    batch_load()

    +

    Load (+/- merge) ROIs for batch of participants

    +

    batch_tm()

    +

    Calculate one or more models for a batch of participants

    +

    batch_voistat()

    +

    Obtain values from voistat files (using load_voistat() for a batch.

    +

    cutoff_aiz()

    +

    Cutoff value calculation using method described in Aizenstein et al. 2008

    +

    dvr()

    +

    Distribution volume ratio (DVR) for one or more ROIs

    +

    fake_DVR

    +

    Fake DVR data for vignette and package testing

    +

    load_tac()

    +

    Loads TAC from file for use by other functions (default is PMOD .tac format)

    +

    load_voistat()

    +

    Reads PMOD .voistat files and optionally merges volume-weighted ROIs

    +

    load_vol()

    +

    Loads ROI volumes from file for use by other functions

    +

    plot(<ref_Logan>)

    +

    Non-invasive reference Logan plot

    +

    plot(<tac>)

    +

    Plots time activity curves from 1 or 2 participants or groups.

    +

    pos_anyroi()

    +

    Dichotomize participants based on ROI cutoff values

    +

    roi_ham_full()

    +

    Return a list of larger ROIs made up of the ROIs in the Hammer's atlas.

    +

    roi_ham_pib()

    +

    Return a list of merged ROIs made up of atomic ROIs in the Hammer's atlas.

    +

    roi_ham_stand()

    +

    Return a list of merged ROIs made up of the atomic ROIs in the Hammer's +atlas.

    +

    save_tac()

    +

    Save a tac object as a .tac file

    +

    split_pvc()

    +

    Subset PMOD tacs with or without PVC

    +

    suvr()

    +

    Calculate weighted SUVRs for specified regions of interest

    +

    suvr_auc()

    +

    Calculate SUVRs for regions of interest with AUC from mid-frame times

    +

    tac_roi()

    +

    Calculate weighted time-activity curves for specified regions of interest

    +

    tacmagic

    +

    tacmagic: PET Analysis in R

    +
    + + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/load_tac.html b/docs/reference/load_tac.html new file mode 100644 index 0000000..5408720 --- /dev/null +++ b/docs/reference/load_tac.html @@ -0,0 +1,220 @@ + + + + + + + + +Loads TAC from file for use by other functions (default is PMOD .tac format) — load_tac • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    This is the main function for loading an individual participant's TAC data. +The minimal required information within the supplied files is the start and +stop times and a time unit (either seconds or minutes), as well as the +activity values for 1 or more ROIs, and units for activity. The currently +supported formats (with the corresponding format argument), include:

      +
    • "PMOD": PMOD .tac files

    • +
    • "voistat": PMOD TAC .voistat files used in combination with PMOD + .acqtimes file for start/stop times.

    • +
    • "magia": magia pipeline .mat tac file

    • +
    • "DFT": Turku PET Centre's DFT format

    • +
    + +
    + +
    load_tac(filename, format = "PMOD", acqtimes = NULL,
    +  time_unit = NULL, activity_unit = NULL)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + +
    filename

    (e.g. "participant01.tac")

    format

    A character string, with options listed above (e.g. "PMOD")

    acqtimes

    Filename for a .acqtimes file (as in PMOD), required for +format="voistat"

    time_unit

    NULL if in file (e.g. PMOD .tac), or set to "seconds" or +"minutes" if not in file or to override file

    activity_unit

    NULL if in file (e.g. PMOD .tac), or set to "kBq/cc", +"Bq/cc", "nCi/cc"

    + +

    Value

    + +

    tac object

    + +

    See also

    + +

    Other Loading functions: as.tac, + load_voistat, load_vol

    + + +

    Examples

    +
    f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") +tac <- load_tac(f_raw_tac)
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/load_voistat.html b/docs/reference/load_voistat.html new file mode 100644 index 0000000..bbe16d9 --- /dev/null +++ b/docs/reference/load_voistat.html @@ -0,0 +1,197 @@ + + + + + + + + +Reads PMOD .voistat files and optionally merges volume-weighted ROIs — load_voistat • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    PMOD can produce .voistat files with the average model values by ROI for +its voxelwise binding potential (BPnd) models, such as Logan, SRTM, etc. +This function reads the .voistat file and returns a data.frame with the +ROI as rows and the model value as the column. Optionally, the ROIs can be +combined into larger ROIs if ROI_def is specified, just as with TAC loading.

    + +
    + +
    load_voistat(filename, ROI_def = NULL, model = "VALUE")
    + +

    Arguments

    + + + + + + + + + + + + + + +
    filename

    (e.g. participant_logan.voistat)

    ROI_def

    Optional ROI definitions to combine ROIs (e.g. roi_ham_pib())

    model

    A string to name the variable being extracted, e.g. "Logan_DVR"

    + +

    Value

    + +

    data.frame with loaded model data in specified combined weighted ROIs

    + +

    See also

    + +

    Other Loading functions: as.tac, + load_tac, load_vol

    + + +

    Examples

    +
    f <- system.file("extdata", "AD06_BPnd_BPnd_Logan.voistat", + package="tacmagic") +vs <- load_voistat(f, ROI_def=roi_ham_pib(), model="Logan")
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/load_vol.html b/docs/reference/load_vol.html new file mode 100644 index 0000000..3042c00 --- /dev/null +++ b/docs/reference/load_vol.html @@ -0,0 +1,186 @@ + + + + + + + + +Loads ROI volumes from file for use by other functions — load_vol • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Loads ROI volumes from file for use by other functions

    + +
    + +
    load_vol(filename, format = "voistat")
    + +

    Arguments

    + + + + + + + + + + +
    filename

    (e.g. participant.voistat)

    format

    (default is the TAC .voistat format from PMOD, also accepts +"DFT and "BPndPaste")

    + +

    Value

    + +

    data.frame with loaded TAC data

    + +

    See also

    + +

    Other Loading functions: as.tac, + load_tac, load_voistat

    + + +

    Examples

    +
    f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") + +vol <- load_vol(f_raw_vol)
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/plot.ref_Logan.html b/docs/reference/plot.ref_Logan.html new file mode 100644 index 0000000..861caad --- /dev/null +++ b/docs/reference/plot.ref_Logan.html @@ -0,0 +1,189 @@ + + + + + + + + +Non-invasive reference Logan plot — plot.ref_Logan • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    This plots the non-invasive Logan plot.

    + +
    + +
    # S3 method for ref_Logan
    +plot(x, ...)
    + +

    Arguments

    + + + + + + + + + + +
    x

    Reference Logan model data object from DVR_ref_Logan()

    ...

    Additional parameters than can be passed to plotting function

    + +

    Value

    + +

    No return +f <- system.file("extdata", "AD06.tac", package="tacmagic") +fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") +AD06_tac <- load_tac(f, format="PMOD") +AD06_volume <- load_vol(fv, format="voistat") +AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), + merge=FALSE, PVC=FALSE) +AD06_DVR_fr <- DVR_ref_Logan(AD06, target="frontal", ref="cerebellum", + k2prime=0.2, t_star=0) +plot(AD06_DVR_fr)

    + +

    See also

    + +

    Other Logan plot functions: DVR_all_ref_Logan, + DVR_ref_Logan, dvr

    + + +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/plot.tac-1.png b/docs/reference/plot.tac-1.png new file mode 100644 index 0000000..7adda60 Binary files /dev/null and b/docs/reference/plot.tac-1.png differ diff --git a/docs/reference/plot.tac.html b/docs/reference/plot.tac.html new file mode 100644 index 0000000..9d34932 --- /dev/null +++ b/docs/reference/plot.tac.html @@ -0,0 +1,218 @@ + + + + + + + + +Plots time activity curves from 1 or 2 participants or groups. — plot.tac • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Plots time activity curves from 1 or 2 participants or groups.

    + +
    + +
    # S3 method for tac
    +plot(x, tac2 = NULL, ROIs, ymax = 25, time = "minutes",
    +  title = "", colors = rainbow, ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    x

    A tac object containing time-activity curves to plot, e.g. from +tac_roi() or load_tac()

    tac2

    An optional, second TAC, to plot for comparison

    ROIs

    A vector of ROIs to plot, names matching the TAC headers

    ymax

    The maximum value on the y-axis

    time

    "seconds" or "minutes" depending on desired x-axis, converts tac

    title

    A title for the plot

    colors

    If null, rainbow palette is used, otherwise another palette can +be specified (heat.colors, terrain.colors, topo.colors, cm.colors

    ...

    Additional arguments

    + +

    Value

    + +

    Creates a plot

    + +

    See also

    + +

    Other tac functions: save_tac, + split_pvc, tac_roi

    + + +

    Examples

    +
    # f_raw_tac and f_raw_vol are the filenames of PMOD-generated files +f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") +f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") + +tac <- load_tac(f_raw_tac) +vol <- load_vol(f_raw_vol) +AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=FALSE, PVC=FALSE) +plot(AD06_tac_nc, ROIs=c("frontal", "cerebellum"), title="Example Plot")
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/plot_ref_Logan.html b/docs/reference/plot_ref_Logan.html new file mode 100644 index 0000000..1778c9c --- /dev/null +++ b/docs/reference/plot_ref_Logan.html @@ -0,0 +1,208 @@ + + + + + + + + +Non-invasive reference Logan plot — plot_ref_Logan • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    This plots the non-invasive Logan plot.

    + +
    + +
    plot_ref_Logan(tac_data, target, ref, k2prime, t_star = 0, error = 0.1,
    +  method = "trapz")
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    tac_data

    The time-activity curve data from tac_roi()

    target

    The name of the receptor-rich region, e.g. "frontal"

    ref

    The reference region, e.g. "cerebellum"

    k2prime

    A fixed value for k2' must be specified (e.g. 0.2)

    t_star

    If 0, t* will be calculated using find_t_star()

    error

    For find_t_star()

    method

    Method of inntegration, "trapz" or "integrate"

    + +

    Value

    + +

    No return +f <- system.file("extdata", "AD06.tac", package="tacmagic") +fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") +AD06_tac <- load_tac(f, format="PMOD") +AD06_volume <- load_vol(fv, format="voistat") +AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), + merge=FALSE, PVC=FALSE)

    +

    plot_ref_Logan(AD06, target="frontal", ref="cerebellum", + k2prime=0.2, t_star=0)

    + +

    See also

    + +

    Other Logan plot functions: DVR_all_ref_Logan, + DVR_ref_Logan

    + + +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/plot_tac-1.png b/docs/reference/plot_tac-1.png new file mode 100644 index 0000000..5ff6023 Binary files /dev/null and b/docs/reference/plot_tac-1.png differ diff --git a/docs/reference/plot_tac.html b/docs/reference/plot_tac.html new file mode 100644 index 0000000..0667d3f --- /dev/null +++ b/docs/reference/plot_tac.html @@ -0,0 +1,207 @@ + + + + + + + + +Plots time activity curves from 1 or 2 participants or groups. — plot_tac • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Plots time activity curves from 1 or 2 participants or groups.

    + +
    + +
    plot_tac(TACtable1, TACtable2 = NULL, ROIs, ymax = 25,
    +  time = "minutes", title = "")
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TACtable1

    (e.g. from tac_roi() or load_tac())

    TACtable2

    An optional, second TAC, to plot for comparison

    ROIs

    A vector of ROIs to plot, names matching the TAC headers

    ymax

    The maximum value on the y-axis

    time

    "seconds" or "minutes" depending on desired x-axis, converts tac

    title

    A title for the plot

    + +

    Value

    + +

    Creates a plot

    + +

    See also

    + +

    Other tac functions: save_tac, + split_pvc, tac_roi

    + + +

    Examples

    +
    # f_raw_tac and f_raw_vol are the filenames of PMOD-generated files +f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") +f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") + +tac <- load_tac(f_raw_tac) +vol <- load_vol(f_raw_vol) +AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=FALSE, PVC=FALSE) +plot_tac(AD06_tac_nc, ROIs=c("frontal", "cerebellum"), title="Example Plot")
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/pos_anyroi.html b/docs/reference/pos_anyroi.html new file mode 100644 index 0000000..a13a862 --- /dev/null +++ b/docs/reference/pos_anyroi.html @@ -0,0 +1,196 @@ + + + + + + + + +Dichotomize participants based on ROI cutoff values — pos_anyroi • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Aizenstein et al. (2008) proposed a standardized method of calculating PIB+ +cutoff values to classify participants as PIB+ or PIB-. They used the DVR +from 7 ROIs associated with amyloid deposition. This function takes the +ROI-based cutoff values, e.g. from cutoff_aiz(), and returns a table +specifying which participants are positive, i.e. which have at least one ROI +greater than the cutoff.

    + +
    + +
    pos_anyroi(modelstats, cutoff)
    + +

    Arguments

    + + + + + + + + + + +
    modelstats

    SUVR or DVR data for group of participants from batch_tm()

    cutoff

    cutoffs for ROIs as from cutoff_aiz()

    + +

    Value

    + +

    data.frame of participants and positive/negative status

    + +

    References

    + +

    Aizenstein HJ, Nebes RD, Saxton JA, et al. 2008. Frequent amyloid +deposition without significant cognitive impairment among the elderly. +Arch Neurol 65: 1509-1517.

    + +

    See also

    + +

    Other Cutoff functions: cutoff_aiz

    + + +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/references.html b/docs/reference/references.html new file mode 100644 index 0000000..3f975f1 --- /dev/null +++ b/docs/reference/references.html @@ -0,0 +1,176 @@ + + + + + + + + +Print and return a list of references for this package. — references • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Print and return a list of references for this package.

    + +
    + +
    references()
    + +

    Value

    + +

    List of references.

    + + +

    Examples

    +
    references()
    #> $Aizenstein_2008 +#> [1] "# Aizenstein HJ, Nebes RD, Saxton JA, et al. 2008. Frequent amyloid \n\tdeposition without significant cognitive impairment among the elderly. \n\tArch Neurol 65: 1509-1517." +#> +#> $Hammers_2003 +#> [1] "Hammers, Alexander, Richard Allom, Matthias J. Koepp, Samantha L. Free, \n\tRalph Myers, Louis Lemieux, Tejal N. Mitchell, David J. Brooks, and John S. \n\tDuncan. 2003. Three-dimensional Maximum Probability Atlas of the Human \n\tBrain, with Particular Reference to the Temporal Lobe. Human Brain Mapping \n\t19 (4): 224-247. doi:10.1002/hbm.10123" +#> +#> $Klunk_2015 +#> [1] "Klunk W.E., Koeppe R.A., Price J.C., Benzinger T.L., \n Devous M.D., Sr., Jagust W.J., Johnson K.A., Mathis C.A., Minhas D., \n Pontecorvo M.J., Rowe C.C., Skovronsky D.M., Mintun M.A. The Centiloid \n Project: standardizing quantitative amyloid plaque estimation by PET. \n Alzheimers Dement. 2015;11" +#> +#> $Logan_1996 +#> [1] "Logan, J., Fowler, J. S., Volkow, N. D., Wang, G.-J., \n Ding, Y.-S., & Alexoff, D. L. (1996). Distribution Volume Ratios without \n Blood Sampling from Graphical Analysis of PET Data. Journal of Cerebral \n Blood Flow & Metabolism, 16(5), 834-840. \n https://doi.org/10.1097/00004647-199609000-00008" +#> +#> $magia +#> [1] "http://aivo.utu.fi/magia/" +#>
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/roi_ham_full.html b/docs/reference/roi_ham_full.html new file mode 100644 index 0000000..552e155 --- /dev/null +++ b/docs/reference/roi_ham_full.html @@ -0,0 +1,298 @@ + + + + + + + + +Return a list of larger ROIs made up of the ROIs in the Hammer's atlas. — roi_ham_full • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    This includes the cortical regions of roi_ham_stand() but also other regions. +It can be modified to suit the user's needs.

    + +
    + +
    roi_ham_full()
    + +

    Value

    + +

    A list of lists, where each list is an ROI (e.g.) frontal lobe that +specifies the atomic ROIs from the atlas that make it up.

    + +

    References

    + +

    Hammers, Alexander, Richard Allom, Matthias J. Koepp, Samantha L. Free, +Ralph Myers, Louis Lemieux, Tejal N. Mitchell, David J. Brooks, and John S. +Duncan. 2003. Three-dimensional Maximum Probability Atlas of the Human +Brain, with Particular Reference to the Temporal Lobe. Human Brain Mapping +19 (4): 224-247. doi:10.1002/hbm.10123

    + +

    See also

    + +

    Other ROI definitions: roi_ham_pib, + roi_ham_stand

    + + +

    Examples

    +
    roi_ham_full()
    #> $leftfrontal +#> [1] "FL_mid_fr_G_l" "FL_precen_G_l" "FL_strai_G_l" +#> [4] "FL_OFC_AOG_l" "FL_inf_fr_G_l" "FL_sup_fr_G_l" +#> [7] "FL_OFC_MOG_l" "FL_OFC_LOG_l" "FL_OFC_POG_l" +#> [10] "Subgen_antCing_l" "Subcall_area_l" "Presubgen_antCing_l" +#> +#> $rightfrontal +#> [1] "FL_mid_fr_G_r" "FL_precen_G_r" "FL_strai_G_r" +#> [4] "FL_OFC_AOG_r" "FL_inf_fr_G_r" "FL_sup_fr_G_r" +#> [7] "FL_OFC_MOG_r" "FL_OFC_LOG_r" "FL_OFC_POG_r" +#> [10] "Subgen_antCing_r" "Subcall_area_r" "Presubgen_antCing_r" +#> +#> $lefttemporal +#> [1] "Hippocampus_l" "Amygdala_l" "Ant_TL_med_l" +#> [4] "Ant_TL_inf_lat_l" "G_paraH_amb_l" "G_sup_temp_post_l" +#> [7] "G_tem_midin_l" "G_fus_l" "Post_TL_l" +#> [10] "G_sup_temp_ant_l" +#> +#> $righttemporal +#> [1] "Hippocampus_r" "Amygdala_r" "Ant_TL_med_r" +#> [4] "Ant_TL_inf_lat_r" "G_paraH_amb_r" "G_sup_temp_post_r" +#> [7] "G_tem_midin_r" "G_fus_r" "Post_TL_r" +#> [10] "G_sup_temp_ant_r" +#> +#> $leftparietal +#> [1] "PL_postce_G_l" "PL_sup_pa_G_l" "PL_rest_l" +#> +#> $rightparietal +#> [1] "PL_postce_G_r" "PL_sup_pa_G_r" "PL_rest_r" +#> +#> $leftoccipital +#> [1] "OL_rest_lat_l" "OL_ling_G_l" "OL_cuneus_l" +#> +#> $rightoccipital +#> [1] "OL_rest_lat_r" "OL_ling_G_r" "OL_cuneus_r" +#> +#> $leftcingulate +#> [1] "G_cing_ant_l" "G_cing_post_l" +#> +#> $rightcingulate +#> [1] "G_cing_ant_r" "G_cing_post_r" +#> +#> $frontal +#> [1] "FL_mid_fr_G_l" "FL_precen_G_l" "FL_strai_G_l" +#> [4] "FL_OFC_AOG_l" "FL_inf_fr_G_l" "FL_sup_fr_G_l" +#> [7] "FL_OFC_MOG_l" "FL_OFC_LOG_l" "FL_OFC_POG_l" +#> [10] "Subgen_antCing_l" "Subcall_area_l" "Presubgen_antCing_l" +#> [13] "FL_mid_fr_G_r" "FL_precen_G_r" "FL_strai_G_r" +#> [16] "FL_OFC_AOG_r" "FL_inf_fr_G_r" "FL_sup_fr_G_r" +#> [19] "FL_OFC_MOG_r" "FL_OFC_LOG_r" "FL_OFC_POG_r" +#> [22] "Subgen_antCing_r" "Subcall_area_r" "Presubgen_antCing_r" +#> +#> $temporal +#> [1] "Hippocampus_l" "Amygdala_l" "Ant_TL_med_l" +#> [4] "Ant_TL_inf_lat_l" "G_paraH_amb_l" "G_sup_temp_post_l" +#> [7] "G_tem_midin_l" "G_fus_l" "Post_TL_l" +#> [10] "G_sup_temp_ant_l" "Hippocampus_r" "Amygdala_r" +#> [13] "Ant_TL_med_r" "Ant_TL_inf_lat_r" "G_paraH_amb_r" +#> [16] "G_sup_temp_post_r" "G_tem_midin_r" "G_fus_r" +#> [19] "Post_TL_r" "G_sup_temp_ant_r" +#> +#> $parietal +#> [1] "PL_postce_G_l" "PL_sup_pa_G_l" "PL_rest_l" "PL_postce_G_r" +#> [5] "PL_sup_pa_G_r" "PL_rest_r" +#> +#> $occipital +#> [1] "OL_rest_lat_l" "OL_ling_G_l" "OL_cuneus_l" "OL_rest_lat_r" +#> [5] "OL_ling_G_r" "OL_cuneus_r" +#> +#> $cingulate +#> [1] "G_cing_ant_l" "G_cing_post_l" "G_cing_ant_r" "G_cing_post_r" +#> +#> $cerebellum +#> [1] "Cerebellum_l" "Cerebellum_r" +#> +#> $totalcortical +#> [1] "FL_mid_fr_G_l" "FL_precen_G_l" "FL_strai_G_l" +#> [4] "FL_OFC_AOG_l" "FL_inf_fr_G_l" "FL_sup_fr_G_l" +#> [7] "FL_OFC_MOG_l" "FL_OFC_LOG_l" "FL_OFC_POG_l" +#> [10] "Subgen_antCing_l" "Subcall_area_l" "Presubgen_antCing_l" +#> [13] "FL_mid_fr_G_r" "FL_precen_G_r" "FL_strai_G_r" +#> [16] "FL_OFC_AOG_r" "FL_inf_fr_G_r" "FL_sup_fr_G_r" +#> [19] "FL_OFC_MOG_r" "FL_OFC_LOG_r" "FL_OFC_POG_r" +#> [22] "Subgen_antCing_r" "Subcall_area_r" "Presubgen_antCing_r" +#> [25] "Hippocampus_l" "Amygdala_l" "Ant_TL_med_l" +#> [28] "Ant_TL_inf_lat_l" "G_paraH_amb_l" "G_sup_temp_post_l" +#> [31] "G_tem_midin_l" "G_fus_l" "Post_TL_l" +#> [34] "G_sup_temp_ant_l" "Hippocampus_r" "Amygdala_r" +#> [37] "Ant_TL_med_r" "Ant_TL_inf_lat_r" "G_paraH_amb_r" +#> [40] "G_sup_temp_post_r" "G_tem_midin_r" "G_fus_r" +#> [43] "Post_TL_r" "G_sup_temp_ant_r" "PL_postce_G_l" +#> [46] "PL_sup_pa_G_l" "PL_rest_l" "PL_postce_G_r" +#> [49] "PL_sup_pa_G_r" "PL_rest_r" "OL_rest_lat_l" +#> [52] "OL_ling_G_l" "OL_cuneus_l" "OL_rest_lat_r" +#> [55] "OL_ling_G_r" "OL_cuneus_r" "G_cing_ant_l" +#> [58] "G_cing_post_l" "G_cing_ant_r" "G_cing_post_r" +#> +#> $leftdeep +#> [1] "CaudateNucl_l" "NuclAccumb_l" "Putamen_l" "Thalamus_l" +#> [5] "Pallidum_l" +#> +#> $rightdeep +#> [1] "CaudateNucl_r" "NuclAccumb_r" "Putamen_r" "Thalamus_r" +#> [5] "Pallidum_r" +#> +#> $deep +#> [1] "CaudateNucl_l" "NuclAccumb_l" "Putamen_l" "Thalamus_l" +#> [5] "Pallidum_l" "CaudateNucl_r" "NuclAccumb_r" "Putamen_r" +#> [9] "Thalamus_r" "Pallidum_r" +#> +#> $ventricles +#> [1] "FrontalHorn_l" "FrontalHorn_r" "TemporaHorn_r" "TemporaHorn_l" +#> [5] "ThirdVentricl" +#> +#> $whitematter +#> [1] "White_matter_l" "White_matter_r" +#>
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/roi_ham_pib.html b/docs/reference/roi_ham_pib.html new file mode 100644 index 0000000..6f089c2 --- /dev/null +++ b/docs/reference/roi_ham_pib.html @@ -0,0 +1,312 @@ + + + + + + + + +Return a list of merged ROIs made up of atomic ROIs in the Hammer's atlas. — roi_ham_pib • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    This includes the ROIs from roi_ham_full and also the PIB cortical composite +ROI as defined in the PMOD documentation and as widely used in PIB studies. +See PMOD Neuro Tool (PNEURO) (Version 4.0) documentation.

    + +
    + +
    roi_ham_pib()
    + +

    Value

    + +

    A list of lists, where each list is an ROI (e.g.) frontal lobe that +specifies the atomic ROIs from the atlas that make it up.

    + +

    References

    + +

    Hammers, Alexander, Richard Allom, Matthias J. Koepp, Samantha L. Free, +Ralph Myers, Louis Lemieux, Tejal N. Mitchell, David J. Brooks, and John S. +Duncan. 2003. Three-dimensional Maximum Probability Atlas of the Human +Brain, with Particular Reference to the Temporal Lobe. Human Brain Mapping +19 (4): 224-247. doi:10.1002/hbm.10123

    + +

    See also

    + +

    Other ROI definitions: roi_ham_full, + roi_ham_stand

    + + +

    Examples

    +
    roi_ham_pib()
    #> $leftfrontal +#> [1] "FL_mid_fr_G_l" "FL_precen_G_l" "FL_strai_G_l" +#> [4] "FL_OFC_AOG_l" "FL_inf_fr_G_l" "FL_sup_fr_G_l" +#> [7] "FL_OFC_MOG_l" "FL_OFC_LOG_l" "FL_OFC_POG_l" +#> [10] "Subgen_antCing_l" "Subcall_area_l" "Presubgen_antCing_l" +#> +#> $rightfrontal +#> [1] "FL_mid_fr_G_r" "FL_precen_G_r" "FL_strai_G_r" +#> [4] "FL_OFC_AOG_r" "FL_inf_fr_G_r" "FL_sup_fr_G_r" +#> [7] "FL_OFC_MOG_r" "FL_OFC_LOG_r" "FL_OFC_POG_r" +#> [10] "Subgen_antCing_r" "Subcall_area_r" "Presubgen_antCing_r" +#> +#> $lefttemporal +#> [1] "Hippocampus_l" "Amygdala_l" "Ant_TL_med_l" +#> [4] "Ant_TL_inf_lat_l" "G_paraH_amb_l" "G_sup_temp_post_l" +#> [7] "G_tem_midin_l" "G_fus_l" "Post_TL_l" +#> [10] "G_sup_temp_ant_l" +#> +#> $righttemporal +#> [1] "Hippocampus_r" "Amygdala_r" "Ant_TL_med_r" +#> [4] "Ant_TL_inf_lat_r" "G_paraH_amb_r" "G_sup_temp_post_r" +#> [7] "G_tem_midin_r" "G_fus_r" "Post_TL_r" +#> [10] "G_sup_temp_ant_r" +#> +#> $leftparietal +#> [1] "PL_postce_G_l" "PL_sup_pa_G_l" "PL_rest_l" +#> +#> $rightparietal +#> [1] "PL_postce_G_r" "PL_sup_pa_G_r" "PL_rest_r" +#> +#> $leftoccipital +#> [1] "OL_rest_lat_l" "OL_ling_G_l" "OL_cuneus_l" +#> +#> $rightoccipital +#> [1] "OL_rest_lat_r" "OL_ling_G_r" "OL_cuneus_r" +#> +#> $leftcingulate +#> [1] "G_cing_ant_l" "G_cing_post_l" +#> +#> $rightcingulate +#> [1] "G_cing_ant_r" "G_cing_post_r" +#> +#> $frontal +#> [1] "FL_mid_fr_G_l" "FL_precen_G_l" "FL_strai_G_l" +#> [4] "FL_OFC_AOG_l" "FL_inf_fr_G_l" "FL_sup_fr_G_l" +#> [7] "FL_OFC_MOG_l" "FL_OFC_LOG_l" "FL_OFC_POG_l" +#> [10] "Subgen_antCing_l" "Subcall_area_l" "Presubgen_antCing_l" +#> [13] "FL_mid_fr_G_r" "FL_precen_G_r" "FL_strai_G_r" +#> [16] "FL_OFC_AOG_r" "FL_inf_fr_G_r" "FL_sup_fr_G_r" +#> [19] "FL_OFC_MOG_r" "FL_OFC_LOG_r" "FL_OFC_POG_r" +#> [22] "Subgen_antCing_r" "Subcall_area_r" "Presubgen_antCing_r" +#> +#> $temporal +#> [1] "Hippocampus_l" "Amygdala_l" "Ant_TL_med_l" +#> [4] "Ant_TL_inf_lat_l" "G_paraH_amb_l" "G_sup_temp_post_l" +#> [7] "G_tem_midin_l" "G_fus_l" "Post_TL_l" +#> [10] "G_sup_temp_ant_l" "Hippocampus_r" "Amygdala_r" +#> [13] "Ant_TL_med_r" "Ant_TL_inf_lat_r" "G_paraH_amb_r" +#> [16] "G_sup_temp_post_r" "G_tem_midin_r" "G_fus_r" +#> [19] "Post_TL_r" "G_sup_temp_ant_r" +#> +#> $parietal +#> [1] "PL_postce_G_l" "PL_sup_pa_G_l" "PL_rest_l" "PL_postce_G_r" +#> [5] "PL_sup_pa_G_r" "PL_rest_r" +#> +#> $occipital +#> [1] "OL_rest_lat_l" "OL_ling_G_l" "OL_cuneus_l" "OL_rest_lat_r" +#> [5] "OL_ling_G_r" "OL_cuneus_r" +#> +#> $cingulate +#> [1] "G_cing_ant_l" "G_cing_post_l" "G_cing_ant_r" "G_cing_post_r" +#> +#> $cerebellum +#> [1] "Cerebellum_l" "Cerebellum_r" +#> +#> $totalcortical +#> [1] "FL_mid_fr_G_l" "FL_precen_G_l" "FL_strai_G_l" +#> [4] "FL_OFC_AOG_l" "FL_inf_fr_G_l" "FL_sup_fr_G_l" +#> [7] "FL_OFC_MOG_l" "FL_OFC_LOG_l" "FL_OFC_POG_l" +#> [10] "Subgen_antCing_l" "Subcall_area_l" "Presubgen_antCing_l" +#> [13] "FL_mid_fr_G_r" "FL_precen_G_r" "FL_strai_G_r" +#> [16] "FL_OFC_AOG_r" "FL_inf_fr_G_r" "FL_sup_fr_G_r" +#> [19] "FL_OFC_MOG_r" "FL_OFC_LOG_r" "FL_OFC_POG_r" +#> [22] "Subgen_antCing_r" "Subcall_area_r" "Presubgen_antCing_r" +#> [25] "Hippocampus_l" "Amygdala_l" "Ant_TL_med_l" +#> [28] "Ant_TL_inf_lat_l" "G_paraH_amb_l" "G_sup_temp_post_l" +#> [31] "G_tem_midin_l" "G_fus_l" "Post_TL_l" +#> [34] "G_sup_temp_ant_l" "Hippocampus_r" "Amygdala_r" +#> [37] "Ant_TL_med_r" "Ant_TL_inf_lat_r" "G_paraH_amb_r" +#> [40] "G_sup_temp_post_r" "G_tem_midin_r" "G_fus_r" +#> [43] "Post_TL_r" "G_sup_temp_ant_r" "PL_postce_G_l" +#> [46] "PL_sup_pa_G_l" "PL_rest_l" "PL_postce_G_r" +#> [49] "PL_sup_pa_G_r" "PL_rest_r" "OL_rest_lat_l" +#> [52] "OL_ling_G_l" "OL_cuneus_l" "OL_rest_lat_r" +#> [55] "OL_ling_G_r" "OL_cuneus_r" "G_cing_ant_l" +#> [58] "G_cing_post_l" "G_cing_ant_r" "G_cing_post_r" +#> +#> $leftdeep +#> [1] "CaudateNucl_l" "NuclAccumb_l" "Putamen_l" "Thalamus_l" +#> [5] "Pallidum_l" +#> +#> $rightdeep +#> [1] "CaudateNucl_r" "NuclAccumb_r" "Putamen_r" "Thalamus_r" +#> [5] "Pallidum_r" +#> +#> $deep +#> [1] "CaudateNucl_l" "NuclAccumb_l" "Putamen_l" "Thalamus_l" +#> [5] "Pallidum_l" "CaudateNucl_r" "NuclAccumb_r" "Putamen_r" +#> [9] "Thalamus_r" "Pallidum_r" +#> +#> $ventricles +#> [1] "FrontalHorn_l" "FrontalHorn_r" "TemporaHorn_r" "TemporaHorn_l" +#> [5] "ThirdVentricl" +#> +#> $whitematter +#> [1] "White_matter_l" "White_matter_r" +#> +#> $amyloidcomp +#> [1] "FL_mid_fr_G_l" "FL_strai_G_l" "FL_sup_fr_G_l" +#> [4] "FL_OFC_MOG_l" "FL_OFC_LOG_l" "FL_OFC_POG_l" +#> [7] "Subgen_antCing_l" "Subcall_area_l" "G_sup_temp_post_l" +#> [10] "G_tem_midin_l" "G_sup_temp_ant_l" "PL_sup_pa_G_l" +#> [13] "PL_rest_l" "G_cing_ant_l" "G_cing_post_l" +#> [16] "FL_mid_fr_G_r" "FL_strai_G_r" "FL_sup_fr_G_r" +#> [19] "FL_OFC_MOG_r" "FL_OFC_LOG_r" "FL_OFC_POG_r" +#> [22] "Subgen_antCing_r" "Subcall_area_r" "G_sup_temp_post_r" +#> [25] "G_tem_midin_r" "G_sup_temp_ant_r" "PL_sup_pa_G_r" +#> [28] "PL_rest_r" "G_cing_ant_r" "G_cing_post_r" +#>
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/roi_ham_stand.html b/docs/reference/roi_ham_stand.html new file mode 100644 index 0000000..843fb04 --- /dev/null +++ b/docs/reference/roi_ham_stand.html @@ -0,0 +1,281 @@ + + + + + + + + +Return a list of merged ROIs made up of the atomic ROIs in the Hammer's +atlas. — roi_ham_stand • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Return a list of merged ROIs made up of the atomic ROIs in the Hammer's +atlas.

    + +
    + +
    roi_ham_stand()
    + +

    Value

    + +

    A list of lists, where each list is an ROI (e.g.) frontal lobe that +specifies the atomic ROIs from the atlas that make it up.

    + +

    References

    + +

    Hammers, Alexander, Richard Allom, Matthias J. Koepp, Samantha L. Free, +Ralph Myers, Louis Lemieux, Tejal N. Mitchell, David J. Brooks, and John S. +Duncan. 2003. Three-dimensional Maximum Probability Atlas of the Human +Brain, with Particular Reference to the Temporal Lobe. Human Brain Mapping +19 (4): 224-247. doi:10.1002/hbm.10123

    + +

    See also

    + +

    Other ROI definitions: roi_ham_full, + roi_ham_pib

    + + +

    Examples

    +
    roi_ham_stand()
    #> $leftfrontal +#> [1] "FL_mid_fr_G_l" "FL_precen_G_l" "FL_strai_G_l" +#> [4] "FL_OFC_AOG_l" "FL_inf_fr_G_l" "FL_sup_fr_G_l" +#> [7] "FL_OFC_MOG_l" "FL_OFC_LOG_l" "FL_OFC_POG_l" +#> [10] "Subgen_antCing_l" "Subcall_area_l" "Presubgen_antCing_l" +#> +#> $rightfrontal +#> [1] "FL_mid_fr_G_r" "FL_precen_G_r" "FL_strai_G_r" +#> [4] "FL_OFC_AOG_r" "FL_inf_fr_G_r" "FL_sup_fr_G_r" +#> [7] "FL_OFC_MOG_r" "FL_OFC_LOG_r" "FL_OFC_POG_r" +#> [10] "Subgen_antCing_r" "Subcall_area_r" "Presubgen_antCing_r" +#> +#> $lefttemporal +#> [1] "Hippocampus_l" "Amygdala_l" "Ant_TL_med_l" +#> [4] "Ant_TL_inf_lat_l" "G_paraH_amb_l" "G_sup_temp_post_l" +#> [7] "G_tem_midin_l" "G_fus_l" "Post_TL_l" +#> [10] "G_sup_temp_ant_l" +#> +#> $righttemporal +#> [1] "Hippocampus_r" "Amygdala_r" "Ant_TL_med_r" +#> [4] "Ant_TL_inf_lat_r" "G_paraH_amb_r" "G_sup_temp_post_r" +#> [7] "G_tem_midin_r" "G_fus_r" "Post_TL_r" +#> [10] "G_sup_temp_ant_r" +#> +#> $leftparietal +#> [1] "PL_postce_G_l" "PL_sup_pa_G_l" "PL_rest_l" +#> +#> $rightparietal +#> [1] "PL_postce_G_r" "PL_sup_pa_G_r" "PL_rest_r" +#> +#> $leftoccipital +#> [1] "OL_rest_lat_l" "OL_ling_G_l" "OL_cuneus_l" +#> +#> $rightoccipital +#> [1] "OL_rest_lat_r" "OL_ling_G_r" "OL_cuneus_r" +#> +#> $leftcingulate +#> [1] "G_cing_ant_l" "G_cing_post_l" +#> +#> $rightcingulate +#> [1] "G_cing_ant_r" "G_cing_post_r" +#> +#> $frontal +#> [1] "FL_mid_fr_G_l" "FL_precen_G_l" "FL_strai_G_l" +#> [4] "FL_OFC_AOG_l" "FL_inf_fr_G_l" "FL_sup_fr_G_l" +#> [7] "FL_OFC_MOG_l" "FL_OFC_LOG_l" "FL_OFC_POG_l" +#> [10] "Subgen_antCing_l" "Subcall_area_l" "Presubgen_antCing_l" +#> [13] "FL_mid_fr_G_r" "FL_precen_G_r" "FL_strai_G_r" +#> [16] "FL_OFC_AOG_r" "FL_inf_fr_G_r" "FL_sup_fr_G_r" +#> [19] "FL_OFC_MOG_r" "FL_OFC_LOG_r" "FL_OFC_POG_r" +#> [22] "Subgen_antCing_r" "Subcall_area_r" "Presubgen_antCing_r" +#> +#> $temporal +#> [1] "Hippocampus_l" "Amygdala_l" "Ant_TL_med_l" +#> [4] "Ant_TL_inf_lat_l" "G_paraH_amb_l" "G_sup_temp_post_l" +#> [7] "G_tem_midin_l" "G_fus_l" "Post_TL_l" +#> [10] "G_sup_temp_ant_l" "Hippocampus_r" "Amygdala_r" +#> [13] "Ant_TL_med_r" "Ant_TL_inf_lat_r" "G_paraH_amb_r" +#> [16] "G_sup_temp_post_r" "G_tem_midin_r" "G_fus_r" +#> [19] "Post_TL_r" "G_sup_temp_ant_r" +#> +#> $parietal +#> [1] "PL_postce_G_l" "PL_sup_pa_G_l" "PL_rest_l" "PL_postce_G_r" +#> [5] "PL_sup_pa_G_r" "PL_rest_r" +#> +#> $occipital +#> [1] "OL_rest_lat_l" "OL_ling_G_l" "OL_cuneus_l" "OL_rest_lat_r" +#> [5] "OL_ling_G_r" "OL_cuneus_r" +#> +#> $cingulate +#> [1] "G_cing_ant_l" "G_cing_post_l" "G_cing_ant_r" "G_cing_post_r" +#> +#> $cerebellum +#> [1] "Cerebellum_l" "Cerebellum_r" +#> +#> $totalcortical +#> [1] "FL_mid_fr_G_l" "FL_precen_G_l" "FL_strai_G_l" +#> [4] "FL_OFC_AOG_l" "FL_inf_fr_G_l" "FL_sup_fr_G_l" +#> [7] "FL_OFC_MOG_l" "FL_OFC_LOG_l" "FL_OFC_POG_l" +#> [10] "Subgen_antCing_l" "Subcall_area_l" "Presubgen_antCing_l" +#> [13] "FL_mid_fr_G_r" "FL_precen_G_r" "FL_strai_G_r" +#> [16] "FL_OFC_AOG_r" "FL_inf_fr_G_r" "FL_sup_fr_G_r" +#> [19] "FL_OFC_MOG_r" "FL_OFC_LOG_r" "FL_OFC_POG_r" +#> [22] "Subgen_antCing_r" "Subcall_area_r" "Presubgen_antCing_r" +#> [25] "Hippocampus_l" "Amygdala_l" "Ant_TL_med_l" +#> [28] "Ant_TL_inf_lat_l" "G_paraH_amb_l" "G_sup_temp_post_l" +#> [31] "G_tem_midin_l" "G_fus_l" "Post_TL_l" +#> [34] "G_sup_temp_ant_l" "Hippocampus_r" "Amygdala_r" +#> [37] "Ant_TL_med_r" "Ant_TL_inf_lat_r" "G_paraH_amb_r" +#> [40] "G_sup_temp_post_r" "G_tem_midin_r" "G_fus_r" +#> [43] "Post_TL_r" "G_sup_temp_ant_r" "PL_postce_G_l" +#> [46] "PL_sup_pa_G_l" "PL_rest_l" "PL_postce_G_r" +#> [49] "PL_sup_pa_G_r" "PL_rest_r" "OL_rest_lat_l" +#> [52] "OL_ling_G_l" "OL_cuneus_l" "OL_rest_lat_r" +#> [55] "OL_ling_G_r" "OL_cuneus_r" "G_cing_ant_l" +#> [58] "G_cing_post_l" "G_cing_ant_r" "G_cing_post_r" +#>
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/save_tac.html b/docs/reference/save_tac.html new file mode 100644 index 0000000..37319da --- /dev/null +++ b/docs/reference/save_tac.html @@ -0,0 +1,183 @@ + + + + + + + + +Save a tac object as a .tac file — save_tac • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Saves a tac object, created by load_tac(), tac_roi() or manually, and +saves it as a PMOD-formatted tac file. Using the .tac extension in the +file name is recommended.

    + +
    + +
    save_tac(tac, outfile)
    + +

    Arguments

    + + + + + + + + + + +
    tac

    The time-activity curve data, e.g. from load_tac() or tac_roi()

    outfile

    The output filename

    + +

    Value

    + +

    Does not return an object, only saves a file

    + +

    See also

    + +

    Other tac functions: plot.tac, + split_pvc, tac_roi

    + + +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/split_pvc.html b/docs/reference/split_pvc.html new file mode 100644 index 0000000..4b889e0 --- /dev/null +++ b/docs/reference/split_pvc.html @@ -0,0 +1,196 @@ + + + + + + + + +Subset PMOD tacs with or without PVC — split_pvc • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    When partial volume correction (PVC) is used in PMOD, the saved tac files +have ROIs with and without PVC. When loaded with load_tac()) it may be +desirable to keep only either the PVC or non-PVC tacs. This returns a tac +object that is a subset of the input tac object with only the PVC or non-PVC +tacs. This relies on PMOD's convention of labelling tac columns with "_C".

    + +
    + +
    split_pvc(tac, PVC = TRUE)
    + +

    Arguments

    + + + + + + + + + + +
    tac

    The time-activity curve data from loading function (PMOD)

    PVC

    If TRUE, includes columns with "_C", if FALSE, ones without "_C"

    + +

    Value

    + +

    Time-activity curve object

    + +

    See also

    + +

    Other tac functions: plot.tac, + save_tac, tac_roi

    + + +

    Examples

    +
    # f_raw_tac and f_raw_vol are the filenames of PMOD-generated files +f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") + +tac <- load_tac(f_raw_tac) +tac_pvc <- split_pvc(tac, TRUE) +tac_nc <- split_pvc(tac, FALSE)
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/suvr.html b/docs/reference/suvr.html new file mode 100644 index 0000000..4d2feda --- /dev/null +++ b/docs/reference/suvr.html @@ -0,0 +1,199 @@ + + + + + + + + +Calculate weighted SUVRs for specified regions of interest — suvr • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Calculate the standardized uptake value ratio (SUVR) for all ROIs in the +provided tac data, using the specified reference region.

    + +
    + +
    suvr(tac, SUVR_def, ref, ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + +
    tac

    The time-activity curve data from tac_roi()

    SUVR_def

    a vector of start times for window to be used in SUVR

    ref

    a string, e.g. "cerebellum", to specify reference region

    ...

    When called from tm_batch, unused parameters may be supplied

    + +

    Value

    + +

    A data.frame of SUVR values for the specified ROIs

    + +

    See also

    + +

    Other SUVR functions: suvr_auc

    + + +

    Examples

    +
    f <- system.file("extdata", "AD06.tac", package="tacmagic") +fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") +AD06_tac <- load_tac(f, format="PMOD") +AD06_volume <- load_vol(fv, format="voistat") +AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), + merge=FALSE, PVC=FALSE) + +AD06_SUVR <- suvr(AD06, SUVR_def=c(3000,3300,3600), ref="cerebellum")
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/suvr_auc.html b/docs/reference/suvr_auc.html new file mode 100644 index 0000000..b4b26f4 --- /dev/null +++ b/docs/reference/suvr_auc.html @@ -0,0 +1,197 @@ + + + + + + + + +Calculate SUVRs for regions of interest with AUC from mid-frame times — suvr_auc • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Calculate the standardized uptake value ratio (SUVR) for all ROIs in the +provided tac data, using the specified reference region. This is an +alternate to suvr() which should provide very similar values.

    + +
    + +
    suvr_auc(tac, SUVR_def, ref, ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + +
    tac

    The time-activity curve data from tac_roi()

    SUVR_def

    a vector of start times for window to be used in SUVR

    ref

    is a string, e.g. "cerebellum", to specify reference region

    ...

    When called from tm_batch, unused parameters may be supplied

    + +

    Value

    + +

    A data.frame of SUVR values for the specified ROIs +#' f <- system.file("extdata", "AD06.tac", package="tacmagic") +fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") +AD06_tac <- load_tac(f, format="PMOD") +AD06_volume <- load_vol(fv, format="voistat") +AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), + merge=FALSE, PVC=FALSE)

    +

    AD06_SUVR <- suvr_auc(AD06, SUVR_def=c(3000,3300,3600), ref="cerebellum")

    + +

    See also

    + +

    Other SUVR functions: suvr

    + + +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/tac_roi.html b/docs/reference/tac_roi.html new file mode 100644 index 0000000..96eba4b --- /dev/null +++ b/docs/reference/tac_roi.html @@ -0,0 +1,201 @@ + + + + + + + + +Calculate weighted time-activity curves for specified regions of interest — tac_roi • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Calculate weighted time-activity curves for specified regions of interest

    + +
    + +
    tac_roi(tac, volumes, ROI_def, merge, PVC)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + +
    tac

    The time-activity curve data from loading function

    volumes

    The ROI volume data from loading function

    ROI_def

    The definition of ROIs by combining smaller ROIs from TAC file

    merge

    If TRUE, includes the original ROIs in the output data

    PVC

    If TRUE, appends "_C" to ROI name header (as in PMOD TAC files)

    + +

    Value

    + +

    Time-activity curves for the specified ROIs

    + +

    See also

    + +

    Other tac functions: plot.tac, + save_tac, split_pvc

    + + +

    Examples

    +
    # f_raw_tac and f_raw_vol are the filenames of PMOD-generated files +f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") +f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") + +tac <- load_tac(f_raw_tac) +vol <- load_vol(f_raw_vol) +AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=FALSE, PVC=FALSE)
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown 1.3.0.

    +
    +
    +
    + + + + + + diff --git a/docs/reference/tacmagic.html b/docs/reference/tacmagic.html new file mode 100644 index 0000000..5297ed7 --- /dev/null +++ b/docs/reference/tacmagic.html @@ -0,0 +1,157 @@ + + + + + + + + +tacmagic: PET Analysis in R — tacmagic • tacmagic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    The main features of tacmagic are to load PET time activity curve (tac) data +from multiple formats, merge ROIs weighted for volume, calculate binding +potential models including SUVR and DVR, basic plotting, and calculation of +cut-off values. Please see the walkthrough vignette for a detailed overview.

    + +
    + + + +
    + +
    + + +
    + + + + + + diff --git a/man/DVR_all_ref_Logan.Rd b/man/DVR_all_ref_Logan.Rd index 93205fd..4775025 100644 --- a/man/DVR_all_ref_Logan.Rd +++ b/man/DVR_all_ref_Logan.Rd @@ -4,8 +4,8 @@ \alias{DVR_all_ref_Logan} \title{Non-invasive reference Logan method for all ROIs in tac data} \usage{ -DVR_all_ref_Logan(tac_data, ref = NULL, k2prime = NULL, - t_star = NULL, error = 0.1, method = "trapz", params = NULL) +DVR_all_ref_Logan(tac_data, ref, k2prime, t_star, error = 0.1, + method = "trapz", ...) } \arguments{ \item{tac_data}{The time-activity curve data from tac_roi()} @@ -18,13 +18,12 @@ DVR_all_ref_Logan(tac_data, ref = NULL, k2prime = NULL, \item{error}{For find_t_star()} -\item{method}{Method of inntegration, "trapz" or "integrate"} +\item{method}{Method of integration, "trapz" or "integrate"} -\item{params}{Used by batch_tm (not for calling individually) to pass model -parameters} +\item{...}{When called from tm_batch, unused parameters may be supplied} } \value{ -Data frame with calculate DVRs for all ROIs +Data frame with calculated DVRs for all ROIs } \description{ This calculates the DVR using the non-invasive reference Logan method for @@ -40,9 +39,16 @@ AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), AD06_DVR <- DVR_all_ref_Logan(AD06, ref="cerebellum", k2prime=0.2, t_star=23) +} +\references{ +Logan, J., Fowler, J. S., Volkow, N. D., Wang, G.-J., +Ding, Y.-S., & Alexoff, D. L. (1996). Distribution Volume Ratios without +Blood Sampling from Graphical Analysis of PET Data. Journal of Cerebral +Blood Flow & Metabolism, 16(5), 834-840. +https://doi.org/10.1097/00004647-199609000-00008 } \seealso{ Other Logan plot functions: \code{\link{DVR_ref_Logan}}, - \code{\link{plot_ref_Logan}} + \code{\link{dvr}}, \code{\link{plot.ref_Logan}} } \concept{Logan plot functions} diff --git a/man/DVR_ref_Logan.Rd b/man/DVR_ref_Logan.Rd index 76270f8..b906ceb 100644 --- a/man/DVR_ref_Logan.Rd +++ b/man/DVR_ref_Logan.Rd @@ -20,7 +20,7 @@ DVR_ref_Logan(tac_data, target, ref, k2prime, t_star, error = 0.1, \item{error}{For find_t_star()} -\item{method}{Method of inntegration, "trapz" or "integrate"} +\item{method}{Method of integration, "trapz" or "integrate"} } \value{ Data frame with calculate DVRs for all ROIs @@ -40,9 +40,16 @@ AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), AD06_DVR_fr <- DVR_ref_Logan(AD06, target="frontal", ref="cerebellum", k2prime=0.2, t_star=0) +} +\references{ +Logan, J., Fowler, J. S., Volkow, N. D., Wang, G.-J., +Ding, Y.-S., & Alexoff, D. L. (1996). Distribution Volume Ratios without +Blood Sampling from Graphical Analysis of PET Data. Journal of Cerebral +Blood Flow & Metabolism, 16(5), 834-840. +https://doi.org/10.1097/00004647-199609000-00008 } \seealso{ Other Logan plot functions: \code{\link{DVR_all_ref_Logan}}, - \code{\link{plot_ref_Logan}} + \code{\link{dvr}}, \code{\link{plot.ref_Logan}} } \concept{Logan plot functions} diff --git a/man/as.tac.Rd b/man/as.tac.Rd new file mode 100644 index 0000000..1175eac --- /dev/null +++ b/man/as.tac.Rd @@ -0,0 +1,40 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tac_methods.R +\name{as.tac} +\alias{as.tac} +\title{Creates a tac object from a data.frame} +\usage{ +as.tac(x, time_unit = NULL, activity_unit = NULL) +} +\arguments{ +\item{x}{data.frame with start, end time and tac data} + +\item{time_unit}{NULL if in data.frame or set to "seconds" or "minutes"} + +\item{activity_unit}{NULL if in data.frame or set to "kBq/cc", "Bq/cc", +"nCi/cc"} +} +\value{ +tac object +} +\description{ +tac objects can be created from data.frame objects with `as.tac()`. The time +and activity units must be specified as arguments if not already set as +attributes in the data.frame. The columns of the data frame are the regional +time activity curves, with the column names the names of the ROIs. +} +\details{ +If the time_unit and activity_unit attributes are already in the data.frame, +they do not need to be set again, but otherwise they will need to be +specified in the input parameters. +} +\examples{ +manual <- data.frame(start=c(0:4), end=c(2:6), + ROI1=c(10.1:14.2), ROI2=c(11:15)) +manual_tac <- as.tac(manual, time_unit="minutes", activity_unit="kBq/cc") +} +\seealso{ +Other Loading functions: \code{\link{load_tac}}, + \code{\link{load_voistat}}, \code{\link{load_vol}} +} +\concept{Loading functions} diff --git a/man/batch_load.Rd b/man/batch_load.Rd index 6bc94ce..71fe0b4 100644 --- a/man/batch_load.Rd +++ b/man/batch_load.Rd @@ -4,22 +4,24 @@ \alias{batch_load} \title{Load (+/- merge) ROIs for batch of participants} \usage{ -batch_load(participants, PVC = FALSE, dir = "", tac_format = "PMOD", - tac_file_suffix = ".tac", roi_m = FALSE, vol_file_suffix = NULL, - vol_format = NULL, merge = NULL, ROI_def = NULL) +batch_load(participants, dir = "", tac_file_suffix = ".tac", + tac_format = "PMOD", roi_m = FALSE, PVC = NULL, + vol_file_suffix = NULL, vol_format = NULL, merge = NULL, + ROI_def = NULL) } \arguments{ \item{participants}{A vector of participant IDs} -\item{PVC}{For PVC, true where the data is stored as _C in same tac file} - \item{dir}{A directory and/or file name prefix for the tac/volume files} +\item{tac_file_suffix}{How participant IDs corresponds to the TAC files} + \item{tac_format}{Format of tac files provided: See load_tac()} -\item{tac_file_suffix}{How participant IDs corresponds to the TAC files} +\item{roi_m}{TRUE if you want to merge atomic ROIs into larger ROIs (and if +not, the following parameters are not used)} -\item{roi_m}{T if you want to merge atomic ROIs into larger ROIs} +\item{PVC}{For PVC, true where the data is stored as _C in same tac file} \item{vol_file_suffix}{How participant IDs correspond to volume files} diff --git a/man/batch_tm.Rd b/man/batch_tm.Rd index aab8651..2cf3068 100644 --- a/man/batch_tm.Rd +++ b/man/batch_tm.Rd @@ -4,26 +4,17 @@ \alias{batch_tm} \title{Calculate one or more models for a batch of participants} \usage{ -batch_tm(all_tacs, models = c("SUVR", "Logan"), ref, SUVR_def = NULL, - k2prime = NULL, t_star = NULL, custom_model = NULL, - custom_params = NULL) +batch_tm(all_tacs, models, custom_model = NULL, ...) } \arguments{ \item{all_tacs}{A list by participant, of tac data (load_batch())} \item{models}{A vector of names of the models to calculate} -\item{ref}{The name of the reference region for DVR/SUVR calculation} - -\item{SUVR_def}{is a vector of the start times for window to be used in SUVR} - -\item{k2prime}{Fixed k2' for DVR calculation} - -\item{t_star}{Change from 0 to manually specify a t* for DVR calculation} - \item{custom_model}{A function that can be run like other models (advanced)} -\item{custom_params}{To pass to custom_model as params$custom_params} +\item{...}{The arguments that get passed to the specified models/custom model, +many are required; please check with model desired.} } \value{ A table of SUVR values for the specified ROIs for all participants @@ -43,7 +34,9 @@ participants <- c(system.file("extdata", "AD06.tac", package="tacmagic"), system.file("extdata", "AD08.tac", package="tacmagic")) tacs <- batch_load(participants, tac_file_suffix="") -for (i in 1:3) tacs[[i]][,1:80] # to remove the PVC values for this example + +# Keeps only the ROIs without partial-volume correction (PMOD convention) +tacs <- lapply(tacs, split_pvc, FALSE) batch <- batch_tm(tacs, models=c("SUVR", "Logan"), ref="Cerebellum_r", SUVR_def=c(3000,3300,3600), k2prime=0.2, t_star=23) diff --git a/man/batch_voistat.Rd b/man/batch_voistat.Rd index de400bc..9e30066 100644 --- a/man/batch_voistat.Rd +++ b/man/batch_voistat.Rd @@ -16,7 +16,7 @@ batch_voistat(participants, ROI_def, dir = "", filesuffix = ".voistat", \item{filesuffix}{Optional filename characters between ID and ".voistat"} -\item{varname}{The name of the variable being exctracted, e.g. "SRTM"} +\item{varname}{The name of the variable being extracted, e.g. "SRTM"} } \value{ A table of values for the specified ROIs for all participants diff --git a/man/cutoff_aiz.Rd b/man/cutoff_aiz.Rd index 5c9539a..f6ec4f3 100644 --- a/man/cutoff_aiz.Rd +++ b/man/cutoff_aiz.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/cutoff.R \name{cutoff_aiz} \alias{cutoff_aiz} -\title{Cutoff value caluclation using method described in Aizenstein et al. 2008} +\title{Cutoff value calculation using method described in Aizenstein et al. 2008} \usage{ cutoff_aiz(modelstats, ROIs) } @@ -15,15 +15,17 @@ cutoff_aiz(modelstats, ROIs) Cutoff values for each ROI based on the above method } \description{ -See references()$Aizenstein. The authors proposed a standardized method of -calculating PIB+ cutoff values to classify participants as PIB+ or PIB-. They -used the DVR from several ROIs associated with amyloid deposition. The steps -are summarized below. cutoff_aiz() implements 1-3, returning cutoff values -for each ROI. It can be used to dichotomize participants, with pos_anyroi(). +See the reference below and the tacmagic walkthrough vignette. Aizenstein et +al. (2008) proposed a standardized method of calculating Pittsburg Compound +B (PIB) cutoff values to classify participants as PIB+ or PIB-. They used the +distribution volume ratio (DVR) from several ROIs associated with amyloid +deposition. The steps are summarized below. cutoff_aiz() implements 1-3, +returning cutoff valuesfor each ROI. It can be used to dichotomize +participants, with pos_anyroi(). } \details{ 1. Remove outliers from a group of cognitively normal individuals. An outlier -is defined as having any ROI with DVR > upper inner fence of that ROI (= 3rd +is defined as having any ROI with DVR > upper inner fence of that ROI (= 3rd quartile + (1.5 * IQR). 2. Iterate step 1 as needed until there are no more outlying participants. 3. From this subset of the group with outliers removed, the cutoff value for @@ -31,6 +33,14 @@ each ROI is set as the upper inner fence. 4. For all participants, if there is any ROI above the cutoff for that region, then the participant is deemed to be PIB+. } +\examples{ +cutoff_aiz(fake_DVR, c("ROI1_DVR", "ROI2_DVR", "ROI3_DVR", "ROI4_DVR")) +} +\references{ +Aizenstein HJ, Nebes RD, Saxton JA, et al. 2008. Frequent amyloid +deposition without significant cognitive impairment among the elderly. +Arch Neurol 65: 1509-1517. +} \seealso{ Other Cutoff functions: \code{\link{pos_anyroi}} } diff --git a/man/dvr.Rd b/man/dvr.Rd new file mode 100644 index 0000000..15f0959 --- /dev/null +++ b/man/dvr.Rd @@ -0,0 +1,62 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/dvr.R +\name{dvr} +\alias{dvr} +\title{Distribution volume ratio (DVR) for one or more ROIs} +\usage{ +dvr(tac, model = "logan", target = NULL, ref, k2prime, t_star, + error = 0.1, method = "trapz") +} +\arguments{ +\item{tac}{The time-activity curve data from load_tac() or tac_roi()} + +\item{model}{Only model currently available is "logan"} + +\item{target}{Optional - otherwise will calculate DVR for all regions} + +\item{ref}{Required -- The reference region, e.g. "cerebellum"} + +\item{k2prime}{Required -- A fixed value for k2' must be specified (e.g. 0.2)} + +\item{t_star}{Required -- If 0, t* will be calculated using find_t_star()} + +\item{error}{For find_t_star()} + +\item{method}{Method of integration, "trapz" or "integrate"} +} +\value{ +Data frame with calculated DVRs +} +\description{ +This calculates the DVR using the non-invasive reference Logan method for +all TACs in a supplied tac file. It uses DVR_ref_Logan if a target ROI is +specified, otherwise will calculate DVR for all ROIs with DVR_ref_all_Logan() +} +\details{ +For other model paramters, directly call DVR_ref_Logan(). +} +\examples{ +f <- system.file("extdata", "AD06.tac", package="tacmagic") +fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") +AD06_tac <- load_tac(f, format="PMOD") +AD06_volume <- load_vol(fv, format="voistat") +AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), + merge=FALSE, PVC=FALSE) + +AD06_DVRs <- dvr(AD06, ref="cerebellum", k2prime=0.2, t_star=23) + +AD06_DVR <- dvr(AD06, target="frontal", ref="cerebellum", + k2prime=0.2, t_star=23) +} +\references{ +Logan, J., Fowler, J. S., Volkow, N. D., Wang, G.-J., +Ding, Y.-S., & Alexoff, D. L. (1996). Distribution Volume Ratios without +Blood Sampling from Graphical Analysis of PET Data. Journal of Cerebral +Blood Flow & Metabolism, 16(5), 834-840. +https://doi.org/10.1097/00004647-199609000-00008 +} +\seealso{ +Other Logan plot functions: \code{\link{DVR_all_ref_Logan}}, + \code{\link{DVR_ref_Logan}}, \code{\link{plot.ref_Logan}} +} +\concept{Logan plot functions} diff --git a/man/load_tac.Rd b/man/load_tac.Rd index 108b8b9..a39d735 100644 --- a/man/load_tac.Rd +++ b/man/load_tac.Rd @@ -22,7 +22,7 @@ format="voistat"} "Bq/cc", "nCi/cc"} } \value{ -data.frame with loaded TAC data +tac object } \description{ This is the main function for loading an individual participant's TAC data. @@ -35,7 +35,7 @@ supported formats (with the corresponding format argument), include: \item "voistat": PMOD TAC .voistat files used in combination with PMOD .acqtimes file for start/stop times. \item "magia": magia pipeline .mat tac file - \item "DFF": Turku PET Centre's DFT format + \item "DFT": Turku PET Centre's DFT format } } \examples{ @@ -44,7 +44,7 @@ tac <- load_tac(f_raw_tac) } \seealso{ -Other Loading functions: \code{\link{load_voistat}}, - \code{\link{load_vol}} +Other Loading functions: \code{\link{as.tac}}, + \code{\link{load_voistat}}, \code{\link{load_vol}} } \concept{Loading functions} diff --git a/man/load_voistat.Rd b/man/load_voistat.Rd index be72b42..befb6c1 100644 --- a/man/load_voistat.Rd +++ b/man/load_voistat.Rd @@ -29,7 +29,7 @@ f <- system.file("extdata", "AD06_BPnd_BPnd_Logan.voistat", vs <- load_voistat(f, ROI_def=roi_ham_pib(), model="Logan") } \seealso{ -Other Loading functions: \code{\link{load_tac}}, - \code{\link{load_vol}} +Other Loading functions: \code{\link{as.tac}}, + \code{\link{load_tac}}, \code{\link{load_vol}} } \concept{Loading functions} diff --git a/man/load_vol.Rd b/man/load_vol.Rd index 21018f7..a80fdd5 100644 --- a/man/load_vol.Rd +++ b/man/load_vol.Rd @@ -24,7 +24,7 @@ f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") vol <- load_vol(f_raw_vol) } \seealso{ -Other Loading functions: \code{\link{load_tac}}, - \code{\link{load_voistat}} +Other Loading functions: \code{\link{as.tac}}, + \code{\link{load_tac}}, \code{\link{load_voistat}} } \concept{Loading functions} diff --git a/man/plot.ref_Logan.Rd b/man/plot.ref_Logan.Rd new file mode 100644 index 0000000..3868c12 --- /dev/null +++ b/man/plot.ref_Logan.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plot.R +\name{plot.ref_Logan} +\alias{plot.ref_Logan} +\title{Non-invasive reference Logan plot} +\usage{ +\method{plot}{ref_Logan}(x, ...) +} +\arguments{ +\item{x}{Reference Logan model data object from DVR_ref_Logan()} + +\item{...}{Additional parameters than can be passed to plotting function} +} +\value{ +No return +f <- system.file("extdata", "AD06.tac", package="tacmagic") +fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") +AD06_tac <- load_tac(f, format="PMOD") +AD06_volume <- load_vol(fv, format="voistat") +AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), + merge=FALSE, PVC=FALSE) +AD06_DVR_fr <- DVR_ref_Logan(AD06, target="frontal", ref="cerebellum", + k2prime=0.2, t_star=0) +plot(AD06_DVR_fr) +} +\description{ +This plots the non-invasive Logan plot. +} +\seealso{ +Other Logan plot functions: \code{\link{DVR_all_ref_Logan}}, + \code{\link{DVR_ref_Logan}}, \code{\link{dvr}} +} +\concept{Logan plot functions} diff --git a/man/plot_tac.Rd b/man/plot.tac.Rd similarity index 58% rename from man/plot_tac.Rd rename to man/plot.tac.Rd index 1e78519..c4515d0 100644 --- a/man/plot_tac.Rd +++ b/man/plot.tac.Rd @@ -1,16 +1,17 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tac.R -\name{plot_tac} -\alias{plot_tac} +% Please edit documentation in R/plot.R +\name{plot.tac} +\alias{plot.tac} \title{Plots time activity curves from 1 or 2 participants or groups.} \usage{ -plot_tac(TACtable1, TACtable2 = NULL, ROIs, ymax = 25, - time = "minutes", title = "") +\method{plot}{tac}(x, tac2 = NULL, ROIs, ymax = 25, time = "minutes", + title = "", colors = rainbow, ...) } \arguments{ -\item{TACtable1}{(e.g. from tac_roi() or load_tac())} +\item{x}{A tac object containing time-activity curves to plot, e.g. from +tac_roi() or load_tac()} -\item{TACtable2}{An optional, second TAC, to plot for comparison} +\item{tac2}{An optional, second TAC, to plot for comparison} \item{ROIs}{A vector of ROIs to plot, names matching the TAC headers} @@ -19,6 +20,11 @@ plot_tac(TACtable1, TACtable2 = NULL, ROIs, ymax = 25, \item{time}{"seconds" or "minutes" depending on desired x-axis, converts tac} \item{title}{A title for the plot} + +\item{colors}{If null, rainbow palette is used, otherwise another palette can +be specified (heat.colors, terrain.colors, topo.colors, cm.colors} + +\item{...}{Additional arguments} } \value{ Creates a plot @@ -34,10 +40,10 @@ f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") tac <- load_tac(f_raw_tac) vol <- load_vol(f_raw_vol) AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=FALSE, PVC=FALSE) -plot_tac(AD06_tac_nc, ROIs=c("frontal", "cerebellum"), title="Example Plot") +plot(AD06_tac_nc, ROIs=c("frontal", "cerebellum"), title="Example Plot") } \seealso{ Other tac functions: \code{\link{save_tac}}, - \code{\link{tac_roi}} + \code{\link{split_pvc}}, \code{\link{tac_roi}} } \concept{tac functions} diff --git a/man/plot_ref_Logan.Rd b/man/plot_ref_Logan.Rd deleted file mode 100644 index e9dd8ba..0000000 --- a/man/plot_ref_Logan.Rd +++ /dev/null @@ -1,44 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/logan.R -\name{plot_ref_Logan} -\alias{plot_ref_Logan} -\title{Non-invasive reference Logan plot} -\usage{ -plot_ref_Logan(tac_data, target, ref, k2prime, t_star = 0, error = 0.1, - method = "trapz") -} -\arguments{ -\item{tac_data}{The time-activity curve data from tac_roi()} - -\item{target}{The name of the receptor-rich region, e.g. "frontal"} - -\item{ref}{The reference region, e.g. "cerebellum"} - -\item{k2prime}{A fixed value for k2' must be specified (e.g. 0.2)} - -\item{t_star}{If 0, t* will be calculated using find_t_star()} - -\item{error}{For find_t_star()} - -\item{method}{Method of inntegration, "trapz" or "integrate"} -} -\value{ -No return -f <- system.file("extdata", "AD06.tac", package="tacmagic") -fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") -AD06_tac <- load_tac(f, format="PMOD") -AD06_volume <- load_vol(fv, format="voistat") -AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), - merge=FALSE, PVC=FALSE) - -plot_ref_Logan(AD06, target="frontal", ref="cerebellum", - k2prime=0.2, t_star=0) -} -\description{ -This plots the non-invasive Logan plot. -} -\seealso{ -Other Logan plot functions: \code{\link{DVR_all_ref_Logan}}, - \code{\link{DVR_ref_Logan}} -} -\concept{Logan plot functions} diff --git a/man/pos_anyroi.Rd b/man/pos_anyroi.Rd index d63685e..31f3036 100644 --- a/man/pos_anyroi.Rd +++ b/man/pos_anyroi.Rd @@ -15,12 +15,17 @@ pos_anyroi(modelstats, cutoff) data.frame of participants and positive/negative status } \description{ -See references()$Aizenstein. The authors proposed a standardized method of -calculating PIB+ cutoff values to classify participants as PIB+ or PIB-. -They used the DVR from 7 ROIs associated with amyloid deposition. This -function takes the ROI-based cutoff-values, e.g. from cutoff_aiz(), and -returns a table specifying which participants are positive, i.e. which have -at least one ROI greater than the cutoff. +Aizenstein et al. (2008) proposed a standardized method of calculating PIB+ +cutoff values to classify participants as PIB+ or PIB-. They used the DVR +from 7 ROIs associated with amyloid deposition. This function takes the +ROI-based cutoff values, e.g. from cutoff_aiz(), and returns a table +specifying which participants are positive, i.e. which have at least one ROI +greater than the cutoff. +} +\references{ +Aizenstein HJ, Nebes RD, Saxton JA, et al. 2008. Frequent amyloid +deposition without significant cognitive impairment among the elderly. +Arch Neurol 65: 1509-1517. } \seealso{ Other Cutoff functions: \code{\link{cutoff_aiz}} diff --git a/man/references.Rd b/man/references.Rd deleted file mode 100644 index 8bf8e50..0000000 --- a/man/references.Rd +++ /dev/null @@ -1,17 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/references.R -\name{references} -\alias{references} -\title{Print and return a list of references for this package.} -\usage{ -references() -} -\value{ -List of references. -} -\description{ -Print and return a list of references for this package. -} -\examples{ -references() -} diff --git a/man/roi_ham_full.Rd b/man/roi_ham_full.Rd index 446249d..5be30be 100644 --- a/man/roi_ham_full.Rd +++ b/man/roi_ham_full.Rd @@ -17,6 +17,13 @@ It can be modified to suit the user's needs. \examples{ roi_ham_full() } +\references{ +Hammers, Alexander, Richard Allom, Matthias J. Koepp, Samantha L. Free, +Ralph Myers, Louis Lemieux, Tejal N. Mitchell, David J. Brooks, and John S. +Duncan. 2003. Three-dimensional Maximum Probability Atlas of the Human +Brain, with Particular Reference to the Temporal Lobe. Human Brain Mapping +19 (4): 224-247. doi:10.1002/hbm.10123 +} \seealso{ Other ROI definitions: \code{\link{roi_ham_pib}}, \code{\link{roi_ham_stand}} diff --git a/man/roi_ham_pib.Rd b/man/roi_ham_pib.Rd index 2181159..f8e7349 100644 --- a/man/roi_ham_pib.Rd +++ b/man/roi_ham_pib.Rd @@ -18,6 +18,13 @@ See PMOD Neuro Tool (PNEURO) (Version 4.0) documentation. \examples{ roi_ham_pib() } +\references{ +Hammers, Alexander, Richard Allom, Matthias J. Koepp, Samantha L. Free, +Ralph Myers, Louis Lemieux, Tejal N. Mitchell, David J. Brooks, and John S. +Duncan. 2003. Three-dimensional Maximum Probability Atlas of the Human +Brain, with Particular Reference to the Temporal Lobe. Human Brain Mapping +19 (4): 224-247. doi:10.1002/hbm.10123 +} \seealso{ Other ROI definitions: \code{\link{roi_ham_full}}, \code{\link{roi_ham_stand}} diff --git a/man/roi_ham_stand.Rd b/man/roi_ham_stand.Rd index 8200fe4..16907f8 100644 --- a/man/roi_ham_stand.Rd +++ b/man/roi_ham_stand.Rd @@ -3,7 +3,7 @@ \name{roi_ham_stand} \alias{roi_ham_stand} \title{Return a list of merged ROIs made up of the atomic ROIs in the Hammer's -atlas (see references()$Hammers_2003).} +atlas.} \usage{ roi_ham_stand() } @@ -13,11 +13,18 @@ specifies the atomic ROIs from the atlas that make it up. } \description{ Return a list of merged ROIs made up of the atomic ROIs in the Hammer's -atlas (see references()$Hammers_2003). +atlas. } \examples{ roi_ham_stand() } +\references{ +Hammers, Alexander, Richard Allom, Matthias J. Koepp, Samantha L. Free, +Ralph Myers, Louis Lemieux, Tejal N. Mitchell, David J. Brooks, and John S. +Duncan. 2003. Three-dimensional Maximum Probability Atlas of the Human +Brain, with Particular Reference to the Temporal Lobe. Human Brain Mapping +19 (4): 224-247. doi:10.1002/hbm.10123 +} \seealso{ Other ROI definitions: \code{\link{roi_ham_full}}, \code{\link{roi_ham_pib}} diff --git a/man/save_tac.Rd b/man/save_tac.Rd index 275db5c..3c3ee18 100644 --- a/man/save_tac.Rd +++ b/man/save_tac.Rd @@ -20,7 +20,7 @@ saves it as a PMOD-formatted tac file. Using the .tac extension in the file name is recommended. } \seealso{ -Other tac functions: \code{\link{plot_tac}}, - \code{\link{tac_roi}} +Other tac functions: \code{\link{plot.tac}}, + \code{\link{split_pvc}}, \code{\link{tac_roi}} } \concept{tac functions} diff --git a/man/split_pvc.Rd b/man/split_pvc.Rd new file mode 100644 index 0000000..9a9195b --- /dev/null +++ b/man/split_pvc.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tac.R +\name{split_pvc} +\alias{split_pvc} +\title{Subset PMOD tacs with or without PVC} +\usage{ +split_pvc(tac, PVC = TRUE) +} +\arguments{ +\item{tac}{The time-activity curve data from loading function (PMOD)} + +\item{PVC}{If TRUE, includes columns with "_C", if FALSE, ones without "_C"} +} +\value{ +Time-activity curve object +} +\description{ +When partial volume correction (PVC) is used in PMOD, the saved tac files +have ROIs with and without PVC. When loaded with load_tac()) it may be +desirable to keep only either the PVC or non-PVC tacs. This returns a tac +object that is a subset of the input tac object with only the PVC or non-PVC +tacs. This relies on PMOD's convention of labelling tac columns with "_C". +} +\examples{ +# f_raw_tac and f_raw_vol are the filenames of PMOD-generated files +f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") + +tac <- load_tac(f_raw_tac) +tac_pvc <- split_pvc(tac, TRUE) +tac_nc <- split_pvc(tac, FALSE) +} +\seealso{ +Other tac functions: \code{\link{plot.tac}}, + \code{\link{save_tac}}, \code{\link{tac_roi}} +} +\concept{tac functions} diff --git a/man/suvr.Rd b/man/suvr.Rd index 128393e..5641efd 100644 --- a/man/suvr.Rd +++ b/man/suvr.Rd @@ -4,17 +4,16 @@ \alias{suvr} \title{Calculate weighted SUVRs for specified regions of interest} \usage{ -suvr(tac, SUVR_def = NULL, ref = NULL, params = NULL) +suvr(tac, SUVR_def, ref, ...) } \arguments{ \item{tac}{The time-activity curve data from tac_roi()} \item{SUVR_def}{a vector of start times for window to be used in SUVR} -\item{ref}{a string, e.g. "cerbellum", to specify reference region} +\item{ref}{a string, e.g. "cerebellum", to specify reference region} -\item{params}{a list of paramters passed from the batch_tm function and is -not needed when calling for individual participants.} +\item{...}{When called from tm_batch, unused parameters may be supplied} } \value{ A data.frame of SUVR values for the specified ROIs diff --git a/man/suvr_auc.Rd b/man/suvr_auc.Rd index ee698b0..ca3a177 100644 --- a/man/suvr_auc.Rd +++ b/man/suvr_auc.Rd @@ -4,14 +4,16 @@ \alias{suvr_auc} \title{Calculate SUVRs for regions of interest with AUC from mid-frame times} \usage{ -suvr_auc(tac, SUVR_def, ref) +suvr_auc(tac, SUVR_def, ref, ...) } \arguments{ \item{tac}{The time-activity curve data from tac_roi()} \item{SUVR_def}{a vector of start times for window to be used in SUVR} -\item{ref}{is a string, e.g. "cerbellum", to specify reference region} +\item{ref}{is a string, e.g. "cerebellum", to specify reference region} + +\item{...}{When called from tm_batch, unused parameters may be supplied} } \value{ A data.frame of SUVR values for the specified ROIs diff --git a/man/tac_roi.Rd b/man/tac_roi.Rd index d665f71..23185c3 100644 --- a/man/tac_roi.Rd +++ b/man/tac_roi.Rd @@ -33,7 +33,7 @@ vol <- load_vol(f_raw_vol) AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=FALSE, PVC=FALSE) } \seealso{ -Other tac functions: \code{\link{plot_tac}}, - \code{\link{save_tac}} +Other tac functions: \code{\link{plot.tac}}, + \code{\link{save_tac}}, \code{\link{split_pvc}} } \concept{tac functions} diff --git a/paper.bib b/paper.bib index 65cf39a..3226f87 100644 --- a/paper.bib +++ b/paper.bib @@ -9,7 +9,7 @@ @book{Dierckx:2014 @misc{tpcclib, author = {Oikonen, V.}, -year = {n.d.}, +year = {2018}, title = {tpcclib: Command-line tools to processing and analyzing data collected in Turku PET Centre}, howpublished = {\url{https://gitlab.utu.fi/vesoik/tpcclib}}, publisher = {Turku PET Centre, Turku, Finland} diff --git a/paper.md b/paper.md index 65ea45f..d600efa 100644 --- a/paper.md +++ b/paper.md @@ -21,27 +21,27 @@ affiliations: # Background -Positron emission tomography (PET) is a research and clinical imaging modality that uses radioactive tracers that bind to target molecules of interest. A PET scanner identifies the tracer location by virtue of the tracer's radioactive decay, providing information that can be used to determine the location of the target in the body. Analysis pipelines are used to calculate radiotracer activity over time within a spatial region of interest (ROI). The resulting time-activity curves (TAC) are analyzed to answer important clinical and research questions using kinetic models.[@Dierckx:2014] +Positron emission tomography (PET) is a research and clinical imaging modality that uses radioactive tracers that bind to target molecules of interest. A PET scanner identifies the tracer location by virtue of the tracer's radioactive decay, providing information about the distribution of target in the body. Analysis pipelines are used to calculate radiotracer activity over time within a spatial region of interest (ROI). The resulting time-activity curves (TAC) are analyzed to answer important clinical and research questions using kinetic models [@Dierckx:2014]. # The ``tacmagic`` R package -BBy supporting multiple source data formats, ``tacmagic`` provides an open R [@R] platform for the analysis of PET TAC data that has been produced by existing image analysis pipelines. The data loading functions provide a common format for subsequent analysis in R. We have also implemented basic non-invasive models commonly used in PET research,[@Lopresti:2005; @Logan:1996] comparing the results against existing tools.[@tpcclib] The goal is to facilitate open, explicit and reproducible research. +By supporting multiple source data formats, ``tacmagic`` provides an open R [@R] platform for the analysis of PET TAC data that has been produced by existing image analysis pipelines. The data loading functions provide a common format for subsequent analysis in R. We have also implemented basic non-invasive models commonly used in PET research [@Lopresti:2005; @Logan:1996], which have been tested against existing tools [@tpcclib]. The goal is to facilitate open, explicit and reproducible research. The major features of ``tacmagic`` are documented in a walkthrough vignette that is included with the package. The features include: 1. loading TAC and volume data to analyze in R, 2. merging regional TAC data into larger ROIs weighted by volume, 3. basic TAC plotting, -4. calculation of standardized uptake value ratio (SUVR),[@Lopresti:2005;@Dierckx:2014] +4. calculation of standardized uptake value ratio (SUVR) [@Lopresti:2005;@Dierckx:2014], 5. calculation and plotting of the non-invasive reference region Logan DVR model [@Logan:1996;@tpcclib] and -6. calculation of cut-off values for dichotomizing data.[@Aizenstein:2008] +6. calculation of cut-off values for dichotomizing data [@Aizenstein:2008]. The package is published with an open source licence, enabling future collaboration and expansion of the package's functions, which may include future support for additional data formats, kinetic models, plotting and cut-off calculation. # Acknowledgments -Many thanks are due to the kind mentorship of Ariel Graff-Guerrero, Philip Gerretsen and Bruce Pollock, as well as to Fernando Caravaggio and Tiffany Chow for their guidance in PET analysis techniques prior to the development of this package. +Many thanks are due to the kind mentorship of Ariel Graff-Guerrero, Philip Gerretsen and Bruce Pollock, as well as to Fernando Caravaggio, Jun Chung, and Tiffany Chow for their guidance in PET analysis techniques prior to the development of this package. Development of parts of this package involved work supported by the Canadian Institute for Health Research Canada Graduate Scholarship, the Ontario Graduate Scholarship, and the Clinician Scientist Program of the University of Toronto's Department of Psychiatry. -# References \ No newline at end of file +# References diff --git a/readme.md b/readme.md index 6055b56..612c5fb 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,8 @@ # tacmagic: PET Analysis in R -[![Build Status](https://travis-ci.org/eebrown/PET.svg?branch=master)](https://travis-ci.org/eebrown/PET) [![Coverage status](https://codecov.io/gh/eebrown/PET/branch/master/graph/badge.svg)](https://codecov.io/github/eebrown/PET?branch=master) [![](https://badges.ropensci.org/280_status.svg)](https://github.com/ropensci/software-review/issues/280) + +[![Build Status](https://travis-ci.org/ropensci/tacmagic.svg?branch=master)](https://travis-ci.org/ropensci/tacmagic) [![Coverage status](https://codecov.io/gh/ropensci/tacmagic/branch/master/graph/badge.svg)](https://codecov.io/github/ropensci/tacmagic?branch=master) [![](https://badges.ropensci.org/280_status.svg)](https://github.com/ropensci/software-review/issues/280) + To foster openness, replicability, and efficiency, ```tacmagic``` facilitates loading and analysis of positron emission tomography data in R. @@ -49,3 +51,5 @@ Loading and analysis functions can be run as a batch or by individual participan but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +[![ropensci_footer](https://ropensci.org/public_images/ropensci_footer.png)](https://ropensci.org) diff --git a/tests/testthat/test_batches.R b/tests/testthat/test_batches.R index cc34042..67317be 100644 --- a/tests/testthat/test_batches.R +++ b/tests/testthat/test_batches.R @@ -97,7 +97,7 @@ test_that("batch_load() with merging loads 3 particpants with same result as batchtest2 <- batch_load(participants, tac_file_suffix=".tac", roi_m=TRUE, vol_file_suffix="_TAC.voistat", - vol_format="voistat", merge=TRUE, + vol_format="voistat", merge=TRUE, PVC=FALSE, ROI_def=roi_ham_stand()) AD07 <- load_tac(system.file("extdata", "AD07.tac", package="tacmagic")) @@ -120,7 +120,7 @@ test_that("custom functions can be passed to batch_tm()", { } # the "custom function" - maxi <- function(tac, SUVR_def=NULL, ref=NULL, params) { + maxi <- function(tac, ...) { table <- new_table_out(tac, "maxi") for (ROI in names(tac)[-(1:2)]) { diff --git a/tests/testthat/test_loading.R b/tests/testthat/test_loading.R index 8f241bb..18226e1 100644 --- a/tests/testthat/test_loading.R +++ b/tests/testthat/test_loading.R @@ -26,9 +26,8 @@ test_that("validate_tac() properly rejects malformed tac objects", { f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") tac <- load_tac(f_raw_tac) - attributes(tac)$tm_type <- "fail" - expect_message(validate_tac(tac)) - expect_equal(FALSE, validate_tac(tac)) + class(tac) <- "data.frame" + expect_error(validate_tac(tac)) tac <- load_tac(f_raw_tac) attributes(tac)$time_unit <- "sec" @@ -80,7 +79,7 @@ test_that("load_tac() properly loads example DFT file", { putam_sin <- c(-0.00918,1.11,4.71,11.5,19.7,25.6,28.7,26.7,29.2,NA,28) cereb_. <- c(0.000298,1.43,5.22,9.87,1.03,9.36,8.69,8.57,6.99,7.05,6.54) ans <- data.frame(start, end, putam_dx, putam_sin, cereb_.) - attributes(ans)$tm_type <- "tac" + class(ans) <- c("tac", "data.frame") attributes(ans)$time_unit <- "minutes" attributes(ans)$activity_unit <- "kBq/cc" @@ -115,7 +114,7 @@ test_that("load_tac_PMOD() can deal with seconds and minutes", { a <- read.csv(f_raw_tac, sep="\t") expect_equal(names(a)[1], "start.seconds.") names(a)[1] <- "start.minutes." - tmp <- tempfile() + tmp <- tempfile(fileext = ".tac") write.table(a, tmp, row.names=FALSE, sep="\t") fake_minutes <- load_tac(tmp) diff --git a/tests/testthat/test_logan.R b/tests/testthat/test_logan.R index 47df42d..543d24e 100644 --- a/tests/testthat/test_logan.R +++ b/tests/testthat/test_logan.R @@ -78,16 +78,14 @@ test_that("plot_ref_logan creates the plots without error", { AD06 <- tac_roi(tac=AD06_tac, volumes=AD06_volume, ROI_def=roi_ham_pib(), merge=F, PVC=F) + AD06_Logan <- DVR_ref_Logan(AD06, target="frontal", ref="cerebellum", + k2prime=0.2, t_star=0) + pdf(NULL) on.exit(dev.off()) dev.control(displaylist="enable") - plot_ref_Logan(AD06, - target="frontal", - ref="cerebellum", - k2prime=0.2, - t_star=0, - ) + plot(AD06_Logan) p <- recordPlot() @@ -100,7 +98,6 @@ test_that("plot_ref_logan creates the plots without error", { }) - test_that("find_t_star gets right answer for reasonable parameters", { x <- c(1,2,3,4,5,6,7,8,9,10) @@ -133,3 +130,31 @@ test_that("find_t_star gets right answer for reasonable parameters", { expect_equal(find_t_star(x,y, error=0.15), 1) }) + + +test_that("dvr() wrapper produces same results as functions it calls", { + + f <- system.file("extdata", "AD06.tac", package="tacmagic") + fv <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") + AD06_tac <- load_tac(f, format="PMOD") + AD06_volume <- load_vol(fv, format="voistat") + + AD06 <- tac_roi(tac=AD06_tac, + volumes=AD06_volume, ROI_def=roi_ham_pib(), merge=F, PVC=F) + + a_AD06_Logan <- DVR_ref_Logan(AD06, target="frontal", ref="cerebellum", + k2prime=0.2, t_star=0) + + b_AD06_Logan <- dvr(AD06, target="frontal", ref="cerebellum", + k2prime=0.2, t_star=0) + + c_AD06_Logan <- DVR_all_ref_Logan(AD06, ref="cerebellum", + k2prime=0.2, t_star=0) + + d_AD06_Logan <- dvr(AD06, ref="cerebellum", k2prime=0.2, t_star=0) + + expect_equal(a_AD06_Logan$DVR, b_AD06_Logan) + + expect_equal(c_AD06_Logan, d_AD06_Logan) + +}) diff --git a/tests/testthat/test_plot.R b/tests/testthat/test_plot.R new file mode 100644 index 0000000..24f041a --- /dev/null +++ b/tests/testthat/test_plot.R @@ -0,0 +1,116 @@ +# test_plot.R + +context("tacmagic plotting") + +test_that("plot.tac runs without error and contains correct axis label", { + + f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") + f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") + + tac <- load_tac(f_raw_tac) + vol <- load_vol(f_raw_vol) + AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=FALSE, PVC=FALSE) + + pdf(NULL) + on.exit(dev.off()) + dev.control(displaylist="enable") + + plot(AD06_tac_nc, ROIs=c("frontal", "cerebellum"), time="minutes", + title="Example Plot") + + p <- recordPlot() + + expect_equal(unlist(p)[[123]], "Time (minutes)") + expect_equal(unlist(p)[[37]], 80) # 80 mins last value on x-axis + + pdf(NULL) + on.exit(dev.off()) + dev.control(displaylist="enable") + + plot(AD06_tac_nc, ROIs=c("frontal", "cerebellum"), time="seconds", + title="Example Plot") + + p <- recordPlot() + + expect_equal(unlist(p)[[123]], "Time (seconds)") +}) + +test_that("plot.tac with 2 tacs and conversion runs without error and + contains correct axis label", { + + f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") + f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") + + f_raw_tac2 <- system.file("extdata", "AD07.tac", package="tacmagic") + f_raw_vol2 <- system.file("extdata", "AD07_TAC.voistat", package="tacmagic") + + tac <- load_tac(f_raw_tac) + vol <- load_vol(f_raw_vol) + AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=FALSE, PVC=FALSE) + tac2 <- load_tac(f_raw_tac2) + vol2 <- load_vol(f_raw_vol2) + AD07_tac_nc <- tac_roi(tac2, vol2, roi_ham_full(), merge=FALSE, PVC=FALSE) + + pdf(NULL) + on.exit(dev.off()) + dev.control(displaylist="enable") + + plot(AD06_tac_nc, AD07_tac_nc, ROIs=c("frontal", "cerebellum"), + title="Example Plot", time="seconds") + + p <- recordPlot() + + expect_equal(unlist(p)[[123]], "Time (seconds)") + expect_equal(unlist(p)[[37]], 4800) #4800 secs on last walk + + ## and errors + + expect_error(plot(AD06_tac_nc, AD07_tac_nc, + ROIs=c("notROI", "cerebellum"), + title="Example Plot", time="seconds")) + + expect_error(plot(AD06_tac_nc, tac, + ROIs=c("frontal", "cerebellum"), + title="Example Plot", time="seconds")) + +}) + +test_that("compare_tac_form() produces errors appropriately", { + + f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") + f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") + + f_raw_tac2 <- system.file("extdata", "AD07.tac", package="tacmagic") + f_raw_vol2 <- system.file("extdata", "AD07_TAC.voistat", package="tacmagic") + + tac <- load_tac(f_raw_tac) + vol <- load_vol(f_raw_vol) + AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=FALSE, PVC=FALSE) + tac2 <- load_tac(f_raw_tac2) + vol2 <- load_vol(f_raw_vol2) + AD07_tac_nc <- tac_roi(tac2, vol2, roi_ham_full(), merge=FALSE, PVC=FALSE) + + expect_equal(compare_tac_form(AD06_tac_nc, AD07_tac_nc), TRUE) + + AD06_tac_nc$start[2] <- 16 + expect_error(compare_tac_form(AD06_tac_nc, AD07_tac_nc)) + + AD06_tac_nc$start[2] <- 15 #back to normal + expect_equal(compare_tac_form(AD06_tac_nc, AD07_tac_nc), TRUE) + + AD07_tac_nc$end[2] <- NA + expect_error(compare_tac_form(AD06_tac_nc, AD07_tac_nc)) + + AD07_tac_nc$end[2] <- 30 #back to normal + expect_equal(compare_tac_form(AD06_tac_nc, AD07_tac_nc), TRUE) + + attributes(AD06_tac_nc)$time_unit <- "minutes" + expect_error(compare_tac_form(AD06_tac_nc, AD07_tac_nc)) + + attributes(AD06_tac_nc)$time_unit <- "seconds" #back to normal + expect_equal(compare_tac_form(AD06_tac_nc, AD07_tac_nc), TRUE) + + attributes(AD07_tac_nc)$activity_unit <- "nCi/cc" + expect_error(compare_tac_form(AD06_tac_nc, AD07_tac_nc)) + +}) diff --git a/tests/testthat/test_references.R b/tests/testthat/test_references.R deleted file mode 100644 index 8484417..0000000 --- a/tests/testthat/test_references.R +++ /dev/null @@ -1,13 +0,0 @@ -# test_references.R - -context("Reference listing") - -test_that("references() generates a named list of references", { - - ref <- references() - - expect_equal(class(ref), "list") - expect_equal(class(ref[2]), "list") - expect_equal(class(ref[[2]]), "character") - -}) diff --git a/tests/testthat/test_save.R b/tests/testthat/test_save.R index b33bd37..a46a389 100644 --- a/tests/testthat/test_save.R +++ b/tests/testthat/test_save.R @@ -1,6 +1,6 @@ # test_save.R -context("SUVR calculation") +context("tac saving") test_that("save_tac() gives error if outfile is bad format", { @@ -13,7 +13,7 @@ test_that("save_tac() gives error if outfile is bad format", { test_that("save_tac() reproduces the original PMOD .tac file", { - tmp <- tempfile() + tmp <- tempfile(fileext = ".tac") f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") tac <- load_tac(f_raw_tac) @@ -27,14 +27,14 @@ test_that("save_tac() reproduces the original PMOD .tac file", { test_that("save_tac() saves a merged tac object without error", { - tmp <- tempfile() + tmp <- tempfile(fileext=".tac") f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") tac <- load_tac(f_raw_tac) vol <- load_vol(f_raw_vol) AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=TRUE, PVC=FALSE) - tmp <- tempfile() + tmp <- tempfile(fileext=".tac") save_tac(AD06_tac_nc, tmp) new <- load_tac(tmp) @@ -46,7 +46,7 @@ test_that("save_tac() saves a merged tac object without error", { test_that("save_tac() saves a magia tac object without error", { - tmp <- tempfile() + tmp <- tempfile(fileext=".tac") f_magia <- system.file("extdata", "AD06_tac_magia.mat", package="tacmagic") n <- load_tac(f_magia, format="magia", time_unit="seconds", activity_unit="kBq/cc") diff --git a/tests/testthat/test_tac.R b/tests/testthat/test_tac.R index 9ac9a2a..dae1fe5 100644 --- a/tests/testthat/test_tac.R +++ b/tests/testthat/test_tac.R @@ -15,11 +15,11 @@ test_that("tac_roi() accurately calculates weighted averages from PMOD .tac and ans_nc <- read.csv(f_ans_nc) attributes(ans_nc)$time_unit <- "seconds" attributes(ans_nc)$activity_unit <- "kBq/cc" - attributes(ans_nc)$tm_type <- "tac" + class(ans_nc) <- c("tac", "data.frame") ans_pvc <- read.csv(f_ans_pvc) attributes(ans_pvc)$time_unit <- "seconds" attributes(ans_pvc)$activity_unit <- "kBq/cc" - attributes(ans_pvc)$tm_type <- "tac" + class(ans_pvc) <- c("tac", "data.frame") tac <- load_tac(f_raw_tac) vol <- load_vol(f_raw_vol) @@ -55,11 +55,11 @@ test_that("tac_roi() accurately calculates weighted averages from PMOD .voistat ans_nc <- read.csv(f_ans_nc) attributes(ans_nc)$time_unit <- "seconds" attributes(ans_nc)$activity_unit <- "kBq/cc" - attributes(ans_nc)$tm_type <- "tac" + class(ans_nc) <- c("tac", "data.frame") ans_pvc <- read.csv(f_ans_pvc) attributes(ans_pvc)$time_unit <- "seconds" attributes(ans_pvc)$activity_unit <- "kBq/cc" - attributes(ans_pvc)$tm_type <- "tac" + class(ans_pvc) <- c("tac", "data.frame") expect_equal(AD06_tac_nc_vs, ans_nc) expect_equal(AD06_tac_pvc_vs, ans_pvc) @@ -75,7 +75,7 @@ test_that("tac_roi() rejects a bad tac", { tac_good <- load_tac(f_raw_tac) tac_bad <- tac_good - attributes(tac_bad)$tm_type <- "fail" # ruin the tac object + class(tac_bad) <- "data.frame" # not a tac class object vol <- load_vol(f_voistat) @@ -95,7 +95,7 @@ test_that("tac_roi() can load magia matlab files to the proper format", { m <- load_tac_magia(f_magia) attributes(m)$time_unit <- "seconds" attributes(m)$activity_unit <- "kBq/cc" - attributes(m)$tm_type <- "tac" + class(m) <- c("tac", "data.frame") n <- load_tac(f_magia, format="magia", time_unit="seconds", activity_unit="kBq/cc") expect_is(m, "data.frame") @@ -105,86 +105,67 @@ test_that("tac_roi() can load magia matlab files to the proper format", { }) -test_that("plot_tac runs without error and contains correct axis label", { +test_that("load_tac_voistat produces errors appropriately", { + f_acq_bad <- system.file("extdata", "AD06_invalid.acqtimes", + package="tacmagic") + f_voistat <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") + + expect_error(load_tac(f_voistat, format="voistat", acqtimes=f_acq_bad)) + +}) + +test_that("summary.tac provides correct output for valid/invalid tac objects", { f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") - tac <- load_tac(f_raw_tac) vol <- load_vol(f_raw_vol) AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=FALSE, PVC=FALSE) - pdf(NULL) - on.exit(dev.off()) - dev.control(displaylist="enable") - - plot_tac(AD06_tac_nc, ROIs=c("frontal", "cerebellum"), time="minutes", - title="Example Plot") - - p <- recordPlot() - - expect_equal(unlist(p)[[123]], "Time (minutes)") - expect_equal(unlist(p)[[37]], 80) # 80 mins last value on x-axis - - pdf(NULL) - on.exit(dev.off()) - dev.control(displaylist="enable") - - plot_tac(AD06_tac_nc, ROIs=c("frontal", "cerebellum"), time="seconds", - title="Example Plot") + expected_output <- paste0("tac object\n", + " Activity unit: kBq/cc \n", + " Time unit: seconds \n", + " Number of ROIs: 22 \n", + " Number of frames: 34 \n", + " Time span: 0 - 5400 seconds \n", + " Unique frame durations: 15 30 60 180 300 600 seconds ") - p <- recordPlot() + expect_equal(capture_output(summary(AD06_tac_nc)), expected_output) - expect_equal(unlist(p)[[123]], "Time (seconds)") + names(AD06_tac_nc)[1] <- "stttttart" + expect_error(summary(AD06_tac_nc)) }) -test_that("plot_tac with 2 tacs and conversion runs without error and - contains correct axis label", { +test_that("split_pvc produces expected tac objects", { f_raw_tac <- system.file("extdata", "AD06.tac", package="tacmagic") - f_raw_vol <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") - - f_raw_tac2 <- system.file("extdata", "AD07.tac", package="tacmagic") - f_raw_vol2 <- system.file("extdata", "AD07_TAC.voistat", package="tacmagic") - tac <- load_tac(f_raw_tac) - vol <- load_vol(f_raw_vol) - AD06_tac_nc <- tac_roi(tac, vol, roi_ham_full(), merge=FALSE, PVC=FALSE) - tac2 <- load_tac(f_raw_tac2) - vol2 <- load_vol(f_raw_vol2) - AD07_tac_nc <- tac_roi(tac2, vol2, roi_ham_full(), merge=FALSE, PVC=FALSE) - - pdf(NULL) - on.exit(dev.off()) - dev.control(displaylist="enable") - plot_tac(AD06_tac_nc, AD07_tac_nc, ROIs=c("frontal", "cerebellum"), - title="Example Plot", time="seconds") + expect_equal(names(tac)[1:88], names(split_pvc(tac, PVC=FALSE))) + expect_equal(names(tac)[c(1, 2, 89:174)], names(split_pvc(tac, PVC=TRUE))) - p <- recordPlot() - - expect_equal(unlist(p)[[123]], "Time (seconds)") - expect_equal(unlist(p)[[37]], 4800) #4800 secs on last walk +}) - ## and errors +test_that("as.tac creates valid tac objects and fails appropriately", { - expect_error(plot_tac(AD06_tac_nc, AD07_tac_nc, - ROIs=c("notROI", "cerebellum"), - title="Example Plot", time="seconds")) + manual <- data.frame(start=c(0:4), end=c(2:6), + ROI1=c(10.1:14.2), ROI2=c(11:15)) + manual_tac <- as.tac(manual, time_unit="minutes", activity_unit="kBq/cc") - expect_error(plot_tac(AD06_tac_nc, tac, - ROIs=c("frontal", "cerebellum"), - title="Example Plot", time="seconds")) + expect_equal(validate_tac(manual_tac), TRUE) -}) + expect_equal(validate_tac(as.tac(manual, time_unit="seconds", + activity_unit="Bq/cc")), TRUE) -test_that("load_tac_voistat procudes errors appropriately", { + expect_equal(validate_tac(as.tac(manual, time_unit="wrong", + activity_unit="Bq/cc")), FALSE) - f_acq_bad <- system.file("extdata", "AD06_invalid.acqtimes", - package="tacmagic") - f_voistat <- system.file("extdata", "AD06_TAC.voistat", package="tacmagic") - - expect_error(load_tac(f_voistat, format="voistat", acqtimes=f_acq_bad)) + expect_equal(validate_tac(as.tac(manual, time_unit="seconds", + activity_unit="wrong")), FALSE) + + expect_error(as.tac(manual, activity_unit="kBq/cc")) + expect_error(as.tac(manual, time_unit="seconds")) + expect_error(as.tac(manual)) }) diff --git a/vignettes/walkthrough.Rmd b/vignettes/walkthrough.Rmd index 574a399..00cd6ac 100644 --- a/vignettes/walkthrough.Rmd +++ b/vignettes/walkthrough.Rmd @@ -19,21 +19,29 @@ knitr::opts_chunk$set( ) ``` -There are two approaches to using the tacmagic package to analyze PET time-activity curve data: either by loading participant data individually and using the various functions to analyze it, or via the batch functions to list and analyze data from multiple participants. Here, we illustrate the main features of tacmagic, by walking through the analysis of a single participant. We provide an explanation of the batch mode at the end. - ## Background -[Positron emission tomography](https://en.wikipedia.org/wiki/Positron_emission_tomography) (PET) is a research and clinical imaging modality that uses radioactive tracers that bind to target molecules of interest. A PET scanner identifies the tracer location by virtue of the tracer's radioactive decay, providing information to determine the location of the target in the body. As the spatial resolution of PET is relatively poor, analysis is frequently combined with higher resolution imaging such as magnetic resonance imaging (MRI), which can be spatially co-registered to the PET image. Subsequently, radiotracer activity (over time) can be identified by spatial region of interest (ROI). The resulting analysis produces time-activity curves (**tac**) which can be further analyzed to answer important clinical and research questions (**magic**). +[Positron emission tomography](https://en.wikipedia.org/wiki/Positron_emission_tomography) (PET) is a research and clinical imaging modality that uses radioactive tracers that bind to target molecules of interest. A PET scanner identifies the tracer location by virtue of the tracer's radioactive decay, providing information to determine the location of the target in the body. As the spatial resolution of PET is relatively poor, analysis is frequently combined with higher resolution imaging such as magnetic resonance imaging (MRI), which can be spatially co-registered to the PET image. Subsequently, radiotracer activity (over time) can be identified by spatial region of interest (ROI). + +An image anaylsis pipeline is required to extract regional time activity curves (tacs) from a dynamic PET image. There are various pipelines available including widely-used commercial solutions (e.g. [PMOD](https://www.pmod.com/web/)) and newer open-source options (e.g. [magia](http://aivo.utu.fi/magia/)). Pipelines generally implement the following steps: + +* Dynamic PET pre-processing (e.g. motion correction, decay-correction) +* PET image co-registration with structural MRI +* MRI segmentation and normalization to atlas + +Various pipelines save tac, volume and related data in various formats. This package enables the loading and analysis of tac and ROI volume data from image analysis pipelines for further analysis in R. -The sample data for this analysis uses an anonymized scans of a participant with Alzheimer's dementia, data from http://www.gaain.org which was generously made available for unrestricted use.^[Klunk, William E., Robert A. Koeppe, Julie C. Price, Tammie L. Benzinger, Michael D. Devous, William J. Jagust, Keith A. Johnson, et al. “The Centiloid Project: Standardizing Quantitative Amyloid Plaque Estimation by PET.” Alzheimer’s & Dementia 11, no. 1 (January 2015): 1-15.e4. https://doi.org/10.1016/j.jalz.2014.07.003.] The radiotracer used is Pittsburgh Compound B (PIB) which binds to beta-amyloid, a protein found in high concentration in the brains of individuals with Alzheimer's dementia. +## Vignette data +The sample data for this vignette uses an anonymized scans of a participant with Alzheimer's dementia, data from http://www.gaain.org which was generously made available for unrestricted use.^[Klunk, William E., Robert A. Koeppe, Julie C. Price, Tammie L. Benzinger, Michael D. Devous, William J. Jagust, Keith A. Johnson, et al. “The Centiloid Project: Standardizing Quantitative Amyloid Plaque Estimation by PET.” Alzheimer’s & Dementia 11, no. 1 (January 2015): 1-15.e4. https://doi.org/10.1016/j.jalz.2014.07.003.] The radiotracer used is Pittsburgh Compound B (PIB) which binds to beta-amyloid, a protein found in high concentration in the brains of individuals with Alzheimer's dementia. +There are two approaches to using the **tacmagic** package to analyze PET time-activity curve data: either by loading participant data individually and using the various functions to analyze it, or via the batch functions to list and analyze data from multiple participants. Here, we illustrate the main features of tacmagic, by walking through the analysis of a single participant. We provide an explanation of the batch mode at the end. ## Time-activity curve operations ### Data loading -Time-activity curve (TAC) data is loaded via `load_tac()`, which is a wrapper for format-specific functions. To specify which file format the tac data is stored as, use the `format` parameter. Supported formats can be viewed in `help(load_tac())`. +Time-activity curve (TAC) data is loaded via `load_tac()`, which is a wrapper for format-specific functions. To specify which file format the tac data is stored as, use the `format` parameter. Supported formats can be viewed in `help(load_tac)`. The minimal amount of information required is the TAC data for one or more ROI, including the start and stop times of each frame, the time units and the activity units. This information may be in 1 or more files depending on the format and software that created it. @@ -48,6 +56,12 @@ filename <- system.file("extdata", "AD06.tac", package="tacmagic") # format that is not yet supported. AD06_tac <- load_tac(filename, format="PMOD") +``` + +A tac object is a data frame with extra attributes including time and activity units. A summary can be printed with the generic `print()` function. + +```{r} +summary(AD06_tac) AD06_tac[1:5,1:5] # the first 5 frames of the first 3 ROIs ``` @@ -63,17 +77,28 @@ tac2 <- load_tac(filename_voistat, format="voistat", acqtimes=filename_acq) all.equal(AD06_tac, tac2) ``` -We also used Turku's [magia](http://aivo.utu.fi/magia/) pipeline to process the same data. It can be loaded similarly, though with units explicitly entered because the information -is not encoded in the .mat file: +We also used Turku's [magia](http://aivo.utu.fi/magia/) pipeline to process the same data. It can be loaded similarly, though with units explicitly entered because the information is not encoded in the .mat file: ```{r} f_magia <- system.file("extdata", "AD06_tac_magia.mat", package="tacmagic") AD06_tac_magia <- load_tac(f_magia, format="magia", time_unit="seconds", activity_unit="kBq/cc") + AD06_tac_magia[1:5,1:5] ``` +#### Manually-created tac objects + +For other data sources, **tacmagic** tac objects can be created from data.frame objects with `as.tac()`. The time and activity units must be specified as arguments if not already set as attributes in the data.frame. The columns of the data.frame are the regional tacs, with the column names the names of the ROIs. + +```{r} +manual <- data.frame(start=c(0:4), end=c(2:6), ROI1=c(10.1:14.2), ROI2=c(11:15)) +manual_tac <- as.tac(manual, time_unit="minutes", activity_unit="kBq/cc") + +summary(manual_tac) +``` + ### ROI merging Often it is desirable to combine tac ROIs into larger ROIs. For example, if the PET analysis pipeline created tacs for each atlas ROI, your analysis may call for merging these atomic ROIs into larger regions, such as merging all of the atlas ROIs that make up the frontal lobe into a single frontal lobe ROI. @@ -101,18 +126,17 @@ AD06[1:5,1:5] ### Plotting -Basic tac plotting is done with `plot_tac`, which accepts tac data from 2 participants (or group means). The ROIs to plot are specified as a vector of ROI names as they appear in the tac object. As the tac object contains time unit information, the plot can conver to desired units, which can be specified with the `time` argument. +Basic tac plotting can be done by calling `plot`, which accepts two tac objects, e.g. from 2 participants or group means. The ROIs to plot are specified as a vector of ROI names as they appear in the tac object. As the tac object contains time unit information, the plot can convert to desired units, which can be specified with the `time` argument. ```{r, fig.show='hold', fig.height=4.5, fig.width=6.5, fig.align='center'} -plot_tac(AD06, # tac data - ROIs=c("frontal", "temporal", "parietal", "cerebellum"), # ROIs to plot - time="minutes", # Convert x axis from seconds to minutes - title="PIB time activity curves for AD06" # A title for the plot - ) +plot(AD06, # tac data + ROIs=c("frontal", "temporal", "parietal", "cerebellum"), # ROIs to plot + time="minutes", # Convert x axis from seconds to minutes + title="PIB time activity curves for AD06" # A title for the plot + ) ``` - ## Model calculation ### SUVR @@ -165,20 +189,14 @@ AD06_DVR_fr <- DVR_ref_Logan(AD06, t_star=0, # 0 to find, or can specify frame ) - -AD06_DVR_fr +AD06_DVR_fr$DVR ``` To visually confirm that the model behaved as expected with linearity, there is a plotting function: ```{r, fig.show='hold', fig.height=4.5, fig.width=6.5, fig.align='center'} -plot_ref_Logan(AD06, - target="frontal", - ref="cerebellum", - k2prime=0.2, - t_star=0, - ) +plot(AD06_DVR_fr) ``` @@ -195,6 +213,14 @@ AD06_DVR For this data, the DVR calculation has been shown to produce equivalent results as an existing tool.^[https://gitlab.utu.fi/vesoik/tpcclib] +A wrapper function `dvr()` is available to conveniently calculate DVR for a target ROI or all ROIs, and currently defaults to using the Logan reference method: + +```{r} +ADO6_frontal_DVR <- dvr(AD06, target="frontal", ref="cerebellum", k2prime=0.2, + t_star=23) + +``` + ## Batch analysis In most cases, a project will involve the analysis of multiple participants. The above workflow can be used to test and visualize an analysis, but a batch workflow will likely be preferred to analyze multiple participants. @@ -203,7 +229,7 @@ All analyses can be run using 2 steps: a batch data loading step and a batch ana ### Batch loading -Data loading is done by `batch_load()`. See `help(batch_load()` for the required arguements. +Data loading is done by `batch_load()`. See `help(batch_load)` for the required arguments. The first argument is a vector of participant IDs that corresponds to file names, e.g.: @@ -211,12 +237,37 @@ The first argument is a vector of participant IDs that corresponds to file names `my_data <- batch_load(participants, dir="/mypath/", tac_format="PMOD", roi_m=T, vol_file_suffix="_TAC.voistat", vol_format="voistat", ROI_def=roi_ham_stand(), merge=F)` -The above would load the appropriate tac and voistat files, perform the ROI merging specified by `ROI_def` because `roi_m=T`, and would return a list where each element represents a participants, e.g. the first participant would be `my_data$participant1`. +The above would load the appropriate tac and voistat files, perform the ROI merging specified by `ROI_def`, because `roi_m = TRUE`, and would return a list where each element represents a participants, e.g. the first participant would be `my_data$participant1`. ### Batch analysis Once the tac data is loaded, all analyses can be run using `batch_tm()`. The output from `batch_load()` is the first argument for `batch_tm()`. The models implemented in tacmagic can be specified using the `models` argument, e.g. `models = c("SUVR", "Logan")` to calculate both SUVR and Logan DVR. The relevant model parameters will also need to be specified, so see `help(batch_tm)` for all possible arguments. +### Batch example + +For the purpose of the vignette, the list of participants will be a list of the full tac filenames (hence tac_file_suffix=""). In real-world data, the participants parameter can be a list of participant IDs that correspond to the actual filenames, i.e. the filename is made up of dir + participant + tac_file_suffix. + +We will also choose not to use the roi_m option in batch_load(), which could be used to combine ROIs as outlined above. + +```{r} + +participants <- c(system.file("extdata", "AD06.tac", package="tacmagic"), + system.file("extdata", "AD07.tac", package="tacmagic"), + system.file("extdata", "AD08.tac", package="tacmagic")) + +tacs <- batch_load(participants, dir="", tac_file_suffix="") + +# Since the PMOD tac files used here have 2 copies of ROIs, with and without +# PVC, we can use split_pvc to keep the PVC-corrected verions. If we had used +# roi_m here to combine ROIs, we could have specified to use the PVC versions +# in batch_load() with PVC = TRUE. +tacs <- lapply(tacs, split_pvc, PVC=TRUE) + +batch <- batch_tm(tacs, models=c("SUVR", "Logan"), ref="Cerebellum_r_C", + SUVR_def=c(3000,3300,3600), k2prime=0.2, t_star=23) + +``` + ## Cut-off calculations In the analysis of PIB/amyloid PET data, often researchers want to dichotomize patients into PIB+ vs. PIB-, i.e. to identify those with significant AD-related amyloid pathology (PIB+).