Displacement Trajectory for Cluster

Quote from Amir Ghorbani on October 31, 2021, 6:36 pmHi
I want to trace the displacement of my clusters at each frame with reference to:
- previous frame
- the Nth frame
and show them as new columns in my table which contains:
- Cluster Identifier": np.int32,
- "Cluster Size": np.int32,
- "Center of Mass.X": np.float64,
- "Center of Mass.Y": np.float64,
- "Center of Mass.Z": np.float64,
- "Radius of Gyration": np.float64,
- "Gyration Tensor.XX": np.float64,
- "Gyration Tensor.YY": np.float64,
- "Gyration Tensor.ZZ": np.float64,
- "Gyration Tensor.XY": np.float64,
- "Gyration Tensor.XZ": np.float64,
- "Gyration Tensor.YZ": np.float64,
- "Time":np.float64
adding the modifier (PipeLine.modifiers.append(CalculateDisplacementsModifier())) will compare atoms individually which results in an error in the case of those which are not in the cluster. Is there any way to find the displacement trajectory for clusters?
for your consideration, below you can find my code:
def ClusterAnalyser(Path_V): PipeLineAdress = Path_V + "" + "*.dump" ReadAddress = Path().resolve() ReadAddressPure = PurePath(ReadAddress) ReadAddressPureParts = ReadAddressPure.parts Try = ReadAddressPureParts[-1] Potential = ReadAddressPureParts[-2] Energy = ReadAddressPureParts[-3] # Importing Dump Files PipeLine = import_file(PipeLineAdress, multiple_frames=True) # Returns number of frames PipeLineFramesCount = PipeLine.source.num_frames print("PipeLineFramesCount is:" + str(PipeLineFramesCount)) # Perform Wigner-Seitz analysis ws = WignerSeitzAnalysisModifier(per_type_occupancies=True, eliminate_cell_deformation=True) PipeLine.modifiers.append(ws) PipeLine.modifiers.append(OvitoWsTime) select = SelectExpressionModifier(expression="Occupancy==1") PipeLine.modifiers.append(select) PipeLine.modifiers.append(DeleteSelectedModifier()) PipeLine.modifiers.append(InvertSelectionModifier()) ExportFileName = "20211019-ClusterAnalysis.OvitoDataWs" export_file(PipeLine, ExportFileName, "txt", columns=['Frame', 'Time', 'Timestep', 'WignerSeitz.interstitial_count', "WignerSeitz.vacancy_count"], multiple_frames=True) ExportAddress = Path_V + "" + ExportFileName WsDf = pd.read_csv(ExportAddress,header=None,skiprows=1, dtype={"Frame": np.int32, "Time": np.float64, "Timestep": np.int32, "WignerSeitz.interstitial_count": np.int32, "WignerSeitz.vacancy_count": np.int32}, delimiter=" ", names=["Frame", "Time", "Timestep", "SIA", "Vacancy"],index_col=False) WsDf.reset_index(drop=True) WsDf ["Try"] = Try WsDf ["Potential"] = Potential WsDf ["Energy"] = Energy print("WsDf is:") print(WsDf) WsDf.to_csv("20211019-WsDf.csv", index=False) # Perform Cluster Size Analysis PipeLine.modifiers.append(CreateBondsModifier(cutoff=3.8)) ClusterAnalysis = ClusterAnalysisModifier( neighbor_mode=ClusterAnalysisModifier.NeighborMode.Bonding, cutoff=3.8, sort_by_size=True, compute_com=True, compute_gyration=True, cluster_coloring=True) PipeLine.modifiers.append(ClusterAnalysis) PipeLine.modifiers.append(OvitoClusterTime) PipeLine.modifiers.append(CalculateDisplacementsModifier()) PipeLine.modifiers.append(OvitoClusterSize) PipeLine.modifiers.append(ExpressionSelectionModifier(expression='ClusterSize < 4')) PipeLine.modifiers.append(DeleteSelectedModifier()) ExportFileName = "20211019-ClusterAnalysis.OvitoDataCa" export_file(PipeLine, ExportFileName, 'txt/table', key='clusters', multiple_frames=True) CaDf = [] for frame in range(PipeLineFramesCount): data = PipeLine.compute(frame) # print(data) ExportFileName = str(frame) + ".OvitoDataCa" export_file(data, ExportFileName, 'txt/table', key='clusters', multiple_frames=False) CaDfNew = pd.read_csv(ExportFileName, header=None, skiprows=2, dtype={"Cluster Identifier": np.int32, "Cluster Size": np.int32, "Center of Mass.X": np.float64, "Center of Mass.Y": np.float64, "Center of Mass.Z": np.float64, "Radius of Gyration": np.float64, "Gyration Tensor.XX": np.float64, "Gyration Tensor.YY": np.float64, "Gyration Tensor.ZZ": np.float64, "Gyration Tensor.XY": np.float64, "Gyration Tensor.XZ": np.float64, "Gyration Tensor.YZ": np.float64, "Time":np.float64}, delimiter=" ", names=["Cluster Identifier", "Cluster Size", "Center of Mass.X", "Center of Mass.Y", "Center of Mass.Z", "Radius of Gyration", "Gyration Tensor.XX", "Gyration Tensor.YY", "Gyration Tensor.ZZ", "Gyration Tensor.XY", "Gyration Tensor.XZ", "Gyration Tensor.YZ", "Time"], index_col=False) CaDfNew["Frame"] = frame CaDf.append(CaDfNew) CaDf = pd.concat(CaDf) CaDf["Try"] = Try CaDf["Potential"] = Potential CaDf["Energy"] = Energy print("CaDf is:") print(CaDf) CaDf.to_csv("20211019-CaDf.csv", index=False) return WsDf, CaDf
Hi
I want to trace the displacement of my clusters at each frame with reference to:
- previous frame
- the Nth frame
and show them as new columns in my table which contains:
- Cluster Identifier": np.int32,
- "Cluster Size": np.int32,
- "Center of Mass.X": np.float64,
- "Center of Mass.Y": np.float64,
- "Center of Mass.Z": np.float64,
- "Radius of Gyration": np.float64,
- "Gyration Tensor.XX": np.float64,
- "Gyration Tensor.YY": np.float64,
- "Gyration Tensor.ZZ": np.float64,
- "Gyration Tensor.XY": np.float64,
- "Gyration Tensor.XZ": np.float64,
- "Gyration Tensor.YZ": np.float64,
- "Time":np.float64
adding the modifier (PipeLine.modifiers.append(CalculateDisplacementsModifier())) will compare atoms individually which results in an error in the case of those which are not in the cluster. Is there any way to find the displacement trajectory for clusters?
for your consideration, below you can find my code:
def ClusterAnalyser(Path_V): PipeLineAdress = Path_V + "" + "*.dump" ReadAddress = Path().resolve() ReadAddressPure = PurePath(ReadAddress) ReadAddressPureParts = ReadAddressPure.parts Try = ReadAddressPureParts[-1] Potential = ReadAddressPureParts[-2] Energy = ReadAddressPureParts[-3] # Importing Dump Files PipeLine = import_file(PipeLineAdress, multiple_frames=True) # Returns number of frames PipeLineFramesCount = PipeLine.source.num_frames print("PipeLineFramesCount is:" + str(PipeLineFramesCount)) # Perform Wigner-Seitz analysis ws = WignerSeitzAnalysisModifier(per_type_occupancies=True, eliminate_cell_deformation=True) PipeLine.modifiers.append(ws) PipeLine.modifiers.append(OvitoWsTime) select = SelectExpressionModifier(expression="Occupancy==1") PipeLine.modifiers.append(select) PipeLine.modifiers.append(DeleteSelectedModifier()) PipeLine.modifiers.append(InvertSelectionModifier()) ExportFileName = "20211019-ClusterAnalysis.OvitoDataWs" export_file(PipeLine, ExportFileName, "txt", columns=['Frame', 'Time', 'Timestep', 'WignerSeitz.interstitial_count', "WignerSeitz.vacancy_count"], multiple_frames=True) ExportAddress = Path_V + "" + ExportFileName WsDf = pd.read_csv(ExportAddress,header=None,skiprows=1, dtype={"Frame": np.int32, "Time": np.float64, "Timestep": np.int32, "WignerSeitz.interstitial_count": np.int32, "WignerSeitz.vacancy_count": np.int32}, delimiter=" ", names=["Frame", "Time", "Timestep", "SIA", "Vacancy"],index_col=False) WsDf.reset_index(drop=True) WsDf ["Try"] = Try WsDf ["Potential"] = Potential WsDf ["Energy"] = Energy print("WsDf is:") print(WsDf) WsDf.to_csv("20211019-WsDf.csv", index=False) # Perform Cluster Size Analysis PipeLine.modifiers.append(CreateBondsModifier(cutoff=3.8)) ClusterAnalysis = ClusterAnalysisModifier( neighbor_mode=ClusterAnalysisModifier.NeighborMode.Bonding, cutoff=3.8, sort_by_size=True, compute_com=True, compute_gyration=True, cluster_coloring=True) PipeLine.modifiers.append(ClusterAnalysis) PipeLine.modifiers.append(OvitoClusterTime) PipeLine.modifiers.append(CalculateDisplacementsModifier()) PipeLine.modifiers.append(OvitoClusterSize) PipeLine.modifiers.append(ExpressionSelectionModifier(expression='ClusterSize < 4')) PipeLine.modifiers.append(DeleteSelectedModifier()) ExportFileName = "20211019-ClusterAnalysis.OvitoDataCa" export_file(PipeLine, ExportFileName, 'txt/table', key='clusters', multiple_frames=True) CaDf = [] for frame in range(PipeLineFramesCount): data = PipeLine.compute(frame) # print(data) ExportFileName = str(frame) + ".OvitoDataCa" export_file(data, ExportFileName, 'txt/table', key='clusters', multiple_frames=False) CaDfNew = pd.read_csv(ExportFileName, header=None, skiprows=2, dtype={"Cluster Identifier": np.int32, "Cluster Size": np.int32, "Center of Mass.X": np.float64, "Center of Mass.Y": np.float64, "Center of Mass.Z": np.float64, "Radius of Gyration": np.float64, "Gyration Tensor.XX": np.float64, "Gyration Tensor.YY": np.float64, "Gyration Tensor.ZZ": np.float64, "Gyration Tensor.XY": np.float64, "Gyration Tensor.XZ": np.float64, "Gyration Tensor.YZ": np.float64, "Time":np.float64}, delimiter=" ", names=["Cluster Identifier", "Cluster Size", "Center of Mass.X", "Center of Mass.Y", "Center of Mass.Z", "Radius of Gyration", "Gyration Tensor.XX", "Gyration Tensor.YY", "Gyration Tensor.ZZ", "Gyration Tensor.XY", "Gyration Tensor.XZ", "Gyration Tensor.YZ", "Time"], index_col=False) CaDfNew["Frame"] = frame CaDf.append(CaDfNew) CaDf = pd.concat(CaDf) CaDf["Try"] = Try CaDf["Potential"] = Potential CaDf["Energy"] = Energy print("CaDf is:") print(CaDf) CaDf.to_csv("20211019-CaDf.csv", index=False) return WsDf, CaDf

Quote from Constanze Kalcher on November 1, 2021, 11:51 amHi,
your exported tables contain the center of mass of each cluster at every frame - so in principle you could simply post-process this data to calculate the displacement of your clusters in reference to any frame.
However, you need to be very careful with this analysis, since there is no guarantee that Cluster ID's in consecutive frames denote the same cluster, especially when they change their sizes. If you haven't taken this into account already I would recommend to compare the particle identifiers of the particles forming each cluster between two consecutive frames and then also allow for some lost/additional particles as clusters can shrink or grow.
-Constanze
Hi,
your exported tables contain the center of mass of each cluster at every frame - so in principle you could simply post-process this data to calculate the displacement of your clusters in reference to any frame.
However, you need to be very careful with this analysis, since there is no guarantee that Cluster ID's in consecutive frames denote the same cluster, especially when they change their sizes. If you haven't taken this into account already I would recommend to compare the particle identifiers of the particles forming each cluster between two consecutive frames and then also allow for some lost/additional particles as clusters can shrink or grow.
-Constanze
新的OVITO微信频道!
New for our users in China: OVITO on WeChat
Official OVITO WeChat channel operated by Foshan Diesi Technology Co., Ltd.
