Source code for tooluniverse.chem_compute_tool

"""
ChemCompute Tools

Provides local computational chemistry tools that require no external API calls.
Currently includes:
- SA Score: Synthetic Accessibility Score using RDKit SA_Score contribution
"""

from typing import Dict, Any
from .base_tool import BaseTool
from .tool_registry import register_tool


[docs] @register_tool("ChemComputeTool") class ChemComputeTool(BaseTool): """ Local computational chemistry tools using RDKit. No external API calls. Provides: - Synthetic Accessibility (SA) Score computation """
[docs] def __init__(self, tool_config: Dict[str, Any]): super().__init__(tool_config) self.parameter = tool_config.get("parameter", {}) self.required = self.parameter.get("required", [])
[docs] def run(self, arguments: Dict[str, Any]) -> Dict[str, Any]: """Execute chem compute tool with given arguments.""" operation = arguments.get("operation") if not operation: return {"status": "error", "error": "Missing required parameter: operation"} operation_handlers = { "sa_score": self._sa_score, } handler = operation_handlers.get(operation) if not handler: return { "status": "error", "error": f"Unknown operation: {operation}", "available_operations": list(operation_handlers.keys()), } try: return handler(arguments) except Exception as e: return {"status": "error", "error": f"Operation failed: {str(e)}"}
[docs] def _sa_score(self, arguments: Dict[str, Any]) -> Dict[str, Any]: """Calculate the Synthetic Accessibility (SA) score for a SMILES string.""" smiles = arguments.get("smiles") if not smiles: return {"status": "error", "error": "Missing required parameter: smiles"} try: from rdkit import Chem, RDConfig import os import sys sys.path.append(os.path.join(RDConfig.RDContribDir, "SA_Score")) import sascorer except ImportError as e: return { "status": "error", "error": f"RDKit is required for SA score calculation: {str(e)}", } mol = Chem.MolFromSmiles(smiles) if mol is None: return {"status": "error", "error": "Invalid SMILES string"} try: score = sascorer.calculateScore(mol) except Exception as e: return { "status": "error", "error": f"SA score calculation failed: {str(e)}", } if score < 3: interpretation = "easy" elif score <= 6: interpretation = "moderate" else: interpretation = "difficult" return { "status": "success", "data": { "smiles": smiles, "sa_score": round(score, 4), "interpretation": interpretation, }, }