Skip to contents

Given an object of class "tracklets" containing a list of tracklets which contain two variable of interest the function use density based clustering as introduced in Ester et al. (1996). As a result, the function use the DBSCAN method from Hennig (2020) to discriminate active and inactive states in a 2d space by returning numeric values indicating whether the particle is "active" (1) or "inactive" (0).

Usage

activity2(
  trackDat,
  var1 = NULL,
  var2 = NULL,
  var1T = NULL,
  var2T = NULL,
  nbins = NULL,
  eps = NULL,
  minPts = NULL,
  scale = TRUE,
  na.rm = TRUE
)

Arguments

trackDat

An object of class "tracklets" containing a list of tracklets and their characteristics classically used for further computations.

var1

A character string indicating the name of the variable to use as the first dimension.

var2

A character string indicating the name of the variable to use as the second dimension.

var1T

A function used to transform var1 (e.g., log, sqrt - optional).

var2T

A function used to transform var2 (e.g., log, sqrt - optional).

nbins

A numeric value indicating the number of bins in both vertical and horizontal directions (default = 100).

eps

A numeric value specifying the reachability distance (Ester et al., 1996), which correspond to the maximum distance around cluster's members (see dbscan).

minPts

A numeric value specifying the reachability minimum no. of points (Ester et al., 1996), which correspond to the minimum number of point per cluster (see dbscan).

scale

A logical value (i.e., TRUE or FALSE) indicating whether the data should be centered (i.e., values minus the mean) and scaled (divided by the standard deviation) (default = TRUE).

na.rm

A logical value (i.e., TRUE or FALSE) indicating whether NA values should be stripped before the computation proceeds (default = TRUE).

Value

This function returns the results of the classification (actives vs. inactives) as numeric value (1 or 0, respectively) appended to each tracklet of the "tracklets" object.

References

  • Christian, H., (2020). fpc: Flexible Procedures for Clustering. R package version 2.2-9. https://CRAN.R-project.org/package=fpc

  • Ester, M., Kriegel H.P., Sander, J., Xu X., (1996). A Density-Based Algorithm for Discovering Clusters in Large Spatial Databases with Noise. Institute for Computer Science, University of Munich. Proceedings of 2nd International Conference on Knowledge Discovery and Data Mining (KDD-96).

See also

Author

Quentin PETITJEAN

Examples

if (FALSE) {

# Download the first dataset from the sample data repository
Path2Data <- MoveR::DLsampleData(dataSet = 1, tracker = "TRex")
Path2Data

# Import the list containing the 9 vectors classically used for further computation
trackDat <- MoveR::readTrex(Path2Data[[1]])

# infinite values that are present in the tracking output should be removed
## define the filter
filter.Inf <-
  MoveR::filterFunc(
    trackDat,
    toFilter = "x.pos",
    customFunc = function(x)
     is.infinite(x)
  )

### filter Infinite values
trackDat.Infilt <-
  MoveR::filterTracklets(trackDat,
                     filter = filter.Inf,
                     splitCond = TRUE,
                     minDur = 100)

### retrieve the list of tracklets
trackdat2 <- trackDat.Infilt[[2]]

# check the tracklet
MoveR::drawTracklets(trackdat2)

# add some metric to the dataset to perform 2d clustering (speed and turning angle)
# and smooth them by computing the mean value over a 10 frames' sliding window
Tstep = 10
trackdat3 <-
  MoveR::analyseTracklets(
    trackdat2,
    customFunc = list(
      # specify a first function to compute speed over each tracklet (a modulus present within the MoveR package)
      speed = function(x)
        MoveR::speed(x),
      # compute turning angle in radians over each tracklet (a modulus present within the MoveR package)
      TurnAngle = function(x)
        MoveR::turnAngle(x),
      # smooth variance of turning angles
      SlideVarAngle = function (y)
        MoveR::slidWindow(y$TurnAngle,
                       Tstep = Tstep, 
                       statistic = 'circular.var',
                       na.rm = TRUE),
      # smooth speed
      slideMeanSpeed = function (y)
        MoveR::slidWindow(y$speed,
                       Tstep = Tstep, 
                       statistic = 'mean', 
                       na.rm = TRUE)
    )
  )

# use density based clustering to classify actives and inactives states in a 2 dimension array (here the speed and the angle variance)

trackdat3 <- MoveR::activity2(
  trackdat3,
  var1 = "slideMeanSpeed",
  var2 = "SlideVarAngle",
  var1T = log10,
  nbins = 100,
  eps = 0.15,
  minPts = 5,
  scale = TRUE,
  na.rm = TRUE
)

## optional, it is possible to draw the distribution of the count in 2 dimension space 
# compute the count matrix in the 2d space with the same parameter than activity2 function
trackDatL <- MoveR::convert2List(trackdat3)
outP <- MoveR::countMat(x = log10(trackDatL[["slideMeanSpeed"]]), 
                 y = trackDatL[["SlideVarAngle"]],
                 groups = trackDatL[["activity2"]],
                 nbins = 100,
                 output = "matrix")

# retrieve max and min value of sqrt-transformed count over the groups for plotting
maxVal <- max(unlist(lapply(outP, function(z) max(sqrt(z)))))
minVal <- min(unlist(lapply(outP, function(z) min(sqrt(z)))))

# draw the plot using plotly (3d interactive plot)
library(plotly)
fig <- plotly::plot_ly(x=~colnames(outP[[1]]), y=~rownames(outP[[1]]), contours = list(
  z = list(
    show = TRUE,
    start = round(minVal,-2),
    project = list(z = TRUE),
    end = round(maxVal,-2),
    size = max(maxVal) / 10,
    color = "white"
  )
))
# add inactive layer
fig <- plotly::add_surface(
  p = fig,
  z = sqrt(outP[[1]]),
  opacity = 0.8,
  colorscale = "Hot",
  cmin = min(sqrt(outP[[1]])),
  cmax = max(sqrt(outP[[1]])),
  colorbar = list(title = "inactive\ncounts (sqrt)")
)
# add active layer
fig <- plotly::add_surface(
  p = fig,
  z = sqrt(outP[[2]]),
  opacity = 1,
  colorscale = list(
    c(0, 0.25, 1),
    c("rgb(20,20,20)", "rgb(58,139,44)", "rgb(234,239,226)")
  ),
  colorbar = list(title = "active\ncounts (sqrt)")
)
fig <- plotly::layout(
  fig,
  title = '3D density plot of activity states',
  scene1 = list(
    xaxis = list(title = "slideMeanSpeed (log10)"),
    yaxis = list(title = "slideVarAngle"),
    zaxis = list(title = "counts (sqrt)")
  )
)
fig

# draw the particle' trajectory and spot the inactive moments using red dots
MoveR::drawTracklets(trackdat3,
          cex.start = 0.1,
          add2It = list(for (i in seq_along(trackdat3)) {
            points(
              trackdat3[[i]][["x.pos"]][which(trackdat3[[i]][["activity2"]] == 0)],
              trackdat3[[i]][["y.pos"]][which(trackdat3[[i]][["activity2"]] == 0)],
              col = "red",
              pch = 19,
              cex = 1.5
            )
          }))

}