Module deeporigin.src.properties

Classes

class MolecularPropertiesClient
Expand source code
class MolecularPropertiesClient(Client):
    """
    A client class for predicting molecular properties of chemical compounds.

    This class provides methods to predict various molecular properties including:
    - Aqueous solubility (logS)
    - Lipophilicity (logP)
    - Distribution coefficient (logD)
    - hERG channel inhibition
    - Cytochrome P450 interactions
    - Ames test mutagenicity
    - Protonation states
    - PAINS substructure detection

    The class accepts input as SMILES strings or Ligand objects, either single instances
    or lists of multiple compounds.

    Methods
    -------
    properties_request(logger, smiles, properties)
        Sends property prediction request to the server.

    predict(smiles_list, properties)
        Executes prediction request for specified properties.

    preprocess(entry)
        Preprocesses input into list of SMILES strings.

    logS(entry)
        Predicts aqueous solubility.

    logP(entry)
        Predicts lipophilicity.

    logD(entry)
        Predicts distribution coefficient.

    hERG(entry)
        Predicts hERG channel inhibition.

    cyp(entry, type)
        Predicts CYP interactions.

    ames(entry)
        Predicts Ames test mutagenicity.

    protonate(entry, pH, filter_percentage, html_output)
        Predicts protonation states.

    pains_detector(entry)
        Detects PAINS substructures.

    properties(entry)
        Predicts all available properties.

    Parameters
    ----------
    entry : Union[str, Ligand, List[Union[str, Ligand]]]
        Input compound(s) as SMILES string(s) or Ligand object(s)
    type : Optional[str]
        CYP isoform type for cyp() method
    pH : float
        pH value for protonate() method
    filter_percentage : float
        Threshold for filtering protonation states
    html_output : bool
        Whether to return HTML report for protonation

    Returns
    -------
    Various Report objects depending on the method called (MolPropsReport, ProtonationReport, PainsReport)
    """
    def __init__(self):
        super().__init__()

    def properties_request(self, logger: Logger, smiles: list, properties: dict):
        """
        Makes a property prediction request for given SMILES strings.

        This method sends a POST request to predict properties for a list of SMILES strings
        using the specified properties dictionary.

        Parameters
        ----------
        logger : Logger
            Logger instance for logging the request process
        smiles : list
            List of SMILES strings to predict properties for
        properties : dict
            Dictionary specifying which properties to predict

        Returns
        -------
        tuple
            A tuple containing (response_json, success_boolean) where:
            - response_json: JSON response from server if successful, None if failed
            - success_boolean: True if request was successful, False otherwise

        Raises
        ------
        Exception
            Any unexpected errors during the request are caught and logged
        """
        logger.log_info("Preparing property prediction request.")

        body = {"smiles": smiles, "predict": properties}

        try:
            logger.log_info("Sending properties prediction request.")
            response = self.post_request(
                endpoint="properties",
                logger=logger,
                data=body,
            )
            logger.log_info("Received properties prediction response.")

            return response.json(), True
        except Exception as e:
            logger.log_error(f"Unexpected error: {str(e)}")
            return None, False

    def predict(self, smiles_list: list, properties: dict):
        """
        Predicts properties for a list of SMILES representations of molecules.

        Args:
            smiles_list (list): List of SMILES strings representing molecules.
            properties (dict): Dictionary specifying which properties to predict.

        Returns:
            dict or None: Dictionary containing predicted properties if successful,
                         None if the prediction failed or an error occurred.

        Raises:
            Exception: Any exception that occurs during the prediction process will be caught,
                      logged, and None will be returned.
        """
        logger = Logger("INFO", os.getenv("LOG_BIOSIM_CLIENT"))
        logger.log_info("Executing predict properties request.")
        try:
            body, completed = self.properties_request(logger, smiles_list, properties)
            if not completed:
                return None

            return body
        except Exception as e:
            logger.log_error(f"Something went wrong: {str(e)}")
            return None

    def preprocess(self, entry):
        """
        Preprocesses input to extract SMILES strings from various input formats.

        This function handles single SMILES strings, Ligand objects, or lists containing
        either SMILES strings or Ligand objects. It validates input types and extracts
        SMILES representations.

        Args:
            entry: Input that can be either:
                - str: A single SMILES string
                - Ligand: A Ligand object containing SMILES information
                - list: A list of SMILES strings or Ligand objects

        Returns:
            tuple: A tuple containing:
                - list: Extracted SMILES strings
                - bool: Status flag indicating success (True) or failure (False)

        Examples:
            >>> preprocess("CC(=O)O")
            (["CC(=O)O"], True)

            >>> preprocess([ligand1, ligand2])  # Where ligand1, ligand2 are Ligand objects
            (["CC(=O)O", "CCCC"], True)

            >>> preprocess(123)  # Invalid input
            ([], False)
        """
        console_logger = Logger("INFO", None)
        logger = Logger("INFO", os.getenv("LOG_BIOSIM_CLIENT"))

        smiles_list, status = [], True

        if isinstance(entry, str):
            smiles_list.append(entry)
        elif isinstance(entry, Ligand):
            smiles_list.append(entry.mol.smiles)
        elif isinstance(entry, list):
            for item in entry:
                if isinstance(item, str):
                    smiles_list.append(item)
                elif isinstance(item, Ligand):
                    smiles_list.append(item.mol.smiles)
                else:
                    console_logger.log_error(f"Invalid list item type: {type(item)}")
                    logger.log_error("List item type error.")
                    status = False

                    return [], status
        else:
            console_logger.log_error(f"Invalid argument type: {type(entry)}")
            logger.log_error("Argument type error.")

            return [], False

        return smiles_list, status

    def logS(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
        """
        Calculate the aqueous solubility (logS) for given chemical compounds.

        Args:
            entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input compound(s) as SMILES string(s),
                Ligand object(s), or a list containing either SMILES strings or Ligand objects.

        Returns:
            MolPropsReport: Object containing predicted logS values for the input compound(s).
                Returns None if preprocessing fails.

        Notes:
            - LogS is a measure of the solubility of a compound in water, expressed as a logarithm
            - Units are typically in mol/L
            - More negative values indicate lower solubility
        """
        smiles_list, status = self.preprocess(entry)
        if status:
            return MolPropsReport(self.predict(smiles_list, {"logS": True}))

    def logP(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
        """
        Calculate the logP (octanol-water partition coefficient) for chemical compounds.

        Args:
            entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input chemical structure(s).
                Can be a SMILES string, Ligand object, or a list containing either format.

        Returns:
            MolPropsReport: Report containing the calculated logP values for the input structure(s).
                Returns prediction results wrapped in MolPropsReport object.

        Note:
            LogP is a measure of the molecule's lipophilicity - its ability to dissolve in fats,
            oils and non-polar solvents. Higher values indicate greater lipophilicity.
        """
        smiles_list, status = self.preprocess(entry)
        if status:
            return MolPropsReport(self.predict(smiles_list, {"logP": True}))

    def logD(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
        """
        Calculate the logD (Distribution coefficient) for the given chemical compound(s).

        The logD is the logarithm of the distribution coefficient, which is the ratio of
        the sum of concentrations of all forms of the compound (ionized plus un-ionized)
        in each of two phases (typically octanol and water).

        Args:
            entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input compound(s) as SMILES string(s),
                Ligand object(s), or a list containing either or both.

        Returns:
            MolPropsReport: A report containing the calculated logD values for the input compound(s).
                Returns None if preprocessing fails.

        Example:
            >>> calculator = PropertyCalculator()
            >>> result = calculator.logD("CCO")  # Calculate logD for ethanol
            >>> result = calculator.logD(["CCO", "CCCO"])  # Calculate for multiple compounds
        """
        smiles_list, status = self.preprocess(entry)
        if status:
            return MolPropsReport(self.predict(smiles_list, {"logD": True}))

    def hERG(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
        """
        Predicts hERG channel blocking potential for given chemical structures.

        Args:
            entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input chemical structure(s).
            Can be a SMILES string, Ligand object, or a list containing either.

        Returns:
            MolPropsReport: Report containing predicted hERG channel blocking probabilities.
            Returns None if preprocessing fails.

        Notes:
            The hERG (human Ether-à-go-go-Related Gene) potassium channel is crucial for
            cardiac action potential. Blocking this channel can lead to potentially fatal
            cardiac arrhythmias, making hERG liability assessment important in drug discovery.

        Example:
            >>> predictor = MolecularPropertiesClient()
            >>> result = predictor.hERG("CC(=O)Oc1ccccc1C(=O)O")  # Aspirin SMILES
            >>> result = predictor.hERG([ligand1, "CCCC"])  # Mixed input types
        """

        smiles_list, status = self.preprocess(entry)
        if status:
            return MolPropsReport(self.predict(smiles_list, {"hERG": True}))

    def cyp(self, entry: Union[str, Ligand, List[Union[str, Ligand]]], type: Optional[str] = None):
        """
        Predicts cytochrome P450 (CYP) enzyme interactions for given chemical compounds.

        This method estimates the likelihood of interaction between chemical compounds and CYP enzymes,
        which are crucial for drug metabolism. Different CYP subtypes can be specified.

        Args:
            entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input compound(s) as SMILES string(s),
                Ligand object(s), or a list containing either.
            type (Optional[str], optional): Specific CYP subtype to analyze. If None, analyzes general
                CYP interaction. Defaults to None.

        Returns:
            MolPropsReport: Report containing CYP interaction predictions for the input compound(s).

        Raises:
            May raise exceptions during SMILES preprocessing or prediction steps.

        Examples:
            >>> props = Properties()
            >>> result = props.cyp("CC(=O)OC1=CC=CC=C1C(=O)O", type="2D6")
            >>> result = props.cyp(ligand_obj)
            >>> result = props.cyp(["CC(=O)OC1=CC=CC=C1C(=O)O", ligand_obj])
        """
        smiles_list, status = self.preprocess(entry)
        prop = "cyp" if type is None else "cyp" + type

        if status:
            return MolPropsReport(self.predict(smiles_list, {prop: True}))

    def ames(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
        """
        Predicts Ames mutagenicity for the given chemical structure(s).

        The Ames test is a widely used method to determine whether a chemical compound can cause
        mutations in DNA. A positive test indicates that the compound is mutagenic and may act
        as a carcinogen.

        Args:
            entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input chemical structure(s).
            Can be a SMILES string, Ligand object, or a list containing either format.

        Returns:
            MolPropsReport: Report containing Ames test prediction results for the input structure(s).
            A positive value indicates mutagenic potential.

        Examples:
            >>> predictor.ames("CC(=O)Oc1ccccc1C(=O)O")  # Aspirin SMILES
            >>> predictor.ames(ligand_obj)  # Using Ligand object
            >>> predictor.ames(["CC(=O)O", "CCO"])  # List of SMILES
        """

        smiles_list, status = self.preprocess(entry)
        if status:
            return MolPropsReport(self.predict(smiles_list, {"ames": True}))

    def protonate(self, entry: Union[str, Ligand, List[Union[str, Ligand]]], pH: float = 7.4, filter_percentage: float = 1, html_output: bool = True):
        """
        Protonates molecules at a given pH value.

        Args:
            entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input molecule(s) to be protonated.
            Can be a single SMILES string, a Ligand object, or a list of either.
            pH (float, optional): The pH value at which to calculate protonation states.
            Default is 7.4.
            filter_percentage (float, optional): Threshold for filtering protonation states,
            between 0 and 1. Default is 1.
            html_output (bool, optional): If True, returns results as an HTML report.
            If False, returns raw results. Default is True.

        Returns:
            Union[ProtonationReport, dict]: If html_output is True, returns a ProtonationReport object.
            If html_output is False, returns a dictionary containing the protonation results.

        Examples:
            >>> mol = "CC(=O)O"  # Acetic acid
            >>> protonated = protonate(mol, pH=4.0)
        """

        smiles_list, status = self.preprocess(entry)
        if status:
            result = self.predict(smiles_list, {"protonation": (pH, filter_percentage)})
            if html_output:
                return ProtonationReport(result)
            else:
                return result

    def pains_detector(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
        """
        Detects PAINS (Pan-Assay Interference Compounds) patterns in chemical structures.

        This method analyzes input chemical structures for potential PAINS patterns,
        which are substructural features known to cause false positives in high-throughput screens.

        Args:
            entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input chemical structure(s).
            Can be a SMILES string, Ligand object, or a list containing either format.

        Returns:
            PainsReport: Report containing PAINS analysis results for the input structure(s).
            Identifies any problematic substructures that may cause assay interference.

        Examples:
            >>> detector = MolecularPropertiesClient()
            >>> result = detector.pains_detector("CC(=O)Nc1ccc(O)cc1")
            >>> result = detector.pains_detector([ligand1, "CCCC"])  # Mixed input types
        """

        smiles_list, status = self.preprocess(entry)
        if status:
            return PainsReport(self.predict(smiles_list, {"PAINS": True}))

    def properties(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
        """
        Calculate molecular properties for the given chemical entries.

        Args:
            entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input chemical structure(s).
            Can be a SMILES string, Ligand object, or a list containing either format.

        Returns:
            MolPropsReport: Report containing the predicted molecular properties including
            hERG, logD, logP, logS, Ames mutagenicity, and CYP inhibition.
            Returns None if preprocessing fails.

        Notes:
            This method predicts all available properties in a single call, providing a
            comprehensive molecular property profile. The input is first preprocessed and
            predictions are only made if preprocessing succeeds.
        """
        smiles_list, status = self.preprocess(entry)
        properties_to_predict = {"hERG": True, "logD": True, "logP": True, "logS": True, "ames": True, "cyp": True}

        if status:
            return MolPropsReport(self.predict(smiles_list, properties_to_predict))

A client class for predicting molecular properties of chemical compounds.

This class provides methods to predict various molecular properties including: - Aqueous solubility (logS) - Lipophilicity (logP) - Distribution coefficient (logD) - hERG channel inhibition - Cytochrome P450 interactions - Ames test mutagenicity - Protonation states - PAINS substructure detection

The class accepts input as SMILES strings or Ligand objects, either single instances or lists of multiple compounds.

Methods

properties_request(logger, smiles, properties) Sends property prediction request to the server.

predict(smiles_list, properties) Executes prediction request for specified properties.

preprocess(entry) Preprocesses input into list of SMILES strings.

logS(entry) Predicts aqueous solubility.

logP(entry) Predicts lipophilicity.

logD(entry) Predicts distribution coefficient.

hERG(entry) Predicts hERG channel inhibition.

cyp(entry, type) Predicts CYP interactions.

ames(entry) Predicts Ames test mutagenicity.

protonate(entry, pH, filter_percentage, html_output) Predicts protonation states.

pains_detector(entry) Detects PAINS substructures.

properties(entry) Predicts all available properties.

Parameters

entry : Union[str, Ligand, List[Union[str, Ligand]]]
Input compound(s) as SMILES string(s) or Ligand object(s)
type : Optional[str]
CYP isoform type for cyp() method
pH : float
pH value for protonate() method
filter_percentage : float
Threshold for filtering protonation states
html_output : bool
Whether to return HTML report for protonation

Returns

Various Report objects depending on the method called (MolPropsReport, ProtonationReport, PainsReport)
 

Ancestors

Methods

def ames(self,
entry: str | Ligand | List[str | Ligand])
Expand source code
def ames(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
    """
    Predicts Ames mutagenicity for the given chemical structure(s).

    The Ames test is a widely used method to determine whether a chemical compound can cause
    mutations in DNA. A positive test indicates that the compound is mutagenic and may act
    as a carcinogen.

    Args:
        entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input chemical structure(s).
        Can be a SMILES string, Ligand object, or a list containing either format.

    Returns:
        MolPropsReport: Report containing Ames test prediction results for the input structure(s).
        A positive value indicates mutagenic potential.

    Examples:
        >>> predictor.ames("CC(=O)Oc1ccccc1C(=O)O")  # Aspirin SMILES
        >>> predictor.ames(ligand_obj)  # Using Ligand object
        >>> predictor.ames(["CC(=O)O", "CCO"])  # List of SMILES
    """

    smiles_list, status = self.preprocess(entry)
    if status:
        return MolPropsReport(self.predict(smiles_list, {"ames": True}))

Predicts Ames mutagenicity for the given chemical structure(s).

The Ames test is a widely used method to determine whether a chemical compound can cause mutations in DNA. A positive test indicates that the compound is mutagenic and may act as a carcinogen.

Args

entry : Union[str, Ligand, List[Union[str, Ligand]]]
Input chemical structure(s).

Can be a SMILES string, Ligand object, or a list containing either format.

Returns

MolPropsReport
Report containing Ames test prediction results for the input structure(s).

A positive value indicates mutagenic potential.

Examples

>>> predictor.ames("CC(=O)Oc1ccccc1C(=O)O")  # Aspirin SMILES
>>> predictor.ames(ligand_obj)  # Using Ligand object
>>> predictor.ames(["CC(=O)O", "CCO"])  # List of SMILES
def cyp(self,
entry: str | Ligand | List[str | Ligand],
type: str | None = None)
Expand source code
def cyp(self, entry: Union[str, Ligand, List[Union[str, Ligand]]], type: Optional[str] = None):
    """
    Predicts cytochrome P450 (CYP) enzyme interactions for given chemical compounds.

    This method estimates the likelihood of interaction between chemical compounds and CYP enzymes,
    which are crucial for drug metabolism. Different CYP subtypes can be specified.

    Args:
        entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input compound(s) as SMILES string(s),
            Ligand object(s), or a list containing either.
        type (Optional[str], optional): Specific CYP subtype to analyze. If None, analyzes general
            CYP interaction. Defaults to None.

    Returns:
        MolPropsReport: Report containing CYP interaction predictions for the input compound(s).

    Raises:
        May raise exceptions during SMILES preprocessing or prediction steps.

    Examples:
        >>> props = Properties()
        >>> result = props.cyp("CC(=O)OC1=CC=CC=C1C(=O)O", type="2D6")
        >>> result = props.cyp(ligand_obj)
        >>> result = props.cyp(["CC(=O)OC1=CC=CC=C1C(=O)O", ligand_obj])
    """
    smiles_list, status = self.preprocess(entry)
    prop = "cyp" if type is None else "cyp" + type

    if status:
        return MolPropsReport(self.predict(smiles_list, {prop: True}))

Predicts cytochrome P450 (CYP) enzyme interactions for given chemical compounds.

This method estimates the likelihood of interaction between chemical compounds and CYP enzymes, which are crucial for drug metabolism. Different CYP subtypes can be specified.

Args

entry : Union[str, Ligand, List[Union[str, Ligand]]]
Input compound(s) as SMILES string(s), Ligand object(s), or a list containing either.
type : Optional[str], optional
Specific CYP subtype to analyze. If None, analyzes general CYP interaction. Defaults to None.

Returns

MolPropsReport
Report containing CYP interaction predictions for the input compound(s).

Raises

May raise exceptions during SMILES preprocessing or prediction steps.

Examples

>>> props = Properties()
>>> result = props.cyp("CC(=O)OC1=CC=CC=C1C(=O)O", type="2D6")
>>> result = props.cyp(ligand_obj)
>>> result = props.cyp(["CC(=O)OC1=CC=CC=C1C(=O)O", ligand_obj])
def hERG(self,
entry: str | Ligand | List[str | Ligand])
Expand source code
def hERG(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
    """
    Predicts hERG channel blocking potential for given chemical structures.

    Args:
        entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input chemical structure(s).
        Can be a SMILES string, Ligand object, or a list containing either.

    Returns:
        MolPropsReport: Report containing predicted hERG channel blocking probabilities.
        Returns None if preprocessing fails.

    Notes:
        The hERG (human Ether-à-go-go-Related Gene) potassium channel is crucial for
        cardiac action potential. Blocking this channel can lead to potentially fatal
        cardiac arrhythmias, making hERG liability assessment important in drug discovery.

    Example:
        >>> predictor = MolecularPropertiesClient()
        >>> result = predictor.hERG("CC(=O)Oc1ccccc1C(=O)O")  # Aspirin SMILES
        >>> result = predictor.hERG([ligand1, "CCCC"])  # Mixed input types
    """

    smiles_list, status = self.preprocess(entry)
    if status:
        return MolPropsReport(self.predict(smiles_list, {"hERG": True}))

Predicts hERG channel blocking potential for given chemical structures.

Args

entry : Union[str, Ligand, List[Union[str, Ligand]]]
Input chemical structure(s).

Can be a SMILES string, Ligand object, or a list containing either.

Returns

MolPropsReport
Report containing predicted hERG channel blocking probabilities.

Returns None if preprocessing fails.

Notes

The hERG (human Ether-à-go-go-Related Gene) potassium channel is crucial for cardiac action potential. Blocking this channel can lead to potentially fatal cardiac arrhythmias, making hERG liability assessment important in drug discovery.

Example

>>> predictor = MolecularPropertiesClient()
>>> result = predictor.hERG("CC(=O)Oc1ccccc1C(=O)O")  # Aspirin SMILES
>>> result = predictor.hERG([ligand1, "CCCC"])  # Mixed input types
def logD(self,
entry: str | Ligand | List[str | Ligand])
Expand source code
def logD(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
    """
    Calculate the logD (Distribution coefficient) for the given chemical compound(s).

    The logD is the logarithm of the distribution coefficient, which is the ratio of
    the sum of concentrations of all forms of the compound (ionized plus un-ionized)
    in each of two phases (typically octanol and water).

    Args:
        entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input compound(s) as SMILES string(s),
            Ligand object(s), or a list containing either or both.

    Returns:
        MolPropsReport: A report containing the calculated logD values for the input compound(s).
            Returns None if preprocessing fails.

    Example:
        >>> calculator = PropertyCalculator()
        >>> result = calculator.logD("CCO")  # Calculate logD for ethanol
        >>> result = calculator.logD(["CCO", "CCCO"])  # Calculate for multiple compounds
    """
    smiles_list, status = self.preprocess(entry)
    if status:
        return MolPropsReport(self.predict(smiles_list, {"logD": True}))

Calculate the logD (Distribution coefficient) for the given chemical compound(s).

The logD is the logarithm of the distribution coefficient, which is the ratio of the sum of concentrations of all forms of the compound (ionized plus un-ionized) in each of two phases (typically octanol and water).

Args

entry : Union[str, Ligand, List[Union[str, Ligand]]]
Input compound(s) as SMILES string(s), Ligand object(s), or a list containing either or both.

Returns

MolPropsReport
A report containing the calculated logD values for the input compound(s). Returns None if preprocessing fails.

Example

>>> calculator = PropertyCalculator()
>>> result = calculator.logD("CCO")  # Calculate logD for ethanol
>>> result = calculator.logD(["CCO", "CCCO"])  # Calculate for multiple compounds
def logP(self,
entry: str | Ligand | List[str | Ligand])
Expand source code
def logP(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
    """
    Calculate the logP (octanol-water partition coefficient) for chemical compounds.

    Args:
        entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input chemical structure(s).
            Can be a SMILES string, Ligand object, or a list containing either format.

    Returns:
        MolPropsReport: Report containing the calculated logP values for the input structure(s).
            Returns prediction results wrapped in MolPropsReport object.

    Note:
        LogP is a measure of the molecule's lipophilicity - its ability to dissolve in fats,
        oils and non-polar solvents. Higher values indicate greater lipophilicity.
    """
    smiles_list, status = self.preprocess(entry)
    if status:
        return MolPropsReport(self.predict(smiles_list, {"logP": True}))

Calculate the logP (octanol-water partition coefficient) for chemical compounds.

Args

entry : Union[str, Ligand, List[Union[str, Ligand]]]
Input chemical structure(s). Can be a SMILES string, Ligand object, or a list containing either format.

Returns

MolPropsReport
Report containing the calculated logP values for the input structure(s). Returns prediction results wrapped in MolPropsReport object.

Note

LogP is a measure of the molecule's lipophilicity - its ability to dissolve in fats, oils and non-polar solvents. Higher values indicate greater lipophilicity.

def logS(self,
entry: str | Ligand | List[str | Ligand])
Expand source code
def logS(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
    """
    Calculate the aqueous solubility (logS) for given chemical compounds.

    Args:
        entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input compound(s) as SMILES string(s),
            Ligand object(s), or a list containing either SMILES strings or Ligand objects.

    Returns:
        MolPropsReport: Object containing predicted logS values for the input compound(s).
            Returns None if preprocessing fails.

    Notes:
        - LogS is a measure of the solubility of a compound in water, expressed as a logarithm
        - Units are typically in mol/L
        - More negative values indicate lower solubility
    """
    smiles_list, status = self.preprocess(entry)
    if status:
        return MolPropsReport(self.predict(smiles_list, {"logS": True}))

Calculate the aqueous solubility (logS) for given chemical compounds.

Args

entry : Union[str, Ligand, List[Union[str, Ligand]]]
Input compound(s) as SMILES string(s), Ligand object(s), or a list containing either SMILES strings or Ligand objects.

Returns

MolPropsReport
Object containing predicted logS values for the input compound(s). Returns None if preprocessing fails.

Notes

  • LogS is a measure of the solubility of a compound in water, expressed as a logarithm
  • Units are typically in mol/L
  • More negative values indicate lower solubility
def pains_detector(self,
entry: str | Ligand | List[str | Ligand])
Expand source code
def pains_detector(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
    """
    Detects PAINS (Pan-Assay Interference Compounds) patterns in chemical structures.

    This method analyzes input chemical structures for potential PAINS patterns,
    which are substructural features known to cause false positives in high-throughput screens.

    Args:
        entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input chemical structure(s).
        Can be a SMILES string, Ligand object, or a list containing either format.

    Returns:
        PainsReport: Report containing PAINS analysis results for the input structure(s).
        Identifies any problematic substructures that may cause assay interference.

    Examples:
        >>> detector = MolecularPropertiesClient()
        >>> result = detector.pains_detector("CC(=O)Nc1ccc(O)cc1")
        >>> result = detector.pains_detector([ligand1, "CCCC"])  # Mixed input types
    """

    smiles_list, status = self.preprocess(entry)
    if status:
        return PainsReport(self.predict(smiles_list, {"PAINS": True}))

Detects PAINS (Pan-Assay Interference Compounds) patterns in chemical structures.

This method analyzes input chemical structures for potential PAINS patterns, which are substructural features known to cause false positives in high-throughput screens.

Args

entry : Union[str, Ligand, List[Union[str, Ligand]]]
Input chemical structure(s).

Can be a SMILES string, Ligand object, or a list containing either format.

Returns

PainsReport
Report containing PAINS analysis results for the input structure(s).

Identifies any problematic substructures that may cause assay interference.

Examples

>>> detector = MolecularPropertiesClient()
>>> result = detector.pains_detector("CC(=O)Nc1ccc(O)cc1")
>>> result = detector.pains_detector([ligand1, "CCCC"])  # Mixed input types
def predict(self, smiles_list: list, properties: dict)
Expand source code
def predict(self, smiles_list: list, properties: dict):
    """
    Predicts properties for a list of SMILES representations of molecules.

    Args:
        smiles_list (list): List of SMILES strings representing molecules.
        properties (dict): Dictionary specifying which properties to predict.

    Returns:
        dict or None: Dictionary containing predicted properties if successful,
                     None if the prediction failed or an error occurred.

    Raises:
        Exception: Any exception that occurs during the prediction process will be caught,
                  logged, and None will be returned.
    """
    logger = Logger("INFO", os.getenv("LOG_BIOSIM_CLIENT"))
    logger.log_info("Executing predict properties request.")
    try:
        body, completed = self.properties_request(logger, smiles_list, properties)
        if not completed:
            return None

        return body
    except Exception as e:
        logger.log_error(f"Something went wrong: {str(e)}")
        return None

Predicts properties for a list of SMILES representations of molecules.

Args

smiles_list : list
List of SMILES strings representing molecules.
properties : dict
Dictionary specifying which properties to predict.

Returns

dict or None
Dictionary containing predicted properties if successful, None if the prediction failed or an error occurred.

Raises

Exception
Any exception that occurs during the prediction process will be caught, logged, and None will be returned.
def preprocess(self, entry)
Expand source code
def preprocess(self, entry):
    """
    Preprocesses input to extract SMILES strings from various input formats.

    This function handles single SMILES strings, Ligand objects, or lists containing
    either SMILES strings or Ligand objects. It validates input types and extracts
    SMILES representations.

    Args:
        entry: Input that can be either:
            - str: A single SMILES string
            - Ligand: A Ligand object containing SMILES information
            - list: A list of SMILES strings or Ligand objects

    Returns:
        tuple: A tuple containing:
            - list: Extracted SMILES strings
            - bool: Status flag indicating success (True) or failure (False)

    Examples:
        >>> preprocess("CC(=O)O")
        (["CC(=O)O"], True)

        >>> preprocess([ligand1, ligand2])  # Where ligand1, ligand2 are Ligand objects
        (["CC(=O)O", "CCCC"], True)

        >>> preprocess(123)  # Invalid input
        ([], False)
    """
    console_logger = Logger("INFO", None)
    logger = Logger("INFO", os.getenv("LOG_BIOSIM_CLIENT"))

    smiles_list, status = [], True

    if isinstance(entry, str):
        smiles_list.append(entry)
    elif isinstance(entry, Ligand):
        smiles_list.append(entry.mol.smiles)
    elif isinstance(entry, list):
        for item in entry:
            if isinstance(item, str):
                smiles_list.append(item)
            elif isinstance(item, Ligand):
                smiles_list.append(item.mol.smiles)
            else:
                console_logger.log_error(f"Invalid list item type: {type(item)}")
                logger.log_error("List item type error.")
                status = False

                return [], status
    else:
        console_logger.log_error(f"Invalid argument type: {type(entry)}")
        logger.log_error("Argument type error.")

        return [], False

    return smiles_list, status

Preprocesses input to extract SMILES strings from various input formats.

This function handles single SMILES strings, Ligand objects, or lists containing either SMILES strings or Ligand objects. It validates input types and extracts SMILES representations.

Args

entry
Input that can be either: - str: A single SMILES string - Ligand: A Ligand object containing SMILES information - list: A list of SMILES strings or Ligand objects

Returns

tuple
A tuple containing: - list: Extracted SMILES strings - bool: Status flag indicating success (True) or failure (False)

Examples

>>> preprocess("CC(=O)O")
(["CC(=O)O"], True)
>>> preprocess([ligand1, ligand2])  # Where ligand1, ligand2 are Ligand objects
(["CC(=O)O", "CCCC"], True)
>>> preprocess(123)  # Invalid input
([], False)
def properties(self,
entry: str | Ligand | List[str | Ligand])
Expand source code
def properties(self, entry: Union[str, Ligand, List[Union[str, Ligand]]]):
    """
    Calculate molecular properties for the given chemical entries.

    Args:
        entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input chemical structure(s).
        Can be a SMILES string, Ligand object, or a list containing either format.

    Returns:
        MolPropsReport: Report containing the predicted molecular properties including
        hERG, logD, logP, logS, Ames mutagenicity, and CYP inhibition.
        Returns None if preprocessing fails.

    Notes:
        This method predicts all available properties in a single call, providing a
        comprehensive molecular property profile. The input is first preprocessed and
        predictions are only made if preprocessing succeeds.
    """
    smiles_list, status = self.preprocess(entry)
    properties_to_predict = {"hERG": True, "logD": True, "logP": True, "logS": True, "ames": True, "cyp": True}

    if status:
        return MolPropsReport(self.predict(smiles_list, properties_to_predict))

Calculate molecular properties for the given chemical entries.

Args

entry : Union[str, Ligand, List[Union[str, Ligand]]]
Input chemical structure(s).

Can be a SMILES string, Ligand object, or a list containing either format.

Returns

MolPropsReport
Report containing the predicted molecular properties including

hERG, logD, logP, logS, Ames mutagenicity, and CYP inhibition. Returns None if preprocessing fails.

Notes

This method predicts all available properties in a single call, providing a comprehensive molecular property profile. The input is first preprocessed and predictions are only made if preprocessing succeeds.

def properties_request(self,
logger: Logger,
smiles: list,
properties: dict)
Expand source code
def properties_request(self, logger: Logger, smiles: list, properties: dict):
    """
    Makes a property prediction request for given SMILES strings.

    This method sends a POST request to predict properties for a list of SMILES strings
    using the specified properties dictionary.

    Parameters
    ----------
    logger : Logger
        Logger instance for logging the request process
    smiles : list
        List of SMILES strings to predict properties for
    properties : dict
        Dictionary specifying which properties to predict

    Returns
    -------
    tuple
        A tuple containing (response_json, success_boolean) where:
        - response_json: JSON response from server if successful, None if failed
        - success_boolean: True if request was successful, False otherwise

    Raises
    ------
    Exception
        Any unexpected errors during the request are caught and logged
    """
    logger.log_info("Preparing property prediction request.")

    body = {"smiles": smiles, "predict": properties}

    try:
        logger.log_info("Sending properties prediction request.")
        response = self.post_request(
            endpoint="properties",
            logger=logger,
            data=body,
        )
        logger.log_info("Received properties prediction response.")

        return response.json(), True
    except Exception as e:
        logger.log_error(f"Unexpected error: {str(e)}")
        return None, False

Makes a property prediction request for given SMILES strings.

This method sends a POST request to predict properties for a list of SMILES strings using the specified properties dictionary.

Parameters

logger : Logger
Logger instance for logging the request process
smiles : list
List of SMILES strings to predict properties for
properties : dict
Dictionary specifying which properties to predict

Returns

tuple
A tuple containing (response_json, success_boolean) where: - response_json: JSON response from server if successful, None if failed - success_boolean: True if request was successful, False otherwise

Raises

Exception
Any unexpected errors during the request are caught and logged
def protonate(self,
entry: str | Ligand | List[str | Ligand],
pH: float = 7.4,
filter_percentage: float = 1,
html_output: bool = True)
Expand source code
def protonate(self, entry: Union[str, Ligand, List[Union[str, Ligand]]], pH: float = 7.4, filter_percentage: float = 1, html_output: bool = True):
    """
    Protonates molecules at a given pH value.

    Args:
        entry (Union[str, Ligand, List[Union[str, Ligand]]]): Input molecule(s) to be protonated.
        Can be a single SMILES string, a Ligand object, or a list of either.
        pH (float, optional): The pH value at which to calculate protonation states.
        Default is 7.4.
        filter_percentage (float, optional): Threshold for filtering protonation states,
        between 0 and 1. Default is 1.
        html_output (bool, optional): If True, returns results as an HTML report.
        If False, returns raw results. Default is True.

    Returns:
        Union[ProtonationReport, dict]: If html_output is True, returns a ProtonationReport object.
        If html_output is False, returns a dictionary containing the protonation results.

    Examples:
        >>> mol = "CC(=O)O"  # Acetic acid
        >>> protonated = protonate(mol, pH=4.0)
    """

    smiles_list, status = self.preprocess(entry)
    if status:
        result = self.predict(smiles_list, {"protonation": (pH, filter_percentage)})
        if html_output:
            return ProtonationReport(result)
        else:
            return result

Protonates molecules at a given pH value.

Args

entry : Union[str, Ligand, List[Union[str, Ligand]]]
Input molecule(s) to be protonated.
Can be a single SMILES string, a Ligand object, or a list of either.
pH : float, optional
The pH value at which to calculate protonation states.
Default is 7.4.
filter_percentage : float, optional
Threshold for filtering protonation states,
between 0 and 1. Default is 1.
html_output : bool, optional
If True, returns results as an HTML report.

If False, returns raw results. Default is True.

Returns

Union[ProtonationReport, dict]
If html_output is True, returns a ProtonationReport object.

If html_output is False, returns a dictionary containing the protonation results.

Examples

>>> mol = "CC(=O)O"  # Acetic acid
>>> protonated = protonate(mol, pH=4.0)

Inherited members