Skip to content

Commit

Permalink
Merge pull request #458 from matthiaskoenig/develop
Browse files Browse the repository at this point in the history
Changes for release v0.6.9
  • Loading branch information
matthiaskoenig authored Nov 1, 2019
2 parents 64fced4 + b4ed7ba commit 2cb54b9
Show file tree
Hide file tree
Showing 98 changed files with 10,198 additions and 7,188 deletions.
401 changes: 0 additions & 401 deletions CURATION.md

This file was deleted.

2 changes: 1 addition & 1 deletion backend/pkdb_app/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from ._version import __version__
from ._version import __version__
2 changes: 1 addition & 1 deletion backend/pkdb_app/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""
Definition of version string.
"""
__version__ = "0.6.7"
__version__ = "0.6.9"
65 changes: 33 additions & 32 deletions backend/pkdb_app/analysis/pharmacokinetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,23 @@
import warnings
import functools


# TODO: add estimation of confidence intervals (use also the errorbars on the curves)
# Currently only simple calculation of pharmacokinetic parameters


def f_pk(
t,
c,
compound,
dose=np.nan,
bodyweight=np.nan,
t_unit="h",
c_unit="mg/L",
dose_unit="mg",
vd_unit="L",
bodyweight_unit="kg",
intervention_time = 0,
t,
c,
compound,
dose=np.nan,
bodyweight=np.nan,
t_unit="h",
c_unit="mg/L",
dose_unit="mg",
vd_unit="L",
bodyweight_unit="kg",
intervention_time=0,
):
""" Calculates all the pk parameters from given time course.
Expand Down Expand Up @@ -151,9 +152,8 @@ def pk_report(pk):
]:
pk_key = pd.to_numeric(pk[key])
lines.append(
"\t{:<12}: {:>3.3f} [{}]".format(key, pk_key, pk["{}_unit".format(key)])
)

"\t{:<12}: {:>3.3f} [{}]".format(key, pk_key, pk["{}_unit".format(key)])
)

lines.append("")
for key in ["dose", "auc", "aucinf", "kel", "vd", "cl"]:
Expand Down Expand Up @@ -199,8 +199,8 @@ def pk_figure(t, c, pk):
ax1.plot(t[: max_idx + 1], c[: max_idx + 1], "o", color="darkgray", **kwargs)
if max_idx < c.size - 1:
ax1.plot(
t[max_idx + 1 :],
c[max_idx + 1 :],
t[max_idx + 1:],
c[max_idx + 1:],
"s",
color="black",
linewidth=2,
Expand All @@ -217,17 +217,17 @@ def pk_figure(t, c, pk):
ax2.plot(t[1:], np.log(c[1:]), "--", color="black", label="__nolabel__", **kwargs)

ax2.plot(
t[1 : max_idx + 1],
np.log(c[1 : max_idx + 1]),
t[1: max_idx + 1],
np.log(c[1: max_idx + 1]),
"o",
color="darkgray",
label="log(substance)",
**kwargs
)
if max_idx < c.size - 1:
ax2.plot(
t[max_idx + 1 :],
np.log(c[max_idx + 1 :]),
t[max_idx + 1:],
np.log(c[max_idx + 1:]),
"s",
color="black",
linewidth=2,
Expand Down Expand Up @@ -255,9 +255,9 @@ def _aucinf(t, c, slope=None, intercept=None):
[slope, intercept, r_value, p_value, std_err, max_index] = _regression(t, c)
auc = _auc(t, c)

#auc_d = -(np.exp(intercept) / slope) * np.exp(slope * t[-1])
#should be equivalent to the result above
auc_d = c[-1]/(-slope)
# auc_d = -(np.exp(intercept) / slope) * np.exp(slope * t[-1])
# should be equivalent to the result above
auc_d = c[-1] / (-slope)

return auc + auc_d

Expand Down Expand Up @@ -317,23 +317,22 @@ def _kel(t, c, slope=None):
line (on a logarithmic y scale).
"""
if slope is None:
[slope, intercept, r_value, p_value, std_err,max_index] = _regression(t, c)
[slope, intercept, r_value, p_value, std_err, max_index] = _regression(t, c)
return -slope

def _kel_cv(t, c, std_err=None,slope=None):

def _kel_cv(t, c, std_err=None, slope=None):
if std_err is None or slope is None:
[slope, intercept, r_value, p_value, std_err,max_index] = _regression(t, c)
return std_err/slope
[slope, intercept, r_value, p_value, std_err, max_index] = _regression(t, c)
return std_err / slope

def _thalf_cv(t, c, slope=None, std_err=None ):

def _thalf_cv(t, c, slope=None, std_err=None):
kel = _kel(t, c, slope=slope)

return np.log(2) / _kel_cv(t, c, slope=slope, std_err=std_err)



def _thalf(t, c, slope=None):
""" Calculates the half-life using the elimination constant.
Expand All @@ -350,6 +349,7 @@ def _thalf(t, c, slope=None):
kel = _kel(t, c, slope=slope)
return np.log(2) / kel


def _vd(t, c, dose, intercept=None):
"""
Apparent volume of distribution.
Expand All @@ -374,9 +374,10 @@ def _vd(t, c, dose, intercept=None):
determined from Vd; only that it goes somewhere.
"""
if intercept is None:
[slope, intercept, r_value, p_value, std_err,max_index] = _regression(t, c)
[slope, intercept, r_value, p_value, std_err, max_index] = _regression(t, c)
return dose / np.exp(intercept)


def _regression(t, c):
""" Linear regression on the log timecourse after maximal value.
No check is performed if already in equilibrium distribution !.
Expand All @@ -391,8 +392,8 @@ def _regression(t, c):
return [np.nan] * 6

# linear regression start regression on datapoint after maximum
x = t[max_index+1:]
y = np.log(c[max_index+1:])
x = t[max_index + 1:]
y = np.log(c[max_index + 1:])
# x = t[-4:]
# y = np.log(c[-4:])

Expand Down
4 changes: 0 additions & 4 deletions backend/pkdb_app/analysis/pharmacokinetic_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ def example1():
t = data.time
c = data.caf



pk = pharmacokinetic.f_pk(
t=t,
c=c,
Expand Down Expand Up @@ -85,8 +83,6 @@ def example2():
elif substance == "paraxanthine":
c = data.px



pk = pharmacokinetic.f_pk(
t=t,
c=c,
Expand Down
10 changes: 4 additions & 6 deletions backend/pkdb_app/behaviours.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@
from .utils import CHAR_MAX_LENGTH_LONG, CHAR_MAX_LENGTH



class Sidable(models.Model):
""" Model has an sid. """
sid = models.CharField(max_length=CHAR_MAX_LENGTH, primary_key=True)

class Meta:
abstract = True


class Externable(models.Model):
#format = models.CharField(max_length=CHAR_MAX_LENGTH, null=True)
# format = models.CharField(max_length=CHAR_MAX_LENGTH, null=True)
subset_map = models.CharField(max_length=CHAR_MAX_LENGTH_LONG, null=True)
groupby = models.CharField(max_length=CHAR_MAX_LENGTH_LONG, null=True)
source_map = models.CharField(max_length=CHAR_MAX_LENGTH_LONG, null=True)
Expand Down Expand Up @@ -46,7 +46,5 @@ def study_name(self):
return self.study.name

@property
def study_pk(self):
return self.study.pk


def study_sid(self):
return self.study.sid
1 change: 0 additions & 1 deletion backend/pkdb_app/categorials/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@

class CategorialsConfig(AppConfig):
name = "categorials"

52 changes: 21 additions & 31 deletions backend/pkdb_app/categorials/behaviours.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@
from django.db import models
from pkdb_app.utils import CHAR_MAX_LENGTH_LONG, CHAR_MAX_LENGTH


def map_field(fields):
return [f"{field}_map" for field in fields]
return [f"{field}_map" for field in fields]


VALUE_FIELDS_NO_UNIT = ["value", "mean", "median", "min", "max", "sd", "se", "cv"]
VALUE_FIELDS = VALUE_FIELDS_NO_UNIT + ["unit"]
VALUE_FIELDS = VALUE_FIELDS_NO_UNIT + ["unit"]
VALUE_MAP_FIELDS = map_field(VALUE_FIELDS)


MEASUREMENTTYPE_FIELDS = ["measurement_type", "choice","substance"] +VALUE_FIELDS
EX_MEASUREMENTTYPE_FIELDS =MEASUREMENTTYPE_FIELDS + map_field(MEASUREMENTTYPE_FIELDS)


MEASUREMENTTYPE_FIELDS = ["measurement_type", "choice", "substance"] + VALUE_FIELDS
EX_MEASUREMENTTYPE_FIELDS = MEASUREMENTTYPE_FIELDS + map_field(MEASUREMENTTYPE_FIELDS)


class ValueableMapNotBlank(models.Model):
Expand All @@ -29,7 +28,6 @@ class ValueableMapNotBlank(models.Model):
cv_map = models.CharField(max_length=CHAR_MAX_LENGTH_LONG, null=True)
unit_map = models.CharField(max_length=CHAR_MAX_LENGTH_LONG, null=True)


class Meta:
abstract = True

Expand All @@ -39,38 +37,35 @@ class ValueableNotBlank(models.Model):
Adds fields to store values with their statistics.
"""
value = models.FloatField(null=True)
mean = models.FloatField(null=True)
median = models.FloatField(null=True)
min = models.FloatField(null=True)
max = models.FloatField(null=True)
sd = models.FloatField(null=True)
se = models.FloatField(null=True)
cv = models.FloatField(null=True)
unit = models.CharField(max_length=CHAR_MAX_LENGTH_LONG, null=True)
value = models.FloatField(null=True)
mean = models.FloatField(null=True)
median = models.FloatField(null=True)
min = models.FloatField(null=True)
max = models.FloatField(null=True)
sd = models.FloatField(null=True)
se = models.FloatField(null=True)
cv = models.FloatField(null=True)
unit = models.CharField(max_length=CHAR_MAX_LENGTH_LONG, null=True)

class Meta:
abstract = True


class ExMeasurementTypeable(ValueableNotBlank,ValueableMapNotBlank):
class ExMeasurementTypeable(ValueableNotBlank, ValueableMapNotBlank):
measurement_type = models.CharField(max_length=CHAR_MAX_LENGTH, null=True)
measurement_type_map = models.CharField(max_length=CHAR_MAX_LENGTH_LONG, null=True)

choice = models.CharField(max_length=CHAR_MAX_LENGTH_LONG, null=True)
choice_map = models.CharField(max_length=CHAR_MAX_LENGTH_LONG, null=True)
#substance = models.ForeignKey(Substance, null=True, on_delete=models.PROTECT)
# substance = models.ForeignKey(Substance, null=True, on_delete=models.PROTECT)
substance = models.CharField(max_length=CHAR_MAX_LENGTH, null=True)
substance_map = models.CharField(max_length=CHAR_MAX_LENGTH_LONG, null=True)


class Meta:
abstract = True



class MeasurementTypeable(ValueableNotBlank):

measurement_type = models.ForeignKey(MeasurementType, on_delete=models.CASCADE)
substance = models.ForeignKey(Substance, null=True, on_delete=models.PROTECT)
choice = models.CharField(max_length=CHAR_MAX_LENGTH_LONG, null=True)
Expand All @@ -95,16 +90,13 @@ def choices(self):
return self.measurement_type.choices_list()




class Normalizable(MeasurementTypeable):
raw = models.ForeignKey("self", related_name="norm", on_delete=models.CASCADE, null=True)
normed = models.BooleanField(default=False)

class Meta:
abstract = True


@property
def norm_fields(self):
return {"value": self.value, "mean": self.mean, "median": self.median, "min": self.min, "max": self.max,
Expand Down Expand Up @@ -144,15 +136,13 @@ def remove_substance_dimension(self):
"""
is_removeable_substance, dimension = self.is_removeable_substance_dimension
if is_removeable_substance:
molar_weight = ureg("g/mol")*self.substance.mass
molar_weight = ureg("g/mol") * self.substance.mass
p_unit = self.measurement_type.p_unit(self.unit)
this_quantity = p_unit*molar_weight**dimension
this_quantity = p_unit * molar_weight ** dimension
return (this_quantity.magnitude, str(this_quantity.units))
else:
return (1, self.unit)



def normalize(self):
""" Normalizes the units.
Expand All @@ -171,10 +161,10 @@ def normalize(self):
if ureg(unit) != ureg(self.unit):
for key, value in self.norm_fields.items():
if value is not None:
setattr(self, key, value*factor)
setattr(self, key, value * factor)
self.unit = unit

#else:
# else:
# self.unit = str(ureg(self.unit).u)

# normalization
Expand Down
4 changes: 2 additions & 2 deletions backend/pkdb_app/categorials/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class MeasurementTypeDocument(Document):

units = interventions = ObjectField(properties={
'name': string_field('name')
}, multi=True)
}, multi=True)

choices = ObjectField(
attr="choices",
Expand All @@ -34,7 +34,7 @@ class MeasurementTypeDocument(Document):
"description": string_field("description"),
"label": string_field("label")
}
)
)
}
)
annotations = ObjectField(
Expand Down
2 changes: 1 addition & 1 deletion backend/pkdb_app/categorials/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ class ChoiceManager(models.Manager):
def create(self, *args, **kwargs):
annotations = kwargs.pop('annotations', [])
choice = super().create(*args, **kwargs)
update_or_create_multiple(choice, annotations, 'annotations', lookup_fields=["term","relation"])
update_or_create_multiple(choice, annotations, 'annotations', lookup_fields=["term", "relation"])
choice.save()
return choice
Loading

0 comments on commit 2cb54b9

Please sign in to comment.