import subprocess from pathlib import Path from typing import Optional import yaml class USalignRunner: def __init__(self, config_path: str = "config.yaml"): """ Initialize USalignRunner with parameters from config file. Args: config_path (str): Path to the configuration file """ with open(config_path, "r", encoding="utf-8") as f: config = yaml.safe_load(f) self.usalign_path = Path(config["USalign"]["path"]) self.default_params = { "tmscore": config["USalign"]["tmscore"], "outfmt": config["USalign"]["outfmt"], "mol": "protein", # Default to protein alignment } def run_alignment( self, target_dir: str, pdb_list_file: str, tmscore: Optional[float] = None, outfmt: Optional[int] = None, ) -> tuple[int, str, str]: tmscore = tmscore if tmscore is not None else self.default_params["tmscore"] outfmt = outfmt if outfmt is not None else self.default_params["outfmt"] # Create the command cmd = [ str(self.usalign_path), "-mol", self.default_params["mol"], "-dir", str(target_dir), pdb_list_file, "-TMscore", str(tmscore), "-outfmt", str(outfmt), ] print(cmd) # Convert command list to string cmd_str = " ".join(cmd) try: # Execute the command process = subprocess.Popen(cmd_str, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, text=True) # Get output stdout, stderr = process.communicate() return process.returncode, stdout, stderr except Exception as e: return -1, "", str(e)