Skip to content

Commit

Permalink
Fixing a couple of minor bugs and added new variable class (#35)
Browse files Browse the repository at this point in the history
Thank you @remidhum 

* FIX: fixed the apply_directionality function

solution.raw dataframe index does not contain the fwd and bwd use variables.

* ENH: added new binary variable class

This class is usefull to deal with inactive reactions in a model.

* ENH: deal with models without an objective function

Objective function is set to Zero (symbol("0") does not work!) if there is no defined objective function

* OOPS: change proper function ...

* FIX: fixed the failing test

As suggested, I added a check to determine what object type is passed.

* MNT: solution object type testing improved
  • Loading branch information
remidhum authored and psalvy committed Nov 14, 2019
1 parent 9724094 commit 686a6a2
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 16 deletions.
22 changes: 16 additions & 6 deletions pytfa/analysis/manipulation.py
@@ -1,3 +1,6 @@
from ..core.model import Solution
import pandas as pd

def apply_reaction_variability(tmodel, va, inplace = True):
"""
Applies the VA results as bounds for the reactions of a cobra_model
Expand Down Expand Up @@ -46,7 +49,7 @@ def apply_generic_variability(tmodel,va, inplace = True):
return _tmodel


def apply_directionality(tmodel,solution, inplace = True):
def apply_directionality(tmodel, solution, inplace = True):
"""
Takes a flux solution and transfers its reaction directionality as
constraints for the cobra_model
Expand All @@ -62,15 +65,22 @@ def apply_directionality(tmodel,solution, inplace = True):
else:
_tmodel = tmodel.copy()

if isinstance(solution, Solution):
sol = solution.raw
elif isinstance(solution, pd.Series) or isinstance(solution, pd.DataFrame):
sol = solution
else:
raise ArgumentError('solution object should be of class Solution or pandas.Series')

for this_reaction in _tmodel.reactions:

backward_use = _tmodel.backward_use_variable.get_by_id(this_reaction.id)
forward_use = _tmodel.forward_use_variable.get_by_id(this_reaction.id)

backward_use.variable.lb = round(solution.raw[backward_use.name])
backward_use.variable.ub = round(solution.raw[backward_use.name])
backward_use.variable.lb = round(sol[backward_use.name])
backward_use.variable.ub = round(sol[backward_use.name])

forward_use.variable.lb = round(solution.raw[forward_use.name])
forward_use.variable.ub = round(solution.raw[forward_use.name])
forward_use.variable.lb = round(sol[forward_use.name])
forward_use.variable.ub = round(sol[forward_use.name])

return _tmodel
return _tmodel
11 changes: 7 additions & 4 deletions pytfa/io/dict.py
Expand Up @@ -22,6 +22,8 @@

from copy import copy

import sympy


def get_all_subclasses(cls):
all_subclasses = []
Expand Down Expand Up @@ -371,8 +373,11 @@ def model_from_dict(obj, solver=None, custom_hooks = None):
return new

def rebuild_obj_from_dict(new, objective_dict):
obj_expr = symbol_sum([v*new.variables.get(x) for x,v in objective_dict.items()])
new.objective = obj_expr
if objective_dict.__class__ is dict:
obj_expr = symbol_sum([v*new.variables.get(x) for x,v in objective_dict.items()])
new.objective = obj_expr
else:
new.objective = sympy.S.Zero

def add_custom_classes(model, custom_hooks):
"""
Expand Down Expand Up @@ -446,5 +451,3 @@ def _rebuild_stoichiometry(new, stoich):
return defaultdict(int,
{new.metabolites.get_by_id(k):v
for k,v in stoich.items()})


24 changes: 18 additions & 6 deletions pytfa/optim/variables.py
Expand Up @@ -454,7 +454,6 @@ def model(self):

prefix = 'MV_'


class ForwardUseVariable(ReactionVariable, BinaryVariable):
"""
Class to represent a forward use variable, a type of binary variable used to
Expand Down Expand Up @@ -486,6 +485,24 @@ def __init__(self, reaction, **kwargs):

prefix = 'BU_'

class ForwardBackwardUseVariable(ReactionVariable, BinaryVariable):
"""
Class to represent a type of binary variable used to tell whether the
reaction is active or not such that:
FU + BU + BFUSE = 1
"""

def __init__(self, reaction, **kwargs):
if not 'lb' in kwargs:
kwargs['lb'] = 0
if not 'ub' in kwargs:
kwargs['ub'] = 1

ReactionVariable.__init__(self, reaction,
type=get_binary_type(),
**kwargs)

prefix = 'BFUSE_'

class LogConcentration(MetaboliteVariable):
"""
Expand All @@ -494,23 +511,20 @@ class LogConcentration(MetaboliteVariable):

prefix = 'LC_'


class DeltaGErr(ReactionVariable):
"""
Class to represent a DeltaGErr
"""

prefix = 'DGE_'


class DeltaG(ReactionVariable):
"""
Class to represent a DeltaG
"""

prefix = 'DG_'


class DeltaGstd(ReactionVariable):
"""
Class to represent a DeltaG^o (naught) - standard conditions
Expand All @@ -536,7 +550,6 @@ def __init__(self,reaction,**kwargs):

prefix = 'PosSlack_'


class NegSlackVariable(ReactionVariable):
"""
Class to represent a negative slack variable for relaxation problems
Expand All @@ -554,4 +567,3 @@ class PosSlackLC(MetaboliteVariable):
class NegSlackLC(MetaboliteVariable):

prefix = 'NegSlackLC_'

0 comments on commit 686a6a2

Please sign in to comment.