-
Notifications
You must be signed in to change notification settings - Fork 0
/
reconstruct_video.py
97 lines (85 loc) · 3.35 KB
/
reconstruct_video.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# Filename: reconstruct_video.py
# Description: Contains functions to reconstruct the series/surface
# from the lower dimensional data.
# Authors: Christian Choe, Min Cheol Kim
import networkx as nx
import numpy as np
import copy as cp
def greedy_reconstruct_frame_order(iso_result):
num_frames, num_components = iso_result.shape
# Compute full (duplicated distance matrix)
distances = np.zeros((num_frames, num_frames))
for fr1 in range(num_frames):
for fr2 in range(num_frames):
distances[fr1, fr2] = np.linalg.norm(iso_result[fr1,] - iso_result[fr2,])
distances[distances==0] = np.nan
overall_std = np.nanstd(distances)
overall_mean = np.nanmean(distances)
# Purge frames who's average distance to every other frame is too large
distances_copy = distances
for fr in range(num_frames):
frame_mean = np.nanmean(distances[fr,])
if abs(frame_mean - overall_mean)/overall_std > 1:
distances[fr,] = np.nan
distances[:,fr] = np.nan
pair1, pair2 = np.unravel_index(np.nanargmin(distances), distances.shape)
distances[pair1, pair2] = np.nan
distances[pair2, pair1] = np.nan
final_order = np.array([pair1, pair2])
while True:
min1 = -1
min2 = -1
if np.sum(np.isnan(distances[pair1,])) == num_frames:
min1 = np.inf
else:
min1 = np.nanmin(distances[pair1,])
if np.sum(np.isnan(distances[pair2,])) == num_frames:
min2 = np.inf
else:
min2 = np.nanmin(distances[pair2,])
if min1 == np.inf and min2 == np.inf:
break
if min1 < min2:
minidx = np.nanargmin(distances[pair1,])
final_order = np.insert(final_order, 0, minidx)
distances[pair1,] = np.nan
distances[:,pair1] = np.nan
pair1 = minidx
else:
minidx = np.nanargmin(distances[pair2,])
final_order = np.append(final_order, minidx)
distances[pair2,] = np.nan
distances[:,pair2] = np.nan
pair2 = minidx
distances[pair1, pair2] = np.nan
distances[pair2, pair1] = np.nan
return final_order
def get_minimum_spanning_tree(iso_result):
num_frames, num_components = iso_result.shape
# Compute full (duplicated distance matrix)
distances = np.zeros((num_frames, num_frames))
for fr1 in range(num_frames):
for fr2 in range(num_frames):
distances[fr1, fr2] = np.linalg.norm(iso_result[fr1,] - iso_result[fr2,])
# Construct the graph/get minimum spanning tree
G = nx.from_numpy_matrix(distances)
G = nx.minimum_spanning_tree(G)
return G
def get_path_from_MSP(minG):
best_path_len = -1
best_path = []
degrees = minG.degree()
leaves = [key for key,value in degrees.iteritems() if value == 1]
for idx, src in enumerate(leaves):
for snk in leaves[idx + 1:]:
for path in nx.all_simple_paths(minG, source=src, target=snk):
if len(path) > best_path_len:
best_path_len = len(path)
best_path = path
return best_path
def get_reconstructed_traj(shuffled_traj, order):
copy = cp.deepcopy(shuffled_traj)
copy.xyz = shuffled_traj.xyz[order, :, :]
return copy
def save_new_trajectory(md_obj, filename):
md_obj.save_dcd(filename)