EnzymeML / PyEnzyme

🧬 - Data management and modeling framework based on EnzymeML.
BSD 2-Clause "Simplified" License
21 stars 9 forks source link

kineticLaw MathML not saved in SBML with binder or colab #39

Closed jmrohwer closed 2 years ago

jmrohwer commented 2 years ago

Execute the first part of Scenario5/PySCeS/Cephalexin_Synthesis_Model4.ipynb from the Lauterbach2022 repo online (either via Binder, or via Google Colab), up until the archive Model_4.omex is written (right before the section on Kinetic Modeling starts). In the resulting archive, the MathML is not written into the SBML file (experiment.xml), which causes the second part of the notebook to fail, when the same archive is read in again and then the simulators fail to find the kineticLaw because it is not there.

Below is a diff between the supplied file (from Model_4.omex, which is on the github repo), and the generated file. When I execute the notebook locally, the resultant file is correct and identical to the supplied file. This is from main on the PyEnzyme repo. I have no idea what is the cause of this, version differences between some package as it is available online and locally? But the error occurs with both Binder and Colab.

No error messages are given during execution of the notebook.

--- /home/jr/tmp/enzymeml/suppl/experiment.xml  2022-03-14 18:14:50.000000000 +0200
+++ /home/jr/tmp/enzymeml/gen/experiment.xml    2022-03-21 15:33:52.000000000 +0200
@@ -310,27 +310,7 @@
           <speciesReference sboTerm="SBO:0000011" species="p0" stoichiometry="1" constant="false"/>
           <speciesReference sboTerm="SBO:0000011" species="s1" stoichiometry="1" constant="false"/>
         </listOfProducts>
-        <kineticLaw name="MassAction Keq">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <times/>
-              <ci> v_r </ci>
-              <apply>
-                <minus/>
-                <apply>
-                  <times/>
-                  <ci> K_n </ci>
-                  <ci> c1 </ci>
-                </apply>
-                <apply>
-                  <times/>
-                  <ci> p0 </ci>
-                  <ci> s1 </ci>
-                </apply>
-              </apply>
-            </apply>
-          </math>
-        </kineticLaw>
+        <kineticLaw name="MassAction Keq"/>
       </reaction>
       <reaction metaid="METAID_R1" sboTerm="SBO:0000176" id="r1" name="reaction-2" reversible="true">
         <listOfReactants>
@@ -341,25 +321,6 @@
           <speciesReference sboTerm="SBO:0000011" species="s0" stoichiometry="1" constant="false"/>
         </listOfProducts>
         <kineticLaw name="MassAction Keq">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <times/>
-              <ci> v_r </ci>
-              <apply>
-                <minus/>
-                <apply>
-                  <times/>
-                  <ci> K_s </ci>
-                  <ci> c0 </ci>
-                </apply>
-                <apply>
-                  <times/>
-                  <ci> p0 </ci>
-                  <ci> s0 </ci>
-                </apply>
-              </apply>
-            </apply>
-          </math>
           <listOfLocalParameters>
             <localParameter id="K_s" units="u1"/>
           </listOfLocalParameters>
@@ -373,13 +334,6 @@
           <speciesReference sboTerm="SBO:0000011" species="p1" stoichiometry="1" constant="false"/>
         </listOfProducts>
         <kineticLaw name="MassAction Irreversible">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <times/>
-              <ci> k_2 </ci>
-              <ci> c0 </ci>
-            </apply>
-          </math>
           <listOfLocalParameters>
             <localParameter id="k_2" units="u6"/>
           </listOfLocalParameters>
@@ -393,27 +347,7 @@
           <speciesReference sboTerm="SBO:0000011" species="c0" stoichiometry="1" constant="false"/>
           <speciesReference sboTerm="SBO:0000011" species="s0" stoichiometry="1" constant="false"/>
         </listOfProducts>
-        <kineticLaw name="MassAction Keq">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <times/>
-              <ci> v_r </ci>
-              <apply>
-                <minus/>
-                <apply>
-                  <times/>
-                  <ci> K_si </ci>
-                  <ci> c3 </ci>
-                </apply>
-                <apply>
-                  <times/>
-                  <ci> c0 </ci>
-                  <ci> s0 </ci>
-                </apply>
-              </apply>
-            </apply>
-          </math>
-        </kineticLaw>
+        <kineticLaw name="MassAction Keq"/>
       </reaction>
       <reaction metaid="METAID_R4" sboTerm="SBO:0000176" id="r4" name="reaction-5" reversible="true">
         <listOfReactants>
@@ -423,27 +357,7 @@
           <speciesReference sboTerm="SBO:0000011" species="p1" stoichiometry="1" constant="false"/>
           <speciesReference sboTerm="SBO:0000011" species="s0" stoichiometry="1" constant="false"/>
         </listOfProducts>
-        <kineticLaw name="MassAction Keq">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <times/>
-              <ci> v_r </ci>
-              <apply>
-                <minus/>
-                <apply>
-                  <times/>
-                  <ci> K_si </ci>
-                  <ci> c5 </ci>
-                </apply>
-                <apply>
-                  <times/>
-                  <ci> p1 </ci>
-                  <ci> s0 </ci>
-                </apply>
-              </apply>
-            </apply>
-          </math>
-        </kineticLaw>
+        <kineticLaw name="MassAction Keq"/>
       </reaction>
       <reaction metaid="METAID_R5" sboTerm="SBO:0000176" id="r5" name="reaction-6" reversible="false">
         <listOfReactants>
@@ -454,13 +368,6 @@
           <speciesReference sboTerm="SBO:0000011" species="s3" stoichiometry="1" constant="false"/>
         </listOfProducts>
         <kineticLaw name="MassAction Irreversible">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <times/>
-              <ci> k_6 </ci>
-              <ci> c5 </ci>
-            </apply>
-          </math>
           <listOfLocalParameters>
             <localParameter id="k_6" units="u6"/>
           </listOfLocalParameters>
@@ -475,13 +382,6 @@
           <speciesReference sboTerm="SBO:0000011" species="s3" stoichiometry="1" constant="false"/>
         </listOfProducts>
         <kineticLaw name="MassAction Irreversible">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <times/>
-              <ci> k_3 </ci>
-              <ci> p1 </ci>
-            </apply>
-          </math>
           <listOfLocalParameters>
             <localParameter id="k_3" units="u6"/>
           </listOfLocalParameters>
@@ -496,25 +396,6 @@
           <speciesReference sboTerm="SBO:0000011" species="s3" stoichiometry="1" constant="false"/>
         </listOfProducts>
         <kineticLaw name="MassAction Keq">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <times/>
-              <ci> v_r </ci>
-              <apply>
-                <minus/>
-                <apply>
-                  <times/>
-                  <ci> K_pg </ci>
-                  <ci> c2 </ci>
-                </apply>
-                <apply>
-                  <times/>
-                  <ci> p0 </ci>
-                  <ci> s3 </ci>
-                </apply>
-              </apply>
-            </apply>
-          </math>
           <listOfLocalParameters>
             <localParameter id="K_pg" units="u1"/>
           </listOfLocalParameters>
@@ -528,27 +409,7 @@
           <speciesReference sboTerm="SBO:0000011" species="p1" stoichiometry="1" constant="false"/>
           <speciesReference sboTerm="SBO:0000011" species="s1" stoichiometry="1" constant="false"/>
         </listOfProducts>
-        <kineticLaw name="MassAction Keq">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <times/>
-              <ci> v_r </ci>
-              <apply>
-                <minus/>
-                <apply>
-                  <times/>
-                  <ci> K_n </ci>
-                  <ci> c4 </ci>
-                </apply>
-                <apply>
-                  <times/>
-                  <ci> p1 </ci>
-                  <ci> s1 </ci>
-                </apply>
-              </apply>
-            </apply>
-          </math>
-        </kineticLaw>
+        <kineticLaw name="MassAction Keq"/>
       </reaction>
       <reaction metaid="METAID_R9" sboTerm="SBO:0000176" id="r9" name="reaction-10" reversible="false">
         <listOfReactants>
@@ -560,13 +421,6 @@
           <speciesReference sboTerm="SBO:0000011" species="s1" stoichiometry="1" constant="false"/>
         </listOfProducts>
         <kineticLaw name="MassAction Irreversible">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <times/>
-              <ci> k_5 </ci>
-              <ci> c4 </ci>
-            </apply>
-          </math>
           <listOfLocalParameters>
             <localParameter id="k_5" units="u6"/>
           </listOfLocalParameters>
@@ -580,21 +434,6 @@
           <speciesReference sboTerm="SBO:0000011" species="c6" stoichiometry="1" constant="false"/>
         </listOfProducts>
         <kineticLaw name="MassAction Reversible">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <minus/>
-              <apply>
-                <times/>
-                <ci> k_4 </ci>
-                <ci> c4 </ci>
-              </apply>
-              <apply>
-                <times/>
-                <ci> k_4b </ci>
-                <ci> c6 </ci>
-              </apply>
-            </apply>
-          </math>
           <listOfLocalParameters>
             <localParameter id="k_4" units="u6"/>
             <localParameter id="k_4b" units="u6"/>
@@ -610,25 +449,6 @@
           <speciesReference sboTerm="SBO:0000011" species="s2" stoichiometry="1" constant="false"/>
         </listOfProducts>
         <kineticLaw name="MassAction Keq">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <times/>
-              <ci> v_r </ci>
-              <apply>
-                <minus/>
-                <apply>
-                  <times/>
-                  <ci> K_p </ci>
-                  <ci> c6 </ci>
-                </apply>
-                <apply>
-                  <times/>
-                  <ci> p0 </ci>
-                  <ci> s2 </ci>
-                </apply>
-              </apply>
-            </apply>
-          </math>
           <listOfLocalParameters>
             <localParameter id="K_p" units="u1"/>
           </listOfLocalParameters>
@@ -642,13 +462,6 @@
           <speciesReference sboTerm="SBO:0000011" species="p2" stoichiometry="1" constant="false"/>
         </listOfProducts>
         <kineticLaw name="MassAction Irreversible">
-          <math xmlns="http://www.w3.org/1998/Math/MathML">
-            <apply>
-              <times/>
-              <ci> k_d </ci>
-              <ci> p0 </ci>
-            </apply>
-          </math>
           <listOfLocalParameters>
             <localParameter id="k_d" units="u6"/>
           </listOfLocalParameters>
fbergmann commented 2 years ago

at first guess, i would blame the deep cloning of the original model. since we are just using the python way of doing things here. if some of the libSBML ASTNode objects would be held by the original document (rather than say an infix form), deep cloning might not be able to copy elements correctly.

jmrohwer commented 2 years ago

Then why does it work (without fail) when I execute it locally?

JR-1991 commented 2 years ago

When a ModelGenerator instance is called, variables in the equation attribute are encapsulated in ' so that on addition to the EnzymeMLDocument these can be identified and checked for consistency to the document. Furthermore, the intend was to give users the opportunity to add variables using their actual names rather than plain IDs to improve readability.

Internally, the method uses the ast module to break down the equation and identify names/IDs to check and convert. However, the syntax of ast slightly differs in Python 3.7 and a name in an equation is typed as ast.Name (3.7) instead of ast.Constant (>3.7), which hasn't been looked after when initially implemented. Thus, the error persists exclusively in Python 3.7, which happens to be the base installation Colab and Binder use.

I was able to fix the error with my last commit and added some tests to make sure everything works as intended. I tested it in Colab and it works just fine now. Will do another test in Binder tomorrow.

jmrohwer commented 2 years ago

I can confirm that it works in Colab on my side and in Binder as well (after updating requirements.txt in Lauterbach2022 to point to main).

jmrohwer commented 2 years ago

I am re-opening the issue. Using the latest commit on main, the kinetic law is now not saved in Python versions 3.8-3.10, but in Python 3.7 everything is okay (so the other way round as originally). Moreover, when trying to save the enzymeml doc with .toFile(), the Python interpreter crashes and core dumps (on Py 3.8-3.10).

Could this have to do with the unit consistency checks introduced? I see also some species are now saved with quotes, does this maybe interfere with the MathML generation? It was not the case previously.

JR-1991 commented 2 years ago

Thanks for pointing that out. The issue was with a logic in an if-pattern using regex pattern found in the setModel-method. It added two quotes instead of a single one what led to the error.

This is fixed now and has been tested with the notebook found in "Lauterbach_2022". It seems like the re package for 3.7 behaves different to the other ones. Also added a test to check if the MathML model has been added correctly to prevent such cases in the future.

jmrohwer commented 2 years ago

Thanks, all good now, tested on my side as well.