Source code for pkpd.protocols.protocol_pkpd_dissolution_deconvolve

# **************************************************************************
# *
# * Authors:     Carlos Oscar Sorzano (info@kinestat.com)
# *
# * Kinestat Pharma
# *
# * This program is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 2 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# * 02111-1307  USA
# *
# *  All comments concerning this program package may be sent to the
# *  e-mail address 'info@kinestat.com'
# *
# **************************************************************************

import numpy as np

import pyworkflow.protocol.params as params
from pkpd.objects import PKPDExperiment, PKPDSample, PKPDVariable
from pkpd.pkpd_units import createUnit
from .protocol_pkpd_ode_base import ProtPKPDODEBase
from pkpd.biopharmaceutics import DrugSource
from pkpd.utils import twoWayUniqueFloatValues

# Tested in test_workflow_deconvolution
# Tested by test_workflow_levyplot
# Tested in test_workflow_deconvolution2
# Tested in test_workflow_ivivc

[docs]class ProtPKPDDeconvolve(ProtPKPDODEBase): """ Deconvolve the drug dissolution from a compartmental model.""" _label = 'dissol deconv' BIOAVAIL_NONE = 0 BIOAVAIL_MULT = 1 BIOAVAIL_DIV = 2 #--------------------------- DEFINE param functions -------------------------------------------- def _defineParams(self, form): form.addSection('Input') form.addParam('inputODE', params.PointerParam, label="Input ODE model", pointerClass='ProtPKPDMonoCompartment, ProtPKPDTwoCompartments,ProtPKPDODERefine,'\ ' ProtPKPDTwoCompartmentsClint, ProtPKPDTwoCompartmentsClintCl', help='Select a run of an ODE model') form.addParam('normalize', params.BooleanParam, label="Normalize by dose", default=True, help='Normalize the output by the input dose, so that a total absorption is represented by 100.') form.addParam('considerBioaval', params.EnumParam, label="Consider bioavailability", default=self.BIOAVAIL_NONE, choices=['Do not correct','Multiply deconvolution by bioavailability','Divide deconvolution by bioavailability'], help='Take into account the bioavailability') form.addParam('saturate', params.BooleanParam, label="Saturate at 100%", default=True, condition='normalize', help='Saturate the absorption so that there cannot be values beyond 100') form.addParam('removeTlag', params.BooleanParam, label="Remove tlag effect", default=True, help='If set to True, then the deconvolution is performed ignoring the the tlag in the absorption.' 'This homogeneizes the different responses.') #--------------------------- INSERT steps functions -------------------------------------------- def _insertAllSteps(self): self._insertFunctionStep('deconvolve',self.inputODE.get().getObjId()) self._insertFunctionStep('createOutputStep') #--------------------------- STEPS functions --------------------------------------------
[docs] def addSample(self, sampleName, t, y): newSample = PKPDSample() newSample.sampleName = sampleName newSample.variableDictPtr = self.outputExperiment.variables newSample.descriptors = {} newSample.addMeasurementPattern(["A"]) tUnique, yUnique = twoWayUniqueFloatValues(t,y) newSample.addMeasurementColumn("t", tUnique) newSample.addMeasurementColumn("A",yUnique) self.outputExperiment.samples[sampleName] = newSample
[docs] def deconvolve(self, objId): self.protODE = self.inputODE.get() self.experiment = self.readExperiment(self.protODE.outputExperiment.fnPKPD) self.fitting = self.readFitting(self.protODE.outputFitting.fnFitting) self.varNameX = self.fitting.predictor.varName self.varNameY = self.fitting.predicted.varName # Create drug source self.clearGroupParameters() self.createDrugSource() # Create output object self.outputExperiment = PKPDExperiment() tvar = PKPDVariable() tvar.varName = "t" tvar.varType = PKPDVariable.TYPE_NUMERIC tvar.role = PKPDVariable.ROLE_TIME tvar.units = createUnit(self.experiment.getTimeUnits().unit) Avar = PKPDVariable() Avar.varName = "A" Avar.varType = PKPDVariable.TYPE_NUMERIC Avar.role = PKPDVariable.ROLE_MEASUREMENT if self.normalize.get(): Avar.units = createUnit("none") else: Avar.units = createUnit(self.experiment.getDoseUnits()) self.outputExperiment.variables[tvar.varName] = tvar self.outputExperiment.variables[Avar.varName] = Avar self.outputExperiment.general["title"]="Deconvolution of the amount released" self.outputExperiment.general["comment"]="Amount released at any time t" # Simulate the different responses timeRange = self.experiment.getRange(self.varNameX) deltaT = 0.5 t = np.arange(0.0,timeRange[1],deltaT) for sampleName, sample in self.experiment.samples.items(): self.printSection("Deconvolving "+sampleName) sample.interpretDose() drugSource = DrugSource() drugSource.setDoses(sample.parsedDoseList, 0.0, timeRange[1]) p=[] tlag=0 for paramName in drugSource.getParameterNames(): p.append(float(sample.getDescriptorValue(paramName))) if paramName.endswith('_tlag') and self.removeTlag.get(): tlag=float(sample.getDescriptorValue(paramName)) drugSource.setParameters(p) cumulatedDose=0.0 A=t*0.0 # Allocate memory totalReleased = drugSource.getAmountReleasedUpTo(10*t[-1]) print("t(min) A(%s)"%Avar.units._toString()) for i in range(t.size): cumulatedDose+=drugSource.getAmountReleasedAt(t[i],deltaT) A[i]=cumulatedDose if self.normalize.get(): A[i] *= 100.0/totalReleased print("%f %f"%(t[i],A[i])) # print("%f %f %f %f"%(t[i], A[i], drugSource.getAmountReleasedAt(t[i], 0.5), drugSource.getAmountReleasedUpTo(t[i] + 0.5))) if self.saturate.get() and self.normalize.get(): A = np.clip(A,None,100.0) if self.considerBioaval.get()==self.BIOAVAIL_DIV: A /= sample.getBioavailability() elif self.considerBioaval.get()==self.BIOAVAIL_MULT: A *= sample.getBioavailability() self.addSample(sampleName,t-tlag,A) self.outputExperiment.write(self._getPath("experiment.pkpd"))
[docs] def createOutputStep(self): self._defineOutputs(outputExperiment=self.outputExperiment) self._defineSourceRelation(self.inputODE.get(), self.outputExperiment)
def _validate(self): return [] def _summary(self): return []