I have the particle movement data in the following format:

 {1., 1., 0., 0.},
 {1., 2., 0.240727, 0.974106},
 {1., 3., 0.0215366, 0.703085},
 {1., 4., 0.437541, 1.19085},
 {2., 1., 0., 0.},
 {2., 2., -2.17808, 0.455328},
 {2., 3., -2.97556, -0.668351},
 {2., 4., -3.91848, -1.25396},
 {3., 1., 0., 0.},
 {3., 2., -0.523589, 0.136621},
 {3., 3., -1.87956, 0.679403},
 {3., 4., -2.36116, 0.749859}

The first number is the particle number, second is the frame number in the movie, third is the $x$ position, and the fourth is the $y$-position. So in the above data, the first 4 lists belong to particle 1, the next 4 to particle 2 and the last 4 to particle 3.

I need to calculate the mean square displacement (MSD) $(x_2-x_1)^2 + (y_2-y_1)^2$ for each of the particles separately. I can calculate MSD if I don't have to care about the above data having 3 particles, treat all as the same (but that's not what I want). I need to calculate MSD for each of these particles separately. Basically, somehow I have to tell the program where the the data for particle 1 end and where data for particle 2 starts.

In MATLAB, I have used the find function to return the location index of the number "1" in the second column of the data and run the loop till that index to calculate MSD for each particle.

I am new to Mathematica and trying to learn it. It's taking me a while to find a answer to this problem. Can anyone help?


1 Answer 1


Let's break down the task step by step.

  1. Separate the data for the different particles: GatherBy
  2. Sort data by frame number (not really necessary as it's sorted, but let's do it anyway): SortBy
  3. Extract the positions and calculate the MSD.

I have your data stored in the variable data.

GatherBy[data, First] separates into sublists having the same first element (same particle). Let's take the first sublist, sublist = First@GatherBy[data, First].

sublist = SortBy[sublist, #[[2]]&] sorts the sublist by the second element (frame number).

Now take the difference of sequential coordinates, take the squared norm of that difference, and calculate the mean: Mean[#.#& /@ sublist[[All, {3,4}]] ].

Putting it all together:

gatheredData = GatherBy[data, First];

msd = Function[sublist, 
  Mean[#.# & /@ 
    Differences@SortBy[sublist, #[[2]] &][[All, {3, 4}]]
] /@ gatheredData

You may wish to pair up this list of results with the particle indices:

Transpose[{gatheredData[[All, 1, 1]], msd}]

(* ==> {{1., 0.513101}, {2., 2.69401}, {3., 0.887661}} *)

Again, this is not necessary if your list was originally sorted by particle index, but it's important if it wasn't.

Recommended reading to understand this code:

  • $\begingroup$ Thank you for your answer. I do get most of it. I still get confused by the syntaxes in mathematica, but I will read the documentation and try to make complete sense of this. $\endgroup$
    – Anjil
    Dec 19, 2013 at 19:55
  • $\begingroup$ @Anjil It's helpful to read code from "outside to inside". First just look at Function[...] /@ gatheredData. Now try t understand what that function does by using it on a single element of gatheredData. You'll see that that's just what I wrote in the first part of the answer. Keep moving inward in the expression to understand what's going on. $\endgroup$
    – Szabolcs
    Dec 19, 2013 at 19:59
  • $\begingroup$ I posted a similar quetsion here: mathematica.stackexchange.com/questions/112100/… and would be very happy if you could help me. The user BlacKow gave a very nice answer based on you answer here, but I have the feeling that it is not fully correct. E.g. I need the Mean of x^2 +y^2 and found out that there might be a problem. Please see my comment: imgur.com/8BAX4pe . Thank you in advance. $\endgroup$
    – mrz
    Apr 8, 2016 at 8:04
  • $\begingroup$ I posted a similar gestion: mathematica.stackexchange.com/questions/112100/… and would be happy if you could help. User BlacKow gave a nice answer based on you answer, but I have the feeling that it is not fully correct. I need the Mean of xdiff^2 +ydiff^2 and found out that there is a problem. Please see here: imgur.com/8BAX4pe I compared the result based on your code with Pythons well known trackpy package, and there is a difference: soft-matter.github.io/trackpy . My Table code produces exactly the same results. $\endgroup$
    – mrz
    Apr 8, 2016 at 8:25
  • $\begingroup$ @mrz I won't be able to spend much time here until Tuesday. Can you remind me then please? $\endgroup$
    – Szabolcs
    Apr 8, 2016 at 14:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.