RAF-CIN

Author
Published

February 16, 2023

1 Purpose

  • Predict when rats turn left on right using deeplabcut pose estimates

 

2 Report overview

Source code and data found at https://github.com/maRce10/cage-test_cin_rats_2021-

3 Detecting half-turns with DLCAnalyzerc

DLCAnalyzer

Code
source("./scripts/DLCAnalyzer_Functions_final.R")

3.1 Analyze a single file

Code
Tracking <- ReadDLCDataFromCSV(file = "./data/raw/raf_deeplabcut_csvs/RAFII-01- AMPHDLC_resnet50_rafi_ratas_cinJan8shuffle1_90000.csv",
    fps = 20)

names(Tracking$data)
head(Tracking$data$nose)

Tracking <- CleanTrackingData(Tracking, likelihoodcutoff = 0.95)

body_points <- c("nose", "ear_left", "ear_right", "body_center", "base_tail",
    "tip_tail")
PlotPointData(Tracking, points = body_points)

Tracking <- CalculateMovement(Tracking, movement_cutoff = 5, integration_period = 5)
head(Tracking$data$body_center)

plots <- PlotDensityPaths(Tracking, points = body_points)

plots$body_center

Tracking <- OFTAnalysis(Tracking, points = body_points, movement_cutoff = 5,
    integration_period = 5)
t(data.frame(Tracking$Report))

3.2 Analyze multiple files

Code
input_folder <- "./data/raw/raf_deeplabcut_csvs/"
files <- list.files(input_folder)
files

pipeline <- function(path) {
    Tracking <- ReadDLCDataFromCSV(path, fps = 20)

    Tracking <- CleanTrackingData(Tracking, likelihoodcutoff = 0.95)

    Tracking <- CalculateMovement(Tracking, movement_cutoff = 5, integration_period = 5)

    Tracking <- OFTAnalysis(Tracking, points = "bodycentre", movement_cutoff = 5,
        integration_period = 5)
    return(Tracking)
}

TrackingAll <- RunPipeline(files, input_folder, FUN = pipeline)

3.3 Train an ML classifier

Code
labeling.data <- read.table("./scripts/FSTLables_Oliver.csv", sep = ";",
    header = T)
pointinfo <- read.table("./scripts/FST_pointinfo.csv", sep = ";",
    header = T)
files <- unique(labeling.data$CSVname)
path <- "./scripts/DLC_Data/"
pipeline <- function(path) {
    Tracking <- ReadDLCDataFromCSV(path, fps = 25)
    Tracking <- CutTrackingData(Tracking, start = 300, end = 300)
    Tracking <- CalibrateTrackingData(Tracking, "distance", in.metric = 20,
        c("t", "b"))
    Tracking <- CleanTrackingData(Tracking, likelihoodcutoff = 0.95)
    Tracking <- AddLabelingData(Tracking, labeling.data[labeling.data$CSVname ==
        Tracking$filename, ])
    Tracking <- CalculateAccelerations(Tracking)
    Tracking <- CreateAccelerationFeatures(Tracking)
    Tracking <- CreateTrainingSet(Tracking, integration_period = 20)
    Tracking <- AddPointInfo(Tracking, pointinfo)
    Tracking <- FSTAnalysis(Tracking, cutoff_floating = 0.03, integration_period = 5,
        points = "bodycentre", Object = "Mouse")
    return(Tracking)
}
Code
TrackingAll <- RunPipeline(files, path, FUN = pipeline)
Code
evaluation <- list()

for (i in names(TrackingAll)) {
    # combine training data from all files except the one we
    # want to evaluate
    MLData <- CombineTrainingsData(TrackingAll[names(TrackingAll) !=
        i], shuffle = TRUE)

    # initialize model
    model <- keras_model_sequential()
    model %>%
        layer_dense(units = 256, activation = "relu", input_shape = c(MLData$parameters$N_input),
            kernel_regularizer = regularizer_l2(l = 0)) %>%
        layer_dropout(rate = 0.4) %>%
        layer_dense(units = 128, activation = "relu", kernel_regularizer = regularizer_l2(l = 0)) %>%
        layer_dropout(rate = 0.3) %>%
        layer_dense(units = MLData$parameters$N_features, activation = "softmax")

    # define optimizer
    model %>%
        compile(loss = "categorical_crossentropy", optimizer = optimizer_rmsprop(),
            metrics = c("accuracy"))

    # train model
    history <- model %>%
        fit(MLData$train_x, MLData$train_y, epochs = 5, batch_size = 32,
            validation_split = 0)

    # we now use this model to classify the behavior in the
    # cross validation file
    TrackingAll[[i]] <- ClassifyBehaviors(t = TrackingAll[[i]], model,
        model_parameters = MLData$parameters)

}

PlotLabels(t = TrackingAll$FST_1.csv)
PlotLabels(TrackingAll$FST_2.csv)

EvaluateClassification(ts = TrackingAll)

PlotLabels.Multi.PDF(TrackingAll)

3.4 Training a classifier and cross validating it

Code
labeling.data <- read.table("./scripts/FSTLables_Oliver.csv", sep = ";",
    header = T)
pointinfo <- read.table("./scripts/FST_pointinfo.csv", sep = ";",
    header = T)
files <- unique(labeling.data$CSVname)
path <- "./scripts/DLC_Data/"

pipeline <- function(path) {
    Tracking <- ReadDLCDataFromCSV(path, fps = 25)
    Tracking <- CutTrackingData(Tracking, start = 300, end = 300)
    Tracking <- CalibrateTrackingData(Tracking, "distance", in.metric = 20,
        c("t", "b"))
    Tracking <- CleanTrackingData(Tracking, likelihoodcutoff = 0.95)
    Tracking <- AddLabelingData(Tracking, labeling.data[labeling.data$CSVname ==
        Tracking$filename, ])
    Tracking <- CalculateAccelerations(Tracking)
    Tracking <- CreateAccelerationFeatures(Tracking)
    Tracking <- CreateTrainingSet(Tracking, integration_period = 20)
    Tracking <- AddPointInfo(Tracking, pointinfo)
    Tracking <- FSTAnalysis(Tracking, cutoff_floating = 0.03, integration_period = 5,
        points = "bodycentre", Object = "Mouse")
    return(Tracking)
}

TrackingAll <- RunPipeline(files, path, FUN = pipeline)
Code
evaluation <- list()

for (i in names(TrackingAll)) {
    # combine training data from all files except the one we
    # want to evaluate
    MLData <- CombineTrainingsData(TrackingAll[names(TrackingAll) !=
        i], shuffle = TRUE)

    # initialize model
    model <- keras_model_sequential()
    model %>%
        layer_dense(units = 256, activation = "relu", input_shape = c(MLData$parameters$N_input),
            kernel_regularizer = regularizer_l2(l = 0)) %>%
        layer_dropout(rate = 0.4) %>%
        layer_dense(units = 128, activation = "relu", kernel_regularizer = regularizer_l2(l = 0)) %>%
        layer_dropout(rate = 0.3) %>%
        layer_dense(units = MLData$parameters$N_features, activation = "softmax")

    # define optimizer
    model %>%
        compile(loss = "categorical_crossentropy", optimizer = optimizer_rmsprop(),
            metrics = c("accuracy"))

    # train model
    history <- model %>%
        fit(MLData$train_x, MLData$train_y, epochs = 5, batch_size = 32,
            validation_split = 0)

    # we now use this model to classify the behavior in the
    # cross validation file
    TrackingAll[[i]] <- ClassifyBehaviors(TrackingAll[[i]], model,
        MLData$parameters)

}
Code
EvaluateClassification(TrackingAll)

4 DLCAnalyzer on CIN data

4.1 Organizing data

Code
csvs <- list.files(path = "./data/processed/solomon_turn_annotations",
    pattern = "csv$", full.names = TRUE)

out <- warbleR:::pblapply_wrblr_int(X = csvs, cl = 10, function(x) {
    # print()
    y <- read.csv(x, header = FALSE, skip = 1)
    y$ms <- sapply(strsplit(y[, 2], ";"), "[", 1)
    y$behav <- sapply(strsplit(y[, 2], ";"), "[", 2)
    y$type <- ifelse(y$behav == "Inmovilidad", "left", ifelse(y$behav ==
        "Digging", "right", NA))
    y$CSVname <- basename(x)
    y$time <- y$V1 + as.numeric(y$ms)/100
    y$V2 <- y$V1 <- y$ms <- y$behav <- NULL
    y$start <- ifelse(is.na(y$type), y$time - 0.04, y$time - 0.055)
    y$end <- ifelse(is.na(y$type), y$time + 0.04, y$time + 0.055)
    y$sound.files <- y$CSVname
    y$selec <- 1:nrow(y)
    mo <- merge_overlaps(y, pb = FALSE)
    mo$from <- mo$start + 0.055
    mo$to <- mo$end - 0.055
    mo$start <- mo$end <- mo$selec <- mo$sound.files <- mo$time <- NULL
    mo <- mo[!is.na(mo$type), ]
    return(mo)
})

turn_annot <- do.call(rbind, out)

dlc_files <- list.files(path = "./data/raw/raf_deeplabcut_csvs", pattern = "\\.csv$")

turn_annot$Experimento <- ifelse(grepl("RAFII", turn_annot$CSVname),
    "RAFII", "RAFI")

turn_annot$Animal <- substring(0, 2, text = gsub("RAFI-|RAFII-", "",
    turn_annot$CSVname))

turn_annot$dia.num <- NA
turn_annot$dia.num[grep("DÍA 1.csv", turn_annot$CSVname)] <- 1
turn_annot$dia.num[grep("-1.csv", turn_annot$CSVname)] <- -1
turn_annot$dia.num[grep("7.csv", turn_annot$CSVname)] <- 7
turn_annot$dia.num[grep("21.csv|APO", turn_annot$CSVname)] <- 21
turn_annot$dia.num[grep("AMP", turn_annot$CSVname)] <- 14
turn_annot[!duplicated(turn_annot$CSVname), ]

turn_annot$id <- paste0(turn_annot$Experimento, "-", turn_annot$Animal,
    " DÍA ", turn_annot$dia.num)

turn_annot$id[turn_annot$id == "RAFII-13 DÍA 21"] <- "RAFII-13 APO"
turn_annot$id[turn_annot$id == "RAFII-1 DÍA 14"] <- "RAFII-01 PRE AMP"
turn_annot$id[turn_annot$id == "RAFII-8 DÍA 1"] <- "RAFII-08 DÍA 1"
turn_annot$id[turn_annot$id == "RAFII-15 DÍA 14"] <- "RAFII-15 AMP"
turn_annot$id[turn_annot$id == "RAFII-4 DÍA 21"] <- "RAFII-04 APO"
turn_annot$id[turn_annot$id == "RAFII-9 DÍA 1"] <- "RAFII-09 DÍA 1"
turn_annot$id[turn_annot$id == "RAFII-11 DÍA 21"] <- "RAFII-11 APO"
turn_annot$id[turn_annot$id == "RAFI-10 DÍA 21"] <- "RAFI-10_pre_APO"
turn_annot$id[turn_annot$id == "RAFII-2 DÍA 1"] <- "RAFII-02 DÍA 1"
turn_annot$id[turn_annot$id == "RAFII-3 DÍA 14"] <- "RAFII-03 AMP"
turn_annot$id[turn_annot$id == "RAFII-6 DÍA 14"] <- "RAFII-06 PRE AMPH"
turn_annot$id[turn_annot$id == "RAFII-7 DÍA 21"] <- "RAFII-07 PRE APO"
turn_annot$id[turn_annot$id == "RAFII-14 DÍA 14"] <- "RAFII-14 PRE AMPH"
turn_annot$id[turn_annot$id == "RAFII-16 DÍA 21"] <- "RAFII-16 APO"
turn_annot$id[turn_annot$id == "RAFII-01 DÍA 14"] <- "RAFII-01 AMPH"
turn_annot$id[turn_annot$id == "RAFII-03 DÍA 14"] <- "RAFII-03 AMPH"
turn_annot$id[turn_annot$id == "RAFII-04 DÍA 21"] <- "RAFII-04 APO"
turn_annot$id[turn_annot$id == "RAFII-06 DÍA 14"] <- "RAFII-06 AMP"
turn_annot$id[turn_annot$id == "RAFII-07 DÍA 21"] <- "RAFII-07 APO"

turn_annot$dlc.file <- sapply(turn_annot$id, function(x) {
    y <- grep(x, dlc_files, value = TRUE)[1]

    if (length(y) == 0)
        y <- NA
    if (length(y) > 1)
        y <- length(y)
    return(y)
})

turn_annot$file <- turn_annot$CSVname
turn_annot$CSVname <- turn_annot$dlc.file
turn_annot$Experimenter <- "Jaime_Fornaguera"
turn_annot$ID <- turn_annot$id
turn_annot$dlc.file <- turn_annot$id <- NULL

turn_annot <- turn_annot[, c("file", "Experimenter", "from", "to",
    "type", "ID", "CSVname")]
head(turn_annot)

write.csv(turn_annot, "./data/raw/turning_annotations_fixed.csv")
Code
dlc_files <- list.files(path = "./data/raw/raf_deeplabcut_csvs", pattern = "\\.csv$")

dlcf <- read.csv(file.path("./data/raw/raf_deeplabcut_csvs", dlc_files[1]))
Code
labeling.data <- read.csv("./data/raw/turning_annotations_fixed.csv")
pointinfo <- data.frame(PointName = c("nose", "ear_left", "ear_right",
    "body_center", "base_tail", "tip_tail"), PointType = "Mouse")

files <- unique(labeling.data$CSVname)
path <- "./data/raw/raf_deeplabcut_csvs/"

pipeline <- function(path) {
    Tracking <- ReadDLCDataFromCSV(path, fps = 20)
    # Tracking <- ReadDLCDataFromCSV(file.path(path, files[1]),
    # fps = 20) keep 5 s to 5 min frames (20 fps)
    Tracking <- CutTrackingData(Tracking, keep.frames = 100:6000)
    # print(length(Tracking$frames)) Tracking <-
    # CalibrateTrackingData(Tracking, 'distance',in.metric = 20,
    # c('t','b'))
    Tracking <- CleanTrackingData(Tracking, likelihoodcutoff = 0.95)
    Tracking <- AddLabelingData(Tracking, labeling.data[labeling.data$CSVname ==
        Tracking$filename, ])
    Tracking <- CalculateMovement(Tracking, movement_cutoff = 5, integration_period = 5)
    Tracking <- CalculateAccelerations(Tracking)
    Tracking <- CreateAccelerationFeatures(Tracking)
    Tracking <- create_speed_features(Tracking)  # my own function
    Tracking <- create_distance_features(Tracking, point.pairs = c("nose/body_center",
        "nose/tip_tail", "nose/base_tail", "ear_right/tip_tail", "ear_right/base_tail",
        "ear_left/base_tail", "ear_left/tip_tail", "body_center/tip_tail",
        "body_center/base_tail"))  # my own function
    Tracking <- CreateSkeletonData_OFT(Tracking)  # modified
    Tracking <- create_angle_features(Tracking)  # my own function
    Tracking <- CreateTrainingSet(Tracking, integration_period = 40)
    Tracking <- AddPointInfo(Tracking, pointinfo)
    sapply(Tracking, function(x) if (is.list(x))
        sapply(x, head) else head(x))

    return(Tracking)
}

TrackingAll <- RunPipeline(files, path, FUN = pipeline)

saveRDS(TrackingAll, "./data/processed/tracking_data_dlc_analyzer_raf.RDS")

4.2 Tensorflow training

4.2.1 Without cross-validation

Code
TrackingAll <- readRDS("./data/processed/tracking_data_dlc_analyzer_raf.RDS")

# evaluation <- list() for(i in names(TrackingAll)){ combine
# training data from all files
MLData <- CombineTrainingsData(TrackingAll, shuffle = FALSE)

saveRDS(MLData, "./data/processed/training_data_for_ML.RDS")

# subsample data to balance it out
counts <- apply(MLData$train_y, 2, sum)
mean(counts[-2])

subsample <- c(which(MLData$train_y[, 1] == 1), which(MLData$train_y[,
    3] == 1), sample(which(MLData$train_y[, 2] == 1), mean(counts[-2])))

length(subsample)
MLData$train_y <- MLData$train_y[subsample, ]
MLData$train_x <- MLData$train_x[subsample, ]
# sapply(MLData, function(x) if(is.list(x)) sapply(x, head) else
# head(x))

if (anyNA(MLData$train_y) | anyNA(MLData$train_x)) stop("NAs in data")

# initialize model
model <- keras_model_sequential()
model %>%
    layer_dense(units = 256, activation = "relu", input_shape = c(MLData$parameters$N_input),
        kernel_regularizer = regularizer_l2(l = 0)) %>%
    layer_dropout(rate = 0.4) %>%
    layer_dense(units = 128, activation = "relu", kernel_regularizer = regularizer_l2(l = 0)) %>%
    layer_dropout(rate = 0.3) %>%
    layer_dense(units = MLData$parameters$N_features, activation = "softmax")

# define optimizer
model %>%
    compile(loss = "categorical_crossentropy", optimizer = optimizer_rmsprop(),
        metrics = c("accuracy"))

# train model
history <- model %>%
    fit(MLData$train_x, MLData$train_y, epochs = 50, batch_size = 32,
        validation_split = 0)

# #we now use this model to classify the behavior in the cross
# validation file
for (i in names(TrackingAll)) TrackingAll[[i]] <- ClassifyBehaviors(t = TrackingAll[[i]],
    model, model_parameters = MLData$parameters)
# # } PlotLabels(t =
# TrackingAll$`RAFI-10_pre_APODLC_resnet50_rafi_ratas_cinJan8shuffle1_90000.csv`)
# PlotLabels(TrackingAll$`RAFII-01
# AMPHDLC_resnet50_rafi_ratas_cinJan8shuffle1_90000.csv`)


saveRDS(TrackingAll, "./data/processed/tracking_data_dlc_analyzer_raf_evaluated.RDS")
Code
TrackingAll <- readRDS("./data/processed/tracking_data_dlc_analyzer_raf.RDS")

EvaluateClassification(ts = TrackingAll)
# PlotLabels.Multi.PDF(TrackingAll)

4.2.2 With cross-validation

Code
evaluation <- list()

for (i in names(TrackingAll)) {
    # combine training data from all files except the one we
    # want to evaluate
    MLData <- CombineTrainingsData(TrackingAll[names(TrackingAll) !=
        i], shuffle = TRUE)

    # initialize model
    model <- keras_model_sequential()
    model %>%
        layer_dense(units = 256, activation = "relu", input_shape = c(MLData$parameters$N_input),
            kernel_regularizer = regularizer_l2(l = 0)) %>%
        layer_dropout(rate = 0.4) %>%
        layer_dense(units = 128, activation = "relu", kernel_regularizer = regularizer_l2(l = 0)) %>%
        layer_dropout(rate = 0.3) %>%
        layer_dense(units = MLData$parameters$N_features, activation = "softmax")

    # define optimizer
    model %>%
        compile(loss = "categorical_crossentropy", optimizer = optimizer_rmsprop(),
            metrics = c("accuracy"))

    # train model
    history <- model %>%
        fit(MLData$train_x, MLData$train_y, epochs = 20, batch_size = 32,
            validation_split = 0)

    # we now use this model to classify the behavior in the
    # cross validation file
    TrackingAll[[i]] <- ClassifyBehaviors(t = TrackingAll[[i]], model,
        model_parameters = MLData$parameters)

}

PlotLabels(t = TrackingAll$`RAFI-10_pre_APODLC_resnet50_rafi_ratas_cinJan8shuffle1_90000.csv`)
PlotLabels(TrackingAll$`RAFII-01 AMPHDLC_resnet50_rafi_ratas_cinJan8shuffle1_90000.csv`)

EvaluateClassification(ts = TrackingAll)

PlotLabels.Multi.PDF(TrackingAll)

5 Random Forest on CIN data

5.1 Training model

Code
TrackingAll <- readRDS("./data/processed/tracking_data_dlc_analyzer_raf.RDS")

MLData <- readRDS("./data/processed/training_data_for_ML.RDS")

# subsample data to balance it out
counts <- apply(MLData$train_y, 2, sum)
mean(counts[-2])

subsample <- c(which(MLData$train_y[, 1] == 1), which(MLData$train_y[,
    3] == 1), sample(which(MLData$train_y[, 2] == 1), mean(counts[-2])))

length(subsample)
MLData$train_y <- MLData$train_y[subsample, ]
MLData$train_x <- MLData$train_x[subsample, ]
MLData$labels <- MLData$labels[subsample]

dat <- data.frame(MLData$train_x, labels = MLData$labels)

dat$labels <- as.factor(dat$labels)

# untunned random forest
rf <- randomForest::randomForest(labels ~ ., data = dat, ntree = 1000)

saveRDS(rf, "./data/processed/untunned_random_forest.RDS")

# tunning random forest
library(doParallel)
registerDoParallel(cores = 16)

# Random Search
control <- trainControl(method = "oob", number = 10, search = "random",
    allowParallel = TRUE)

set.seed(123)
mtry <- sqrt(ncol(x))

rf_random <- train(labels ~ ., data = dat, method = "rf", metric = "Accuracy",
    tuneLength = 15, trControl = control)


new_dat <- as.data.frame(MLData$train_x)
names(new_dat) <- names(rf_random$trainingData)[-1]
predicted_class <- predict(rf_random, newdata = new_dat)

# save confusion matrix
conf_mat <- confusionMatrix(predicted_class, as.factor(MLData$labels))

conf_df <- as.data.frame(conf_mat$table)

conf_df$total <- sapply(conf_df$Reference, function(x) sum(MLData$labels ==
    x))

conf_df$proportion <- conf_df$Freq/conf_df$total

saveRDS(list(predicted_class = predicted_class, conf_mat = conf_mat,
    conf_df = conf_df, new_dat = new_dat, files = MLData$file.names,
    class = MLData$labels), "./data/processed/tunned_random_forest_model_results.RDS")

saveRDS(rf_random, "./data/processed/tunned_random_forest_model.RDS")

5.2 Results

5.2.1 Accuracy by class

Code
rf_results <- readRDS("./data/processed/tunned_random_forest_model_results.RDS")

ggplot(rf_results$conf_df, aes(x = Reference, y = Prediction, fill = proportion)) +
    geom_tile() + theme_bw() + coord_equal() + scale_fill_distiller(palette = "Greens",
    direction = 1) + geom_text(aes(label = round(proportion, 2)),
    color = "black") + theme_classic() + theme(axis.text.x = element_text(color = "black",
    size = 11, angle = 30, vjust = 0.8, hjust = 0.8))

Code
rf_results$conf_mat
Confusion Matrix and Statistics

          Reference
Prediction   left   None  right
     left   33708  10144      0
     None       0 106441     57
     right      0   6177  23924

Overall Statistics
                                          
               Accuracy : 0.9092          
                 95% CI : (0.9079, 0.9106)
    No Information Rate : 0.6803          
    P-Value [Acc > NIR] : < 2.2e-16       
                                          
                  Kappa : 0.8291          
                                          
 Mcnemar's Test P-Value : NA              

Statistics by Class:

                     Class: left Class: None Class: right
Sensitivity               1.0000      0.8671       0.9976
Specificity               0.9309      0.9990       0.9605
Pos Pred Value            0.7687      0.9995       0.7948
Neg Pred Value            1.0000      0.7793       0.9996
Prevalence                0.1868      0.6803       0.1329
Detection Rate            0.1868      0.5899       0.1326
Detection Prevalence      0.2430      0.5902       0.1668
Balanced Accuracy         0.9654      0.9330       0.9791

5.2.2 Prediction by file

These graphs show the observed behavior (left colum) and the predicted by the model (right column) for each video (rows)

Code
dat <- data.frame(file = gsub("_resnet50_rafi_ratas_cinJan8shuffle1_90000.csv",
    "", rf_results$files), class = c(as.character(rf_results$predicted_class),
    rf_results$class), type = rep(c("predicted", "observed"), each = length(rf_results$files)))

dat$frame <- 1:(unique(table(dat$file))/2)
dat$time <- dat$frame/20

ggplot(data = dat, aes(x = time, y = class, color = class)) + geom_point(size = 4,
    shape = 124) + facet_grid(file ~ type, scales = "free_x") + scale_color_viridis_d() +
    theme_bw()

Scatterplots of the correlation between number of predicted frames and actual turns observed

Code
turn_annot <- read.csv("./data/raw/turning_annotations_fixed.csv")

turn_annot$file <- gsub("_resnet50_rafi_ratas_cinJan8shuffle1_90000.csv",
    "", turn_annot$CSVname)
agg_turns <- aggregate(ID ~ file + type, turn_annot, length)
names(agg_turns)[ncol(agg_turns)] <- "quarter.turns"
agg_turns <- agg_turns[order(agg_turns$file), ]
agg_turns$frames <- sapply(1:nrow(agg_turns), function(x) {
    sum(dat$file == agg_turns$file[x] & dat$class == agg_turns$type[x])
})

ggplot(agg_turns, aes(y = frames, x = quarter.turns)) + geom_smooth(method = "lm",
    col = viridis(10, alpha = 0.4)[3]) + geom_point(size = 4, pch = 21,
    fill = viridis(10, alpha = 0.4)[8]) + facet_wrap(~type, nrow = 1,
    scales = "free") + labs(x = "Quarter of turns count (observed)",
    y = "Number of frames (predicted)") + theme_classic()

Code
print("Overall correlation:")
[1] "Overall correlation:"
Code
cor(agg_turns$quarter.turns, agg_turns$frames)
[1] 0.8486071
Code
print("Left turn correlation:")
[1] "Left turn correlation:"
Code
cor(agg_turns$quarter.turns[agg_turns$type == "left"], agg_turns$frames[agg_turns$type ==
    "left"])
[1] 0.8627682
Code
print("Right turn correlation:")
[1] "Right turn correlation:"
Code
cor(agg_turns$quarter.turns[agg_turns$type == "right"], agg_turns$frames[agg_turns$type ==
    "right"])
[1] 0.7597413

6 Create label videos (srt files)

Code
library(srt)
x <- read_srt(srt_example(), collapse = " ")

dif <- x$end - x$start
x$start <- x$start - abs(min(x$start))
x$end <- x$start + dif

x <- x[x$end < 960, ]
head(x)
# write_srt(x, tempfile(fileext = '.srt'), wrap = FALSE)
write_srt(x, "~/Downloads/delete.srt", wrap = FALSE)


labeling.data <- read.csv("./data/raw/turning_annotations_fixed.csv")


for (i in unique(labeling.data$CSVname)) {

    labs <- labeling.data[labeling.data$CSVname == i, ]
    labs$start <- labs$from
    labs$end <- labs$to
    labs$n <- 1:nrow(labs)
    labs$subtitle <- labs$type

    file <- gsub("DLC_resnet50_rafi_ratas_cinJan8shuffle1_90000.csv",
        "", labs$CSVname[1])
    labs <- labs[, c("n", "start", "end", "subtitle")]
    labs <- rbind(labs, data.frame(n = nrow(labs) + 1, start = 300,
        end = 360, subtitle = "******* END OF MANUAL TRACKING *******"))

    write_srt(labs, paste0("/media/m/Seagate Portable Drive/rafII_videos/subtitle_files/",
        file, ".srt"), wrap = FALSE)

}

 

7 Takeaways

  • Left and right turns can be predicted with good accuracy form deeplabcut pose estimations

 


 

Session information

R version 4.1.0 (2021-05-18)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 20.04.2 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/atlas/libblas.so.3.10.3
LAPACK: /usr/lib/x86_64-linux-gnu/atlas/liblapack.so.3.10.3

locale:
 [1] LC_CTYPE=pt_BR.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=es_CR.UTF-8        LC_COLLATE=pt_BR.UTF-8    
 [5] LC_MONETARY=es_CR.UTF-8    LC_MESSAGES=pt_BR.UTF-8   
 [7] LC_PAPER=es_CR.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=es_CR.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] viridis_0.6.2       viridisLite_0.4.1   caret_6.0-88       
 [4] lattice_0.20-44     srt_1.0.3           adehabitatLT_0.3.25
 [7] CircStats_0.2-6     boot_1.3-28         MASS_7.3-54        
[10] adehabitatMA_0.3.14 ade4_1.7-17         tensorflow_2.9.0   
[13] keras_2.9.0         corrplot_0.90       cowplot_1.1.1      
[16] data.table_1.14.0   ggmap_3.0.0         ggplot2_3.4.0      
[19] imputeTS_3.3        sp_1.5-1            xaringanExtra_0.7.0
[22] rprojroot_2.0.3     formatR_1.11        knitr_1.42         
[25] kableExtra_1.3.4   

loaded via a namespace (and not attached):
  [1] colorspace_2.0-3     rjson_0.2.21         class_7.3-19        
  [4] base64enc_0.1-3      gridtext_0.1.5       ggtext_0.1.2        
  [7] rstudioapi_0.14      farver_2.1.1         remotes_2.4.2       
 [10] lubridate_1.7.10     prodlim_2019.11.13   fansi_1.0.3         
 [13] xml2_1.3.3           codetools_0.2-18     splines_4.1.0       
 [16] zeallot_0.1.0        jsonlite_1.8.4       pROC_1.17.0.1       
 [19] packrat_0.9.0        png_0.1-7            tfruns_1.5.1        
 [22] compiler_4.1.0       httr_1.4.4           assertthat_0.2.1    
 [25] Matrix_1.5-1         fastmap_1.1.0        cli_3.6.0           
 [28] htmltools_0.5.4      tools_4.1.0          gtable_0.3.1        
 [31] glue_1.6.2           reshape2_1.4.4       dplyr_1.0.10        
 [34] Rcpp_1.0.9           fracdiff_1.5-1       vctrs_0.5.2         
 [37] urca_1.3-3           svglite_2.1.0        nlme_3.1-152        
 [40] iterators_1.0.13     lmtest_0.9-40        timeDate_3043.102   
 [43] xfun_0.36            gower_0.2.2          stringr_1.5.0       
 [46] rvest_1.0.3          lifecycle_1.0.3      zoo_1.8-11          
 [49] scales_1.2.1         ipred_0.9-11         parallel_4.1.0      
 [52] RColorBrewer_1.1-3   yaml_2.3.7           quantmod_0.4.20     
 [55] curl_4.3.3           gridExtra_2.3        reticulate_1.26     
 [58] rpart_4.1-15         stringi_1.7.12       tseries_0.10-52     
 [61] foreach_1.5.1        TTR_0.24.3           lava_1.6.9          
 [64] RgoogleMaps_1.4.5.3  rlang_1.0.6          pkgconfig_2.0.3     
 [67] systemfonts_1.0.4    bitops_1.0-7         evaluate_0.20       
 [70] purrr_1.0.0          labeling_0.4.2       stinepack_1.4       
 [73] recipes_0.1.16       htmlwidgets_1.5.4    tidyselect_1.2.0    
 [76] plyr_1.8.7           magrittr_2.0.3       R6_2.5.1            
 [79] generics_0.1.3       DBI_1.1.1            mgcv_1.8-36         
 [82] pillar_1.8.1         whisker_0.4.1        withr_2.5.0         
 [85] xts_0.12.2           survival_3.2-11      nnet_7.3-16         
 [88] tibble_3.1.8         crayon_1.5.2         utf8_1.2.2          
 [91] rmarkdown_2.20       jpeg_0.1-8.1         grid_4.1.0          
 [94] sketchy_1.0.2        ModelMetrics_1.2.2.2 forecast_8.18       
 [97] digest_0.6.31        webshot_0.5.4        tidyr_1.1.3         
[100] stats4_4.1.0         munsell_0.5.0        quadprog_1.5-8