From 291701052b484e8720edf0b33ddeddaf7970d5f2 Mon Sep 17 00:00:00 2001 From: Peter Schubert <Peter.Schubert@hhu.de> Date: Fri, 9 Sep 2022 11:40:13 +0200 Subject: [PATCH] support unit definitions --- xbanalysis/model/__init__.py | 5 +-- xbanalysis/model/xba_model.py | 3 ++ xbanalysis/model/xba_unit_def.py | 55 ++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 xbanalysis/model/xba_unit_def.py diff --git a/xbanalysis/model/__init__.py b/xbanalysis/model/__init__.py index c050038..3edfe6f 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 495dbcb..f4b3c54 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 0000000..5cd1326 --- /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 -- GitLab