-
Notifications
You must be signed in to change notification settings - Fork 12
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
WIP: Specification of Timecourses #581
base: main
Are you sure you want to change the base?
Conversation
* extract all changes from previous * fixup * allow hyphens in extension names * fixup hyphens * only require one toolbox that implements extension * specify how to work with multiple PEtab problems * specify we do not require a quorum number of votes * allow test cases to be provided by the extension library * Apply suggestions from code review Co-authored-by: Daniel Weindl <[email protected]> Co-authored-by: Daniel Weindl <[email protected]>
PEtab extensions were introduced in #537. We should be able to distinguish there between optional extensions and required extensions, i.e. those that modify the parameter estimation problem as such, and those that just add additional/optional information (e.g. annotations, info for visualization, ...). If some tool does not know about a certain optional extension, it can safely be ignored during import, if it does not know about a required extension, it should fail. This PR adds a `required` attribute to extensions in the yaml file to indicate whether they are required for the mathematical interpretation of the PEtab problem. Resolves #544
Co-authored-by: Dilan Pathirana <[email protected]>
- remove preequilibrationConditionId - remove simulationConditionId - add timecourseID
Previously, the math expression syntax wasn't specified. This was very problematic, because different libraries and programming languages have different names for the same functions, and more importantly, differ in operator precedence. Co-authored-by: Dilan Pathirana <[email protected]> Co-authored-by: dilpath <[email protected]>
Resolved merge conflicts. This needs to be updated to match the new mostly-agreed-upon format in #586
|
f08da31
to
5933d5a
Compare
b79293f
to
56be96d
Compare
Add basic support for PEtab version 2 experiments (see also PEtab-dev/PEtab#586, and PEtab-dev/PEtab#581). Follow-up to #334. Partially supersedes #263, which was started before petab.v1/petab.v2 were introduced and before PEtab-dev/PEtab#586. * updates the required fields in the measurement table * updates some validation functions to not expect the old `simulationConditionId`s (but does not do full validation yet) * extends PEtab v1 up-conversion to create a new experiment table. --------- Co-authored-by: Dilan Pathirana <[email protected]>
56be96d
to
59eefdc
Compare
values as defined in the model). | ||
The target must be a constant target or a differential target. | ||
|
||
- ``setRate``: The time-derivative of the target is set to ``targetValue`` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems natural to have an addToCurrentValue
as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine to have it for coherence. For simplicity, we could leave it out, since in this case, the target value for setCurrentValue
and X
could easily be written as X + 10
instead of addToCurrentValue
, X
, 10
.
Another question is what other operations we would need. multiply{CurrentValue,Rate,...}
? exp? log?
It would be nice if we could always just refer to the old value in targetValue
, but that would require introducing additional functions there (rateOf
, rateExpressionOf
, ...). That would reduce the list of operations, and one could also use the old values of other entities, not just that of the current target.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that sounds like it would be helpful to introduce targetValue
in favour of having addTo
, multiply
, etc.
Why would we need operators like rateOf
, rateExpressionOf
? I don't see why one would ever transfer information from rate to value and everything else should be achievable one way or another.
Also, what about using setValue
in favor of setCurrentValue
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One use case where one might want to use both the current value and the rate expression could be some piecewise definition of a rate expression where the condition depends on the current state. I'd don't consider super important.
This is specified as a tab-separated value file in the following way: | ||
|
||
+---------------------+-------------------+-----------------+ | ||
| experimentId | time | conditionId | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I agree that we can drop the name in the conditions table, I think it would be nice to have an optional name column here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine to add experimentName
here if we drop the condition names. However, if we want to keep condition names, which then would have to be specified in some other place (yaml, annotations table, ...?), I would collect all of that in the same place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case I would propose to move all names (including observables etc) to such a table. Would anyways be nice as it would introduce the possibility of, e.g. naming states.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I'm happy to review this again after the current feedback round
|
||
- A model | ||
|
||
- A measurement file to fit the model to [TSV] | ||
|
||
- A condition file specifying model inputs and condition-specific parameters | ||
- (optional) A condition file specifying model inputs and condition-specific parameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we usually refer to this as the "conditions table"
- (optional) A condition file specifying model inputs and condition-specific parameters | |
- (optional) A conditions file specifying model inputs and condition-specific parameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. Makes sense to use coherent terminology. Also for all other tables/files...
* Clarification and specification of various previously underspecified aspects | ||
(math expressions, overriding values in the condition table, etc.) | ||
(:ref:`math_expressions`, overriding values in the condition table, etc.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should list everything (explicitly or by some grouping)
(:ref:`math_expressions`, overriding values in the condition table, etc.) | |
(:ref:`math_expressions`, overriding values in the condition table) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be updated once all changes here have been finalized.
doc/v2/documentation_data_format.rst
Outdated
| ... | ... | ... | | ... | | ||
+--------------+------------------+------------------+-----------------+--------------------+ | ||
|
||
Each line specifies a change of one specific property of a specific entity. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each line specifies a change of one specific property of a specific entity. | |
Each line specifies the change in the numeric value of one specific non-estimated entity. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This hides the fact that a single entity has different types of associated values (e.g., current value vs. rate) and excludes "symbolic assignment" like setAssignment
, doesn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right, make sense. Then to avoid the word property, which isn't defined yet:
Each line specifies a change of one specific property of a specific entity. | |
Each line specifies one change in one target entity. |
+---------------------+-------------------+-----------------+ | ||
| experimentId | time | conditionId | | ||
+=====================+===================+=================+ | ||
| PETAB_ID | NUMERIC or '-inf' | CONDITION_ID | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, in the measurements table it is NUMERIC\|inf
instead
Thanks for the feedback. |
Co-authored-by: Dilan Pathirana <[email protected]> Co-authored-by: Fabian Fröhlich <[email protected]>
a920847
to
4b7b692
Compare
Co-authored-by: Dilan Pathirana <[email protected]>
|
||
This is specified as a tab-separated value file in the following way: | ||
|
||
**TODO: keep conditionName or not?** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conditionName I think can be kept as optional as it can help with nicer plotting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is that now there may be several rows per condition, which makes it not so ideal to specify any condition names there. Would you still keep it that table? Would all rows for that condition have to have the same value, or should there only be one non-empty entry per condition?
- ``setAssignment``: The target is set to the value of ``targetValue`` | ||
(symbolically). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I have missed this discussion, but, is setRate
, setAssignment
and other operationType
that alter in a sense the dynamic model (e.g. if setRate = 0.0
for one condition and setRate = 1.0
for another, the structural model differs between conditions, so I imagine that tools need to basically build multiple model structures during import), something that is going to be supported and encouraged to be supported by most PEtab tools?
Instead if this is a feature that is reserved to mean this, maybe it should be stated somewhere (so that users and potential developers of importers does not think this is a key important feature to support)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this is discussed after Differential/Algebraic/Constant targets are introduced. To my understanding, structural alterations are not allowed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might have different understandings of "structural alterations". Changing some algebraic expression e := x
to e := y
would be allowed, but changing some differential state to some algebraic expression would not be allowed. In how much that requires building different models is probably very much implementation dependent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might have different understandings of "structural alterations". Changing some algebraic expression e := x to e := y would be allowed, but changing some differential state to some algebraic expression would not be allowed. In how much that requires building different models is probably very much implementation dependent.
Thanks for clarification, just a last question to fully understand. So if we have a parameter given via an assignment rule; k = k1 * k2
would it then be allowed to change k
via setAssignment
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that was to my understanding the (only) use case for setAssignment
.
graph between model components: | ||
|
||
- When a condition changes quantity ``A`` and ``B``, and ``B`` is dependent on | ||
``A``, the change in quantity A should be applied first such that the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not how SBML work right?
If I remember correctly if both A
and B
are assigned something in an event, basically the pre-event A
and B
values are used unless priority is specified.
But regardless, I agree compartment should have priority.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not how SBML work right?
If I remember correctly if both
A
andB
are assigned something in an event, basically the pre-eventA
andB
values are used unless priority is specified.
I'm not sure, all I see in the SBML spec is (regarding simultaneously-occurring events)
A given simulator may use any algorithm to choose an order as long as every event is executed exactly once.
This choice of compartment priority (and more generally to respect the dependency graph) is partly based on discussions with @matthiaskoenig last year -- perhaps @matthiaskoenig can say more here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a difference between simultaneously occuring events and simultaneous assignments during the same event. I would treat assignments via conditions the same as a single event, i.e. not subject to priority or useValuesFromTriggerTime attributes. I would propose to not follow the dependency graph (and rather simply use pre-assignment values) with the exception of compartments. As done with SBML Event Assignments (even though this isn't crystal clear in the sbml spec).
For example it might make sense to average two species A = B = (A + B)/2. Due to circularity, this assignment is not possible when following the dependency graph, but straightforward with pre-change values. Following of dependencies can always be reproduces through substitution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want 2 different behaviors. These are managed in SBML events via the useValuesFromTriggerTime
flag. So we need probably this flag on the timecourse to ensure both scenarios are possible (see also comment below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd vote for @FFroehlich's suggestion here.
In the timecourses, what we essentially have are event assignments triggered at t=t_trigger. All event assignments must be executed simultaneously—this is not a step-by-step process. Instead, the model state must transition to the new state all at once. Any mathematical expressions that depend on updated parameters, compartments, or species must be re-evaluated accordingly. In other words, all changes are applied in a single step, and the AST (Abstract Syntax Tree) affected by these changes is fully re-evaluated. There is no predefined execution order—it is a single transformation of the model state. Therefore, the claim that "compartment has priority" is incorrect and does not make sense. The underlying issue is that PETab changes are not clearly defined and have been incorrectly implemented by simulators. As seen in cases where changes affect both compartment volumes and concentrations, many simulators apply these changes sequentially, which is incorrect. Instead, all triggered changes must be applied in a single step. This clarification should also be explicitly stated for changes applied outside of timecourses. Additionally, in SBML, there is a flag called useValuesFromTriggerTime, which allows the use of values before the assignments. This is likely what you are referring to:
|
In SBML, all ListOf constructs are unordered lists. This means an SBML model can be modified by shuffling any ListOf elements, such as ListOfEventAssignments, without affecting the numerical results of a simulation. In other words, there is no inherent order in these lists, nor are there execution priorities—except in cases where ordering is necessary, in which attributes like priority have been introduced to dictate the execution of multiple Events. The same principle should apply when multiple changes are made in PETab: all changes should be applied simultaneously. If ordering is required, an explicit order or priority attribute must be introduced. If mathematical expressions need to reference values from the end of the previous time span, a useValuesFromTriggerTime mechanism is necessary. For cases where a mix of behaviors is needed, an Event-like construct could be introduced, allowing assignments to be grouped and prioritized. There is a reason SBML Events are complex. Either we adopt a full event-based approach where changes can be triggered after each time span, or we adhere to a simpler default approach where all changes are applied simultaneously. One concern is that specifications often end up reflecting existing implementations rather than defining a general, correct solution. This appears to be happening here, as most PETab implementations currently apply changes sequentially. This approach is likely incorrect, but since the specification does not clearly define the intended behavior, there is uncertainty. Moreover, it does not align with what users of SBML models would expect. |
Right. That definitely needs to be addressed.
To be honest, I am not sure for how many SBML users the users' expectations match the SBML standard when it comes to event assignments. I am still regularly confused when it comes to simultaneous changes in compartment sizes and concentrations. |
The main issue with establishing a fixed order for updating multiple variables (such as compartments, species, or parameters) is that mathematical calculations dependent on these variables could produce unexpected results depending on the update sequence. For example, consider a compartment V and a concentration C. Any calculation that relies on both V and C may yield different outcomes depending on the update order. Suppose we start with V=1 and C=1, then update both to V=10 and C=10. If there is a calculation dependent on the relationship between V and C, the result will vary based on the order in which they are updated. For instance, an event triggered when V>C will only occur if V is updated before C. If C is updated first or both are updated simultaneously, the event may not trigger, leading to inconsistencies. In other words, updating variables sequentially in a fixed order can lead to intermediate steps that place the model in an undefined state. This issue persists regardless of the specific order. Therefore, it is essential to either update all variables synchronously or clearly define and follow a predetermined update sequence for each variable to maintain a consistent model state (simply updating compartments before species does not resolve the issue). The issue with the concentrations is just one of such a problem because species concentrations depend on their compartment volumes, so there is a math dependency linking C and V which depends on the order. But there can be many such dependencies in the math of the model. |
Okay, fair point. The intermediate model states would be a problem. |
This draft PR adds the descriptions from the Time course specification to the
release/2.0.0
branch.preview site is: https://petab--581.org.readthedocs.build/en/581/documentation_data_format.html#timecourses-table