One of the major advantages of having environmental control on our microscopes at the CCI, is that you can get cells to behave a little more like they do in an animal or plant. A great example of this is when looking at cardiomyocytes that can spontaneously start to contract when grown in culture. You can see a load of these on YouTube.
These types of culture are a great model with which to study the effect of drugs or other treatments on the cells of the heart. This post will look at one way to quantify contractile motion without the need for exogenous stains or dyes (which can themselves perturb physiological behaviour).
There are really two useful metrics when dealing with cardiomyocytes: the magnitude (how far the cells contract) and frequency of contraction (how many contractions per unit of time). Let’s take these one at a time:
1) Magnitude of contraction
First things first, find a contracting cell. Once that’s done, draw a line selection along the axis of contraction in one of your frames. The dataset has 2 dimensions of spatial intensity data (in x and y) and one of time:
We can plot the intensity along the selection in a single timepoint (using Fiji, run [Analyze > Plot Profile] also available as Ctrl + k). Here you now have one spatial dimension versus intensity but are lacking the time dimension.
Here’s where the magic happens. If we plot a kymograph, we effectively plot time as a spatial dimension (imagine this as a representation of the plot above in time). We do this by drawing a line selection (as above) and running [Image > Stacks > Reslice].
In this way, it’s really easy to see the repetitive motion over time. Remember, what we want to measure is the shift in the spatial (in this case X) axis. In order to do this, we go back to plotting a profile.
To do this, draw a line selection horizontally through the image in the rested position (top line below). Plot the profile (Ctrl + k) then just using the down-arrow key, move the selection vertically until you’re overlapping the contracted position. It’s really important to keep the horizontal alignment so that we can compare graphs afterwards. Once you have the profiles you can then fit a Gaussian curve to the profile (using Fiji as described in an earlier post or your favourite curve fitting program), and find the mean of the two positions. Note that because we didn’t change the horizontal position, we can compare the plots on the same scale:Repeating this analysis for several of the contractions in your movie will enhance the accuracy of your measurement. Of course this is the magnitude of contraction for one cell. For more robust analysis, you will need to repeat this process for more cells in the same and other fields.
2) Frequency of contraction
We can use basically the same technique to look at the frequency of contractions. Instead of making a profile in the spatial dimension though, we use the temporal dimension:
plot( frameNum, intensity );
…the original data from the profile should look something like this:
You can use the function findpeaks to calculate the local maxima in the signal:
[peakInt, peakFrames] = findpeaks( intensity, 'minpeakheight', mean(intensity) );
Here I’m using the mean intensity value as a minimum peak height to prevent the identification of peaks in the basal noise (see for example two small peaks at around Frame 60 with intensity of ~31500 counts).
If multiple pseudo-peaks are found in the data, you can always use the ‘threshold’ keyword to specify a local threshold for peak identification. Once you have the right parameters, you can validate the peak identification using the following code to overlay the found peaks with the original data:
plot( peakFrames, peakInt, 'rv', 'MarkerFaceColor', [1 0 0] );
mean( diff( peakFrames ) )
Note that as findpeaks doesn’t take an X-dimension you may need to multiply this by your temporal calibration to get an interval in time (cf. frame) units. In this case, the above function returns a value of 13.5 frames. If the movie was taken at 30 frames per second, that means that the mean interval is 450ms ( = 13.5 / 30 ). Taking the reciprocal of this value gives you the frequency, which is equal to 2.2Hz (= 1 / 0.45 ).
NOTE: I’m using MATLAB 2013a. In later versions of MATLAB, the parameters for findpeaks has been changed. Make sure to check the documentation for your version.
So there you have it. Magnitude and frequency calculated without the use of extraneous dyes. It’s worth pointing out that a much more rigorous (and automated) analysis is possible if you can fluorescently label your cells, as this allows for better morphological analysis. Once I can get my hands on some sample data I’ll make that into another post.