#' Synchronize camera frames
#'
#'
#' @param obj A target image of Image object or an array.
#' @param ref A reference image of Image object or an array.
#' @export
#' @examples
#' sync_frames()
sync_frames <- function(dir, fluo_flash, fly_flash, arena_flash, output, reuse=F){
# Start time
message("Analyzing metadata")
metadata <-scan(paste0(dir, list.files(dir, pattern="metadata\\.txt$")), what=character(),sep="")
log <- scan(paste0(dir, list.files(dir, pattern="fv-log-")), what=character(),sep="")
avlog <- scan(paste0(dir, list.files(dir, pattern="av-log-")), what=character(),sep="")
starttimefl <- metadata[which(metadata == "Time")[1]+2]
# Exposure and binning
exposure <- substr(metadata[which(metadata == "Exposure-ms")[1]+2], 1, nchar(metadata[which(metadata == "Exposure-ms")[1]+2])-1)
message(sprintf("fluo-view exposure: %s ms", exposure))
# Elapsed time (in ms) of each frame from the fluorescence camera relative to the flash
elapsedtimefl <- metadata[grep("ElapsedTime-ms", metadata)+2]
elapsedtimefl <- as.numeric(substr(elapsedtimefl, 1, nchar(elapsedtimefl)-1))
fpsfl <- round((length(elapsedtimefl)-1)/(tail(elapsedtimefl, n=1) - elapsedtimefl[1])*1000)
message(paste("fluo-view fps:", fpsfl))
elapsedtime <- elapsedtimefl - elapsedtimefl[fluo_flash$fvflashes[1]]
# Elapsed time (in ms) of each frame from the fly view camera
timestampusec <- as.numeric(log[grep("TimeStamp", log)+1])
# fix rollover of raw timestamp (after 2^31 usec, time stamp rolls over to 0)
timestampusec_fix = timestampusec + (timestampusec < timestampusec[1]) * 2^31
elapsedtimefv <- (timestampusec_fix - timestampusec_fix[1])/1000
elapsedtimefvflash <- elapsedtimefv - elapsedtimefv[fly_flash$fvflashes[1]]
fpsfv <- round((length(elapsedtimefv) - 1)/((tail(elapsedtimefv, n=1) - elapsedtimefv[1])/1000))
message(paste("fly-view fps:", fpsfv))
framediff <- diff(elapsedtimefvflash)
# Elapsed time (in ms) of each frame from the arenaview camera
avtimestampcyclesec <- avlog[grep("TimeStamp", avlog)+1]
avtimestampcyclesec <- as.numeric(avtimestampcyclesec)
cnt <- 0
avtimestampsec <- rep(0, length(avtimestampcyclesec))
avtimestampsec[1] <- avtimestampcyclesec[1]
for(t in 2:length(avtimestampsec)){
if(avtimestampcyclesec[t-1]==127 & avtimestampcyclesec[t]==0) cnt <- cnt + 1
avtimestampsec[t] <- avtimestampcyclesec[t] + 127*cnt
}
avtimestampsec <- avtimestampsec*1000
avtimestampcnt <- avlog[grep("TimeStamp", avlog)+2]
avtimestampmsec <- 1/8000*as.numeric(avtimestampcnt)*1000
elapsedtimeav <- (avtimestampsec + avtimestampmsec) - (avtimestampsec[1] + avtimestampmsec[1])
elapsedtimeavflash <- elapsedtimeav - elapsedtimeav[arena_flash$avflashes[1]]
fpsav <- round((length(elapsedtimeav)-1)/((tail(elapsedtimeav, n=1) - elapsedtimeav[1])/1000))
message(paste("arena-view fps:", fpsav))
# Align frames between fly-view and fluo-view
message("Aligning frames between fly-view and fluo-view")
if(file.exists(paste0(output, "_frid.RDS"))==T & reuse==T){
message("Loading RDS file")
frid <- readRDS(paste0(output, "_frid.RDS"))
}else{
frameratio <- round(fpsfv/fpsfl)
message(paste0("fv/fl frame ratio: ", frameratio))
# Hypothetical trigger
frid <- seq(fly_flash$fvflashes[1]-(fluo_flash$flflashes[1]-1)*frameratio,
fly_flash$fvflashes[1]+frameratio*(fluo_flash$nframesfl-fluo_flash$flflashes[1]), frameratio)
# Check if two flashes match
fvflashesfrid <- frid[fluo_flash$flflashes]
message(sprintf("Hypothetical flash for fly-view: %s", paste(fvflashesfrid, collapse=" ")))
message(sprintf("Actual flash for fly-view: %s", paste(fly_flash$fvflashes, collapse=" ")))
if(all.equal(fvflashesfrid, fly_flash$fvflashes)==T){
message(paste0("Hypothetical flashes match actual flashes in fly-view."))
}else{
message(paste0("Hypothetical flashes didn't match actual flashes in fly-view. Syncing failed?"))
}
if(length(fluo_flash$flflashes)!=length(fly_flash$fvflashes)) {
warning("Number of flash in fly-view and fluo-view didn't match.")
}
frid <- frid[which(frid<=fly_flash$nframesfv)]
if(length(frid) < fluo_flash$nframesfl){
frid <- c(frid, rep(tail(frid, 1), fluo_flash$nframesfl-length(frid)))
}
saveRDS(frid, paste0(output, "_frid.RDS"))
}
# Align frames between fluo-view and arena-view
message("Aligning frames between fluo-view and arena-view")
if(file.exists(paste0(output, "_frida.RDS")) & reuse==T){
message("Loading RDS file")
frida <- readRDS(paste0(output, "_frida.RDS"))
}else{
frameratio2 <- round(fpsav/fpsfl)
message(paste0("av/fl frame ratio: ", frameratio2))
# Hypothetical trigger
frida <- seq(arena_flash$avflashes[1]-(fluo_flash$flflashes[1]-1)*frameratio2,
arena_flash$avflashes[1]+frameratio2*(fluo_flash$nframesfl-fluo_flash$flflashes[1]), frameratio2)
# Check if two flashes match
avflashesfridav <- frida[fluo_flash$flflashes]
message(sprintf("Hypothetical flash for arena-view: %s", paste(avflashesfridav, collapse=" ")))
message(sprintf("Actual flash for arena-view: %s", paste(arena_flash$avflashes, collapse=" ")))
if(all.equal(avflashesfridav, arena_flash$avflashes)==T){
message(paste0("Hypothetical flashes match actual flashes in arena-view."))
}else{
message(paste0("Hypothetical flashes didn't match actual flashes in arena-view. Syncing failed?"))
}
if(length(fluo_flash$flflashes)!=length(arena_flash$avflashes)) {
message("Number of flash in arena-view and fluo-fiew did not match.")
}
frida <- frida[which(frida<=arena_flash$nframesav)]
if(length(frida) < fluo_flash$nframesfl){
frida <- c(frida, rep(tail(frida, 1), fluo_flash$nframesfl-length(frida)))
}
saveRDS(frida, paste0(output, "_frida.RDS"))
}
return(list("fpsfv"=fpsfv, "elapsedtimeavflash"=elapsedtimeavflash, "frid"=frid, "frida"=frida))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.