NOTE: Run all the code included on the “Base Code” page prior to running the following.
Load eigenworms and worm data of choice.
# working directory
setwd("") # enter appropriate working directory
# load eigenworms [Broekmans et al. 2016]
ew = read.csv("eigenworms.csv", header=F, sep=",")
# load coefficients from worm of choice
data = read.csv("12 Foraging Worms/1.txt", header=F, sep="")[10001:12000,1:5]
These are the optimal parameters for the data produced by Broekmans et al. 2016.
E = 5 # embedding dimension
tp = 1
theta = 2 # linearity
tau = 1
# library and prediction selection
lib = c(1,1000)
pred = c(1001,2000)
# convert frames to seconds (i.e. indicate frames per second as fps)
fps = 16 # foraging worms
Run the functions created on the “Base Code” page.
# run the embedding function for separate lib and pred
matrix1 <- make_embed(data[lib[1]:lib[2],], E, tau, tp)
matrix2 <- make_embed(data[pred[1]:pred[2],], E, tau, tp)
matrix = rbind(matrix1, matrix2)
# run the prediction function
new_pred <- make_pred(E, matrix, theta, lib, pred)
observations_total = new_pred$obs
predictions_total = new_pred$pred
# run the EDM error function
errors <- edm_error(pred, observations_total, ew, predictions_total)
# run the cp error function
cp_mean <- cp_error(pred, data, ew)
Create a coefficients vs time plot with the library shown as backwards in time.
# define "ends" of the figure as lengths of lib and pred
left_end = -length(lib[1]:lib[2])
right_end = length(pred[1]:pred[2]) - 1
# pick a coefficient to plot with choice of 1, 2, 3, 4, or 5
co_num = 1
co = data[lib[1]:pred[2], co_num]
# plot assumes that lib and pred are adjacent
par(mai=c(0.95,0.95,0.05,0.05))
plot(c(left_end:right_end)/fps, co, type="l", xlab="time (s)", ylab="a1", cex.lab=1.5,
cex.axis=1.5, xaxs="i", yaxs="i")
rect(left_end, min(co, na.rm=TRUE), 0, max(co, na.rm=TRUE), col="grey60", border=NA)
lines(c(left_end:right_end)/fps, co, lwd=2)
box(col="black")
Create an RMS error vs time plot with red dots indicating a3 > 15 turns.
# identify turns as a3 > 15 points
turns <- which(abs(data[pred[1]:pred[2],3]) > 15)
# choose frames for the worm poses
black_points <- c(428,432,436,437,438,440,476,477,479,481,483,489)
# RMS error with red points on a3 > 15 turns
par(mai=c(0.95,0.95,0.1,0.1))
plot(c(1:length(errors))/fps, errors, type="l", xlab="time (s)", ylab="prediction error (rad)",
col="grey50", cex.lab=1.5, cex.axis=1.5, lwd=1.5)
points(turns/fps, errors[turns], col="red", pch=19, cex=1.3)
points(black_points/fps, errors[black_points], pch=19, cex=1.3)
abline(h=cp_mean, lty="dashed") # average cp error
legend("topright", legend=c("a3 > 15 turns", "worm poses in C"), col=c("red", "black"), pch=19,
box.lty=0, cex=1.3)
box(col="black")
Plot the observed and predicted positions of the worm at the frames chosen above.
# create empty vectors for the total observations and predictions
total_obs_x = {}
total_obs_y = {}
total_pred_x = {}
total_pred_y = {}
# loop through all the chosen frames
for (worm in black_points){
obs_data = observations_total[worm,]
pred_data = predictions_total[worm,]
# create an empty position array for the observations
obs_pos = array(0, dim=c(100,1))
for(i in c(1:5)){
# multiply eigenworms by coefficients
obs_pos = obs_pos + ew[,i]*as.numeric(obs_data[i])
}
# repeat for the predictions
pred_pos = array(0, dim=c(100,1))
for(i in c(1:5)){
# multiply eigenworms by coefficients
pred_pos = pred_pos + ew[,i]*as.numeric(pred_data[i])
}
# create x and y coordinates for the observations
obs_x = {0}
obs_y = {0}
for(i in c(2:100)){
# convert worm angles to xy space
obs_x = c(obs_x, obs_x[i-1] + cos(obs_pos[i]))
obs_y = c(obs_y, obs_y[i-1] + sin(obs_pos[i]))
}
# repeat for the predictions
pred_x = {0}
pred_y = {0}
for(i in c(2:100)){
# convert worm angles to xy space
pred_x = c(pred_x, pred_x[i-1] + cos(pred_pos[i]))
pred_y = c(pred_y, pred_y[i-1] + sin(pred_pos[i]))
}
# subtract the mean of each
obs_x = obs_x - mean(obs_x)
obs_y = obs_y - mean(obs_y)
pred_x = pred_x - mean(pred_x)
pred_y = pred_y - mean(pred_y)
# add the observations and predictions to the total
total_obs_x = c(total_obs_x, obs_x)
total_obs_y = c(total_obs_y, obs_y)
total_pred_x = c(total_pred_x, pred_x)
total_pred_y = c(total_pred_y, pred_y)
}
# calculate the graph limits based on the total
xmag = max(abs(total_obs_x), abs(total_pred_x))
ymag = max(abs(total_obs_y), abs(total_pred_y))
# create a counter for the graphs
i = 1
# loop through all the chosen frames
for (worm in black_points){
# select the observations and predictions
obs_x = total_obs_x[((i*100) - 99):(i*100)]
obs_y = total_obs_y[((i*100) - 99):(i*100)]
pred_x = total_pred_x[((i*100) - 99):(i*100)]
pred_y = total_pred_y[((i*100) - 99):(i*100)]
# plot the worm poses for the observed and predicted data
par(mai=c(0.15,0.15,0.15,0.15))
plot(obs_x, obs_y, type="l", xlab="", ylab="", main=paste(round(worm/fps, digits=2),"sec"),
lwd=4, axes=F, cex.main=1.5, xlim=c(-xmag,xmag), ylim=c(-ymag,ymag), asp=1)
lines(pred_x, pred_y, col="orange", lwd=3)
# increase the counter
i = i + 1
}