Skip to content
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

Documentation page on how to access model properties #889

Merged
merged 11 commits into from
Jul 21, 2024

Conversation

TorkelE
Copy link
Member

@TorkelE TorkelE commented May 30, 2024

Not actually sure what to call this one, but this is the tutorial that goes through how to access stuff within a ReactionSystem.

  • For a starter, it goes through basic stuff like species(rs).
  • For now, I also put our main section on how accessing symbolic variables via the model (e.g. rs.X) works.
  • There is also a bit on hierarchical models, i.e. the difference between get_species and species, and rs.submodelname.X.

@TorkelE TorkelE changed the title Documentation page on how to access model properties [Ready] Documentation page on how to access model properties Jun 5, 2024
@TorkelE TorkelE changed the title [Ready] Documentation page on how to access model properties [Documentation - Ready] Documentation page on how to access model properties Jun 5, 2024
@TorkelE TorkelE changed the title [Documentation - Ready] Documentation page on how to access model properties [Non-urgent - Ready] Documentation page on how to access model properties Jun 11, 2024
@TorkelE TorkelE changed the title [Non-urgent - Ready] Documentation page on how to access model properties Documentation page on how to access model properties Jul 6, 2024
Copy link
Member

@isaacsas isaacsas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy for you to merge after you've addressed my comments.

Generally, the field of Julia structures can be accessed through `struct.field`. E.g. a simulation's time vector can be retrieved using `simulation.t`. While Catalyst `ReactionSystem`s are structures, one should *never* access their fields using this approach, but rather using the accessor functions described below and in the [API](@ref api_accessor_functions) (direct accessing of fields can yield unexpected behaviours). E.g. to retrieve the species of a `ReactionsSystem` `rs`, use `Catalyst.get_species(rs)`, *not* `rs.species`.

## [Direct accessing of symbolic model parameter and species](@id model_accessing_symbolic_variables)
Previously we have described how the parameters and species (and [variables](@ref constraint_equations_coupling_constraints)) that Catalyst models contain are represented using so-called [*symbolic variables*](@ref introduction_to_catalyst) (and how these enable the forming of [*symbolic expressions*](@ref introduction_to_catalyst)). We have described how, during [programmatic modelling](@ref programmatic_CRN_construction), the user has [direct access to these](@ref programmatic_CRN_construction) and how this can be [taken advantage of](@ref programmatic_CRN_construction). We have also described how, during [DSL-based modelling](@ref dsl_description), the need for symbolic representation can be circumvented by [using `@unpack`](@ref dsl_advanced_options_symbolics_and_DSL_unpack) or by [creating an observable](@ref dsl_advanced_options_observables). However, sometimes, it is easier to *directly access a symbolic variable through the model itself*.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Previously we have described how the parameters and species (and [variables](@ref constraint_equations_coupling_constraints)) that Catalyst models contain are represented using so-called [*symbolic variables*](@ref introduction_to_catalyst) (and how these enable the forming of [*symbolic expressions*](@ref introduction_to_catalyst)). We have described how, during [programmatic modelling](@ref programmatic_CRN_construction), the user has [direct access to these](@ref programmatic_CRN_construction) and how this can be [taken advantage of](@ref programmatic_CRN_construction). We have also described how, during [DSL-based modelling](@ref dsl_description), the need for symbolic representation can be circumvented by [using `@unpack`](@ref dsl_advanced_options_symbolics_and_DSL_unpack) or by [creating an observable](@ref dsl_advanced_options_observables). However, sometimes, it is easier to *directly access a symbolic variable through the model itself*.
... the need for symbolic representation can be circumvented by [using `@unpack`](@ref dsl_advanced_options_symbolics_and_DSL_unpack) or by [creating an observable](@ref dsl_advanced_options_observables)...*.

I found this part of the paragraph confusing. Maybe separately just recall the ways to access a symbolic variable/parameter that have already been shown? (I'd leave out the observable stuff as I think it will just confuse the discussion.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was kind of written in the mind that we had a dedicated section on symbolic variables, but I agree that it might be a bit confusing now. I will try to reword/improve.

Ideally I'd still have a link to the observables (although maybe rather and example where it is used). For DSL-based models, in most cases, I think this is probably the best way to do it (i.e. if there is a specific quantity like this you are using, it probably should be an observable, in other situations @unpack might be better)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New section

[Direct accessing of symbolic model parameter and species](@id model_accessing_symbolic_variables)

Previously we have described how the parameters and species that Catalyst models contain are represented using so-called [symbolic variables](@ref introduction_to_catalyst) (and how these enable the forming of [symbolic expressions](@ref introduction_to_catalyst)). We have described how, during [programmatic modelling](@ref programmatic_CRN_construction), the user has [direct access to these](@ref programmatic_CRN_construction) and how this can be [taken advantage of](@ref programmatic_CRN_construction). I.e. here we declare the symbolic variables associated with a two-state model, and also creates the model programmatically.

using Catalyst
t = default_t()
@parameters k1 k2
@species X1(t) X2(t)

rxs = [
    Reaction(k1, [X1], [X2]),
    Reaction(k2, [X2], [X1])
]
@named rs = ReactionSystem(rxs, t)
nothing # hide

We have also described how, during [DSL-based modelling](@ref dsl_description), the need for symbolic representation can be circumvented by [using @unpack](@ref dsl_advanced_options_symbolics_and_DSL_unpack) or by [creating an observable](@ref dsl_advanced_options_observables). However, sometimes, it is easier to directly access a symbolic variable through the model itself.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, didn't like how this turned out, especially since the same model is declare later. Now I use

Previously we have described how the parameters and species that Catalyst models contain are represented using so-called [*symbolic variables*](@ref introduction_to_catalyst) (and how these enable the forming of [*symbolic expressions*](@ref introduction_to_catalyst)). We have described how, during [programmatic modelling](@ref programmatic_CRN_construction), the user has [direct access to these](@ref programmatic_CRN_construction) and how this can be [taken advantage of](@ref programmatic_CRN_construction). We have also described how, during [DSL-based modelling](@ref dsl_description), the need for symbolic representation can be circumvented by [using `@unpack`](@ref dsl_advanced_options_symbolics_and_DSL_unpack) or by [creating an observable](@ref dsl_advanced_options_observables). However, sometimes, it is easier to *directly access a symbolic variable through the model itself*, something which we will describe here.

which is not that different from what we had originally. I think the best solution is to create a model creation example which illustrates this, and then simply link to that.

TorkelE and others added 7 commits July 17, 2024 15:23
Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
Co-authored-by: Sam Isaacson <isaacsas@users.noreply.github.com>
@TorkelE TorkelE merged commit 27ce254 into master Jul 21, 2024
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants