def _test_inline(cls): """ Detect whether weave.inline is functional. Produces compile warnings, which we suppress by capturing STDERR. """ if not hasattr(cls, '_use_inline'): cls._use_inline = False if weave_inline is not None: logger = get_logger(__name__) extra_compile_args = [] # See comment in __init__ for why this must be EXTENDED_DEBUG. if not logger.isEnabledFor(EXTENDED_DEBUG): if os.name == 'posix': extra_compile_args.append('2>/dev/null') elif os.name == 'nt': extra_compile_args.append('2>NUL') try: with _patch_distutils_logging(logger): weave_inline('int i=0; i=i;', force=1, extra_compile_args=extra_compile_args) cls._use_inline = True except (weave.build_tools.CompileError, distutils.errors.CompileError, ImportError): pass except ValueError as e: if len(e.args) == 1 and \ e.args[0] == "Symbol table not found": get_logger(__name__).debug( "'ValueError: Symbol table not found' " "encountered; weave compiler is not functional") else: raise
def _test_inline(cls): """ Detect whether weave.inline is functional. Produces compile warnings, which we suppress by capturing STDERR. """ if not hasattr(cls, '_use_inline'): cls._use_inline = False if weave_inline is not None: logger = get_logger(__name__) extra_compile_args = [] # See comment in __init__ for why this must be EXTENDED_DEBUG. if not logger.isEnabledFor(EXTENDED_DEBUG): if os.name == 'posix': extra_compile_args.append('2>/dev/null') elif os.name == 'nt': extra_compile_args.append('2>NUL') try: with _patch_distutils_logging(logger): weave_inline('int i=0; i=i;', force=1, extra_compile_args=extra_compile_args) cls._use_inline = True except (weave.build_tools.CompileError, distutils.errors.CompileError, ImportError, ValueError) as e: if not cls._check_compiler_error(e, 'weave'): raise
def __init__(self, solver, values_to_sample, objective_function, observable): self._model = solver.model self._logger = get_logger(__name__, model=self._model) self._logger.info('%s created for observable %s' % ( self.__class__.__name__, observable)) generate_equations(self._model) self._ic_params_of_interest_cache = None self._values_to_sample = values_to_sample if solver is None or not isinstance(solver, pysb.simulator.base.Simulator): raise(TypeError, "solver must be a pysb.simulator object") self._solver = solver self.objective_function = objective_function self.observable = observable # Outputs self.b_matrix = [] self.b_prime_matrix = [] self.p_prime_matrix = np.zeros(self._size_of_matrix) self.p_matrix = np.zeros(self._size_of_matrix) self._original_initial_conditions = np.zeros(len(self._model.species)) self._index_of_species_of_interest = self._create_index_of_species() self.simulation_initials = self._setup_simulations() # Stores the objective function value for the original unperturbed # model self._objective_fn_standard = None
def __init__(self, model=None, verbose=False, cleanup=False, output_prefix=None, output_dir=None, model_additional_species=None, model_population_maps=None): self._logger = get_logger(__name__, model=model, log_level=verbose) self._base_file_stem = 'pysb' self.cleanup = cleanup self.output_prefix = 'tmpBNG' if output_prefix is None else \ output_prefix if model: self.generator = BngGenerator( model, additional_initials=model_additional_species, population_maps=model_population_maps ) self.model = self.generator.model self._check_model() else: self.generator = None self.model = None self.base_directory = tempfile.mkdtemp(prefix=self.output_prefix, dir=output_dir) self._logger.debug('{} instantiated in directory {}'.format( self.__class__, self.base_directory) )
def __init__(self, model=None, verbose=False, cleanup=False, output_prefix=None, output_dir=None, model_additional_species=None, model_population_maps=None): self._logger = get_logger(__name__, model=model, log_level=verbose) self._base_file_stem = 'pysb' self.cleanup = cleanup self.output_prefix = 'tmpBNG' if output_prefix is None else \ output_prefix if model: self.generator = BngGenerator( model, additional_initials=model_additional_species, population_maps=model_population_maps) self.model = self.generator.model self._check_model() else: self.generator = None self.model = None self.base_directory = tempfile.mkdtemp(prefix=self.output_prefix, dir=output_dir) self._logger.debug('{} instantiated in directory {}'.format( self.__class__, self.base_directory))
def model_from_biomodels(accession_no, force=False, cleanup=True, **kwargs): """ Create a PySB Model based on a BioModels SBML model Downloads file from BioModels (https://www.ebi.ac.uk/biomodels-main/) and runs it through :func:`model_from_sbml`. See that function for further details on additional arguments and implementation details. Utilizes BioNetGen's SBMLTranslator. Notes ----- Read the `sbmlTranslator documentation <http://bionetgen.org/index.php/SBML2BNGL>`_ for further information on sbmlTranslator's limitations. Parameters ---------- accession_no : str A BioModels accession number - the string 'BIOMD' followed by 10 digits, e.g. 'BIOMD0000000001'. For brevity, just the last digits will be accepted as a string, e.g. '1' is equivalent the accession number in the previous sentence. force : bool, optional The default, False, will raise an Exception if there are any errors importing the model to PySB, e.g. due to unsupported features. Setting to True will attempt to ignore any import errors, which may lead to a model that only poorly represents the original. Use at own risk! cleanup : bool Delete temporary directory on completion if True. Set to False for debugging purposes. **kwargs: kwargs Keyword arguments to pass on to :func:`sbml_translator` Examples -------- >>> from pysb.importers.sbml import model_from_biomodels >>> model = model_from_biomodels('1') >>> print(model) #doctest: +ELLIPSIS <Model 'pysb' (monomers: 12, rules: 17, parameters: 37, expressions: 0, ... """ logger = get_logger(__name__, log_level=kwargs.get('verbose')) if not BIOMODELS_REGEX.match(accession_no): try: accession_no = 'BIOMD{:010d}'.format(int(accession_no)) except ValueError: raise ValueError('accession_no must be an integer or a BioModels ' 'accession number (BIOMDxxxxxxxxxx)') logger.info('Importing model {} to PySB'.format(accession_no)) filename, headers = urlretrieve(BIOMODELS_URL.format(accession_no)) try: return model_from_sbml(filename, force=force, cleanup=cleanup, **kwargs) finally: try: os.remove(filename) except OSError: pass
def __init__(self, solver, values_to_sample, objective_function, observable): self._model = solver.model self._logger = get_logger(__name__, model=self._model) self._logger.info('%s created for observable %s' % (self.__class__.__name__, observable)) generate_equations(self._model) self._ic_params_of_interest_cache = None self._values_to_sample = values_to_sample if solver is None or not isinstance(solver, pysb.simulator.base.Simulator): raise (TypeError, "solver must be a pysb.simulator object") self._solver = solver self.objective_function = objective_function self.observable = observable # Outputs self.b_matrix = [] self.b_prime_matrix = [] self.p_prime_matrix = np.zeros(self._size_of_matrix) self.p_matrix = np.zeros(self._size_of_matrix) self._original_initial_conditions = np.zeros(len(self._model.species)) self._index_of_species_of_interest = self._create_index_of_species() self.simulation_initials = self._setup_simulations() # Stores the objective function value for the original unperturbed # model self._objective_fn_standard = None
def _test_cython(cls): if not hasattr(cls, '_use_cython'): cls._use_cython = False if Cython is None: return try: Cython.inline('x = 1', force=True, quiet=True) cls._use_cython = True except Cython.Compiler.Errors.CompileError: pass except ValueError as e: if len(e.args) == 1 and e.args[0] == "Symbol table not found": get_logger(__name__).debug( "'ValueError: Symbol table not found' " "encountered; Cython compiler is not functional") else: raise
def __init__(self, solver, values_to_sample, objective_function, observable, sens_type='initials', sample_list=None): if not isinstance(solver, pysb.simulator.base.Simulator): raise TypeError("solver must be a pysb.simulator object") self._model = solver.model self._logger = get_logger(__name__, model=self._model) self._logger.info('%s created for observable %s' % (self.__class__.__name__, observable)) generate_equations(self._model) self._values_to_sample = values_to_sample self._solver = solver self.objective_function = objective_function self._observable = observable self._sens_type = sens_type if self._sens_type not in ('params', 'initials', 'all'): if sample_list is None: raise ValueError("Please provide 'sens_type' or 'sample_list'") if sample_list is not None: _valid_options = [i.name for i in self._model.parameters] for i in sample_list: if i not in _valid_options: raise ValueError("{} not in model.parameters".format(i)) self.index = sample_list elif self._sens_type == 'params': self.index = [i.name for i in self._model.parameters_rules()] elif self._sens_type == 'initials': self.index = [i[1].name for i in self._model.initial_conditions] elif self._sens_type == 'all': self.index = [i.name for i in self._model.parameters] self.orig_vals = [i.value for i in self._model.parameters] self.index_of_param = { i.name: n for n, i in enumerate(self._model.parameters) } self._n_sam = len(self._values_to_sample) self._n_species = len(self.index) self._nm = self._n_species * self._n_sam self._size_of_matrix = self._nm**2 self._shape_of_matrix = self._nm, self._nm # Outputs self.b_matrix = [] self.b_prime_matrix = [] self.params_to_run = self._setup_simulations() self.p_prime_matrix = np.zeros(self._size_of_matrix) self.p_matrix = np.zeros(self._size_of_matrix) # Stores the objective function value for the original unperturbed # model self._objective_fn_standard = None
def _check_compiler_error(e, compiler): if isinstance(e, distutils.errors.DistutilsPlatformError) and \ str(e) != 'Unable to find vcvarsall.bat': return False if isinstance(e, ValueError) and e.args != ('Symbol table not found',): return False # Build platform-specific C compiler error message message = 'Please check you have a functional C compiler' if os.name == 'nt': message += ', available from ' \ 'https://wiki.python.org/moin/WindowsCompilers' else: message += '.' get_logger(__name__).warn( '{} compiler appears non-functional. {}\n' 'Original error: {}'.format(compiler, message, repr(e))) return True
def _check_compiler_error(e, compiler): if isinstance(e, distutils.errors.DistutilsPlatformError) and \ str(e) != 'Unable to find vcvarsall.bat': return False if isinstance(e, ValueError) and e.args != ('Symbol table not found', ): return False # Build platform-specific C compiler error message message = 'Please check you have a functional C compiler' if os.name == 'nt': message += ', available from ' \ 'https://wiki.python.org/moin/WindowsCompilers' else: message += '.' get_logger(__name__).warn('{} compiler appears non-functional. {}\n' 'Original error: {}'.format( compiler, message, repr(e))) return True
def model_from_sbml(filename, force=False, cleanup=True, **kwargs): """ Create a PySB Model object from an Systems Biology Markup Language (SBML) file, using BioNetGen's `sbmlTranslator <http://bionetgen.org/index.php/SBML2BNGL>`_, which can attempt to extrapolate higher-level (rule-based) structure from an SBML source file (argument atomize=True). The model is first converted into BioNetGen language by sbmlTranslator, then PySB's :class:`BnglBuilder` class converts the BioNetGen language model into a PySB Model. Notes ----- Requires the sbmlTranslator program (also known at Atomizer). If PySB was installed using "conda", you can install sbmlTranslator using "conda install -c alubbock atomizer". It is bundled with BioNetGen if BNG is installed by manual download and unzip. Read the `sbmlTranslator documentation <http://bionetgen.org/index.php/SBML2BNGL>`_ for further information on sbmlTranslator's limitations. Parameters ---------- filename : A Systems Biology Markup Language .sbml file force : bool, optional The default, False, will raise an Exception if there are any errors importing the model to PySB, e.g. due to unsupported features. Setting to True will attempt to ignore any import errors, which may lead to a model that only poorly represents the original. Use at own risk! cleanup : bool Delete temporary directory on completion if True. Set to False for debugging purposes. **kwargs: kwargs Keyword arguments to pass on to :func:`sbml_translator` """ logger = get_logger(__name__, log_level=kwargs.get('verbose')) tmpdir = tempfile.mkdtemp() logger.debug("Performing SBML to BNGL translation in temporary " "directory %s" % tmpdir) try: bngl_file = os.path.join(tmpdir, 'model.bngl') sbml_translator(filename, bngl_file, **kwargs) return model_from_bngl(bngl_file, force=force, cleanup=cleanup) finally: if cleanup: shutil.rmtree(tmpdir)
def __init__(self, model, tspan=None, initials=None, param_values=None, verbose=False, **kwargs): # Get or create base a PySB logger for this module and model self._logger = get_logger(self.__module__, model=model, log_level=verbose) self._logger.debug('Simulator created') self._model = model self.verbose = verbose self.tout = None # Per-run initial conditions/parameter/tspan override self.tspan = tspan self._initials = None self.initials = initials self._params = None self.param_values = param_values
def __init__(self, solver, values_to_sample, objective_function, observable, sens_type='initials', sample_list=None): if not isinstance(solver, pysb.simulator.base.Simulator): raise TypeError("solver must be a pysb.simulator object") self._model = solver.model self._logger = get_logger(__name__, model=self._model) self._logger.info('%s created for observable %s' % ( self.__class__.__name__, observable)) generate_equations(self._model) self._values_to_sample = values_to_sample self._solver = solver self.objective_function = objective_function self._observable = observable self._sens_type = sens_type if self._sens_type not in ('params', 'initials', 'all'): if sample_list is None: raise ValueError("Please provide 'sens_type' or 'sample_list'") if sample_list is not None: _valid_options = [i.name for i in self._model.parameters] for i in sample_list: if i not in _valid_options: raise ValueError("{} not in model.parameters".format(i)) self.index = sample_list elif self._sens_type == 'params': self.index = [i.name for i in self._model.parameters_rules()] elif self._sens_type == 'initials': self.index = [i[1].name for i in self._model.initial_conditions] elif self._sens_type == 'all': self.index = [i.name for i in self._model.parameters] self.orig_vals = [i.value for i in self._model.parameters] self.index_of_param = {i.name: n for n, i in enumerate(self._model.parameters)} self._n_sam = len(self._values_to_sample) self._n_species = len(self.index) self._nm = self._n_species * self._n_sam self._size_of_matrix = self._nm ** 2 self._shape_of_matrix = self._nm, self._nm # Outputs self.b_matrix = [] self.b_prime_matrix = [] self.params_to_run = self._setup_simulations() self.p_prime_matrix = np.zeros(self._size_of_matrix) self.p_matrix = np.zeros(self._size_of_matrix) # Stores the objective function value for the original unperturbed # model self._objective_fn_standard = None
def _patch_distutils_logging(base_logger): """Patch distutils logging functionality with logging.Logger calls. The value of the 'base_logger' argument should be a logging.Logger instance, and its effective level will be passed on to the patched distutils loggers. distutils.log contains its own internal PEP 282 style logging system that sends messages straight to stdout/stderr, and numpy.distutils.log extends that. This code patches all of this with calls to logging.LoggerAdapter instances, and disables the module-level threshold-setting functions so we can retain full control over the threshold. Also all WARNING messages are "downgraded" to INFO to suppress excessive use of WARNING-level logging in numpy.distutils. """ logger = get_logger(__name__) logger.debug('patching distutils and numpy.distutils logging') logger_methods = 'log', 'debug', 'info', 'warn', 'error', 'fatal' other_functions = 'set_threshold', 'set_verbosity' saved_symbols = {} for module_name in 'distutils.log', 'numpy.distutils.log': new_logger = _DistutilsProxyLoggerAdapter( base_logger, {'module': module_name} ) module = importlib.import_module(module_name) # Save the old values. for name in logger_methods + other_functions: saved_symbols[module, name] = getattr(module, name) # Replace logging functions with bound methods of the Logger object. for name in logger_methods: setattr(module, name, getattr(new_logger, name)) # Replace threshold-setting functions with no-ops. for name in other_functions: setattr(module, name, lambda *args, **kwargs: None) try: yield finally: logger.debug('restoring distutils and numpy.distutils logging') # Restore everything we overwrote. for (module, name), value in saved_symbols.items(): setattr(module, name, value)
def sbml_translator(input_file, output_file=None, convention_file=None, naming_conventions=None, user_structures=None, molecule_id=False, atomize=False, pathway_commons=False, verbose=False): """ Run the BioNetGen sbmlTranslator binary to convert SBML to BNGL This function runs the external program sbmlTranslator, included with BioNetGen, which converts SBML files to BioNetGen language (BNGL). Generally, PySB users don't need to run this function directly; an SBML model can be imported to PySB in a single step with :func:`model_from_sbml`. However, users may wish to note the parameters for this function, which alter the way the SBML file is processed. These parameters can be supplied as ``**kwargs`` to :func:`model_from_sbml`. For more detailed descriptions of the arguments, see the `sbmlTranslator documentation <http://bionetgen.org/index.php/SBML2BNGL>`_. Parameters ---------- input_file : string SBML input filename output_file : string, optional BNGL output filename convention_file : string, optional Conventions filename naming_conventions : string, optional Naming conventions filename user_structures : string, optional User structures filename molecule_id : bool, optional Use SBML molecule IDs (True) or names (False). IDs are less descriptive but more BNGL friendly. Use only if the generated BNGL has syntactic errors atomize : bool, optional Atomize the model, i.e. attempt to infer molecular structure and build rules from the model (True) or just perform a flat import (False) pathway_commons : bool, optional Use pathway commons to infer molecule binding. This setting requires an internet connection and will query the pathway commons web service. verbose : bool or int, optional (default: False) Sets the verbosity level of the logger. See the logging levels and constants from Python's logging module for interpretation of integer values. False leaves the logging verbosity unchanged, True is equal to DEBUG. Returns ------- string BNGL output filename """ logger = get_logger(__name__, log_level=verbose) sbmltrans_bin = os.path.join(os.path.dirname(pf.get_path('bng')), 'bin/sbmlTranslator') sbmltrans_args = [sbmltrans_bin, '-i', input_file] if output_file is None: output_file = os.path.splitext(input_file)[0] + '.bngl' sbmltrans_args.extend(['-o', output_file]) if convention_file: sbmltrans_args.extend(['-c', convention_file]) if naming_conventions: sbmltrans_args.extend(['-n', naming_conventions]) if user_structures: sbmltrans_args.extend(['-u', user_structures]) if molecule_id: sbmltrans_args.append('-id') if atomize: sbmltrans_args.append('-a') if pathway_commons: sbmltrans_args.append('-p') logger.debug("sbmlTranslator command: " + " ".join(sbmltrans_args)) p = subprocess.Popen(sbmltrans_args, cwd=os.getcwd(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) if logger.getEffectiveLevel() <= EXTENDED_DEBUG: output = "\n".join([line for line in iter(p.stdout.readline, b'')]) if output: logger.log(EXTENDED_DEBUG, "sbmlTranslator output:\n\n" + output) (p_out, p_err) = p.communicate() if p.returncode: raise SbmlTranslationError(p_out.decode('utf-8') + "\n" + p_err.decode('utf-8')) return output_file
def __setstate__(self, state): state["_logger"] = PySBModelLoggerAdapter(get_logger(self.__module__), state["_logger_extra"]) del state["_logger_extra"] self.__dict__.update(state)
from nose.tools import assert_raises_regexp, raises import warnings import mock import tempfile import shutil from pysb.logging import get_logger # Some models don't match BNG originals exactly due to loss of numerical # precision. REDUCED_PRECISION = { 'CaOscillate_Func': 1e-4, 'michment': 1e-8, 'motor': 1e-8 } logger = get_logger(__name__) def bngl_import_compare_simulations(bng_file, force=False, precision=1e-12, sim_times=range(0, 100, 10)): """ Test BNGL file import by running an ODE simulation on the imported model and on the BNGL file directly to compare trajectories. """ m = model_from_bngl(bng_file, force=force) # Simulate using the BNGL file directly with BngFileInterface(model=None) as bng: bng.action('readFile', file=bng_file, skip_actions=1) bng.action('generate_network')
import tempfile import shutil from pysb.logging import get_logger # Some models don't match BNG originals exactly due to loss of numerical # precision. See https://github.com/pysb/pysb/issues/443 REDUCED_PRECISION = { 'CaOscillate_Func': 1e-4, 'michment': 1e-8, 'motor': 1e-8, 'fceri_ji': 1e-4, 'test_paramname': 1e-4, 'tlmr': 1e-4 } logger = get_logger(__name__) def bngl_import_compare_simulations(bng_file, force=False, precision=1e-12, sim_times=range(0, 100, 10)): """ Test BNGL file import by running an ODE simulation on the imported model and on the BNGL file directly to compare trajectories. """ m = model_from_bngl(bng_file, force=force) if sim_times is None: # Skip simulation check return
from pysb.logging import get_logger import logging # Nosetests adds its own logging handler - console_output=False avoids # duplication get_logger(level=logging.DEBUG, console_output=False)