Nothing
#' @title Add metadata to GIFTI XML tree.
#'
#' @param xmltree XML tree from xml2
#'
#' @param metadata_named_list named list, the metadata entries
#'
#' @param as_cdata logical, whether to wrap the value in cdata tags
#'
#' @return the modified tree.
#'
#' @note Assumes that there already exists a global MetaData node. Also not that this is not supposed to be used for adding metadata to datarrays.
#'
#' @examples
#' \dontrun{
#' xmltree = gifti_xml(list(rep(3.1, 3L), matrix(seq(6)+0.1, nrow=2L)));
#' newtree = gifti_xml_add_global_metadata(xmltree, list("User"="Me", "Weather"="Great"));
#' gifti_xsd = "https://www.nitrc.org/frs/download.php/158/gifti.xsd";
#' xml2::xml_validate(newtree, xml2::read_xml(gifti_xsd));
#' }
#' @export
gifti_xml_add_global_metadata <- function(xmltree, metadata_named_list, as_cdata=TRUE) {
xpath='.//MetaData';
for(name in names(metadata_named_list)) {
value = metadata_named_list[[name]];
md_node = xml_node_gifti_MD(name, value, as_cdata=as_cdata);
metadata_node = xml2::xml_find_first(xmltree, xpath);
xml2::xml_add_child(metadata_node, md_node);
}
return(xmltree);
}
#' @title Create XML GIFTI metadata node.
#'
#' @param name character string, the metadata name
#'
#' @param value character string, the metadata value
#'
#' @param as_cdata logical, whether to wrap the value in cdata tags
#'
#' @note This creates an MD note, not the outer MetaData node.
#'
#' @return XML tree from xml2
#'
#' @keywords internal
xml_node_gifti_MD <- function(name, value, as_cdata=TRUE) {
if(as_cdata) {
name = cdata(name);
value = cdata(value);
}
return(xml2::read_xml(paste('<MD><Name>', name, '</Name><Value>', value, '</Value></MD>', sep="")));
}
#' @title Create CDATA element string from string.
#'
#' @param string character string, the input string, freeform text. Must not contain the cdata start and end tags.
#'
#' @return character string, the input wrapped in the cdata tags
#'
#' @note This returns a string, not an XML node. See \code{\link[xml2]{xml_cdata}} if you want a node.
#'
#' @export
cdata <- function(string) {
cdata_start_tag = "<![CDATA[";
cdata_end_tag = "]]>";
if(grepl(string, cdata_start_tag, fixed = TRUE)) {
stop(sprintf("Input string must not contain the cdata start tag '%s'.\n", cdata_start_tag));
}
if(grepl(string, cdata_end_tag, fixed = TRUE)) {
stop(sprintf("Input string must not contain the cdata end tag '%s'.\n", cdata_end_tag));
}
return(paste(cdata_start_tag, string, cdata_end_tag, sep=""));
}
#' @title Create XML GIFTI Label node.
#'
#' @param attributes named list, the attributes
#'
#' @param value the text contents of the node, usually the region name
#'
#' @param as_cdata logical, whether to wrap the value in cdata tags
#'
#' @return XML node from xml2
#'
#' @importFrom xml2 read_xml xml_set_attrs
#' @keywords internal
xml_node_gifti_label <- function(value, attributes=list(), as_cdata=TRUE) {
if(! is.list(attributes)) {
stop("Parameter 'value' must be a named list.");
}
if(as_cdata) {
value = cdata(value);
}
label_node = xml2::read_xml(paste('<Label>', value, '</Label>', sep=''));
xml2::xml_set_attrs(label_node, attributes);
return(label_node);
}
#' @title Create XML GIFTI CoordinateSystemTransformMatrix node.
#'
#' @param transform_matrix numerical 4x4 matrix, the transformation matrix from 'data_space' to 'transformed_space'.
#'
#' @param data_space character string, the space used by the data before transformation.
#'
#' @param transformed_space character string, the space reached after application of the transformation matrix.
#'
#' @param as_cdata logical, whether to wrap text attributes ('data_space' and 'transformed_space') in cdata tags.
#'
#' @return XML node from xml2
#'
#' @importFrom xml2 read_xml xml_set_attrs
#' @export
# @keywords internal
xml_node_gifti_coordtransform <- function(transform_matrix, data_space='NIFTI_XFORM_UNKNOWN', transformed_space='NIFTI_XFORM_UNKNOWN', as_cdata=TRUE) {
if(! is.character(data_space)) {
stop("Parameter 'data_space' must be a character string.");
}
if(! is.character(transformed_space)) {
stop("Parameter 'transformed_space' must be a character string.");
}
if(! is.matrix(transform_matrix)) {
stop("Parameter 'transform_matrix' must be a numerical matrix.");
}
if(! (ncol(transform_matrix) == 4L & nrow(transform_matrix) == 4L)) {
stop("Parameter 'transform_matrix' must be a numerical 4x4 matrix.");
}
if(as_cdata) {
data_space = cdata(data_space);
transformed_space = cdata(transformed_space);
}
r1 = paste(sprintf("%f", transform_matrix[1, ]), collapse = ' ');
r2 = paste(sprintf("%f", transform_matrix[2, ]), collapse = ' ');
r3 = paste(sprintf("%f", transform_matrix[3, ]), collapse = ' ');
r4 = paste(sprintf("%f", transform_matrix[4, ]), collapse = ' ');
matrix_data_formatted = paste(r1, r2, r3, r4, sep='\n');
matrix_data_formatted = sprintf("\n%s\n", matrix_data_formatted); # start and end in fresh rows.
matrix_node = xml2::read_xml('<CoordinateSystemTransformMatrix/>');
data_space_node = xml2::read_xml(paste('<DataSpace>', data_space, '</DataSpace>', sep=''));
transformed_space_node = xml2::read_xml(paste('<TransformedSpace>', transformed_space, '</TransformedSpace>', sep=''));
matrix_data_node = xml2::read_xml(paste('<MatrixData>', matrix_data_formatted, '</MatrixData>', sep=''));
xml2::xml_add_child(matrix_node, data_space_node);
xml2::xml_add_child(matrix_node, transformed_space_node);
xml2::xml_add_child(matrix_node, matrix_data_node);
return(matrix_node);
}
#' @title Create XML GIFTI LabelTable node.
#'
#' @return XML node from xml2
#'
#' @importFrom xml2 read_xml
#' @keywords internal
xml_node_gifti_label_table <- function(attributes=list()) {
return(xml2::read_xml('<LabelTable></LabelTable>'));
}
#' @title Add a standard label tabel for to a GIFTI XML tree.
#'
#' @description This label table is suitable for labels in the FreeSurfer sense, i.e., if only a positive label (1) and a negative label (0) exist in the label data.
#'
#' @param xmltree an XML tree from xml2, typically the return value from \code{\link[freesurferformats]{gifti_xml}}.
#'
#' @return XML tree from xml2, the modified tree with the LabelTable added below the root node.
#'
#' @importFrom xml2 xml_add_child
#' @keywords internal
giftixml_add_labeltable_posneg <- function(xmltree) {
label_table_node = xml_node_gifti_label_table();
xml2::xml_add_child(label_table_node, xml_node_gifti_label('negative', attributes=list('Key'=0L, 'Index'=0L)));
xml2::xml_add_child(label_table_node, xml_node_gifti_label('positive', attributes=list('Key'=1L, 'Index'=1L)));
xml2::xml_add_child(xmltree, label_table_node);
return(xmltree);
}
#' @title Add a label tabel from an annotation to a GIFTI XML tree.
#'
#' @description Computes the LabelTable XML node for the given annotation and adds it to the XML tree.
#'
#' @param xmltree an XML tree from xml2, typically the return value from \code{\link[freesurferformats]{gifti_xml}}.
#'
#' @param annot an fs.annotation, the included data will be used to compute the LabelTable node
#'
#' @return XML tree from xml2, the modified tree with the LabelTable added below the root node.
#'
#' @importFrom xml2 xml_add_child
# ' @keywords internal
#' @export
giftixml_add_labeltable_from_annot <- function(xmltree, annot) {
label_table_node = xml_node_gifti_label_table_from_annot(annot);
xml2::xml_add_child(xmltree, label_table_node, .where=1); # GIFTI spec requires ordered elements
return(xmltree);
}
#' @title Compute LabelTable node from annotation.
#'
#' @param annot an fs.annotation, the included data will be used to compute the LabelTable node
#'
#' @return XML tree from xml2, the LabelTable and its child nodes
#'
#' @importFrom xml2 xml_add_child
#' @keywords internal
xml_node_gifti_label_table_from_annot <- function(annot) {
label_table_node = xml_node_gifti_label_table();
if(! is.null(annot$colortable_df)) {
for(row_idx in seq.int(nrow(annot$colortable_df))) {
sr = annot$colortable_df[row_idx, ];
xml2::xml_add_child(label_table_node, xml_node_gifti_label(sr$struct_name, attributes=list('Red'=sr$r, 'Green'=sr$g, 'Blue'=sr$b, 'Alpha'=sr$a, 'Key'=sr$code, 'Index'=sr$code)));
}
}
return(label_table_node);
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.