Skip to content

Commit

Permalink
Added possibility to have initial state >1 for integrate() and bifurc…
Browse files Browse the repository at this point in the history
…ation(). For multiagent() and SSA() the widgets are still limited to the sum of 1.

This fixes #318 #317
  • Loading branch information
Andreagiovanni Reina committed Sep 27, 2019
1 parent f1d090b commit 7c6a869
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 58 deletions.
1 change: 1 addition & 0 deletions mumot/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,7 @@ def __init__(self, controllers, params=None, initWidgets=None, **kwargs):
controller._view._chooseXrange = kwargs.get('choose_xrange')
if key == 'initialState':
ep1 = views_[0]._mumotModel._getAllReactants()
ep2 = [react for react in views_[0]._mumotModel._getAllReactants()[0] if react not in views_[0]._mumotModel._reactants][0] if views_[0]._mumotModel._systemSize is not None else None
# @todo assuming same model for all views.
# This operation is NOT correct when multicotroller views have different models.
if key == 'visualisationType':
Expand Down
31 changes: 21 additions & 10 deletions mumot/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,11 +804,13 @@ def integrate(self, showStateVars=None, initWidgets=None, **kwargs):

IntParams = {}
# read input parameters
IntParams['substitutedReactant'] = [[react for react in self._getAllReactants()[0] if react not in self._reactants][0] if self._systemSize is not None else None, True]
IntParams['initialState'] = utils._format_advanced_option(
optionName='initialState',
inputValue=kwargs.get('initialState'),
initValues=initWidgets.get('initialState'),
extraParam=self._getAllReactants())
extraParam=self._getAllReactants(),
extraParam2 = IntParams['substitutedReactant'][0] )
IntParams['maxTime'] = utils._format_advanced_option(
optionName='maxTime',
inputValue=kwargs.get('maxTime'),
Expand All @@ -818,7 +820,6 @@ def integrate(self, showStateVars=None, initWidgets=None, **kwargs):
inputValue=kwargs.get('plotProportions'),
initValues=initWidgets.get('plotProportions'))
IntParams['conserved'] = [kwargs.get('conserved', False), True]
IntParams['substitutedReactant'] = [[react for react in self._getAllReactants()[0] if react not in self._reactants][0] if self._systemSize is not None else None, True]

# construct controller
viewController = controllers.MuMoTtimeEvolutionController(
Expand Down Expand Up @@ -919,17 +920,18 @@ def noiseCorrelations(self, initWidgets=None, **kwargs):

NCParams = {}
# read input parameters
NCParams['substitutedReactant'] = [[react for react in self._getAllReactants()[0] if react not in self._reactants][0] if self._systemSize is not None else None, True]
NCParams['initialState'] = utils._format_advanced_option(
optionName='initialState',
inputValue=kwargs.get('initialState'),
initValues=initWidgets.get('initialState'),
extraParam=self._getAllReactants())
extraParam=self._getAllReactants(),
extraParam2=NCParams['substitutedReactant'][0])
NCParams['maxTime'] = utils._format_advanced_option(
optionName='maxTime',
inputValue=kwargs.get('maxTime'),
initValues=initWidgets.get('maxTime'))
NCParams['conserved'] = [kwargs.get('conserved', False), True]
NCParams['substitutedReactant'] = [[react for react in self._getAllReactants()[0] if react not in self._reactants][0] if self._systemSize is not None else None, True]

EQsys1stOrdMom, EOM_1stOrderMom, NoiseSubs1stOrder, EQsys2ndOrdMom, EOM_2ndOrderMom, NoiseSubs2ndOrder = \
_getNoiseEOM(_getFokkerPlanckEquation, _get_orderedLists_vKE, self._stoichiometry)
Expand Down Expand Up @@ -1370,14 +1372,15 @@ def bifurcation(self, bifurcationParameter, stateVariable1,
optionName='initBifParam',
inputValue=kwargs.get('initBifParam'),
initValues=initWidgets.get('initBifParam'))
BfcParams['substitutedReactant'] = [[react for react in self._getAllReactants()[0] if react not in self._reactants][0] if self._systemSize is not None else None, True]
BfcParams['initialState'] = utils._format_advanced_option(
optionName='initialState',
inputValue=kwargs.get('initialState'),
initValues=initWidgets.get('initialState'),
extraParam=self._getAllReactants())
extraParam=self._getAllReactants(),
extraParam2=BfcParams['substitutedReactant'][0])
BfcParams['bifurcationParameter'] = [bifPar, True]
BfcParams['conserved'] = [conserved, True]
BfcParams['substitutedReactant'] = [[react for react in self._getAllReactants()[0] if react not in self._reactants][0] if self._systemSize is not None else None, True]

# construct controller
viewController = controllers.MuMoTbifurcationController(
Expand Down Expand Up @@ -1464,12 +1467,16 @@ def multiagent(self, initWidgets=None, **kwargs):

MAParams = {}
# Read input parameters
MAParams['substitutedReactant'] = [[react for react in self._getAllReactants()[0] if react not in self._reactants][0] if self._systemSize is not None else None, True]
# next line forces the multiagent() view to have the sum of the initial states to 1. If this wants to be changed, remember to change also the callback function of the widgets _updateInitialStateWidgets in controllers.py
if MAParams['substitutedReactant'][0] is None:
MAParams['substitutedReactant'][0] = sorted(self._getAllReactants()[0], key=str)[0]
MAParams['initialState'] = utils._format_advanced_option(
optionName='initialState',
inputValue=kwargs.get('initialState'),
initValues=initWidgets.get('initialState'),
extraParam=self._getAllReactants())
MAParams['substitutedReactant'] = [[react for react in self._getAllReactants()[0] if react not in self._reactants][0] if self._systemSize is not None else None, True]
extraParam=self._getAllReactants(),
extraParam2=MAParams['substitutedReactant'][0])
MAParams['maxTime'] = utils._format_advanced_option(
optionName='maxTime',
inputValue=kwargs.get('maxTime'),
Expand Down Expand Up @@ -1622,12 +1629,16 @@ def SSA(self, initWidgets=None, **kwargs):

ssaParams = {}
# Read input parameters
ssaParams['substitutedReactant'] = [[react for react in self._getAllReactants()[0] if react not in self._reactants][0] if self._systemSize is not None else None, True]
# next line forces the SSA() view to have the sum of the initial states to 1. If this wants to be changed, remember to change also the callback function of the widgets _updateInitialStateWidgets in controllers.py
if ssaParams['substitutedReactant'][0] is None:
ssaParams['substitutedReactant'][0] = sorted(self._getAllReactants()[0], key=str)[0]
ssaParams['initialState'] = utils._format_advanced_option(
optionName='initialState',
inputValue=kwargs.get('initialState'),
initValues=initWidgets.get('initialState'),
extraParam=self._getAllReactants())
ssaParams['substitutedReactant'] = [[react for react in self._getAllReactants()[0] if react not in self._reactants][0] if self._systemSize is not None else None, True]
extraParam=self._getAllReactants(),
extraParam2=ssaParams['substitutedReactant'][0])
ssaParams['maxTime'] = utils._format_advanced_option(
optionName='maxTime',
inputValue=kwargs.get('maxTime'),
Expand Down
106 changes: 58 additions & 48 deletions mumot/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,12 @@ def _format_advanced_option(optionName: str, inputValue, initValues, extraParam=
"""
if optionName == 'initialState':
(allReactants, _) = extraParam
fixSumTo1 = extraParam2 is not None
idleReactant = extraParam2 #if extraParam2 is not None else sorted(allReactants, key=str)[0]
initialState = {}
# handle initialState dictionary (either convert or generate a default one)
if inputValue is not None:
for i, reactant in enumerate(sorted(inputValue.keys(), key=str)):
for reactant in sorted(inputValue.keys(), key=str):
pop = inputValue[reactant]
initPop = initValues.get(reactant) if initValues is not None else None

Expand All @@ -116,14 +118,14 @@ def _format_advanced_option(optionName: str, inputValue, initValues, extraParam=
defaults.MuMoTdefault._agentsLimits[1],
defaults.MuMoTdefault._agentsStep],
initValueRangeStep=initPop,
validRange=(0.0, 1.0))
validRange=(0.0, 1.0) if fixSumTo1 else (0, float("inf")))
fixedBool = True
else:
first = True
initValuesSympy = ({parse_latex(reactant): pop
for reactant, pop in initValues.items()}
if initValues is not None else {})
for i, reactant in enumerate(sorted(allReactants, key=str)):
for reactant in sorted(allReactants, key=str):
defaultV = defaults.MuMoTdefault._agents if first else 0
first = False
initialState[reactant] = _parse_input_keyword_for_numeric_widgets(
Expand All @@ -133,54 +135,62 @@ def _format_advanced_option(optionName: str, inputValue, initValues, extraParam=
defaults.MuMoTdefault._agentsLimits[1],
defaults.MuMoTdefault._agentsStep],
initValueRangeStep=initValuesSympy.get(reactant),
validRange=(0.0, 1.0))
validRange=(0.0, 1.0) if fixSumTo1 else (0, float("inf")))
fixedBool = False

# Check if the initialState values are valid
sumValues = sum([initialState[reactant][0] for reactant in allReactants])
minStep = min([initialState[reactant][3] for reactant in allReactants])
for i, reactant in enumerate(sorted(allReactants, key=str)):
if reactant not in allReactants:
error_msg = (f"Reactant '{reactant}' does not exist in this model.\n"
f"Valid reactants are {allReactants}. Please, correct the value and retry.")
raise exceptions.MuMoTValueError(error_msg)

pop = initialState[reactant]
# check if the proportions sum to 1
if i == 0:
idleReactant = reactant
idleValue = pop[0]
# the idleValue have range min-max reset to [0,1]
initialState[reactant][1] = 0
initialState[reactant][2] = 1
initialState[reactant][3] = minStep
else:
# modify (if necessary) the initial value
if sumValues > 1:
new_val = max(0, pop[0] + (1 - sumValues))
if not _almostEqual(pop[0], new_val):
wrn_msg = f"WARNING! the initial value of reactant {reactant} has been changed to {new_val}\n"
raise exceptions.MuMoTWarning(wrn_msg)
sumValues -= pop[0]
sumValues += new_val
initialState[reactant][0] = new_val
# modify (if necessary) min-max
pop = initialState[reactant]
sumNorm = sumValues if sumValues <= 1 else 1
if pop[2] > (1 - sumNorm + pop[0] + idleValue): # max
if pop[1] > (1 - sumNorm + pop[0] + idleValue): # min
initialState[reactant][1] = (1 - sumNorm + pop[0] + idleValue)
initialState[reactant][2] = (1 - sumNorm + pop[0] + idleValue)
if pop[1] > (1 - sumNorm + pop[0]): # min
initialState[reactant][1] = (1 - sumNorm + pop[0])
# initialState[reactant][3] = minStep
if not _almostEqual(sumValues, 1):
new_val = 1 - sum([initialState[reactant][0]
for reactant in allReactants
if reactant != idleReactant])
wrn_msg = f"WARNING! the initial value of reactant {idleReactant} has been changed to {new_val}\n"
raise exceptions.MuMoTWarning(wrn_msg)
initialState[idleReactant][0] = new_val
if fixSumTo1:
sumValues = sum([initialState[reactant][0] for reactant in allReactants])
minStep = min([initialState[reactant][3] for reactant in allReactants])

# first thing setting the values of the idleReactant
idleValue = initialState[idleReactant][0]
if idleValue > 1:
wrn_msg = f"WARNING! the initial value of reactant {idleReactant} has been changed to {new_val}\n"
print(wrn_msg)
#raise exceptions.MuMoTWarning(wrn_msg)
initialState[idleReactant][0] = new_val
# the idleValue have range min-max reset to [0,1]
initialState[idleReactant][1] = 0
initialState[idleReactant][2] = 1
initialState[idleReactant][3] = minStep
for reactant in sorted(allReactants, key=str):
if reactant not in allReactants:
error_msg = (f"Reactant '{reactant}' does not exist in this model.\n"
f"Valid reactants are {allReactants}. Please, correct the value and retry.")
raise exceptions.MuMoTValueError(error_msg)

# check if the proportions sum to 1
if reactant != idleReactant:
pop = initialState[reactant]
# modify (if necessary) the initial value
if sumValues > 1:
new_val = max(0, pop[0] + (1 - sumValues))
if not _almostEqual(pop[0], new_val):
wrn_msg = f"WARNING! the initial value of reactant {reactant} has been changed to {new_val}\n"
print(wrn_msg)
#raise exceptions.MuMoTWarning(wrn_msg)
sumValues -= pop[0]
sumValues += new_val
initialState[reactant][0] = new_val
# modify (if necessary) min-max
pop = initialState[reactant]
sumNorm = sumValues if sumValues <= 1 else 1
if pop[2] > (1 - sumNorm + pop[0] + idleValue): # max
if pop[1] > (1 - sumNorm + pop[0] + idleValue): # min
initialState[reactant][1] = (1 - sumNorm + pop[0] + idleValue)
initialState[reactant][2] = (1 - sumNorm + pop[0] + idleValue)
if pop[1] > (1 - sumNorm + pop[0]): # min
initialState[reactant][1] = (1 - sumNorm + pop[0])
# initialState[reactant][3] = minStep
if not _almostEqual(sumValues, 1):
new_val = 1 - sum([initialState[reactant][0]
for reactant in allReactants
if reactant != idleReactant])
wrn_msg = f"WARNING! the initial value of reactant {idleReactant} has been changed to {new_val}\n"
print(wrn_msg)
#raise exceptions.MuMoTWarning(wrn_msg)
initialState[idleReactant][0] = new_val
return [initialState, fixedBool]
# print("Initial State is " + str(initialState))
if optionName == 'maxTime':
Expand Down

0 comments on commit 7c6a869

Please sign in to comment.