File Exchange

image thumbnail

Mean square displacement analysis of particles trajectories

version (27 KB) by Jean-Yves Tinevez
A MATLAB class for the mean square displacement analysis of particle trajectories, with a tutorial.


Updated 26 Apr 2020

GitHub view license on GitHub

Mean square displacement (MSD) analysis is a technique commonly used in colloidal studies and biophysics to determine what is the mode of displacement of particles followed over time. In particular, it can help determine whether the particle is:
- freely diffusing;
- transported;
- bound and limited in its movement.
On top of this, it can also derive an estimate of the parameters of the movement, such as the diffusion coefficient.

@msdanalyzer is a MATLAB per-value class that helps performing this kind of analysis. The user provides several trajectories he measured, and the class can derive meaningful quantities for the determination of the movement modality.

@msdanalyzer can deal with tracks (particle trajectories) that do not start all at the same time, have different lengths, have missing detections (gaps: a particle fails to be detected in one or several frame then reappear), and do not have the same time sampling. As soon as you added your tracks to the class, everything is transparent. It offers facilities to plot and inspect the data, whether for individual particles, or on ensemble average quantities. It has several methods for correcting for drift, which is the main source of error in the analysis. Once corrected, the data can analyzed via the MSD curves or via the velocity autocorrelation. Automated fits of the MSD curves are included (but they require you have the curve fitting toolbox), allowing to derive the type of motion and its characteristics.

Included is a rather long tutorial with references, that will introduce you to the problem using numerical simulations, make you reproduce published results, and detail how the class work. Some basis of physics are required.

If you use this tool for your work, we kindly ask you to cite the following article for which it was created:

Nadine Tarantino, Jean-Yves Tinevez, Elizabeth Faris Crowell, Bertrand Boisson, Ricardo Henriques, Musa Mhlanga, Fabrice Agou, Alain Israël, and Emmanuel Laplantine. TNF and IL-1 exhibit distinct ubiquitin requirements for inducing NEMO-IKK supramolecular structures. J Cell Biol (2014) vol. 204 (2) pp. 231-45

Cite As

Jean-Yves Tinevez (2020). Mean square displacement analysis of particles trajectories (, GitHub. Retrieved .

Comments and Ratings (71)

Anna Bajur

Can anyone help how to compute Van Hove correlation function with msdanalyzer?


Hello, I really like this program. I have a few questions regarding how to use it. I saw your explanation and I am importing tracks from Trackmate program on FIJI. When you say class, what does that exactly mean? I get the final result in a xml file from Trackmate with xy coordinates and time, I am concerned about how to extract that info to MATLAB so that I can get the MSD from it. I have x and y coordinates along with time from each frame, how should I go about this? Please let me know. Thank you.

Hi Jean, Thanks for sharing this beautiful program. Howerver, I have questions in my mind. Does loglog fit works based on weight? if so, what is the criteria for weight determination? Another question is my mind that, why the Time avergaed ensemble mean MSD's fitted α not always replicate all of the α's mean or median? Thank you

I read the comments but not managed to import my trajectory to the code. should I define a new class or something? I have 2D trajectories with the format of matlab .mat file an array of Nsteps x 3 (time x y ). please guide me how to import them

Perfect software with a detailed description, examples and support.
Thanks a lot.



I currently use the ImageJ plug-in mosaic to do single particle tracking. The file has the following format;

Trajectory Frame x y z m0 m1 m2 m3 m4 NPscore
1 1 0 117.605 14.233 0 1.304 1.275 2.059 3.649 6.958 25.804

How can I use this xls file to calculate MSD by using @msdanalyzer?

Thanks a lot!


Great program!
Just one question, how do you define the degree of freedom when calculating the std? I notice that the degree of freedom is not an integer. Thanks a lot!

Hi Jean-Yves,
I am using U-track to do single particle tracking. I was wondering if you have any suggestion if i can use your code to calculate MSD for all tracks from U-tracks

Fantastic program.

Is there a way to only compute for a certain lag (delay) time, rather than all delays?

For example, if my data extends to 10 seconds but i only want to compute MSD for up to a 5 second delay time, is this possible?

Regards, Andy


I solve the problem!
This is a really nice program.
For those who are not familiar with the calss of MATLAB as I was.
The class msdanalyzer should be define in a folder named @msdanalyzer. (@ is important don't modify it as I did)
And we should add the path to where @msdanalyzer locates.


The program looks very nice.

But I undergo same issue:
When typing "ma=ma.addAll(tracks);" it gives me "No appropriate method, property, or field addAll for class msdanalyzer."

Any update.



I have a question concerning the following, I have seen that many people have the same problem:
When typing "ma=ma.addAll(tracks);" it gives me "No appropriate method, property, or field addAll for class msdanalyzer."

According to you intstructions I typed "which msdanalyzer" and it gives me "C:\Users\jrl743\Documents\MATLAB\MSDANALYZER\msdanalyzer.m % msdanalyzer constructor, similarly typing "which addAll" shows C:\Users\jrl743\Documents\MATLAB\MSDANALYZER\addAll.m.
I suppose the path is set well, however Matlab still complains. I am using the Matlab version 2014 in Matlab and also tried it in 2013. I think the problem is with the ma object, it is blocking data to be inserted.

I appreaciate any hint.

Kind regards


Hi Jean-Yves,

sorry, my bad, I had MSD curves with the same lengths in mind. For different lengths you're right, of course.

At the moment there is only question left that puzzels me: If I have a look at simulated data, the results that are listed in ma.lfit.a, representing the slopes, agree perfectly with the slopes I get when I fit the corresponding MSD curve with some other program (excel). So, for example, MSD curve Nr. 5 has a slope of 0.14 if I apply a linear fit and consider only the first 25% of it, and this is also the 5th value in ma.lfit.a. However, this is not true for my actual data. In this case, the slope of let's say MSD curve 492 is 59 for manual fitting and the value of 492nd entry in ma.lfit.a is 91: It's somehow in the same range, but the values differ sometimes quite strongly.

Since the only real difference between the simulated data I used and my acutal data is that for the first all tracks have the same length and for the latter the single tracks have different lengths, I tried out what happens when I use simulated tracks with different lengths. And I observed the same - the results of the curve fit outside matlab/msdanalyzer do not correspond with the value given out by fitMSD. I think that's quite weird and was wondering if you have an explanation for this?

I am sorry to continue asking so many questions. I am aware of the fact that it's not your job to answer everything is ask. However, I really like your program and have performed quite a lot of analysis with it. I need to understand it in order to use it correctly, and I am thankful to you for helping me - and for your patience;)


Hi @LM.

Ok here is a simple counter-example. Imagine that you have 2 tracks.
The first one has a MSD curve that extends from dt=0 to 10 and is a perfect line with a slope of 5.
The second one has a MSD curve that extends from dt=0 to infinity and is a perfect line with a slope of 1.

If you average the 2 diffusion coefficients found by fitting individual curves, you will get D=3.

If you average the MSD curves then fit the mean, you will get D=1.



Dear Jean-Yves,

in the last days I have run some simulations and have now come up with a possible reason for the problem.

First, I investigated theoretically whether the fit of the mean MSD curve or the mean of all fits of single MSD curves could be different. This is not possible.

Then, I went on to use simulated data and analyzed it with the program. I found out that the mean of the single MSD-curve fits perfectly corresponds with the fit of the mean MSD curve. I noticed that all tracks have the same lengths, which is not not the case for my experimental data - there I have tracks with 500 steps down to only 5 steps.

Could it be that that the problem has something to do with this? Maybe the 25% used for linear fit of the single MSD curves are seen from the perspective of the longest track, which means in my case for example that tracks with 125 steps or less (the majority) is considered 100%?


Hi Jean-Yves,

after running some simulations and talking to colleagues, I am still puzzeled. It should not matter whether one first determines the slope of all the single slopes and builds the mean from them or calculates first the mean curve and then determines the slope (given that the same clipping factors are used, but in this case, it is the first 25% in any case, right?). The resutlting values should be identical.

I compared the single slopes with the MSDs of the sinlge curves - they fit, i.e. if I plot the MSD of curve n, fit it and compare it to the slope of curve n after the fitMSD-procedure, they line up.

I am really sorry to bother you yo much, but I think you are the best person to ask.

Thanks a lot in advance!



Hi Jean-Yves,

could you go a little into detail why the mean value of all the single slopes is not identical to the slope obtained from the mean MSD curve...? So far, I have found no reason why these two values should be different.
When individual tracks are fitted, only the first 25% of the tacks are considered as in case of the calculation of the mean MSD curve. So - why is there this discrepancy?

Thanks a lot!:)

For the record: the problem reported by @LM and @YOUNGKWANG LEE is not a problem.
When fitting individual tracks, the fit receives the expected amount of data regardless of the individual size of tracks.

I think you have found a bug. Can you send me the faulty data so that I can investigate it and reproduce the bug? That would help me.


Hi Jean-Yves,

once more, it's me;)
I used the fitMSD routine to calculate the slopes as you said (I really should have just looked up the

manual... sorry!^^).

As I wrote before, I used getMeanMSD to obtain the mean MSD curve for the tracked particles. If I fit

a linear curve to the data, I obtain a certain value for the straight line mean MSD vs. time.

Now, I used fitMSD to get the slopes for all the single MSD curves ("a" in lfit).

And here comes my question: Shouldn't this mean of all the a-values result in the value of the slope that I obtain when fitting the mean MSD curve...? Becuase - this isn't the case. The mean of all the a-values is about 40% larger than the slope of the mean MSD curve.



Hi Jean-Yves,

thank you very much for your fast answer!:)

Hi Jean-Yves,

Thank you for sharing nice tools.

I have some problem running msdanlayzer.
Running with fake data is completely fine, but when I work with actual data, I have some bugs.

In short, all trajectories have different trajectory length. If I do MSD fit to get individual D values from each trajectory, the fitting range is automatically set as Max. trajectory length * clip factor. It turned out all computed msd values have same time axis corresponding to the longest trajectories. In short trajectories, If the x^2 and y^2 is not available in the later time delay, NaN is shown.

Thank you.

Hi @LM,
The fitMSD method does what you want.


Hi Jean-Yves,

it's me again - I asked a question some months ago;) The problem I had that time is solved now, and before I come to the next one, let me compliment you for this great program! H
Now, to my question - I guess it is a rather silly one, but I am pretty much of a matlab-noob... For a certain application I need the diffusion coefficients of every single trajectory, not the mean diffusion coefficient. Of course, your program calculates it, because it calculates the mean, but how can I the values out? In the ideal case, I just have a list with diffusion coefficients obtaiend from every single MSD curve...

Thanks a lot!:)

John Rogers

Hi Jean-Yves,

I am having a similar problem as others have with the error, "No appropriate method, property, or field addAll for class msdanalyzer." I have checked that the paths are set properly, but things are still not working. Do you have any advice on how to make this program work?


Hi Jean-Yves,

I found out where the problem was.

Thank's for a really great and robust program.


Hi Jean-Yves,

First thank's a lot for sharing such program. However I have a little difficulties to run it. In the fact, I have the same problem as Florent and Johannes already reported. When typing "ma=ma.addAll(tracks);" it gives me "No appropriate method, property, or field addAll for class msdanalyzer."
According to you intstructions I typed "which msdanalyzer" and it gives me "E:\Martin\Matlab-fce\Makra\MSD analyzer\msdanalyzer.m % msdanalyzer constructor", similarly typing "which addAll" shows "E:\Martin\Matlab-fce\Makra\MSD analyzer\addAll.m".
I suppose the path is set well, however Matlab still complains. I also tried to put your function package to C:\....\Matlab\toolbox\MSD analyzer folder but it did not help.
Any hint would be helpful

Thank's a lot


Hi Jean-Yves,
Yes, it involves the ImarisXT version of the MatLab program.
I can send you one of the files for which this error occurs (there are several - though not all the files I have made this way). I will send you a message directly for this, and we can discuss it on ImarisOpen.
Many thanks,

Hi @Liam.
It seems that you are commenting on another - related - piece of software. From the bug you report, I guess you are speaking of the port of this class to the ImarisXT right?
Let's discuss it on the ImarisOpen page. Also, I cannot do anything without the file that produces the bug.


Hi again Jean-Yves,

I have a new error message appearing which is slightly different to the previous one (which strangely just stopped appearing when I reanalysed my data in Imaris...).
Here is the error message:

Index exceeds matrix dimensions.

Error in importTracksFromImarisXT (line 54)
T{i} = t(trackFrames);

Error in XTMeanSquareDisplacementGrapher (line 116)
tracks = importTracksFromImarisXT(vSpots);

Is this still the same origin?
I have checked the number of digits of the timestamps in Imaris, and there are only 3 decimal places as far as I can tell. I also checked the timestamps of the imported data, and there are usually 2-3 decimals, and very occasionally 4-5.
Also, this error is appearing for only some tracks of a .ims file, but not other tracks (in the same .ims file).

Do you have any ideas?



Hi Jean-Yves,
now it is ok, Thank you for your help, and this code is very useful.

Kind regards,

Hi @Renjie
It looks like an installation problem. MSDanalyzer is shipped as a class, so you need to install it as a class. Check that the folder containing @msdanalyzer is in the path, but not the @msdanalyzer folder itself.
Tell me if it works.



Hi Jean-Yves,

First I need to say it is a very useful program, thank you for your sharing. However, following the tutorial, the first step is error, when I input mc=msdanalyzer(2,'μm','s'); the matlab will say there is no function for 'private'. Did you find this situation? can you help me for this?

Thank you so much for your help.

Kind regards,


Hi @Javad
It's always the same bug. Just check my comment below on its origin and how to fix it.


Hi Jean-Yves,

First I'd like to appreciate you for sharing your comprehensive program. I tried several times to run it with my own trajectories but I got the following error:
1/ 525Error using -
Matrix dimensions must agree.

Error in msdanalyzer/computeMSD (line 86)
delta = dr2 - mean_msd(index_in_all_delays);

I did not go through the subroutines but can I ask you that weather you used smoothing or any kind of noise reduction procedure in your code or not?

Kind regards,

Hi @Liam, and thanks for the feedback.
What you mention here resembles a known bug. If the frame interval of the movie you want to analyze is defined over too many digits (something like 0.18374531289123648392716 seconds), the class gets confused when binning intervals together, which ultimately triggers the error you got.
Could you please check what is the frame interval in your case? Cropping it to a few digits should solve the problem.


Hi Jean-Yves,

Great piece of software! Very useful. However I used it for Imaris tracks analysis and got the following error:

Computing velocity autocorrelation of 152 tracks... [...] 17/152Error using +
Matrix dimensions must agree.

Error in msdanalyser/computeVCorr (line 1266)
sum_vcorr(index_in_all_delays) = sum_vcorr(index_in_all_delays) + lvcorr;

Error in XTMeanSquareDisplacementGrapher (line 137)
msd = msd.computeVCorr;

Do you have a solution for this? (I'm afraid to say I have no knowledge of MatLab language...).

Many thanks!

Hi @LM,
I am a great admirer of the u-track software, but I did not create something that can arrange its results into the analyzer, sorry.
Thanks for feedback.



Hello Jean-Yves,

first of all congrats to your fone program!
I have a question regarding the preparation of data for the analysis. It needs to be a cell array with the time points and x/y-coordinates. I use uTrack ( for tracking. This gives me the coordinates in a quite complicated way. I am rather new to matlab and have difficulties to arrange them as the msdanalyzer needs them.
So here is my question: Do you perhaps have already used uTrack for tracking or now a method by somebody else to extract the relevant data from the output?
Any help would be very much appreciated!


@Vid. Indeed the problem is caused by the frame interval having too many digits. This causes rounding errors while subtracting time position between frames, and some frame intervals are not pooled together.
This a severe flaw, originating from my design choice. Storing the frame intervals in physical units was a bad idea that leads to these errors and the only solution is to rewrite the analyzer and store the frame intervals as integer.
In the meantime, your fix works of course.

@Florent @Johannes. This clearly points to a MATLAB path problem. Remember that msdanalyzer is a class. What does
>> which msdanalyzer

Vid Sustar


I've sent the xml file via email some time ago, but anyhow, with one colleague we backtracked the code.

Indeed the frameInterval in trackmate .xml file had too many decimals (due to Zeiss microscope software update).

I've solved it by adding a 100. line to ImportTrackmateTracks.m: metadata.frameInterval = digits(7);

Best regards,



I have the same problem as "Florent" with the addall "ma=ma.addAll(tracks)". Error message: "No appropriate method, property, or field addAll for class msdanalyzer.".

I checked the location of the Files with "which msdanalyzer":
C:\ProgramFiles\MATLAB\R2012a\toolbox\msd\msdanalyzer.m % msdanalyzer constructor


C:\Program Files\MATLAB\R2012a\toolbox\msd\addAll.m

If I get it right the file locations are ok and the code must be work?!

Best regards

Hi @Vid,
I suspect this is caused by a problem found by a good friend, related to rounding errors with float frame intervals. Could you send me via email the XML file of the tracks?

Vid Sustar


When using msdanalyser with xml file from trackmate I get a message:
Computing MSD of 44 tracks... 1/ 44Error using -
Matrix dimensions must agree.

Error in msdanalyzer/computeMSD (line 487)
delta = dr2 - mean_msd(index_in_all_delays);

How could this problem be solved?

Best regards,

Vid Sustar

Hi @Florent
It seems like an installation problem.
What does the 'which msdanalyzer' command says?
What does 'help msdanalyzer' says?

Hi Jean-Yves,
I have a problem with a class type with your matlab files especially for the addall "ma = ma.addAll(tracks);".
I have this error message printed on the terminal: "No appropriate method, property, or field addAll for class msdanalyzer.".
Did you have this message in the past or have a solution to make it work?
Looking forward to reading to you very soon.
Best regards


For the record: @Gurthwin sent me his track for me to investigate and I found them to be faulty. In some cases, the times of two consecutive detections were the same, so we had dT = 0 for them, which caused the msdanalyzer not to work properly.
Gurthwin is investigating the cause of the problem on his side, and I released a new version that checks that the tracks provided don't have this problem.


Hi Jean-Yves

I would be able to send you the data.


It looks like a touchy part of the code. I would need the data that generates the error to fix it. Can you contact me via email to send it?



This is really a wonderful tool for MSD analysis. I have attempted to submit some of my own tracks but I am greeted with the following error msg in the command window:
Computing MSD of 208 tracks... 3/ 208??? Error using ==> minus
Matrix dimensions must agree.

Error in ==> msdanalyzer>msdanalyzer.computeMSD at 470
delta = dr2 - mean_msd(index_in_all_delays);

I am pretty sure that the tracks are correct. What do you suggest I do?


@Fredik: Hi Fredik.
Actually no: this MATLAB class is a per-value class, which means that the updates are lost if you do not re-assign the changed object to a new reference.
So in fact you need to do something like that:
>> msd = msd.addTracks(...);
each time.


Its a really nice little class that will be very useful I think. Especially nice to see such good documentation.

I have one problem Im hoping to get assistance with:
In principle everything that should update the properties throw out a new obj looking like it should (with eg added trajectories etc). But the object operated on did not save the updates. If I change the constructor to take trajectories it works and they persist as an object property but cannot be changed.

I am using Matlab 2012a if that should matter.
I dont have any other problems with similar classes that I use.

Would appreciate any input on this.


Hi. The tool is documented in the html tutorial you will find in the download. Just read it, and you will find the info you need.

I really want to use this msdanalyzer, but I could not find any documentation for usage. What type of file (trajectory) do I have to load for analysis? How can I load my trajectory?
Thanks a lot.


Yilong Jia


Yilong Jia

Matt Baker

Great documentation. Standalone it is a very useful tutorial for understanding MSD computation, but additionally is very functional for diffusion coefficient computation across myriad situations.


Link to source on github, and to the online tutorial.

- Safeguards to ensure that the tracks provided are not erroneous.
- Links to the paper for which this work was created, now that it is out.

MATLAB Release Compatibility
Created with R2012b
Compatible with any release
Platform Compatibility
Windows macOS Linux

Inspired by: raacampbell/shadedErrorBar