sbmlteam / libsbml

LibSBML is a native library for reading, writing and manipulating files and data streams containing the Systems Biology Markup Language (SBML). It offers language bindings for C, C++, C#, Java, JavaScript, MATLAB, Perl, PHP, Python, R and Ruby.
https://sbml.org/software/libsbml
Other
41 stars 29 forks source link

Annotations cannot be written through the Perl binding #208

Closed smoretti closed 2 years ago

smoretti commented 2 years ago

Hi

I don't know if this is the right place or still on sourceforge?

I have CV terms and would like to add them to my model

$SBML_model->addCVTerm($CV);

this first method looks to work, but not the next ones

$SBML_model->setAnnotation($CV);
$SBML_model->appendAnnotation();

I got those errors:

No matching function for overloaded 'Model_setAnnotation'
No matching function for overloaded 'Model_appendAnnotation'

Could it be an issue happening because swig cannot convert all C++ methods in Perl? How to solve that?

I have already reported several issues with the Perl binding https://sourceforge.net/p/sbml/libsbml/476/ https://sourceforge.net/p/sbml/libsbml/473/

It happens with libSBML 5.18.0 and libSBML 5.19.0, compiled on Linux and Mac

fbergmann commented 2 years ago

Yes, here at github it would be the right place to report these issues. We have some perl examples that used to work. Could you verify, whether addCVTerms, , addModelHistory, addingEvidenceCodes, appendAnnotation. Work for you or cause the same issues? If they have the same issue, please let us know what SWIG version you were using and i'll try to reproduce locally.

While the functions do not exist on the model class, they do exist on the base class and SWIG should have figured it out. Can you verify that the workaround using LibSBMLc::SBase_setAnnotation or LibSBMLc::SBase_appendAnnotation would work?

smoretti commented 2 years ago

appendAnnotation causes the same issue

addCVTerms, addModelHistory and addingEvidenceCodes cause this error: Can't locate object method "addingEvidenceCodes" via package "LibSBML::Model"

Maybe I don't call them at the right place, or with the right object.

On Mac I use SWIG Version 4.0.2 and Perl 5.34.0; on Linux I used SWIG Version 3.0.10 and Perl 5.24.0


How do you call LibSBMLc::SBase_setAnnotation?

I got this error message: No matching function for overloaded 'SBase_setAnnotation'

fbergmann commented 2 years ago

I'm afraid i can't reproduce that, so let me describe what i did (and please excuse the horrible way of doing things, i hardly know anything about perl):

At this point the perl bindings are installed into ../install_perl, so i changed into that: cd ../install_perl/lib, and now i'm free to call libsbml from perl. Since i dont know a better way, for the examples here, i just always attach the include path: which for me is -I ~/install_perl/lib/perl5/site_perl/5.24.1/x86_64-linux-gnu-thread-multi/ to all perl invocations. Since that is a lot to type:

export INC_SBML=~/install_perl/lib/perl5/site_perl/5.24.1/x86_64-linux-gnu-thread-multi/

Now i change to the perl example folder (cd ~/libsbml/examples/perl), and am free to call all the examples:


> perl -I$INC_SBML createExampleSBML.pl 
Wrote file 'enzymaticreaction.xml'
Wrote file 'units.xml'
Wrote file 'functiondef.xml'

> perl -I$INC_SBML addCVTerms.pl enzymaticreaction.xml out.xml

now i have a file out.xml with cv terms in it. similarly the other examples are working too (just there was a typo in the appendAnnotation one, and i filed a PR for it), there was a dangling brace at the end of the file.

But basically it is all working for me and i dont get e message about overloaded functions. So i will need to know more about the precise steps and calls you are making.

smoretti commented 2 years ago

Your example scripts work with my installation, maybe because they don't use setAnnotation.

I will try to follow what these scripts do to add annotations. Will let you know.


Also I don't build libSBML the same way you did (not with ninja, and with expat instead of libxml). Maybe it has consequences on the Perl binding.

cmake -DCMAKE_INSTALL_PREFIX=../install_perl -DWITH_CHECK=ON -DWITH_SWIG=ON -DWITH_PERL=ON -DWITH_EXPAT=ON -DWITH_LIBXML=OFF -DENABLE_{LAYOUT,QUAL,COMP,FBC,RENDER,GROUPS,MULTI,DISTRIB,ARRAYS,DYN,REQ,SPATIAL}=ON ..
make
make check
make install


A side note, how do you activate the support for the SBML 'req' package?

With the command above, all packages are ON but req.

smoretti commented 2 years ago

Also I currently want to add annotations for the model attribute itself.

And setNotes works for it

fbergmann commented 2 years ago

The appendAnnotation example adds annotations to the model, which could be what you are looking for.

The required elements package has been discontinued, and is not recommended for use. That being said, if you want to enable it, you'd add the cmake option -DENABLE_REQUIREDELEMENTS=ON.

smoretti commented 2 years ago

appendAnnotation.pl does not work for me. Could it be linked to the compilation with expat and not libxml?

Thanks for the required elements package

smoretti commented 2 years ago

Could you try with my script and your Perl libSBML settings? It is available here: https://github.com/MetaNetX/MNXtools

cd MNXtools/bin/
./TSV_to_SBML.pl -t ../examples/ECOLI/bigg_iML1515/mapped/
fbergmann commented 2 years ago

Ok .. thank you for the link to the code, that explains what is going on. Annotations can only be added to elements, that have a metaId set. After that, your call to addCVTerm already would have added it to the model. No need to call setAnnotation / appendAnnotation. The error message about the unknown overload comes, as setAnnotation / appendAnnotation work with XMLNode objects or strings. Not with CVTerms. So the fix to your script would be


diff --git a/bin/TSV_to_SBML.pl b/bin/TSV_to_SBML.pl
index 11f32a2..1551e52 100755
--- a/bin/TSV_to_SBML.pl
+++ b/bin/TSV_to_SBML.pl
@@ -99,6 +99,12 @@ if ( $TSV_directory ){
         }
         $SBML_model->setNotes($notes);
     }
+
+    if (!$SBML_model->isSetMetaId()){
+        # its vital to set a metaId first, otherwise the cvterms cant be added
+        $SBML_model->setMetaId($SBML_model->getId());
+    }
+
     #annotations
     my ($taxid) = map { $_->[1] } grep { $_->[0] =~ /Taxid/ } $MetNet->get_mnet_info($mnet_id);
     if ( $taxid && $taxid =~ /^\d+$/ ){
@@ -107,8 +113,8 @@ if ( $TSV_directory ){
         $CV->setBiologicalQualifierType($LibSBML::BQB_HAS_TAXON);
         $CV->addResource($Constants::identifiers_taxid.$taxid);
         $SBML_model->addCVTerm($CV);
-        $SBML_model->setAnnotation($CV);
-        $SBML_model->appendAnnotation();
+        #$SBML_model->setAnnotation($CV);
+        #$SBML_model->appendAnnotation();
 #FIXME swig issue that does not make setAnnotation available???
     }

then the expexted annotation is added:

    <annotation>
      <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:vCard4="http://www.w3.org/2006/vcard/ns#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/">
        <rdf:Description rdf:about="#iML1515">
          <bqbiol:hasTaxon>
            <rdf:Bag>
              <rdf:li rdf:resource="https://identifiers.org/taxonomy:83333"/>
            </rdf:Bag>
          </bqbiol:hasTaxon>
        </rdf:Description>
      </rdf:RDF>
    </annotation>
smoretti commented 2 years ago

It works! I completely missed that point

Many thanks