diff --git a/xbanalysis/model/__init__.py b/xbanalysis/model/__init__.py index c050038fe1b8eec3d120c2600479c2efeceb1884..3edfe6f5d5b88a040b94c53ec91aec340d23b9ca 100644 --- a/xbanalysis/model/__init__.py +++ b/xbanalysis/model/__init__.py @@ -1,6 +1,7 @@ """Subpackage with XBA model classes """ from .xba_model import XbaModel +from .xba_unit_def import XbaUnitDef, XbaUnit from .xba_compartment import XbaCompartment from .xba_function import XbaFunction from .xba_parameter import XbaParameter @@ -8,5 +9,5 @@ from .xba_reaction import XbaReaction from .xba_species import XbaSpecies from .sbo_term import SboTerm -__all__ = ['XbaModel', 'XbaCompartment', 'XbaFunction', 'XbaParameter', - 'XbaReaction', 'XbaSpecies', 'SboTerm'] +__all__ = ['XbaModel', 'XbaUnitDef', 'XbaUnit', 'XbaCompartment', + 'XbaFunction', 'XbaParameter', 'XbaReaction', 'XbaSpecies', 'SboTerm'] diff --git a/xbanalysis/model/xba_model.py b/xbanalysis/model/xba_model.py index 495dbcbbfd63735400a6f6be97a2847853094ae4..f4b3c5441114537d3cf198dbdc45d4f32fc3c601 100644 --- a/xbanalysis/model/xba_model.py +++ b/xbanalysis/model/xba_model.py @@ -9,6 +9,7 @@ import numpy as np import sbmlxdf from scipy.sparse import coo_array +from .xba_unit_def import XbaUnitDef from .xba_compartment import XbaCompartment from .xba_function import XbaFunction from .xba_parameter import XbaParameter @@ -32,6 +33,8 @@ class XbaModel: print(f'{sbml_file} seems not to be a valid SBML model') return model_dict = sbml_model.to_df() + self.unit_defs = {udid: XbaUnitDef(row) + for udid, row in model_dict['unitDefs'].iterrows()} self.compartments = {cid: XbaCompartment(row) for cid, row in model_dict['compartments'].iterrows()} self.parameters = {pid: XbaParameter(row) diff --git a/xbanalysis/model/xba_unit_def.py b/xbanalysis/model/xba_unit_def.py new file mode 100644 index 0000000000000000000000000000000000000000..5cd13264b0ddc70d79a89a86231c4b4b69926dda --- /dev/null +++ b/xbanalysis/model/xba_unit_def.py @@ -0,0 +1,55 @@ +"""Implementation of XbaUnitDef class. + +Peter Schubert, HHU Duesseldorf, May 2022 +""" + +import numpy as np +import sbmlxdf + + +class XbaUnitDef: + + def __init__(self, s_unit_def): + self.id = s_unit_def.name + self.name = s_unit_def.get('name', self.id) + self.units = [XbaUnit(sbmlxdf.extract_params(u)) + for u in sbmlxdf.record_generator(s_unit_def['units'])] + + def is_equivalent(self, qry_units): + if len(qry_units) != len(self.units): + return False + else: + equivalent_u = np.zeros(len(qry_units)) + for i, qry_unit in enumerate(qry_units): + for unit in self.units: + if unit == qry_unit: + equivalent_u[i] = 1 + break + return np.all(equivalent_u) + + +class XbaUnit: + + def __init__(self, params): + self.kind = params.get('kind') + self.exp = float(params.get('exp', '1.0')) + self.scale = int(params.get('scale', '0')) + self.mult = float(params.get('mult', '1.0')) + + def __eq__(self, other): + if (self.kind == other.kind and + self.exp == other.exp and + self.scale == other.scale and + self.mult == other.mult): + return True + else: + return False + + def __str__(self): + factor = self.mult * 10**self.scale + factor_str = f'{factor} ' if factor != 1.0 else '' + if self.exp != 1.0: + unit_str = f'({factor_str}{self.kind})^{self.exp}' + else: + unit_str = f'{factor_str}{self.kind}' + return unit_str