sys-bio / roadrunner

libRoadRunner: A high-performance SBML simulator
http://libroadrunner.org/
Other
39 stars 25 forks source link

getScaledFluxControlCoefficientMatrix fails with division by zero #251

Closed 0u812 closed 3 years ago

0u812 commented 8 years ago

Via Matthias.

0u812 commented 8 years ago

demo_mca.py


# coding: utf-8

# # Variability analysis
# 
# An important tool in analyzing the behavior of computational models is analyzing the sensitivity of results to parameter changes. Metabolic Control Analysis (MCA) provides tools for analyzing the effects of such changes on the steady state of the model.

# In[54]:

from __future__ import print_function, division
# get_ipython().magic(u'matplotlib inline')

import roadrunner
import numpy as np
import pandas as pd
from pandas import DataFrame
import matplotlib.pylab as plt

# We are interested in the effects of parameters for a given simulation scenario. The analysed scenario is simple simulation to steady state.

# In[55]:

# from multiscale.examples.testdata import demo_filepath
demo_filepath="demo_v02.xml"

# equidistant timecourse
roadrunner.Config.setValue(roadrunner.Config.LOADSBMLOPTIONS_CONSERVED_MOIETIES, True)
rr = roadrunner.RoadRunner(demo_filepath)
s = rr.simulate(0,40, 100, plot=True)  

for sid, value in zip(rr.model.getFloatingSpeciesIds(), rr.model.getFloatingSpeciesConcentrations()):
    print('{} = {}'.format(sid, value))

# In[56]:

# Steady States
# Performs a steady state calculation (evolves the system to a steady
#        state), then calculates and returns the set of values specified by
#        the steady state selections.
print(rr.selections)
print(rr.getSteadyStateValues())

# ## Metabolic Control Analysis (MCA)
# 
# Metabolic control analysis (MCA) is a mathematical framework for describing metabolic, signaling, and genetic pathways. MCA quantifies how variables, such as fluxes and species concentrations, depend on network parameters. In particular it is able to describe how network dependent properties, called control coefficients, depend on local properties called elasticities [http://en.wikipedia.org/wiki/Metabolic_control_analysis].
# 
# ### Control Coefficients
# 
# A control coefficient measures the relative steady state change in a system variable, e.g. pathway flux (J) or metabolite concentration (S), in response to a relative change in a parameter, e.g. enzyme activity or the steady-state rate ( v_i ) of step i. The two main control coefficients are the flux and concentration control coefficients. Flux control coefficients are defined by:
# 
# $$C^J_{v_i} = \left( \frac{dJ}{dp} \frac{p}{J} \right) \bigg/ \left( \frac{\partial v_i}{\partial p}\frac{p}{v_i} \right) = \frac{d\ln J}{d\ln v_i}$$

# In[57]:

# Scaled control coefficient with respect to a global parameter.
rr.getCC('bA', 'Vmax_bA')

# In[58]:

# The n by n matrix of scaled flux control coefficients 
# where n is the number of reactions.
print('** Scaled Flux Control Coefficients **')
rr.getScaledFluxControlCoefficientMatrix()
C_J = DataFrame(rr.getScaledFluxControlCoefficientMatrix(),                 index=rr.model.getReactionIds(),                 columns=rr.model.getReactionIds())
print(C_J)

# and concentration control coefficients by:
# 
# $$C^S_{v_i} = \left( \frac{dS}{dp} \frac{p}{S} \right) \bigg/ \left( \frac{\partial v_i}{\partial p} \frac{p}{v_i} \right) = \frac{d\ln S}{d\ln v_i}$$

# In[59]:

# The m by n matrix of scaled concentration control coefficients where m is the number
# of floating species and n the number of reactions.
print('** Scaled Concentration Control Coefficients **')
C_S = DataFrame(rr.getScaledConcentrationControlCoefficientMatrix(),                 index=rr.model.getFloatingSpeciesIds(),                 columns=rr.model.getReactionIds())
print(C_S)

# ### Summation Theorems
# 
# The flux control summation theorem was discovered independently by the Kacser/Burns group and the Heinrich/Rapoport group in the early 1970s and late 1960s. The flux control summation theorem implies that metabolic fluxes are systemic properties and that their control is shared by all reactions in the system. When a single reaction changes its control of the flux this is compensated by changes in the control of the same flux by all other reactions.
# 
# $$\sum_i C^J_{v_i} = 1$$
# 
# $$\sum_i C^S_{v_i} = 0$$

# In[60]:

# Flux control coefficients have to sum to 1
print(np.sum(C_J, axis=1))
abs(np.sum(C_J, axis=1)-1) < 1E-6

# In[61]:

# Concentration control coefficients have to sum to 0
print(np.sum(C_S, axis=1))
np.sum(C_S, axis=1) < 1E-6

# ### Elasticity coefficients
# Retrieve a single elasticity coefficient with respect to a global parameter.
# 
#         For example::
# 
#           x = rr.getEE ('J1', 'Vmax')

# In[62]:

print(rr.model.getGlobalParameterIds())
print(rr.getEE('v1', 'Vmax_v1'))
print(rr.getEE('v1', 'Keq_v1'))
0u812 commented 8 years ago

demo_v02.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created by libAntimony version v2.7.0 on 2015-05-18 10:03 with libSBML version 5.11.4. -->
<sbml xmlns="http://www.sbml.org/sbml/level3/version1/core" xmlns:comp="http://www.sbml.org/sbml/level3/version1/comp/version1" level="3" version="1" comp:required="true">
  <model id="Koenig_demo_v02" name="Koenig_demo_v02" substanceUnits="substance" timeUnits="time_unit" volumeUnits="volume" areaUnits="area" lengthUnits="length" extentUnits="extent">
    <listOfUnitDefinitions>
      <unitDefinition id="mM">
        <listOfUnits>
          <unit kind="mole" exponent="1" scale="0" multiplier="1"/>
          <unit kind="metre" exponent="-3" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="m3">
        <listOfUnits>
          <unit kind="metre" exponent="3" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="m2">
        <listOfUnits>
          <unit kind="metre" exponent="2" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="mole_per_s">
        <listOfUnits>
          <unit kind="mole" exponent="1" scale="0" multiplier="1"/>
          <unit kind="second" exponent="-1" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="substance">
        <listOfUnits>
          <unit kind="mole" exponent="1" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="volume">
        <listOfUnits>
          <unit kind="metre" exponent="3" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="area">
        <listOfUnits>
          <unit kind="metre" exponent="2" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="length">
        <listOfUnits>
          <unit kind="metre" exponent="1" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="extent">
        <listOfUnits>
          <unit kind="mole" exponent="1" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
      <unitDefinition id="time_unit">
        <listOfUnits>
          <unit kind="second" exponent="1" scale="0" multiplier="1"/>
        </listOfUnits>
      </unitDefinition>
    </listOfUnitDefinitions>
    <listOfCompartments>
      <compartment id="extern" name="External Compartment" spatialDimensions="3" size="1e-06" units="m3" constant="true"/>
      <compartment id="cell" name="Cell Compartment" spatialDimensions="3" size="1e-06" units="m3" constant="true"/>
      <compartment id="membrane" name="Cell Membrane" spatialDimensions="3" size="1" units="m2" constant="true"/>
    </listOfCompartments>
    <listOfSpecies>
      <species id="A" name="A cell" compartment="cell" initialConcentration="0" substanceUnits="mole" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
      <species id="B" name="B cell" compartment="cell" initialConcentration="0" substanceUnits="mole" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
      <species id="C" name="C cell" compartment="cell" initialConcentration="0" substanceUnits="mole" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
      <species id="A_ext" name="A extern" compartment="extern" initialConcentration="10" substanceUnits="mole" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
      <species id="B_ext" name="B extern" compartment="extern" initialConcentration="0" substanceUnits="mole" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
      <species id="C_ext" name="C extern" compartment="extern" initialConcentration="0" substanceUnits="mole" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="false"/>
    </listOfSpecies>
    <listOfParameters>
      <parameter id="scale_f" value="1e-06" units="dimensionless" constant="true"/>
      <parameter id="Vmax_bA" value="5" units="mole_per_s" constant="true"/>
      <parameter id="Km_A" value="1" units="mM" constant="true"/>
      <parameter id="Vmax_bB" value="2" units="mole_per_s" constant="true"/>
      <parameter id="Km_B" value="0.5" units="mM" constant="true"/>
      <parameter id="Vmax_bC" value="2" units="mole_per_s" constant="true"/>
      <parameter id="Km_C" value="3" units="mM" constant="true"/>
      <parameter id="Vmax_v1" value="1" units="mole_per_s" constant="true"/>
      <parameter id="Keq_v1" value="10" units="dimensionless" constant="true"/>
      <parameter id="Vmax_v2" value="0.5" units="mole_per_s" constant="true"/>
      <parameter id="Vmax_v3" value="0.5" units="mole_per_s" constant="true"/>
      <parameter id="Vmax_v4" value="0.5" units="mole_per_s" constant="true"/>
      <parameter id="Keq_v4" value="2" units="dimensionless" constant="true"/>
    </listOfParameters>
    <listOfReactions>
      <reaction id="bA" name="A import" reversible="false" fast="false" compartment="membrane">
        <listOfReactants>
          <speciesReference species="A_ext" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
          <speciesReference species="A" stoichiometry="1" constant="true"/>
        </listOfProducts>
        <kineticLaw>
          <math xmlns="http://www.w3.org/1998/Math/MathML" xmlns:sbml="http://www.sbml.org/sbml/level3/version1/core">
            <apply>
              <divide/>
              <apply>
                <times/>
                <ci> scale_f </ci>
                <apply>
                  <divide/>
                  <ci> Vmax_bA </ci>
                  <ci> Km_A </ci>
                </apply>
                <apply>
                  <minus/>
                  <ci> A_ext </ci>
                  <ci> A </ci>
                </apply>
              </apply>
              <apply>
                <plus/>
                <cn sbml:units="dimensionless" type="integer"> 1 </cn>
                <apply>
                  <divide/>
                  <ci> A_ext </ci>
                  <ci> Km_A </ci>
                </apply>
                <apply>
                  <divide/>
                  <ci> A </ci>
                  <ci> Km_A </ci>
                </apply>
              </apply>
            </apply>
          </math>
        </kineticLaw>
      </reaction>
      <reaction id="bB" name="B export" reversible="false" fast="false" compartment="membrane">
        <listOfReactants>
          <speciesReference species="B" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
          <speciesReference species="B_ext" stoichiometry="1" constant="true"/>
        </listOfProducts>
        <kineticLaw>
          <math xmlns="http://www.w3.org/1998/Math/MathML" xmlns:sbml="http://www.sbml.org/sbml/level3/version1/core">
            <apply>
              <divide/>
              <apply>
                <times/>
                <ci> scale_f </ci>
                <apply>
                  <divide/>
                  <ci> Vmax_bB </ci>
                  <ci> Km_B </ci>
                </apply>
                <apply>
                  <minus/>
                  <ci> B </ci>
                  <ci> B_ext </ci>
                </apply>
              </apply>
              <apply>
                <plus/>
                <cn sbml:units="dimensionless" type="integer"> 1 </cn>
                <apply>
                  <divide/>
                  <ci> B_ext </ci>
                  <ci> Km_B </ci>
                </apply>
                <apply>
                  <divide/>
                  <ci> B </ci>
                  <ci> Km_B </ci>
                </apply>
              </apply>
            </apply>
          </math>
        </kineticLaw>
      </reaction>
      <reaction id="bC" name="C export" reversible="false" fast="false" compartment="membrane">
        <listOfReactants>
          <speciesReference species="C" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
          <speciesReference species="C_ext" stoichiometry="1" constant="true"/>
        </listOfProducts>
        <kineticLaw>
          <math xmlns="http://www.w3.org/1998/Math/MathML" xmlns:sbml="http://www.sbml.org/sbml/level3/version1/core">
            <apply>
              <divide/>
              <apply>
                <times/>
                <ci> scale_f </ci>
                <apply>
                  <divide/>
                  <ci> Vmax_bC </ci>
                  <ci> Km_C </ci>
                </apply>
                <apply>
                  <minus/>
                  <ci> C </ci>
                  <ci> C_ext </ci>
                </apply>
              </apply>
              <apply>
                <plus/>
                <cn sbml:units="dimensionless" type="integer"> 1 </cn>
                <apply>
                  <divide/>
                  <ci> C_ext </ci>
                  <ci> Km_C </ci>
                </apply>
                <apply>
                  <divide/>
                  <ci> C </ci>
                  <ci> Km_C </ci>
                </apply>
              </apply>
            </apply>
          </math>
        </kineticLaw>
      </reaction>
      <reaction id="v1" name="A -&gt; B" reversible="true" fast="false" compartment="cell">
        <listOfReactants>
          <speciesReference species="A" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
          <speciesReference species="B" stoichiometry="1" constant="true"/>
        </listOfProducts>
        <kineticLaw>
          <math xmlns="http://www.w3.org/1998/Math/MathML" xmlns:sbml="http://www.sbml.org/sbml/level3/version1/core">
            <apply>
              <times/>
              <apply>
                <divide/>
                <apply>
                  <times/>
                  <ci> scale_f </ci>
                  <ci> Vmax_v1 </ci>
                </apply>
                <ci> Km_A </ci>
              </apply>
              <apply>
                <minus/>
                <ci> A </ci>
                <apply>
                  <times/>
                  <apply>
                    <divide/>
                    <cn sbml:units="dimensionless" type="integer"> 1 </cn>
                    <ci> Keq_v1 </ci>
                  </apply>
                  <ci> B </ci>
                </apply>
              </apply>
            </apply>
          </math>
        </kineticLaw>
      </reaction>
      <reaction id="v2" name="A -&gt; C" reversible="true" fast="false" compartment="cell">
        <listOfReactants>
          <speciesReference species="A" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
          <speciesReference species="C" stoichiometry="1" constant="true"/>
        </listOfProducts>
        <kineticLaw>
          <math xmlns="http://www.w3.org/1998/Math/MathML">
            <apply>
              <times/>
              <apply>
                <divide/>
                <apply>
                  <times/>
                  <ci> scale_f </ci>
                  <ci> Vmax_v2 </ci>
                </apply>
                <ci> Km_A </ci>
              </apply>
              <ci> A </ci>
            </apply>
          </math>
        </kineticLaw>
      </reaction>
      <reaction id="v3" name="C -&gt; A" reversible="true" fast="false" compartment="cell">
        <listOfReactants>
          <speciesReference species="C" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
          <speciesReference species="A" stoichiometry="1" constant="true"/>
        </listOfProducts>
        <kineticLaw>
          <math xmlns="http://www.w3.org/1998/Math/MathML">
            <apply>
              <times/>
              <apply>
                <divide/>
                <apply>
                  <times/>
                  <ci> scale_f </ci>
                  <ci> Vmax_v3 </ci>
                </apply>
                <ci> Km_A </ci>
              </apply>
              <ci> C </ci>
            </apply>
          </math>
        </kineticLaw>
      </reaction>
      <reaction id="v4" name="C -&gt; B" reversible="true" fast="false" compartment="cell">
        <listOfReactants>
          <speciesReference species="C" stoichiometry="1" constant="true"/>
        </listOfReactants>
        <listOfProducts>
          <speciesReference species="B" stoichiometry="1" constant="true"/>
        </listOfProducts>
        <kineticLaw>
          <math xmlns="http://www.w3.org/1998/Math/MathML" xmlns:sbml="http://www.sbml.org/sbml/level3/version1/core">
            <apply>
              <times/>
              <apply>
                <divide/>
                <apply>
                  <times/>
                  <ci> scale_f </ci>
                  <ci> Vmax_v4 </ci>
                </apply>
                <ci> Km_A </ci>
              </apply>
              <apply>
                <minus/>
                <ci> C </ci>
                <apply>
                  <times/>
                  <apply>
                    <divide/>
                    <cn sbml:units="dimensionless" type="integer"> 1 </cn>
                    <ci> Keq_v4 </ci>
                  </apply>
                  <ci> B </ci>
                </apply>
              </apply>
            </apply>
          </math>
        </kineticLaw>
      </reaction>
    </listOfReactions>
  </model>
</sbml>
hsauro commented 7 years ago

Investigate what this is all about 15 Feb 2017

evilnose commented 4 years ago

The reason seems to be that getScaledFluxControlCoefficientMatrix() divides each element of the unscaled matrix by a reaction rate, but one of the reaction rates is zero, i.e.

double irate = 0;
impl->model->getReactionRates(1, &i, &irate);
if(irate !=0)
{
   double jrate = 0;
   impl->model->getReactionRates(1, &j, &jrate);
   ufcc[i][j] = ufcc[i][j] * jrate / irate;  // <----- possible division by zero here
}
else
{
   throw(Exception("Dividing with zero"));  // <---- actual error thrown here
}

One of the reactions bB has a rate of zero, since its rate is proportional to B - B_ext, which is zero. Is it the expected behavior to fail here? I'm not sure if the correct scaling is done.

On a related note, getCC('bB', 'Vmax_bB') returns NaN, since it tries to divide getuCC('bB', 'Vmax_bB') by the amount of bB, but both values are zero. I think if we were to throw a division-by-zero error, we should probably do it for all similar functions?

hsauro commented 4 years ago

Yes, it should throw a division by zero, it there also anyway for it to report the bad reaction that has a rate of zero?

Herbert

On Wed, Jul 22, 2020 at 10:59 AM Gary Geng notifications@github.com wrote:

The reason seems to be that getScaledFluxControlCoefficientMatrix() divides each element of the unscaled matrix by a reaction rate, but one of the reaction rates is zero, i.e.

double irate = 0; impl->model->getReactionRates(1, &i, &irate);if(irate !=0) { double jrate = 0; impl->model->getReactionRates(1, &j, &jrate); ufcc[i][j] = ufcc[i][j] * jrate / irate; // <----- possible division by zero here }else { throw(Exception("Dividing with zero")); // <---- actual error thrown here }

One of the reactions bB has a rate of zero, since its rate is proportional to B - B_ext, which is zero. Is it the expected behavior to fail here? I'm not sure if the correct scaling is done.

On a related note, getCC('bB', 'Vmax_bB') returns NaN, since it tries to divide getuCC('bB', 'Vmax_bB') by the amount of bB, but both values are zero. I think if we were to throw a division-by-zero error, we should probably do it for all similar functions?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/sys-bio/roadrunner/issues/251#issuecomment-662599575, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIBSDVGUW4SOZ27GSVPYX3R44SGBANCNFSM4BYJ5PZA .

-- Herbert Sauro, Professor University of Washington, Bioengineering 206-685-2119, www.sys-bio.org hsauro@uw.edu Books: http://books.analogmachine.org/

evilnose commented 4 years ago

Yes, I can get the ID of the reaction and display it. Should I do the same for getCC() for when the amount of the variable is 0?

hsauro commented 4 years ago

Yes that would be useful.

H

On Wed, Jul 22, 2020 at 1:03 PM Gary Geng notifications@github.com wrote:

Yes, I can get the ID of the reaction and display it. Should I do the same for getCC() for when the amount of the variable is 0?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/sys-bio/roadrunner/issues/251#issuecomment-662666631, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIBSDSPEASYSL6SX56XS5DR45AUFANCNFSM4BYJ5PZA .

-- Herbert Sauro, Professor University of Washington, Bioengineering 206-685-2119, www.sys-bio.org hsauro@uw.edu Books: http://books.analogmachine.org/