Skip to content

Instantly share code, notes, and snippets.

@tractatus
Last active November 26, 2018 19:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tractatus/306a62f091a8c3562f5bc3e5db9a41e5 to your computer and use it in GitHub Desktop.
Save tractatus/306a62f091a8c3562f5bc3e5db9a41e5 to your computer and use it in GitHub Desktop.
Stitch WholeBrain Perkin-Elmer
#' Sticthing on a Perkin-Elmer instrument
#'
#' This function allows you to stitch image tiles from Perkin Elmer Harmony software contained in a single folder.
#' @param folder a path to a folder containing image tiles in TIFF format and XML file for metadata.
#' @param digits number of significant digits to round up the position X,Y reported by Harmony XML metadata (this is used for matching).
#' @return a character vector with images that have been stitched.
#' @keywords perkin-elmer
#' @export
#' @examples
#' stitch.perkin.elmer('./Images')
stitch.perkin.elmer<-function(folder, digits = 4, ...){
#check if folder exist first
if(!file.exists(folder))
stop(paste('The folder:', folder, 'does not exist'))
#Get metadata from XML file
xml_source <- which(tools::file_ext(dir(folder)) == 'xml')
xml_source <- paste(path.expand(folder), dir(folder)[xml_source], sep = "/")
doc <- xmlInternalTreeParse(xml_source)
ns <- getDefaultNamespace(doc)[[1]]$uri
names(ns)[1] <- "xmlns"
#Extract metadata into img list object
img<-list()
img$x<-as.numeric(xpathSApply(doc,"//xmlns:PositionX", xmlValue, namespaces = ns))
img$y<-as.numeric(xpathSApply(doc,"//xmlns:PositionY", xmlValue, namespaces = ns))
img$name<-xpathSApply(doc,"//xmlns:URL", xmlValue, namespaces = ns)
img$channel<-regmatches(img$name, regexpr("ch[0-9]+", img$name))
#Get order of images
sorted.x<-sort(unique(round(img$x, digits)))
sorted.y<-sort(unique(round(img$y, digits)))
#get the theoretical position of each spot in a grid.
theoretical.position<-expand.grid(sorted.x, sorted.y)
order.matrix<-do.call("rbind", lapply(1:nrow(theoretical.position), function(x)which(round(img$x, digits) == theoretical.position[x,1] & round(img$y, digits) == theoretical.position[x,2] )))
#loop through all channels
output.files<-rep('', length(unique(img$channel)))
for(i in seq_along(unique(img$channel)) ){
cat(paste('PROCESSING CHANNEL', unique(img$channel)[i], '\n' ))
input<-img$name
input<-input[order.matrix[,i]]
input<-paste0(folder, '/', input)
output.files[i]<-stitch(input, rotate = 90, tilesize = 1080, type = "row.by.row", order = "right.&.up", stitched.image.name = paste0("stitched_", unique(img$channel)[i],".tif"), ...)
}
return(output.files)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment