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

fbc-v3: Can't set xmlns on KeyValuePairList & Can't set key and value on KeyValuePair #241

Closed
matthiaskoenig opened this issue Jul 13, 2022 · 4 comments · Fixed by #243
Closed

Comments

@matthiaskoenig
Copy link

Hi all,
we are currently in the process of implementing support for the fbc version 3 draft in sbmlutils and cobrapy.
I just tried creating the KeyValuePairs but have some issues.

The following code results in issues

"""
Test bed for FBC version 3.
For latest SBML fbc v3 specification see
https://sourceforge.net/p/sbml/code/26312/tree/trunk/specifications/sbml-level-3/version-1/fbc/spec/main.pdf?format=raw

"""
import libsbml
from logging import getLogger
logger = getLogger(__name__)


def check(value: int, message: str) -> bool:
    """Check the libsbml return value and prints message if something happened.

    If 'value' is None, prints an error message constructed using
      'message' and then exits with status code 1. If 'value' is an integer,
      it assumes it is a libSBML return status code. If the code value is
      LIBSBML_OPERATION_SUCCESS, returns without further action; if it is not,
      prints an error message constructed using 'message' along with text from
      libSBML explaining the meaning of the code, and exits with status code 1.
    """
    valid = True
    if value is None:
        logger.error(f"Error: LibSBML returned a null value trying to <{message}>.")
        valid = False
    elif isinstance(value, int):
        if value != libsbml.LIBSBML_OPERATION_SUCCESS:
            logger.error(f"Error encountered trying to '{message}'.")
            logger.error(
                f"LibSBML returned error code {str(value)}: "
                f"{libsbml.OperationReturnValue_toString(value).strip()}"
            )
            valid = False

    return valid


# create document with new fbc version 3 namespace
sbmlns: libsbml.SBMLNamespaces = libsbml.SBMLNamespaces(3, 1)
sbmlns.addPkgNamespace("fbc", 3)
doc: libsbml.SBMLDocument = libsbml.SBMLDocument(sbmlns)
doc_fbc: libsbml.FbcSBMLDocumentPlugin = doc.getPlugin("fbc")
doc_fbc.setRequired(False)

model: libsbml.Model = doc.createModel()
model_fbc: libsbml.FbcModelPlugin = model.getPlugin("fbc")
print(model_fbc)
model_fbc.setStrict(True)

# Support for key value pairs exists
c: libsbml.Compartment = model.createCompartment()
c.setId("c1")
c.setSize(1.0)
c.setConstant(True)

s1: libsbml.Species = model.createSpecies()
s1.setId("s1")
s1.setCompartment("c1")
s1.setInitialConcentration(1.0)
s1.setConstant(True)
s1.setHasOnlySubstanceUnits(False)
s1.setBoundaryCondition(False)

s1_fbc: libsbml.FbcSpeciesPlugin = s1.getPlugin("fbc")

kvp_list: libsbml.ListOfKeyValuePairs = s1_fbc.getListOfKeyValuePairs()
kvp_list.setXmlns("http://sbml.org/fbc/keyvaluepair")
kvp: libsbml.KeyValuePair = s1_fbc.createKeyValuePair()
check(kvp.setKey("testdata"), "Set Key on KeyValuePair")
check(kvp.setValue("1.0"), "Set Value on KeyValuePair")
s1_fbc.addKeyValuePair(kvp)

sbml_str: str = libsbml.writeSBMLToString(doc)
print("-" * 80)
print(sbml_str)
print("-" * 80)

Results in problems setting the KeyValue Pairs? You can see that these are not written in the SBML below.
Also the xlmns is not set on the list, but xmlns="http://www.sbml.org/sbml/level3/version1/fbc/version3". Perhaps this is the reason the setting of Key and Value fails ?

The specification states that

The xmlns is a mandatory component of the ListOfKeyValuePairs, is of the type uri and must have the value
http://sbml.org/fbc/keyvaluepair.

But it seems I cannot set the xmlns. Also why is this not set automatically if the value has the required value http://sbml.org/fbc/keyvaluepair

<FbcModelPlugin>
Error encountered trying to 'Set Key on KeyValuePair'.
LibSBML returned error code -2: The attribute that is the subject of this operation is not valid for the combination of SBML Level and Version for the underlying object. This can happen because libSBML strives to offer a uniform API for all SBML Levels and Versions, but some object attributes and elements are not defined for all SBML Levels and Versions. Calling programs are expected to be aware of which object structures they are working with, but when errors of this kind occur, they are reported using this return value.
Error encountered trying to 'Set Value on KeyValuePair'.
LibSBML returned error code -2: The attribute that is the subject of this operation is not valid for the combination of SBML Level and Version for the underlying object. This can happen because libSBML strives to offer a uniform API for all SBML Levels and Versions, but some object attributes and elements are not defined for all SBML Levels and Versions. Calling programs are expected to be aware of which object structures they are working with, but when errors of this kind occur, they are reported using this return value.

and the following SBML

<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version1/core" xmlns:fbc="http://www.sbml.org/sbml/level3/version1/fbc/version3" level="3" version="1" fbc:required="false">
  <model fbc:strict="true">
    <listOfCompartments>
      <compartment id="c1" size="1" constant="true"/>
    </listOfCompartments>
    <listOfSpecies>
      <species id="s1" compartment="c1" initialConcentration="1" hasOnlySubstanceUnits="false" boundaryCondition="false" constant="true">
        <annotation>
          <listOfKeyValuePairs xmlns="http://www.sbml.org/sbml/level3/version1/fbc/version3">
            <keyValuePair/>
          </listOfKeyValuePairs>
        </annotation>
      </species>
    </listOfSpecies>
  </model>
</sbml>

Best Matthias

@matthiaskoenig matthiaskoenig changed the title Can't set xmlns on KeyValuePairList & Can't set key and value on KeyValuePair fbc-v3: Can't set xmlns on KeyValuePairList & Can't set key and value on KeyValuePair Jul 13, 2022
@fbergmann
Copy link
Member

this is strange. Setting key / value in the code above works for me if i initialize with: sbmlns = libsbml.FbcPkgNamespaces(3, 1, 3) And yes, the element namespace ought to be changed.

@fbergmann
Copy link
Member

Alternatively

kvp: libsbml.KeyValuePair = kvp_list.createKeyValuePair()

will work in your version, as the sbaseplugin extensionpoint does not provide the package version.

but yes, the namespace is an issue that needs to be resolved.

@matthiaskoenig
Copy link
Author

Thanks, using kvp: libsbml.KeyValuePair = kvp_list.createKeyValuePair() works.
I also see the namespace issue as validation warning, so there must be a way to set it correctly ;)

WARNING  E0: SBML component consistency (fbc, L1, code)        validation.py:186
         [Warning] Attributes allowed on <keyValuePair>.                        
         A <keyValuePair> object must have the required                         
         attribute 'fbc:key', and may have the optional                         
         attributes 'fbc:id', 'fbc:name', 'fbc:value' and                       
         'fbc:uri'. No other attributes from the SBML Level 3                   
         Flux Balance Constraints namespaces are permitted on                   
         a <keyValuePair> object.                                               
          Fbc attribute 'xmlns' is missing from the                             
         <ListOfKeyValuePairs> element.                                         
                                                                                
WARNING  E1: SBML component consistency (fbc, L1, code)        validation.py:186
         [Warning] Attributes allowed on <keyValuePair>.                        
         A <keyValuePair> object must have the required                         
         attribute 'fbc:key', and may have the optional                         
         attributes 'fbc:id', 'fbc:name', 'fbc:value' and                       
         'fbc:uri'. No other attributes from the SBML Level 3                   
         Flux Balance Constraints namespaces are permitted on                   
         a <keyValuePair> object.                                               
          Fbc attribute 'xmlns' is missing from the                             
         <ListOfKeyValuePairs> element. 

@fbergmann
Copy link
Member

it will take a bit with the xmlns one, as namespaces are not just normal attributes. so it needs to be handled differently (and probably also requires changes in the validation code (after tall the xmlns is not missing, it is present, it just is the FBC one)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants