def setup_static_restraints(anchor_atoms, windows, structure, distance_fc=5.0, angle_fc=100.0): static_restraints = [] static_restraint_atoms = [ [anchor_atoms["D1"], anchor_atoms["H1"]], [anchor_atoms["D2"], anchor_atoms["D1"], anchor_atoms["H1"]], [anchor_atoms["D1"], anchor_atoms["H1"], anchor_atoms["H2"]], [ anchor_atoms["D3"], anchor_atoms["D2"], anchor_atoms["D1"], anchor_atoms["H1"], ], [ anchor_atoms["D2"], anchor_atoms["D1"], anchor_atoms["H1"], anchor_atoms["H2"], ], [ anchor_atoms["D1"], anchor_atoms["H1"], anchor_atoms["H2"], anchor_atoms["H3"], ], ] for _, atoms in enumerate(static_restraint_atoms): this = static_DAT_restraint( restraint_mask_list=atoms, num_window_list=windows, ref_structure=structure, force_constant=angle_fc if len(atoms) > 2 else distance_fc, amber_index=True, ) static_restraints.append(this) print(f"There are {len(static_restraints)} static restraints") return static_restraints
def build_static_restraints( cls, coordinate_path: str, n_attach_windows: Optional[int], n_pull_windows: Optional[int], n_release_windows: Optional[int], restraint_schemas: List[Dict[str, Any]], use_amber_indices: bool = False, ) -> List[DAT_restraint]: """A method to convert a set of static restraints defined by their 'schemas' into corresponding ``DAT_restraint``objects. Each 'schema' should be a dictionary with: * an ``atoms`` entry with a value of the atom selection make which specifies which atoms the restraint will apply to * a ``force_constant`` entry which specifies the force constant of the restraint. These 'schemas` map directly to the 'restraints -> static -> restraint' dictionaries specified in the `taproom` host YAML files. Parameters ---------- coordinate_path The path to the coordinate file which the restraints will be applied to. This should contain either the host or the complex, the dummy atoms and and solvent. n_attach_windows The total number of attach windows being used in the APR calculation. n_pull_windows The total number of pull windows being used in the APR calculation. n_release_windows The total number of release windows being used in the APR calculation. restraint_schemas The list of dictionaries which provide the settings to use for each static restraint to add. use_amber_indices Whether to use amber based (i.e. starting from 1) restraint indices or OpenMM based (i.e. starting from 0) indices. Returns ------- The constructed static restraint objects. """ if n_pull_windows is not None: assert n_attach_windows is not None static_restraints: List[DAT_restraint] = [] n_windows = [n_attach_windows, n_pull_windows, n_release_windows] for restraint_schema in restraint_schemas: static = static_DAT_restraint( restraint_mask_list=restraint_schema["atoms"].split(), num_window_list=n_windows, ref_structure=coordinate_path, force_constant=restraint_schema["force_constant"], amber_index=use_amber_indices, continuous_apr=False, ) static_restraints.append(static) return static_restraints
guest_angle_rest2 = [D[0], G[0], G[1]] guest_restraint_atoms = [ guest_distance_rest, guest_angle_rest1, guest_angle_rest2 ] guest_restraint_targets = [guest_init_dist, 180.0, 180.0] guest_restraint_target_final = [18.0 + guest_init_dist, 180.0, 180.0] guest_restraint_distance_fc = 5.0 guest_restraint_angle_fc = 100.0 # Create restraint objects static_restraints = [] for index, atoms in enumerate(static_restraint_atoms): this = static_DAT_restraint( restraint_mask_list=atoms, num_window_list=windows, ref_structure=structure, force_constant=static_restraint_angle_fc if len(atoms) > 2 else static_restraint_distance_fc, amber_index=True) static_restraints.append(this) guest_restraints = [] for index, atoms in enumerate(guest_restraint_atoms): if len(atoms) > 2: angle = True else: angle = False this = DAT_restraint() this.auto_apr = True this.amber_index = True this.topology = structure
def initialize_restraints(self, structure="output.pdb"): if self.guest != "release": windows = [ self.host_yaml["calculation"]["windows"]["attach"], self.host_yaml["calculation"]["windows"]["pull"], None, ] else: windows = [ None, None, self.host_yaml["calculation"]["windows"]["release"] ] static_restraints = [] for restraint in self.host_yaml["restraints"]["static"]: static = static_DAT_restraint( restraint_mask_list=restraint["restraint"]["atoms"].split(), num_window_list=windows, ref_structure=str(structure), force_constant=restraint["restraint"]["force_constant"], amber_index=False if self.backend == "openmm" else True, ) static_restraints.append(static) conformational_restraints = [] if self.host_yaml["restraints"]["conformational"]: for conformational in self.host_yaml["restraints"][ "conformational"]: mask = conformational["restraint"]["atoms"].split() conformational_restraint = DAT_restraint() conformational_restraint.auto_apr = True conformational_restraint.continuous_apr = True conformational_restraint.amber_index = False if self.backend == "openmm" else True conformational_restraint.topology = str(structure) conformational_restraint.mask1 = mask[0] conformational_restraint.mask2 = mask[1] conformational_restraint.mask3 = mask[2] if len( mask) > 2 else None conformational_restraint.mask4 = mask[3] if len( mask) > 3 else None if self.guest != "release": conformational_restraint.attach["target"] = conformational[ "restraint"]["target"] conformational_restraint.attach[ "fc_final"] = conformational["restraint"][ "force_constant"] conformational_restraint.attach[ "fraction_list"] = self.host_yaml["calculation"][ "lambda"]["attach"] conformational_restraint.pull[ "target_final"] = conformational["restraint"]["target"] conformational_restraint.pull["num_windows"] = windows[1] else: conformational_restraint.auto_apr = False conformational_restraint.continuous_apr = False conformational_restraint.release[ "target"] = conformational["restraint"]["target"] conformational_restraint.release[ "fc_final"] = conformational["restraint"][ "force_constant"] conformational_restraint.release[ "fraction_list"] = self.host_yaml["calculation"][ "lambda"]["release"] conformational_restraint.initialize() conformational_restraints.append(conformational_restraint) else: logger.debug("Skipping conformational restraints...") symmetry_restraints = [] if self.guest != "release" and "symmetry_correction" in self.guest_yaml: for symmetry in self.guest_yaml["symmetry_correction"][ "restraints"]: symmetry_restraint = DAT_restraint() symmetry_restraint.auto_apr = True symmetry_restraint.continuous_apr = True symmetry_restraint.amber_index = False if self.backend == "openmm" else True symmetry_restraint.topology = str(structure) symmetry_restraint.mask1 = symmetry["atoms"].split()[0] symmetry_restraint.mask2 = symmetry["atoms"].split()[1] symmetry_restraint.mask3 = symmetry["atoms"].split()[2] symmetry_restraint.attach["fc_final"] = symmetry[ "force_constant"] symmetry_restraint.attach["fraction_list"] = [1.0] * len( self.host_yaml["calculation"]["lambda"]["attach"]) # This target should be overridden by the custom values. symmetry_restraint.attach["target"] = 999.99 symmetry_restraint.custom_restraint_values["r2"] = 91 symmetry_restraint.custom_restraint_values["r3"] = 91 # 0 force constant between 91 degrees and 180 degrees. symmetry_restraint.custom_restraint_values["rk3"] = 0.0 symmetry_restraint.initialize() symmetry_restraints.append(symmetry_restraint) else: logger.debug("Skipping symmetry restraints...") wall_restraints = [] if self.guest != "release" and "wall_restraints" in self.guest_yaml[ 'restraints']: for wall in self.guest_yaml["restraints"]["wall_restraints"]: wall_restraint = DAT_restraint() wall_restraint.auto_apr = True wall_restraint.continuous_apr = True wall_restraint.amber_index = False if self.backend == "openmm" else True wall_restraint.topology = str(structure) wall_restraint.mask1 = wall["restraint"]["atoms"].split()[0] wall_restraint.mask2 = wall["restraint"]["atoms"].split()[1] wall_restraint.attach["fc_final"] = wall["restraint"][ "force_constant"] wall_restraint.attach["fraction_list"] = [1.0] * len( self.host_yaml["calculation"]["lambda"]["attach"]) wall_restraint.attach["target"] = wall["restraint"]["target"] # Minimum distance is 0 Angstrom wall_restraint.custom_restraint_values["r1"] = 0 wall_restraint.custom_restraint_values["r2"] = 0 # Harmonic force constant beyond target distance. wall_restraint.custom_restraint_values["rk2"] = wall[ "restraint"]["force_constant"] wall_restraint.custom_restraint_values["rk3"] = wall[ "restraint"]["force_constant"] wall_restraint.initialize() wall_restraints.append(wall_restraint) else: logger.debug("Skipping wall restraints...") guest_restraints = [] for restraint in [] if not hasattr( self, 'guest_yaml') else self.guest_yaml["restraints"]["guest"]: mask = restraint["restraint"]["atoms"].split() guest_restraint = DAT_restraint() guest_restraint.auto_apr = True guest_restraint.continuous_apr = True guest_restraint.amber_index = False if self.backend == "openmm" else True guest_restraint.topology = str(structure) guest_restraint.mask1 = mask[0] guest_restraint.mask2 = mask[1] guest_restraint.mask3 = mask[2] if len(mask) > 2 else None guest_restraint.mask4 = mask[3] if len(mask) > 3 else None guest_restraint.attach["target"] = restraint["restraint"][ "attach"]["target"] guest_restraint.attach["fc_final"] = restraint["restraint"][ "attach"]["force_constant"] guest_restraint.attach["fraction_list"] = self.host_yaml[ "calculation"]["lambda"]["attach"] guest_restraint.pull["target_final"] = restraint["restraint"][ "pull"]["target"] guest_restraint.pull["num_windows"] = windows[1] guest_restraint.initialize() guest_restraints.append(guest_restraint) return ( static_restraints, conformational_restraints, symmetry_restraints, wall_restraints, guest_restraints, )