def setup_conformation_restraints(template, targets, windows, attach_fractions, structure, resname, fc=6.0): conformational_restraints = [] host_residues = len(structure[":{}".format(resname.upper())].residues) first_host_residue = structure[":{}".format( resname.upper())].residues[0].number + 1 for n in range(first_host_residue, host_residues + first_host_residue): if n + 1 < host_residues + first_host_residue: next_residue = n + 1 else: next_residue = first_host_residue for (index, atoms), target in zip(enumerate(template), targets): conformational_restraint_atoms = [] if index == 0: conformational_restraint_atoms.append(f":{n}@{atoms[0]}") conformational_restraint_atoms.append(f":{n}@{atoms[1]}") conformational_restraint_atoms.append(f":{n}@{atoms[2]}") conformational_restraint_atoms.append( f":{next_residue}@{atoms[3]}") else: conformational_restraint_atoms.append(f":{n}@{atoms[0]}") conformational_restraint_atoms.append(f":{n}@{atoms[1]}") conformational_restraint_atoms.append( f":{next_residue}@{atoms[2]}") conformational_restraint_atoms.append( f":{next_residue}@{atoms[3]}") this = DAT_restraint() this.auto_apr = True this.amber_index = True this.topology = structure this.mask1 = conformational_restraint_atoms[0] this.mask2 = conformational_restraint_atoms[1] this.mask3 = conformational_restraint_atoms[2] this.mask4 = conformational_restraint_atoms[3] this.attach["fraction_list"] = attach_fractions this.attach["target"] = target this.attach["fc_final"] = fc this.pull["target_final"] = target this.pull["num_windows"] = windows[1] this.release["fraction_list"] = attach_fractions[::-1] this.release["target"] = target this.release["fc_final"] = fc this.initialize() conformational_restraints.append(this) return conformational_restraints
def build_guest_restraints( cls, coordinate_path: str, attach_lambdas: List[float], n_pull_windows: Optional[int], restraint_schemas: List[Dict[str, Any]], use_amber_indices: bool = False, ) -> List[DAT_restraint]: """A method to convert a set of guest 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 and additionally a nested ``attach`` and ``pull`` dictionary with * a ``force_constant`` entry which specifies the force constant of the restraint. * a ``target`` entry which specifies the target value of the restraint. These 'schemas` map directly to the 'restraints -> guest -> restraint' dictionaries specified in the `taproom` guest 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. attach_lambdas The values 'lambda' being used during the attach phase of the APR calculation. n_pull_windows The total number of pull windows being used in the APR calculation. restraint_schemas The list of dictionaries which provide the settings to use for each wall 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 wall restraint objects. """ restraints = [] for restraint_schema in restraint_schemas: mask = restraint_schema["atoms"].split() guest_restraint = DAT_restraint() guest_restraint.auto_apr = True guest_restraint.continuous_apr = False guest_restraint.amber_index = use_amber_indices guest_restraint.topology = coordinate_path 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_schema["attach"]["target"] guest_restraint.attach["fc_final"] = restraint_schema["attach"][ "force_constant" ] guest_restraint.attach["fraction_list"] = attach_lambdas if n_pull_windows: guest_restraint.pull["target_final"] = restraint_schema["pull"][ "target" ] guest_restraint.pull["num_windows"] = n_pull_windows guest_restraint.initialize() restraints.append(guest_restraint) return restraints
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, )