Differences between revisions 1 and 7 (spanning 6 versions)
Revision 1 as of 2022-04-29 14:55:30
Size: 7854
Editor: mark
Comment:
Revision 7 as of 2022-04-29 15:43:16
Size: 8384
Editor: yanica
Comment:
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:
Once again, start [[https://mudshark.brookes.ac.uk/ScrumPy|ScrumPy]] as described in the [[http://mudshark.brookes.ac.uk/Meetings/C1netWork4/ScrumPyInstall#GettingStarted|installation instructions]]. Once again, start ScrumPy as described in the [[http://mudshark.brookes.ac.uk/Meetings/C1netWork4/ScrumPyInstall#GettingStarted|installation instructions]].
Line 5: Line 5:
 . A pre-existing model is loaded by creating an instance of a model object {{{ScrumPy.Model(model)}}} with {{{model}}} being the name of the file (string-type ending with the {{{ScrumPy}}} file extension, {{{.spy}}},  all enclosed in quotes) containing the description of the model,  provided that the file is stored in the directory from where ScrumPy was  launched. If no name is provided, a GUI for selecting a model to open,  is launched.  . A pre-existing model is loaded by creating an instance of a model object {{{ScrumPy.Model(model)}}} with {{{model}}} being the name of the file (string-type ending with the {{{ScrumPy}}} file extension, {{{.spy}}}, all enclosed in quotes) containing the description of the model, provided that the file is stored in the directory from where !ScrumPy was launched. If no name is provided, a GUI for selecting a model to open, is launched.
Line 7: Line 7:
[[https://mudshark.brookes.ac.uk/Meetings/Nepal2018/Prac3#|Toggle line numbers]] {{{#!python
>>> m = ScrumPy.Model('toy_model.spy')
}}}
 . If this file has not yet been created, the instruction will open a new empty editor window. Copy and paste the model description below. Having done that, select "compile" from the !ScrumPy menu in the editor, and the model is loaded. {{{toy_model.spy}}} is the small structural model described by:
Line 9: Line 12:
{{{
}}}
 . If this file has not yet been created, the instruction will open a new empty editor window. Copy and paste the model description below. Having done that, select "compile" from the ScrumPy menu in the editor, and the model is loaded. {{{toy_model.spy}}} is the small structural model described by:

{{{
Structural()
{{{#!python
Structural() # tells ScrumPy not to bother with kinetics
Line 50: Line 49:
 . Having  edited the model, before you can do any further analysis, you must tell  ScrumPy to update the model internally by clicking the !ScrumPy/Compile menu option. This will also save the model, and as  long as you have made no errors in entering it, you will see no further  messages. You will be informed of any errors in a pop-up window, which  will tell you where the error was first detected (not always the same  as where the error is).  . Having edited the model, before you can do any further analysis, you must tell !ScrumPy  to update the model internally by clicking the !ScrumPy/Compile menu option. This will also save the model, and as long as you have made no errors in entering it, you will see no further messages. You will be informed of any errors in a pop-up window, which will tell you where the error was first detected (not always the same as where the error is).
Line 53: Line 52:
 . The class {{{Model}}}  has a range of methods, of which some are only useful for kinetic  models (which are also structural models, but the opposite is not true).  The methods are actions on the model object ({{{m}}} in this case), and are invoked by instructions such as {{{ x = m.Method()}}}, where the outcome is a new data object {{{x}}} that contains the result. Among the structurally relevant methods we find {{{ConsMoieties()}}} - which returns a list of conserved moieties; {{{DeadReactions()}}} - which returns a list of reactions that cannot carry steady state flux; {{{FindIsoforms()}}} - which identifies reactions from the model that are redundant, i.e. a set of reactions that have identical stoichiometry; {{{ElModes()}}} - which returns an elementary modes object; {{{Externals()}}} - which returns a list of external metabolites.  . The class {{{Model}}} has a range of methods, of which some are only useful for kinetic models (which are also structural models, but the opposite is not true). The methods are actions on the model object ({{{m}}} in this case), and are invoked by instructions such as {{{ x = m.Method()}}}, where the outcome is a new data object {{{x}}} that contains the result. Among the structurally relevant methods we find {{{ConsMoieties()}}} - which returns a list of conserved moieties; {{{DeadReactions()}}} - which returns a list of reactions that cannot carry steady state flux; {{{FindIsoforms()}}} - which identifies reactions from the model that are redundant, i.e. a set of reactions that have identical stoichiometry; {{{ElModes()}}} - which returns an elementary modes object; {{{Externals()}}} - which returns a list of external metabolites.
Line 56: Line 55:
 . The fields {{{Model.sm}}} and {{{Model.smx}}}  are the two stoichiometry matrices associated with a model - the  former is the internal matrix, the latter the external. The external  matrix contains infomation about external metabolites, whereas the  internal does not. All instances of {{{ScrumPy}}} matrices (subclasses of {{{DynMatrix}}}) have the fields {{{cnames}}} - column names and {{{rnames}}} - row names. Note that these are both [[https://mudshark.brookes.ac.uk/Meetings/C1netWork4/Prac2#List|lists]], and can be examined as such.  . The fields {{{Model.sm}}} and {{{Model.smx}}} are the two stoichiometry matrices associated with a model - the former is the internal matrix, the latter the external. The external matrix contains infomation about external metabolites, whereas the internal does not. All instances of {{{ScrumPy}}} matrices (subclasses of {{{DynMatrix}}}) have the fields {{{cnames}}} - column names and {{{rnames}}} - row names. Note that these are both [[Meetings/C1netWork4/Prac2#List|lists]], and can be examined as such.
Line 58: Line 57:
[[https://mudshark.brookes.ac.uk/Meetings/Nepal2018/Prac3#|Toggle line numbers]]

{{{
{{{#!python
>>> m.sm.cnames
['R_1', 'R_2', 'R_3', 'R_4', 'R_5', 'R_6', 'E_tx', 'A_tx']
>>> m.sm.rnames #but m.smx.rnames will be longer
['D', 'E', 'A', 'F', 'C', 'B']
Line 64: Line 65:
[[https://mudshark.brookes.ac.uk/Meetings/Nepal2018/Prac3#|Toggle line numbers]]

{{{
{{{#!python
>>> print (m.sm.ReacToStr('R_2'))
R_2:
 1 B -> 1 C
 ~
Line 70: Line 73:
[[https://mudshark.brookes.ac.uk/Meetings/Nepal2018/Prac3#|Toggle line numbers]]

{{{
{{{#!python
>>> m.sm.InvolvedWith('R_2')
{'C': mpq(1,1), 'B': mpq(-1,1)}
>>> m.sm.InvolvedWith('C')
{'R_2': mpq(1,1), 'R_3': mpq(-1,1)}
Line 74: Line 79:
 . Here,  'mpq(1,1)' is the stoichiometric coefficient for C, which for  technical reasons is represented in the model object as an arbitrary  precision rational number, i.e., 1/1 = 1, and as it is positive, C is a  product. The coefficient for B is -1/1 = -1; it is a substrate of the  reaction because its coefficient is negative.  . Here, 'mpq(1,1)' is the stoichiometric coefficient for C, which for technical reasons is represented in the model object as an arbitrary precision rational number, i.e., 1/1 = 1, and as it is positive, C is a product. The coefficient for B is -1/1 = -1; it is a substrate of the reaction because its coefficient is negative.
Line 79: Line 84:
[[https://mudshark.brookes.ac.uk/Meetings/Nepal2018/Prac3#|Toggle line numbers]] {{{#!python
>>> k = m.sm.NullSpace()
>>> k
    c_0 c_1
Line 81: Line 89:
{{{  R_1 -1/1 0/1
 R_2 -1/1 1/1
 R_3 -1/1 1/1
 R_4 0/1 -1/1
 R_5 0/1 -1/1
 R_6 0/1 0/1
 E_tx -1/1 0/1
 A_tx -1/1 0/1
Line 83: Line 98:
 . Even  if the signs of some of the coefficients indicate thermodynamically  infeasible solutions (e.g. all active reactions in the first column  have negative coefficients, even though they are irreversible) a lot of  useful information can be obtained form {{{k}}}. For instance, we see that the row associated with {{{R_6}}} is a null-vector, indicating that there is no steady-state solution involving {{{R_6}}}. In fact this is how {{{ScrumPy}}} detects '''''dead reactions''''' with the method {{{DeadReactions()}}}.  . Even if the signs of some of the coefficients indicate thermodynamically infeasible solutions (e.g. all active reactions in the first column have negative coefficients, even though they are irreversible) a lot of useful information can be obtained form {{{k}}}. For instance, we see that the row associated with {{{R_6}}} is a null-vector, indicating that there is no steady-state solution involving {{{R_6}}}. In fact this is how {{{ScrumPy}}} detects '''''dead reactions''''' with the method {{{DeadReactions()}}}.
Line 85: Line 100:
[[https://mudshark.brookes.ac.uk/Meetings/Nepal2018/Prac3#|Toggle line numbers]]

{{{
{{{#!python
>>> m.DeadReactions()
['R_6']
Line 90: Line 105:
 . Also, note that some of the row-vectors are proportional to each other - {{{R_2}}}, {{{R_3}}}; {{{R_4}}}, {{{R_5}}}; and {{{E_tx}}}, {{{A_tx}}}, {{{R_1}}}. This implies that these sets must carry flux in a coordinated fashion, e.g. any flux solution involving {{{R_4}}} must also involve {{{R_5}}}. These sets of coordinated reactions are referred to as '''''enzyme subsets''''' and can be determined using the {{{Model}}} method {{{EnzSubsets()}}}.  This method returns a dictionary object where keys are subset names  (or reaction name if a reaction is in a singleton set) and values are  nested dictionaries where keys are reaction names and values are the  flux ratios of the reactions. The key {{{DeadReacs}}} maps to a list of dead reactions.  . Also, note that some of the row-vectors are proportional to each other - {{{R_2}}}, {{{R_3}}}; {{{R_4}}}, {{{R_5}}}; and {{{E_tx}}}, {{{A_tx}}}, {{{R_1}}}. This implies that these sets must carry flux in a coordinated fashion, e.g. any flux solution involving {{{R_4}}} must also involve {{{R_5}}}. These sets of coordinated reactions are referred to as '''''enzyme subsets''''' and can be determined using the {{{Model}}} method {{{EnzSubsets()}}}. This method returns a dictionary object where keys are subset names (or reaction name if a reaction is in a singleton set) and values are nested dictionaries where keys are reaction names and values are the flux ratios of the reactions. The key {{{DeadReacs}}} maps to a list of dead reactions.
Line 92: Line 107:
[[https://mudshark.brookes.ac.uk/Meetings/Nepal2018/Prac3#|Toggle line numbers]]

{{{
{{{#!python
>>> ess=m.EnzSubsets()
>>> ess
{'Ess_3': {'R_4': mpq(-1,1), 'R_5': mpq(-1,1)}, 'Ess_2': {'R_2': mpq(1,1), 'R_3': mpq(1,1)}, 'Ess_1': {'E_tx': mpq(1,1), 'R_1': mpq(1,1), 'A_tx': mpq(1,1)}, 'DeadReacs': {'R_6': mpq(1,1)}}
Line 99: Line 115:
[[https://mudshark.brookes.ac.uk/Meetings/Nepal2018/Prac3#|Toggle line numbers]] {{{#!python
>>> elmo = m.ElModes()
>>> elmo.mo
    ElMo_0 ElMo_1
Line 101: Line 120:
{{{  R_1 1/1 1/1
 R_2 1/1 0/1
 R_3 1/1 0/1
 R_4 0/1 1/1
 R_5 0/1 1/1
 R_6 0/1 0/1
 E_tx 1/1 1/1
 A_tx 1/1 1/1
Line 105: Line 131:
[[https://mudshark.brookes.ac.uk/Meetings/Nepal2018/Prac3#|Toggle line numbers]] {{{#!python
>>> elmo.sto
    ElMo_0 ElMo_1
Line 107: Line 135:
{{{  x_A -1/1 -1/1
 A 0/1 0/1
 B 0/1 0/1
 C 0/1 0/1
 E 0/1 0/1
 D 0/1 0/1
 F 0/1 0/1
 x_E 1/1 1/1
Line 111: Line 146:
[[https://mudshark.brookes.ac.uk/Meetings/Nepal2018/Prac3#|Toggle line numbers]] {{{#!python
>>> print (elmo.Modes())
ElMo_0, 1/1 E_tx, 1/1 R_1, 1/1 R_2, 1/1 R_3, 1/1 A_tx
Line 113: Line 150:
{{{ ElMo_1, 1/1 E_tx, 1/1 R_1, 1/1 A_tx, 1/1 R_4, 1/1 R_5

>>> print (elmo.Stos())
ElMo_0:
        1/1 x_A -> 1/1 x_E
        ~
ElMo_1:
        1/1 x_A -> 1/1 x_E
        ~
Line 124: Line 169:
 . More details and explanation of how [[https://mudshark.brookes.ac.uk/ScrumPy|ScrumPy]] works can be found in the [[https://mudshark.brookes.ac.uk/ScrumPy/Doc|documentation]], sections 2 and 3.  . More details and explanation of how ScrumPy works can be found in the [[ScrumPy/Doc|documentation]], sections 2 and 3.

Practical 3: Models and their Structural Analysis

Once again, start ScrumPy as described in the installation instructions.

Loading and defining models

  • A pre-existing model is loaded by creating an instance of a model object ScrumPy.Model(model) with model being the name of the file (string-type ending with the ScrumPy file extension, .spy, all enclosed in quotes) containing the description of the model, provided that the file is stored in the directory from where ScrumPy was launched. If no name is provided, a GUI for selecting a model to open, is launched.

   1 >>> m = ScrumPy.Model('toy_model.spy')
  • If this file has not yet been created, the instruction will open a new empty editor window. Copy and paste the model description below. Having done that, select "compile" from the ScrumPy menu in the editor, and the model is loaded. toy_model.spy is the small structural model described by:

   1 Structural() # tells ScrumPy not to bother with kinetics
   2 
   3 A_tx:
   4     x_A -> A
   5     ~
   6 
   7 R_1:
   8     A -> B
   9     ~
  10 
  11 R_2:
  12     B -> C
  13     ~
  14 
  15 R_3:
  16     C -> E
  17     ~
  18 
  19 R_4:
  20     B -> D
  21     ~
  22 
  23 R_5:
  24     D -> E
  25     ~
  26 
  27 R_6:
  28     D -> F
  29     ~
  30 
  31 E_tx:
  32     E -> x_E
  33     ~
  • The reactions with the suffix "_tx" are transporters, i.e. they convert external metabolites (with prefix "x_"), which can be consumed or produced, to internal metabolites, which have no net consumption or production at steady state.

  • Take a piece of paper and draw this reaction scheme as a metabolic pathway.
  • Having edited the model, before you can do any further analysis, you must tell ScrumPy to update the model internally by clicking the !ScrumPy/Compile menu option. This will also save the model, and as long as you have made no errors in entering it, you will see no further messages. You will be informed of any errors in a pop-up window, which will tell you where the error was first detected (not always the same as where the error is).

Properties of structural models

  • The class Model has a range of methods, of which some are only useful for kinetic models (which are also structural models, but the opposite is not true). The methods are actions on the model object (m in this case), and are invoked by instructions such as  x = m.Method(), where the outcome is a new data object x that contains the result. Among the structurally relevant methods we find ConsMoieties() - which returns a list of conserved moieties; DeadReactions() - which returns a list of reactions that cannot carry steady state flux; FindIsoforms() - which identifies reactions from the model that are redundant, i.e. a set of reactions that have identical stoichiometry; ElModes() - which returns an elementary modes object; Externals() - which returns a list of external metabolites.

The stoichiometry matrix

  • The fields Model.sm and Model.smx are the two stoichiometry matrices associated with a model - the former is the internal matrix, the latter the external. The external matrix contains infomation about external metabolites, whereas the internal does not. All instances of ScrumPy matrices (subclasses of DynMatrix) have the fields cnames - column names and rnames - row names. Note that these are both lists, and can be examined as such.

   1 >>> m.sm.cnames
   2 ['R_1', 'R_2', 'R_3', 'R_4', 'R_5', 'R_6', 'E_tx', 'A_tx']
   3 >>> m.sm.rnames                #but m.smx.rnames will be longer
   4 ['D', 'E', 'A', 'F', 'C', 'B']
  • Useful methods of sm (and smx) include ReacToStr(reac),

   1 >>> print (m.sm.ReacToStr('R_2'))
   2 R_2:
   3         1 B -> 1 C
   4         ~
  • and InvolvedWith(name),

   1 >>> m.sm.InvolvedWith('R_2')
   2 {'C': mpq(1,1), 'B': mpq(-1,1)}
   3 >>> m.sm.InvolvedWith('C')
   4 {'R_2': mpq(1,1), 'R_3': mpq(-1,1)}
  • Here, 'mpq(1,1)' is the stoichiometric coefficient for C, which for technical reasons is represented in the model object as an arbitrary precision rational number, i.e., 1/1 = 1, and as it is positive, C is a product. The coefficient for B is -1/1 = -1; it is a substrate of the reaction because its coefficient is negative.

Nullspace analysis

  • The kernel of the stoichiometry matrix can be calculated using the sm.NullSpace() method.

   1 >>> k = m.sm.NullSpace()
   2 >>> k
   3     c_0 c_1
   4 
   5  R_1 -1/1  0/1
   6  R_2 -1/1  1/1
   7  R_3 -1/1  1/1
   8  R_4 0/1  -1/1
   9  R_5 0/1  -1/1
  10  R_6 0/1  0/1
  11  E_tx -1/1  0/1
  12  A_tx -1/1  0/1
  • Even if the signs of some of the coefficients indicate thermodynamically infeasible solutions (e.g. all active reactions in the first column have negative coefficients, even though they are irreversible) a lot of useful information can be obtained form k. For instance, we see that the row associated with R_6 is a null-vector, indicating that there is no steady-state solution involving R_6. In fact this is how ScrumPy detects dead reactions with the method DeadReactions().

   1 >>> m.DeadReactions()
   2 ['R_6']

Enzyme subsets

  • Also, note that some of the row-vectors are proportional to each other - R_2, R_3; R_4, R_5; and E_tx, A_tx, R_1. This implies that these sets must carry flux in a coordinated fashion, e.g. any flux solution involving R_4 must also involve R_5. These sets of coordinated reactions are referred to as enzyme subsets and can be determined using the Model method EnzSubsets(). This method returns a dictionary object where keys are subset names (or reaction name if a reaction is in a singleton set) and values are nested dictionaries where keys are reaction names and values are the flux ratios of the reactions. The key DeadReacs maps to a list of dead reactions.

   1 >>> ess=m.EnzSubsets()
   2 >>> ess
   3 {'Ess_3': {'R_4': mpq(-1,1), 'R_5': mpq(-1,1)}, 'Ess_2': {'R_2': mpq(1,1), 'R_3': mpq(1,1)}, 'Ess_1': {'E_tx': mpq(1,1), 'R_1': mpq(1,1), 'A_tx': mpq(1,1)}, 'DeadReacs': {'R_6': mpq(1,1)}}

Elementary modes

  • The elementary modes of a model can be analysed using the method Model.ElModes(). This method returns an object that collects methods and fields related to the elementary modes of a given model. The member, .mo, is a matrix similar to k.

   1 >>> elmo = m.ElModes()
   2 >>> elmo.mo
   3     ElMo_0 ElMo_1
   4 
   5  R_1 1/1  1/1
   6  R_2 1/1  0/1
   7  R_3 1/1  0/1
   8  R_4 0/1  1/1
   9  R_5 0/1  1/1
  10  R_6 0/1  0/1
  11  E_tx 1/1  1/1
  12  A_tx 1/1  1/1
  • The relationship between modes and metabolites is stored in the sto matrix.

   1 >>> elmo.sto
   2     ElMo_0 ElMo_1
   3 
   4  x_A -1/1  -1/1
   5  A 0/1  0/1
   6  B 0/1  0/1
   7  C 0/1  0/1
   8  E 0/1  0/1
   9  D 0/1  0/1
  10  F 0/1  0/1
  11  x_E 1/1  1/1
  • The methods Modes() and Stos() return strings with with same information as the matrices above.

   1 >>> print (elmo.Modes())
   2 ElMo_0, 1/1 E_tx, 1/1 R_1, 1/1 R_2, 1/1 R_3, 1/1 A_tx
   3 
   4 ElMo_1, 1/1 E_tx, 1/1 R_1, 1/1 A_tx, 1/1 R_4, 1/1 R_5
   5 
   6 >>> print (elmo.Stos())
   7 ElMo_0:
   8         1/1 x_A -> 1/1 x_E
   9         ~
  10 ElMo_1:
  11         1/1 x_A -> 1/1 x_E
  12         ~

Further Properties of the Stoichiometry Matrix and Null-space

  • (a) Generate a kernel of the stoichiometry matrix (using the .NullSpace() method described above).

  • (b) Multiply the stoichiometry matrix by the kernel matrix, using the .Mul() method of the stoichiometry matrix.

  • (c) Repeat the multiplication above using the external stoichiometry matrix instead.

  • (d) Create a kernel of the external stoichiometry matrix - what is different?

  • (e) Multiply the internal and external stoichiometry matrices by your new kernel.

  • (f) Try adding or removing reactions from the model, and repeat the exercises above, explain the new results.

Further information

  • More details and explanation of how ScrumPy works can be found in the documentation, sections 2 and 3.

None: Meetings/Nottingham2022/Prac3 (last edited 2022-05-04 11:42:09 by david)