# Identifying and tracking cluster elements in ClusterClassify for multiple time-steps of data

I have multiple time-steps of {x,y,z}coordinates data for some atoms. I would like to cluster the data for each frame and later identify how cluster compositions change and how each atom changes from one cluster to another.

That is, if atom number 54 was in cluster 1, how many members are lost or added in the next frame? Similarly, how do the number of clusters change and on average, what is the difference in cluster composition between one frame and the next? I am at a complete loss on how to proceed. Additionally, plotting the points in different clusters is also desirable. I have tried to create some data to demonstrate the problem.

The interpretation would be 10 frames of data and each frame has coordinates of 100 atoms. Each atom is identified by an atom number and each frame has a key of "frame number".

dataFrames = Association[Table[i -> Association[Table[i -> RandomReal[3, 3], {i, 1, 100}]], {i, 1, 10}]];
clustersEachFrame = FindClusters[#, Method -> "DBSCAN"] & /@ dataFrames;


A truncated output of clustersEachFrame is shown below

<|1 -> {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 63, 65, 66, 67, 68,
69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
85, 86, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100}, {22,
62, 64, 87}},  2 -> {{1, 2, 3, 4, 5, 7, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 34, 35, 37, 39, 40,
41, 42, 44, 45, 46, 47, 48, 49, 51, 52, 53, 55, 56, 58, 59, 60,
62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
79, 80, 81, 82, 85, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 98,
100}, {6, 33, 61, 84, 99}, {8, 13, 31, 38, 43, 50, 54, 66, 86,
97}, {36, 57, 83}},


Finding the total number of clusters in each frame is easy.

Length/@clustersEachFrame
<|1 -> 2, 2 -> 4, 3 -> 3, 4 -> 1, 5 -> 2, 6 -> 2, 7 -> 6, 8 -> 9,9 -> 3, 10 -> 3|>


Now, figuring out which cluster did a particular atom belong to in each frame? I have no idea how to do that. I look for any advice that the community can offer. Are there better data representations, eg. Dataset that I should think about for this or any connected advice is highly appreciated.

Thank you,

• It is difficult to test this on random data. I am guessing that you want to identify cluster correspondence between frames. With random data there will be no correlation (i.e, atom 1 will jump from cluster to cluster.) I recommend organizing your data as dataFrames = RandomReal[{-1, 1}, {10, 100, 3}] an then clustersEachFrame = FindClusters[#, Method -> "DBSCAN"] & /@ dataFrames I'd try computing the center of mass for each cluster, then update the centers of mass of each with a Nearest[com->"Index"]--thus tracking the correspondence. Perhaps your "real data" might test this? Commented May 24, 2022 at 5:35
• Thanks a lot for this. I thought I might figure out representations etc. using random data and add time step as key for association. However, I see your point. The suggestion to use Nearest for tracking correspondence is highly appreciated. Thank you. Commented May 25, 2022 at 10:08