| 153 | |
| 154 | @R.register('SO2VESchedule') |
| 155 | class SO2VESchedule(SO2Schedule, core.Configurable): |
| 156 | def __init__(self, pi_periodic=False, cache_folder=None, sigma_min=0.01 * np.pi, sigma_max=np.pi, annealed_temp=3, mode="sde"): |
| 157 | """ |
| 158 | Args: |
| 159 | sigma_min (float): minimum standard deviation |
| 160 | sigma_max (float): maximum standard deviation |
| 161 | """ |
| 162 | PI = 1/2 * np.pi if pi_periodic else np.pi # TODO: remove ambiguity |
| 163 | super().__init__(PI, cache_folder) |
| 164 | self.sigma_min = sigma_min |
| 165 | self.sigma_max = sigma_max |
| 166 | self.sigma_min_log = np.log(sigma_min) |
| 167 | self.sigma_max_log = np.log(sigma_max) |
| 168 | self.annealed_temp = annealed_temp |
| 169 | self.mode = mode |
| 170 | |
| 171 | def t_to_sigma(self, t): |
| 172 | """Transfer timesteps to standard deviation. |
| 173 | |
| 174 | Args: |
| 175 | t (Tensor): timesteps ranging from 0 to 1 |
| 176 | |
| 177 | Returns: |
| 178 | Tensor: standard deviation ranging from sigma_min to sigma_max |
| 179 | """ |
| 180 | return torch.exp(self.sigma_min_log + (self.sigma_max_log - self.sigma_min_log) * t) |
| 181 | |
| 182 | @torch.no_grad() |
| 183 | def add_noise(self, x, t, x_mask=None): |
| 184 | """Add noise to the input tensor (torsion angles). |
| 185 | |
| 186 | Args: |
| 187 | x (Tensor): Torsion angles of shape :math:`(num_res, 4)` |
| 188 | x_mask (Tensor): Mask of shape :math:`(num_res, 4)` |
| 189 | t (Tensor): Timesteps of shape :math:`(num_res)` |
| 190 | """ |
| 191 | sigmas = self.t_to_sigma(t) |
| 192 | noise = torch.randn_like(x) * sigmas.unsqueeze(-1) |
| 193 | score = torch.tensor( |
| 194 | self.score(noise.cpu().numpy(), sigmas.cpu().numpy()), device=x.device, dtype=x.dtype |
| 195 | ) |
| 196 | |
| 197 | if x_mask is not None: |
| 198 | noise *= x_mask |
| 199 | score *= x_mask |
| 200 | |
| 201 | x = x + noise |
| 202 | return x, score |
| 203 | |
| 204 | @torch.no_grad() |
| 205 | def step(self, x, x_score, t, dt, x_mask=None): |
| 206 | """Denoise step for the input tensor (torsion angles). |
| 207 | |
| 208 | Args: |
| 209 | x (Tensor): Torsion angles of shape :math:`(num_res, 4)` |
| 210 | x_score (Tensor): Score of shape :math:`(num_res, 4)` |
| 211 | t (Tensor): Timesteps of shape :math:`(num_res)` |
| 212 | dt (float): Step size of shape :math:`(num_res)` |
nothing calls this directly
no outgoing calls
no test coverage detected