def _visualize(self, obj, **kwargs): fnResults = self.protocol._getPath("results.txt") if exists(fnResults): X, Y, _, _ = self.protocol.getXYValues(False) minX = min(X) maxX = max(X) step = (maxX - minX) / 50 xValues = np.arange(minX, maxX+step, step) yValues = self.protocol.evalFunction(xValues) plotter = EmPlotter() varNameX = self.protocol.labelX.get() varNameY = self.protocol.labelY.get() ax = plotter.createSubPlot("Regression Plot", "%s [%s]"%(varNameX,strUnit(self.protocol.experiment.variables[varNameX].units.unit)), "%s [%s]"%(varNameY,strUnit(self.protocol.experiment.variables[varNameY].units.unit))) ax.plot(xValues, yValues) ax.plot(X, Y, 'o') return [plotter] else: return [self.errorMessage("Result file '%s' not produced yet. " % fnResults)]
def prepareForSampleAnalysis(self, sampleName): sample = self.experiment.samples[sampleName] sampleFit = self.eliminationFitting.getSampleFit(sampleName) sample.interpretDose() self.model.D = sample.getDoseAt(0.0) self.model.Dunits = sample.getDoseUnits() if sampleFit == None: print( " Cannot process %s because its elimination rate cannot be found\n\n" % sampleName) return False self.model.C0 = sampleFit.parameters[0] self.model.C0units = self.eliminationFitting.modelParameterUnits[0] self.model.Ke = sampleFit.parameters[1] self.model.KeUnits = self.eliminationFitting.modelParameterUnits[1] print("Concentration at t=0 = %f [%s]" % (self.model.C0, strUnit(self.model.C0units))) print("Elimination rate = %f [%s]" % (self.model.Ke, strUnit(self.model.KeUnits))) self.experiment.addParameterToSample( sampleName, "Ke", self.model.KeUnits, "Automatically estimated elimination rate", self.model.Ke) return True
def _visualize(self, obj, **kwargs): fnResults = self.protocol._getPath("results.txt") if exists(fnResults): X, Y, _, _ = self.protocol.getXYValues(False) minX = min(X) maxX = max(X) step = (maxX - minX) / 50 xValues = np.arange(minX, maxX + step, step) yValues = self.protocol.evalFunction(xValues) plotter = EmPlotter() varNameX = self.protocol.labelX.get() varNameY = self.protocol.labelY.get() ax = plotter.createSubPlot( "Regression Plot", "%s [%s]" % (varNameX, strUnit( self.protocol.experiment.variables[varNameX].units.unit)), "%s [%s]" % (varNameY, strUnit( self.protocol.experiment.variables[varNameY].units.unit))) ax.plot(xValues, yValues) ax.plot(X, Y, 'o') return [plotter] else: return [ self.errorMessage("Result file '%s' not produced yet. " % fnResults) ]
def postSampleAnalysis(self, sampleName): xunits = self.experiment.getVarUnits(self.varNameX) Cunits = self.experiment.getVarUnits(self.varNameY) Ka = self.model.parameters[0] Ke = self.model.Ke tmax = math.log(Ka/Ke)/(Ka-Ke) self.experiment.addParameterToSample(sampleName, "tmax", xunits, "Estimated time of the Maximum of the non-iv peak", tmax) Cmax = self.model.forwardModel(self.model.parameters,x=[np.atleast_1d(np.array(tmax))])[0][0] self.experiment.addParameterToSample(sampleName, "Cmax", Cunits, "Estimated concentration of the Maximum of the non-iv peak", Cmax) print("tmax = %f [%s]"%(tmax,strUnit(xunits))) print("Cmax = %f [%s]"%(Cmax,strUnit(Cunits)))
def postSampleAnalysis(self, sampleName): xunits = self.experiment.getVarUnits(self.varNameX) Cunits = self.experiment.getVarUnits(self.varNameY) Ka = self.model.parameters[0] Ke = self.model.Ke tmax = math.log(Ka / Ke) / (Ka - Ke) self.experiment.addParameterToSample( sampleName, "tmax", xunits, "Estimated time of the Maximum of the non-iv peak", tmax) Cmax = self.model.forwardModel(self.model.parameters, x=[np.atleast_1d(np.array(tmax))])[0][0] self.experiment.addParameterToSample( sampleName, "Cmax", Cunits, "Estimated concentration of the Maximum of the non-iv peak", Cmax) print("tmax = %f [%s]" % (tmax, strUnit(xunits))) print("Cmax = %f [%s]" % (Cmax, strUnit(Cunits)))
def runStatistcs(self, objId): experiment = self.readExperiment(self.inputExperiment.get().fnPKPD) self.printSection("Calculating statistical descriptors") fnStatistics = self._getPath("statistics.txt") fhOut = open(fnStatistics, 'w') for varName, variable in experiment.variables.iteritems(): if variable.role == PKPDVariable.ROLE_LABEL: varValues = experiment.getSubGroupLabels("True", varName) if variable.varType == PKPDVariable.TYPE_TEXT: self.doublePrint(fhOut, "%s ------------" % varName) counter = {} for value in varValues: if value in counter: counter[value] += 1 else: counter[value] = 1 for value in counter: self.doublePrint( fhOut, "Value=%s Total count=%d (%f%%)" % (value, counter[value], 100 * float(counter[value]) / len(varValues))) elif variable.varType == PKPDVariable.TYPE_NUMERIC: self.doublePrint( fhOut, "%s [%s] ------------" % (varName, strUnit(variable.units.unit))) varValues = np.asarray(varValues, np.double) self.doublePrint( fhOut, "Number of observations= %d" % len(varValues)) self.doublePrint( fhOut, "Range= [%f,%f]" % (np.min(varValues), np.max(varValues))) self.doublePrint(fhOut, "Mean= %f" % np.mean(varValues)) self.doublePrint(fhOut, "StdDev= %f" % np.std(varValues)) self.doublePrint( fhOut, "Skewness= %f" % scipy.stats.skew(varValues)) self.doublePrint( fhOut, "Kurtosis= %f" % scipy.stats.kurtosis(varValues)) self.doublePrint( fhOut, "Quantile 5%%= %f" % np.percentile(varValues, 5)) self.doublePrint( fhOut, "Quantile 25%%= %f" % np.percentile(varValues, 25)) self.doublePrint( fhOut, "Quantile 50%%= %f" % np.percentile(varValues, 50)) self.doublePrint( fhOut, "Quantile 75%%= %f" % np.percentile(varValues, 75)) self.doublePrint( fhOut, "Quantile 95%%= %f" % np.percentile(varValues, 95)) self.doublePrint(fhOut, " ") fhOut.close()
def prepareForSampleAnalysis(self, sampleName): sample = self.experiment.samples[sampleName] sampleFit = self.eliminationFitting.getSampleFit(sampleName) sample.interpretDose() self.model.D = sample.getDoseAt(0.0) self.model.Dunits = sample.getDoseUnits() if sampleFit == None: print(" Cannot process %s because its elimination rate cannot be found\n\n"%sampleName) return False self.model.C0 = sampleFit.parameters[0] self.model.C0units = self.eliminationFitting.modelParameterUnits[0] self.model.Ke = sampleFit.parameters[1] self.model.KeUnits = self.eliminationFitting.modelParameterUnits[1] print("Concentration at t=0 = %f [%s]"%(self.model.C0,strUnit(self.model.C0units))) print("Elimination rate = %f [%s]"%(self.model.Ke,strUnit(self.model.KeUnits))) self.experiment.addParameterToSample(sampleName, "Ke", self.model.KeUnits, "Automatically estimated elimination rate", self.model.Ke) return True
def _validate(self): errors=[] experiment = self.readExperiment(self.inputExperiment.get().fnPKPD, False) if not self.labelToChange.get() in experiment.variables: errors.append("Cannot find %s as variable"%self.labelToChange) else: variable = experiment.variables[self.labelToChange.get()] if variable.varType!=PKPDVariable.TYPE_NUMERIC: errors.append("%s is not a numeric variable"%variable.varName) else: currentUnit = experiment.getVarUnits(self.labelToChange.get()) newUnit = unitFromString(self._getNewUnit()) try: K=convertUnits(1,currentUnit,newUnit) if K==None: errors.append("Unknown conversion from %s to %s. If it makes sense and it is not implemented you may contact [email protected]"%\ (strUnit(currentUnit),strUnit(newUnit))) except: errors.append("Unknown conversion from %s to %s. If it makes sense and it is not implemented you may contact [email protected]"%(currentUnit,newUnit)) return errors
def _validate(self): errors = [] experiment = self.readExperiment(self.inputExperiment.get().fnPKPD, False) if not self.labelToChange.get() in experiment.variables: errors.append("Cannot find %s as variable" % self.labelToChange) else: variable = experiment.variables[self.labelToChange.get()] if variable.varType != PKPDVariable.TYPE_NUMERIC: errors.append("%s is not a numeric variable" % variable.varName) else: currentUnit = experiment.getVarUnits(self.labelToChange.get()) newUnit = unitFromString(self._getNewUnit()) try: K = convertUnits(1, currentUnit, newUnit) if K == None: errors.append("Unknown conversion from %s to %s. If it makes sense and it is not implemented you may contact [email protected]"%\ (strUnit(currentUnit),strUnit(newUnit))) except: errors.append( "Unknown conversion from %s to %s. If it makes sense and it is not implemented you may contact [email protected]" % (currentUnit, newUnit)) return errors
def postAnalysis(self, sampleName): if self.experimentIV!=None: if sampleName in self.experimentIV.samples: sampleNIV = self.experiment.samples[sampleName] DNIV= self.analysis.D sampleIV = self.experimentIV.samples[sampleName] sampleIV.interpretDose() DIV = sampleIV.getDoseAt(0.0) F = float(sampleNIV.descriptors['AUC_0inf'])/float(sampleNIV.descriptors['AUC_0inf'])*DIV/DNIV MAT = float(sampleNIV.descriptors['MRT']) - float(sampleIV.descriptors['MRT']) self.experiment.addParameterToSample(sampleName, "F", PKPDUnit.UNIT_NONE, "Estimated bioavailability", F) self.experiment.addParameterToSample(sampleName, "MAT", self.analysis.parameterUnits[-1], "Estimated Mean Absorption Time", MAT) print("F = %f"%F) print("MAT = %f [%s]"%(MAT,strUnit(self.analysis.parameterUnits[-1])))
def _createSlidersFrame(self, content): frame = tk.Frame(content, bg='white') lfBounds = tk.LabelFrame(frame, text="Parameter Bounds", bg='white') gui.configureWeigths(frame) i = 0 self.sliders = {} paramUnits = self.targetProtocol.parameterUnits for paramName, bounds in self.targetProtocol.getParameterBounds().iteritems(): bounds = bounds or (0, 1) slider = MinMaxSlider(lfBounds, "%s [%s]"%(paramName,strUnit(paramUnits[i])), bounds[0], bounds[1], callback=self._onVarChanged) slider.grid(row=i, column=0, padx=5, pady=5) self.sliders[paramName] = slider i += 1 lfBounds.grid(row=0, column=0, sticky='news', padx=5, pady=5) frame.grid(row=0, column=1, sticky='news', padx=5, pady=5)
def _createSlidersFrame(self, content): frame = tk.Frame(content, bg='white') lfBounds = tk.LabelFrame(frame, text="Parameter Bounds", bg='white') gui.configureWeigths(frame) i = 0 self.sliders = {} paramUnits = self.targetProtocol.parameterUnits for paramName, bounds in self.targetProtocol.getParameterBounds( ).iteritems(): bounds = bounds or (0, 1) slider = MinMaxSlider(lfBounds, "%s [%s]" % (paramName, strUnit(paramUnits[i])), bounds[0], bounds[1], callback=self._onVarChanged) slider.grid(row=i, column=0, padx=5, pady=5) self.sliders[paramName] = slider i += 1 lfBounds.grid(row=0, column=0, sticky='news', padx=5, pady=5) frame.grid(row=0, column=1, sticky='news', padx=5, pady=5)
def runStatistcs(self, objId): experiment = self.readExperiment(self.inputExperiment.get().fnPKPD) self.printSection("Calculating statistical descriptors") fnStatistics = self._getPath("statistics.txt") fhOut = open(fnStatistics,'w') for varName, variable in experiment.variables.iteritems(): if variable.role == PKPDVariable.ROLE_LABEL: varValues = experiment.getSubGroupLabels("True",varName) if variable.varType == PKPDVariable.TYPE_TEXT: self.doublePrint(fhOut,"%s ------------"%varName) counter = {} for value in varValues: if value in counter: counter[value]+=1 else: counter[value]=1 for value in counter: self.doublePrint(fhOut,"Value=%s Total count=%d (%f%%)"%(value,counter[value],100*float(counter[value])/len(varValues))) elif variable.varType == PKPDVariable.TYPE_NUMERIC: self.doublePrint(fhOut,"%s [%s] ------------"%(varName,strUnit(variable.units.unit))) varValues = np.asarray(varValues,np.double) self.doublePrint(fhOut,"Number of observations= %d"%len(varValues)) self.doublePrint(fhOut,"Range= [%f,%f]"%(np.min(varValues),np.max(varValues))) self.doublePrint(fhOut,"Mean= %f"%np.mean(varValues)) self.doublePrint(fhOut,"StdDev= %f"%np.std(varValues)) self.doublePrint(fhOut,"Skewness= %f"%scipy.stats.skew(varValues)) self.doublePrint(fhOut,"Kurtosis= %f"%scipy.stats.kurtosis(varValues)) self.doublePrint(fhOut,"Quantile 5%%= %f"%np.percentile(varValues,5)) self.doublePrint(fhOut,"Quantile 25%%= %f"%np.percentile(varValues,25)) self.doublePrint(fhOut,"Quantile 50%%= %f"%np.percentile(varValues,50)) self.doublePrint(fhOut,"Quantile 75%%= %f"%np.percentile(varValues,75)) self.doublePrint(fhOut,"Quantile 95%%= %f"%np.percentile(varValues,95)) self.doublePrint(fhOut," ") fhOut.close()
def runSimulate(self, objId, Nsimulations, confidenceInterval, doses): self.protODE = self.inputODE.get() if hasattr(self.protODE, "outputExperiment"): self.experiment = self.readExperiment( self.protODE.outputExperiment.fnPKPD) elif hasattr(self.protODE, "outputExperiment1"): self.experiment = self.readExperiment( self.protODE.outputExperiment1.fnPKPD) else: raise Exception("Cannot find an outputExperiment in the input ODE") if self.paramsSource == ProtPKPDODESimulate.PRM_POPULATION: self.fitting = self.readFitting( self.inputPopulation.get().fnFitting, cls="PKPDSampleFitBootstrap") else: if hasattr(self.protODE, "outputFitting"): self.fitting = self.readFitting( self.protODE.outputFitting.fnFitting) elif hasattr(self.protODE, "outputFitting1"): self.fitting = self.readFitting( self.protODE.outputFitting1.fnFitting) self.varNameX = self.fitting.predictor.varName if type(self.fitting.predicted) != list: self.varNameY = self.fitting.predicted.varName else: self.varNameY = [var.varName for var in self.fitting.predicted] # 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("min") self.outputExperiment.variables[self.varNameX] = tvar if type(self.fitting.predicted) != list: self.outputExperiment.variables[ self.varNameY] = self.experiment.variables[self.varNameY] else: for varName in self.varNameY: self.outputExperiment.variables[ varName] = self.experiment.variables[varName] self.outputExperiment.general["title"] = "Simulated ODE response" self.outputExperiment.general["comment"] = "Simulated ODE response" self.outputExperiment.vias = self.experiment.vias # Setup model self.model = self.protODE.createModel() self.model.setExperiment(self.outputExperiment) if hasattr(self.protODE, "deltaT"): self.model.deltaT = self.protODE.deltaT.get() self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) Nsamples = int(60 * math.ceil( (self.tF.get() - self.t0.get()) / self.model.deltaT)) + 1 self.model.x = [ self.t0.get() + i * self.model.deltaT for i in range(0, Nsamples) ] self.modelList.append(self.model) # Read the doses for line in self.doses.get().replace('\n', ';;').split(';;'): tokens = line.split(';') if len(tokens) < 5: print("Skipping dose: ", line) continue dosename = tokens[0].strip() self.outputExperiment.doses[dosename] = PKPDDose() self.outputExperiment.doses[dosename].parseTokens( tokens, self.experiment.vias) auxSample = PKPDSample() auxSample.descriptors = {} auxSample.doseDictPtr = self.outputExperiment.doses auxSample.variableDictPtr = self.outputExperiment.variables auxSample.doseList = [dosename] auxSample.interpretDose() self.drugSource.setDoses(auxSample.parsedDoseList, self.t0.get() - 10, self.tF.get() + 10) self.model.drugSource = self.drugSource # Check units # Dunits = self.outputExperiment.doses[dosename].dunits # Cunits = self.experiment.variables[self.varNameY].units # Process user parameters if self.paramsSource == ProtPKPDODESimulate.PRM_POPULATION: Nsimulations = self.Nsimulations.get() else: lines = self.prmUser.get().strip().replace('\n', ';;').split(';;') Nsimulations = len(lines) prmUser = [] for line in lines: tokens = line.strip().split(',') prmUser.append([float(token) for token in tokens]) # Simulate the different responses simulationsX = self.model.x simulationsY = np.zeros( (Nsimulations, len(simulationsX), self.getResponseDimension())) AUCarray = np.zeros(Nsimulations) AUMCarray = np.zeros(Nsimulations) MRTarray = np.zeros(Nsimulations) CminArray = np.zeros(Nsimulations) CmaxArray = np.zeros(Nsimulations) CavgArray = np.zeros(Nsimulations) fluctuationArray = np.zeros(Nsimulations) percentageAccumulationArray = np.zeros(Nsimulations) for i in range(0, Nsimulations): self.setTimeRange(None) if self.paramsSource == ProtPKPDODESimulate.PRM_POPULATION: # Take parameters randomly from the population nfit = int(random.uniform(0, len(self.fitting.sampleFits))) sampleFit = self.fitting.sampleFits[nfit] nprm = int(random.uniform(0, sampleFit.parameters.shape[0])) parameters = sampleFit.parameters[nprm, :] else: parameters = np.asarray(prmUser[i], np.double) print("Simulated sample %d: %s" % (i, str(parameters))) # Prepare source and this object self.drugSource.setDoses(auxSample.parsedDoseList, self.model.t0, self.model.tF) self.protODE.configureSource(self.drugSource) self.model.drugSource = self.drugSource parameterNames = self.getParameterNames( ) # Necessary to count the number of source and PK parameters # Prepare the model self.setParameters(parameters) y = self.forwardModel(parameters, [simulationsX] * self.getResponseDimension()) # Create AUC, AUMC, MRT variables and units if i == 0: if type(self.varNameY) != list: self.Cunits = self.experiment.variables[ self.varNameY].units else: self.Cunits = self.experiment.variables[ self.varNameY[0]].units self.AUCunits = multiplyUnits(tvar.units.unit, self.Cunits.unit) self.AUMCunits = multiplyUnits(tvar.units.unit, self.AUCunits) if self.addStats or self.addIndividuals: AUCvar = PKPDVariable() AUCvar.varName = "AUC0t" AUCvar.varType = PKPDVariable.TYPE_NUMERIC AUCvar.role = PKPDVariable.ROLE_LABEL AUCvar.units = createUnit(strUnit(self.AUCunits)) AUMCvar = PKPDVariable() AUMCvar.varName = "AUMC0t" AUMCvar.varType = PKPDVariable.TYPE_NUMERIC AUMCvar.role = PKPDVariable.ROLE_LABEL AUMCvar.units = createUnit(strUnit(self.AUMCunits)) MRTvar = PKPDVariable() MRTvar.varName = "MRT" MRTvar.varType = PKPDVariable.TYPE_NUMERIC MRTvar.role = PKPDVariable.ROLE_LABEL MRTvar.units = createUnit("min") self.outputExperiment.variables["AUC0t"] = AUCvar self.outputExperiment.variables["AUMC0t"] = AUMCvar self.outputExperiment.variables["MRT"] = MRTvar # Evaluate AUC, AUMC and MRT in the last full period self.NCA(self.model.x, y[0]) # Keep results for j in range(self.getResponseDimension()): simulationsY[i, :, j] = y[j] AUCarray[i] = self.AUC0t AUMCarray[i] = self.AUMC0t MRTarray[i] = self.MRT CminArray[i] = self.Cmin CmaxArray[i] = self.Cmax CavgArray[i] = self.Cavg fluctuationArray[i] = self.fluctuation percentageAccumulationArray[i] = self.percentageAccumulation if self.addIndividuals or self.paramsSource == ProtPKPDODESimulate.PRM_USER_DEFINED: self.addSample("Simulation_%d" % i, dosename, simulationsX, y) # Report NCA statistics alpha_2 = (100 - self.confidenceLevel.get()) / 2 limits = np.percentile(AUCarray, [alpha_2, 100 - alpha_2]) print("AUC %f%% confidence interval=[%f,%f] [%s] mean=%f" % (self.confidenceLevel.get(), limits[0], limits[1], strUnit(self.AUCunits), np.mean(AUCarray))) limits = np.percentile(AUMCarray, [alpha_2, 100 - alpha_2]) print("AUMC %f%% confidence interval=[%f,%f] [%s] mean=%f" % (self.confidenceLevel.get(), limits[0], limits[1], strUnit(self.AUMCunits), np.mean(AUMCarray))) limits = np.percentile(MRTarray, [alpha_2, 100 - alpha_2]) print("MRT %f%% confidence interval=[%f,%f] [min] mean=%f" % (self.confidenceLevel.get(), limits[0], limits[1], np.mean(MRTarray))) limits = np.percentile(CminArray, [alpha_2, 100 - alpha_2]) print("Cmin %f%% confidence interval=[%f,%f] [%s] mean=%f" % (self.confidenceLevel.get(), limits[0], limits[1], strUnit(self.Cunits.unit), np.mean(CminArray))) limits = np.percentile(CmaxArray, [alpha_2, 100 - alpha_2]) print("Cmax %f%% confidence interval=[%f,%f] [%s] mean=%f" % (self.confidenceLevel.get(), limits[0], limits[1], strUnit(self.Cunits.unit), np.mean(CmaxArray))) limits = np.percentile(CavgArray, [alpha_2, 100 - alpha_2]) print("Cavg %f%% confidence interval=[%f,%f] [%s] mean=%f" % (self.confidenceLevel.get(), limits[0], limits[1], strUnit(self.Cunits.unit), np.mean(CavgArray))) limits = np.percentile(fluctuationArray, [alpha_2, 100 - alpha_2]) print("Fluctuation %f%% confidence interval=[%f,%f] [%%] mean=%f" % (self.confidenceLevel.get(), limits[0] * 100, limits[1] * 100, np.mean(fluctuationArray) * 100)) limits = np.percentile(percentageAccumulationArray, [alpha_2, 100 - alpha_2]) print("Accum(1) %f%% confidence interval=[%f,%f] [%%] mean=%f" % (self.confidenceLevel.get(), limits[0] * 100, limits[1] * 100, np.mean(percentageAccumulationArray) * 100)) # Calculate statistics if self.addStats: if self.paramsSource != ProtPKPDODESimulate.PRM_USER_DEFINED: limits = np.percentile(simulationsY, [alpha_2, 100 - alpha_2], axis=0) print("Lower limit NCA") self.NCA(simulationsX, limits[0]) self.addSample("LowerLimit", dosename, simulationsX, limits[0]) print("Mean profile NCA") if self.getResponseDimension() == 1: mu = np.mean(simulationsY, axis=0) self.NCA(simulationsX, mu) else: mu = [] for j in range(self.getResponseDimension()): mu.append(np.mean(simulationsY[:, :, j], axis=0)) self.NCA(simulationsX, mu[0]) self.addSample("Mean", dosename, simulationsX, mu) if self.paramsSource != ProtPKPDODESimulate.PRM_USER_DEFINED: print("Upper limit NCA") self.NCA(simulationsX, limits[1]) self.addSample("UpperLimit", dosename, simulationsX, limits[1]) self.outputExperiment.write(self._getPath("experiment.pkpd"))
def NCA(self, t, C): AUClist = [] AUMClist = [] Cminlist = [] Cavglist = [] Cmaxlist = [] Tmaxlist = [] Tminlist = [] Ndoses = len(self.drugSource.parsedDoseList) for ndose in range(0, max(Ndoses - 1, 1)): tperiod0 = self.drugSource.parsedDoseList[ndose].t0 if ndose + 1 < Ndoses: tperiodF = self.drugSource.parsedDoseList[ ndose + 1].t0 - self.model.deltaT else: tperiodF = np.max(t) - 1 idx0 = find_nearest(t, tperiod0) idxF = find_nearest(t, tperiodF) AUC0t = 0 AUMC0t = 0 t0 = t[idx0 + 1] for idx in range(idx0, idxF + 1): dt = (t[idx + 1] - t[idx]) if C[idx + 1] >= C[idx]: # Trapezoidal in the raise AUC0t += 0.5 * dt * (C[idx] + C[idx + 1]) AUMC0t += 0.5 * dt * (C[idx] * t[idx] + C[idx + 1] * t[idx + 1]) else: # Log-trapezoidal in the decay decrement = C[idx] / C[idx + 1] K = math.log(decrement) B = K / dt AUC0t += dt * (C[idx] - C[idx + 1]) / K AUMC0t += (C[idx] * (t[idx] - tperiod0) - C[idx + 1] * (t[idx + 1] - tperiod0)) / B - ( C[idx + 1] - C[idx]) / (B * B) if idx == idx0: Cmax = C[idx] Tmax = t[idx] - t0 Cmin = C[idx] Tmin = t[idx] - t0 else: if C[idx] < Cmin: Cmin = C[idx] Tmin = t[idx] - t0 elif C[idx] > Cmax: Cmax = C[idx] Tmax = t[idx] - t0 if ndose == 0: Cmin = C[idx] Tmin = t[idx] - t0 AUClist.append(AUC0t) AUMClist.append(AUMC0t) Cminlist.append(Cmin) Cmaxlist.append(Cmax) Tmaxlist.append(Tmax) Tminlist.append(Tmin) Cavglist.append(AUC0t / (t[idxF] - t[idx0])) print("Fluctuation = Cmax/Cmin") print("Accumulation(1) = Cavg(n)/Cavg(1) %") print("Accumulation(n) = Cavg(n)/Cavg(n-1) %") print("Steady state fraction(n) = Cavg(n)/Cavg(last) %") for ndose in range(0, len(AUClist)): fluctuation = Cmaxlist[ndose] / Cminlist[ndose] if ndose > 0: accumn = Cavglist[ndose] / Cavglist[ndose - 1] else: accumn = 0 print("Dose #%d: Cavg= %f [%s] Cmin= %f [%s] Tmin= %d [min] Cmax= %f [%s] Tmax= %d [min] Fluct= %f %% Accum(1)= %f %% Accum(n)= %f %% SSFrac(n)= %f %% AUC= %f [%s] AUMC= %f [%s]"%\ (ndose+1,Cavglist[ndose], strUnit(self.Cunits.unit), Cminlist[ndose],strUnit(self.Cunits.unit), int(Tminlist[ndose]), Cmaxlist[ndose], strUnit(self.Cunits.unit), int(Tmaxlist[ndose]), fluctuation*100, Cavglist[ndose]/Cavglist[0]*100, accumn*100, Cavglist[ndose]/Cavglist[-1]*100, AUClist[ndose],strUnit(self.AUCunits), AUMClist[ndose],strUnit(self.AUMCunits))) self.AUC0t = AUClist[-1] self.AUMC0t = AUMClist[-1] self.MRT = self.AUMC0t / self.AUC0t self.Cmin = Cminlist[-1] self.Cmax = Cmaxlist[-1] self.Cavg = Cavglist[-1] self.fluctuation = self.Cmax / self.Cmin self.percentageAccumulation = Cavglist[-1] / Cavglist[0] print(" AUC0t=%f [%s]" % (self.AUC0t, strUnit(self.AUCunits))) print(" AUMC0t=%f [%s]" % (self.AUMC0t, strUnit(self.AUMCunits))) print(" MRT=%f [min]" % self.MRT)
def runSimulate(self, objId, Nsimulations, confidenceInterval, doses): self.protODE = self.inputODE.get() if hasattr(self.protODE,"outputExperiment"): self.experiment = self.readExperiment(self.protODE.outputExperiment.fnPKPD) elif hasattr(self.protODE,"outputExperiment1"): self.experiment = self.readExperiment(self.protODE.outputExperiment1.fnPKPD) else: raise Exception("Cannot find an outputExperiment in the input ODE") if self.paramsSource==ProtPKPDODESimulate.PRM_POPULATION: self.fitting = self.readFitting(self.inputPopulation.get().fnFitting, cls="PKPDSampleFitBootstrap") else: if hasattr(self.protODE, "outputFitting"): self.fitting = self.readFitting(self.protODE.outputFitting.fnFitting) elif hasattr(self.protODE, "outputFitting1"): self.fitting = self.readFitting(self.protODE.outputFitting1.fnFitting) self.varNameX = self.fitting.predictor.varName if type(self.fitting.predicted)!=list: self.varNameY = self.fitting.predicted.varName else: self.varNameY = [var.varName for var in self.fitting.predicted] # 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("min") self.outputExperiment.variables[self.varNameX] = tvar if type(self.fitting.predicted)!=list: self.outputExperiment.variables[self.varNameY] = self.experiment.variables[self.varNameY] else: for varName in self.varNameY: self.outputExperiment.variables[varName] = self.experiment.variables[varName] self.outputExperiment.general["title"]="Simulated ODE response" self.outputExperiment.general["comment"]="Simulated ODE response" self.outputExperiment.vias = self.experiment.vias # Setup model self.model = self.protODE.createModel() self.model.setExperiment(self.outputExperiment) if hasattr(self.protODE,"deltaT"): self.model.deltaT = self.protODE.deltaT.get() self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) Nsamples = int(60*math.ceil((self.tF.get()-self.t0.get())/self.model.deltaT))+1 self.model.x = [self.t0.get()+i*self.model.deltaT for i in range(0,Nsamples)] self.modelList.append(self.model) # Read the doses for line in self.doses.get().replace('\n',';;').split(';;'): tokens = line.split(';') if len(tokens)<5: print("Skipping dose: ",line) continue dosename = tokens[0].strip() self.outputExperiment.doses[dosename] = PKPDDose() self.outputExperiment.doses[dosename].parseTokens(tokens,self.experiment.vias) auxSample = PKPDSample() auxSample.descriptors = {} auxSample.doseDictPtr = self.outputExperiment.doses auxSample.variableDictPtr = self.outputExperiment.variables auxSample.doseList = [dosename] auxSample.interpretDose() self.drugSource.setDoses(auxSample.parsedDoseList, self.t0.get()-10, self.tF.get()+10) self.model.drugSource = self.drugSource # Check units # Dunits = self.outputExperiment.doses[dosename].dunits # Cunits = self.experiment.variables[self.varNameY].units # Process user parameters if self.paramsSource==ProtPKPDODESimulate.PRM_POPULATION: Nsimulations = self.Nsimulations.get() else: lines = self.prmUser.get().strip().replace('\n',';;').split(';;') Nsimulations = len(lines) prmUser = [] for line in lines: tokens = line.strip().split(',') prmUser.append([float(token) for token in tokens]) # Simulate the different responses simulationsX = self.model.x simulationsY = np.zeros((Nsimulations,len(simulationsX),self.getResponseDimension())) AUCarray = np.zeros(Nsimulations) AUMCarray = np.zeros(Nsimulations) MRTarray = np.zeros(Nsimulations) CminArray = np.zeros(Nsimulations) CmaxArray = np.zeros(Nsimulations) CavgArray = np.zeros(Nsimulations) fluctuationArray = np.zeros(Nsimulations) percentageAccumulationArray = np.zeros(Nsimulations) for i in range(0,Nsimulations): self.setTimeRange(None) if self.paramsSource==ProtPKPDODESimulate.PRM_POPULATION: # Take parameters randomly from the population nfit = int(random.uniform(0,len(self.fitting.sampleFits))) sampleFit = self.fitting.sampleFits[nfit] nprm = int(random.uniform(0,sampleFit.parameters.shape[0])) parameters = sampleFit.parameters[nprm,:] else: parameters = np.asarray(prmUser[i],np.double) print("Simulated sample %d: %s"%(i,str(parameters))) # Prepare source and this object self.drugSource.setDoses(auxSample.parsedDoseList, self.model.t0, self.model.tF) self.protODE.configureSource(self.drugSource) self.model.drugSource = self.drugSource parameterNames = self.getParameterNames() # Necessary to count the number of source and PK parameters # Prepare the model self.setParameters(parameters) y = self.forwardModel(parameters, [simulationsX]*self.getResponseDimension()) # Create AUC, AUMC, MRT variables and units if i == 0: if type(self.varNameY)!=list: self.Cunits = self.experiment.variables[self.varNameY].units else: self.Cunits = self.experiment.variables[self.varNameY[0]].units self.AUCunits = multiplyUnits(tvar.units.unit, self.Cunits.unit) self.AUMCunits = multiplyUnits(tvar.units.unit, self.AUCunits) if self.addStats or self.addIndividuals: AUCvar = PKPDVariable() AUCvar.varName = "AUC0t" AUCvar.varType = PKPDVariable.TYPE_NUMERIC AUCvar.role = PKPDVariable.ROLE_LABEL AUCvar.units = createUnit(strUnit(self.AUCunits)) AUMCvar = PKPDVariable() AUMCvar.varName = "AUMC0t" AUMCvar.varType = PKPDVariable.TYPE_NUMERIC AUMCvar.role = PKPDVariable.ROLE_LABEL AUMCvar.units = createUnit(strUnit(self.AUMCunits)) MRTvar = PKPDVariable() MRTvar.varName = "MRT" MRTvar.varType = PKPDVariable.TYPE_NUMERIC MRTvar.role = PKPDVariable.ROLE_LABEL MRTvar.units = createUnit("min") self.outputExperiment.variables["AUC0t"] = AUCvar self.outputExperiment.variables["AUMC0t"] = AUMCvar self.outputExperiment.variables["MRT"] = MRTvar # Evaluate AUC, AUMC and MRT in the last full period self.NCA(self.model.x,y[0]) # Keep results for j in range(self.getResponseDimension()): simulationsY[i,:,j] = y[j] AUCarray[i] = self.AUC0t AUMCarray[i] = self.AUMC0t MRTarray[i] = self.MRT CminArray[i] = self.Cmin CmaxArray[i] = self.Cmax CavgArray[i] = self.Cavg fluctuationArray[i] = self.fluctuation percentageAccumulationArray[i] = self.percentageAccumulation if self.addIndividuals or self.paramsSource==ProtPKPDODESimulate.PRM_USER_DEFINED: self.addSample("Simulation_%d"%i, dosename, simulationsX, y) # Report NCA statistics alpha_2 = (100-self.confidenceLevel.get())/2 limits = np.percentile(AUCarray,[alpha_2,100-alpha_2]) print("AUC %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.AUCunits),np.mean(AUCarray))) limits = np.percentile(AUMCarray,[alpha_2,100-alpha_2]) print("AUMC %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.AUMCunits),np.mean(AUMCarray))) limits = np.percentile(MRTarray,[alpha_2,100-alpha_2]) print("MRT %f%% confidence interval=[%f,%f] [min] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],np.mean(MRTarray))) limits = np.percentile(CminArray,[alpha_2,100-alpha_2]) print("Cmin %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.Cunits.unit),np.mean(CminArray))) limits = np.percentile(CmaxArray,[alpha_2,100-alpha_2]) print("Cmax %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.Cunits.unit),np.mean(CmaxArray))) limits = np.percentile(CavgArray,[alpha_2,100-alpha_2]) print("Cavg %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.Cunits.unit),np.mean(CavgArray))) limits = np.percentile(fluctuationArray,[alpha_2,100-alpha_2]) print("Fluctuation %f%% confidence interval=[%f,%f] [%%] mean=%f"%(self.confidenceLevel.get(),limits[0]*100,limits[1]*100,np.mean(fluctuationArray)*100)) limits = np.percentile(percentageAccumulationArray,[alpha_2,100-alpha_2]) print("Accum(1) %f%% confidence interval=[%f,%f] [%%] mean=%f"%(self.confidenceLevel.get(),limits[0]*100,limits[1]*100,np.mean(percentageAccumulationArray)*100)) # Calculate statistics if self.addStats: if self.paramsSource!=ProtPKPDODESimulate.PRM_USER_DEFINED: limits = np.percentile(simulationsY,[alpha_2,100-alpha_2],axis=0) print("Lower limit NCA") self.NCA(simulationsX,limits[0]) self.addSample("LowerLimit", dosename, simulationsX, limits[0]) print("Mean profile NCA") if self.getResponseDimension()==1: mu = np.mean(simulationsY,axis=0) self.NCA(simulationsX, mu) else: mu = [] for j in range(self.getResponseDimension()): mu.append(np.mean(simulationsY[:,:,j],axis=0)) self.NCA(simulationsX,mu[0]) self.addSample("Mean", dosename, simulationsX, mu) if self.paramsSource!=ProtPKPDODESimulate.PRM_USER_DEFINED: print("Upper limit NCA") self.NCA(simulationsX,limits[1]) self.addSample("UpperLimit", dosename, simulationsX, limits[1]) self.outputExperiment.write(self._getPath("experiment.pkpd"))
def NCA(self,t,C): AUClist = [] AUMClist = [] Cminlist = [] Cavglist = [] Cmaxlist = [] Tmaxlist = [] Tminlist = [] Ndoses=len(self.drugSource.parsedDoseList) for ndose in range(0,max(Ndoses-1,1)): tperiod0 = self.drugSource.parsedDoseList[ndose].t0 if ndose+1<Ndoses: tperiodF = self.drugSource.parsedDoseList[ndose+1].t0-self.model.deltaT else: tperiodF = np.max(t)-1 idx0 = find_nearest(t,tperiod0) idxF = find_nearest(t,tperiodF) AUC0t = 0 AUMC0t = 0 t0 = t[idx0+1] for idx in range(idx0,idxF+1): dt = (t[idx+1]-t[idx]) if C[idx+1]>=C[idx]: # Trapezoidal in the raise AUC0t += 0.5*dt*(C[idx]+C[idx+1]) AUMC0t += 0.5*dt*(C[idx]*t[idx]+C[idx+1]*t[idx+1]) else: # Log-trapezoidal in the decay decrement = C[idx]/C[idx+1] K = math.log(decrement) B = K/dt AUC0t += dt*(C[idx]-C[idx+1])/K AUMC0t += (C[idx]*(t[idx]-tperiod0)-C[idx+1]*(t[idx+1]-tperiod0))/B-(C[idx+1]-C[idx])/(B*B) if idx==idx0: Cmax=C[idx] Tmax=t[idx]-t0 Cmin=C[idx] Tmin=t[idx]-t0 else: if C[idx]<Cmin: Cmin=C[idx] Tmin=t[idx]-t0 elif C[idx]>Cmax: Cmax=C[idx] Tmax=t[idx]-t0 if ndose==0: Cmin=C[idx] Tmin=t[idx]-t0 AUClist.append(AUC0t) AUMClist.append(AUMC0t) Cminlist.append(Cmin) Cmaxlist.append(Cmax) Tmaxlist.append(Tmax) Tminlist.append(Tmin) Cavglist.append(AUC0t/(t[idxF]-t[idx0])) print("Fluctuation = Cmax/Cmin") print("Accumulation(1) = Cavg(n)/Cavg(1) %") print("Accumulation(n) = Cavg(n)/Cavg(n-1) %") print("Steady state fraction(n) = Cavg(n)/Cavg(last) %") for ndose in range(0,len(AUClist)): fluctuation = Cmaxlist[ndose]/Cminlist[ndose] if ndose>0: accumn = Cavglist[ndose]/Cavglist[ndose-1] else: accumn = 0 print("Dose #%d: Cavg= %f [%s] Cmin= %f [%s] Tmin= %d [min] Cmax= %f [%s] Tmax= %d [min] Fluct= %f %% Accum(1)= %f %% Accum(n)= %f %% SSFrac(n)= %f %% AUC= %f [%s] AUMC= %f [%s]"%\ (ndose+1,Cavglist[ndose], strUnit(self.Cunits.unit), Cminlist[ndose],strUnit(self.Cunits.unit), int(Tminlist[ndose]), Cmaxlist[ndose], strUnit(self.Cunits.unit), int(Tmaxlist[ndose]), fluctuation*100, Cavglist[ndose]/Cavglist[0]*100, accumn*100, Cavglist[ndose]/Cavglist[-1]*100, AUClist[ndose],strUnit(self.AUCunits), AUMClist[ndose],strUnit(self.AUMCunits))) self.AUC0t = AUClist[-1] self.AUMC0t = AUMClist[-1] self.MRT = self.AUMC0t/self.AUC0t self.Cmin = Cminlist[-1] self.Cmax = Cmaxlist[-1] self.Cavg = Cavglist[-1] self.fluctuation = self.Cmax/self.Cmin self.percentageAccumulation = Cavglist[-1]/Cavglist[0] print(" AUC0t=%f [%s]"%(self.AUC0t,strUnit(self.AUCunits))) print(" AUMC0t=%f [%s]"%(self.AUMC0t,strUnit(self.AUMCunits))) print(" MRT=%f [min]"%self.MRT)
def runFit(self, predictor, avgParameters, confidenceInterval): self.scaleModel = PKPDAllometricScale() self.scaleModel.confidence = float(self.confidenceInterval.get()) self.scaleModel.predictor = self.predictor.get() if self.allometricParameters.get().strip()!="": for token in self.allometricParameters.get().split(','): self.scaleModel.scaled_vars.append(token.strip()) if self.avgParameters.get().strip()!="": for token in self.avgParameters.get().split(','): self.scaleModel.averaged_vars.append(token.strip()) X=[] Y={} for varName in self.scaleModel.scaled_vars+self.scaleModel.averaged_vars: Y[varName]=[] for experimentPtr in self.inputExps: # Load experiment experiment = PKPDExperiment() experiment.load(experimentPtr.get().fnPKPD) # Get the first sample sample = experiment.samples.values()[0] # Extract X retval = sample.getDescriptorValue(self.predictor.get()) if retval: X.append(float(retval)) else: raise Exception("Cannot find %s in %s"%(self.predictor.get(),experiment.fnPKPD)) # Extract Y for varName in self.scaleModel.scaled_vars+self.scaleModel.averaged_vars: retval = sample.getDescriptorValue(varName) if retval: Y[varName].append(float(retval)) else: raise Exception("Cannot find %s in %s"%(varName,experiment.fnPKPD)) self.scaleModel.predictorUnits = strUnit(experiment.variables[self.predictor.get()].units.unit) varList = [] for varName in self.scaleModel.scaled_vars: varList.append((varName,strUnit(experiment.variables[varName].units.unit))) self.scaleModel.scaled_vars = copy.copy(varList) varList = [] for varName in self.scaleModel.averaged_vars: varList.append((varName,strUnit(experiment.variables[varName].units.unit))) self.scaleModel.averaged_vars = copy.copy(varList) print("X: %s"%str(X)) logx=np.log10(np.asarray(X)) self.scaleModel.X = X self.scaleModel.Y = Y fhSummary=open(self._getPath("summary.txt"),"w") fhSummary.write("Predictor variable: %s\n"%self.predictor.get()) fhSummary.write("Parameters to average: %s\n"%self.avgParameters.get()) fhSummary.write("Confidence interval: %f\n"%self.confidenceInterval.get()) for varName, varUnits in self.scaleModel.scaled_vars: print("%s: %s"%(varName,str(Y[varName]))) y = np.asarray(Y[varName]) logy = np.log10(y) A=np.ones((logx.size,2)) A[:,0]=logx.T F=np.linalg.inv(np.dot(A.T,A)) p = np.dot(F,np.dot(A.T,logy.T)) logyPredicted=np.dot(A,p) e=logy-logyPredicted sigma2=np.var(e) V=sigma2*F # We manually implement the regression because np.polyfit has an unbiased estimator of V that # does not work well with 4 samples # p, V = np.polyfit(logx, logy, 1, cov=True) # e = logy - logyPredicted R2 = (1 - np.var(e) / np.var(logy)) from scipy.stats import norm nstd = norm.ppf(1-(1-self.scaleModel.confidence/100)/2) perr = np.sqrt(np.diag(V)) lowerBound = p - nstd * perr upperBound = p + nstd * perr # Back to natural units p[1]=math.pow(10.0,p[1]) lowerBound[1]=math.pow(10.0,lowerBound[1]) upperBound[1]=math.pow(10.0,upperBound[1]) self.scaleModel.models[varName] = [p[1],p[0]] self.scaleModel.qualifiers[varName] = [R2,lowerBound[1],upperBound[1],lowerBound[0],upperBound[0]] self.doublePrint(fhSummary, "%s=(%f)*%s^(%f) R2=%f %f%% Confidence intervals (y=k*x^a): k=[%f,%f] a=[%f,%f]; %s" % \ (varName, p[1], self.predictor, p[0], R2, self.confidenceInterval, lowerBound[1],upperBound[1],lowerBound[0],upperBound[0], varUnits)) for varName, varUnits in self.scaleModel.averaged_vars: print("%s: %s"%(varName,str(Y[varName]))) y = np.asarray(Y[varName]) self.scaleModel.models[varName] = [np.mean(y)] self.scaleModel.qualifiers[varName] = [np.std(y)] self.doublePrint(fhSummary, "%s avg=%f std=%f; %s"%(varName,self.scaleModel.models[varName][0],self.scaleModel.qualifiers[varName][0],varUnits)) fhSummary.close() self.scaleModel.write(self._getPath("allometricScale.pkpd"))