Linking

On this page, you will process the segmented data in particle_data into a single linked_data which contains the time-series trajectory data for all tracked microbots.

These commands can be run in the Julia REPL or in the generated Pluto notebook file after Creating an environment for your project. See the Pluto tutorial page to see how to open and use the notebook.

Input parameters

First, let's format our inputs to the linking process, the translation_dict and linking_settings.

Translation Dictionary

Provided you've followed the requirements for filenaming detailed in Experimental, you now need to tell MicroTracker what your independent variables are. This is in the form of a Dictionary where the key is the name of the variable and the value is a tuple of the index and type. Following the example in Experimental, we have a filename that looks like 32_6p2_1. The translation dictionary would then look like:

translation_dict = Dict("T_C" => (1, Float64), "B_mT" => (2, Float64))

In plain english, this is telling MicroTracker that the temperature is recorded in the first position and is a floating point number (can have decimal places) and the field strength is a floating point number in the second position. These are the possible types a variable in a filename can have:

  • Int64 If an integer variable makes sense, like number of washes, number of particles, etc.
  • Float64 Most variables, a floating point number.
  • String If the variable makes most sense if its a string. Like "washed" or "aerosolized".

In this example detailed in Experimental we know the FPS of our videos is constant across all videos, so we'll include it in the linking_settings below.

Linking Settings

The linking settings are in the format of a NamedTuple. This linking_settings contains information about your video, like the microns per pixel (MPP) of your microscope setup and the frames per second of your video (FPS). It also contains parameters to feed to the underlying linking machinery in trackpy.link.

linking_settings = (
    MPP = 0.605,  # Microns per pixel, scale of objective.
    SEARCH_RANGE_MICRONS = 1000, # microns/s. Fastest a particle could be traveling. Determines "how far" to look to link.
    MEMORY = 0,  # number of frames the blob can disappear and still be remembered
    STUBS_SECONDS = 0.5,  # trajectory needs to exist for at least this many seconds 
    FPS = 60.0 # Frames per second. **Can omit if the FPS has been specified in the filename.**
)
Tip

MicroTracker supports videos having different framerates, as long as this information is recorded in the filename. For an example of this, see the included examples and Pluto notebook.

If instead the FPS across all videos is constant, we can include the FPS parameter in linking_settings and the exclude any mention of FPS in our translation_dict, as shown above.

Batch linking

Now that we've formatted and defined our translation_dict and linking_settings, its time to link.

The function batch_particle_data_to_linked_data is the 1-command version which runs all of the processing steps at once for every video. If you'd like to separate out the process and tinker with each step, see the Under the hood section below.

julia> linked_data = batch_particle_data_to_linked_data(translation_dict, linking_settings)
...output snipped

And just like that - all the segmented data in particle_data has been linked into continuous microbot trajectories and concatenated into one DataFrame, here the variable linked_data. This data contains the instantaneous velocity, size, and much more over the entire experimental lifetime of the microbot.

Under the hood

Continue to Collapsing after batch linking. However, if you'd like to insert in your own processing step in the pipeline, here are the sub-functions that make up batch_particle_data_to_linked_data for your convenience. These functions are applied in order, from particle_data to linked_data.

MicroTracker.load_particle_dataFunction
load_particle_data(video_name::AbstractString)

Read a particle data .csv located in /particle_data into a DataFrame.

If the .csv file is from ImageJ (contains X, Y, and Label columns, not x, y, and frame), it will:

  1. Extract the frame number from the label column and add it as a new column using extract_frame_from_label
  2. Rename the X and Y columns to x and y so it works with link.
  3. Remove any columns with a blank name.
  4. Rename the Circ. column to Circ so it works with Julia symbol notation.
source
MicroTracker.add_info_columns_from_filenameFunction
add_info_columns_from_filename(particle_data::AbstractDataFrame, translation_dict::AbstractDict)

Extract experimental metadata from the filename column and create a new column for each in particle_data. Returns a new DataFrame.

Assumes the filename is separated by underscores and periods are denoted by p. The translation_dict details the filename format. For full explanation, see the MicroTracker docs: Translation Dictionary.

source
MicroTracker.linkFunction
link(particle_data::AbstractDataFrame, linking_settings::NamedTuple; trackpykwargs...)

Use trackpy to link particle data into trajectories across frames.

See the Linking Settings docs for the fields and format of linking_settings. Any kwargs will be passed to the trackpy.link function trackpy.link.

Example

julia> link(particle_data, linking_settings)
source
MicroTracker.add_resolution_column!Function
add_resolution_column!(particle_data::AbstractDataFrame)

Look at a frame of the video in original_video which corresponds to the data and add a column for the resolution of type Tuple{Int, Int}. Modifies particle_data in place, signfified by the ! in the function name.

Uses getvideoresolution.

source
MicroTracker.add_useful_columnsFunction
add_useful_columns(linked_data::AbstractDataFrame, linking_settings::NamedTuple)

After linking, add some useful columns to the dataframe, like include dx, dy, dp (speed), and size measurements in microns.

Uses the numerical_derivative and total_displacement functions.

Definitions

  • particle_unique : a string which uniquely identifies a particle. This is a combination of the filename and the particle number.
  • dx : numerical derivative of x, i.e. instantaneous velocity in the x direction. Units of pixels/frame.
  • dy : numerical derivative of y, i.e. instantaneous velocity in the y direction. Units of pixels/frame.
  • dp : instantaneous speed. √(dx^2 + dy^2). Units of pixels/frame.
  • dx_um : dx converted to µm/s.
  • dy_um : dy converted to µm/s.
  • dp_um : dp converted to µm/s.
  • total_displacement_um : total displacement of the microbot. Constant on every row, since this is a total. Units of µm.
  • Area_um : area of the microbot. Units of µm^2.
  • time : time, converted from the frame column. Units of seconds.
  • Major_um : major axis of the fit ellipse of the microbot. Units of µm.
  • Minor_um : minor axis of the fit ellipse of the microbot. Units of µm.
source
MicroTracker.clip_trajectory_edgesFunction
clip_trajectory_edges(linked_data::AbstractDataFrame, linking_settings::NamedTuple)

Iterate through each trajectory and remove the tracking data where the particle is out of frame.

The particle is out of frame when the center is within the radius of the particle from the edge of the video.

Uses find_trajectory_bounds to find the bounds of the trajectory with inbounds.

source