Skip to content

Commit

Permalink
Rate constants can now be of type quantity, or string
Browse files Browse the repository at this point in the history
  • Loading branch information
uliw committed Nov 5, 2020
1 parent 7427013 commit e5087df
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 120 deletions.
5 changes: 0 additions & 5 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,9 @@ ESBMTK relies on the following python versions and libraries
- matplotlib
- numpy
- pandas
- logging
- typing
- builtins
- nptyping
- numbers
- pint
- copy
- time

If you work with conda, it is recommended to install the above via
conda. If you work with pip, the installer should install these
Expand Down
17 changes: 1 addition & 16 deletions build/lib/esbmtk/base_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,6 @@ def __validateinput__(self, kwargs: Dict[str, any]) -> None:
# check if key values are of correct type
self.__checktypes__(self.lkk, self.kwargs)

# this wont work since we don't know the model yet.
# coulde be moved into a post init section?

# register instance on the list of model objects
#if not type(self) == Model:
# self.mo.lmo.append(self) # register on the list of model objects

# start log entry
#logfile = self.name+".log"
#logging.basicConfig(filename=logfile,
# filemode='w',
# format='%(message)s',
# level=logging.INFO)
#logging.info(f"{self.name} initialized on {time.ctime()}")

def __checktypes__(self, av: Dict[any, any], pv: Dict[any, any]) -> None:
""" this method will use the the dict key in the user provided
Expand All @@ -129,8 +115,7 @@ def __checktypes__(self, av: Dict[any, any], pv: Dict[any, any]) -> None:
for k, v in pv.items():
# check av if provided value v is of correct type
if not isinstance(v, av[k]):
print(f"Offending Key = {k}")
raise TypeError(f"{v} must be {m[k]}, not {type(v)}")
raise TypeError(f"{type(v)} is the wrong type for '{k}', should be '{av[k]}'")

def __initerrormessages__(self):
""" Init the list of known error messages"""
Expand Down
73 changes: 57 additions & 16 deletions build/lib/esbmtk/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

from .base_class import esbmtkBase


class Connect(esbmtkBase):
"""Name:
Expand Down Expand Up @@ -76,7 +77,6 @@ class Connect(esbmtkBase):
Currently reckonized flux properties: delta, rate, alpha, species, k_value, k_mass, k_concentration, ref_value,
"""

def __init__(self, **kwargs):
""" The init method of the connector obbjects performs sanity checks e.g.:
- whether the reservoirs exist
Expand All @@ -93,17 +93,17 @@ def __init__(self, **kwargs):
pl[optional] = optional processes : list
"""

from . import ureg, Q_

# provide a dict of all known keywords and their type
self.lkk: Dict[str, any] = {
"name": str,
"id": str,
"source": (Source, Reservoir),
"sink": (Sink, Reservoir),
"delta": Number,
"rate": str,
"rate": (str, Number),
"pl": list,
"alpha": Number,
"species": Species,
Expand All @@ -112,9 +112,9 @@ def __init__(self, **kwargs):
"react_with": Flux,
"ratio": Number,
"scale": Number,
"k_concentration": Number,
"k_mass": Number,
"ref_value": Number,
"k_concentration": (str, Number, Q_),
"k_mass": (str, Number, Q_),
"ref_value": (str, Number, Q_),
"k_value": Number,
"a_value": Number,
"b_value": Number,
Expand All @@ -138,7 +138,7 @@ def __init__(self, **kwargs):
"k_mass": "a number",
"k_value": "a number",
"a_value": "a number",
"ref_value": "a number",
"ref_value": "a number, string, or quantity",
"b_value": "a number",
"name": "a string",
"id": "a string",
Expand All @@ -149,8 +149,6 @@ def __init__(self, **kwargs):
if not 'pl' in kwargs:
self.pl: list[Process] = []



# legacy names
self.influx: int = 1
self.outflux: int = -1
Expand Down Expand Up @@ -215,7 +213,7 @@ def register_fluxes(self) -> None:
n = self.r1.n + '_to_' + self.r2.n

# derive flux unit from species obbject
funit = self.sp.mu + "/" + str(self.sp.mo.bu) # xxx
funit = self.sp.mu + "/" + str(self.sp.mo.bu) # xxx

print(f"r = {r}")
self.fh = Flux(
Expand Down Expand Up @@ -405,14 +403,39 @@ def __alpha__(self) -> None:
self.pl.append(ph) #

def __rateconstant__(self) -> None:
""" Add rate constant process"""
""" Add rate constant type process
"""

from . import ureg, Q_

if "rate" not in self.kwargs:
raise ValueError(
"The rate constant process requires that the flux rate for this reservoir is being set explicitly"
)

# k_concentration, k_mass and ref_value can be a number, a unit string, or a quantity
# if unit - convert into qauntity
# if quantity convert into number
if "k_concentration" in self.kwargs:
if isinstance(self.k_concentration,str):
self.k_concentration = Q_(self.k_concentration)

if "k_mass" in self.kwargs:
if isinstance(self.k_mass,str):
self.k_mass = Q_(self.k_mass)

if "ref_value" in self.kwargs:
if isinstance(self.ref_value,str):
self.ref_value = Q_(self.ref_value)

if "k_concentration" in self.kwargs and "ref_value" in self.kwargs:
# if necessary, map units
if isinstance(self.k_concentration, Q_):
self.k_concentration = self.k_concentration.to(self.mo.c_unit).magnitude
if isinstance(self.ref_value, Q_):
self.ref_value = self.ref_value.to(self.mo.c_unit).magnitude

ph = ScaleRelativeToNormalizedConcentration(
name=self.pn + "_PknC",
reservoir=self.r,
Expand All @@ -421,19 +444,33 @@ def __rateconstant__(self) -> None:
k_value=self.k_concentration)

elif "k_mass" in self.kwargs and "ref_value" in self.kwargs:
# if necessary, map units
if isinstance(self.k_mass, Q_):
self.k_mass = self.k_mass.to(self.mo.m_unit).magnitude
if isinstance(self.ref_value, Q_):
self.ref_value = self.ref_value.to(self.mo.m_unit).magnitude

ph = ScaleRelativeToNormalizedMass(name=self.pn + "_PknM",
reservoir=self.r,
flux=self.fh,
ref_value=self.ref_value,
k_value=self.k_mass)

elif "k_mass" in self.kwargs and not "ref_value" in self.kwargs:
# if necessary, map units
if isinstance(self.k_mass, Q_):
self.k_mass = self.k_mass.to(self.mo.m_unit).magnitude

ph = ScaleRelativeToMass(name=self.pn + "_PkM",
reservoir=self.r,
flux=self.fh,
k_value=self.k_mass)

elif "k_concentration" in self.kwargs and not "ref_value" in self.kwargs:
# if necessary, map units
if isinstance(self.k_concentration, Q_):
self.k_concentration = self.k_concentration.to(self.mo.c_unit).magnitude

ph = ScaleRelativeToConcentration(name=self.pn + "_PkC",
reservoir=self.r,
flux=self.fh,
Expand Down Expand Up @@ -860,8 +897,11 @@ class RateConstant(Process):
"""

def __init__(self, **kwargs: Dict[str, any]) -> None:
""" Initialize this Process """
""" Initialize this Process
"""

from . import ureg, Q_

# Note that self.lkk values also need to be added to the lkk
# list of the connector object.
Expand All @@ -872,7 +912,7 @@ def __init__(self, **kwargs: Dict[str, any]) -> None:
# update the allowed keywords
self.lkk = {
"k_value": Number,
"ref_value": Number,
"ref_value": (Number,str, Q_),
"name": str,
"reservoir": Reservoir,
"flux": Flux,
Expand Down Expand Up @@ -1045,7 +1085,8 @@ def __init__(self, **kwargs: Dict[str, any]) -> None:
"""
"""


from . import ureg, Q_

""" Initialize this Process """
# get default names and update list for this Process
Expand All @@ -1055,7 +1096,7 @@ def __init__(self, **kwargs: Dict[str, any]) -> None:
self.lkk = {
"a_value": Number,
"b_value": Number,
"ref_value": Number,
"ref_value": (Number,str, Q_),
"name": str,
"reservoir": Reservoir,
"flux": Flux,
Expand Down
5 changes: 0 additions & 5 deletions esbmtk.egg-info/requires.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,4 @@ typing
numpy
pandas
matplotlib
builtins
logging
numbers
pint
copy
time
17 changes: 1 addition & 16 deletions esbmtk/base_class.org
Original file line number Diff line number Diff line change
Expand Up @@ -111,20 +111,6 @@ class esbmtkBase():
# check if key values are of correct type
self.__checktypes__(self.lkk, self.kwargs)

# this wont work since we don't know the model yet.
# coulde be moved into a post init section?

# register instance on the list of model objects
#if not type(self) == Model:
# self.mo.lmo.append(self) # register on the list of model objects

# start log entry
#logfile = self.name+".log"
#logging.basicConfig(filename=logfile,
# filemode='w',
# format='%(message)s',
# level=logging.INFO)
#logging.info(f"{self.name} initialized on {time.ctime()}")

def __checktypes__(self, av: Dict[any, any], pv: Dict[any, any]) -> None:
""" this method will use the the dict key in the user provided
Expand All @@ -143,8 +129,7 @@ class esbmtkBase():
for k, v in pv.items():
# check av if provided value v is of correct type
if not isinstance(v, av[k]):
print(f"Offending Key = {k}")
raise TypeError(f"{v} must be {m[k]}, not {type(v)}")
raise TypeError(f"{type(v)} is the wrong type for '{k}', should be '{av[k]}'")

def __initerrormessages__(self):
""" Init the list of known error messages"""
Expand Down
17 changes: 1 addition & 16 deletions esbmtk/base_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,6 @@ def __validateinput__(self, kwargs: Dict[str, any]) -> None:
# check if key values are of correct type
self.__checktypes__(self.lkk, self.kwargs)

# this wont work since we don't know the model yet.
# coulde be moved into a post init section?

# register instance on the list of model objects
#if not type(self) == Model:
# self.mo.lmo.append(self) # register on the list of model objects

# start log entry
#logfile = self.name+".log"
#logging.basicConfig(filename=logfile,
# filemode='w',
# format='%(message)s',
# level=logging.INFO)
#logging.info(f"{self.name} initialized on {time.ctime()}")

def __checktypes__(self, av: Dict[any, any], pv: Dict[any, any]) -> None:
""" this method will use the the dict key in the user provided
Expand All @@ -129,8 +115,7 @@ def __checktypes__(self, av: Dict[any, any], pv: Dict[any, any]) -> None:
for k, v in pv.items():
# check av if provided value v is of correct type
if not isinstance(v, av[k]):
print(f"Offending Key = {k}")
raise TypeError(f"{v} must be {m[k]}, not {type(v)}")
raise TypeError(f"{type(v)} is the wrong type for '{k}', should be '{av[k]}'")

def __initerrormessages__(self):
""" Init the list of known error messages"""
Expand Down
Loading

0 comments on commit e5087df

Please sign in to comment.