Source code for schrodinger.application.desmond.automatic_analysis_generator

import schrodinger.structutils.analyze as analyze
import schrodinger.structutils.build as build
import schrodinger.structutils.smiles as smiles
import schrodinger.utils.sea as sea
from schrodinger.application.bioluminate import protein
from schrodinger.application.desmond import constants
from schrodinger.application.desmond.struc import get_reference_ct

PROTEIN_ASL = "(protein)"
MAX_RING_SIZE = 8


[docs]def removeAminoAcids(ligand_list): """ This function iterates over ligand structures in the given list and removes those that have amino acid names in their pdb residue name. :param ligand_list: list of ligand structures :type ligand_list: list :return: a list of `Ligand` instances :rtype: list """ AMINO_ACID_NAMES = (protein.Mutator.SUPPORTED_BUILD_RESIDUES + ["HID", "ARN", "ASH", "GLH", "LYN"]) new_list = [] for ligand in ligand_list: if not ligand.st.atom[1].pdbres.strip() in AMINO_ACID_NAMES: new_list.append(ligand) return new_list
[docs]def getLigand(cms_st): """ This parses a CMS for the ligand to use. :param cms_st: A CMS to find a ligand within :type cms_st: cms.Cms object :return: (ligand structure, ligand asl) :rtype: (Structure, str) """ ligand_list = analyze.find_ligands(cms_st) # only filter ligand list when it has more than 1 ligand if len(ligand_list) > 1: ligand_list = removeAminoAcids(ligand_list) if len(ligand_list) == 0: return None, None ligand_st = ligand_list[0].st ligand_asl = str(ligand_list[0].ligand_asl) return ligand_st, ligand_asl
[docs]def getASLExcludingLigand(asl_type, protein_asl=PROTEIN_ASL, ligand_asl=''): """ This gives an ASL for a subsection of the protein without the ligand. :param asl_type: Type of protein wanted, Heavy, Backbone, etc :type asl_type: str :param protein_asl: The ASL to describe the entire protein :type protein_asl: str :param ligand_asl: The ASL to describe the ligand :type ligand_asl: str :return: ASL for the protein component minus the ligand :rtype: str """ if ligand_asl: exclude_ligand = 'and not (%s)' % ligand_asl else: exclude_ligand = '' types = { 'Heavy': "(%s and not (atom.ele H) %s)", 'Backbone': "((%s and backbone) and not (atom.ele H) %s)", 'C-Alpha': "((%s and backbone ) and ( atom.ptype ' CA ') %s)", 'All residues': "(%s %s)", 'Side chains': "(%s and sidechain %s)" } return types[asl_type] % (protein_asl, exclude_ligand)
[docs]def getRMSDKeywords(protein_asl, ligand_asl, ref_struct_fname=None, frame=0): """ Returns keywords for RMSD analysis of protein components. :param protein_asl: The ASL to describe the entire protein :type protein_asl: str :param ligand_asl: The ASL to describe the ligand :type ligand_asl: str or None :param ref_struct_fname: Path to the structure to do the RMSD against :type ref_struct_fname: None or `str` :param frame: The frame to take the RMSD against, ignored if ref_struct_fname!=None :type frame: int :return: Keyword(s) for calculation :rtype: sea.Map """ types = ["Backbone", "Side chains", "C-Alpha", "Heavy"] for rmsd_type in types: asl = getASLExcludingLigand(rmsd_type, protein_asl, ligand_asl) ark_kw = sea.Map() ark_kw["RMSD"] = sea.Map() ark_kw["RMSD"]["Unit"] = "Angstrom" #Either use a reference frame, or a reference structure if ref_struct_fname: ark_kw["RMSD"]["Reference_Struct"] = ref_struct_fname else: ark_kw["RMSD"]["Frame"] = frame ark_kw["RMSD"]["Type"] = "ASL" ark_kw["RMSD"]["SelectionType"] = rmsd_type ark_kw["RMSD"]["ASL"] = asl ark_kw["RMSD"]["Panel"] = 'pl_interact_survey' ark_kw["RMSD"]["Tab"] = 'pl_rmsd_tab' if asl: ark_kw["RMSD"]["ASL"] = asl yield ark_kw
[docs]def getRMSDLigandKW(ligand_asl, fitby, ref_struct_fname=None, frame=0): """ Returns keywords for RMSD analysis of the ligand. :param ligand_asl: The ASL to describe the ligand :type ligand_asl: str :param fitby: None or an ASL to describe what portion of the CMS to fit :type fitby: None or str :param ref_struct_fname: Path to the structure to do the RMSD against :type ref_struct_fname: None or `str` :param frame: The frame to take the RMSD against, ignored if ref_struct_fname!=None :type frame: int """ ark_kw = sea.Map() ark_kw["RMSD"] = sea.Map() ark_kw["RMSD"]["Unit"] = "Angstrom" #Either use a reference frame, or a reference structure if ref_struct_fname: ark_kw["RMSD"]["Reference_Struct"] = ref_struct_fname else: ark_kw["RMSD"]["Frame"] = frame ark_kw["RMSD"]["Type"] = "Ligand" ark_kw["RMSD"]["SelectionType"] = "Ligand" ark_kw["RMSD"]["Panel"] = 'pl_interact_survey' ark_kw["RMSD"]["Tab"] = 'pl_rmsd_tab' ark_kw["RMSD"]["UseSymmetry"] = 'yes' ark_kw["RMSD"]["ASL"] = ligand_asl if fitby: ark_kw["RMSD"]["FitBy"] = fitby return ark_kw
[docs]def getRMSFProtKeywords(protein_asl, ligand_asl, ref_struct_fname=None, frame=0): """ Returns keywords for RMSF analysis of protein components. :param protein_asl: The ASL to describe the entire protein :type protein_asl: str :param ligand_asl: The ASL to describe the ligand :type ligand_asl: str :param ref_struct_fname: A structure to do the RMSF against :type ref_struct_fname: None or schrodinger.structure.Structure :param frame: The frame to take the RMSF against, ignored if ref_struct_fname!=None :type frame: int :return: Keyword(s) for calculation :rtype: sea.Map """ types = ["Backbone", "Side chains", "C-Alpha", "Heavy"] for rmsf_type in types: asl = getASLExcludingLigand(rmsf_type, protein_asl, ligand_asl) ark_kw = sea.Map() ark_kw["RMSF"] = sea.Map() ark_kw["RMSF"]["Unit"] = "Angstrom" #Either use a reference frame, or a reference structure if ref_struct_fname: ark_kw["RMSF"]["Reference_Struct"] = ref_struct_fname else: ark_kw["RMSF"]["Frame"] = frame #ark_kw["RMSF"]["FitBy"] = "backbone" ark_kw["RMSF"]["FitBy"] = getASLExcludingLigand("Backbone", protein_asl, ligand_asl) ark_kw["RMSF"]["Type"] = "ASL" ark_kw["RMSF"]["SelectionType"] = rmsf_type ark_kw["RMSF"]["ASL"] = asl ark_kw["RMSF"]["Panel"] = 'pl_interact_survey' ark_kw["RMSF"]["Tab"] = 'p_rmsf_tab' yield ark_kw
[docs]def getSSEProtKeywords(protein_asl, ligand_asl): """ Returns keywords for SSE analysis :param protein_asl: The ASL to describe the entire protein :type protein_asl: str :param ligand_asl: The ASL to describe the ligand :type ligand_asl: str :return: Keyword(s) for calculation :rtype: sea.Map """ # add secondary structure analysis for protein ark_kw = sea.Map() ark_kw["SecondaryStructure"] = sea.Map() asl = getASLExcludingLigand("All residues", protein_asl, ligand_asl) ark_kw["SecondaryStructure"]["Type"] = "ASL" ark_kw["SecondaryStructure"]["SelectionType"] = asl ark_kw["SecondaryStructure"]["ASL"] = asl ark_kw["SecondaryStructure"]["Panel"] = "pl_interact_survey" ark_kw["SecondaryStructure"]["Tab"] = "p_sse_tab" ark_kw["SecondaryStructure"][ "Legend"] = "-1: NONE; 0: LOOP; 1: HELIX; 2: STRAND; 3:TURN" yield ark_kw
[docs]def getRMSFLigandKW(fitby_asl, ligand_asl, ref_struct_fname=None, frame=0): """ Returns keywords for RMSF analysis of the ligand. :param ligand_asl: The ASL to describe the ligand :type ligand_asl: str :param fitby: None or an ASL to describe what portion of the CMS to fit :type fitby: None or str :param ref_struct_fname: A structure to do the RMSF against :type ref_struct_fname: None or schrodinger.structure.Structure :param frame: The frame to take the RMSF against, ignored if ref_struct_fname!=None :type frame: int """ ark_kw = sea.Map() ark_kw["RMSF"] = sea.Map() ark_kw["RMSF"]["Unit"] = "Angstrom" #Either use a reference frame, or a reference structure if ref_struct_fname: ark_kw["RMSF"]["Reference_Struct"] = ref_struct_fname else: ark_kw["RMSF"]["Frame"] = frame ark_kw["RMSF"]["FitBy"] = fitby_asl ark_kw["RMSF"]["ASL"] = ligand_asl ark_kw["RMSF"]["Type"] = "ASL" ark_kw["RMSF"]["Panel"] = 'pl_interact_survey' ark_kw["RMSF"]["Tab"] = 'l_rmsf_tab' return ark_kw
[docs]def getProtLigInterKW(protein_asl, ligand_asl, metal_asl=None): """ Returns keywords for PLI analysis :param protein_asl: The ASL to describe the entire protein :type protein_asl: str :param ligand_asl: The ASL to describe the ligand :type ligand_asl: str :param metal_asl: The ASL to describe metals or ions. If None, use all metals and ions in the input structure. :type metal_asl: str or None """ ark_kw = sea.Map() ark_kw["ProtLigInter"] = sea.Map() ark_kw["ProtLigInter"]["ASL"] = protein_asl ark_kw["ProtLigInter"]["LigandASL"] = ligand_asl if metal_asl is not None: ark_kw["ProtLigInter"]["MetalASL"] = metal_asl ark_kw["ProtLigInter"]["Panel"] = 'pl_interact_survey' ark_kw["ProtLigInter"]["Tab"] = 'pl_inter_tab' return ark_kw
[docs]def getSolubilityKeywords(molecule_asl): """ Returns keywords for analyzing solubility's sublimation leg. Here we look at the environment of the molecule and its interactions with it. """ ark_kw = sea.Map() ark_kw['AmorphousCrystalInter'] = sea.Map() ark_kw['AmorphousCrystalInter']['ASL'] = molecule_asl return ark_kw
[docs]def get_idx(ligand_st, lig_idx): """ This will get the atoms index associated with an asl index :param ligand_st : ligand structure :type ligand_st : structure :param lig_idx : ligand atom index :type lig_idx : int :return : atom_index of the asl selection for that atom :rtype : atom_index """ if constants.ORIGINAL_INDEX in list(ligand_st.atom[lig_idx].property): atom_index = ligand_st.atom[lig_idx].property[constants.ORIGINAL_INDEX] elif 'i_i_internal_atom_index' in list(ligand_st.atom[lig_idx].property): atom_index = ligand_st.atom[lig_idx].property['i_i_internal_atom_index'] #FIXME: what if both condition is False? return atom_index
[docs]def sort_atoms(st, a_id, exclude_atom_id=None, for_fep=False): """ Extract atoms that are bonded to a_id atom (excluding the exclude_atom_id atom) and returns a list of atoms in the order such that hydrogens are last :param st: small molecule structure :type st: structure :param a_id: index of the atom whose bonded atoms you want to return :type a_id: int :param exclude_atom_id: remove that atom from the list :type exclude_atom_id: int :param for_fep: if this options is ture, then return only atoms that is mapped to another atoms (contains i_fep_mapping prop) :type for_fep: bool :rtype: int :return: The index of the first heavy atom a_id, that is bounded, and that doesn't exclude_atom_id """ bonded_atoms = [] # sort atoms such that hydrogen and/or linear atoms appear last for atom in st.atom[a_id].bonded_atoms: if atom.index == exclude_atom_id: continue a_type = 1 if atom.atomic_number == 1 else 0 bond_order = st.getBond(st.atom[a_id], atom).order if bond_order == 0: continue cm = sum([a.atomic_weight for a in atom.bonded_atoms]) angle = st.measure(exclude_atom_id, a_id, atom.index) if exclude_atom_id else 0.0 # this is to make the algorithm to be less conformation dependant but # we want to bias the selection away from linear atoms. angle = angle if angle > 170. else 0. bonded_atoms.append((a_type, bond_order, cm, angle, atom.index)) bonded_atoms = [atom_props[-1] for atom_props in sorted(bonded_atoms)] if not for_fep: return bonded_atoms[0] # if for_fep, make sure to return the mapped atom for ba in bonded_atoms: if st.atom[ba].property.get(constants.FEP_MAPPING, 0): return ba return None
[docs]def get_rotatable_bonds(st): """ returns all rotatable bonds, defined as torsions. returns original atoms indeces. :param st: structure of a ligand :type st: structure :rtype: list :return: a list of four atoms that define a rotatable bond """ rb_atoms = [] for rb in analyze.rotatable_bonds_iterator(st, max_size=MAX_RING_SIZE): a2, a3 = rb a1 = sort_atoms(st, a2, a3) a4 = sort_atoms(st, a3, a2) b1 = st.atom[a1].property[constants.ORIGINAL_INDEX] b2 = st.atom[a2].property[constants.ORIGINAL_INDEX] b3 = st.atom[a3].property[constants.ORIGINAL_INDEX] b4 = st.atom[a4].property[constants.ORIGINAL_INDEX] rb_atoms.append([b1, b2, b3, b4]) return rb_atoms
[docs]def canonicalize_ligand(st): """ Use uSMILES to canonicalize the ligand structure, this is so we get the order of the rotatable bonds(torsions) in the same order, regardless of the atom order :param st: structure of a ligand :type st: structure :rtype: structure :return: a structure file with reordered atoms according to unique SMILES """ smiles_generator = smiles.SmilesGenerator( smiles.STEREO_FROM_ANNOTATION_AND_GEOM, unique=True) # get all heavy atoms and polar hydrogens asl = '(not a.e H) or ( atom.ele H and not /C0-H0/ )' heavy_polarH_list = analyze.evaluate_asl(st, asl) new_st = st.extract(heavy_polarH_list) # get a list of left over hydrogens pol_h = [atom.index for atom in new_st.atom if atom.element == 'H'] smi, atom_list = smiles_generator.getSmilesAndMap(new_st) # add the polar hydrogens to the end of the list for h in pol_h: if h not in atom_list: atom_list.append(h) return build.reorder_atoms(new_st, atom_list)
[docs]def getLigandPropsKeywords(ligand_asl, calcRMSD, ref_struct_fname=None, frame=None): """ Returns keywords for ligand-specific analysis * Intramolecular Hbonds * Molecular Surface Area (Cannolly surface) * Solvent Accessible Surface Area * Polar Surface area * Radius of Gyration :param ligand_asl: The ASL to describe the ligand :type ligand_asl: str :param calcRMSD: Bool to also set up RMSD jobs :type calcRMSD: bool :param ref_struct_fname: path to the reference structure :param frame: frame index :type frame: `int` :return: Keyword(s) for calculation :rtype: sea.Map """ ark_kw = sea.Map() ark_kw["LigandHBonds"] = sea.Map() ark_kw["LigandHBonds"]["ASL1"] = ligand_asl ark_kw["LigandHBonds"]["Name"] = 'Intramolecular Hydrogen Bonds' ark_kw["LigandHBonds"]["Type"] = 'ASL' ark_kw["LigandHBonds"]["Unit"] = 'Numb. of HBonds' ark_kw["LigandHBonds"]["Panel"] = 'pl_interact_survey' ark_kw["LigandHBonds"]["ReturnHBonds"] = 'True' ark_kw["LigandHBonds"]["Tab"] = 'l_properties_tab' yield ark_kw ark_kw = sea.Map() ark_kw["Molecular_Surface_Area"] = sea.Map() ark_kw["Molecular_Surface_Area"]['ASL'] = ligand_asl ark_kw["Molecular_Surface_Area"]['Grid_Spacing'] = 0.5 ark_kw["Molecular_Surface_Area"]["Unit"] = 'Angstrom^2' ark_kw["Molecular_Surface_Area"]['Panel'] = 'pl_interact_survey' ark_kw["Molecular_Surface_Area"]['Tab'] = 'l_properties_tab' yield ark_kw ark_kw = sea.Map() ark_kw["SA_Surface_Area"] = sea.Map() ark_kw["SA_Surface_Area"]['ASL'] = ligand_asl # TODO: need a better definition to exclude FEP image ions_asl = '(metals) or (metalloids)' if 'protein' in ligand_asl: exclude_asl = 'not ((%s) or (ions) or (water) or %s)' % (ligand_asl, ions_asl) else: exclude_asl = 'not ((protein) or (%s) or (ions) or (water) or %s)' % \ (ligand_asl, ions_asl) ark_kw["SA_Surface_Area"]['Exclude_ASL'] = exclude_asl ark_kw["SA_Surface_Area"]['Resolution'] = 0.3 ark_kw["SA_Surface_Area"]["Unit"] = 'Angstrom^2' ark_kw["SA_Surface_Area"]['Panel'] = 'pl_interact_survey' ark_kw["SA_Surface_Area"]['Tab'] = 'l_properties_tab' yield ark_kw ark_kw = sea.Map() ark_kw["Polar_Surface_Area"] = sea.Map() ark_kw["Polar_Surface_Area"]['ASL'] = ligand_asl ark_kw["Polar_Surface_Area"]['Resolution'] = 0.3 ark_kw["Polar_Surface_Area"]["Unit"] = 'Angstrom^2' ark_kw["Polar_Surface_Area"]['Panel'] = 'pl_interact_survey' ark_kw["Polar_Surface_Area"]['Tab'] = 'l_properties_tab' yield ark_kw ark_kw = sea.Map() ark_kw["Rad_Gyration"] = sea.Map() ark_kw["Rad_Gyration"]['ASL'] = ligand_asl ark_kw["Rad_Gyration"]["Unit"] = 'Angstrom' ark_kw["Rad_Gyration"]['Panel'] = 'pl_interact_survey' ark_kw["Rad_Gyration"]['Tab'] = 'l_properties_tab' yield ark_kw if calcRMSD: ark_kw = sea.Map() ark_kw["RMSD"] = sea.Map() ark_kw["RMSD"]["Unit"] = "Angstrom" if ref_struct_fname: ark_kw["RMSD"]["Reference_Struct"] = ref_struct_fname else: ark_kw["RMSD"]["Frame"] = frame ark_kw["RMSD"]["Type"] = "Ligand" ark_kw["RMSD"]["SelectionType"] = "Ligand" ark_kw["RMSD"]["Panel"] = 'pl_interact_survey' ark_kw["RMSD"]["Tab"] = 'l_properties_tab' ark_kw["RMSD"]["UseSymmetry"] = 'yes' ark_kw["RMSD"]["ASL"] = ligand_asl yield ark_kw
def _getLoneTorsionFEP(lig_st, core_rb): """ This method returns Torsions/RB that are not in the core_rb. """ ret_torsions = [] for rb in analyze.rotatable_bonds_iterator(lig_st, max_size=MAX_RING_SIZE): a2, a3 = rb if (a2, a3) in core_rb or (a3, a2) in core_rb: continue a1 = sort_atoms(lig_st, a2, a3) a4 = sort_atoms(lig_st, a3, a2) ret_torsions.append((a1, a2, a3, a4)) return ret_torsions
[docs]def getFEPTorsionKeywords(lig1_st, lig2_st, lig1_asl, lig2_asl, fep_lambda=0, is_covalent=False): """ For a pair for ligands/fragments that, whose atoms are mapped, return sea object of torsions for each rotatable bond. """ def get_ark_tor(lig_st, rb, asl, fep_pair=None): fsys_ct_rb = lig_to_fullsys_aid(rb, lig_st) # Use the analysis reference coords if present ref_lig_st = get_reference_ct(lig_st) ref_lig_st = get_reference_ct( ref_lig_st, prop_names=constants.ANALYSIS_REFERENCE_COORD_PROPERTIES) ark_kw = sea.Map() ark_kw["Torsion"] = sea.Map() ark_kw["Torsion"]["a1"] = fsys_ct_rb[0] ark_kw["Torsion"]["a2"] = fsys_ct_rb[1] ark_kw["Torsion"]["a3"] = fsys_ct_rb[2] ark_kw["Torsion"]["a4"] = fsys_ct_rb[3] ark_kw["Torsion"]["Unit"] = "Degrees" ark_kw["Torsion"]["Panel"] = 'pl_interact_survey' ark_kw["Torsion"]["Tab"] = 'l_torsions_tab' ark_kw["Torsion"]["LigandASL"] = asl ark_kw["Torsion"]["StartingConformation"] = ref_lig_st.measure(*rb) if fep_pair is not None: ark_kw["Torsion"]["FEP_pair"] = fep_pair return ark_kw core1, core2, lone1, lone2 = _getFEPTorsion(lig1_st, lig2_st, is_covalent) ret_list = sea.List() if fep_lambda == 0: for irb, rb in enumerate(core1, start=1): ret_list.append(get_ark_tor(lig1_st, rb, lig1_asl, irb)) for rb in lone1: ret_list.append(get_ark_tor(lig1_st, rb, lig1_asl)) else: for irb, rb in enumerate(core2, start=1): ret_list.append(get_ark_tor(lig2_st, rb, lig2_asl, irb)) for rb in lone2: ret_list.append(get_ark_tor(lig2_st, rb, lig2_asl)) return ret_list
def _valid_mapped_fep_atom(atom): """ Check if atom is alchemically mapped """ return atom.property.get(constants.FEP_MAPPING, 0) != 0 def _getFEPTorsion(lig1_st, lig2_st, is_covalent): """ This method generates torsions that represent rotatable bonds by taking two ligands, that are alchemically-mapped. The torsions generated are mapped between the two ligands. CoreRBs are the ones where the dihedrals are mapped, loneRBs are those that are not mapped. :param is_covalent: if the covalent ligand is used, the provided structures will be a subset -- sidechain residue + ligand :type is_covalent: bool """ core1_rb = [] core2_rb = [] cpx1_frag1_map = None if is_covalent: cpx1_frag1_map = { atom.property[constants.ORIGINAL_INDEX]: atom.index for atom in lig1_st.atom } # Add mapping information to lig1_st for atom in lig2_st.atom: m_idx = atom.property.get(constants.FEP_MAPPING, 0) if m_idx: m_idx = m_idx if not cpx1_frag1_map else cpx1_frag1_map[m_idx] lig1_st.atom[m_idx].property[constants.FEP_MAPPING] = atom.index # get RBs that are common to lig1 and lig2 for rb in analyze.rotatable_bonds_iterator(lig1_st, max_size=MAX_RING_SIZE): a2, a3 = rb if not (_valid_mapped_fep_atom(lig1_st.atom[a2]) and _valid_mapped_fep_atom(lig1_st.atom[a3])): continue a2_2 = lig1_st.atom[a2].property[constants.FEP_MAPPING] a3_2 = lig1_st.atom[a3].property[constants.FEP_MAPPING] bond_2 = lig2_st.getBond(lig2_st.atom[a2_2], lig2_st.atom[a3_2]) # Check that the rotatable bond is also in lig2_st (DESMOND-10109) if bond_2 and analyze.is_bond_rotatable(bond_2): core1_rb.append((a2, a3)) core2_rb.append((a2_2, a3_2)) # get torsions in core for both ligands core_tors1 = [] core_tors2 = [] for rb1, rb2 in zip(core1_rb[:], core2_rb[:]): a2_rb1, a3_rb1 = rb1 a1_rb1 = sort_atoms(lig1_st, a2_rb1, a3_rb1, True) a4_rb1 = sort_atoms(lig1_st, a3_rb1, a2_rb1, True) if not (a1_rb1 and a4_rb1): core1_rb.remove(rb1) core2_rb.remove(rb2) continue a2_rb2, a3_rb2 = rb2 a1_rb2 = lig1_st.atom[a1_rb1].property[constants.FEP_MAPPING] a4_rb2 = lig1_st.atom[a4_rb1].property[constants.FEP_MAPPING] if not (a1_rb2 and a4_rb2): core1_rb.remove(rb1) core2_rb.remove(rb2) continue core_tors1.append((a1_rb1, a2_rb1, a3_rb1, a4_rb1)) core_tors2.append((a1_rb2, a2_rb2, a3_rb2, a4_rb2)) lone_tors1 = _getLoneTorsionFEP(lig1_st, core1_rb) lone_tors2 = _getLoneTorsionFEP(lig2_st, core2_rb) return core_tors1, core_tors2, lone_tors1, lone_tors2
[docs]def lig_to_fullsys_aid(torsion_list, st): """ Convert ligand atom IDs to full-system atom IDs """ a, b, c, d = torsion_list return [ st.atom[a].property[constants.ORIGINAL_INDEX], st.atom[b].property[constants.ORIGINAL_INDEX], st.atom[c].property[constants.ORIGINAL_INDEX], st.atom[d].property[constants.ORIGINAL_INDEX] ]
[docs]def getTorsionKeywords(ligand_st, ligand_asl): """ Returns keywords for ligand torsion analysis :param ligand_st: Structure of the ligand :type ligand_st: schrodinger.structure.Structure :param ligand_asl: The ASL to describe the ligand :type ligand_asl: str :return: Keyword(s) for calculation :rtype: sea.Map """ new_ligand_st = canonicalize_ligand(ligand_st) rb_list = get_rotatable_bonds(new_ligand_st) for rb in rb_list: ark_kw = sea.Map() ark_kw["Torsion"] = sea.Map() ark_kw["Torsion"]["a1"] = rb[0] ark_kw["Torsion"]["a2"] = rb[1] ark_kw["Torsion"]["a3"] = rb[2] ark_kw["Torsion"]["a4"] = rb[3] ark_kw["Torsion"]["Unit"] = "Degrees" ark_kw["Torsion"]["Panel"] = 'pl_interact_survey' ark_kw["Torsion"]["Tab"] = 'l_torsions_tab' ark_kw["Torsion"]["LigandASL"] = ligand_asl yield ark_kw
[docs]def getPPIKeywords(protein_asl): """ Returns keywords for PLI analysis :param protein_asl: The ASL to describe the entire protein :type protein_asl: str """ ark_kw = sea.Map() ark_kw["ProtProtInter"] = sea.Map() ark_kw["ProtProtInter"]["ASL"] = protein_asl return ark_kw
[docs]def getPLISKWList(cms_st, ligand_st, ligand_asl, ref_struct_fname, frame=0, protein_asl=PROTEIN_ASL, want_rmsd=True, want_prmsf=True, want_lrmsf=True, want_pli=True, want_ltorsion=True, want_lprops=True, want_ppi=True, protein_fep=False, metal_asl=None): """ Generate the entire keyword list for all PLI calculations. Also returns the ligand_asl used in those keywords. :param ligand_st: Structure of the ligand :type ligand_st: schrodinger.structure.Structure :param ligand_asl: The ASL to describe the ligand :type ligand_asl: str :param ref_struct_fname: Path to the structure to do the RMSD against :type ref_struct_fname: None or `str` :param frame: The frame to take the RMSF/RMSD against, ignored if ref_struct_fname!=None :type frame: int :param protein_asl: The ASL to describe the entire protein :type protein_asl: str :param want_rmsd: Whether to add RMSD keywords :type want_rmsd: bool :param want_prmsf: Whether to add RMSF keywords for protein :type want_prmsf: bool :param want_lrmsf: Whether to add an RMSF ligand keyword :type want_lrmsf: bool :param want_pli: Whether to add a PLI keyword :type want_pli: bool :param want_ppi: Whether to add a PPI keyword :type want_ppi: bool :param want_ltorsion: Whether to add a ligand torsions keyword :type want_ltorsion: bool :param want_lprops: Whether to add ligand properties keyword :type want_lprops: bool :param protein_fep: Whether the input system is a protein_fep job :type protein_fep: bool :param metal_asl: The ASL to describe metals or ions. If None, use '(ions) or (metals) or (metalloids)'. :type metal_asl: str or None :return: Keyword(s) for calculation :rtype: sea.List """ lst = sea.List() lig_asl = '' if protein_fep else ligand_asl if want_rmsd: for ark_kw in getRMSDKeywords(protein_asl, lig_asl, ref_struct_fname, frame=frame): lst.append(ark_kw) if ligand_asl: for fitby in [None, protein_asl]: ark_kw = getRMSDLigandKW(ligand_asl, fitby, ref_struct_fname, frame=frame) lst.append(ark_kw) if want_prmsf: for ark_kw in getSSEProtKeywords(protein_asl, lig_asl): lst.append(ark_kw) for ark_kw in getRMSFProtKeywords(protein_asl, lig_asl, ref_struct_fname, frame=frame): lst.append(ark_kw) if want_lrmsf: ark_kw = getRMSFLigandKW(ligand_asl + " and not atom.e H", ligand_asl + " and not atom.e H", ref_struct_fname) lst.append(ark_kw) if protein_asl: ark_kw = getRMSFLigandKW(protein_asl, ligand_asl + " and not atom.e H", ref_struct_fname) lst.append(ark_kw) if want_pli: lst.append( getProtLigInterKW(protein_asl, ligand_asl, metal_asl=metal_asl)) if want_ppi: lst.append(getPPIKeywords(protein_asl)) if want_ltorsion: for ark_kw in getTorsionKeywords(ligand_st, ligand_asl): lst.append(ark_kw) if want_lprops: # if want_rmsd is not selected, then ligand RMSD will not be # calculated. So bool 'calcRMSD' is passed for RMSD calculation. calcRMSD = not want_rmsd for ark_kw in getLigandPropsKeywords(ligand_asl, calcRMSD, ref_struct_fname, frame): lst.append(ark_kw) return lst