data analysis
This document will walk you through an analyzing data of growing bacteria cells.
[[TOC]]
- Completed the cell tracking example
- Have a MAT-file named
demodata.mat
containing aTrackArray
object namedtrackdata
After reviewing this document, you will be able to:
- Load saved track data
- Get data of a specific cell
- Plot cell length vs time
- Plot a lineage tree of the cells
- Tracks represent the data connected to individual objects across every frame of the timelapse video.
- Track ID is a unique identifier (number) that is assigned to a track when it is created. For most functions, this is the identifier that should be used to refer to a track.
- A TrackArray object is a concrete realization (instant) of the
TrackArray
class. For example:TA = TrackArray;
TA
will be aTrackArray
object. -
NaN
- Not-A-Number is a specific data value that MATLAB recognizes as not being a number. This value will affect functions in different ways.
- Let's start by clearing variables in the workspace
>> clearvars
- Load the MAT-file by double-clicking in the Current Folder panel or by
typing in the Command Window
>> load('demodata.mat')
We can get an overview of the trackdata
variable by displaying it in the
Command Window
>> trackdata
trackdata =
TrackArray with properties:
Tracks: [1×7 struct]
FileMetadata: []
CreatedOn: '11-Apr-2020 12:20:43'
NumTracks: 7
Datafields: {5×1 cell}
In this example, the object has the following properties:
-
Tracks
- a struct containing time series data (more this later). -
FileMetadata
- a struct containing file metadata. We did not set this in the previous example so it is empty here. -
CreatedOn
- a string showing the date and time the object was created. -
NumTracks
- number of tracks in the array. -
Datafields
- a cell string array with the names of the data fields in the tracks.
To see what data was tracked we can look at the Datafields
property:
>> trackdata.Datafields
ans =
3×1 cell array
{'Centroid' }
{'MajorAxisLength'}
{'PixelIdxList' }
You can access a track using the method getTrack(obj, trackID)
, where obj
is
the variable containing the TrackArray
object and trackID
is the unique
identifier assigned to the track.
If you followed along with the cell tracking example, the cell IDs are the numbers displayed on the resulting GIF:
As an example, to get track 1:
>> track1 = getTrack(trackdata, 1)
track1 =
struct with fields:
ID: 1
MotherID: NaN
DaughterID: [2 3]
Frames: [1 2 3 4 5 6]
Centroid: [6×2 double]
MajorAxisLength: [6×1 double]
PixelIdxList: {1×6 cell}
Note that the variable track1
is a normal MATLAB struct
, which is a built-in
data structure.
For example, to access a property such as the MajorAxisLength
(cell length):
>> track1.MajorAxisLength
ans =
43.3994
45.8512
49.4658
53.4396
58.1812
63.1483
Note that the data fields will be concatenated into a matrix if they share the same number of elements. In this case, each row contains data belonging to a different frame.
To access data belonging to a specific element in the matrix, you can use standard indexing notation:
>> track1.MajorAxisLength(3)
ans =
49.4658
If the data for each frame is not a matrix of the same size, the data is stored
as a cell instead. In the example above, the PixelIdxList
contains the linear
indices of the pixels in the
mask of each cell
in each frame. Since the cell is constantly changing shape, the number of
elements in the index list changes from frame to frame.
To access a specific cell, use the curly braces when indexing:
>> track1.PixelIdxList{3}
To learn more about indexing in MATLAB:
A track will always have the following fields:
-
ID
: Unique number that identifies the track -
MotherID
: ID of mother track -
DaughterID
: ID of daughter tracks -
Frames
: Vector containing frame number that correspond to the dataFor example:
>> track1.Frames ans = 1 2 3 4 5 6
shows that track 1 existed between frames 1 and 6 of the movie.
You can plot time series data using the Frames
property. For example, to plot
cell length over time:
%Convert frame to hours (conversion rate of 0.5 hour per frame was determined by microscope settings)
timeAxis = track1.Frames * 0.5;
%Convert cell length from pixels into microns (conversion is 0.065 um/pixel,
%obtained from the microscope)
cellLength = track1.MajorAxisLength * 0.065;
plot(timeAxis, cellLength)
xlabel('Time (hours)')
ylabel('Cell length (\mum)')
In TrackArray
, tracks are modelled as a binary linked list. Each track can
have, at most, a link to a previous track in time, and two links to the next
track. Since we wrote this code originally for tracking cells, the track IDs are
tracked as MotherID
and DaughterID
.
For example, once again looking at track 1:
>> track1 = getTrack(trackdata, 1)
track1 =
struct with fields:
ID: 1
MotherID: NaN
DaughterID: [2 3]
Frames: [1 2 3 4 5 6]
Centroid: [6×2 double]
MajorAxisLength: [6×1 double]
PixelIdxList: {1×6 cell}
Since MotherID
is NaN
, track 1 is not linked to a previous track, which
makes sense since we know that cell 1 existed prior to the start of the movie.
The DaughterID
of track 1 is [2 3]
, indicating that cell 1 divided into
cells 2 and 3. From the last element of Frames
, we know that division occured
between frames 6 and 7.
Inspecting track 2, one of the the daughter cells:
>> track1 = getTrack(trackdata, 2)
track1 =
struct with fields:
ID: 2
MotherID: 1
DaughterID: [6 7]
Frames: [7 8 9 10 11 12 13 14]
Centroid: [8×2 double]
MajorAxisLength: [8×1 double]
PixelIdxList: {1×8 cell}
We can see that the data here is consistent as MotherID
is 1 and the first
element in Frames
is 7, indicating that this track started in frame 7 of the
movie.
These relationships can be plotted as a binary using the method treeplot(obj, rootID)
. rootID
specifies the track ID at the root (bottom most node) of the tree
>> treeplot(trackdata, 1)
>> ylabel('Frames')
The y-axis of the tree plot is frames
You can change where the tree starts by changing the root node. For example, to plot the subtree starting from cell 2:
>> treeplot(trackdata, 2)
>> ylabel('Frames')
This document concludes the example case of tracking cells.
If you encountered any issues, please send us a ticket at biof-imaging@colorado.edu and we will be happy to help.