# group vis functions
#' @title Recycle parameters or whatever.
#'
#' @param x a vector of whatever
#'
#' @param times positive integer, the required length of the output
#'
#' @return a vector of length 'times', with the recycled 'x'
#'
#' @note Todo: most likely there is an R function for this already, find it.
#' @keywords internal
recycle <- function(x, times) {
if(length(x) == times) {
return(x);
} else {
if(length(x) == 1L) {
return(rep(x, times));
} else if (length(x) > times) {
return(x[1:times]);
} else {
res = x;
do_break = FALSE;
current_idx = 1L;
while (! do_break) {
res = c(res, x[current_idx]);
current_idx = current_idx + 1L;
if(current_idx > length(x)) {
current_idx = 1L;
}
if(length(res) == times) {
do_break = TRUE;
}
}
return(res);
}
}
}
#' @title Plot atlas annotations for a group of subjects.
#'
#' @description Plot atlas annotations for a group of subjects and combine them into a single large image.
#'
#' @inheritParams vis.subject.annot
#'
#' @param subject_id vector of character strings, the subject identifiers
#'
#' @param atlas vector of character strings, the atlas names. Example: \code{c('aparc', 'aparc.a2009s')}
#'
#' @param view_angles see \code{\link{get.view.angle.names}}.
#'
#' @param output_img character string, the file path for the output image. Should end with '.png'.
#'
#' @param num_per_row positive integer, the number of tiles per row.
#'
#' @param captions optional vector of character strings, the short text annotations for the individual tiles. Typically used to plot the subject identifier.
#'
#' @param ... extra parameters passed to the subject level visualization function. Not all may make sense in this context. Example: \code{surface='pial'}.
#'
#' @return named list, see the return value of \code{\link{arrange.brainview.images.grid}} for details.
#'
#' @note The subjects are plotted row-wise, in the order in which they appear in the 'subject_id' parameter. This function is vectorized over 'subject_id' and 'atlas'.
#'
#' @family group visualization functions
#'
#' @export
vis.group.annot <- function(subjects_dir, subject_id, atlas, view_angles = 'sd_dorsal', output_img='fsbrain_group_annot.png', num_per_row = 5L, captions = subject_id, rglactions = list('no_vis'=TRUE), ...) {
num_plots = max(length(subject_id), length(atlas));
if(num_plots > length(subject_id)) {
subject_id = recycle(subject_id, num_plots);
captions = subject_id;
}
subjects_dir = recycle(subjects_dir, num_plots);
atlas = recycle(atlas, num_plots);
coloredmeshes = list();
for(plot_idx in seq.int(num_plots)) {
coloredmeshes[[plot_idx]] = vis.subject.annot(subjects_dir[plot_idx], subject_id[plot_idx], atlas[plot_idx], views='si', rglactions = rglactions, ...);
}
return(invisible(vis.group.coloredmeshes(coloredmeshes, view_angles = view_angles, output_img = output_img, num_per_row = num_per_row, captions = captions)));
}
#' @title Plot native space morphometry data for a group of subjects.
#'
#' @description Plot native space morphometry data for a group of subjects and combine them into a single large image.
#'
#' @inheritParams vis.group.annot
#'
#' @param measure vector of character strings, the morphometry measures, e.g., \code{c('thickness', 'area')}
#'
#' @note The subjects are plotted row-wise, in the order in which they appear in the 'subject_id' parameter. This function is vectorized over 'subject_id' and 'measure'.
#'
#' @note You can force an identical plot range for all subjects, so that one color represents identical values across subjects, via 'makecmap_options'. E.g., for the ... parameter, pass \code{makecmap_options=list('colFn'=viridis::viridis, 'range'=c(0, 4)))}.
#'
#' @return named list, see the return value of \code{\link{arrange.brainview.images.grid}} for details.
#'
#' @family group visualization functions
#'
#' @export
vis.group.morph.native <- function(subjects_dir, subject_id, measure, view_angles = 'sd_dorsal', output_img='fsbrain_group_morph.png', num_per_row = 5L, captions = subject_id, rglactions = list('no_vis'=TRUE), ...) {
num_plots = max(length(subject_id), length(measure));
if(num_plots > length(subject_id)) {
subject_id = recycle(subject_id, num_plots);
captions = subject_id;
}
subjects_dir = recycle(subjects_dir, num_plots);
measure = recycle(measure, num_plots);
coloredmeshes = list();
for(plot_idx in seq.int(num_plots)) {
coloredmeshes[[plot_idx]] = vis.subject.morph.native(subjects_dir[plot_idx], subject_id[plot_idx], measure[plot_idx], views='si', rglactions = rglactions, ...);
}
return(invisible(vis.group.coloredmeshes(coloredmeshes, view_angles = view_angles, output_img = output_img, num_per_row = num_per_row, captions = captions)));
}
#' @title Plot standard space morphometry data for a group of subjects.
#'
#' @description Plot standard space morphometry data for a group of subjects and combine them into a single large image.
#'
#' @inheritParams vis.group.morph.native
#'
#' @param fwhm vector of character strings, the smoothing kernel FWHM strings, e.g., \code{c('0', '10', '15')}
#'
#' @note The subjects are plotted row-wise, in the order in which they appear in the 'subject_id' parameter. This function is vectorized over 'subject_id', 'measure' and 'fwhm'.
#'
#' @note You can force an identical plot range for all subjects, so that one color represents identical values across subjects, via 'makecmap_options'. E.g., for the ... parameter, pass \code{makecmap_options=list('colFn'=viridis::viridis, 'range'=c(0, 4)))}.
#'
#' @return named list, see the return value of \code{\link{arrange.brainview.images.grid}} for details.
#'
#' @family group visualization functions
#'
#' @export
vis.group.morph.standard <- function(subjects_dir, subject_id, measure, fwhm = "10", view_angles = 'sd_dorsal', output_img='fsbrain_group_morph.png', num_per_row = 5L, captions = subject_id, rglactions = list('no_vis'=TRUE), ...) {
num_plots = max(length(subject_id), length(measure), length(fwhm));
if(num_plots > length(subject_id)) {
subject_id = recycle(subject_id, num_plots);
captions = subject_id;
}
subjects_dir = recycle(subjects_dir, num_plots);
fwhm = recycle(fwhm, num_plots);
measure = recycle(measure, num_plots);
coloredmeshes = list();
for(plot_idx in seq.int(num_plots)) {
coloredmeshes[[plot_idx]] = vis.subject.morph.standard(subjects_dir[plot_idx], subject_id[plot_idx], measure[plot_idx], fwhm=fwhm[plot_idx], views='si', rglactions = rglactions, ...);
}
return(invisible(vis.group.coloredmeshes(coloredmeshes, view_angles = view_angles, output_img = output_img, num_per_row = num_per_row, captions = captions)));
}
#' @title Visualize native space data on a group of subjects.
#'
#' @description Plot surface data on the native space surfaces of a group of subjects and combine the tiles into a single large image.
#'
#' @inheritParams vis.group.morph.native
#'
#' @param morph_data_both named list of numerical vectors, the morph data for both hemispheres of all subjects. Can be loaded with \code{\link{group.morph.native}}.
#'
#' @note The subjects are plotted row-wise, in the order in which they appear in the 'morph_data_both' parameter. The surfaces are loaded in the order of the 'subject_id' parameter, so the order in both must match.
#'
#' @note You can force an identical plot range for all subjects, so that one color represents identical values across subjects, via 'makecmap_options'. E.g., for the ... parameter, pass \code{makecmap_options=list('colFn'=viridis::viridis, 'range'=c(0, 4)))}.
#'
#' @return named list, see the return value of \code{\link{arrange.brainview.images.grid}} for details.
#'
#' @family group visualization functions
#'
#' @export
vis.data.on.group.native <- function(subjects_dir, subject_id, morph_data_both, view_angles = 'sd_dorsal', output_img='fsbrain_group_morph.png', num_per_row = 5L, captions = subject_id, rglactions = list('no_vis'=TRUE), ...) {
num_plots = length(subject_id);
if(num_plots != length(morph_data_both)) {
stop("Number of subjects in 'subject_id' must match number of entries in list 'morph_data_both'.");
}
coloredmeshes = list();
subjects_dir = recycle(subjects_dir, num_plots);
for(plot_idx in seq.int(num_plots)) {
subject = subject_id[[plot_idx]];
coloredmeshes[[plot_idx]] = vis.data.on.subject(subjects_dir[plot_idx], subject_id[plot_idx], morph_data_both=morph_data_both[[subject]], views='si', rglactions = rglactions, ...);
}
return(invisible(vis.group.coloredmeshes(coloredmeshes, view_angles = view_angles, output_img = output_img, num_per_row = num_per_row, captions = captions)));
}
#' @title Visualize standard space data for a group on template.
#'
#' @description Plot standard space data for a group of subjects onto a template brain and combine the tiles into a single large image.
#'
#' @inheritParams vis.group.morph.native
#'
#' @param morph_data_both named list of numerical vectors, 4D array or dataframe, the morph data for both hemispheres of all subjects. Can be loaded with \code{\link{group.morph.standard}} or \code{\link{group.morph.standard.sf}}.
#'
#' @param subjects_dir character string, the path to the SUBJECTS_DIR containing the template subject
#'
#' @param vis_subject_id character string, the template subject name. A typical choice is 'fsaverage'.
#'
#' @return named list, see the return value of \code{\link{arrange.brainview.images.grid}} for details.
#'
#' @family group visualization functions
#'
#' @note The subject data are plotted row-wise, in the order in which they appear in the 'morph_data_both' parameter.
#'
#' @note You can force an identical plot range for all subjects, so that one color represents identical values across subjects, via 'makecmap_options'. E.g., for the ... parameter, pass \code{makecmap_options=list('colFn'=viridis::viridis, 'range'=c(0, 4)))}.
#'
#' @export
vis.data.on.group.standard <- function(subjects_dir, vis_subject_id, morph_data_both, captions = NULL, view_angles = 'sd_dorsal', output_img='fsbrain_group_morph.png', num_per_row = 5L, rglactions = list('no_vis'=TRUE), ...) {
if(length(vis_subject_id) != 1L) {
stop("Parameter 'vis_subject' must have length one: this is the name of the template subject, which must be identical for all plotted datasets.");
}
if(length(subjects_dir) != 1L) {
stop("Parameter 'subjects_dir' must have length one: this is the directory of the template subject.");
}
morph_data_both = group.data.to.array(morph_data_both);
num_plots = dim(morph_data_both)[4];
coloredmeshes = list();
for(plot_idx in seq.int(num_plots)) {
subject_data = morph_data_both[,1,1,plot_idx];
coloredmeshes[[plot_idx]] = vis.data.on.subject(subjects_dir, vis_subject_id, morph_data_both=subject_data, views='si', rglactions = rglactions, ...);
}
return(invisible(vis.group.coloredmeshes(coloredmeshes, view_angles = view_angles, output_img = output_img, num_per_row = num_per_row, captions = captions)));
}
#' @title Plot coloredmeshes for a group of subjects.
#'
#' @description Plot coloredmeshes for a group of subjects into a single image.
#'
#' @inheritParams vis.group.annot
#'
#' @param coloredmeshes a list of coloredmeshes lists, each entry in the outer list contains the hemilist of coloredmeshes (lefgt and right hemisphere mesh) for one subject.
#'
#' @param background_color color for image background (transparency is not supported).
#'
#' @note This is a mid-level function, end users may want to call high-level functions like \code{\link{vis.group.annot}} instead.
#'
#' @return named list, see the return value of \code{\link{arrange.brainview.images.grid}} for details.
#'
#' @family group visualization functions
#'
#' @export
vis.group.coloredmeshes <- function(coloredmeshes, view_angles = 'sd_dorsal', output_img='fsbrain_group_annot.png', num_per_row = 5L, captions = NULL, background_color = "white") {
num_subjects = length(coloredmeshes);
tdir = tempdir();
all_output_images = rep(NA, num_subjects);
for(subject_idx in seq.int(num_subjects)) {
cm = coloredmeshes[[subject_idx]];
subject_output_img = file.path(tdir, sprintf("coloredmesh_num_%d.png", subject_idx));
vislayout.from.coloredmeshes(cm, view_angles=view_angles, output_img=subject_output_img, silent=TRUE, grid_like=TRUE, background_color = background_color);
all_output_images[subject_idx] = subject_output_img;
}
return(invisible(arrange.brainview.images.grid(all_output_images, output_img=output_img, num_per_row = num_per_row, captions = captions, background_color = background_color)));
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.