libSBML Python API  5.18.0
createExampleSBML.py

Lengthy example of creating SBML models presented in the SBML specification.

1 #!/usr/bin/env python
2 ##
3 ## @file createExampleSBML.py
4 ## @brief Creates example SBML models presented in the SBML specification.
5 ## @author Akiya Jouraku
6 ## @author Michael Hucka
7 ## @author Sarah Keating
8 ##
9 ## <!--------------------------------------------------------------------------
10 ## This sample program is distributed under a different license than the rest
11 ## of libSBML. This program uses the open-source MIT license, as follows:
12 ##
13 ## Copyright (c) 2013-2018 by the California Institute of Technology
14 ## (California, USA), the European Bioinformatics Institute (EMBL-EBI, UK)
15 ## and the University of Heidelberg (Germany), with support from the National
16 ## Institutes of Health (USA) under grant R01GM070923. All rights reserved.
17 ##
18 ## Permission is hereby granted, free of charge, to any person obtaining a
19 ## copy of this software and associated documentation files (the "Software"),
20 ## to deal in the Software without restriction, including without limitation
21 ## the rights to use, copy, modify, merge, publish, distribute, sublicense,
22 ## and/or sell copies of the Software, and to permit persons to whom the
23 ## Software is furnished to do so, subject to the following conditions:
24 ##
25 ## The above copyright notice and this permission notice shall be included in
26 ## all copies or substantial portions of the Software.
27 ##
28 ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
31 ## THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32 ## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33 ## FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
34 ## DEALINGS IN THE SOFTWARE.
35 ##
36 ## Neither the name of the California Institute of Technology (Caltech), nor
37 ## of the European Bioinformatics Institute (EMBL-EBI), nor of the University
38 ## of Heidelberg, nor the names of any contributors, may be used to endorse
39 ## or promote products derived from this software without specific prior
40 ## written permission.
41 ## ------------------------------------------------------------------------ -->
42 ##
43 
44 
45 import sys
46 import os.path
47 from libsbml import *
48 
49 #
50 # These variables are used in writeExampleSBML when writing an SBML
51 # document. They are handed to libSBML functions in order to include
52 # the program information into comments within the SBML file.
53 #
54 ProgramName = "createExampleModels"
55 ProgramVersion = "1.0.0"
56 
57 #
58 # The SBML Level and Version of the example SBML models.
59 #
60 Level = 2
61 Version = 4
62 
63 
64 # ===============================================================================
65 #
66 #
67 # Functions for creating the Example SBML documents.
68 #
69 #
70 # ===============================================================================
71 
72 
73 #
74 #
75 # Creates an SBML model represented in "7.1 A Simple example application of SBML"
76 # in the SBML Level 2 Version 4 Specification.
77 #
78 #
79 
80 def createExampleEnzymaticReaction():
81  level = Level
82  version = Version
83 
84  # ---------------------------------------------------------------------------
85  #
86  # Creates an SBMLDocument object
87  #
88  # ---------------------------------------------------------------------------
89 
90  sbmlDoc = SBMLDocument(level, version)
91 
92  # ---------------------------------------------------------------------------
93  #
94  # Creates a Model object inside the SBMLDocument object.
95  #
96  # ---------------------------------------------------------------------------
97 
98  model = sbmlDoc.createModel()
99  model.setId("EnzymaticReaction")
100 
101  # ---------------------------------------------------------------------------
102  #
103  # Creates UnitDefinition objects inside the Model object.
104  #
105  # ---------------------------------------------------------------------------
106 
107  # ---------------------------------------------------------------------------
108  # (UnitDefinition1) Creates an UnitDefinition object ("per_second")
109  # ---------------------------------------------------------------------------
110 
111  unitdef = model.createUnitDefinition()
112  unitdef.setId("per_second")
113 
114  # Creates an Unit inside the UnitDefinition object
115 
116  unit = unitdef.createUnit()
117  unit.setKind(UNIT_KIND_SECOND)
118  unit.setExponent(-1)
119 
120  # --------------------------------------------------------------------------------
121  # (UnitDefinition2) Creates an UnitDefinition object ("litre_per_mole_per_second")
122  # --------------------------------------------------------------------------------
123 
124  # Note that we can reuse the pointers 'unitdef' and 'unit' because the
125  # actual UnitDefinition object (along with the Unit objects within it)
126  # is already attached to the Model object.
127 
128  unitdef = model.createUnitDefinition()
129  unitdef.setId("litre_per_mole_per_second")
130 
131  # Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second")
132 
133  unit = unitdef.createUnit()
134  unit.setKind(UNIT_KIND_MOLE)
135  unit.setExponent(-1)
136 
137  # Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second")
138 
139  unit = unitdef.createUnit()
140  unit.setKind(UNIT_KIND_LITRE)
141  unit.setExponent(1)
142 
143  # Creates an Unit inside the UnitDefinition object ("litre_per_mole_per_second")
144 
145  unit = unitdef.createUnit()
146  unit.setKind(UNIT_KIND_SECOND)
147  unit.setExponent(-1)
148 
149  # ---------------------------------------------------------------------------
150  #
151  # Creates a Compartment object inside the Model object.
152  #
153  # ---------------------------------------------------------------------------
154 
155  compName = "cytosol"
156 
157  # Creates a Compartment object ("cytosol")
158 
159  comp = model.createCompartment()
160  comp.setId(compName)
161 
162  # Sets the "size" attribute of the Compartment object.
163  #
164  # We are not setting the units on the compartment size explicitly, so
165  # the units of this Compartment object will be the default SBML units of
166  # volume, which are liters.
167  #
168  comp.setSize(1e-14)
169 
170  # ---------------------------------------------------------------------------
171  #
172  # Creates Species objects inside the Model object.
173  #
174  # ---------------------------------------------------------------------------
175 
176  # ---------------------------------------------------------------------------
177  # (Species1) Creates a Species object ("ES")
178  # ---------------------------------------------------------------------------
179 
180  # Create the Species objects inside the Model object.
181 
182  sp = model.createSpecies()
183  sp.setId("ES")
184  sp.setName("ES")
185 
186  # Sets the "compartment" attribute of the Species object to identify the
187  # compartment in which the Species object is located.
188 
189  sp.setCompartment(compName)
190 
191  # Sets the "initialAmount" attribute of the Species object.
192  #
193  # In SBML, the units of a Species object's initial quantity are
194  # determined by two attributes, "substanceUnits" and
195  # "hasOnlySubstanceUnits", and the "spatialDimensions" attribute
196  # of the Compartment object ("cytosol") in which the species
197  # object is located. Here, we are using the default values for
198  # "substanceUnits" (which is "mole") and "hasOnlySubstanceUnits"
199  # (which is "False"). The compartment in which the species is
200  # located uses volume units of liters, so the units of these
201  # species (when the species appear in numerical formulas in the
202  # model) will be moles/liters.
203  #
204  sp.setInitialAmount(0)
205 
206  # ---------------------------------------------------------------------------
207  # (Species2) Creates a Species object ("P")
208  # ---------------------------------------------------------------------------
209 
210  sp = model.createSpecies()
211  sp.setCompartment(compName)
212  sp.setId("P")
213  sp.setName("P")
214  sp.setInitialAmount(0)
215 
216  # ---------------------------------------------------------------------------
217  # (Species3) Creates a Species object ("S")
218  # ---------------------------------------------------------------------------
219 
220  sp = model.createSpecies()
221  sp.setCompartment(compName)
222  sp.setId("S")
223  sp.setName("S")
224  sp.setInitialAmount(1e-20)
225 
226  # ---------------------------------------------------------------------------
227  # (Species4) Creates a Species object ("E")
228  # ---------------------------------------------------------------------------
229 
230  sp = model.createSpecies()
231  sp.setCompartment(compName)
232  sp.setId("E")
233  sp.setName("E")
234  sp.setInitialAmount(5e-21)
235 
236  # ---------------------------------------------------------------------------
237  #
238  # Creates Reaction objects inside the Model object.
239  #
240  # ---------------------------------------------------------------------------
241 
242  # ---------------------------------------------------------------------------
243  # (Reaction1) Creates a Reaction object ("veq").
244  # ---------------------------------------------------------------------------
245 
246  reaction = model.createReaction()
247  reaction.setId("veq")
248 
249  # (Reactant1) Creates a Reactant object that references Species "E"
250  # in the model. The object will be created within the reaction in the
251  # SBML <listOfReactants>.
252 
253  spr = reaction.createReactant()
254  spr.setSpecies("E")
255 
256  # (Reactant2) Creates a Reactant object that references Species "S"
257  # in the model.
258 
259  spr = reaction.createReactant()
260  spr.setSpecies("S")
261 
262  # ---------------------------------------------------------------------------
263  # (Product1) Creates a Product object that references Species "ES" in
264  # the model.
265  # ---------------------------------------------------------------------------
266 
267  spr = reaction.createProduct()
268  spr.setSpecies("ES")
269 
270  # ---------------------------------------------------------------------------
271  # Creates a KineticLaw object inside the Reaction object ("veq").
272  # ---------------------------------------------------------------------------
273 
274  kl = reaction.createKineticLaw()
275 
276  # ---------------------------------------------------------------------------
277  # Creates an object which represents the following math of the
278  # KineticLaw.
279  #
280  # <math xmlns="http://www.w3.org/1998/Math/MathML">
281  # <apply>
282  # <times/>
283  # <ci> cytosol </ci>
284  # <apply>
285  # <minus/>
286  # <apply>
287  # <times/>
288  # <ci> kon </ci>
289  # <ci> E </ci>
290  # <ci> S </ci>
291  # </apply>
292  # <apply>
293  # <times/>
294  # <ci> koff </ci>
295  # <ci> ES </ci>
296  # </apply>
297  # </apply>
298  # </apply>
299  # </math>
300  #
301  # ---------------------------------------------------------------------------
302 
303  # ------------------------------------------
304  #
305  # create nodes representing the variables
306  #
307  # ------------------------------------------
308 
309  astCytosol = ASTNode(AST_NAME)
310  astCytosol.setName("cytosol")
311 
312  astKon = ASTNode(AST_NAME)
313  astKon.setName("kon")
314 
315  astKoff = ASTNode(AST_NAME)
316  astKoff.setName("koff")
317 
318  astE = ASTNode(AST_NAME)
319  astE.setName("E")
320 
321  astS = ASTNode(AST_NAME)
322  astS.setName("S")
323 
324  astES = ASTNode(AST_NAME)
325  astES.setName("ES")
326 
327  # --------------------------------------------
328  #
329  # create node representing
330  # <apply>
331  # <times/>
332  # <ci> koff </ci>
333  # <ci> ES </ci>
334  # </apply>
335  #
336  # --------------------------------------------
337 
338  astTimes1 = ASTNode(AST_TIMES)
339  astTimes1.addChild(astKoff)
340  astTimes1.addChild(astES)
341 
342  # --------------------------------------------
343  #
344  # create node representing
345  # <apply>
346  # <times/>
347  # <ci> kon </ci>
348  # <ci> E </ci>
349  # <ci> S </ci>
350  # </apply>
351  #
352  #
353  # (NOTES)
354  #
355  # Since there is a restriction with an of "<times/>" operation
356  # such that the is a binary class and thus only two operands can
357  # be directly added, the following code in this comment block is invalid
358  # because the code directly adds three <ci> ASTNodes to <times/> ASTNode.
359  #
360  # *astTimes = ASTNode(AST_TIMES);
361  # astTimes.addChild(astKon);
362  # astTimes.addChild(astE);
363  # astTimes.addChild(astS);
364  #
365  # The following valid code after this comment block creates the ASTNode
366  # as a binary tree.
367  #
368  # Please see "Converting between ASTs and text strings" described
369  # at http://sbml.org/Software/libSBML/docs/cpp-api/class_a_s_t_node.html
370  # for the detailed information.
371  #
372  # --------------------------------------------
373 
374  astTimes2 = ASTNode(AST_TIMES)
375  astTimes2.addChild(astE)
376  astTimes2.addChild(astS)
377 
378  astTimes = ASTNode(AST_TIMES)
379  astTimes.addChild(astKon)
380  astTimes.addChild(astTimes2)
381 
382  # --------------------------------------------
383  #
384  # create node representing
385  # <apply>
386  # <minus/>
387  # <apply>
388  # <times/>
389  # <ci> kon </ci>
390  # <ci> E </ci>
391  # <ci> S </ci>
392  # </apply>
393  # <apply>
394  # <times/>
395  # <ci> koff </ci>
396  # <ci> ES </ci>
397  # </apply>
398  # </apply>
399  #
400  # --------------------------------------------
401 
402  astMinus = ASTNode(AST_MINUS)
403  astMinus.addChild(astTimes)
404  astMinus.addChild(astTimes1)
405 
406  # --------------------------------------------
407  #
408  # create node representing
409  # <apply>
410  # <times/>
411  # <ci> cytosol </ci>
412  # <apply>
413  # <minus/>
414  # <apply>
415  # <times/>
416  # <ci> kon </ci>
417  # <ci> E </ci>
418  # <ci> S </ci>
419  # </apply>
420  # <apply>
421  # <times/>
422  # <ci> koff </ci>
423  # <ci> ES </ci>
424  # </apply>
425  # </apply>
426  # </apply>
427  #
428  # --------------------------------------------
429 
430  astMath = ASTNode(AST_TIMES)
431  astMath.addChild(astCytosol)
432  astMath.addChild(astMinus)
433 
434  # ---------------------------------------------
435  #
436  # set the Math element
437  #
438  # ------------------------------------------------
439 
440  kl.setMath(astMath)
441 
442  # ---------------------------------------------------------------------------
443  # Creates local Parameter objects inside the KineticLaw object.
444  # ---------------------------------------------------------------------------
445 
446  # Creates a Parameter ("kon")
447 
448  para = kl.createParameter()
449  para.setId("kon")
450  para.setValue(1000000)
451  para.setUnits("litre_per_mole_per_second")
452 
453  # Creates a Parameter ("koff")
454 
455  para = kl.createParameter()
456  para.setId("koff")
457  para.setValue(0.2)
458  para.setUnits("per_second")
459 
460  # ---------------------------------------------------------------------------
461  # (Reaction2) Creates a Reaction object ("vcat") .
462  # ---------------------------------------------------------------------------
463 
464  reaction = model.createReaction()
465  reaction.setId("vcat")
466  reaction.setReversible(False)
467 
468  # ---------------------------------------------------------------------------
469  # Creates Reactant objects inside the Reaction object ("vcat").
470  # ---------------------------------------------------------------------------
471 
472  # (Reactant1) Creates a Reactant object that references Species "ES" in the
473  # model.
474 
475  spr = reaction.createReactant()
476  spr.setSpecies("ES")
477 
478  # ---------------------------------------------------------------------------
479  # Creates a Product object inside the Reaction object ("vcat").
480  # ---------------------------------------------------------------------------
481 
482  # (Product1) Creates a Product object that references Species "E" in the model.
483 
484  spr = reaction.createProduct()
485  spr.setSpecies("E")
486 
487  # (Product2) Creates a Product object that references Species "P" in the model.
488 
489  spr = reaction.createProduct()
490  spr.setSpecies("P")
491 
492  # ---------------------------------------------------------------------------
493  # Creates a KineticLaw object inside the Reaction object ("vcat").
494  # ---------------------------------------------------------------------------
495 
496  kl = reaction.createKineticLaw()
497 
498  # ---------------------------------------------------------------------------
499  # Sets a math (object) to the KineticLaw object.
500  # ---------------------------------------------------------------------------
501 
502  # To create mathematical expressions, one would typically construct
503  # an tree as the above example code which creates a math of another
504  # KineticLaw object. Here, to save some space and illustrate another approach
505  # of doing it, we will write out the formula in MathML form and then use a
506  # libSBML convenience function to create the tree for us.
507  # (This is a bit dangerous; it's very easy to make mistakes when writing MathML
508  # by hand, so in a real program, we would not really want to do it this way.)
509 
510  mathXMLString = """<math xmlns="http://www.w3.org/1998/Math/MathML">
511  <apply>
512  <times/>
513  <ci> cytosol </ci>
514  <ci> kcat </ci>
515  <ci> ES </ci>
516  </apply>
517  </math>
518  """
519 
520  astMath = readMathMLFromString(mathXMLString)
521  kl.setMath(astMath)
522 
523  # ---------------------------------------------------------------------------
524  # Creates local Parameter objects inside the KineticLaw object.
525  # ---------------------------------------------------------------------------
526 
527  # Creates a Parameter ("kcat")
528 
529  para = kl.createParameter()
530  para.setId("kcat")
531  para.setValue(0.1)
532  para.setUnits("per_second")
533 
534  # Returns the created SBMLDocument object.
535  # The returned object must be explicitly deleted by the caller,
536  # otherwise a memory leak will happen.
537 
538  return sbmlDoc
539 
540 
541 #
542 #
543 # Creates an SBML model represented in "7.2 Example involving units"
544 # in the SBML Level 2 Version 4 Specification.
545 #
546 #
547 
548 def createExampleInvolvingUnits():
549  level = Level
550  version = Version
551 
552  # ---------------------------------------------------------------------------
553  #
554  # Creates an SBMLDocument object
555  #
556  # ---------------------------------------------------------------------------
557 
558  sbmlDoc = SBMLDocument(level, version)
559 
560  # Adds the namespace for XHTML to the SBMLDocument object. We need this
561  # because we will add notes to the model. (By default, the SBML document
562  # created by SBMLDocument only declares the SBML XML namespace.)
563 
564  sbmlDoc.getNamespaces().add("http://www.w3.org/1999/xhtml", "xhtml")
565 
566  # ---------------------------------------------------------------------------
567  #
568  # Creates a Model object inside the SBMLDocument object.
569  #
570  # ---------------------------------------------------------------------------
571 
572  model = sbmlDoc.createModel()
573  model.setId("unitsExample")
574 
575  # ---------------------------------------------------------------------------
576  #
577  # Creates UnitDefinition objects inside the Model object.
578  #
579  # ---------------------------------------------------------------------------
580 
581  # ---------------------------------------------------------------------------
582  # (UnitDefinition1) Creates an UnitDefinition object ("substance").
583  #
584  # This has the effect of redefining the default unit of subtance for the
585  # whole model.
586  # ---------------------------------------------------------------------------
587 
588  unitdef = model.createUnitDefinition()
589  unitdef.setId("substance")
590 
591  # Creates an Unit inside the UnitDefinition object
592 
593  unit = unitdef.createUnit()
594  unit.setKind(UNIT_KIND_MOLE)
595  unit.setScale(-3)
596 
597  # --------------------------------------------------------------------------------
598  # (UnitDefinition2) Creates an UnitDefinition object ("mmls")
599  # --------------------------------------------------------------------------------
600 
601  # Note that we can reuse the pointers 'unitdef' and 'unit' because the
602  # actual UnitDefinition object (along with the Unit objects within it)
603  # is already attached to the Model object.
604 
605  unitdef = model.createUnitDefinition()
606  unitdef.setId("mmls")
607 
608  # Creates an Unit inside the UnitDefinition object ("mmls")
609 
610  unit = unitdef.createUnit()
611  unit.setKind(UNIT_KIND_MOLE)
612  unit.setScale(-3)
613 
614  # Creates an Unit inside the UnitDefinition object ("mmls")
615 
616  unit = unitdef.createUnit()
617  unit.setKind(UNIT_KIND_LITRE)
618  unit.setExponent(-1)
619 
620  # Creates an Unit inside the UnitDefinition object ("mmls")
621 
622  unit = unitdef.createUnit()
623  unit.setKind(UNIT_KIND_SECOND)
624  unit.setExponent(-1)
625 
626  # --------------------------------------------------------------------------------
627  # (UnitDefinition3) Creates an UnitDefinition object ("mml")
628  # --------------------------------------------------------------------------------
629 
630  unitdef = model.createUnitDefinition()
631  unitdef.setId("mml")
632 
633  # Creates an Unit inside the UnitDefinition object ("mml")
634 
635  unit = unitdef.createUnit()
636  unit.setKind(UNIT_KIND_MOLE)
637  unit.setScale(-3)
638 
639  # Creates an Unit inside the UnitDefinition object ("mml")
640 
641  unit = unitdef.createUnit()
642  unit.setKind(UNIT_KIND_LITRE)
643  unit.setExponent(-1)
644 
645  # ---------------------------------------------------------------------------
646  #
647  # Creates a Compartment object inside the Model object.
648  #
649  # ---------------------------------------------------------------------------
650 
651  compName = "cell"
652 
653  # Creates a Compartment object ("cell")
654 
655  comp = model.createCompartment()
656  comp.setId(compName)
657 
658  # Sets the "size" attribute of the Compartment object.
659  #
660  # The units of this Compartment object is the default SBML
661  # units of volume (litre), and thus we don't have to explicitly invoke
662  # setUnits("litre") function to set the default units.
663  #
664  comp.setSize(1)
665 
666  # ---------------------------------------------------------------------------
667  #
668  # Creates Species objects inside the Model object.
669  #
670  # ---------------------------------------------------------------------------
671 
672 
673  # ---------------------------------------------------------------------------
674  # (Species1) Creates a Species object ("x0")
675  # ---------------------------------------------------------------------------
676 
677  sp = model.createSpecies()
678  sp.setId("x0")
679 
680  # Sets the "compartment" attribute of the Species object to identify the
681  # compartnet in which the Species object located.
682 
683  sp.setCompartment(compName)
684 
685  # Sets the "initialConcentration" attribute of the Species object.
686  #
687  # The units of this Species object is determined by two attributes of this
688  # Species object ("substanceUnits" and "hasOnlySubstanceUnits") and the
689  # "spatialDimensions" attribute of the Compartment object ("cytosol") in which
690  # this species object is located.
691  # Since the default values are used for "substanceUnits" (substance (mole))
692  # and "hasOnlySubstanceUnits" (False) and the value of "spatialDimension" (3)
693  # is greater than 0, the units of this Species object is moles/liters .
694  #
695  sp.setInitialConcentration(1)
696 
697  # ---------------------------------------------------------------------------
698  # (Species2) Creates a Species object ("x1")
699  # ---------------------------------------------------------------------------
700 
701  sp = model.createSpecies()
702  sp.setId("x1")
703  sp.setCompartment(compName)
704  sp.setInitialConcentration(1)
705 
706  # ---------------------------------------------------------------------------
707  # (Species3) Creates a Species object ("s1")
708  # ---------------------------------------------------------------------------
709 
710  sp = model.createSpecies()
711  sp.setCompartment(compName)
712  sp.setId("s1")
713  sp.setInitialConcentration(1)
714 
715  # ---------------------------------------------------------------------------
716  # (Species4) Creates a Species object ("s2")
717  # ---------------------------------------------------------------------------
718 
719  sp = model.createSpecies()
720  sp.setCompartment(compName)
721  sp.setId("s2")
722  sp.setInitialConcentration(1)
723 
724  # ---------------------------------------------------------------------------
725  #
726  # Creates global Parameter objects inside the Model object.
727  #
728  # ---------------------------------------------------------------------------
729 
730  # Creates a Parameter ("vm")
731 
732  para = model.createParameter()
733  para.setId("vm")
734  para.setValue(2)
735  para.setUnits("mmls")
736 
737  # Creates a Parameter ("km")
738 
739  para = model.createParameter()
740  para.setId("km")
741  para.setValue(2)
742  para.setUnits("mml")
743 
744  # ---------------------------------------------------------------------------
745  #
746  # Creates Reaction objects inside the Model object.
747  #
748  # ---------------------------------------------------------------------------
749 
750  # ---------------------------------------------------------------------------
751  # (Reaction1) Creates a Reaction object ("v1").
752  # ---------------------------------------------------------------------------
753 
754  reaction = model.createReaction()
755  reaction.setId("v1")
756 
757  # ---------------------------------------------------------------------------
758  # Creates Reactant objects inside the Reaction object ("v1").
759  # ---------------------------------------------------------------------------
760 
761  # (Reactant1) Creates a Reactant object that references Species "x0"
762  # in the model.
763 
764  spr = reaction.createReactant()
765  spr.setSpecies("x0")
766 
767  # ---------------------------------------------------------------------------
768  # Creates a Product object inside the Reaction object ("v1").
769  # ---------------------------------------------------------------------------
770 
771  # Creates a Product object that references Species "s1" in the model.
772 
773  spr = reaction.createProduct()
774  spr.setSpecies("s1")
775 
776  # ---------------------------------------------------------------------------
777  # Creates a KineticLaw object inside the Reaction object ("v1").
778  # ---------------------------------------------------------------------------
779 
780  kl = reaction.createKineticLaw()
781 
782  # Creates a <notes> element in the KineticLaw object.
783  # Here we illustrate how to do it using a literal string. This requires
784  # known the required syntax of XHTML and the requirements for SBML <notes>
785  # elements. Later below, we show how to create notes using objects instead
786  # of strings.
787 
788  notesString = "<xhtml:p> ((vm * s1)/(km + s1)) * cell </xhtml:p>"
789  kl.setNotes(notesString)
790 
791  # ---------------------------------------------------------------------------
792  # Creates an object which represents the following KineticLaw object.
793  #
794  # <math xmlns="http://www.w3.org/1998/Math/MathML">
795  # <apply>
796  # <times/>
797  # <apply>
798  # <divide/>
799  # <apply>
800  # <times/>
801  # <ci> vm </ci>
802  # <ci> s1 </ci>
803  # </apply>
804  # <apply>
805  # <plus/>
806  # <ci> km </ci>
807  # <ci> s1 </ci>
808  # </apply>
809  # </apply>
810  # <ci> cell </ci>
811  # </apply>
812  # </math>
813  # ---------------------------------------------------------------------------
814 
815  #
816  # In the following code, objects, which construct an tree
817  # of the above math, are created and added in the order of preorder traversal
818  # of the tree (i.e. the order corresponds to the nested structure of the above
819  # MathML elements), and thus the following code maybe a bit more efficient but
820  # maybe a bit difficult to read.
821  #
822 
823  astMath = ASTNode(AST_TIMES)
824 
825  astMath.addChild(ASTNode(AST_DIVIDE))
826  astDivide = astMath.getLeftChild()
827 
828  astDivide.addChild(ASTNode(AST_TIMES))
829  astTimes = astDivide.getLeftChild()
830 
831  astTimes.addChild(ASTNode(AST_NAME))
832  astTimes.getLeftChild().setName("vm")
833 
834  astTimes.addChild(ASTNode(AST_NAME))
835  astTimes.getRightChild().setName("s1")
836 
837  astDivide.addChild(ASTNode(AST_PLUS))
838  astPlus = astDivide.getRightChild()
839 
840  astPlus.addChild(ASTNode(AST_NAME))
841  astPlus.getLeftChild().setName("km")
842 
843  astPlus.addChild(ASTNode(AST_NAME))
844  astPlus.getRightChild().setName("s1")
845 
846  astMath.addChild(ASTNode(AST_NAME))
847  astMath.getRightChild().setName("cell")
848 
849  # ---------------------------------------------
850  #
851  # set the Math element
852  #
853  # ------------------------------------------------
854 
855  kl.setMath(astMath)
856 
857  # ---------------------------------------------------------------------------
858  # (Reaction2) Creates a Reaction object ("v2").
859  # ---------------------------------------------------------------------------
860 
861  reaction = model.createReaction()
862  reaction.setId("v2")
863 
864  # ---------------------------------------------------------------------------
865  # Creates Reactant objects inside the Reaction object ("v2").
866  # ---------------------------------------------------------------------------
867 
868  # (Reactant2) Creates a Reactant object that references Species "s1"
869  # in the model.
870 
871  spr = reaction.createReactant()
872  spr.setSpecies("s1")
873 
874  # ---------------------------------------------------------------------------
875  # Creates a Product object inside the Reaction object ("v2").
876  # ---------------------------------------------------------------------------
877 
878  # Creates a Product object that references Species "s2" in the model.
879 
880  spr = reaction.createProduct()
881  spr.setSpecies("s2")
882 
883  # ---------------------------------------------------------------------------
884  # Creates a KineticLaw object inside the Reaction object ("v2").
885  # ---------------------------------------------------------------------------
886 
887  kl = reaction.createKineticLaw()
888 
889  # Sets a notes (by XMLNode) to the KineticLaw object.
890  #
891  # The following code is an alternative to using setNotes(const string&).
892  # The equivalent code would be like this:
893  #
894  # notesString = "<xhtml:p>((vm * s2)/(km + s2))*cell</xhtml:p>";
895  # kl.setNotes(notesString);
896 
897  # Creates an of start element (<xhtml:p>) without attributes.
898 
899  notesXMLNode = XMLNode(
900  XMLTriple("p", "", "xhtml"),
901  XMLAttributes())
902 
903  # Adds a text element to the start element.
904 
905  notesXMLNode.addChild(XMLNode(" ((vm * s2)/(km + s2)) * cell "))
906 
907  # Adds it to the kineticLaw object.
908 
909  kl.setNotes(notesXMLNode)
910 
911  # ---------------------------------------------------------------------------
912  # Sets a math (object) to the KineticLaw object.
913  # ---------------------------------------------------------------------------
914 
915  # To create mathematical expressions, one would typically construct
916  # an tree as the above example code which creates a math of another
917  # KineticLaw object. Here, to save some space and illustrate another approach
918  # of doing it, we will write out the formula in MathML form and then use a
919  # libSBML convenience function to create the tree for us.
920  # (This is a bit dangerous; it's very easy to make mistakes when writing MathML
921  # by hand, so in a real program, we would not really want to do it this way.)
922 
923  mathXMLString = """<math xmlns="http://www.w3.org/1998/Math/MathML">
924  <apply>
925  <times/>
926  <apply>
927  <divide/>
928  <apply>
929  <times/>
930  <ci> vm </ci>
931  <ci> s2 </ci>
932  </apply>
933  <apply>
934  <plus/>
935  <ci> km </ci>
936  <ci> s2 </ci>
937  </apply>
938  </apply>
939  <ci> cell </ci>
940  </apply>
941  </math>
942  """
943 
944  astMath = readMathMLFromString(mathXMLString)
945  kl.setMath(astMath)
946 
947  # ---------------------------------------------------------------------------
948  # (Reaction3) Creates a Reaction object ("v3").
949  # ---------------------------------------------------------------------------
950 
951  reaction = model.createReaction()
952  reaction.setId("v3")
953 
954  # ---------------------------------------------------------------------------
955  # Creates Reactant objects inside the Reaction object ("v3").
956  # ---------------------------------------------------------------------------
957 
958  # (Reactant2) Creates a Reactant object that references Species "s2"
959  # in the model.
960 
961  spr = reaction.createReactant()
962  spr.setSpecies("s2")
963 
964  # ---------------------------------------------------------------------------
965  # Creates a Product object inside the Reaction object ("v3").
966  # ---------------------------------------------------------------------------
967 
968  # Creates a Product object that references Species "x1" in the model.
969 
970  spr = reaction.createProduct()
971  spr.setSpecies("x1")
972 
973  # ---------------------------------------------------------------------------
974  # Creates a KineticLaw object inside the Reaction object ("v3").
975  # ---------------------------------------------------------------------------
976 
977  kl = reaction.createKineticLaw()
978 
979  # Sets a notes (by string) to the KineticLaw object.
980 
981  notesString = "<xhtml:p> ((vm * x1)/(km + x1)) * cell </xhtml:p>"
982  kl.setNotes(notesString)
983 
984  # ---------------------------------------------------------------------------
985  # Sets a math (object) to the KineticLaw object.
986  # ---------------------------------------------------------------------------
987 
988  mathXMLString = """<math xmlns="http://www.w3.org/1998/Math/MathML">
989  <apply>
990  <times/>
991  <apply>
992  <divide/>
993  <apply>
994  <times/>
995  <ci> vm </ci>
996  <ci> x1 </ci>
997  </apply>
998  <apply>
999  <plus/>
1000  <ci> km </ci>
1001  <ci> x1 </ci>
1002  </apply>
1003  </apply>
1004  <ci> cell </ci>
1005  </apply>
1006  </math>
1007  """
1008 
1009  astMath = readMathMLFromString(mathXMLString)
1010  kl.setMath(astMath)
1011 
1012  # Returns the created SBMLDocument object.
1013  # The returned object must be explicitly deleted by the caller,
1014  # otherwise memory leak will happen.
1015 
1016  return sbmlDoc
1017 
1018 
1019 #
1020 #
1021 # Creates an SBML model represented in "7.8 Example involving function definitions"
1022 # in the SBML Level 2 Version 4 Specification.
1023 #
1024 #
1025 
1026 def createExampleInvolvingFunctionDefinitions():
1027  level = Level
1028  version = Version
1029 
1030  # ---------------------------------------------------------------------------
1031  #
1032  # Creates an SBMLDocument object
1033  #
1034  # ---------------------------------------------------------------------------
1035 
1036  sbmlDoc = SBMLDocument(level, version)
1037 
1038  # ---------------------------------------------------------------------------
1039  #
1040  # Creates a Model object inside the SBMLDocument object.
1041  #
1042  # ---------------------------------------------------------------------------
1043 
1044  model = sbmlDoc.createModel()
1045  model.setId("functionExample")
1046 
1047  # ---------------------------------------------------------------------------
1048  #
1049  # Creates a FunctionDefinition object inside the Model object.
1050  #
1051  # ---------------------------------------------------------------------------
1052 
1053  fdef = model.createFunctionDefinition()
1054  fdef.setId("f")
1055 
1056  # Sets a math (object) to the FunctionDefinition object.
1057 
1058  mathXMLString = """<math xmlns="http://www.w3.org/1998/Math/MathML">
1059  <lambda>
1060  <bvar>
1061  <ci> x </ci>
1062  </bvar>
1063  <apply>
1064  <times/>
1065  <ci> x </ci>
1066  <cn> 2 </cn>
1067  </apply>
1068  </lambda>
1069  </math>
1070  """
1071 
1072  astMath = readMathMLFromString(mathXMLString)
1073  fdef.setMath(astMath)
1074 
1075  # ---------------------------------------------------------------------------
1076  #
1077  # Creates a Compartment object inside the Model object.
1078  #
1079  # ---------------------------------------------------------------------------
1080 
1081  compName = "compartmentOne"
1082 
1083  # Creates a Compartment object ("compartmentOne")
1084 
1085  comp = model.createCompartment()
1086  comp.setId(compName)
1087 
1088  # Sets the "size" attribute of the Compartment object.
1089  #
1090  # The units of this Compartment object is the default SBML
1091  # units of volume (litre), and thus we don't have to explicitly invoke
1092  # setUnits("litre") function to set the default units.
1093  #
1094  comp.setSize(1)
1095 
1096  # ---------------------------------------------------------------------------
1097  #
1098  # Creates Species objects inside the Model object.
1099  #
1100  # ---------------------------------------------------------------------------
1101 
1102  # ---------------------------------------------------------------------------
1103  # (Species1) Creates a Species object ("S1")
1104  # ---------------------------------------------------------------------------
1105 
1106  sp = model.createSpecies()
1107  sp.setId("S1")
1108 
1109  # Sets the "compartment" attribute of the Species object to identify the
1110  # compartnet in which the Species object located.
1111 
1112  sp.setCompartment(compName)
1113 
1114  # Sets the "initialConcentration" attribute of the Species object.
1115  #
1116  # The units of this Species object is determined by two attributes of this
1117  # Species object ("substanceUnits" and "hasOnlySubstanceUnits") and the
1118  # "spatialDimension" attribute of the Compartment object ("cytosol") in which
1119  # this species object located.
1120  # Since the default values are used for "substanceUnits" (substance (mole))
1121  # and "hasOnlySubstanceUnits" (False) and the value of "spatialDimension" (3)
1122  # is greater than 0, the units of this Species object is mole/litre .
1123  #
1124 
1125  sp.setInitialConcentration(1)
1126 
1127  # ---------------------------------------------------------------------------
1128  # (Species2) Creates a Species object ("S2")
1129  # ---------------------------------------------------------------------------
1130 
1131  sp = model.createSpecies()
1132  sp.setId("S2")
1133  sp.setCompartment(compName)
1134  sp.setInitialConcentration(0)
1135 
1136  # ---------------------------------------------------------------------------
1137  #
1138  # Creates a global Parameter object inside the Model object.
1139  #
1140  # ---------------------------------------------------------------------------
1141 
1142  # Creates a Parameter ("t")
1143 
1144  para = model.createParameter()
1145  para.setId("t")
1146  para.setValue(1)
1147  para.setUnits("second")
1148 
1149  # ---------------------------------------------------------------------------
1150  #
1151  # Creates Reaction objects inside the Model object.
1152  #
1153  # ---------------------------------------------------------------------------
1154 
1155  # ---------------------------------------------------------------------------
1156  # (Reaction1) Creates a Reaction object ("reaction_1").
1157  # ---------------------------------------------------------------------------
1158 
1159  reaction = model.createReaction()
1160  reaction.setId("reaction_1")
1161  reaction.setReversible(False)
1162 
1163  # ---------------------------------------------------------------------------
1164  # Creates Reactant objects inside the Reaction object ("reaction_1").
1165  # ---------------------------------------------------------------------------
1166 
1167  # (Reactant1) Creates a Reactant object that references Species "S1"
1168  # in the model.
1169 
1170  spr = reaction.createReactant()
1171  spr.setSpecies("S1")
1172 
1173  # ---------------------------------------------------------------------------
1174  # Creates a Product object inside the Reaction object ("reaction_1").
1175  # ---------------------------------------------------------------------------
1176 
1177  # Creates a Product object that references Species "S2" in the model.
1178 
1179  spr = reaction.createProduct()
1180  spr.setSpecies("S2")
1181 
1182  # ---------------------------------------------------------------------------
1183  # Creates a KineticLaw object inside the Reaction object ("reaction_1").
1184  # ---------------------------------------------------------------------------
1185 
1186  kl = reaction.createKineticLaw()
1187 
1188  # ---------------------------------------------------------------------------
1189  # Sets a math (object) to the KineticLaw object.
1190  # ---------------------------------------------------------------------------
1191 
1192  mathXMLString = """<math xmlns="http://www.w3.org/1998/Math/MathML">
1193  <apply>
1194  <divide/>
1195  <apply>
1196  <times/>
1197  <apply>
1198  <ci> f </ci>
1199  <ci> S1 </ci>
1200  </apply>
1201  <ci> compartmentOne </ci>
1202  </apply>
1203  <ci> t </ci>
1204  </apply>
1205  </math>
1206  """
1207 
1208  astMath = readMathMLFromString(mathXMLString)
1209  kl.setMath(astMath)
1210 
1211  # Returns the created SBMLDocument object.
1212  # The returned object must be explicitly deleted by the caller,
1213  # otherwise memory leak will happen.
1214 
1215  return sbmlDoc
1216 
1217 
1218 # ===============================================================================
1219 #
1220 #
1221 # Helper functions for writing/validating the given SBML documents.
1222 #
1223 #
1224 # ===============================================================================
1225 
1226 #
1227 #
1228 # Validates the given SBMLDocument.
1229 #
1230 # This function is based on validateSBML.py implemented by
1231 # Sarah Keating, Ben Bornstein, and Michael Hucka.
1232 #
1233 #
1234 
1235 def validateExampleSBML(sbmlDoc):
1236  if sbmlDoc is None:
1237  print("validateExampleSBML: given a None SBML Document")
1238  return False
1239 
1240  consistencyMessages = ""
1241  validationMessages = ""
1242  noProblems = True
1243  numCheckFailures = 0
1244  numConsistencyErrors = 0
1245  numConsistencyWarnings = 0
1246  numValidationErrors = 0
1247  numValidationWarnings = 0
1248 
1249  # LibSBML 3.3 is lenient when generating models from scratch using the
1250  # API for creating objects. Once the whole model is done and before it
1251  # gets written out, it's important to check that the whole model is in
1252  # fact complete, consistent and valid.
1253 
1254  numCheckFailures = sbmlDoc.checkInternalConsistency()
1255  if numCheckFailures > 0:
1256  noProblems = False
1257  for i in range(0, numCheckFailures):
1258  sbmlErr = sbmlDoc.getError(i)
1259  if sbmlErr.isFatal() or sbmlErr.isError():
1260  numConsistencyErrors += 1
1261  else:
1262  numConsistencyWarnings += 1
1263  sbmlDoc.printErrors()
1264 
1265  # If the internal checks fail, it makes little sense to attempt
1266  # further validation, because the model may be too compromised to
1267  # be properly interpreted.
1268 
1269  if numConsistencyErrors > 0:
1270  consistencyMessages += "Further validation aborted."
1271  else:
1272  numCheckFailures = sbmlDoc.checkConsistency()
1273  if numCheckFailures > 0:
1274  noProblems = False
1275  for i in range(0, numCheckFailures):
1276  sbmlErr = sbmlDoc.getError(i)
1277  if sbmlErr.isFatal() or sbmlErr.isError():
1278  numValidationErrors += 1
1279  else:
1280  numValidationWarnings += 1
1281  sbmlDoc.printErrors()
1282 
1283  if noProblems:
1284  return True
1285  else:
1286  if numConsistencyErrors > 0:
1287  tmp = ""
1288  if numConsistencyErrors > 1:
1289  tmp = "s"
1290  print("ERROR: encountered " + str(
1291  numConsistencyErrors) + " consistency error" + tmp + " in model '" + sbmlDoc.getModel().getId() + "'.")
1292 
1293  if numConsistencyWarnings > 0:
1294  tmp = ""
1295  if numConsistencyWarnings > 1:
1296  tmp = "s"
1297  print("Notice: encountered " + str(numConsistencyWarnings)
1298  + " consistency warning" + tmp
1299  + " in model '" + sbmlDoc.getModel().getId() + "'.")
1300  print(consistencyMessages)
1301 
1302  if numValidationErrors > 0:
1303  tmp = ""
1304  if numValidationErrors > 1:
1305  tmp = "s"
1306  print("ERROR: encountered " + str(numValidationErrors) + " validation error" + tmp
1307  + " in model '" + sbmlDoc.getModel().getId() + "'.")
1308  if numValidationWarnings > 0:
1309  tmp = ""
1310  if numValidationWarnings > 1:
1311  tmp = "s"
1312  print("Notice: encountered " + str(numValidationWarnings)
1313  + " validation warning" + tmp
1314  + " in model '" + sbmlDoc.getModel().getId() + "'.")
1315  print(validationMessages)
1316 
1317  return numConsistencyErrors == 0 and numValidationErrors == 0
1318 
1319 
1320 #
1321 #
1322 # Writes the given SBMLDocument to the given file.
1323 #
1324 #
1325 def writeExampleSBML(sbmlDoc, filename):
1326  result = writeSBML(sbmlDoc, filename)
1327  if result == 1:
1328  print("Wrote file '" + filename + "'")
1329  return True
1330  else:
1331  print("Failed to write '" + filename + "'")
1332  return False
1333 
1334 
1335 # ===============================================================================
1336 #
1337 # Main routine
1338 #
1339 # Creates SBML models represented in "Example models expressed in XML using
1340 # SBML" in Section 7 of the SBML Level 2 Version 4 specification(*).
1341 #
1342 # (*) The specification document is available at the following URL:
1343 # http://sbml.org/Documents/Specifications
1344 #
1345 # ===============================================================================
1346 #
1347 def main(args):
1348  sbmlDoc = None
1349  SBMLok = False
1350 
1351  try:
1352  # -------------------------------------------------
1353  # 7.1 A Simple example application of SBML
1354  # -------------------------------------------------
1355 
1356  sbmlDoc = createExampleEnzymaticReaction()
1357  SBMLok = validateExampleSBML(sbmlDoc)
1358  if SBMLok:
1359  writeExampleSBML(sbmlDoc, "enzymaticreaction.xml")
1360  if not SBMLok:
1361  return 1
1362 
1363  # -------------------------------------------------
1364  # 7.2 Example involving units
1365  # -------------------------------------------------
1366 
1367  sbmlDoc = createExampleInvolvingUnits()
1368  SBMLok = validateExampleSBML(sbmlDoc)
1369  if SBMLok:
1370  writeExampleSBML(sbmlDoc, "units.xml")
1371  if not SBMLok:
1372  return 1
1373 
1374  # -------------------------------------------------
1375  # 7.8 Example involving function definitions
1376  # -------------------------------------------------
1377 
1378  sbmlDoc = createExampleInvolvingFunctionDefinitions()
1379  SBMLok = validateExampleSBML(sbmlDoc)
1380  if SBMLok:
1381  writeExampleSBML(sbmlDoc, "functiondef.xml")
1382  if not SBMLok:
1383  return 1
1384  except:
1385  print("Unexpected exceptional condition encountered.")
1386  return 1
1387 
1388  # A 0 return status is the standard Unix/Linux way to say "all ok".
1389  return 0
1390 
1391 
1392 if __name__ == '__main__':
1393  main(sys.argv)