-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simulation rate not calculated correctly when compartments are present #79
Comments
Interesting, thanks for the deep dive diagnoses. The problem is that if the species symbols are concentrations in the rate equations ( 'Species_In_Conc' ) then they have to be internally evaluated as such and the problem is then how to get back to amounts. The warning was meant to show this is a problem - it doesn't occur if the species symbols are amounts. It's been a while since I thought about this stuff so my apologies in advance for the following!
If we knew the location of each reaction we could do something on the right hand side (dSx/dt = Vn([S])*Vcomp_vol, but I'm not sure this is generally possible. What about something like dSx/dt = Vn([S])*Scomp_vol?
This should, at least, work for single compartment systems (for now I'm purposely ignoring cross-compartment reactions which have to be defined in amounts or defined with a reaction location)?
Note that this is independent of the ('Output_In_Conc') which does a post conversion of the results that are calculated as amounts. Alternatively, you can rewrite your rate equations in terms of amount and the problem goes away ;-)
Seriously though, thanks for the notebook, I'll get back to you if this is indeed the problem.
…On Fri, Jun 10, 2022 at 11:30 AM Johann Rohwer ***@***.***> wrote:
I picked up an issue when species are in conc, and output is in conc as
well, with a module that has compartments (even only a single compartment)
with a volume other than 1.
Illustrated with a simple mass-action model of a closed system. The following
notebook
<https://github.com/PySCeS/pyscesdev/blob/main/johann/volumes/test_volumes.ipynb>
shows the issue. In a nutshell, the starting concentrations and amounts
seem to be correct, but the rate constant is evaluated wrong when the
volume is not 1.
As far as I could ascertain this has to do with PySCeS converts species to
amounts in Simulate() even when there is only a single compartment:
https://github.com/PySCeS/pysces/blob/1831cb281817d62d3a7d225fe1acd0ba6c39cbc3/pysces/PyscesModel.py#L4639-L4640
For EvalReq() the species are converted back to concentrations:
https://github.com/PySCeS/pysces/blob/1831cb281817d62d3a7d225fe1acd0ba6c39cbc3/pysces/PyscesModel.py#L3603-L3607
(Note that _EvalODE() calls EvalReq()).
However, CVODE() and LSODA() both assume in this case that the ODEs are
actually in amounts, with the conversion to concentrations occurring at the
end after the simulation. For CVODE:
https://github.com/PySCeS/pysces/blob/1831cb281817d62d3a7d225fe1acd0ba6c39cbc3/pysces/PyscesModel.py#L3909-L3915
For LSODA:
https://github.com/PySCeS/pysces/blob/1831cb281817d62d3a7d225fe1acd0ba6c39cbc3/pysces/PyscesModel.py#L4052-L4054
This means that when an ODE is evaluated in such a case, the LHS is
assumed to be in amounts, while the RHS is in concentrations. Obviously
this can't work if the compartment volume is not 1, and will give an error
for all rate parameters (kcat, k, Vmax, etc.)
Finally, maybe this has to do with the following warning (not shown by
default):
https://github.com/PySCeS/pysces/blob/1831cb281817d62d3a7d225fe1acd0ba6c39cbc3/pysces/PyscesModel.py#L3443-L3446
This is, however, not very practical.
I stumbled on this bug through the PySCeS Thinlayer for the PyEnzyme
library used for analysing, processing and fitting enzyme kinetics data:
https://github.com/EnzymeML/PyEnzyme specifically
https://github.com/EnzymeML/PyEnzyme/tree/main/pyenzyme/thinlayers. The
data are captured in an EnzymeML document (extension of SBML) which outputs
the compartment (reaction vessel) by default with its volume (generally not
equal to 1). However, for fitting purposes, all species are generally
reported in concentrations, leading to an issue when fitting time courses
with PySCeS.
—
Reply to this email directly, view it on GitHub
<#79>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABGHUEICTCYMOYZEJ4UBLWLVOMDMBANCNFSM5YNBTTRQ>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
I have discussed this with @jhsh and am taking the liberty to post his reply here: PySCeS evalueer Goue reël van kompartementele modellering: om mol/s snelheidsvgl te produseer, skaleer die kanoniese snelheidsvgl k1*S met die grootte van die kompartement waar die reaction events plaasvind (Cell) vir Species_In_Conc: True
vir Species_In_Conc: False
Traai dit op die aangehegde notebook. Alles werk soos geadverteer. |
The above is implemented in a second notebook. Everything now works as it should, with one caveat: As explained in the notebook, if both
Your ideas in this regard will be appreciated. |
Thanks, I've been looking at the code and I can implement something that writes the ODE's as Cell*R1() in the code, however, the problem is that SBML derived KineticLaws should already be in that form so that complicates things (and I should have noticed that your model was written using Rate Equations and had no compartment term, sorry about that). Thanks for noticing the rate output issue. I think this may have been taken care of in the old CVODE using the one-step algorithm? With the new CVODE, would it be possible to use dummy variables (non-fixed parameters) to track "rates in concentration" during a simulation if needed? Some more things to consider:
|
With regards to Johann's comment in the notebook: "Convert the rates to conc per time post-hoc. This again is problematic if the reaction occurs across two compartments or even in a third compartment, so which volume should the rate be scaled to?" the problem has a simple solution. In the following the equation numbers refer to Hofmeyr, J-HS (2020) Kinetic modelling of compartmentalised reaction networks. BioSystems 197, 104302
There are now two options: a. Specifying "Output_In_Conc: True" implies that BOTH species and rates should be output as concentrations of species and concentrations of reaction events per time respectively. b. Since in principle the units of a correctly-defined rate have nothing to do with whether reactants and products are in amounts or concentrations in its rate equation, one may rather want to distinguish between the units in which output-concentrations and output-rates are expressed. This can be done by adding a flag that specifies the form in which rates are output. Something like Rate_Output_In_Conc_Per_Time (with True as default?) Here "Output_In_Conc" could however be construed as referring to both species and rates). Therefore "Species_Output_In_Conc" would be better than "Output_In_Conc". Too late for that now? PySCeS could easily be made back-compatible with models that still use "Output_In_Conc".
For the moment, 2 and 3 can be implemented by the modeller with assignment rules. We still have to consider Brett's suggestions, but this is all for the moment. |
Hi @bgoli Coming back to this:
You mention that SBML derived KineticLaws should already be in the The reason I'm asking this is that what prompted all of this actually started out from SBML. It is an EnzymeML document (which is basically an SBML document with custom annotations for storing the kinetic details, i.e. EnzymeML specific stuff). But the rate law is entered by hand when creating this document. And most enzyme kineticists of course work in rate equations in concentrations.
Yes, as also mentioned in Jannie's comments above, I've re-implemented the ability to track arbitrary model attributes with assignment rules (see release 1.0.2). |
Yes to the first question - this is the modellers responsibility. As I understand it SBML 3 defines it's KineticLaw as something that returns amounts per time (Size*rates_in_concentration) so one can't use a Biochemical Rate Equation directly in SBML. It is well hidden but this is a bit from section 4.11.7 on Page 76 of the L3V2 core spec, Mathematical interpretation of SBML reactions and kinetic laws. Constructing rate-of-change equations for the species
More on this topic on page 128 of the spec. You may want to check this for EnzymeML so that it is using valid SBML, if it is a case of a 90% of the time it is a single compartment then the tool can easily do the modification on SBML export (multiply rate law by compartment size). In my other comment the question I raised, was, whether this couldn't be further generalised into a (semi-?)automated solution where one uses the Reaction location to determine the compartment size that multiplies the rate law? |
Interesting, just as this reply came through I had started to have another detailed look at the SBML spec and came across exactly the passage you are referring to.
Indeed, to quote the preceding paragraph from the spec, as it states this unambiguously:
Quoting @bgoli:
Indeed, 99% of the time I can guarantee you that EnzymeML deals with single compartment models. Their use case is for experimental enzyme kinetics or biocatalysis experiments, which are done in a single reaction "vessel" (
I guess one could do that but automated solutions are always dangerous because they may have unintended consequences in the background and/or the modeller doesn't really know what they're doing. But I am convinced now that there is actually a need for a single compartment automated solution, where there is no ambiguity. Refer to my comment above re. As soon as we are dealing with multiple compartments, I'd stay away from automated conversions. This has the potential to become a black box too quickly, and modellers should know what they are doing if they venture here! |
Quoting @jhsh:
In principle this is all true, but refer to my reply to @bgoli above. I am not sure if its possible to implement a solid, foolproof, consistent, automated <listOfSpecies>
<species id="Y1n" compartment="nucleus" initialAmount="1" constant="false"
boundaryCondition="false" hasOnlySubstanceUnits="false"/>
<species id="Y1c" compartment="cytoplasm" initialAmount="0" constant="false"
boundaryCondition="false" hasOnlySubstanceUnits="false"/>
</listOfSpecies>
<reaction id="transport" reversible="true">
<listOfReactants>
<speciesReference species="Y1n" stoichiometry="1" constant="true"/>
</listOfReactants>
<listOfProducts>
<speciesReference species="Y1c" stoichiometry="1" constant="true"/>
</listOfProducts>
<kineticLaw>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<times/>
<ci>cytoplasm</ci>
<ci>KT</ci>
<apply>
<minus/>
<ci>Y1n</ci>
<ci>Y1c</ci>
</apply>
</apply>
</math>
</kineticLaw>
</reaction> I would rather have an automated conversion of the reaction rates (see above) for single compartment models with We should also keep in mind that the current
PySCeS has a hidden method
This is very similar to your point 2, in fact it is just one term of the ODE for X.
And indeed it is now possible to track assignment rules again during simulations (release 1.0.2), so I would not build additional functionality here. |
@jmrohwer being SBML compatible (export/import) does not mean limiting ourselves to it or the way it has evolved :-) Let me put it this way: If we know the location (compartment) of the Reaction and the individual Species how far can we get with automatically generating amount/time ODE's with concentration based rates. From @jhsh Point 1 above (hopefully :-)) a reaction must be located in a compartment, and, then that compartment can then be used to calculate the amount of enzyme per unit volume or area etc. If this is true then the only "problem" is if you have badly designed models where enzymes float on the interface between compartments (likely SBML example models that make no sense). On the other hand, for PySCeS models it should be easier to use biochemical Rate Equations in multicompartment models - assuming we require all Reactions/Species to have a location in a compartment. SBML models generally do not have the reaction compartment defined, although I think the attribute exists in L3, so we need to treat them differently ... as always.
(Edit. Note, one thing we should keep in mind when using compartment sizes for single compartment models is scaling, we will have to detect very small compartment sizes and autoscale the compartment sizes pre/post ODE evaluation simulation - no matter which direction we go.) |
Quoting @jmrohwer: "Indeed, to quote the preceding paragraph from the spec, as it states this unambiguously:
This is, as I have often mentioned before, the wrong way round: species quantity/time is an extensive property that is proportional to the size of the compartment in which the reaction events occur, while species quantity/size/time is an intensive property that does not depend on the size of the compartment. I make this clear in my paper. I do wish someone would change this in the SBML documentation. Quoting @bgoli: "SBML models generally do not have the reaction compartment defined, although I think the attribute exists in L3" Such an attribute is crucial in compartmental models and should be there. What happens when "v1@Cell:" in a PySCeS input file is translated to SBML? |
Quoting @jhsh
The attribute exists in L3 but it is optional (i.e. not required). So when a PySCeS input file as above is translated to SBML, then the attribute is included. In the example I cited from the SBML spec above, the attribute is missing though. I see that in the example above (this post) the kinetic law is multiplied by |
@jmrohwer we currently only export L2 so I don't think that attribute exists. What I would do with L3 is set the Reaction compartment attribute to the correct compartment and then multiply the RateEquation with the PySCeS defined compartment size to create the associated KineticLaw for export. SBML export is not the problem, import is. If the Reaction compartment is not defined, I can't easily extract the correct compartment term from the KineticLaw so I need to treat the SBML KineticLaw as "something" that returns rates in amount/time (as we do now). PySCeS could, if we can get it to work, deal with multi-compartment RateEquation models in a slightly more sophisticated way than SBML, whilst still being SBML3 compatible @jhsh has pointed out the issues with the SBML example which, as you see, is dodgy and the intrinsic/extrinsic issue which is just wrong and is registered as an SBML specification issue. |
Well, if the compartment is defined for the reaction in SBML, this gets correctly translated to PSC and I get
Okay I get what you're saying here. |
FWIW I've just checked that during the SBML->PSC conversion PySCeS assigns the reaction to a compartment (i.e. This is all only tested with single compartment models. Not sure what would happen in the case of multi-compartment models. |
Ja so it looks like if the model was from SBML, or, a PySCeS model that had rate laws in amount/time it would be correct SBML. Whereas if a PySCeS model was defined with no compartments the SBML KineticLaw would technically be incorrect, although practically the model would be exported with a compartment of size 1.0 and still work for that value! This is a good time to discuss this as SBML, Python and libSBML have evolved a lot since this code was written and now that people are actually using SBML we can't just say "just use PSC" anymore. Also the person that wrote this stuff now knows a bit more about libSBML and Python :-) So some things to consider (assume we are eventually moving to L3).
Maybe we should do something like:
We can do this in multiple releases as we fix essential stuff first etc. |
Sounds like a plan 😀 On the topic of moving to L3: as an aside, I've put in an Honours project for a Bioinformatics student to work on updating the events framework in PySCeS to be fully L3 compliant (handling of simultaneous events with priority). However, I don't know yet whether there will be any takers. |
Sounds good. First issue (a lot of which has been discussed here so we can continue here or split). First attempt at some use cases, please feel free to add/extend/modify: Defining and interpreting no-, single- and multi-compartment PySCeS models (in PSC).Case 1: A vanilla PSC model with no compartments definedCase 2: A PSC model defined with a single compartmentCase 3: A PSC model defined with a multiple compartmentsFor each use case we should think about things like
|
I picked up an issue when species are in conc, and output is in conc as well, with a model that has compartments (even only a single compartment) with a volume other than 1.
Illustrated with a simple mass-action model of a closed system. The following notebook shows the issue. In a nutshell, the starting concentrations and amounts seem to be correct, but the rate constant is evaluated wrong when the volume is not 1.
As far as I could ascertain this has to do with PySCeS converts species to amounts in
Simulate()
even when there is only a single compartment:pysces/pysces/PyscesModel.py
Lines 4639 to 4640 in 1831cb2
For
EvalReq()
the species are converted back to concentrations:pysces/pysces/PyscesModel.py
Lines 3603 to 3607 in 1831cb2
(Note that
_EvalODE()
callsEvalReq()
).However,
CVODE()
andLSODA()
both assume in this case that the ODEs are actually in amounts, with the conversion to concentrations occurring at the end after the simulation. ForCVODE
:pysces/pysces/PyscesModel.py
Lines 3909 to 3915 in 1831cb2
For
LSODA
:pysces/pysces/PyscesModel.py
Lines 4052 to 4054 in 1831cb2
This means that when an ODE is evaluated in such a case, the LHS is assumed to be in amounts, while the RHS is in concentrations. Obviously this can't work if the compartment volume is not 1, and will give an error for all rate parameters (kcat, k, Vmax, etc.)
Finally, maybe this has to do with the following warning (not shown by default):
pysces/pysces/PyscesModel.py
Lines 3443 to 3446 in 1831cb2
This is, however, not very practical.
I stumbled on this bug through the PySCeS Thinlayer for the PyEnzyme library used for analysing, processing and fitting enzyme kinetics data: https://github.com/EnzymeML/PyEnzyme specifically https://github.com/EnzymeML/PyEnzyme/tree/main/pyenzyme/thinlayers. The data are captured in an EnzymeML document (extension of SBML) which outputs the compartment (reaction vessel) by default with its volume (generally not equal to 1). However, for fitting purposes, all species are generally reported in concentrations, leading to an issue when fitting time courses with PySCeS.
The text was updated successfully, but these errors were encountered: