soft-matter / trackpy

Python particle tracking toolkit
http://soft-matter.github.io/trackpy
Other
449 stars 132 forks source link

trackpy.relate_frames() issue #553

Open gernor opened 5 years ago

gernor commented 5 years ago

Lately, I ran into a problem when using the relate_frames() function. Below a small part of the frames I wanted to analyze:

Schermafbeelding 2019-06-04 om 16 49 23

When I use the relate_frames() function, it only works for a few combinations of frames. For example, it works properly for the following comparisons:

Schermafbeelding 2019-06-04 om 17 02 44 Schermafbeelding 2019-06-04 om 16 47 59

However, when I want to compare frame 136 and 137, the following error occurs:

Schermafbeelding 2019-06-04 om 16 48 20

I got the same error for quite a few more combinations in my dataset.

I solved the problem by changing the relate_frames() functions slightly (in my own python code). I changed numpy.sum() to sum() and it worked as it should.

Schermafbeelding 2019-06-04 om 16 56 41 Schermafbeelding 2019-06-04 om 17 14 18

I am not sure why this fixed my problem, but it did. Does anyone know why? Besides, I thought it might be helpful to at least mention the problem and my solution, since someone else might run into the same problem.

caspervdw commented 5 years ago

Thanks for the report. It seems like we are using the wrong sum function, but replacing it by the built in sum is not the best solution. This is because the built in one will result in a “under the hood” for loop in python, while the numpy version has the loop implemented in C.

Could you try something like :

pd.sum(df[[‘d’ + x for x in pos_columns]]**2), axis=1)**0.5

In that way we still take advantage of the better performance.

FdeSchae commented 5 years ago

I wanted to add to this topic as I have experienced the exact same issue.

After some digging I found the issue. It seems the problem occurs when j only has one row, meaning one particle. This is also supported by @gernor findings. In the instances tp.relate_frames worked he had more that one particle he fed into function. While the error only occurred when there was only one particle.

The suggested solution by @caspervdw does not help with this problem.

To solve the problem I changed

j['dr'] = np.sqrt(np.sum([j['d' + pos]**2 for pos in pos_columns], 0))

into

if j.shape[0] == 1: j['dr'] = np.sqrt(sum([j['d' + pos]2 for pos in pos_columns], 0)) else: j['dr'] = np.sqrt(np.sum([j['d' + pos]2 for pos in pos_columns], 0))

(ofcourse with the right indents)

This solution seems to work fine for me, but please advice nonetheless!

Furthermore, I am curious as to why np.sqrt and np.sum are used while np.hypot would do exactly the same in one function?

Cheers, Fre

rbnvrw commented 5 years ago

Hi @Renderfarm thank you for the clarification. Would you maybe be interested in submitting a pull request to fix this issue? Your help would be greatly appreciated! :+1: