Source code for dasi.command_line

r"""
Command Line (:mod:`dasi.command_line`)
=============================

.. currentmodule:: dasi.command_line

This module provide command line interface for DASi.

.. code-block::

    dasi run
"""
import os

import fire
from Bio import BiopythonParserWarning
from Bio import SeqIO
from pyblast.utils import load_fasta_glob
from pyblast.utils import load_genbank_glob
from pyblast.utils import make_circular
from pyblast.utils import make_linear

from dasi import __version__
from dasi import Design
from dasi.cost import SpanCost
from dasi.log import logger


[docs]class DasiCLI: """DASi command line interface.""" def __init__( self, directory=os.getcwd(), primers="primers.fasta", templates="templates/*.gb", fragments="fragments/*.gb", goals="goals/*.gb", verbose="v", ): """Initialize a new design.""" self._directory = directory self._primers = os.path.join(self._directory, primers) self._templates = os.path.join(self._directory, templates) self._fragments = os.path.join(self._directory, fragments) self._goals = os.path.join(self._directory, goals) self._do_save = True self._logger = logger(self) if verbose == "v": self._logger.set_level("INFO") elif verbose == "vv": logger.set_level("INFO") elif verbose == "vvv": logger.set_level("DEBUG") elif verbose is None: pass else: raise ValueError( "Verbose level '{}' not recognized. " "Select from 'v', 'vv', or 'vvv'" )
[docs] def run(self, n_jobs: int = 10): """Run a design job. :param n_jobs: number of parrallel jobs to run. (default: 10) :return: """ import warnings warnings.simplefilter(action="ignore", category=RuntimeWarning) warnings.simplefilter(action="ignore", category=BiopythonParserWarning) self._logger.info("Loading sequence files") primers = make_linear(load_fasta_glob(self._primers)) templates = make_circular(load_genbank_glob(self._templates)) fragments = make_linear(load_genbank_glob(self._fragments)) goals = make_circular(load_genbank_glob(self._goals)) design = Design() design.n_jobs = n_jobs design.add_materials( primers=primers, templates=templates, fragments=fragments, queries=goals ) self._logger.info("Getting span cost model") span_cost = self._get_span_cost() design.span_cost = span_cost self._logger.info("Compiling possible molecular assemblies") design.compile() self._logger.info("Optimizing molecular assemblies") design.optimize() self._logger.info("Designing assembly primers and fragments") df, adf, design_json = design.to_df() adf.to_csv("summary.csv") df.to_csv("sequence_design.csv") records = [] for result in design.results.values(): if result.assemblies: a = result.assemblies[0] for i, role, m in a.molecules: records.append(m.sequence) SeqIO.write(records, os.path.join(self._directory, "sequences.gb"), "genbank")
[docs] def version(self): """Print the package version.""" print(__version__)
[docs] def _get_span_cost(self): """Saves the span cost as bytes; reloads when called.""" path = os.path.join(self._directory, "span_cost.b") if self._do_save and os.path.isfile(path): with logger.timeit("INFO", "loading bytes"): print("Loading file: {}".format(path)) span_cost = SpanCost.load(path) else: span_cost = SpanCost.open() if self._do_save: with logger.timeit("INFO", "saving bytes"): print("Saving file: {}".format(path)) span_cost.dump(path) return span_cost
def main(): fire.Fire(DasiCLI)