Source code for schrodinger.application.phase.packages.hypo_refine.hypo_utils
"""
Module with phase_hypo_refine hypothesis-related functionality.
Copyright Schrodinger LLC, All Rights Reserved.
"""
import itertools
from schrodinger.infra import phase
[docs]def clean_hypo(hypo, to_static):
    """
    Prepares the hypothesis for refinement by removing attributes that are
    likely to be invalidated by the refinement process and/or would interfere
    with refinement. Also converts the reference ligand to static fragments if
    to_static is True. Returns a string that describes the changes made and
    a Boolean indicating whether the changes warrant a new active/decoy screen.
    :param hypo: Hypothesis to be cleaned
    :type hypo: phase.PhpHypoAdaptor
    :param to_static: Whether to convert reference ligand to static fragments
    :type to_static: bool
    :return: Description of changes and Boolean for rerunning screen
    :rtype: str, bool
    """
    attr_names = []
    rescreen = False
    if hypo.hasAddCts():
        attr_names.append(phase.HYPO_ATTR_ADD)
    if hypo.hasCnst():
        attr_names.append(phase.HYPO_ATTR_CNST)
        rescreen = True
    if hypo.hasIvol():
        attr_names.append(phase.HYPO_ATTR_IVOL)
        rescreen = True
    if hypo.hasMask():
        attr_names.append(phase.HYPO_ATTR_MASK)
        rescreen = True
    if hypo.hasQsar():
        attr_names.append(phase.HYPO_ATTR_QSAR)
    if hypo.hasXvol():
        attr_names.append(phase.HYPO_ATTR_XVOL)
        rescreen = True
    changes = ""
    for attr_name in attr_names:
        attr_descr = phase.HYPO_ATTR_DESCR[attr_name]
        changes += "\nDeleting attribute: %s" % attr_descr
        hypo.deleteAttr(attr_name)
    if to_static and not hypo.isStatic():
        changes += "\nCreating fragment-based reference ligand"
        hypo.convertToStatic(hypo.getFd())
        rescreen = True
    # Don't inadvertently run screens with partial matching.
    if hypo.hasProp(phase.PHASE_MIN_SITES):
        changes += "\nDeleting property %s" % phase.PHASE_MIN_SITES
        hypo.deleteProp(phase.PHASE_MIN_SITES)
        rescreen = True
    if changes:
        changes = "\nPreparing hypothesis for refinement" + changes
    return changes, rescreen 
[docs]def get_match_options(hypo_file, exhaustive):
    """
    Returns matching options that are appropriate for BEDROC screens against
    the supplied hypothesis.
    :param hypo_file: Hypothesis file
    :type hypo_file: str
    :param exhaustive: Whether to do exhaustive partial matching
    :type exhaustive: bool
    :return: Matching options
    :rtype: phase.PhpMatchOptions
    """
    match_options = phase.PhpMatchOptions()
    # Turn off volume scoring if the hypothesis consists of static features.
    # Turn off vector scoring if hypothesis has feature rules that contain
    # mixed permitted feature types.
    hypo = phase.PhpHypoAdaptor(hypo_file)
    if hypo.isStatic():
        match_options.setVolumeWeight(0.0)
    if hypo.hasRules() and hypo.getRules().hasMixedFeatures():
        match_options.setVectorWeight(0.0)
    # Set minimum number of sites to match, if applicable.
    if hypo.hasProp(phase.PHASE_MIN_SITES):
        min_sites = int(hypo.getProp(phase.PHASE_MIN_SITES))
        if min_sites < hypo.getSiteCount():
            match_options.setMinSites(min_sites)
            if exhaustive:
                match_options.setExhaustiveMatching(True)
    return match_options 
[docs]def get_site_mask_summary(hypo_file):
    """
    Returns a string that contains a summary of the site mask in the
    provided hypothesis file.
    :param hypo_file: Hypothesis file
    :type hypo_file: str
    :return: Site mask summary
    :rtype: str
    """
    hypo = phase.PhpHypoAdaptor(hypo_file)
    s = "Site    Mask"
    for site in phase.PhpHypoAdaptor(hypo_file).getHypoSites():
        site_name = site.getSiteName(0)
        s += " \n %s%d" % (site_name.ljust(8), site.getMaskValue())
    return s 
[docs]def get_site_masks(hypo, max_miss):
    """
    Returns all possible site masks for the provided hypothesis, where the
    number of sites that may be missed is 1,...,max_miss.
    :param hypo: Pharmacophore hypothesis
    :type hypo: phase.PhpHypoAdaptor
    :param max_miss: Maximum number of sites that need not be matched
    :type max_miss: int
    :return: All possible site masks
    :rtype: list(phase.PhpSiteMask)
    """
    num_sites = hypo.getSiteCount()
    sample_pool = range(num_sites)
    miss_limit = 1 + min(max_miss, num_sites)
    site_numbers = []
    site_types = []
    for site in hypo.getHypoSites():
        site_numbers.append(site.getSiteNumber())
        site_types.append(site.getSiteType())
    site_masks = []
    for n in range(1, miss_limit):
        for subset in itertools.combinations(sample_pool, n):
            mask_values = num_sites * [1]
            for i in subset:
                mask_values[i] = 0
            site_mask = phase.PhpSiteMask()
            for i in range(num_sites):
                site_mask.addSiteMaskData(site_numbers[i], site_types[i],
                                          mask_values[i])
            site_masks.append(site_mask)
    return site_masks 
[docs]def get_site_tol(hypo, step_size, direct):
    """
    Returns positional tolerances obtained by adding step_size * direct
    to the tolerances in the provided hypothesis.
    :param hypo: Pharmacophore hypothesis
    :type hypo: phase.PhpHypoAdaptor
    :param step_size: Scalar step size
    :type step_size: float
    :param direct: Direction of tolerance shift for each site in hypo
    :type direct: list(float)
    :return: Positional tolerances
    :rtype: phase.PhpDeltaHypo
    """
    hypo_sites = hypo.getHypoSites()
    if hypo.hasTol():
        t0 = [site.getTol() for site in hypo_sites]
    else:
        t0 = hypo.getSiteCount() * [phase.PHASE_DEFAULT_TOL]
    tstep = [t0[i] + step_size * direct[i] for i in range(len(direct))]
    site_tol = phase.PhpDeltaHypo()
    for tol, site in zip(tstep, hypo_sites):
        site_tol.addSiteData(site.getSiteNumber(), site.getSiteType(), tol)
    return site_tol 
[docs]def get_site_tol_probes(hypo, step_size):
    """
    Returns a list of hypothesis positional tolerance objects obtained by
    adding/subtracting step_size to/from each positional tolerance in the
    provided hypothesis.
    :param hypo: Pharmacophore hypothesis
    :type hypo: phase.PhpHypoAdaptor
    :param step_size: Scalar step size
    :type step_size: float
    :return: List of hypothesis positional tolerances
    :rtype: list(phase.PhpDeltaHypo)
    """
    site_tol = []
    num_sites = hypo.getSiteCount()
    for i in range(num_sites):
        direct = num_sites * [0.0]
        for value in [1.0, -1.0]:
            direct[i] = value
            site_tol.append(get_site_tol(hypo, step_size, direct))
    return site_tol 
[docs]def get_site_tol_summary(hypo_file):
    """
    Returns a string that contains a summary of the positional tolerances in
    the provided hypothesis file.
    :param hypo_file: Hypothesis file
    :type hypo_file: str
    :return: Positional tolerances summary
    :rtype: str
    """
    hypo = phase.PhpHypoAdaptor(hypo_file)
    s = "Site  Tolerance"
    for site in phase.PhpHypoAdaptor(hypo_file).getHypoSites():
        site_name = site.getSiteName(0)
        s += " \n %s%.2f" % (site_name.ljust(7), site.getTol())
    return s 
[docs]def save_hypo_with_score(hypo, score, hypo_file, baseline=False):
    """
    Stores the provided score in the hypothesis property PHASE_WEIGHTED_BEDROC
    and saves the hypothesis to disk. If baseline is true, the score will also
    be stored in the property PHASE_WEIGHTED_BEDROC_BASELINE.
    :param hypo: Hypothesis
    :type hypo: phase.PhpHypoAdaptor
    :param score: Weighted BEDROC score
    :type score: float
    :param hypo_file: Destination hypothesis file
    :type hypo_file: str
    :param baseline: Whether to store score in baseline property
    :type baseline: bool
    """
    hypo.addProp(phase.PHASE_WEIGHTED_BEDROC, score)
    if baseline:
        hypo.addProp(phase.PHASE_WEIGHTED_BEDROC_BASELINE, score)
    hypo.save(hypo_file, True)