ModellingWebLab / cellmlmanip

CellML loading and model equation manipulation
Other
3 stars 1 forks source link

model.get_symbol_by_cmeta_id vs model.get_symbol_by_ontology_term behaviour #68

Closed MauriceHendrix closed 5 years ago

MauriceHendrix commented 5 years ago

Right so I've been working with model.get_symbol_by_cmeta_id to get hold of various things in the model, Now however I have come across a model that doesn't have the cmeta_id I need. However it does have an RDF description on a variable with a different idea to say this this is indeed what I'm looking for.

The extract from the cellml file is blow. model.get_symbol_by_cmeta_id throws an error. I guess this is technically correct and model.get_symbol_by_ontology_term does give me the expected answer but I'm just wondering in this case what is actually the point of the cmeta_id and would it make sense to have a method that looks in both?

`

'
mirams commented 5 years ago

We should really be working with the rdf tags, each of which should name a thing that has a cmeta:id so the "#cell_V" above should match the cmeta:id of the voltage variable. But the cmeta:id could be anything at all, just need to match.

MauriceHendrix commented 5 years ago

Which begs the question why do we even have get_symbol_by_cmeta_id? Or at least we should add comments explaining that it really does get just the id and not by oxmeta ontology term

MauriceHendrix commented 5 years ago

Actually I have just noticed: there are models that don't do it properly. In luo_rudy_1991_dyn:

<variable units="millivolt" public_interface="out" cmeta:id="membrane_voltage" name="V" initial_value="-83.853"/>

(in case you weren't aware is equivalent to with nothing inside it)

MichaelClerx commented 5 years ago

At the moment, we annotate like this:

<model xmlns:cmeta="http://www.cellml.org/metadata/1.0#" ...
...
<component ...
  <variable name="time" public_interface="out" units="msc" cmeta:id="engine_time">
  ...
</component>
...
<rdf:RDF
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:bqbiol="http://biomodels.net/biology-qualifiers/"
        xmlns:oxmeta="https://chaste.comlab.ox.ac.uk/cellml/ns/oxford-metadata#"
        xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
    <rdf:Description rdf:about="#engine_time">
        <bqbiol:is rdf:resource="https://chaste.comlab.ox.ac.uk/cellml/ns/oxford-metadata#time"/>
    </rdf:Description>
</rdf>
</model>

So the ontology term is defined in the RDF annotation, but the RDF is linked to the variable via its cmeta_id. The get_symbol_by_cmeta_id() method is temporary, just a hack to get things to work. The get_symbol_by_ontology_term() method is the one that should be used in the future

MichaelClerx commented 5 years ago

Actually I have just noticed: there are models that don't do it properly. In luo_rudy_1991_dyn:

<variable units="millivolt" public_interface="out" cmeta:id="membrane_voltage" name="V" initial_value="-83.853"/>

(in case you weren't aware is equivalent to with nothing inside it)

What do you mean here? What's not proper about that bit of cellml?

MichaelClerx commented 5 years ago

(Note the cmeta:id can be anything, it only exists within the model to link the variable to its RDF annotation. It may or may not overlap with an ontology term, but that doesn't change anything functionally!)

MauriceHendrix commented 5 years ago

(Note the cmeta:id can be anything, it only exists within the model to link the variable to its RDF annotation. It may or may not overlap with an ontology term, but that doesn't change anything functionally!)

That makes sense, but in that case what "isn't propper" is that translation with pycml currently it recognises this as the membrane voltage.

@mirams suggested just updating the cellml and using the rdf "properly"

MichaelClerx commented 5 years ago

Yeah if the RDF isn't in there then update it please! You can remove the get_by_cmeta_id if you like, to make sure nothing depends on it

mirams commented 5 years ago

PyCML doesn't actually recognise that cmeta tag, it falls back to its global config file which just looks for variables that might be voltage based on their component and names: https://github.com/Chaste/Chaste/blob/release/python/pycml/config.xml

  <currents>
      <stimulus>
          <var type='oxmeta'>membrane_stimulus_current</var>
          <var type='name'>membrane,i_Stim</var>
          <var type='name'>membrane,I_stim</var>
          <var type='name'>cell,i_Stim</var>
          <var type='name'>membrane,i_stim</var>
          <var type='name'>membrane,I_st</var>
          <var type='name'>membrane,i_st</var>
          <var type='name'>membrane,i_pulse</var>
    </stimulus>  
  </currents>
  <transmembrane_potential>
        <var type='oxmeta'>membrane_voltage</var>
        <var type='name'>membrane,V</var>
        <var type='name'>cell,V</var>
        <var type='name'>membrane,E</var>
  </transmembrane_potential>
  <membrane_capacitance>
        <var type='oxmeta'>membrane_capacitance</var>
        <var type='name'>membrane,Cm</var>
        <var type='name'>membrane,C</var>
        <var type='name'>membrane,C_m</var>
        <var type='name'>membrane,C_sc</var>
  </membrane_capacitance>

So you can see why we introduced the metadata tags to make that safer!

MauriceHendrix commented 5 years ago

PyCML doesn't actually recognise that cmeta tag, it falls back to its global config file which just looks for variables that might be voltage based on their names: https://github.com/Chaste/Chaste/blob/release/python/pycml/config.xml

  <currents>
      <stimulus>
          <var type='oxmeta'>membrane_stimulus_current</var>
          <var type='name'>membrane,i_Stim</var>
          <var type='name'>membrane,I_stim</var>
          <var type='name'>cell,i_Stim</var>
          <var type='name'>membrane,i_stim</var>
          <var type='name'>membrane,I_st</var>
          <var type='name'>membrane,i_st</var>
          <var type='name'>membrane,i_pulse</var>
    </stimulus>  
  </currents>
  <transmembrane_potential>
        <var type='oxmeta'>membrane_voltage</var>
        <var type='name'>membrane,V</var>
        <var type='name'>cell,V</var>
        <var type='name'>membrane,E</var>
  </transmembrane_potential>
  <membrane_capacitance>
        <var type='oxmeta'>membrane_capacitance</var>
        <var type='name'>membrane,Cm</var>
        <var type='name'>membrane,C</var>
        <var type='name'>membrane,C_m</var>
        <var type='name'>membrane,C_sc</var>
  </membrane_capacitance>

So you can see why we introduced the metadata tags to make that safer!

aah yes that makse sense

mirams commented 5 years ago

But yeah, I'm happy for future chaste-cg to rely on the tags being in there and not do the old fashioned config.

MauriceHendrix commented 5 years ago

ok so the question now is: is get_symbol_by_cmeta_id needed by anything else?

MichaelClerx commented 5 years ago

Nope. Just kick it out and we'll fix whatever uses it

MichaelClerx commented 5 years ago

You basically know all there is to know about cellmlmanip and cg now. Feel free to change as you see fit!

MauriceHendrix commented 5 years ago

You basically know all there is to know about cellmlmanip and cg now. Feel free to change as you see fit!

sure I'll put in a pull request I wanted to discuss it first though :)

jonc125 commented 5 years ago

It's just for internal use, as part of the link from ontology term -> RDF annotation -> cmeta:id -> variable.

MauriceHendrix commented 5 years ago

It's just for internal use, as part of the link from ontology term -> RDF annotation -> cmeta:id -> variable.

sure but surely cmeta:id terms are only there to make teh ontology work and shouldn't really be used directly to identify variables (other than by cellmlmanip itself) ?

jonc125 commented 5 years ago

Indeed. (Although other libraries using cellmlmanip and getting annotations from elsewhere might also need to look up ids, so possibly not entirely internal eventually.) (And of course, in CellML 2 the ids become part of the CellML vocab, not a separate cmeta namespace.)