Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: TrackMateR
Type: Package
Title: Working with TrackMate outputs in R
Version: 0.3.11
Version: 0.3.12
Authors@R:
person(given = "Stephen J",
family = "Royle",
Expand All @@ -21,16 +21,13 @@ VignetteBuilder:
knitr,
rmarkdown
Imports:
doParallel,
dplyr,
foreach,
ggplot2,
ggforce,
patchwork,
parallelly,
reshape2,
utils,
XML,
xml2,
zoo
Suggests:
knitr,
Expand Down
19 changes: 7 additions & 12 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,16 @@ export(plot_tm_width)
export(readGTFile)
export(readTrackMateXML)
export(reportDataset)
import(doParallel)
import(dplyr)
import(ggplot2)
import(parallelly)
import(patchwork)
importFrom(XML,getNodeSet)
importFrom(XML,xmlDoc)
importFrom(XML,xmlGetAttr)
importFrom(XML,xmlParse)
importFrom(XML,xpathApply)
importFrom(XML,xpathSApply)
importFrom(foreach,"%do%")
importFrom(foreach,"%dopar%")
importFrom(foreach,foreach)
importFrom(ggforce,geom_sina)
importFrom(graphics,frame)
importFrom(graphics,hist)
importFrom(parallelly,availableCores)
importFrom(parallel,detectCores)
importFrom(parallel,mclapply)
importFrom(reshape2,melt)
importFrom(stats,aggregate)
importFrom(stats,approx)
importFrom(stats,coef)
importFrom(stats,dist)
Expand All @@ -62,4 +53,8 @@ importFrom(utils,data)
importFrom(utils,install.packages)
importFrom(utils,read.csv)
importFrom(utils,write.csv)
importFrom(xml2,read_xml)
importFrom(xml2,xml_attr)
importFrom(xml2,xml_find_all)
importFrom(xml2,xml_find_first)
importFrom(zoo,rollmean)
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# TrackMateR

# TrackMateR 0.3.12

- Moved from {XML} to {xml2} for reading TrackMate XML files. Future-proof but currently slower.
- Large speed improvement when analysing multiple datasets.
- Better memory management when analysing large datasets.

# TrackMateR 0.3.11

- Better handling of more than one channel in TrackMate XML files
Expand Down
19 changes: 7 additions & 12 deletions R/TrackMateR-package.R
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#' @importFrom foreach %do%
#' @importFrom foreach %dopar%
#' @importFrom foreach foreach
#' @importFrom ggforce geom_sina
#' @importFrom graphics frame
#' @importFrom graphics hist
#' @importFrom parallelly availableCores
#' @importFrom parallel detectCores
#' @importFrom parallel mclapply
#' @importFrom reshape2 melt
#' @importFrom stats aggregate
#' @importFrom stats approx
#' @importFrom stats quantile
#' @importFrom stats sd
Expand All @@ -19,17 +18,13 @@
#' @importFrom utils install.packages
#' @importFrom utils read.csv
#' @importFrom utils write.csv
#' @importFrom XML xmlParse
#' @importFrom XML getNodeSet
#' @importFrom XML xpathSApply
#' @importFrom XML xmlGetAttr
#' @importFrom XML xmlDoc
#' @importFrom XML xpathApply
#' @importFrom xml2 read_xml
#' @importFrom xml2 xml_find_all
#' @importFrom xml2 xml_find_first
#' @importFrom xml2 xml_attr
#' @importFrom zoo rollmean
#' @import ggplot2
#' @import dplyr
#' @import patchwork
#' @import doParallel
#' @import parallelly
NULL
#> NULL
67 changes: 32 additions & 35 deletions R/calculateTrackDensity.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,49 +16,46 @@
#' tdDF <- calculateTrackDensity(dataList = tmObj, radius = 2)
#' @export

calculateTrackDensity <- function(dataList, radius = 1) {
x <- y <- trace <- NULL

if(inherits(dataList, "list")) {
df <- dataList[[1]]
calibration <- dataList[[2]]
} else {
calculateTrackDensity <- function(dataList, radius = 1) {
# base R optimized version
if (!inherits(dataList, "list")) {
cat("Function requires a list of TrackMate data and calibration data\n")
return(NULL)
}
# make a list of all traces (this is the filtered list of traces from TrackMate XML)
df <- dataList[[1]]
calibration <- dataList[[2]]
traceList <- unique(df$trace)

# for each trace, find the first frame
for (i in traceList) {
a <- df %>%
filter(trace == i) %>%
select(frame, x, y)
frame0 <- a$frame[1]
x0 <- a$x[1]
y0 <- a$y[1]
# select first frame for this track
a <- df %>%
filter(frame == frame0) %>%
select(x, y)
# calculate the distance from x0, y0 to all other coords
distances <- find_distances(x0,y0,a)
# count how many are less than search radius (this will include the track itself, so subtract 1)
neighbours <- sum(distances <= radius, na.rm = TRUE) - 1
# calculate how much of the search circle was inside the frame
search_fraction <- find_td_area(r = radius, xy = c(x0,y0), a= c(0,calibration[3,1]), b = c(0,calibration[4,1])) / (pi * radius^2)
subdf <- data.frame(trace = i,
neighbours = neighbours,
fraction = search_fraction)
if(i == traceList[1]) {
dfall <- subdf
} else {
dfall <- rbind(dfall,subdf)
}
# Precompute starting positions for all traces
first_frame_idx <- match(traceList, df$trace)
frame0s <- df$frame[first_frame_idx]
x0s <- df$x[first_frame_idx]
y0s <- df$y[first_frame_idx]

# Preallocate result vectors
neighbours <- numeric(length(traceList))
fractions <- numeric(length(traceList))

for (j in seq_along(traceList)) {
frame0 <- frame0s[j]
x0 <- x0s[j]
y0 <- y0s[j]
# select all tracks in the same starting frame
idx <- which(df$frame == frame0)
x_all <- df$x[idx]
y_all <- df$y[idx]
# vectorized distance calculation
dists <- sqrt((x_all - x0)^2 + (y_all - y0)^2)
neighbours[j] <- sum(dists <= radius, na.rm = TRUE) - 1
# search area fraction
fractions[j] <- find_td_area(r = radius, xy = c(x0, y0), a = c(0, calibration[3,1]), b = c(0, calibration[4,1])) / (pi * radius^2)
}
# divide the count by the fraction of circle that was inside the frame to give "density" - do this at the end
dfall$density <- dfall$neighbours / dfall$fraction

dfall <- data.frame(trace = traceList,
neighbours = neighbours,
fraction = fractions)
dfall$density <- dfall$neighbours / dfall$fraction
return(dfall)
}

Expand Down
Loading