Quantitative Big Imaging

Kevin Mader, Maria Büchner
17 April 2014

ETHZ: 227-0966-00L

Dynamics

Exercises

Tools for the Exercise

  • Basic Exercises
    • FIJI (ImageJ with all the plugins already installed): Visualization, Preprocessing, Segmentation, Morphometrics [http://www.fiji.sc]
    • RStudio (Statistics and Plots)

Objectives

  1. Make Reports in R
  2. Analyze a time series of images
  3. Track the objects using the center of mass positions
  4. Track the voxels using DIC

Setting up the Computers

Once you have logged in

  1. Install FIJI (if it is not already installed)
    • FIJI can be downloaded from this link
  2. Start FIJI
  3. Start RStudio by typing rstudio at command line

Creating a Scripted Analysis

Starting Macro Movie So we have a macro which runs once, how can we modify it to perform a Parameter Sweep Analysis?

  • Using the loops inside the ImageJ API.
  • Make sure you save each file with a different name
  • Make sure you select the image window before doing any additional processing
for (threshold=90; threshold<110; threshold++) {
      selectWindow("blobs.gif");
      setThreshold(threshold, 255);
      run("3D Objects Counter", "threshold="+threshold+" slice=0 min.=1 max.=65024 statistics");
      outFileName=getDirectory("home")+File.separator+"blob_analysis_th_"+threshold+".txt";
      print("Saving Results as:"+outFileName);
      saveAs("Results", outFileName);
}

Create a new Macro

Use these starting macros and scripts

  1. Plugins \( \rightarrow \) New \( \rightarrow \) Macro
  2. Language \( \rightarrow \) ImageJ Macro
  3. Type or paste code in and run

Looking at a 2D Time Series

plot of chunk unnamed-chunk-1

Starting Script: https://gist.github.com/kmader/10871528

  1. Open the images (firstflow) as a sequence in Fiji:
    • File \( \rightarrow \) Import \( \rightarrow \) Image Sequence…
  2. Run a shape analysis on each slice and save the results into text files
  3. Read the text files in R
  4. Perform a tracking

Creating a Report in R

  1. File \( \rightarrow \) New \( \rightarrow \) R Markdown
    • If you are familiar with Latex you can also use R Sweave
  2. Paste the code from the course into blocks starting with 3 apostrophe-like symbols (upper left key below escape on American Keyboards)
    • The brackets {r} indicates the language is r, and after that come standard options
  3. Paste the plot code into such blocks (adjust fig.width and fig.height as necessary)
  4. Use the kable comand to show tables like kable(all.results)

See the part E of the starting script for a running example (the path will need to be fixed)

Looking at the results with R

Start RStudio, Install the plyr and ggplot2 packages

install.packages(c("plyr","ggplot2"))

Read in the data


library("plyr")
library("ggplot2")
# get the parameters from the file name (parm.loc means 4th spot by _ in the name)
parm.from.filename<-function(in.name,parm.loc=4) {
  last.name<-sub("^([^.]*).*", "\\1", basename(in.name))
  as.numeric(strsplit(last.name,"_")[[1]][parm.loc])
}
# home.dir needs to be defined to where you
# save the data
file.list<-Sys.glob(file.path(home.dir,"firstflow","shape*.txt"))
# function to read each file and add a column for threshold
read.fcn<-function(in.name) cbind(read.csv(in.name,sep="\t"),
          time=parm.from.filename(in.name,parm.loc=2))
# read in all of the files
all.results<-ldply(file.list,read.fcn)
# change the names to com.x and com.y to keep things clear
all.results$com.x<-all.results$X.1
all.results$com.y<-all.results$Y
ggplot(all.results,aes(x=com.x,y=com.y,color=time))+
  geom_point()+
  scale_color_gradientn(colours=rainbow(10))+
  theme_bw()

plot of chunk unnamed-chunk-4

Simple Tracking Function

track.fun<-function(in.results) {
  # run the function on time values
  # through n-1 (since the last time cant be tracked)
  ddply(subset(in.results,time<max(in.results$time)),.(time),
        function(cur.frame) {
          # get and save the current time
          c.time<-cur.frame[1,"time"]
          # calculate the next frame time
          next.time<-min(subset(in.results,time>c.time)$time)
          next.frame<-subset(in.results,time==next.time)
          print(next.time)
          ddply(cur.frame,.(com.x,com.y),function(c.pos) {
            cx<-c.pos[1,"com.x"]
            cy<-c.pos[1,"com.y"]
            r.dist<-with(next.frame,sqrt((com.x-cx)^2+(com.y-cy)^2))
            min.idx<-which.min(r.dist)
            # copy all of the information from the matched
            # point to the current point
            matched.pt<-next.frame[min.idx,,drop=F]
            names(matched.pt)<-sapply(names(matched.pt),function(in.name) paste("M_",in.name,sep=""))
            cbind(c.pos,matched.pt,dist=min(r.dist))
            })

          })
  }
track.stats<-function(in.tracks) {
  ddply(in.tracks,.(time),function(cur.frame) {
    data.frame(Vx.Mean=with(cur.frame,mean(M_com.x-com.x)),
               Vx.Sd=with(cur.frame,sd(M_com.x-com.x)),
               Vy.Mean=with(cur.frame,mean(M_com.y-com.y)),
               Vy.Sd=with(cur.frame,sd(M_com.y-com.y)),
               Area.Change=with(cur.frame,mean(abs(M_Area-Area)/Area))
               )
  })
}

Basic Tracking

all.tracks<-track.fun(all.results)

[1] 20 [1] 40 [1] 60 [1] 80 [1] 100 [1] 120 [1] 140 [1] 160

track.stats(all.tracks)
time Vx.Mean Vx.Sd Vy.Mean Vy.Sd Area.Change
0 0.00 0.28 8.73 6.47 2.04
20 0.03 0.30 10.64 2.15 0.23
40 -0.03 0.43 7.59 8.51 0.79
60 -0.02 0.29 10.74 1.63 0.24
80 0.07 0.61 4.45 10.88 0.31
100 -0.02 0.32 10.77 1.50 0.27
120 0.03 0.54 7.05 10.00 0.24
140 0.06 0.29 11.73 0.63 0.10

plot of chunk unnamed-chunk-8

Critical Questions

  1. How can you improve the tracking?
  2. How well does the tracking work with double the time step?
    • half.results<-subset(all.results,(time/20)%%2==1)
  3. How fast can an experiment go and still be tracked well?
  4. How could you estimate the jitter in the system?
    • How might this be useful in simulations?

More Complicated Flows

Second Flow

Perform the same analysis using the second flow

plot of chunk unnamed-chunk-9

Voxel-Based Tracking

Third Flow

Perform the same analysis using the third flow (the script is in this gist https://gist.github.com/kmader/e457917df6acdf695b91)

plot of chunk unnamed-chunk-10

Voxel-Based Tracking

The code for Voxel-based tracking will be run directly in R and is not particularly efficient. It provides nonetheless an idea for how such results might look.


img.files<-Sys.glob(file.path("thirdflow","*.png"))
# get the parameters from the file name (parm.loc means 4th spot by _ in the name)
parm.from.filename<-function(in.name,parm.loc=4) {
  last.name<-sub("^([^.]*).*", "\\1", basename(in.name))
  as.numeric(strsplit(last.name,"_")[[1]][parm.loc])
}
all.images<-ldply(img.files,
                  function(file.name) {data.frame(file.name=file.name,
                                                  time=parm.from.filename(file.name,1),
                                                  im.to.df(readPNG(file.name)))
                                       })

all.images$phase<-all.images$val>0

First Correlation

We can now examine the overall correlation between the first and second images

plot of chunk unnamed-chunk-11

plot of chunk unnamed-chunk-13

Advanced

FIJI offers a number of plugins to perform tracking. One of the most flexible is called TrackMate (Plugins\( \rightarrow \) Tracking \( \rightarrow \) TrackMate), http://fiji.sc/TrackMate

It can also be well integrated into Matlab-based workflows (http://fiji.sc/Using_TrackMate_with_MATLAB)

Tutorial Movie with Second Flow: http://people.ee.ethz.ch/~maderk/videos/TrackMate.ogv