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.**
)
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_data
— Functionload_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:
- Extract the frame number from the label column and add it as a new column using
extract_frame_from_label
- Rename the
X
andY
columns tox
andy
so it works withlink
. - Remove any columns with a blank name.
- Rename the
Circ.
column toCirc
so it works with Julia symbol notation.
MicroTracker.add_info_columns_from_filename
— Functionadd_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.
MicroTracker.link
— Functionlink(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)
MicroTracker.add_resolution_column!
— Functionadd_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
.
MicroTracker.add_useful_columns
— Functionadd_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 ofx
, i.e. instantaneous velocity in the x direction. Units of pixels/frame.dy
: numerical derivative ofy
, 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.
MicroTracker.clip_trajectory_edges
— Functionclip_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
.