/** * Creates the data generators for SEDML. */ void CSEDMLExporter::createDataGenerators(CCopasiDataModel & dataModel, std::string & taskId, CCopasiTask* task) { const CModel* pModel = dataModel.getModel(); std::vector<std::string> stringsContainer; //split string container if (pModel == NULL) CCopasiMessage(CCopasiMessage::ERROR, "SED-ML: No model for this SED-ML document. An SBML model must exist for every SED-ML document."); SedPlot2D* pPSedPlot; SedCurve* pCurve; // = pPSedPlot->createCurve(); //create generator for special varibale time const CCopasiObject* pTime = static_cast<const CCopasiObject *>(dataModel.getModel()->getObject(CCopasiObjectName("Reference=Time"))); SedDataGenerator *pTimeDGenp = this->mpSEDMLDocument->createDataGenerator(); pTimeDGenp->setId("time"); pTimeDGenp->setName(pTime->getObjectName()); SedVariable *pTimeVar = pTimeDGenp->createVariable(); pTimeVar->setId("var_time"); pTimeVar->setTaskReference(taskId); pTimeVar->setSymbol(SEDML_TIME_URN); pTimeDGenp->setMath(SBML_parseFormula(pTimeVar->getId().c_str())); size_t i, imax = dataModel.getPlotDefinitionList()->size(); SedDataGenerator *pPDGen; if (imax == 0 && (task == NULL || task->getReport().getTarget().empty())) CCopasiMessage(CCopasiMessage::ERROR, "SED-ML: No plot/report definition for this SED-ML document."); // export report if (task != NULL && !task->getReport().getTarget().empty()) { CReportDefinition* def = task->getReport().getReportDefinition(); if (def != NULL) { SedReport* pReport = mpSEDMLDocument->createReport(); std::string name = def->getObjectName(); SEDMLUtils::removeCharactersFromString(name, "[]"); // pReport->setId(SEDMLUtils::getNextId("report", mpSEDMLDocument->getNumOutputs())); pReport->setName(name); std::vector<CRegisteredObjectName> header = *def->getHeaderAddr(); std::vector<CRegisteredObjectName> body = def->isTable() ? *def->getTableAddr() : *def->getBodyAddr(); int dsCount = 0; for (size_t i = 0; i < body.size(); ++i) { CRegisteredObjectName& current = body[i]; if (current == def->getSeparator().getCN()) continue; CCopasiObject *object = dataModel.getDataObject(current); if (object == NULL) continue; const std::string& typeX = object->getObjectName(); std::string xAxis = object->getObjectDisplayName(); std::string targetXPathStringX = SEDMLUtils::getXPathAndName(xAxis, typeX, pModel, dataModel); if (object->getCN() == pTime->getCN()) pPDGen = pTimeDGenp; else pPDGen = createDataGenerator( this->mpSEDMLDocument, xAxis, targetXPathStringX, taskId, i, 0 ); SedDataSet* pDS = pReport->createDataSet(); pDS->setId(SEDMLUtils::getNextId("ds", ++dsCount)); if (def->isTable()) { CCopasiObject *headerObj = NULL; if (header.size() > i) headerObj = dataModel.getDataObject(header[i]); else headerObj = dataModel.getDataObject(body[i]); if (headerObj != NULL) pDS->setLabel(headerObj->getObjectDisplayName()); else pDS->setLabel(xAxis); } else pDS->setLabel(xAxis); pDS->setDataReference(pPDGen->getId()); } } } // export plots for (i = 0; i < imax; i++) { pPSedPlot = this->mpSEDMLDocument->createPlot2D(); const CPlotSpecification* pPlot = (*dataModel.getPlotDefinitionList())[i]; std::string plotName = pPlot->getObjectName(); SEDMLUtils::removeCharactersFromString(plotName, "[]"); pPSedPlot->setId(SEDMLUtils::getNextId("plot", mpSEDMLDocument->getNumOutputs())); pPSedPlot->setName(plotName); size_t j, jmax = pPlot->getItems().size(); for (j = 0; j < jmax; j++) { const CPlotItem* pPlotItem = pPlot->getItems()[j]; CCopasiObject *objectX, *objectY; if (pPlotItem->getChannels().size() >= 1) { objectX = dataModel.getDataObject(pPlotItem->getChannels()[0]); } else { CCopasiMessage(CCopasiMessage::WARNING, "SED-ML: Can't export plotItem '%s', as it has no data channel.", pPlotItem->getObjectName().c_str()); continue; } if (objectX == NULL) { CCopasiMessage(CCopasiMessage::WARNING, "SED-ML: Can't export plotItem '%s' variable '%s', as it cannot be resolved.", pPlotItem->getObjectName().c_str(), pPlotItem->getChannels()[0].c_str()); continue; } bool xIsTime = objectX->getCN() == pTime->getCN(); if (pPlotItem->getChannels().size() >= 2) { objectY = dataModel.getDataObject(pPlotItem->getChannels()[1]); } else { CCopasiMessage(CCopasiMessage::WARNING, "SED-ML: Can't export plotItem '%s', as it has only 1 data channel.", pPlotItem->getObjectName().c_str()); continue; } if (objectY == NULL) { CCopasiMessage(CCopasiMessage::WARNING, "SED-ML: Can't export plotItem '%s' variable '%s', as it cannot be resolved.", pPlotItem->getObjectName().c_str(), pPlotItem->getChannels()[1].c_str()); continue; } const std::string& type = objectY->getObjectName(); std::string yAxis = objectY->getObjectDisplayName(); std::string sbmlId = yAxis; std::string targetXPathString = SEDMLUtils::getXPathAndName(sbmlId, type, pModel, dataModel); if (targetXPathString.empty()) { CCopasiMessage(CCopasiMessage::WARNING, "SED-ML: Can't export plotItem '%s' variable '%s', as no xpath expression for it could be generated.", pPlotItem->getObjectName().c_str(), pPlotItem->getChannels()[1].c_str()); continue; } pPDGen = createDataGenerator( this->mpSEDMLDocument, sbmlId, targetXPathString, taskId, i, j ); pPDGen->setName(yAxis); pCurve = pPSedPlot->createCurve(); std::ostringstream idCurveStrStream; idCurveStrStream << "p"; idCurveStrStream << i + 1; idCurveStrStream << "_curve_"; idCurveStrStream << j + 1; pCurve->setId(idCurveStrStream.str()); pCurve->setLogX(pPlot->isLogX()); pCurve->setLogY(pPlot->isLogY()); pCurve->setName(yAxis); pCurve->setYDataReference(pPDGen->getId()); if (xIsTime) { pCurve->setXDataReference(pTimeDGenp->getId()); } else { const std::string& typeX = objectX->getObjectName(); std::string xAxis = objectX->getObjectDisplayName(); std::string targetXPathStringX = SEDMLUtils::getXPathAndName(xAxis, typeX, pModel, dataModel); pPDGen = createDataGenerator( this->mpSEDMLDocument, xAxis, targetXPathStringX, taskId, i, j ); pCurve->setXDataReference(pPDGen->getId()); } } } }
/** * Creates the data generators for SEDML. */ void CSEDMLExporter::createDataGenerators(CCopasiDataModel & dataModel, std::string & taskId) { const CModel* pModel = dataModel.getModel(); std::vector<std::string> stringsContainer; //split string container if (pModel == NULL) CCopasiMessage(CCopasiMessage::ERROR, "No model for this SEDML document. An SBML model must exist for every SEDML document."); SedPlot2D* pPSedPlot; SedCurve* pCurve; // = pPSedPlot->createCurve(); //create generator for special varibale time const CCopasiObject* pTime = static_cast<const CCopasiObject *>(dataModel.getModel()->getObject(CCopasiObjectName("Reference=Time"))); SedDataGenerator *pTimeDGenp = this->mpSEDMLDocument->createDataGenerator(); pTimeDGenp->setId("time"); pTimeDGenp->setName(pTime->getObjectName()); SedVariable *pTimeVar = pTimeDGenp->createVariable(); pTimeVar->setId("var_time"); pTimeVar->setTaskReference(taskId); pTimeVar->setSymbol(SEDML_TIME_URN); pTimeDGenp->setMath(SBML_parseFormula(pTimeVar->getId().c_str())); size_t i, imax = dataModel.getPlotDefinitionList()->size(); SedDataGenerator *pPDGen; if (!imax) CCopasiMessage(CCopasiMessage::ERROR, "No plot definition for this SEDML document."); for (i = 0; i < imax; i++) { pPSedPlot = this->mpSEDMLDocument->createPlot2D(); const CPlotSpecification* pPlot = (*dataModel.getPlotDefinitionList())[i]; std::string plotName = pPlot->getObjectName(); SEDMLUtils::removeCharactersFromString(plotName, "[]"); pPSedPlot->setId(SEDMLUtils::getNextId("plot", mpSEDMLDocument->getNumOutputs())); pPSedPlot->setName(plotName); size_t j, jmax = pPlot->getItems().size(); for (j = 0; j < jmax; j++) { const CPlotItem* pPlotItem = pPlot->getItems()[j]; CCopasiObject *objectX, *objectY; if (pPlotItem->getChannels().size() >= 1) objectX = dataModel.getDataObject(pPlotItem->getChannels()[0]); bool xIsTime = objectX->getCN() == pTime->getCN(); if (pPlotItem->getChannels().size() >= 2) objectY = dataModel.getDataObject(pPlotItem->getChannels()[1]); const std::string& type = objectY->getObjectName(); std::string yAxis = objectY->getObjectDisplayName(); std::string targetXPathString = SEDMLUtils::getXPathAndName(yAxis, type, pModel, dataModel); if (targetXPathString.empty()) { continue; } pPDGen = createDataGenerator( this->mpSEDMLDocument, yAxis, targetXPathString, taskId, i, j ); pCurve = pPSedPlot->createCurve(); std::ostringstream idCurveStrStream; idCurveStrStream << "p"; idCurveStrStream << i + 1; idCurveStrStream << "_curve_"; idCurveStrStream << j + 1; pCurve->setId(idCurveStrStream.str()); pCurve->setLogX(pPlot->isLogX()); pCurve->setLogY(pPlot->isLogY()); pCurve->setYDataReference(pPDGen->getId()); if (xIsTime) { pCurve->setXDataReference(pTimeDGenp->getId()); } else { const std::string& typeX = objectX->getObjectName(); std::string xAxis = objectX->getObjectDisplayName(); std::string targetXPathStringX = SEDMLUtils::getXPathAndName(xAxis, typeX, pModel, dataModel); pPDGen = createDataGenerator( this->mpSEDMLDocument, xAxis, targetXPathStringX, taskId, i, j ); pCurve->setXDataReference(pPDGen->getId()); } } } }
LIBSEDML_CPP_NAMESPACE_USE int main (int argc, char* argv[]) { if (argc != 2) { cout << endl << "Usage: create_sedml output-filename" << endl << endl; return 2; } // create the document SedDocument doc(1,3); doc.setAnnotation("<test xmlns='http://test.org/test/annotation' attribute='test' />"); { SedDataDescription* dataDesc = doc.createDataDescription(); dataDesc->setId("oscli"); dataDesc->setName("Oscli Timecourse data"); dataDesc->setSource("oscli.numl"); DimensionDescription* dimDesc = dataDesc->createDimensionDescription(); CompositeDescription* timeDesc = new CompositeDescription(); timeDesc->setIndexType("double"); timeDesc->setId("time"); timeDesc->setName("time"); CompositeDescription* speciesDesc = timeDesc->createCompositeDescription(); speciesDesc->setIndexType("string"); speciesDesc->setId("SpeciesIds"); speciesDesc->setName("SpeciesIds"); AtomicDescription* concentrationDesc = speciesDesc->createAtomicDescription(); concentrationDesc->setValueType("double"); concentrationDesc->setName("Concentrations"); dimDesc->appendAndOwn(timeDesc); SedDataSource* dataSource = dataDesc->createDataSource(); dataSource->setId("dataS1"); SedSlice* slice = dataSource->createSlice(); slice->setReference("SpeciesIds"); slice->setValue("S1"); dataSource = dataDesc->createDataSource(); dataSource->setIndexSet("time"); } { // create a first model referencing an sbml file SedModel *model = doc.createModel(); model->setId("model1"); model->setSource("file.xml"); model->setLanguage("urn:sedml:sbml"); // create a second model modifying a variable of that other sbml file model = doc.createModel(); model->setId("model2"); model->setSource("model1"); model->setLanguage("urn:sedml:sbml"); // change a paramerter 'k' to 0.1 SedChangeAttribute* change = model->createChangeAttribute(); change->setTarget("/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id='k']/@value"); change->setNewValue("0.1"); // remove species 's1' SedRemoveXML* remove = model->createRemoveXML(); remove->setTarget("/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id='S1']"); // add another species 's1' using addxml SedAddXML* addXml = model->createAddXML(); addXml->setTarget("/sbml:sbml/sbml:model/sbml:listOfSpecies"); addXml->setNewXML(XMLNode::convertStringToXMLNode("<species xmlns='http://www.sbml.org/sbml/level2' id='S1' boundaryCondition='false' initialConcentration='0' compartment='compartment' />")); // replace 's1' one more time by a better one SedChangeXML* changeXML = model->createChangeXML(); changeXML->setTarget("/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id='S1']"); changeXML->setNewXML(XMLNode::convertStringToXMLNode("<species xmlns='http://www.sbml.org/sbml/level2' id='S1' boundaryCondition='false' initialConcentration='10' compartment='compartment' />")); // now for something tricky we want to update the initialConcentration of 'S2' to be // half what it was in the original model SedComputeChange* compute = model->createComputeChange(); compute->setTarget("/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id="S2"]/@initialConcentration"); SedVariable *variable = compute->createVariable(); variable->setId("S2"); variable->setModelReference("model1"); variable->setTarget("/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id='S2']"); compute->setMath(SBML_parseFormula("S2 / 2")); } // create simulation SedUniformTimeCourse* tc = doc.createUniformTimeCourse(); tc->setId("sim1"); tc->setInitialTime(0.0); tc->setOutputStartTime(0.0); tc->setOutputEndTime(10.0); tc->setNumberOfPoints(1000); // need to set the correct KISAO Term SedAlgorithm* alg = tc->createAlgorithm(); alg->setKisaoID("KISAO:0000019"); SedAlgorithmParameter* algParam = alg->createAlgorithmParameter(); algParam ->setNotes("<p xmlns='http://www.w3.org/1999/xhtml'>This is the absolute tolerance</p>"); algParam ->setKisaoID("KISAO:0000211"); algParam ->setValue("1e-12"); // add annotation tc->setAnnotation("<test xmlns='http://test.org/test/simulation/annotation' attribute='uniform time course' />"); alg->setAnnotation("<test xmlns='http://test.org/test/simulation/annotation' attribute='algorithm' />"); // create one step SedOneStep* step = doc.createOneStep(); step->setId("sim2"); step->setStep(0.1); alg = step->createAlgorithm(); alg->setKisaoID("KISAO:0000019"); // create steady state SedSteadyState* steady = doc.createSteadyState(); steady->setId("sim3"); alg = steady->createAlgorithm(); alg->setKisaoID("KISAO:0000282"); // create a task that uses the simulation and the model above SedTask* task = doc.createTask(); task->setId("task1"); task->setModelReference("model1"); task->setSimulationReference("sim1"); task = doc.createTask(); task->setId("task2"); task->setModelReference("model1"); task->setSimulationReference("sim2"); SedRepeatedTask* repeat = doc.createRepeatedTask(); repeat->setId("task3"); repeat->setRangeId("index"); repeat->setResetModel(false); SedUniformRange* index = repeat->createUniformRange(); index->setId("index"); index->setStart(0); index->setEnd(10); index->setNumberOfPoints(100); index->setType("linear"); SedFunctionalRange* current = repeat->createFunctionalRange(); current->setId("current"); current->setRange("index"); current->setMath(SBML_parseFormula("piecewise(8, lt(index, 1), 0.1, and(geq(index, 4), lt(index, 6)), 8)")); SedVectorRange* vrange = repeat->createVectorRange(); vrange->setId("vRange"); vrange->addValue(8); vrange->addValue(4); vrange->addValue(0.1); SedSetValue* setValue = repeat->createTaskChange(); setValue->setTarget("/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id='J0_v0']"); setValue->setRange("current"); setValue->setModelReference("model1"); setValue->setMath(SBML_parseFormula("current")); SedSubTask* subTask = repeat->createSubTask(); subTask->setTask("task1"); subTask->setOrder(1); // add a DataGenerator to hold the output for time SedDataGenerator* dg = doc.createDataGenerator(); dg->setId("time"); dg->setName("time"); SedVariable* var = dg->createVariable(); var->setId("v0"); var->setName("time"); var->setTaskReference("task1"); var->setSymbol("urn:sedml:symbol:time"); dg->setMath(SBML_parseFormula("v0")); // and one for S1 dg = doc.createDataGenerator(); dg->setId("S1"); dg->setName("S1"); var = dg->createVariable(); var->setId("v1"); var->setName("S1"); var->setTaskReference("task1"); var->setTarget("/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id='S1']"); dg->setMath(SBML_parseFormula("v1")); // add a report SedReport* report = doc.createReport(); report->setId("r1"); report->setName("report 1"); SedDataSet* set = report->createDataSet(); set->setId("ds1"); set->setLabel("time"); set->setDataReference("time"); set = report->createDataSet(); set->setId("ds2"); set->setLabel("S1"); set->setDataReference("S1"); // add a 2d plot SedPlot2D* plot = doc.createPlot2D(); plot->setId("p1"); plot->setName("S1 Timecourse"); SedCurve* curve = plot->createCurve(); curve->setId("c1"); curve->setName("S1"); curve->setLogX(false); curve->setLogY(false); curve->setXDataReference("time"); curve->setYDataReference("S1"); // add a 3D Plot SedPlot3D* plot2 = doc.createPlot3D(); plot2->setId("p2"); plot2->setName("dunno"); SedSurface* surf = plot2->createSurface(); surf->setId("surf1"); surf->setName("S1"); surf->setLogX(false); surf->setLogY(false); surf->setLogZ(false); surf->setXDataReference("time"); surf->setYDataReference("S1"); surf->setZDataReference("S1"); // write the document writeSedML(&doc, argv[1]); return 0; }