def test_sbml_level_version(level: int, version: int, tmp_path: Path) -> None: """Test that the various levels and versions of SBML can be generated.""" md = { "mid": "level_version", "compartments": [Compartment(sid="C", value=1.0)], "species": [ 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)", "-")) ], } results = create_model( modules=md, output_dir=tmp_path, tmp=False, units_consistency=False, sbml_level=level, sbml_version=version, ) doc = read_sbml(source=results.sbml_path, validate=False) assert level == doc.getLevel() assert version == doc.getVersion()
def flatten_sbml(sbml_path: Path, filepath=None, leave_ports=True) -> libsbml.SBMLDocument: """Flatten given SBML file. :param sbml_path: Comp SBML Path :param filepath: SBML file to write to :param leave_ports: flat to leave ports in flattened model. :return: flattened SBMLDocument """ # FIXME: not working with relative paths, # necessary to change the working directory to the sbml file directory # to resolve relative links to external model definitions. if not isinstance(sbml_path, Path): sbml_path = Path(sbml_path) working_dir = os.getcwd() os.chdir(str(sbml_path.parent)) doc = read_sbml(source=sbml_path) flat_doc = flatten_sbml_doc(doc, leave_ports=leave_ports, output_path=filepath) # change back the working dir os.chdir(working_dir) return flat_doc
def test_odefac_to_python(sbml_path: Path, tmp_path: Path) -> None: """Create python code for given model.""" doc: libsbml.SBMLDocument = read_sbml(sbml_path) sbml2ode = SBML2ODE(doc=doc) out_path = tmp_path / "model.py" sbml2ode.to_python(out_path) assert out_path.exists()
def test_compartment_value( value: Any, constant: bool, expected: Dict, tmp_path: Path ) -> None: m1 = { "mid": "compartment_value", "compartments": [Compartment(sid="C", value=value, constant=constant)], } result = create_model( modules=m1, output_dir=tmp_path, units_consistency=False, ) doc = read_sbml(source=result.sbml_path) model = doc.getModel() # type: libsbml.Model assert model.getNumCompartments() == expected["compartments"] assert model.getNumInitialAssignments() == expected["initial_assignments"] assert model.getNumRules() == expected["rules"]
def from_sbml(source: Union[Path, str]) -> "SBMLDocumentInfo": """Read model info from SBML.""" doc: libsbml.SBMLDocument = read_sbml(source) return SBMLDocumentInfo(doc=doc)
def merge_models( model_paths: Dict[str, Path], output_dir: Path = None, merged_id: str = "merged", validate: bool = True, ) -> libsbml.SBMLDocument: """Merge models in model path. All models must exist in the same subfolder. Relative paths are set in the merged models. Output directory must exist. :param output_dir: :param merged_id: :param validate: :param model_paths: absolute paths to models :return: """ # necessary to convert models to SBML L3V1 cur_dir = os.getcwd() os.chdir(str(output_dir)) base_dir = None for model_id, path in model_paths.items(): if path.exists(): logging.error(f"Path for SBML file does not exist: {path}") # get base dir of all model files from first file if base_dir is None: base_dir = path.parent else: new_dir = path.parent if not new_dir != base_dir: raise IOError(f"All SBML files for merging must be in same " f"directory: {new_dir} != {base_dir}") # convert to L3V1 path_L3: Path = output_dir / f"{model_id}_L3.xml" # type: ignore doc = read_sbml(path_L3) if doc.getLevel() < SBML_LEVEL: doc.setLevelAndVersion(SBML_LEVEL, SBML_VERSION) write_sbml(doc, path_L3) model_paths[model_id] = path_L3 if validate is True: for path in model_paths: # type: ignore validate_sbml(source=path, name=str(path)) # create comp model merged_doc = create_merged_doc( model_paths, merged_id=merged_id) # type: libsbml.SBMLDocument if validate is True: validate_sbml(path, name=str(path)) # write merged doc f_out = os.path.join(output_dir, "{}.xml".format(merged_id)) # type: ignore libsbml.writeSBMLToFile(merged_doc, f_out) os.chdir(cur_dir) return merged_doc
def merge_models( model_paths: Dict[str, Path], output_dir: Path, merged_id: str = "merged", flatten: bool = True, validate: bool = True, validate_input: bool = True, units_consistency: bool = False, modeling_practice: bool = False, sbml_level: int = 3, sbml_version: int = 1, ) -> libsbml.SBMLDocument: """Merge SBML models. Merges SBML models given in `model_paths` in the `output_dir`. Models are provided as dictionary { 'model1_id': model1_path, 'model2_id': model2_path, ... } The model ids are used as ids for the ExternalModelDefinitions. Relative paths are set in the merged models. The created model is either in SBML L3V1 (default) or SBML L3V2. :param model_paths: absolute paths to models :param output_dir: output directory for merged model :param merged_id: model id of the merged model :param flatten: flattens the merged model :param validate: boolean flag to validate the merged model :param validate_input: boolean flag to validate the input models :param units_consistency: boolean flag to check units consistency :param modeling_practice: boolean flag to check modeling practise :param sbml_level: SBML Level of the merged model in [3] :param sbml_version: SBML Version of the merged model in [1, 2] :return: SBMLDocument of the merged models """ # necessary to convert models to SBML L3V1 if isinstance(output_dir, str): logger.warning( f"'output_dir' should be a Path but: '{type(output_dir)}'") output_dir = Path(output_dir) if not output_dir.exists(): raise IOError(f"'output_dir' does not exist: {output_dir}") validate_kwargs: Dict[str, bool] = { "units_consistency": units_consistency, "modeling_practice": modeling_practice, } for model_id, path in model_paths.items(): if not path.exists(): raise IOError(f"Path for SBML file does not exist: {path}") if isinstance(path, str): path = Path(path) # convert to L3V1 path_L3: Path = output_dir / f"{model_id}_L3.xml" doc = read_sbml(path) doc.setLevelAndVersion(sbml_level, sbml_version) write_sbml(doc, path_L3) model_paths[model_id] = path_L3 if validate_input: validate_sbml( source=path_L3, name=str(path), **validate_kwargs, ) # create comp model cur_dir = os.getcwd() os.chdir(str(output_dir)) merged_doc: libsbml.SBMLDocument = _create_merged_doc(model_paths, merged_id=merged_id) os.chdir(cur_dir) # write merged doc merged_path = output_dir / f"{merged_id}.xml" write_sbml(merged_doc, filepath=merged_path) if validate: validate_sbml(merged_path, name=str(merged_path), **validate_kwargs) if flatten: flat_path = output_dir / f"{merged_id}_flat.xml" flatten_sbml(sbml_path=merged_path, sbml_flat_path=flat_path) if validate: validate_sbml(flat_path, name=str(flat_path), **validate_kwargs) return merged_doc