MCPcopy Create free account
hub / github.com/DeepGraphLearning/S3F / subsample

Function subsample

s3f/surface.py:107–153  ·  view source on GitHub ↗

Subsamples the point cloud using a grid (cubic) clustering scheme. The function returns one average sample per cell, as described in Fig. 3.e) of the paper. Args: x (Tensor): (N,3) point cloud. batch (integer Tensor, optional): (N,) batch vector, as in PyTorch_geometric

(x, batch=None, scale=1.0)

Source from the content-addressed store, hash-verified

105# On-the-fly generation of the surfaces ========================================
106# Code taken from https://github.com/FreyrS/dMaSIF/blob/master/geometry_processing.py
107def subsample(x, batch=None, scale=1.0):
108 """Subsamples the point cloud using a grid (cubic) clustering scheme.
109
110 The function returns one average sample per cell, as described in Fig. 3.e)
111 of the paper.
112
113 Args:
114 x (Tensor): (N,3) point cloud.
115 batch (integer Tensor, optional): (N,) batch vector, as in PyTorch_geometric.
116 Defaults to None.
117 scale (float, optional): side length of the cubic grid cells. Defaults to 1 (Angstrom).
118
119 Returns:
120 (M,3): sub-sampled point cloud, with M <= N.
121 """
122
123 if batch is None: # Single protein case:
124 if True: # Use a fast scatter_add_ implementation
125 labels = grid_cluster(x, scale).long()
126 C = labels.max() + 1
127
128 # We append a "1" to the input vectors, in order to
129 # compute both the numerator and denominator of the "average"
130 #  fraction in one pass through the data.
131 x_1 = torch.cat((x, torch.ones_like(x[:, :1])), dim=1)
132 D = x_1.shape[1]
133 points = torch.zeros_like(x_1[:C])
134 points.scatter_add_(0, labels[:, None].repeat(1, D), x_1)
135 return (points[:, :-1] / points[:, -1:]).contiguous()
136
137 else: # Older implementation;
138 points = scatter(points * weights[:, None], labels, dim=0)
139 weights = scatter(weights, labels, dim=0)
140 points = points / weights[:, None]
141
142 else: # We process proteins using a for loop.
143 # This is probably sub-optimal, but I don't really know
144 # how to do more elegantly (this type of computation is
145 # not super well supported by PyTorch).
146 batch_size = torch.max(batch).item() + 1 # Typically, =32
147 points, batches = [], []
148 for b in range(batch_size):
149 p = subsample(x[batch == b], scale=scale)
150 points.append(p)
151 batches.append(b * torch.ones_like(batch[: len(p)]))
152
153 return torch.cat(points, dim=0), torch.cat(batches, dim=0)
154
155
156def soft_distances(x, y, batch_x, batch_y, smoothness=0.01, atomtypes=None):

Callers 1

atoms_to_points_normalsFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected