Source code for utils.anarcii

#!/usr/bin/env python3

"""Module containing the Anarcii class and the command line interface."""

import contextlib
import io
import logging
from pathlib import Path
from typing import Optional, Union

from biobb_common.generic.biobb_object import BiobbObject
from biobb_common.tools import file_utils as fu
from biobb_common.tools.file_utils import launchlogger
from anarcii import Anarcii as AnarciiModel


[docs] class Anarcii(BiobbObject): """ | biobb_haddock Anarcii | Wrapper class for the `ANARCII <https://github.com/oxpig/ANARCII>`_ antibody numbering tool. | ANARCII numbers antibody, TCR, and other immune receptor sequences. Given an input PDB structure it renumbers it (IMGT scheme by default) and writes the renumbered PDB structure. Args: input_pdb_path (str): Path to the input PDB structure file. File type: input. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_haddock/master/biobb_haddock/test/data/haddock_restraints/4G6K_clean.pdb>`_. Accepted formats: pdb (edam:format_1476). output_pdb_path (str): Path to the output renumbered PDB structure file. File type: output. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_haddock/master/biobb_haddock/test/data/utils/4G6K_anarcii_imgt.pdb>`_. Accepted formats: pdb (edam:format_1476). properties (dict - Python dictionary object containing the tool parameters, not input/output files): * **seq_type** (*str*) - ("antibody") Type of sequence to number. Values: antibody, tcr, vhh, sabdab. * **mode** (*str*) - ("accuracy") Numbering mode. Values: accuracy, speed. * **verbose** (*bool*) - (True) Print verbose output during numbering. * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files. * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist. * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory. Examples: This is a use example of how to use the building block from Python:: from biobb_haddock.utils.anarcii import anarcii prop = { 'seq_type': 'antibody', 'mode': 'accuracy' } anarcii(input_pdb_path='/path/to/structure.pdb', output_pdb_path='/path/to/renumbered.pdb', properties=prop) Info: * wrapped_software: * name: ANARCII * version: 2.0.0 * license: BSD-3-Clause * ontology: * name: EDAM * schema: http://edamontology.org/EDAM.owl """ def __init__( self, input_pdb_path: Union[str, Path], output_pdb_path: Union[str, Path], properties: Optional[dict] = None, **kwargs, ) -> None: properties = properties or {} # Call parent class constructor super().__init__(properties) self.locals_var_dict = locals().copy() # Input/Output files self.io_dict = { "in": {"input_pdb_path": input_pdb_path}, "out": {"output_pdb_path": output_pdb_path}, } # Properties specific for BB self.seq_type = properties.get("seq_type", "antibody") self.mode = properties.get("mode", "accuracy") self.verbose = properties.get("verbose", True) # Check the properties self.check_properties(properties) self.check_arguments()
[docs] @launchlogger def launch(self) -> int: """Execute the :class:`Anarcii <utils.anarcii.Anarcii>` object.""" # Setup Biobb if self.check_restart(): return 0 self.stage_files() # ANARCII appends the '.pdb' suffix to the output stem output_pdb_path = self.stage_io_dict["out"]["output_pdb_path"] pdb_out_stem = str(Path(output_pdb_path).with_suffix("")) fu.log( "Numbering %s with ANARCII (seq_type=%s, mode=%s)" % (self.stage_io_dict["in"]["input_pdb_path"], self.seq_type, self.mode), self.out_log, self.global_log, ) # Capture ANARCII output (stdout/stderr prints and logging) into the Biobb log log_capture = io.StringIO() log_handler = logging.StreamHandler(log_capture) root_logger = logging.getLogger() root_logger.addHandler(log_handler) try: with contextlib.redirect_stdout(log_capture), contextlib.redirect_stderr(log_capture): model = AnarciiModel( seq_type=self.seq_type, mode=self.mode, verbose=self.verbose ) # number() renumbers the structure and returns the numbering self.results = model.number( self.stage_io_dict["in"]["input_pdb_path"], pdb_out_stem=pdb_out_stem ) finally: root_logger.removeHandler(log_handler) captured = log_capture.getvalue().strip() if captured: fu.log("ANARCII output:\n%s" % captured, self.out_log, self.global_log) # Copy files to host self.copy_to_host() # Remove temporal files self.remove_tmp_files() self.check_arguments(output_files_created=True, raise_exception=True) return self.return_code
[docs] def anarcii( input_pdb_path: Union[str, Path], output_pdb_path: Union[str, Path], properties: Optional[dict] = None, **kwargs, ) -> int: """Create :class:`Anarcii <utils.anarcii.Anarcii>` class and execute the :meth:`launch() <utils.anarcii.Anarcii.launch>` method.""" return Anarcii(**dict(locals())).launch()
anarcii.__doc__ = Anarcii.__doc__ main = Anarcii.get_main(anarcii, "Wrapper for the ANARCII antibody numbering tool.") if __name__ == "__main__": main()