def test_biomodel_merge(tmp_path: Path) -> None: """Test model merging.""" merge_dir = DATA_DIR / "manipulation" / "merge" # dictionary of ids & paths of models which should be combined # here we just bring together the first Biomodels model_ids = ["BIOMD000000000{}".format(k) for k in range(1, 5)] model_paths = dict(zip(model_ids, [merge_dir / f"{mid}.xml" for mid in model_ids])) # merge model out_dir = tmp_path / "output" out_dir.mkdir() doc = merge.merge_models(model_paths, output_dir=out_dir, validate=False) assert doc is not None vresults = validation.validate_doc(doc, units_consistency=False) assert vresults.error_count == 0 assert vresults.warning_count == 0 assert vresults.all_count == 0 # flatten the model doc_flat = comp.flatten_sbml_doc(doc) assert doc_flat is not None vresults = validation.validate_doc(doc_flat, units_consistency=False) assert vresults.error_count == 0 assert vresults.warning_count in [0, 74] assert vresults.all_count in [0, 74] merged_sbml_path = out_dir / "merged_flat.xml" write_sbml(doc_flat, filepath=merged_sbml_path) assert merged_sbml_path.exists()
def read_sbml( source: Union[Path, str], promote: bool = False, validate: bool = False, log_errors: bool = True, units_consistency: bool = True, modeling_practice: bool = True, internal_consistency: bool = True, ) -> libsbml.SBMLDocument: """Read SBMLDocument from given source. :param source: SBML path or string :param promote: promote local parameters to global parameters :param validate: validate file :param log_errors: validation flag :param units_consistency: validation flag :param modeling_practice: validation flag :param internal_consistency: validation flag :return: SBMLDocument """ if isinstance(source, str) and "<sbml" in source: doc = libsbml.readSBMLFromString(source) else: if not isinstance(source, Path): logger.error(f"All SBML paths should be of type 'Path', but " f"'{type(source)}' found for: {source}") source = Path(source) doc = libsbml.readSBMLFromFile( str(source)) # type: libsbml.SBMLDocument # promote local parameters if promote: doc = promote_local_variables(doc) # type: libsbml.SBMLDocument # check for errors if doc.getNumErrors() > 0: if doc.getError(0).getErrorId() == libsbml.XMLFileUnreadable: err_message = f"Unreadable SBML file" elif doc.getError(0).getErrorId() == libsbml.XMLFileOperationError: err_message = "Problems reading SBML file: XMLFileOperationError" else: err_message = "SBMLDocumentErrors encountered while reading the SBML file." validation.log_sbml_errors_for_doc(doc) err_message = f"read_sbml error '{source}': {err_message}" logger.error(err_message) if validate: validation.validate_doc( doc=doc, name=source, log_errors=log_errors, units_consistency=units_consistency, modeling_practice=modeling_practice, internal_consistency=internal_consistency, ) return doc
def _create_sbml(self) -> None: """Create the SBMLDocument.""" self._init_sbml_model() self.interpolators = Interpolation.create_interpolators( self.data, self.method) for interpolator in self.interpolators: Interpolation.add_interpolator_to_model(interpolator, self.model) # validation of SBML document validate_doc(self.doc, units_consistency=False)
def validate_sbml( source: Union[str, Path], name: str = None, log_errors: bool = True, units_consistency: bool = True, modeling_practice: bool = True, internal_consistency: bool = True, ) -> validation.ValidationResult: """Check given SBML source. :param source: SBML path or string :param name: identifier or path for report :param units_consistency: boolean flag units consistency :param modeling_practice: boolean flag modeling practise :param internal_consistency: boolean flag internal consistency :param log_errors: boolean flag of errors should be logged :return: Nall, Nerr, Nwarn (number of all warnings/errors, errors and warnings) """ doc = read_sbml(source) return validation.validate_doc( doc, name=name, log_errors=log_errors, units_consistency=units_consistency, modeling_practice=modeling_practice, internal_consistency=internal_consistency, )
def test_biomodel_merge(tmp_path): """Test model merging. Using the pytest tmpdir fixture :param tmpdir: :return: """ merge_dir = DATA_DIR / "manipulation" / "merge" # dictionary of ids & paths of models which should be combined # here we just bring together the first Biomodels model_ids = ["BIOMD000000000{}".format(k) for k in range(1, 5)] model_paths = dict( zip(model_ids, [merge_dir / f"{mid}.xml" for mid in model_ids])) # merge model out_dir = tmp_path / "output" out_dir.mkdir() doc = merge.merge_models(model_paths, out_dir=out_dir, validate=False) assert doc is not None Nall, Nerr, Nwarn = validation.validate_doc(doc, units_consistency=False) assert Nerr == 0 assert Nwarn == 0 assert Nall == 0 # flatten the model doc_flat = comp.flatten_sbml_doc(doc) assert doc_flat is not None Nall, Nerr, Nwarn = validation.validate_doc(doc_flat, units_consistency=False) assert Nerr == 0 assert Nwarn in [0, 74] assert Nall in [0, 74] merged_sbml_path = out_dir / "merged_flat.xml" write_sbml(doc_flat, filepath=merged_sbml_path) assert merged_sbml_path.exists()
def create_examples(tmp: bool = False) -> None: """Create distrib examples.""" functions = [ distrib_normal, distrib_all, uncertainty, ] for f_creator in functions: name = f_creator.__name__ print(name) # distrib_example1() doc = f_creator() sbml = libsbml.writeSBMLToString(doc) print("-" * 80) print(sbml) print("-" * 80) if tmp: sbml_path = tempfile.mktemp() else: sbml_path = f"./{name}.xml" libsbml.writeSBMLToFile(doc, sbml_path) validation.validate_doc(doc)
def check_model_dict(d: Dict) -> libsbml.SBMLDocument: """Check that no errors.""" # create model and print SBML core_model = CoreModel.from_dict(model_dict=d) core_model.create_sbml() assert core_model.doc is not None vresults = validate_doc(core_model.doc, units_consistency=False) # debugging if vresults.error_count > 0: doc = core_model.doc # type: libsbml.SBMLDocument error_log = doc.getErrorLog() # type: libsbml.SBMLErrorLog print(error_log.toString()) assert vresults.is_valid() return core_model.doc
def flatten_external_model_definitions( doc: libsbml.SBMLDocument, validate: bool = False) -> libsbml.SBMLDocument: """Converts all ExternalModelDefinitions to ModelDefinitions. I.e. the definition of models in external files are read and directly included in the top model. The resulting comp model consists than only of a single file. The model refs in the submodel do not change in the process, so no need to update the submodels. :param doc: SBMLDocument :param validate: validation flag :return: SBMLDocument with ExternalModelDefinitions replaced """ logger.debug("* flattenExternalModelDefinitions") # FIXME: handle multiple levels of hierarchies. Recursively to handle the ExternalModelDefinitions of submodels logger.warning( "flattenExternalModelDefinitions is experimental and does not work recursively!" ) comp_doc = doc.getPlugin("comp") if comp_doc is None: logger.warning( "Model is not a comp model, no ExternalModelDefinitions") return doc emd_list = comp_doc.getListOfExternalModelDefinitions() if (emd_list is None) or (len(emd_list) == 0): # no ExternalModelDefinitions logger.warning("Model does not contain any ExternalModelDefinitions") return doc else: emd_ids = [] for emd in emd_list: logger.debug(emd) emd_ids.append(emd.getId()) # get the model definition from the model ref_model = emd.getReferencedModel() ref_doc = ref_model.getSBMLDocument() # print(ref_model) for k in range(ref_doc.getNumPlugins()): plugin = ref_doc.getPlugin(k) # print(k, plugin) # enable the package on the main SBMLDocument uri = plugin.getURI() prefix = plugin.getPrefix() doc.enablePackage(uri, prefix, True) # print("\n") # add model definition for model md = libsbml.ModelDefinition(ref_model) comp_doc.addModelDefinition(md) # remove the emds afterwards for emd_id in emd_ids: # remove the emd from the model comp_doc.removeExternalModelDefinition(emd_id) # validate if validate: validate_doc(doc) return doc
# dictionary of ids & paths of models which should be combined # here we just bring together the first Biomodels model_ids = ["BIOMD000000000{}".format(k) for k in range(1, 5)] model_paths = dict( zip(model_ids, [os.path.join(merge_dir, "{}.xml".format(mid)) for mid in model_ids])) pprint(model_paths) # create merged model output_dir = os.path.join(merge_dir, 'output') doc = manipulation.merge_models(model_paths, out_dir=output_dir, validate=False) # validate Nall, Nerr, Nwarn = validation.validate_doc(doc, units_consistency=False) assert Nerr == 0 assert Nwarn == 0 assert Nall == 0 # write the merged model print(libsbml.writeSBMLToString(doc)) libsbml.writeSBMLToFile(doc, os.path.join(output_dir, "merged.xml")) # flatten the merged model doc_flat = comp.flatten_sbml(doc) Nall, Nerr, Nwarn = validation.validate_doc(doc_flat, units_consistency=False) libsbml.writeSBMLToFile(doc_flat, os.path.join(output_dir, "merged_flat.xml")) # In[ ]:
Species( sid="S1", initialConcentration=10.0, compartment="C", hasOnlySubstanceUnits=False, boundaryCondition=True, ) ], "parameters": [Parameter(sid="k1", value=1.0)], "reactions": [ Reaction(sid="R1", equation="S1 ->", formula=("k1 * S1 * sin(time)", None)) ], "assignments": [], } m2_dict = m1_dict.copy() m2_dict["mid"] = "m2_boundary_condition" m2_dict["assignments"] = [AssignmentRule("S1", 20.0)] core_model = CoreModel.from_dict(model_dict=m1_dict) core_model.create_sbml() core_model.write_sbml("m1_boundary_condition.xml") [Nall, Nerr, Nwar] = validate_doc(core_model.doc, units_consistency=False) core_model = CoreModel.from_dict(model_dict=m2_dict) core_model.create_sbml() core_model.write_sbml("m2_boundary_condition.xml") [Nall, Nerr, Nwar] = validate_doc(core_model.doc, units_consistency=False)