END_TEST START_TEST(test_FbcExtension_convert_and_write) { string file(TestDataDirectory); file += "/fbc_ga_example.xml"; SBMLDocument* document = readSBMLFromFile(file.c_str()); document->printErrors(); fail_unless(document->getNumErrors(LIBSBML_SEV_ERROR) == 0); fail_unless(document->getModel() != NULL); // convert to v2 { ConversionProperties props; props.addOption("convert fbc v1 to fbc v2", true); props.addOption("strict", true); int result = document->convert(props); // ensure that all is well with the model fail_unless(result == LIBSBML_OPERATION_SUCCESS); fail_unless(document->getLevel() == 3); fail_unless(document->getVersion() == 1); fail_unless(document->getPlugin("fbc") != NULL); fail_unless(document->getPlugin("fbc")->getPackageVersion() == 2); } // ensure that all the v1 stuff is no longer there FbcModelPlugin* mplug = dynamic_cast<FbcModelPlugin*>( document->getModel()->getPlugin("fbc")); fail_unless(mplug != NULL); fail_unless(mplug->isSetStrict()); fail_unless(mplug->getNumGeneAssociations() == 0); fail_unless(mplug->getNumFluxBounds() == 0); delete document; }
Model* CompModelPlugin::flattenModel() const { //First make a copy of our parent (the model to be flattened): const Model* parent = static_cast<const Model*>(getParentSBMLObject()); if (parent==NULL) { return NULL; } //doc needs to be non-const so that the error messages can be updated. Otherwise, nothing changes. SBMLDocument* doc = const_cast<SBMLDocument*>(getSBMLDocument()); if (doc==NULL) { return NULL; } //Set the original document so that it can find the model definitions //and external model definitions while we flatten. Model* flat = parent->clone(); flat->setSBMLDocument(doc); CompModelPlugin* flatplug = static_cast<CompModelPlugin*>(flat->getPlugin(getPrefix())); // Now instantiate its submodels and // follow all renaming/deletion/replacement rules. vector<const Model*> submods; int success = flatplug->instantiateSubmodels(); if (success != LIBSBML_OPERATION_SUCCESS) { //instantiateSubmodels sets its own error messages. delete flat; return NULL; } //Now start the aggregation process. //This goes from the bottom up, calling 'appendFrom' iteratively //(from the plugin). for (unsigned int sm=0; sm<flatplug->getNumSubmodels(); sm++) { Model* submodel = flatplug->getSubmodel(sm)->getInstantiation(); if (submodel==NULL) { //getInstantiation should be calling a cached value by now, but if not, it will set its own error messages. delete flat; return NULL; } CompModelPlugin* submodplug = static_cast<CompModelPlugin*>(submodel->getPlugin(getPrefix())); if (submodplug != NULL) { //Strip the ports from the submodel, as we no longer need them. while (submodplug->getNumPorts() > 0) { delete submodplug->removePort(0); } } success = flat->appendFrom(submodel); if (success != LIBSBML_OPERATION_SUCCESS) { string error = "Unable to flatten model in CompModelPlugin::flattenModel: appending elements from the submodel '" + submodel->getId() + "' to the elements of the parent model failed."; doc->getErrorLog()->logPackageError("comp", CompModelFlatteningFailed, getPackageVersion(), getLevel(), getVersion(), error); delete flat; return NULL; } #ifdef LIBSBML_HAS_PACKAGE_FBC // for an fbc v2 model we need to check that the model element // in the flat document has the fbc:strict attribute // note this can happen if the parent document did not have fbc but // included a submodel from an external document that did if (SBMLExtensionRegistry::isPackageEnabled("fbc")) { FbcModelPlugin *mplugin = static_cast<FbcModelPlugin*> (flat->getPlugin("fbc")); if (mplugin != NULL && mplugin->getPackageVersion() == 2 && mplugin->isSetStrict() == false) { mplugin->setStrict(false); } } #endif // LIBSBML_HAS_PACKAGE_FBC } // Now we clear the saved referenced elements in the local Port objects, // but point them to the new object if necessary. flatplug->resetPorts(); // Next, strip the package info from 'flat'. // We're going to remove everything but the Ports: flatplug->mListOfSubmodels.clear(); flatplug->clearReplacedElements(); flatplug->unsetReplacedBy(); List* allelements = flat->getAllElements(); vector<SBase*> nonReplacedElements; for (unsigned int el=0; el<allelements->getSize(); el++) { SBase* element = static_cast<SBase*>(allelements->get(el)); int type = element->getTypeCode(); if (!(type==SBML_COMP_REPLACEDBY || type==SBML_COMP_REPLACEDELEMENT || type==SBML_COMP_SBASEREF)) { nonReplacedElements.push_back(element); } } // delete the list delete allelements; for (unsigned int el=0; el<nonReplacedElements.size(); el++) { SBase* element = nonReplacedElements[el]; CompSBasePlugin* elplug = static_cast<CompSBasePlugin*>(element->getPlugin(getPrefix())); if (elplug != NULL) { elplug->clearReplacedElements(); elplug->unsetReplacedBy(); } } //Finally, unset the document again. flat->setSBMLDocument(NULL); return flat; }