Skip to content

Commit

Permalink
Merge branch 'pep8' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
jonls committed Jul 1, 2015
2 parents 54ec4d7 + 6d0d33f commit fc54182
Show file tree
Hide file tree
Showing 24 changed files with 318 additions and 222 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ env:
- TOXENV=py27-nosolver
- TOXENV=py34-nosolver
- TOXENV=docs
- TOXENV=flake
2 changes: 1 addition & 1 deletion psamm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#
# Copyright 2014-2015 Jon Lund Steffensen <jon_steffensen@uri.edu>

"""Metabolic networks module"""
"""Metabolic networks module."""

from pkg_resources import get_distribution

Expand Down
48 changes: 30 additions & 18 deletions psamm/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
# Copyright 2014-2015 Jon Lund Steffensen <jon_steffensen@uri.edu>
# Copyright 2015 Keith Dufault-Thompson <keitht547@my.uri.edu>

"""Command line interface
"""Command line interface.
Each command in the command line interface is implemented as a subclass of
:class:`Command`. Commands are automatically discovered based on this
Expand All @@ -38,7 +38,7 @@
import abc

from . import __version__ as package_version
from .formula import Formula, Radical
from .formula import Formula
from .gapfill import gapfind, gapfill
from .database import DictDatabase
from .metabolicmodel import MetabolicModel
Expand Down Expand Up @@ -205,7 +205,8 @@ def open_python(self, message, namespace):
# and related packages at this point when we are certain
# they are needed.
from code import InteractiveConsole
import readline, rlcompleter
import readline
import rlcompleter

readline.set_completer(rlcompleter.Completer(namespace).complete)
readline.parse_and_bind('tab: complete')
Expand Down Expand Up @@ -287,7 +288,8 @@ def run(self):
# Add exchange and transport reactions to database
model_complete = self._mm.copy()
logger.info('Adding database, exchange and transport reactions')
db_added = model_complete.add_all_database_reactions(model_compartments)
db_added = model_complete.add_all_database_reactions(
model_compartments)
ex_added = model_complete.add_all_exchange_reactions()
tp_added = model_complete.add_all_transport_reactions()

Expand Down Expand Up @@ -344,9 +346,10 @@ def run(self):
if self._mm.has_reaction(rxnid):
reaction_class = 'Model'
weight = 0
reaction = model_complete.get_reaction(rxnid).translated_compounds(lambda x: compound_name.get(x, x))
rx = model_complete.get_reaction(rxnid)
rxt = rx.translated_compounds(lambda x: compound_name.get(x, x))
print('{}\t{}\t{}\t{}\t{}'.format(
rxnid, reaction_class, weight, flux, reaction))
rxnid, reaction_class, weight, flux, rxt))

logger.info('Calculating Fastcc consistent subset of induced model')
consistent_core = fastcore.fastcc_consistent_subset(
Expand Down Expand Up @@ -538,15 +541,16 @@ def run(self):

if reaction in inconsistent:
rx = self._mm.get_reaction(reaction)
rxt = rx.translated_compounds(lambda x: compound_name.get(x, x))
rxt = rx.translated_compounds(
lambda x: compound_name.get(x, x))
print('{}\t{}'.format(reaction, rxt))

logger.info('Model has {}/{} inconsistent internal reactions'
' ({} disabled by user)'.format(
count_internal, total_internal, disabled_internal))
count_internal, total_internal, disabled_internal))
logger.info('Model has {}/{} inconsistent exchange reactions'
' ({} disabled by user)'.format(
count_exchange, total_exchange, disabled_exchange))
count_exchange, total_exchange, disabled_exchange))


class FluxVariabilityCommand(SolverCommandMixin, Command):
Expand Down Expand Up @@ -884,11 +888,12 @@ def run(self):
p.solve(reaction)
flux_threshold = p.get_flux(reaction) * threshold

logger.info('Flux threshold for {} is {}'.format(reaction, flux_threshold))
logger.info('Flux threshold for {} is {}'.format(
reaction, flux_threshold))

if self._args.exchange:
model_test = self._mm.copy()
essential = { reaction }
essential = {reaction}
deleted = set()
exchange = set()
for reaction_id in self._mm.reactions:
Expand All @@ -897,7 +902,7 @@ def run(self):
test_set = set(exchange) - essential
else:
model_test = self._mm.copy()
essential = { reaction }
essential = {reaction}
deleted = set()
test_set = set(self._mm.reactions) - essential

Expand All @@ -907,26 +912,32 @@ def run(self):
saved_bounds = model_test.limits[testing_reaction].bounds
model_test.limits[testing_reaction].bounds = 0, 0

logger.info('Trying FBA without reaction {}...'.format(testing_reaction))
logger.info('Trying FBA without reaction {}...'.format(
testing_reaction))

p = fb_problem(model_test, solver)
try:
p.solve(reaction)
except fluxanalysis.FluxBalanceError:
logger.info('FBA is infeasible, marking {} as essential'.format(testing_reaction))
logger.info(
'FBA is infeasible, marking {} as essential'.format(
testing_reaction))
model_test.limits[testing_reaction].bound = saved_bounds
essential.add(testing_reaction)
continue

logger.debug('Reaction {} has flux {}'.format(reaction, p.get_flux(reaction)))
logger.debug('Reaction {} has flux {}'.format(
reaction, p.get_flux(reaction)))

if p.get_flux(reaction) < flux_threshold:
model_test.limits[testing_reaction].bounds = saved_bounds
essential.add(testing_reaction)
logger.info('Reaction {} was essential'.format(testing_reaction))
logger.info('Reaction {} was essential'.format(
testing_reaction))
else:
deleted.add(testing_reaction)
logger.info('Reaction {} was deleted'.format(testing_reaction))

if self._args.exchange:
for reaction_id in sorted(exchange):
value = 0 if reaction_id in deleted else 1
Expand All @@ -936,6 +947,7 @@ def run(self):
value = 0 if reaction_id in deleted else 1
print('{}\t{}'.format(reaction_id, value))


class RobustnessCommand(SolverCommandMixin, Command):
"""Run robustness analysis on metabolic model
Expand Down Expand Up @@ -1115,13 +1127,13 @@ def filter_search_term(s):
compound_synonyms.setdefault(compound.id, []).extend(
compound.properties.get('names', []))

if compound.formula is not None and not '.' in compound.formula:
if compound.formula is not None and '.' not in compound.formula:
compound_formula[compound.id] = Formula.parse(compound.formula)

# Create references from names to id
for compound_id in compound_name.iterkeys():
names = ([compound_name[compound_id]] +
compound_synonyms[compound_id])
compound_synonyms[compound_id])

for n in names:
n = filter_search_term(n)
Expand Down
33 changes: 16 additions & 17 deletions psamm/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#
# Copyright 2014-2015 Jon Lund Steffensen <jon_steffensen@uri.edu>

"""Representation of metabolic network databases"""
"""Representation of metabolic network databases."""

import abc
from collections import defaultdict, Mapping
Expand All @@ -26,7 +26,7 @@


class StoichiometricMatrixView(Mapping):
"""Provides a sparse matrix view on the stoichiometry of a database
"""Provides a sparse matrix view on the stoichiometry of a database.
This object is used internally in the database to expose a sparse matrix
view of the model stoichiometry. This class should not be instantied,
Expand Down Expand Up @@ -67,11 +67,10 @@ def __len__(self):
for reaction in self._database.reactions)

def __array__(self):
"""Return Numpy ndarray instance of matrix
"""Return Numpy ndarray instance of matrix.
The matrix is indexed by sorted compound, reaction-keys
"""

import numpy # NumPy is only required for this method

compound_list = sorted(self._database.compounds)
Expand All @@ -95,32 +94,32 @@ def __array__(self):

@add_metaclass(abc.ABCMeta)
class MetabolicDatabase(object):
"""Database of metabolic reactions"""
"""Database of metabolic reactions."""

@abc.abstractproperty
def reactions(self):
"""Iterator of reactions IDs in the database"""
"""Iterator of reactions IDs in the database."""

@abc.abstractproperty
def compounds(self):
"""Itertor of :class:`Compounds <psamm.reaction.Compound>` in the
database"""
database."""

@abc.abstractproperty
def compartments(self):
"""Iterator of compartment IDs in the database"""
"""Iterator of compartment IDs in the database."""

@abc.abstractmethod
def has_reaction(self, reaction_id):
"""Whether the given reaction exists in the database"""
"""Whether the given reaction exists in the database."""

@abc.abstractmethod
def is_reversible(self, reaction_id):
"""Whether the given reaction is reversible"""
"""Whether the given reaction is reversible."""

@abc.abstractmethod
def get_reaction_values(self, reaction_id):
"""Return an iterator of reaction compounds and stoichiometric values
"""Return an iterator of reaction compounds and stoichiometric values.
The returned iterator contains
(:class:`Compound <psamm.reaction.Compound>`, value)-tuples. The value
Expand All @@ -130,35 +129,35 @@ def get_reaction_values(self, reaction_id):

@abc.abstractmethod
def get_compound_reactions(self, compound_id):
"""Return an iterator of reactions containing the compound
"""Return an iterator of reactions containing the compound.
Reactions are returned as IDs.
"""

@property
def reversible(self):
"""The set of reversible reactions"""
"""The set of reversible reactions."""
return set(reaction_id for reaction_id in self.reactions
if self.is_reversible(reaction_id))

@property
def matrix(self):
"""Mapping from compound, reaction to stoichiometric value
"""Mapping from compound, reaction to stoichiometric value.
This is an instance of :class:`StoichiometricMatrixView`."""
return StoichiometricMatrixView(self)

def get_reaction(self, reaction_id):
"""Return reaction as a :class:`Reaction <psamm.reaction.Reaction>`"""
"""Return reaction as a :class:`Reaction <psamm.reaction.Reaction>`."""

direction = Reaction.Right
if self.is_reversible(reaction_id):
direction = Reaction.Bidir

left = ((compound, -value) for compound, value in
self.get_reaction_values(reaction_id) if value < 0)
self.get_reaction_values(reaction_id) if value < 0)
right = ((compound, value) for compound, value in
self.get_reaction_values(reaction_id) if value > 0)
self.get_reaction_values(reaction_id) if value > 0)

return Reaction(direction, left, right)

Expand Down
5 changes: 3 additions & 2 deletions psamm/datasource/kegg.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#
# Copyright 2014-2015 Jon Lund Steffensen <jon_steffensen@uri.edu>

"""Module related to loading KEGG database files"""
"""Module related to loading KEGG database files."""

import re

Expand Down Expand Up @@ -165,7 +165,8 @@ def parse_compound_list(s):

fields = cpd.strip().split(' ')
if len(fields) > 2:
raise ParseError('Malformed compound specification: {}'.format(cpd))
raise ParseError(
'Malformed compound specification: {}'.format(cpd))
if len(fields) == 1:
count = 1
compound = parse_compound(fields[0])
Expand Down
12 changes: 8 additions & 4 deletions psamm/datasource/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,20 @@
#
# Copyright 2014-2015 Jon Lund Steffensen <jon_steffensen@uri.edu>

"""Miscellaneaus data source functions"""
"""Miscellaneaus data source functions."""

import re
from decimal import Decimal

from psamm.reaction import Reaction, Compound


def parse_sudensimple_reaction(s, arrow_rev='<=>', arrow_irrev='->'):
"""Parse a reaction string (SudenSimple)"""

# Compile pattern for matching reaction arrows
arrow_pattern = re.compile('(' + ('|'.join(re.escape(x) for x in (arrow_irrev, arrow_rev))) + ')')
arrow_pattern = re.compile(
'(' + ('|'.join(re.escape(x) for x in (arrow_irrev, arrow_rev))) + ')')

def parse_compound_list(s):
if s.strip() == '':
Expand Down Expand Up @@ -59,14 +61,16 @@ def parse_compound_list(s):
left, arrow, right = arrow_pattern.split(s, maxsplit=1)
direction = Reaction.Right if arrow == arrow_irrev else Reaction.Bidir

return Reaction(direction, parse_compound_list(left), parse_compound_list(right))
return Reaction(direction, parse_compound_list(left),
parse_compound_list(right))


def parse_metnet_reaction(s, arrow_rev='<==>', arrow_irrev='-->'):
"""Parser for the reaction format in MetNet model"""

# Compile pattern for matching reaction arrows
arrow_pattern = re.compile('(' + ('|'.join(re.escape(x) for x in (arrow_irrev, arrow_rev))) + ')')
arrow_pattern = re.compile(
'(' + ('|'.join(re.escape(x) for x in (arrow_irrev, arrow_rev))) + ')')

def parse_compound_list(s, global_comp):
if s.strip() == '':
Expand Down

0 comments on commit fc54182

Please sign in to comment.