def readFitting(self, fnIn, show=True, cls=""): fitting = PKPDFitting(cls) fitting.load(fnIn) if show: self.printSection("Reading %s"%fnIn) fitting._printToStream(sys.stdout) return fitting
def visualize(self, obj, **kwargs): if hasattr(obj, "outputPopulation"): population = PKPDFitting("PKPDSampleFitBootstrap") population.load(obj.outputPopulation.fnFitting) self.populationWindow = self.tkWindow(PopulationWindow, title='Population Viewer', population=population) self.populationWindow.show()
def visualize(self, obj, **kwargs): if hasattr(obj,"outputPopulation"): population = PKPDFitting("PKPDSampleFitBootstrap") population.load(obj.outputPopulation.fnFitting) self.populationWindow = self.tkWindow(PopulationWindow, title='Population Viewer', population=population) self.populationWindow.show()
def runMerge(self, objId1, objId2): self.population1 = self.readFitting( self.inputPopulation1.get().fnFitting, cls="PKPDSampleFitBootstrap") self.population2 = self.readFitting( self.inputPopulation2.get().fnFitting, cls="PKPDSampleFitBootstrap") self.printSection("Merging populations") self.fitting = PKPDFitting("PKPDSampleFitBootstrap") self.fitting.fnExperiment.set(self.population1.fnExperiment) self.fitting.predictor = self.population1.predictor self.fitting.predicted = self.population1.predicted self.fitting.modelParameterUnits = self.population1.modelParameterUnits self.fitting.modelParameters = self.population1.modelParameters self.fitting.modelDescription = self.population1.modelDescription newSampleFit = PKPDSampleFitBootstrap() newSampleFit.sampleName = "Merged population" newSampleFit.parameters = None for sampleFit in self.population1.sampleFits: if newSampleFit.parameters == None: newSampleFit.parameters = np.copy(sampleFit.parameters) newSampleFit.xB = copy.copy(sampleFit.xB) newSampleFit.yB = copy.copy(sampleFit.yB) newSampleFit.R2 = copy.copy(sampleFit.R2) newSampleFit.R2adj = copy.copy(sampleFit.R2adj) newSampleFit.AIC = copy.copy(sampleFit.AIC) newSampleFit.AICc = copy.copy(sampleFit.AICc) newSampleFit.BIC = copy.copy(sampleFit.BIC) else: newSampleFit.parameters = np.vstack( [newSampleFit.parameters, sampleFit.parameters]) newSampleFit.xB += sampleFit.xB newSampleFit.yB += sampleFit.yB newSampleFit.R2 += sampleFit.R2 newSampleFit.R2adj += sampleFit.R2adj newSampleFit.AIC += sampleFit.AIC newSampleFit.AICc += sampleFit.AICc newSampleFit.BIC += sampleFit.BIC for sampleFit in self.population2.sampleFits: newSampleFit.parameters = np.vstack( [newSampleFit.parameters, sampleFit.parameters]) print(type(newSampleFit.xB)) print(type(sampleFit.xB)) newSampleFit.xB += sampleFit.xB newSampleFit.yB += sampleFit.yB newSampleFit.R2 += sampleFit.R2 newSampleFit.R2adj += sampleFit.R2adj newSampleFit.AIC += sampleFit.AIC newSampleFit.AICc += sampleFit.AICc newSampleFit.BIC += sampleFit.BIC self.fitting.sampleFits.append(newSampleFit) self.fitting.write(self._getPath("bootstrapPopulation.pkpd"))
def readFitting(self, fnIn, show=True, cls=""): fitting = PKPDFitting(cls) fitting.load(fnIn) if show: self.printSection("Reading %s" % fnIn) fitting._printToStream(sys.stdout) return fitting
def runMerge(self, objId1, objId2): self.population1 = self.readFitting(self.inputPopulation1.get().fnFitting,cls="PKPDSampleFitBootstrap") self.population2 = self.readFitting(self.inputPopulation2.get().fnFitting,cls="PKPDSampleFitBootstrap") self.printSection("Merging populations") self.fitting = PKPDFitting("PKPDSampleFitBootstrap") self.fitting.fnExperiment.set(self.population1.fnExperiment) self.fitting.predictor=self.population1.predictor self.fitting.predicted=self.population1.predicted self.fitting.modelParameterUnits = self.population1.modelParameterUnits self.fitting.modelParameters = self.population1.modelParameters self.fitting.modelDescription = self.population1.modelDescription newSampleFit = PKPDSampleFitBootstrap() newSampleFit.sampleName = "Merged population" newSampleFit.parameters = None for sampleFit in self.population1.sampleFits: if newSampleFit.parameters == None: newSampleFit.parameters = np.copy(sampleFit.parameters) newSampleFit.xB = copy.copy(sampleFit.xB) newSampleFit.yB = copy.copy(sampleFit.yB) newSampleFit.R2 = copy.copy(sampleFit.R2) newSampleFit.R2adj = copy.copy(sampleFit.R2adj) newSampleFit.AIC = copy.copy(sampleFit.AIC) newSampleFit.AICc = copy.copy(sampleFit.AICc) newSampleFit.BIC = copy.copy(sampleFit.BIC) else: newSampleFit.parameters = np.vstack([newSampleFit.parameters, sampleFit.parameters]) newSampleFit.xB += sampleFit.xB newSampleFit.yB += sampleFit.yB newSampleFit.R2 += sampleFit.R2 newSampleFit.R2adj += sampleFit.R2adj newSampleFit.AIC += sampleFit.AIC newSampleFit.AICc += sampleFit.AICc newSampleFit.BIC += sampleFit.BIC for sampleFit in self.population2.sampleFits: newSampleFit.parameters = np.vstack([newSampleFit.parameters, sampleFit.parameters]) print(type(newSampleFit.xB)) print(type(sampleFit.xB)) newSampleFit.xB += sampleFit.xB newSampleFit.yB += sampleFit.yB newSampleFit.R2 += sampleFit.R2 newSampleFit.R2adj += sampleFit.R2adj newSampleFit.AIC += sampleFit.AIC newSampleFit.AICc += sampleFit.AICc newSampleFit.BIC += sampleFit.BIC self.fitting.sampleFits.append(newSampleFit) self.fitting.write(self._getPath("bootstrapPopulation.pkpd"))
def createFitting(self, prot, experiment, suffix): # Create output object fitting = PKPDFitting() fitting.fnExperiment.set(self._getPath("experiment%d.pkpd"%suffix)) fitting.predictor=experiment.variables[prot.varNameX] if type(prot.varNameY)==list: fitting.predicted=[] for y in prot.varNameY: fitting.predicted.append(experiment.variables[y]) else: fitting.predicted=experiment.variables[prot.varNameY] fitting.modelParameterUnits = None return fitting
def runFilter(self, objId, filterType, condition): self.population = self.readFitting(self.inputPopulation.get().fnFitting,cls="PKPDSampleFitBootstrap") self.printSection("Filtering population") self.fitting = PKPDFitting("PKPDSampleFitBootstrap") self.fitting.fnExperiment.set(self.population.fnExperiment) self.fitting.predictor=self.population.predictor self.fitting.predicted=self.population.predicted self.fitting.modelParameterUnits = self.population.modelParameterUnits self.fitting.modelParameters = self.population.modelParameters self.fitting.modelDescription = self.population.modelDescription newSampleFit = PKPDSampleFitBootstrap() newSampleFit.parameters = None filterType = self.filterType.get() for sampleFit in self.population.sampleFits: newSampleFit.sampleName = sampleFit.sampleName if newSampleFit.parameters == None: newSampleFit.parameters = np.empty((0,sampleFit.parameters.shape[1])) newSampleFit.xB = [] newSampleFit.yB = [] newSampleFit.R2 = [] newSampleFit.R2adj = [] newSampleFit.AIC = [] newSampleFit.AICc = [] newSampleFit.BIC = [] if filterType<=1: conditionToEvaluate = self.condition.get() else: tokens=self.condition.get().strip().split(' ') variable = tokens[0][2:-1] confidenceLevel = float(tokens[1]) columnIdx = -1 for j in range(len(self.population.modelParameters)): if self.population.modelParameters[j]==variable: columnIdx = j break if columnIdx==-1: raise Exception("Cannot find %s amongst the model variables"%variable) values=sampleFit.parameters[:,columnIdx] alpha_2 = (100-confidenceLevel)/2 limits = np.percentile(values,[alpha_2,100-alpha_2]) conditionToEvaluate = "%s>=%f and %s<=%f"%(tokens[0],limits[0],tokens[0],limits[1]) print("Condition to evaluate: %s"%conditionToEvaluate) for n in range(0,len(sampleFit.R2)): evaluatedCondition = copy.copy(conditionToEvaluate) evaluatedCondition = evaluatedCondition.replace('$(R2)',"(%f)"%sampleFit.R2[n]) evaluatedCondition = evaluatedCondition.replace('$(R2adj)',"(%f)"%sampleFit.R2adj[n]) evaluatedCondition = evaluatedCondition.replace('$(AIC)',"(%f)"%sampleFit.AIC[n]) evaluatedCondition = evaluatedCondition.replace('$(AICc)',"(%f)"%sampleFit.AICc[n]) evaluatedCondition = evaluatedCondition.replace('$(BIC)',"(%f)"%sampleFit.BIC[n]) for j in range(len(self.population.modelParameters)): evaluatedCondition = evaluatedCondition.replace('$(%s)'%self.population.modelParameters[j],"(%f)"%sampleFit.parameters[n,j]) evaluatedCondition = eval(evaluatedCondition) if (filterType==0 and not evaluatedCondition) or (filterType>=1 and evaluatedCondition): newSampleFit.parameters = np.vstack([newSampleFit.parameters, sampleFit.parameters[n,:]]) newSampleFit.xB += sampleFit.xB newSampleFit.yB += sampleFit.yB newSampleFit.R2.append(sampleFit.R2[n]) newSampleFit.R2adj.append(sampleFit.R2adj[n]) newSampleFit.AIC.append(sampleFit.AIC[n]) newSampleFit.AICc.append(sampleFit.AICc[n]) newSampleFit.BIC.append(sampleFit.BIC[n]) self.fitting.sampleFits.append(newSampleFit) self.fitting.write(self._getPath("bootstrapPopulation.pkpd"))
class ProtPKPDFitBase(ProtPKPD): """ Base fit protocol""" #--------------------------- DEFINE param functions -------------------------------------------- def _defineParams1(self, form, defaultPredictor, defaultPredicted): form.addSection('Input') form.addParam('inputExperiment', params.PointerParam, label="Input experiment", pointerClass='PKPDExperiment', help='Select an experiment with samples') form.addParam('predictor', params.StringParam, label="Predictor variable (X)", default=defaultPredictor, help='Y is predicted as an exponential function of X, Y=f(X)') form.addParam('predicted', params.StringParam, label="Predicted variable (Y)", default=defaultPredicted, help='Y is predicted as an exponential function of X, Y=f(X)') #--------------------------- INSERT steps functions -------------------------------------------- def _insertAllSteps(self): self._insertFunctionStep('runFit',self.getInputExperiment().getObjId(),self.getListOfFormDependencies()) self._insertFunctionStep('createOutputStep') #--------------------------- STEPS functions -------------------------------------------- def getInputExperiment(self): if hasattr(self,"inputExperiment"): return self.inputExperiment.get() else: return None def getXYvars(self): if hasattr(self,"predictor"): self.varNameX=self.predictor.get() else: self.varNameX=None if hasattr(self,"predicted"): self.varNameY=self.predicted.get() else: self.varNameY=None def setExperiment(self, experiment): self.experiment = experiment if experiment!=None: self.fnExperiment = experiment.fnPKPD def setSample(self, sample): self.sample = sample self.model.setSample(sample) def createModel(self): pass def parseBounds(self, boundsString): self.boundsList = [] if boundsString!="" and boundsString!=None: tokens = boundsString.split(';') if len(tokens)!=self.getNumberOfParameters(): raise Exception("The number of bound intervals does not match the number of parameters") for token in tokens: values = token.strip().split(',') self.boundsList.append((float(values[0][1:]),float(values[1][:-1]))) def getBounds(self): return self.boundsList def getParameterBounds(self): """ Return a dictionary where the parameter name is the key and the bounds are its values. """ boundsDict = OrderedDict() self.parseBounds(self.bounds.get()) # after this we have boundsList parameterNames = self.model.getParameterNames() for paramName, bound in izip(parameterNames, self.getBounds()): boundsDict[paramName] = bound # Set None as bound for parameters not matched for paramName in parameterNames: if paramName not in boundsDict: boundsDict[paramName] = None return boundsDict def setupModel(self): # Setup model self.model = self.createModel() self.model.setExperiment(self.experiment) self.setupFromFormParameters() self.getXYvars() self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) def calculateParameterUnits(self,sample): self.parameterUnits = self.model.calculateParameterUnits(sample) def getParameterNames(self): return self.model.getParameterNames() def getNumberOfParameters(self): return len(self.getParameterNames()) def setParameters(self,prm): self.model.setParameters(prm) def forwardModel(self,prm,xValues): return self.model.forwardModel(prm,xValues) def setupFromFormParameters(self): pass def prepareForSampleAnalysis(self, sampleName): pass def postSampleAnalysis(self, sampleName): pass def runFit(self, objId, otherDependencies): self.getXYvars() if hasattr(self,"reportX"): reportX = parseRange(self.reportX.get()) else: reportX = None self.experiment = self.readExperiment(self.getInputExperiment().fnPKPD) # Setup model self.printSection("Model setup") self.model = self.createModel() self.model.setExperiment(self.experiment) self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) self.setupFromFormParameters() self.model.printSetup() # Create output object self.fitting = PKPDFitting() self.fitting.fnExperiment.set(self.getInputExperiment().fnPKPD.get()) self.fitting.predictor=self.experiment.variables[self.varNameX] self.fitting.predicted=self.experiment.variables[self.varNameY] self.fitting.modelDescription=self.model.getDescription() self.fitting.modelParameters = self.model.getParameterNames() self.fitting.modelParameterUnits = None # Actual fitting if self.fitType.get()==0: fitType = "linear" elif self.fitType.get()==1: fitType = "log" elif self.fitType.get()==2: fitType = "relative" for sampleName, sample in self.experiment.samples.iteritems(): self.printSection("Fitting "+sampleName) x, y = sample.getXYValues(self.varNameX,self.varNameY) print("X= "+str(x)) print("Y= "+str(y)) print(" ") self.model.setBounds(self.bounds.get()) self.model.setXYValues(x, y) self.prepareForSampleAnalysis(sampleName) self.model.calculateParameterUnits(sample) if self.fitting.modelParameterUnits==None: self.fitting.modelParameterUnits = self.model.parameterUnits self.model.prepare() if self.model.bounds == None: continue print(" ") optimizer1 = PKPDDEOptimizer(self.model,fitType) optimizer1.optimize() optimizer2 = PKPDLSOptimizer(self.model,fitType) optimizer2.optimize() optimizer2.setConfidenceInterval(self.confidenceInterval.get()) self.setParameters(optimizer2.optimum) optimizer2.evaluateQuality() # Keep this result sampleFit = PKPDSampleFit() sampleFit.sampleName = sample.sampleName sampleFit.x = self.model.x sampleFit.y = self.model.y sampleFit.yp = self.model.yPredicted sampleFit.yl = self.model.yPredictedLower sampleFit.yu = self.model.yPredictedUpper sampleFit.parameters = self.model.parameters sampleFit.modelEquation = self.model.getEquation() sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) # Add the parameters to the sample and experiment for varName, varUnits, description, varValue in izip(self.model.getParameterNames(), self.model.parameterUnits, self.model.getParameterDescriptions(), self.model.parameters): self.experiment.addParameterToSample(sampleName, varName, varUnits, description, varValue) self.postSampleAnalysis(sampleName) if reportX!=None: print("Evaluation of the model at specified time points") yreportX = self.model.forwardModel(self.model.parameters, reportX) print("==========================================") print("X Ypredicted log10(Ypredicted)") print("==========================================") for n in range(0,reportX.shape[0]): print("%f %f %f"%(reportX[n],yreportX[n],math.log10(yreportX[n]))) print(' ') self.fitting.write(self._getPath("fitting.pkpd")) self.experiment.write(self._getPath("experiment.pkpd")) def createOutputStep(self): self._defineOutputs(outputFitting=self.fitting) self._defineOutputs(outputExperiment=self.experiment) self._defineSourceRelation(self.getInputExperiment(), self.fitting) self._defineSourceRelation(self.getInputExperiment(), self.experiment) #--------------------------- INFO functions -------------------------------------------- def _summary(self): self.getXYvars() msg=['Predicting %s from %s'%(self.varNameX,self.varNameY)] return msg def _validate(self): self.getXYvars() errors=[] experiment = self.readExperiment(self.getInputExperiment().fnPKPD, False) if not self.varNameX in experiment.variables: errors.append("Cannot find %s as variable"%self.varNameX) if not self.varNameY in experiment.variables: errors.append("Cannot find %s as variable"%self.varNameY) return errors def _citations(self): return ['Spiess2010'] def filterVarForWizard(self, v): """ Define the type of variables required (used in wizard). """ return v.isNumeric() and (v.isMeasurement() or v.isTime())
class ProtPKPDMergePopulations(ProtPKPD): """ Merge two populations. Both populations must have the same labels\n Protocol created by http://www.kinestatpharma.com\n """ _label = 'merge populations' #--------------------------- DEFINE param functions -------------------------------------------- def _defineParams(self, form): form.addSection('Input') form.addParam( 'inputPopulation1', params.PointerParam, label="Population 1", important=True, pointerClass='PKPDFitting', pointerCondition="isPopulation", help='It must be a fitting coming from a bootstrap sample') form.addParam( 'inputPopulation2', params.PointerParam, label="Population 2", important=True, pointerClass='PKPDFitting', pointerCondition="isPopulation", help='It must be a fitting coming from a bootstrap sample') #--------------------------- INSERT steps functions -------------------------------------------- def _insertAllSteps(self): self._insertFunctionStep('runMerge', self.inputPopulation1.get().getObjId(), self.inputPopulation2.getObjId()) self._insertFunctionStep('createOutputStep') #--------------------------- STEPS functions -------------------------------------------- def runMerge(self, objId1, objId2): self.population1 = self.readFitting( self.inputPopulation1.get().fnFitting, cls="PKPDSampleFitBootstrap") self.population2 = self.readFitting( self.inputPopulation2.get().fnFitting, cls="PKPDSampleFitBootstrap") self.printSection("Merging populations") self.fitting = PKPDFitting("PKPDSampleFitBootstrap") self.fitting.fnExperiment.set(self.population1.fnExperiment) self.fitting.predictor = self.population1.predictor self.fitting.predicted = self.population1.predicted self.fitting.modelParameterUnits = self.population1.modelParameterUnits self.fitting.modelParameters = self.population1.modelParameters self.fitting.modelDescription = self.population1.modelDescription newSampleFit = PKPDSampleFitBootstrap() newSampleFit.sampleName = "Merged population" newSampleFit.parameters = None for sampleFit in self.population1.sampleFits: if newSampleFit.parameters == None: newSampleFit.parameters = np.copy(sampleFit.parameters) newSampleFit.xB = copy.copy(sampleFit.xB) newSampleFit.yB = copy.copy(sampleFit.yB) newSampleFit.R2 = copy.copy(sampleFit.R2) newSampleFit.R2adj = copy.copy(sampleFit.R2adj) newSampleFit.AIC = copy.copy(sampleFit.AIC) newSampleFit.AICc = copy.copy(sampleFit.AICc) newSampleFit.BIC = copy.copy(sampleFit.BIC) else: newSampleFit.parameters = np.vstack( [newSampleFit.parameters, sampleFit.parameters]) newSampleFit.xB += sampleFit.xB newSampleFit.yB += sampleFit.yB newSampleFit.R2 += sampleFit.R2 newSampleFit.R2adj += sampleFit.R2adj newSampleFit.AIC += sampleFit.AIC newSampleFit.AICc += sampleFit.AICc newSampleFit.BIC += sampleFit.BIC for sampleFit in self.population2.sampleFits: newSampleFit.parameters = np.vstack( [newSampleFit.parameters, sampleFit.parameters]) print(type(newSampleFit.xB)) print(type(sampleFit.xB)) newSampleFit.xB += sampleFit.xB newSampleFit.yB += sampleFit.yB newSampleFit.R2 += sampleFit.R2 newSampleFit.R2adj += sampleFit.R2adj newSampleFit.AIC += sampleFit.AIC newSampleFit.AICc += sampleFit.AICc newSampleFit.BIC += sampleFit.BIC self.fitting.sampleFits.append(newSampleFit) self.fitting.write(self._getPath("bootstrapPopulation.pkpd")) def createOutputStep(self): self._defineOutputs(outputPopulation=self.fitting) self._defineSourceRelation(self.inputPopulation1, self.fitting) self._defineSourceRelation(self.inputPopulation2, self.fitting) #--------------------------- INFO functions -------------------------------------------- def _summary(self): msg = [ "Populations %s and %s were merged" % (self.getObjectTag(self.inputPopulation1.get()), self.getObjectTag(self.inputPopulation2.get())) ] return msg def _validate(self): msg = [] if not self.inputPopulation1.get().fnFitting.get().endswith( "bootstrapPopulation.pkpd"): msg.append("Population 1 must be a bootstrap sample") if not self.inputPopulation2.get().fnFitting.get().endswith( "bootstrapPopulation.pkpd"): msg.append("Population 2 must be a bootstrap sample") return msg
class ProtPKPDODEBase(ProtPKPD, PKPDModelBase2): """ Base ODE protocol""" def __init__(self, **kwargs): ProtPKPD.__init__(self, **kwargs) self.boundsList = None #--------------------------- DEFINE param functions -------------------------------------------- def _defineParams1(self, form, addXY=False, defaultPredictor="", defaultPredicted=""): form.addSection('Input') form.addParam('inputExperiment', params.PointerParam, label="Input experiment", pointerClass='PKPDExperiment', help='Select an experiment with samples') if addXY: form.addParam( 'predictor', params.StringParam, label="Predictor variable (X)", default=defaultPredictor, help='Y is predicted as an exponential function of X, Y=f(X)') form.addParam( 'predicted', params.StringParam, label="Predicted variable (Y)", default=defaultPredicted, help='Y is predicted as an exponential function of X, Y=f(X)') fromTo = form.addLine( 'Simulation length', expertLevel=LEVEL_ADVANCED, help= 'Minimum and maximum time (in hours) and step size (in minutes). ' 'If minimum and maximum are not given (set to -1), they are estimated from the sample' ) fromTo.addParam('t0', params.StringParam, default="", label='Min (h)') fromTo.addParam('tF', params.StringParam, default="", label='Max (h)') fromTo.addParam('deltaT', params.FloatParam, default=0.5, label='Step (min)') form.addParam('fitType', params.EnumParam, choices=["Linear","Logarithmic","Relative"], label="Fit mode", default=1, expertLevel=LEVEL_ADVANCED, help='Linear: sum (Cobserved-Cpredicted)^2\nLogarithmic: sum(log10(Cobserved)-log10(Cpredicted))^2\n'\ "Relative: sum ((Cobserved-Cpredicted)/Cobserved)^2") form.addParam('confidenceInterval', params.FloatParam, label="Confidence interval", default=95, expertLevel=LEVEL_ADVANCED, help='Confidence interval for the fitted parameters') form.addParam( 'reportX', params.StringParam, label="Evaluate at X", default="", expertLevel=LEVEL_ADVANCED, help= 'Evaluate the model at these X values\nExample 1: [0,5,10,20,40,100]\nExample 2: 0:0.55:10, from 0 to 10 in steps of 0.5' ) form.addParam( 'globalSearch', params.BooleanParam, label="Global search", default=True, expertLevel=LEVEL_ADVANCED, help= 'Global search looks for the best parameters within bounds. If it is not performed, the ' 'middle of the bounding box is used as initial parameter for a local optimization' ) #--------------------------- INSERT steps functions -------------------------------------------- def getListOfFormDependencies(self): retval = [ self.fitType.get(), self.confidenceInterval.get(), self.reportX.get() ] if hasattr(self, "predictor"): retval.append(self.predictor.get()) retval.append(self.predicted.get()) if hasattr(self, "bounds"): retval.append(self.bounds.get()) return retval def _insertAllSteps(self): self._insertFunctionStep('runFit', self.getInputExperiment().getObjId(), self.getListOfFormDependencies()) self._insertFunctionStep('createOutputStep') #--------------------------- STEPS functions -------------------------------------------- def getInputExperiment(self): if hasattr(self, "inputExperiment"): return self.inputExperiment.get() else: return None def getXYvars(self): if hasattr(self, "predictor"): self.varNameX = self.predictor.get() else: self.varNameX = None if hasattr(self, "predicted"): self.varNameY = self.predicted.get() else: self.varNameY = None def configureSource(self, drugSource): pass def createModel(self): pass def setupModel(self): # Setup model self.model = self.createModel() self.model.setExperiment(self.experiment) self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) self.modelList.append(self.model) def getResponseDimension(self): return self.model.getResponseDimension() def getStateDimension(self): return self.model.getStateDimension() def setBounds(self, sample): if hasattr(self, "bounds"): self.model.setBounds(self.bounds.get()) def prepareForSampleAnalysis(self, sampleName): pass def postSampleAnalysis(self, sampleName): pass def setTimeRange(self, sample): if self.t0.get() == "" or self.tF.get() == "": tmin, tmax = sample.getRange(self.varNameX) else: tmin = self.t0.get() tmax = self.tF.get() if self.tmin == None: self.tmin = tmin else: self.tmin = min(tmin, self.tmin) if self.tmax == None: self.tmax = tmax else: self.tmax = max(tmax, self.tmax) if self.t0.get() == "": self.model.t0 = min(-10, self.tmin - 10) # 10 minutes before else: self.model.t0 = min(-10, float(self.t0.get()) * 60) if self.tF.get() == "": self.model.tF = self.tmax + 10 # 10 minutes later else: self.model.tF = float(self.tF.get()) * 60 if hasattr(self, "deltaT"): self.model.deltaT = self.deltaT.get() # As model -------------------------------------------- def clearGroupParameters(self): self.tmin = None self.tmax = None self.sampleList = [] self.modelList = [] self.drugSourceList = [] self.clearXYLists() def clearXYLists(self): self.XList = [] self.YList = [] def parseBounds(self, boundsString): self.boundsList = [] if boundsString != "" and boundsString != None: tokens = boundsString.split(';') if len(tokens) != self.getNumberOfParameters(): raise Exception( "The number of bound intervals does not match the number of parameters" ) for token in tokens: values = token.strip().split(',') self.boundsList.append( (float(values[0][1:]), float(values[1][:-1]))) def setBounds(self, sample): self.parseBounds(self.bounds.get()) self.setBoundsFromBoundsList() def setBoundsFromBoundsList(self): Nbounds = len(self.boundsList) Nsource = self.drugSource.getNumberOfParameters() Nmodel = self.model.getNumberOfParameters() if Nbounds != Nsource + Nmodel: raise Exception( "The number of parameters (%d) and bounds (%d) are different" % (Nsource + Nmodel, Nbounds)) self.boundsSource = self.boundsList[0:Nsource] self.boundsPK = self.boundsList[Nsource:] self.model.bounds = self.boundsPK def getBounds(self): return self.boundsList def getParameterBounds(self): """ Return a dictionary where the parameter name is the key and the bounds are its values. """ boundsDict = OrderedDict() self.parseBounds(self.bounds.get()) # after this we have boundsList parameterNames = self.getParameterNames() for paramName, bound in izip(parameterNames, self.getBounds()): boundsDict[paramName] = bound # Set None as bound for parameters not matched for paramName in parameterNames: if paramName not in boundsDict: boundsDict[paramName] = None return boundsDict def setParameters(self, parameters): self.parameters = parameters self.parametersPK = self.parameters[-self.NparametersModel:] for n in range(len(self.modelList)): if self.NparametersSource > 0: self.drugSourceList[n].setParameters( self.parameters[0:self.NparametersSource]) self.modelList[n].setParameters(self.parametersPK) def setXYValues(self, x, y): PKPDModelBase.setXYValues(self, x, y) self.model.setXYValues(x, y) self.XList.append(x) self.YList.append(y) def mergeLists(self, iny): if len(self.XList) > 1: outy = [] for m in range(len(iny[0])): outy.append(np.empty(shape=[0])) for m in range(len(outy)): for n in range(len(iny)): outy[m] = np.concatenate((outy[m], iny[n][m])) return outy else: return iny[0] def separateLists(self, iny): outy = [] Nsamples = len(self.YList) if Nsamples == 0: return Nmeasurements = self.model.getResponseDimension() idx = [0] * Nmeasurements for n in range(Nsamples): yn = self.YList[n] perSampleIn = [] for j in range(Nmeasurements): ynDim = yn[j].size ysample = iny[j][idx[j]:(idx[j] + ynDim)] perSampleIn.append(ysample) idx[j] += ynDim outy.append(perSampleIn) return outy def addSample(self, sample): self.sampleList.append(sample) self.model.setSample(sample) def forwardModel(self, parameters, x=None): self.setParameters(parameters) yPredictedList = [] for n in range(len(self.modelList)): self.modelList[n].forwardModel(self.parametersPK, x) yPredictedList.append(self.modelList[n].yPredicted) self.yPredicted = self.mergeLists(yPredictedList) return copy.copy(self.yPredicted) def imposeConstraints(self, yt): self.model.imposeConstraints(yt) def getEquation(self): return self.drugSource.getEquation( ) + " and " + self.model.getEquation() def getModelEquation(self): return self.drugSource.getModelEquation( ) + " and " + self.model.getModelEquation() def getDescription(self): return self.drugSource.getDescription( ) + "; " + self.model.getDescription() def getParameterNames(self): retval = [] parametersSource = self.drugSource.getParameterNames() self.NparametersSource = len(parametersSource) retval += parametersSource parametersModel = self.model.getParameterNames() self.NparametersModel = len(parametersModel) retval += parametersModel return retval def calculateParameterUnits(self, sample): retval = [] retval += self.drugSource.calculateParameterUnits(sample) retval += self.model.calculateParameterUnits(sample) self.parameterUnits = retval def areParametersSignificant(self, lowerBound, upperBound): retval = [] idx = 0 if len(self.boundsSource) > 0: retval += self.drugSource.areParametersSignificant( lowerBound[idx:len(self.boundsSource)], upperBound[idx:len(self.boundsSource)]) retval += self.model.areParametersSignificant( lowerBound[len(self.boundsSource):], upperBound[len(self.boundsSource):]) return retval def areParametersValid(self, p): return self.drugSource.areParametersValid(p[0:len(self.boundsSource)]) and \ self.model.areParametersValid(p[len(self.boundsSource):]) def createDrugSource(self): self.drugSource = DrugSource() self.drugSourceList.append(self.drugSource) return self.drugSource # Really fit --------------------------------------------------------- def runFit(self, objId, otherDependencies): reportX = parseRange(self.reportX.get()) self.setInputExperiment() # Setup model self.getXYvars() # Create output object self.fitting = PKPDFitting() self.fitting.fnExperiment.set(self._getPath("experiment.pkpd")) self.fitting.predictor = self.experiment.variables[self.varNameX] if type(self.varNameY) == list: self.fitting.predicted = [] for y in self.varNameY: self.fitting.predicted.append(self.experiment.variables[y]) else: self.fitting.predicted = self.experiment.variables[self.varNameY] self.fitting.modelParameterUnits = None # Actual fitting if self.fitType.get() == 0: fitType = "linear" elif self.fitType.get() == 1: fitType = "log" elif self.fitType.get() == 2: fitType = "relative" for groupName, group in self.experiment.groups.iteritems(): self.printSection("Fitting " + groupName) self.clearGroupParameters() for sampleName in group.sampleList: print(" Sample " + sampleName) sample = self.experiment.samples[sampleName] self.createDrugSource() self.setupModel() # Get the values to fit x, y = sample.getXYValues(self.varNameX, self.varNameY) print("X= " + str(x)) print("Y= " + str(y)) print(" ") # Interpret the dose self.setTimeRange(sample) sample.interpretDose() self.drugSource.setDoses(sample.parsedDoseList, self.model.t0, self.model.tF) self.configureSource(self.drugSource) self.model.drugSource = self.drugSource # Prepare the model self.setBounds(sample) self.setXYValues(x, y) self.addSample(sample) self.prepareForSampleAnalysis(sampleName) self.calculateParameterUnits(sample) if self.fitting.modelParameterUnits == None: self.fitting.modelParameterUnits = self.parameterUnits self.printSetup() self.x = self.mergeLists(self.XList) self.y = self.mergeLists(self.YList) if self.globalSearch: optimizer1 = PKPDDEOptimizer(self, fitType) optimizer1.optimize() else: self.parameters = np.zeros(len(self.boundsList), np.double) n = 0 for bound in self.boundsList: self.parameters[n] = 0.5 * (bound[0] + bound[1]) n += 1 try: optimizer2 = PKPDLSOptimizer(self, fitType) optimizer2.optimize() except Exception as e: msg = str(e) msg += "Errors in the local optimizer may be caused by starting from a bad initial guess\n" msg += "Try performing a global search first or changing the bounding box" raise Exception("Error in the local optimizer\n" + msg) optimizer2.setConfidenceInterval(self.confidenceInterval.get()) self.setParameters(optimizer2.optimum) optimizer2.evaluateQuality() self.yPredictedList = self.separateLists(self.yPredicted) self.yPredictedLowerList = self.separateLists(self.yPredictedLower) self.yPredictedUpperList = self.separateLists(self.yPredictedUpper) n = 0 for sampleName in group.sampleList: sample = self.experiment.samples[sampleName] # Keep this result sampleFit = PKPDSampleFit() sampleFit.sampleName = sample.sampleName sampleFit.x = self.XList[n] sampleFit.y = self.YList[n] sampleFit.yp = self.yPredictedList[n] sampleFit.yl = self.yPredictedLowerList[n] sampleFit.yu = self.yPredictedUpperList[n] sampleFit.parameters = self.parameters sampleFit.modelEquation = self.getEquation() sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) # Add the parameters to the sample and experiment for varName, varUnits, description, varValue in izip( self.getParameterNames(), self.parameterUnits, self.getParameterDescriptions(), self.parameters): self.experiment.addParameterToSample( sampleName, varName, varUnits, description, varValue) self.postSampleAnalysis(sampleName) if reportX != None: print("Evaluation of the model at specified time points") self.model.tF = np.max(reportX) yreportX = self.model.forwardModel(self.model.parameters, reportX) print("==========================================") print("X Ypredicted log10(Ypredicted)") print("==========================================") for n in range(0, reportX.shape[0]): aux = 0 if yreportX[n] > 0: aux = math.log10(yreportX[n]) print("%f %f %f" % (reportX[n], yreportX[n], aux)) print(' ') n += 1 self.fitting.modelParameters = self.getParameterNames() self.fitting.modelDescription = self.getDescription() self.fitting.write(self._getPath("fitting.pkpd")) self.experiment.write(self._getPath("experiment.pkpd")) def createOutputStep(self): self._defineOutputs(outputFitting=self.fitting) self._defineOutputs(outputExperiment=self.experiment) self._defineSourceRelation(self.getInputExperiment(), self.fitting) self._defineSourceRelation(self.getInputExperiment(), self.experiment) #--------------------------- INFO functions -------------------------------------------- def _summary(self): msg = [] self.getXYvars() if self.varNameX != None: msg.append('Predicting %s from %s' % (self.varNameX, self.varNameY)) return msg def _validate(self): self.getXYvars() errors = [] if self.varNameX != None: experiment = self.readExperiment(self.getInputExperiment().fnPKPD, False) if not self.varNameX in experiment.variables: errors.append("Cannot find %s as variable" % self.varNameX) if type(self.varNameY) == list: for y in self.varNameY: if not y in experiment.variables: errors.append("Cannot find %s as variable" % y) else: if not self.varNameY in experiment.variables: errors.append("Cannot find %s as variable" % self.varNameY) if self.bounds.get() == "": errors.append("Bounds are required") return errors def _citations(self): return ['Spiess2010'] def filterVarForWizard(self, v): """ Define the type of variables required (used in wizard). """ return v.isNumeric() and (v.isTime() or v.isMeasurement())
def runFit(self, objId, otherDependencies): self.getXYvars() if hasattr(self,"reportX"): reportX = parseRange(self.reportX.get()) else: reportX = None self.experiment = self.readExperiment(self.getInputExperiment().fnPKPD) # Setup model self.printSection("Model setup") self.model = self.createModel() self.model.setExperiment(self.experiment) self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) self.setupFromFormParameters() self.model.printSetup() # Create output object self.fitting = PKPDFitting() self.fitting.fnExperiment.set(self.getInputExperiment().fnPKPD.get()) self.fitting.predictor=self.experiment.variables[self.varNameX] self.fitting.predicted=self.experiment.variables[self.varNameY] self.fitting.modelDescription=self.model.getDescription() self.fitting.modelParameters = self.model.getParameterNames() self.fitting.modelParameterUnits = None # Actual fitting if self.fitType.get()==0: fitType = "linear" elif self.fitType.get()==1: fitType = "log" elif self.fitType.get()==2: fitType = "relative" for sampleName, sample in self.experiment.samples.iteritems(): self.printSection("Fitting "+sampleName) x, y = sample.getXYValues(self.varNameX,self.varNameY) print("X= "+str(x)) print("Y= "+str(y)) print(" ") self.model.setBounds(self.bounds.get()) self.model.setXYValues(x, y) self.prepareForSampleAnalysis(sampleName) self.model.calculateParameterUnits(sample) if self.fitting.modelParameterUnits==None: self.fitting.modelParameterUnits = self.model.parameterUnits self.model.prepare() if self.model.bounds == None: continue print(" ") optimizer1 = PKPDDEOptimizer(self.model,fitType) optimizer1.optimize() optimizer2 = PKPDLSOptimizer(self.model,fitType) optimizer2.optimize() optimizer2.setConfidenceInterval(self.confidenceInterval.get()) self.setParameters(optimizer2.optimum) optimizer2.evaluateQuality() # Keep this result sampleFit = PKPDSampleFit() sampleFit.sampleName = sample.sampleName sampleFit.x = self.model.x sampleFit.y = self.model.y sampleFit.yp = self.model.yPredicted sampleFit.yl = self.model.yPredictedLower sampleFit.yu = self.model.yPredictedUpper sampleFit.parameters = self.model.parameters sampleFit.modelEquation = self.model.getEquation() sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) # Add the parameters to the sample and experiment for varName, varUnits, description, varValue in izip(self.model.getParameterNames(), self.model.parameterUnits, self.model.getParameterDescriptions(), self.model.parameters): self.experiment.addParameterToSample(sampleName, varName, varUnits, description, varValue) self.postSampleAnalysis(sampleName) if reportX!=None: print("Evaluation of the model at specified time points") yreportX = self.model.forwardModel(self.model.parameters, reportX) print("==========================================") print("X Ypredicted log10(Ypredicted)") print("==========================================") for n in range(0,reportX.shape[0]): print("%f %f %f"%(reportX[n],yreportX[n],math.log10(yreportX[n]))) print(' ') self.fitting.write(self._getPath("fitting.pkpd")) self.experiment.write(self._getPath("experiment.pkpd"))
def runFit(self, objId, otherDependencies): reportX = parseRange(self.reportX.get()) self.setInputExperiment() # Setup model self.getXYvars() # Create output object self.fitting = PKPDFitting() self.fitting.fnExperiment.set(self._getPath("experiment.pkpd")) self.fitting.predictor=self.experiment.variables[self.varNameX] if type(self.varNameY)==list: self.fitting.predicted=[] for y in self.varNameY: self.fitting.predicted.append(self.experiment.variables[y]) else: self.fitting.predicted=self.experiment.variables[self.varNameY] self.fitting.modelParameterUnits = None # Actual fitting if self.fitType.get()==0: fitType = "linear" elif self.fitType.get()==1: fitType = "log" elif self.fitType.get()==2: fitType = "relative" for groupName, group in self.experiment.groups.iteritems(): self.printSection("Fitting "+groupName) self.clearGroupParameters() for sampleName in group.sampleList: print(" Sample "+sampleName) sample = self.experiment.samples[sampleName] self.createDrugSource() self.setupModel() # Get the values to fit x, y = sample.getXYValues(self.varNameX,self.varNameY) print("X= "+str(x)) print("Y= "+str(y)) print(" ") # Interpret the dose self.setTimeRange(sample) sample.interpretDose() self.drugSource.setDoses(sample.parsedDoseList, self.model.t0, self.model.tF) self.configureSource(self.drugSource) self.model.drugSource = self.drugSource # Prepare the model self.setBounds(sample) self.setXYValues(x, y) self.addSample(sample) self.prepareForSampleAnalysis(sampleName) self.calculateParameterUnits(sample) if self.fitting.modelParameterUnits==None: self.fitting.modelParameterUnits = self.parameterUnits self.printSetup() self.x = self.mergeLists(self.XList) self.y = self.mergeLists(self.YList) if self.globalSearch: optimizer1 = PKPDDEOptimizer(self,fitType) optimizer1.optimize() else: self.parameters = np.zeros(len(self.boundsList),np.double) n = 0 for bound in self.boundsList: self.parameters[n] = 0.5*(bound[0]+bound[1]) n += 1 try: optimizer2 = PKPDLSOptimizer(self,fitType) optimizer2.optimize() except Exception as e: msg=str(e) msg+="Errors in the local optimizer may be caused by starting from a bad initial guess\n" msg+="Try performing a global search first or changing the bounding box" raise Exception("Error in the local optimizer\n"+msg) optimizer2.setConfidenceInterval(self.confidenceInterval.get()) self.setParameters(optimizer2.optimum) optimizer2.evaluateQuality() self.yPredictedList=self.separateLists(self.yPredicted) self.yPredictedLowerList=self.separateLists(self.yPredictedLower) self.yPredictedUpperList=self.separateLists(self.yPredictedUpper) n=0 for sampleName in group.sampleList: sample = self.experiment.samples[sampleName] # Keep this result sampleFit = PKPDSampleFit() sampleFit.sampleName = sample.sampleName sampleFit.x = self.XList[n] sampleFit.y = self.YList[n] sampleFit.yp = self.yPredictedList[n] sampleFit.yl = self.yPredictedLowerList[n] sampleFit.yu = self.yPredictedUpperList[n] sampleFit.parameters = self.parameters sampleFit.modelEquation = self.getEquation() sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) # Add the parameters to the sample and experiment for varName, varUnits, description, varValue in izip(self.getParameterNames(), self.parameterUnits, self.getParameterDescriptions(), self.parameters): self.experiment.addParameterToSample(sampleName, varName, varUnits, description, varValue) self.postSampleAnalysis(sampleName) if reportX!=None: print("Evaluation of the model at specified time points") self.model.tF = np.max(reportX) yreportX = self.model.forwardModel(self.model.parameters, reportX) print("==========================================") print("X Ypredicted log10(Ypredicted)") print("==========================================") for n in range(0,reportX.shape[0]): aux = 0 if yreportX[n]>0: aux = math.log10(yreportX[n]) print("%f %f %f"%(reportX[n],yreportX[n],aux)) print(' ') n+=1 self.fitting.modelParameters = self.getParameterNames() self.fitting.modelDescription=self.getDescription() self.fitting.write(self._getPath("fitting.pkpd")) self.experiment.write(self._getPath("experiment.pkpd"))
def runFit(self, objId, otherDependencies): reportX = parseRange(self.reportX.get()) self.setInputExperiment() # Setup model self.getXYvars() # Create output object self.fitting = PKPDFitting() self.fitting.fnExperiment.set(self._getPath("experiment.pkpd")) self.fitting.predictor = self.experiment.variables[self.varNameX] if type(self.varNameY) == list: self.fitting.predicted = [] for y in self.varNameY: self.fitting.predicted.append(self.experiment.variables[y]) else: self.fitting.predicted = self.experiment.variables[self.varNameY] self.fitting.modelParameterUnits = None # Actual fitting if self.fitType.get() == 0: fitType = "linear" elif self.fitType.get() == 1: fitType = "log" elif self.fitType.get() == 2: fitType = "relative" for groupName, group in self.experiment.groups.iteritems(): self.printSection("Fitting " + groupName) self.clearGroupParameters() for sampleName in group.sampleList: print(" Sample " + sampleName) sample = self.experiment.samples[sampleName] self.createDrugSource() self.setupModel() # Get the values to fit x, y = sample.getXYValues(self.varNameX, self.varNameY) print("X= " + str(x)) print("Y= " + str(y)) print(" ") # Interpret the dose self.setTimeRange(sample) sample.interpretDose() self.drugSource.setDoses(sample.parsedDoseList, self.model.t0, self.model.tF) self.configureSource(self.drugSource) self.model.drugSource = self.drugSource # Prepare the model self.setBounds(sample) self.setXYValues(x, y) self.addSample(sample) self.prepareForSampleAnalysis(sampleName) self.calculateParameterUnits(sample) if self.fitting.modelParameterUnits == None: self.fitting.modelParameterUnits = self.parameterUnits self.printSetup() self.x = self.mergeLists(self.XList) self.y = self.mergeLists(self.YList) if self.globalSearch: optimizer1 = PKPDDEOptimizer(self, fitType) optimizer1.optimize() else: self.parameters = np.zeros(len(self.boundsList), np.double) n = 0 for bound in self.boundsList: self.parameters[n] = 0.5 * (bound[0] + bound[1]) n += 1 try: optimizer2 = PKPDLSOptimizer(self, fitType) optimizer2.optimize() except Exception as e: msg = str(e) msg += "Errors in the local optimizer may be caused by starting from a bad initial guess\n" msg += "Try performing a global search first or changing the bounding box" raise Exception("Error in the local optimizer\n" + msg) optimizer2.setConfidenceInterval(self.confidenceInterval.get()) self.setParameters(optimizer2.optimum) optimizer2.evaluateQuality() self.yPredictedList = self.separateLists(self.yPredicted) self.yPredictedLowerList = self.separateLists(self.yPredictedLower) self.yPredictedUpperList = self.separateLists(self.yPredictedUpper) n = 0 for sampleName in group.sampleList: sample = self.experiment.samples[sampleName] # Keep this result sampleFit = PKPDSampleFit() sampleFit.sampleName = sample.sampleName sampleFit.x = self.XList[n] sampleFit.y = self.YList[n] sampleFit.yp = self.yPredictedList[n] sampleFit.yl = self.yPredictedLowerList[n] sampleFit.yu = self.yPredictedUpperList[n] sampleFit.parameters = self.parameters sampleFit.modelEquation = self.getEquation() sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) # Add the parameters to the sample and experiment for varName, varUnits, description, varValue in izip( self.getParameterNames(), self.parameterUnits, self.getParameterDescriptions(), self.parameters): self.experiment.addParameterToSample( sampleName, varName, varUnits, description, varValue) self.postSampleAnalysis(sampleName) if reportX != None: print("Evaluation of the model at specified time points") self.model.tF = np.max(reportX) yreportX = self.model.forwardModel(self.model.parameters, reportX) print("==========================================") print("X Ypredicted log10(Ypredicted)") print("==========================================") for n in range(0, reportX.shape[0]): aux = 0 if yreportX[n] > 0: aux = math.log10(yreportX[n]) print("%f %f %f" % (reportX[n], yreportX[n], aux)) print(' ') n += 1 self.fitting.modelParameters = self.getParameterNames() self.fitting.modelDescription = self.getDescription() self.fitting.write(self._getPath("fitting.pkpd")) self.experiment.write(self._getPath("experiment.pkpd"))
def runFit(self, objId, Nbootstrap, confidenceInterval): self.protODE = self.inputODE.get() self.experiment = self.readExperiment( self.protODE.outputExperiment.fnPKPD) self.fitting = self.readFitting(self.protODE.outputFitting.fnFitting) # Get the X and Y variable names self.varNameX = self.fitting.predictor.varName if type(self.fitting.predicted) == list: self.varNameY = [v.varName for v in self.fitting.predicted] else: self.varNameY = self.fitting.predicted.varName self.protODE.experiment = self.experiment self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY # Create output object self.fitting = PKPDFitting("PKPDSampleFitBootstrap") self.fitting.fnExperiment.set(self.experiment.fnPKPD.get()) self.fitting.predictor = self.experiment.variables[self.varNameX] if type(self.varNameY) == list: self.fitting.predicted = [ self.experiment.variables[v] for v in self.varNameY ] else: self.fitting.predicted = self.experiment.variables[self.varNameY] self.fitting.modelParameterUnits = None # Actual fitting if self.protODE.fitType.get() == 0: fitType = "linear" elif self.protODE.fitType.get() == 1: fitType = "log" elif self.protODE.fitType.get() == 2: fitType = "relative" parameterNames = None for groupName, group in self.experiment.groups.iteritems(): self.printSection("Fitting " + groupName) self.protODE.clearGroupParameters() self.clearGroupParameters() for sampleName in group.sampleList: print(" Sample " + sampleName) sample = self.experiment.samples[sampleName] self.protODE.createDrugSource() self.protODE.setupModel() # Setup self model self.drugSource = self.protODE.drugSource self.drugSourceList = self.protODE.drugSourceList self.model = self.protODE.model self.modelList = self.protODE.modelList self.model.deltaT = self.deltaT.get() self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) # Get the values to fit x, y = sample.getXYValues(self.varNameX, self.varNameY) print("X= " + str(x)) print("Y= " + str(y)) firstX = x[0] # From [array(...)] to array(...) firstY = y[0] # From [array(...)] to array(...) # Interpret the dose self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY self.protODE.model = self.model self.protODE.setTimeRange(sample) sample.interpretDose() self.drugSource.setDoses(sample.parsedDoseList, self.model.t0, self.model.tF) self.protODE.configureSource(self.drugSource) self.model.drugSource = self.drugSource # Prepare the model self.model.setSample(sample) self.calculateParameterUnits(sample) if self.fitting.modelParameterUnits == None: self.fitting.modelParameterUnits = self.parameterUnits # Get the initial parameters if parameterNames == None: parameterNames = self.getParameterNames() parameters0 = [] for parameterName in parameterNames: parameters0.append(float( sample.descriptors[parameterName])) print("Initial solution: %s" % str(parameters0)) print(" ") # Set bounds self.setBounds(sample) # Output object sampleFit = PKPDSampleFitBootstrap() sampleFit.sampleName = sample.sampleName sampleFit.parameters = np.zeros( (self.Nbootstrap.get(), len(parameters0)), np.double) sampleFit.xB = [] sampleFit.yB = [] # Bootstrap samples idx = [k for k in range(0, len(firstX))] for n in range(0, self.Nbootstrap.get()): ok = False while not ok: if self.sampleLength.get() > 0: lenToUse = self.sampleLength.get() else: lenToUse = len(idx) idxB = sorted(np.random.choice(idx, lenToUse)) xB = [np.asarray([firstX[i] for i in idxB])] yB = [np.asarray([firstY[i] for i in idxB])] print("Bootstrap sample %d" % n) print("X= " + str(xB)) print("Y= " + str(yB)) self.clearXYLists() self.setXYValues(xB, yB) self.parameters = parameters0 optimizer2 = PKPDLSOptimizer(self, fitType) optimizer2.verbose = 0 try: optimizer2.optimize() ok = True except Exception as e: print(e) raise (e) ok = False # Evaluate the quality on the whole data set self.clearXYLists() self.setXYValues(x, y) optimizer2.evaluateQuality() print(optimizer2.optimum) print(" R2 = %f R2Adj=%f AIC=%f AICc=%f BIC=%f"%(optimizer2.R2,optimizer2.R2adj,optimizer2.AIC,\ optimizer2.AICc,optimizer2.BIC)) # Keep this result sampleFit.parameters[n, :] = optimizer2.optimum sampleFit.xB.append(str(xB[0])) sampleFit.yB.append(str(yB[0])) sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) self.fitting.modelParameters = self.getParameterNames() self.fitting.modelDescription = self.getDescription() self.fitting.write(self._getPath("bootstrapPopulation.pkpd"))
class ProtPKPDODEBootstrap(ProtPKPDODEBase): """ Bootstrap of an ODE protocol""" _label = 'ODE bootstrap' #--------------------------- DEFINE param functions -------------------------------------------- def _defineParams(self, form): form.addSection('Input') form.addParam('inputODE', params.PointerParam, label="Input ODE model", pointerClass='ProtPKPDMonoCompartment, ProtPKPDMonoCompartmentUrine, ProtPKPDTwoCompartments, '\ 'ProtPKPDTwoCompartmentsAutoinduction, ProtPKPDTwoCompartmentsClint, '\ 'ProtPKPDTwoCompartmentsClintMetabolite, ProtPKPDTwoCompartmentsUrine', help='Select a run of an ODE model') form.addParam('Nbootstrap', params.IntParam, label="Bootstrap samples", default=200, expertLevel=LEVEL_ADVANCED, help='Number of bootstrap realizations for each sample') form.addParam('sampleLength', params.IntParam, label="Sample length", default=-1, expertLevel=LEVEL_ADVANCED, help='If the input experiment represents a population, the bootstrap sample is so overdetermined '\ 'that the bootstrap parameter estimate seldom moves from the original values. In this case, '\ 'you may use the sample length to generate bootstrap samples of the same length as the indiviudals '\ 'taking part of the population. If this value is set to -1, then the length of the bootstrap sample '\ 'will be the same as the one in the input experiment. If set to any other value, e.g. 8, then '\ 'each bootstrap sample will have this length') form.addParam('confidenceInterval', params.FloatParam, label="Confidence interval", default=95, expertLevel=LEVEL_ADVANCED, help='Confidence interval for the fitted parameters') form.addParam('deltaT', params.FloatParam, default=2, label='Step (min)', expertLevel=LEVEL_ADVANCED) #--------------------------- INSERT steps functions -------------------------------------------- def _insertAllSteps(self): self._insertFunctionStep('runFit', self.inputODE.get().getObjId(), self.Nbootstrap.get(), self.confidenceInterval.get()) self._insertFunctionStep('createOutputStep') #--------------------------- STEPS functions -------------------------------------------- def parseBounds(self, boundsString): if boundsString != "" and boundsString != None: tokens = boundsString.split(';') if len(tokens) != self.getNumberOfParameters(): raise Exception( "The number of bound intervals does not match the number of parameters" ) self.boundsList = [] for token in tokens: values = token.strip().split(',') self.boundsList.append( (float(values[0][1:]), float(values[1][:-1]))) def setBounds(self, sample): self.parseBounds(self.protODE.bounds.get()) self.setBoundsFromBoundsList() def setBoundsFromBoundsList(self): Nbounds = len(self.boundsList) Nsource = self.drugSource.getNumberOfParameters() Nmodel = self.model.getNumberOfParameters() if Nbounds != Nsource + Nmodel: raise "The number of parameters (%d) and bounds (%d) are different" % ( Nsource + Nmodel, Nbounds) self.boundsSource = self.boundsList[0:Nsource] self.boundsPK = self.boundsList[Nsource:] self.model.bounds = self.boundsPK def getBounds(self): return self.boundsList def runFit(self, objId, Nbootstrap, confidenceInterval): self.protODE = self.inputODE.get() self.experiment = self.readExperiment( self.protODE.outputExperiment.fnPKPD) self.fitting = self.readFitting(self.protODE.outputFitting.fnFitting) # Get the X and Y variable names self.varNameX = self.fitting.predictor.varName if type(self.fitting.predicted) == list: self.varNameY = [v.varName for v in self.fitting.predicted] else: self.varNameY = self.fitting.predicted.varName self.protODE.experiment = self.experiment self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY # Create output object self.fitting = PKPDFitting("PKPDSampleFitBootstrap") self.fitting.fnExperiment.set(self.experiment.fnPKPD.get()) self.fitting.predictor = self.experiment.variables[self.varNameX] if type(self.varNameY) == list: self.fitting.predicted = [ self.experiment.variables[v] for v in self.varNameY ] else: self.fitting.predicted = self.experiment.variables[self.varNameY] self.fitting.modelParameterUnits = None # Actual fitting if self.protODE.fitType.get() == 0: fitType = "linear" elif self.protODE.fitType.get() == 1: fitType = "log" elif self.protODE.fitType.get() == 2: fitType = "relative" parameterNames = None for groupName, group in self.experiment.groups.iteritems(): self.printSection("Fitting " + groupName) self.protODE.clearGroupParameters() self.clearGroupParameters() for sampleName in group.sampleList: print(" Sample " + sampleName) sample = self.experiment.samples[sampleName] self.protODE.createDrugSource() self.protODE.setupModel() # Setup self model self.drugSource = self.protODE.drugSource self.drugSourceList = self.protODE.drugSourceList self.model = self.protODE.model self.modelList = self.protODE.modelList self.model.deltaT = self.deltaT.get() self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) # Get the values to fit x, y = sample.getXYValues(self.varNameX, self.varNameY) print("X= " + str(x)) print("Y= " + str(y)) firstX = x[0] # From [array(...)] to array(...) firstY = y[0] # From [array(...)] to array(...) # Interpret the dose self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY self.protODE.model = self.model self.protODE.setTimeRange(sample) sample.interpretDose() self.drugSource.setDoses(sample.parsedDoseList, self.model.t0, self.model.tF) self.protODE.configureSource(self.drugSource) self.model.drugSource = self.drugSource # Prepare the model self.model.setSample(sample) self.calculateParameterUnits(sample) if self.fitting.modelParameterUnits == None: self.fitting.modelParameterUnits = self.parameterUnits # Get the initial parameters if parameterNames == None: parameterNames = self.getParameterNames() parameters0 = [] for parameterName in parameterNames: parameters0.append(float( sample.descriptors[parameterName])) print("Initial solution: %s" % str(parameters0)) print(" ") # Set bounds self.setBounds(sample) # Output object sampleFit = PKPDSampleFitBootstrap() sampleFit.sampleName = sample.sampleName sampleFit.parameters = np.zeros( (self.Nbootstrap.get(), len(parameters0)), np.double) sampleFit.xB = [] sampleFit.yB = [] # Bootstrap samples idx = [k for k in range(0, len(firstX))] for n in range(0, self.Nbootstrap.get()): ok = False while not ok: if self.sampleLength.get() > 0: lenToUse = self.sampleLength.get() else: lenToUse = len(idx) idxB = sorted(np.random.choice(idx, lenToUse)) xB = [np.asarray([firstX[i] for i in idxB])] yB = [np.asarray([firstY[i] for i in idxB])] print("Bootstrap sample %d" % n) print("X= " + str(xB)) print("Y= " + str(yB)) self.clearXYLists() self.setXYValues(xB, yB) self.parameters = parameters0 optimizer2 = PKPDLSOptimizer(self, fitType) optimizer2.verbose = 0 try: optimizer2.optimize() ok = True except Exception as e: print(e) raise (e) ok = False # Evaluate the quality on the whole data set self.clearXYLists() self.setXYValues(x, y) optimizer2.evaluateQuality() print(optimizer2.optimum) print(" R2 = %f R2Adj=%f AIC=%f AICc=%f BIC=%f"%(optimizer2.R2,optimizer2.R2adj,optimizer2.AIC,\ optimizer2.AICc,optimizer2.BIC)) # Keep this result sampleFit.parameters[n, :] = optimizer2.optimum sampleFit.xB.append(str(xB[0])) sampleFit.yB.append(str(yB[0])) sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) self.fitting.modelParameters = self.getParameterNames() self.fitting.modelDescription = self.getDescription() self.fitting.write(self._getPath("bootstrapPopulation.pkpd")) def createOutputStep(self): self._defineOutputs(outputPopulation=self.fitting) self._defineSourceRelation(self.inputODE.get(), self.fitting) #--------------------------- INFO functions -------------------------------------------- def _summary(self): msg = [] msg.append("Number of bootstrap realizations: %d" % self.Nbootstrap.get()) msg.append("Confidence interval: %f" % self.confidenceInterval.get()) return msg def _validate(self): return []
class ProtPKPDODERefine(ProtPKPDODEBase): """ Refinement of an ODE protocol. The parameters are reestimated with a finer sampling rate. """ _label = 'ODE refinement' #--------------------------- DEFINE param functions -------------------------------------------- def _defineParams(self, form): form.addSection('Input') form.addParam( 'inputODE', params.PointerParam, label="Input ODE model", pointerClass= 'ProtPKPDMonoCompartment, ProtPKPDMonoCompartmentUrine, ProtPKPDTwoCompartments', help='Select a run of an ODE model') form.addParam('deltaT', params.FloatParam, default=0.5, label='Step (min)', expertLevel=LEVEL_ADVANCED) #--------------------------- INSERT steps functions -------------------------------------------- def _insertAllSteps(self): self._insertFunctionStep('runFit', self.inputODE.get().getObjId(), self.deltaT.get()) self._insertFunctionStep('createOutputStep') #--------------------------- STEPS functions -------------------------------------------- def parseBounds(self, boundsString): if boundsString != "" and boundsString != None: tokens = boundsString.split(';') if len(tokens) != self.getNumberOfParameters(): raise Exception( "The number of bound intervals does not match the number of parameters" ) self.boundsList = [] for token in tokens: values = token.strip().split(',') self.boundsList.append( (float(values[0][1:]), float(values[1][:-1]))) def setBounds(self, sample): self.parseBounds(self.protODE.bounds.get()) self.setBoundsFromBoundsList() def setBoundsFromBoundsList(self): Nbounds = len(self.boundsList) Nsource = self.drugSource.getNumberOfParameters() Nmodel = self.model.getNumberOfParameters() if Nbounds != Nsource + Nmodel: raise "The number of parameters (%d) and bounds (%d) are different" % ( Nsource + Nmodel, Nbounds) self.boundsSource = self.boundsList[0:Nsource] self.boundsPK = self.boundsList[Nsource:] self.model.bounds = self.boundsPK def getBounds(self): return self.boundsList def runFit(self, objId, deltaT): self.protODE = self.inputODE.get() self.experiment = self.readExperiment( self.protODE.outputExperiment.fnPKPD) self.fitting = self.readFitting(self.protODE.outputFitting.fnFitting) # Get the X and Y variable names self.varNameX = self.fitting.predictor.varName if type(self.fitting.predicted) == list: self.varNameY = [v.varName for v in self.fitting.predicted] else: self.varNameY = self.fitting.predicted.varName self.protODE.experiment = self.experiment self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY # Create output object self.fitting = PKPDFitting() self.fitting.fnExperiment.set(self.experiment.fnPKPD.get()) self.fitting.predictor = self.experiment.variables[self.varNameX] self.fitting.predicted = self.experiment.variables[self.varNameY] self.fitting.modelParameterUnits = None # Actual fitting if self.protODE.fitType.get() == 0: fitType = "linear" elif self.protODE.fitType.get() == 1: fitType = "log" elif self.protODE.fitType.get() == 2: fitType = "relative" parameterNames = None for groupName, group in self.experiment.groups.iteritems(): self.printSection("Fitting " + groupName) self.protODE.clearGroupParameters() self.clearGroupParameters() for sampleName in group.sampleList: print(" Sample " + sampleName) sample = self.experiment.samples[sampleName] self.protODE.createDrugSource() self.protODE.setupModel() # Setup self model self.drugSource = self.protODE.drugSource self.drugSourceList = self.protODE.drugSourceList self.model = self.protODE.model self.modelList = self.protODE.modelList self.model.deltaT = self.deltaT.get() self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) # Get the values to fit x, y = sample.getXYValues(self.varNameX, self.varNameY) print("X= " + str(x)) print("Y= " + str(y)) # Interpret the dose self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY self.protODE.model = self.model self.protODE.setTimeRange(sample) sample.interpretDose() self.drugSource.setDoses(sample.parsedDoseList, self.model.t0, self.model.tF) self.protODE.configureSource(self.drugSource) self.model.drugSource = self.drugSource # Prepare the model self.model.setSample(sample) self.calculateParameterUnits(sample) if self.fitting.modelParameterUnits == None: self.fitting.modelParameterUnits = self.parameterUnits # Get the initial parameters if parameterNames == None: parameterNames = self.getParameterNames() parameters0 = [] for parameterName in parameterNames: parameters0.append(float( sample.descriptors[parameterName])) print("Initial solution: %s" % str(parameters0)) print(" ") # Set bounds self.setBounds(sample) self.setXYValues(x, y) self.parameters = parameters0 self.printSetup() self.x = self.mergeLists(self.XList) self.y = self.mergeLists(self.YList) optimizer2 = PKPDLSOptimizer(self, fitType) optimizer2.optimize() optimizer2.setConfidenceInterval( self.protODE.confidenceInterval.get()) self.setParameters(optimizer2.optimum) n = 0 for sampleName in group.sampleList: sample = self.experiment.samples[sampleName] # Keep this result sampleFit = PKPDSampleFit() sampleFit.sampleName = sample.sampleName sampleFit.x = x sampleFit.y = y sampleFit.yp = self.yPredicted sampleFit.yl = self.yPredictedLower sampleFit.yu = self.yPredictedUpper sampleFit.parameters = self.parameters sampleFit.modelEquation = self.getEquation() sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) # Add the parameters to the sample and experiment for varName, varUnits, description, varValue in izip( self.getParameterNames(), self.parameterUnits, self.getParameterDescriptions(), self.parameters): self.experiment.addParameterToSample( sampleName, varName, varUnits, description, varValue) n += 1 self.fitting.modelParameters = self.getParameterNames() self.fitting.modelDescription = self.getDescription() self.fitting.write(self._getPath("fitting.pkpd")) self.experiment.write(self._getPath("experiment.pkpd")) def createOutputStep(self): self._defineOutputs(outputFitting=self.fitting) self._defineOutputs(outputExperiment=self.experiment) self._defineSourceRelation(self.inputODE.get(), self.fitting) self._defineSourceRelation(self.inputODE.get(), self.experiment) #--------------------------- INFO functions -------------------------------------------- def _summary(self): msg = [] msg.append("New sampling rate: %f" % self.deltaT.get()) return msg def _validate(self): return []
class ProtPKPDFilterPopulation(ProtPKPD): """ Filter a population by some criterion\n Protocol created by http://www.kinestatpharma.com\n """ _label = 'filter population' #--------------------------- DEFINE param functions -------------------------------------------- def _defineParams(self, form): form.addSection('Input') form.addParam('inputPopulation', params.PointerParam, label="Population", important=True, pointerClass='PKPDFitting', help='It must be a fitting coming from a bootstrap sample') form.addParam('filterType', params.EnumParam, choices=["Exclude","Keep","Keep confidence interval"], label="Filter mode", default=0, help='Exclude or keep samples meeting the following condition\n') form.addParam('condition', params.StringParam, label="Condition", default="$(AICc)>-10 or $(R2)<0.7", help='Example: $(Cl)>0.25 and $(tlag)>0\n'\ 'Example for the confidence interval: $(Cl) 95 (keep the central 95% of clearance).\n'\ 'The variables R2, R2adj, AIC, AICc, and BIC can be used, \n'\ 'e.g., $(AICc)>-10 selects those elements with suspicious fitting.\n'\ 'Confidence intervals cannot be placed on the quality parameters (R2, R2adj, ...)') #--------------------------- INSERT steps functions -------------------------------------------- def _insertAllSteps(self): self._insertFunctionStep('runFilter',self.inputPopulation.get().getObjId(), self.filterType.get(), self.condition.get()) self._insertFunctionStep('createOutputStep') #--------------------------- STEPS functions -------------------------------------------- def runFilter(self, objId, filterType, condition): self.population = self.readFitting(self.inputPopulation.get().fnFitting,cls="PKPDSampleFitBootstrap") self.printSection("Filtering population") self.fitting = PKPDFitting("PKPDSampleFitBootstrap") self.fitting.fnExperiment.set(self.population.fnExperiment) self.fitting.predictor=self.population.predictor self.fitting.predicted=self.population.predicted self.fitting.modelParameterUnits = self.population.modelParameterUnits self.fitting.modelParameters = self.population.modelParameters self.fitting.modelDescription = self.population.modelDescription newSampleFit = PKPDSampleFitBootstrap() newSampleFit.parameters = None filterType = self.filterType.get() for sampleFit in self.population.sampleFits: newSampleFit.sampleName = sampleFit.sampleName if newSampleFit.parameters == None: newSampleFit.parameters = np.empty((0,sampleFit.parameters.shape[1])) newSampleFit.xB = [] newSampleFit.yB = [] newSampleFit.R2 = [] newSampleFit.R2adj = [] newSampleFit.AIC = [] newSampleFit.AICc = [] newSampleFit.BIC = [] if filterType<=1: conditionToEvaluate = self.condition.get() else: tokens=self.condition.get().strip().split(' ') variable = tokens[0][2:-1] confidenceLevel = float(tokens[1]) columnIdx = -1 for j in range(len(self.population.modelParameters)): if self.population.modelParameters[j]==variable: columnIdx = j break if columnIdx==-1: raise Exception("Cannot find %s amongst the model variables"%variable) values=sampleFit.parameters[:,columnIdx] alpha_2 = (100-confidenceLevel)/2 limits = np.percentile(values,[alpha_2,100-alpha_2]) conditionToEvaluate = "%s>=%f and %s<=%f"%(tokens[0],limits[0],tokens[0],limits[1]) print("Condition to evaluate: %s"%conditionToEvaluate) for n in range(0,len(sampleFit.R2)): evaluatedCondition = copy.copy(conditionToEvaluate) evaluatedCondition = evaluatedCondition.replace('$(R2)',"(%f)"%sampleFit.R2[n]) evaluatedCondition = evaluatedCondition.replace('$(R2adj)',"(%f)"%sampleFit.R2adj[n]) evaluatedCondition = evaluatedCondition.replace('$(AIC)',"(%f)"%sampleFit.AIC[n]) evaluatedCondition = evaluatedCondition.replace('$(AICc)',"(%f)"%sampleFit.AICc[n]) evaluatedCondition = evaluatedCondition.replace('$(BIC)',"(%f)"%sampleFit.BIC[n]) for j in range(len(self.population.modelParameters)): evaluatedCondition = evaluatedCondition.replace('$(%s)'%self.population.modelParameters[j],"(%f)"%sampleFit.parameters[n,j]) evaluatedCondition = eval(evaluatedCondition) if (filterType==0 and not evaluatedCondition) or (filterType>=1 and evaluatedCondition): newSampleFit.parameters = np.vstack([newSampleFit.parameters, sampleFit.parameters[n,:]]) newSampleFit.xB += sampleFit.xB newSampleFit.yB += sampleFit.yB newSampleFit.R2.append(sampleFit.R2[n]) newSampleFit.R2adj.append(sampleFit.R2adj[n]) newSampleFit.AIC.append(sampleFit.AIC[n]) newSampleFit.AICc.append(sampleFit.AICc[n]) newSampleFit.BIC.append(sampleFit.BIC[n]) self.fitting.sampleFits.append(newSampleFit) self.fitting.write(self._getPath("bootstrapPopulation.pkpd")) def createOutputStep(self): self._defineOutputs(outputPopulation=self.fitting) self._defineSourceRelation(self.inputPopulation, self.fitting) #--------------------------- INFO functions -------------------------------------------- def _summary(self): if self.filterType.get()==0: filterType = "Exclude" elif self.filterType.get()==1: filterType = "Keep" elif self.filterType.get()==2: filterType = "Keep confidence interval" msg=["Filter type: %s"%filterType] msg.append("Condition: %s"%self.condition.get()) return msg def _validate(self): msg=[] if not self.inputPopulation.get().fnFitting.get().endswith("bootstrapPopulation.pkpd"): msg.append("Population must be a bootstrap sample") return msg
class ProtPKPDFitBase(ProtPKPD): """ Base fit protocol""" #--------------------------- DEFINE param functions -------------------------------------------- def _defineParams1(self, form, defaultPredictor, defaultPredicted): form.addSection('Input') form.addParam('inputExperiment', params.PointerParam, label="Input experiment", pointerClass='PKPDExperiment', help='Select an experiment with samples') form.addParam( 'predictor', params.StringParam, label="Predictor variable (X)", default=defaultPredictor, help='Y is predicted as an exponential function of X, Y=f(X)') form.addParam( 'predicted', params.StringParam, label="Predicted variable (Y)", default=defaultPredicted, help='Y is predicted as an exponential function of X, Y=f(X)') #--------------------------- INSERT steps functions -------------------------------------------- def _insertAllSteps(self): self._insertFunctionStep('runFit', self.getInputExperiment().getObjId(), self.getListOfFormDependencies()) self._insertFunctionStep('createOutputStep') #--------------------------- STEPS functions -------------------------------------------- def getInputExperiment(self): if hasattr(self, "inputExperiment"): return self.inputExperiment.get() else: return None def getXYvars(self): if hasattr(self, "predictor"): self.varNameX = self.predictor.get() else: self.varNameX = None if hasattr(self, "predicted"): self.varNameY = self.predicted.get() else: self.varNameY = None def setExperiment(self, experiment): self.experiment = experiment if experiment != None: self.fnExperiment = experiment.fnPKPD def setSample(self, sample): self.sample = sample self.model.setSample(sample) def createModel(self): pass def parseBounds(self, boundsString): self.boundsList = [] if boundsString != "" and boundsString != None: tokens = boundsString.split(';') if len(tokens) != self.getNumberOfParameters(): raise Exception( "The number of bound intervals does not match the number of parameters" ) for token in tokens: values = token.strip().split(',') self.boundsList.append( (float(values[0][1:]), float(values[1][:-1]))) def getBounds(self): return self.boundsList def getParameterBounds(self): """ Return a dictionary where the parameter name is the key and the bounds are its values. """ boundsDict = OrderedDict() self.parseBounds(self.bounds.get()) # after this we have boundsList parameterNames = self.model.getParameterNames() for paramName, bound in izip(parameterNames, self.getBounds()): boundsDict[paramName] = bound # Set None as bound for parameters not matched for paramName in parameterNames: if paramName not in boundsDict: boundsDict[paramName] = None return boundsDict def setupModel(self): # Setup model self.model = self.createModel() self.model.setExperiment(self.experiment) self.setupFromFormParameters() self.getXYvars() self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) def calculateParameterUnits(self, sample): self.parameterUnits = self.model.calculateParameterUnits(sample) def getParameterNames(self): return self.model.getParameterNames() def getNumberOfParameters(self): return len(self.getParameterNames()) def setParameters(self, prm): self.model.setParameters(prm) def forwardModel(self, prm, xValues): return self.model.forwardModel(prm, xValues) def setupFromFormParameters(self): pass def prepareForSampleAnalysis(self, sampleName): pass def postSampleAnalysis(self, sampleName): pass def runFit(self, objId, otherDependencies): self.getXYvars() if hasattr(self, "reportX"): reportX = parseRange(self.reportX.get()) else: reportX = None self.experiment = self.readExperiment(self.getInputExperiment().fnPKPD) # Setup model self.printSection("Model setup") self.model = self.createModel() self.model.setExperiment(self.experiment) self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) self.setupFromFormParameters() self.model.printSetup() # Create output object self.fitting = PKPDFitting() self.fitting.fnExperiment.set(self.getInputExperiment().fnPKPD.get()) self.fitting.predictor = self.experiment.variables[self.varNameX] self.fitting.predicted = self.experiment.variables[self.varNameY] self.fitting.modelDescription = self.model.getDescription() self.fitting.modelParameters = self.model.getParameterNames() self.fitting.modelParameterUnits = None # Actual fitting if self.fitType.get() == 0: fitType = "linear" elif self.fitType.get() == 1: fitType = "log" elif self.fitType.get() == 2: fitType = "relative" for sampleName, sample in self.experiment.samples.iteritems(): self.printSection("Fitting " + sampleName) x, y = sample.getXYValues(self.varNameX, self.varNameY) print("X= " + str(x)) print("Y= " + str(y)) print(" ") self.model.setBounds(self.bounds.get()) self.model.setXYValues(x, y) self.prepareForSampleAnalysis(sampleName) self.model.calculateParameterUnits(sample) if self.fitting.modelParameterUnits == None: self.fitting.modelParameterUnits = self.model.parameterUnits self.model.prepare() if self.model.bounds == None: continue print(" ") optimizer1 = PKPDDEOptimizer(self.model, fitType) optimizer1.optimize() optimizer2 = PKPDLSOptimizer(self.model, fitType) optimizer2.optimize() optimizer2.setConfidenceInterval(self.confidenceInterval.get()) self.setParameters(optimizer2.optimum) optimizer2.evaluateQuality() # Keep this result sampleFit = PKPDSampleFit() sampleFit.sampleName = sample.sampleName sampleFit.x = self.model.x sampleFit.y = self.model.y sampleFit.yp = self.model.yPredicted sampleFit.yl = self.model.yPredictedLower sampleFit.yu = self.model.yPredictedUpper sampleFit.parameters = self.model.parameters sampleFit.modelEquation = self.model.getEquation() sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) # Add the parameters to the sample and experiment for varName, varUnits, description, varValue in izip( self.model.getParameterNames(), self.model.parameterUnits, self.model.getParameterDescriptions(), self.model.parameters): self.experiment.addParameterToSample(sampleName, varName, varUnits, description, varValue) self.postSampleAnalysis(sampleName) if reportX != None: print("Evaluation of the model at specified time points") yreportX = self.model.forwardModel(self.model.parameters, reportX) print("==========================================") print("X Ypredicted log10(Ypredicted)") print("==========================================") for n in range(0, reportX.shape[0]): print("%f %f %f" % (reportX[n], yreportX[n], math.log10(yreportX[n]))) print(' ') self.fitting.write(self._getPath("fitting.pkpd")) self.experiment.write(self._getPath("experiment.pkpd")) def createOutputStep(self): self._defineOutputs(outputFitting=self.fitting) self._defineOutputs(outputExperiment=self.experiment) self._defineSourceRelation(self.getInputExperiment(), self.fitting) self._defineSourceRelation(self.getInputExperiment(), self.experiment) #--------------------------- INFO functions -------------------------------------------- def _summary(self): self.getXYvars() msg = ['Predicting %s from %s' % (self.varNameX, self.varNameY)] return msg def _validate(self): self.getXYvars() errors = [] experiment = self.readExperiment(self.getInputExperiment().fnPKPD, False) if not self.varNameX in experiment.variables: errors.append("Cannot find %s as variable" % self.varNameX) if not self.varNameY in experiment.variables: errors.append("Cannot find %s as variable" % self.varNameY) return errors def _citations(self): return ['Spiess2010'] def filterVarForWizard(self, v): """ Define the type of variables required (used in wizard). """ return v.isNumeric() and (v.isMeasurement() or v.isTime())
def runFit(self, objId, deltaT): self.protODE = self.inputODE.get() self.experiment = self.readExperiment(self.protODE.outputExperiment.fnPKPD) self.fitting = self.readFitting(self.protODE.outputFitting.fnFitting) # Get the X and Y variable names self.varNameX = self.fitting.predictor.varName if type(self.fitting.predicted)==list: self.varNameY = [v.varName for v in self.fitting.predicted] else: self.varNameY = self.fitting.predicted.varName self.protODE.experiment = self.experiment self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY # Create output object self.fitting = PKPDFitting() self.fitting.fnExperiment.set(self.experiment.fnPKPD.get()) self.fitting.predictor=self.experiment.variables[self.varNameX] self.fitting.predicted=self.experiment.variables[self.varNameY] self.fitting.modelParameterUnits = None # Actual fitting if self.protODE.fitType.get()==0: fitType = "linear" elif self.protODE.fitType.get()==1: fitType = "log" elif self.protODE.fitType.get()==2: fitType = "relative" parameterNames = None for groupName, group in self.experiment.groups.iteritems(): self.printSection("Fitting "+groupName) self.protODE.clearGroupParameters() self.clearGroupParameters() for sampleName in group.sampleList: print(" Sample "+sampleName) sample = self.experiment.samples[sampleName] self.protODE.createDrugSource() self.protODE.setupModel() # Setup self model self.drugSource = self.protODE.drugSource self.drugSourceList = self.protODE.drugSourceList self.model = self.protODE.model self.modelList = self.protODE.modelList self.model.deltaT = self.deltaT.get() self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) # Get the values to fit x, y = sample.getXYValues(self.varNameX,self.varNameY) print("X= "+str(x)) print("Y= "+str(y)) # Interpret the dose self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY self.protODE.model = self.model self.protODE.setTimeRange(sample) sample.interpretDose() self.drugSource.setDoses(sample.parsedDoseList, self.model.t0, self.model.tF) self.protODE.configureSource(self.drugSource) self.model.drugSource = self.drugSource # Prepare the model self.model.setSample(sample) self.calculateParameterUnits(sample) if self.fitting.modelParameterUnits==None: self.fitting.modelParameterUnits = self.parameterUnits # Get the initial parameters if parameterNames==None: parameterNames = self.getParameterNames() parameters0 = [] for parameterName in parameterNames: parameters0.append(float(sample.descriptors[parameterName])) print("Initial solution: %s"%str(parameters0)) print(" ") # Set bounds self.setBounds(sample) self.setXYValues(x, y) self.parameters = parameters0 self.printSetup() self.x = self.mergeLists(self.XList) self.y = self.mergeLists(self.YList) optimizer2 = PKPDLSOptimizer(self,fitType) optimizer2.optimize() optimizer2.setConfidenceInterval(self.protODE.confidenceInterval.get()) self.setParameters(optimizer2.optimum) n=0 for sampleName in group.sampleList: sample = self.experiment.samples[sampleName] # Keep this result sampleFit = PKPDSampleFit() sampleFit.sampleName = sample.sampleName sampleFit.x = x sampleFit.y = y sampleFit.yp = self.yPredicted sampleFit.yl = self.yPredictedLower sampleFit.yu = self.yPredictedUpper sampleFit.parameters = self.parameters sampleFit.modelEquation = self.getEquation() sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) # Add the parameters to the sample and experiment for varName, varUnits, description, varValue in izip(self.getParameterNames(), self.parameterUnits, self.getParameterDescriptions(), self.parameters): self.experiment.addParameterToSample(sampleName, varName, varUnits, description, varValue) n+=1 self.fitting.modelParameters = self.getParameterNames() self.fitting.modelDescription = self.getDescription() self.fitting.write(self._getPath("fitting.pkpd")) self.experiment.write(self._getPath("experiment.pkpd"))
class ProtPKPDODERefine(ProtPKPDODEBase): """ Refinement of an ODE protocol. The parameters are reestimated with a finer sampling rate. """ _label = 'ODE refinement' #--------------------------- DEFINE param functions -------------------------------------------- def _defineParams(self, form): form.addSection('Input') form.addParam('inputODE', params.PointerParam, label="Input ODE model", pointerClass='ProtPKPDMonoCompartment, ProtPKPDMonoCompartmentUrine, ProtPKPDTwoCompartments', help='Select a run of an ODE model') form.addParam('deltaT', params.FloatParam, default=0.5, label='Step (min)', expertLevel=LEVEL_ADVANCED) #--------------------------- INSERT steps functions -------------------------------------------- def _insertAllSteps(self): self._insertFunctionStep('runFit',self.inputODE.get().getObjId(), self.deltaT.get()) self._insertFunctionStep('createOutputStep') #--------------------------- STEPS functions -------------------------------------------- def parseBounds(self, boundsString): if boundsString!="" and boundsString!=None: tokens=boundsString.split(';') if len(tokens)!=self.getNumberOfParameters(): raise Exception("The number of bound intervals does not match the number of parameters") self.boundsList=[] for token in tokens: values = token.strip().split(',') self.boundsList.append((float(values[0][1:]),float(values[1][:-1]))) def setBounds(self,sample): self.parseBounds(self.protODE.bounds.get()) self.setBoundsFromBoundsList() def setBoundsFromBoundsList(self): Nbounds = len(self.boundsList) Nsource = self.drugSource.getNumberOfParameters() Nmodel = self.model.getNumberOfParameters() if Nbounds!=Nsource+Nmodel: raise "The number of parameters (%d) and bounds (%d) are different"%(Nsource+Nmodel,Nbounds) self.boundsSource = self.boundsList[0:Nsource] self.boundsPK = self.boundsList[Nsource:] self.model.bounds = self.boundsPK def getBounds(self): return self.boundsList def runFit(self, objId, deltaT): self.protODE = self.inputODE.get() self.experiment = self.readExperiment(self.protODE.outputExperiment.fnPKPD) self.fitting = self.readFitting(self.protODE.outputFitting.fnFitting) # Get the X and Y variable names self.varNameX = self.fitting.predictor.varName if type(self.fitting.predicted)==list: self.varNameY = [v.varName for v in self.fitting.predicted] else: self.varNameY = self.fitting.predicted.varName self.protODE.experiment = self.experiment self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY # Create output object self.fitting = PKPDFitting() self.fitting.fnExperiment.set(self.experiment.fnPKPD.get()) self.fitting.predictor=self.experiment.variables[self.varNameX] self.fitting.predicted=self.experiment.variables[self.varNameY] self.fitting.modelParameterUnits = None # Actual fitting if self.protODE.fitType.get()==0: fitType = "linear" elif self.protODE.fitType.get()==1: fitType = "log" elif self.protODE.fitType.get()==2: fitType = "relative" parameterNames = None for groupName, group in self.experiment.groups.iteritems(): self.printSection("Fitting "+groupName) self.protODE.clearGroupParameters() self.clearGroupParameters() for sampleName in group.sampleList: print(" Sample "+sampleName) sample = self.experiment.samples[sampleName] self.protODE.createDrugSource() self.protODE.setupModel() # Setup self model self.drugSource = self.protODE.drugSource self.drugSourceList = self.protODE.drugSourceList self.model = self.protODE.model self.modelList = self.protODE.modelList self.model.deltaT = self.deltaT.get() self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) # Get the values to fit x, y = sample.getXYValues(self.varNameX,self.varNameY) print("X= "+str(x)) print("Y= "+str(y)) # Interpret the dose self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY self.protODE.model = self.model self.protODE.setTimeRange(sample) sample.interpretDose() self.drugSource.setDoses(sample.parsedDoseList, self.model.t0, self.model.tF) self.protODE.configureSource(self.drugSource) self.model.drugSource = self.drugSource # Prepare the model self.model.setSample(sample) self.calculateParameterUnits(sample) if self.fitting.modelParameterUnits==None: self.fitting.modelParameterUnits = self.parameterUnits # Get the initial parameters if parameterNames==None: parameterNames = self.getParameterNames() parameters0 = [] for parameterName in parameterNames: parameters0.append(float(sample.descriptors[parameterName])) print("Initial solution: %s"%str(parameters0)) print(" ") # Set bounds self.setBounds(sample) self.setXYValues(x, y) self.parameters = parameters0 self.printSetup() self.x = self.mergeLists(self.XList) self.y = self.mergeLists(self.YList) optimizer2 = PKPDLSOptimizer(self,fitType) optimizer2.optimize() optimizer2.setConfidenceInterval(self.protODE.confidenceInterval.get()) self.setParameters(optimizer2.optimum) n=0 for sampleName in group.sampleList: sample = self.experiment.samples[sampleName] # Keep this result sampleFit = PKPDSampleFit() sampleFit.sampleName = sample.sampleName sampleFit.x = x sampleFit.y = y sampleFit.yp = self.yPredicted sampleFit.yl = self.yPredictedLower sampleFit.yu = self.yPredictedUpper sampleFit.parameters = self.parameters sampleFit.modelEquation = self.getEquation() sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) # Add the parameters to the sample and experiment for varName, varUnits, description, varValue in izip(self.getParameterNames(), self.parameterUnits, self.getParameterDescriptions(), self.parameters): self.experiment.addParameterToSample(sampleName, varName, varUnits, description, varValue) n+=1 self.fitting.modelParameters = self.getParameterNames() self.fitting.modelDescription = self.getDescription() self.fitting.write(self._getPath("fitting.pkpd")) self.experiment.write(self._getPath("experiment.pkpd")) def createOutputStep(self): self._defineOutputs(outputFitting=self.fitting) self._defineOutputs(outputExperiment=self.experiment) self._defineSourceRelation(self.inputODE.get(), self.fitting) self._defineSourceRelation(self.inputODE.get(), self.experiment) #--------------------------- INFO functions -------------------------------------------- def _summary(self): msg = [] msg.append("New sampling rate: %f"%self.deltaT.get()) return msg def _validate(self): return []
class ProtPKPDMergePopulations(ProtPKPD): """ Merge two populations. Both populations must have the same labels\n Protocol created by http://www.kinestatpharma.com\n """ _label = 'merge populations' #--------------------------- DEFINE param functions -------------------------------------------- def _defineParams(self, form): form.addSection('Input') form.addParam('inputPopulation1', params.PointerParam, label="Population 1", important=True, pointerClass='PKPDFitting', pointerCondition="isPopulation", help='It must be a fitting coming from a bootstrap sample') form.addParam('inputPopulation2', params.PointerParam, label="Population 2", important=True, pointerClass='PKPDFitting', pointerCondition="isPopulation", help='It must be a fitting coming from a bootstrap sample') #--------------------------- INSERT steps functions -------------------------------------------- def _insertAllSteps(self): self._insertFunctionStep('runMerge',self.inputPopulation1.get().getObjId(), self.inputPopulation2.getObjId()) self._insertFunctionStep('createOutputStep') #--------------------------- STEPS functions -------------------------------------------- def runMerge(self, objId1, objId2): self.population1 = self.readFitting(self.inputPopulation1.get().fnFitting,cls="PKPDSampleFitBootstrap") self.population2 = self.readFitting(self.inputPopulation2.get().fnFitting,cls="PKPDSampleFitBootstrap") self.printSection("Merging populations") self.fitting = PKPDFitting("PKPDSampleFitBootstrap") self.fitting.fnExperiment.set(self.population1.fnExperiment) self.fitting.predictor=self.population1.predictor self.fitting.predicted=self.population1.predicted self.fitting.modelParameterUnits = self.population1.modelParameterUnits self.fitting.modelParameters = self.population1.modelParameters self.fitting.modelDescription = self.population1.modelDescription newSampleFit = PKPDSampleFitBootstrap() newSampleFit.sampleName = "Merged population" newSampleFit.parameters = None for sampleFit in self.population1.sampleFits: if newSampleFit.parameters == None: newSampleFit.parameters = np.copy(sampleFit.parameters) newSampleFit.xB = copy.copy(sampleFit.xB) newSampleFit.yB = copy.copy(sampleFit.yB) newSampleFit.R2 = copy.copy(sampleFit.R2) newSampleFit.R2adj = copy.copy(sampleFit.R2adj) newSampleFit.AIC = copy.copy(sampleFit.AIC) newSampleFit.AICc = copy.copy(sampleFit.AICc) newSampleFit.BIC = copy.copy(sampleFit.BIC) else: newSampleFit.parameters = np.vstack([newSampleFit.parameters, sampleFit.parameters]) newSampleFit.xB += sampleFit.xB newSampleFit.yB += sampleFit.yB newSampleFit.R2 += sampleFit.R2 newSampleFit.R2adj += sampleFit.R2adj newSampleFit.AIC += sampleFit.AIC newSampleFit.AICc += sampleFit.AICc newSampleFit.BIC += sampleFit.BIC for sampleFit in self.population2.sampleFits: newSampleFit.parameters = np.vstack([newSampleFit.parameters, sampleFit.parameters]) print(type(newSampleFit.xB)) print(type(sampleFit.xB)) newSampleFit.xB += sampleFit.xB newSampleFit.yB += sampleFit.yB newSampleFit.R2 += sampleFit.R2 newSampleFit.R2adj += sampleFit.R2adj newSampleFit.AIC += sampleFit.AIC newSampleFit.AICc += sampleFit.AICc newSampleFit.BIC += sampleFit.BIC self.fitting.sampleFits.append(newSampleFit) self.fitting.write(self._getPath("bootstrapPopulation.pkpd")) def createOutputStep(self): self._defineOutputs(outputPopulation=self.fitting) self._defineSourceRelation(self.inputPopulation1, self.fitting) self._defineSourceRelation(self.inputPopulation2, self.fitting) #--------------------------- INFO functions -------------------------------------------- def _summary(self): msg=["Populations %s and %s were merged"%(self.getObjectTag(self.inputPopulation1.get()), self.getObjectTag(self.inputPopulation2.get()))] return msg def _validate(self): msg=[] if not self.inputPopulation1.get().fnFitting.get().endswith("bootstrapPopulation.pkpd"): msg.append("Population 1 must be a bootstrap sample") if not self.inputPopulation2.get().fnFitting.get().endswith("bootstrapPopulation.pkpd"): msg.append("Population 2 must be a bootstrap sample") return msg
def runFit(self, objId, otherDependencies): self.getXYvars() if hasattr(self, "reportX"): reportX = parseRange(self.reportX.get()) else: reportX = None self.experiment = self.readExperiment(self.getInputExperiment().fnPKPD) # Setup model self.printSection("Model setup") self.model = self.createModel() self.model.setExperiment(self.experiment) self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) self.setupFromFormParameters() self.model.printSetup() # Create output object self.fitting = PKPDFitting() self.fitting.fnExperiment.set(self.getInputExperiment().fnPKPD.get()) self.fitting.predictor = self.experiment.variables[self.varNameX] self.fitting.predicted = self.experiment.variables[self.varNameY] self.fitting.modelDescription = self.model.getDescription() self.fitting.modelParameters = self.model.getParameterNames() self.fitting.modelParameterUnits = None # Actual fitting if self.fitType.get() == 0: fitType = "linear" elif self.fitType.get() == 1: fitType = "log" elif self.fitType.get() == 2: fitType = "relative" for sampleName, sample in self.experiment.samples.iteritems(): self.printSection("Fitting " + sampleName) x, y = sample.getXYValues(self.varNameX, self.varNameY) print("X= " + str(x)) print("Y= " + str(y)) print(" ") self.model.setBounds(self.bounds.get()) self.model.setXYValues(x, y) self.prepareForSampleAnalysis(sampleName) self.model.calculateParameterUnits(sample) if self.fitting.modelParameterUnits == None: self.fitting.modelParameterUnits = self.model.parameterUnits self.model.prepare() if self.model.bounds == None: continue print(" ") optimizer1 = PKPDDEOptimizer(self.model, fitType) optimizer1.optimize() optimizer2 = PKPDLSOptimizer(self.model, fitType) optimizer2.optimize() optimizer2.setConfidenceInterval(self.confidenceInterval.get()) self.setParameters(optimizer2.optimum) optimizer2.evaluateQuality() # Keep this result sampleFit = PKPDSampleFit() sampleFit.sampleName = sample.sampleName sampleFit.x = self.model.x sampleFit.y = self.model.y sampleFit.yp = self.model.yPredicted sampleFit.yl = self.model.yPredictedLower sampleFit.yu = self.model.yPredictedUpper sampleFit.parameters = self.model.parameters sampleFit.modelEquation = self.model.getEquation() sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) # Add the parameters to the sample and experiment for varName, varUnits, description, varValue in izip( self.model.getParameterNames(), self.model.parameterUnits, self.model.getParameterDescriptions(), self.model.parameters): self.experiment.addParameterToSample(sampleName, varName, varUnits, description, varValue) self.postSampleAnalysis(sampleName) if reportX != None: print("Evaluation of the model at specified time points") yreportX = self.model.forwardModel(self.model.parameters, reportX) print("==========================================") print("X Ypredicted log10(Ypredicted)") print("==========================================") for n in range(0, reportX.shape[0]): print("%f %f %f" % (reportX[n], yreportX[n], math.log10(yreportX[n]))) print(' ') self.fitting.write(self._getPath("fitting.pkpd")) self.experiment.write(self._getPath("experiment.pkpd"))
class ProtPKPDODEBootstrap(ProtPKPDODEBase): """ Bootstrap of an ODE protocol""" _label = 'ODE bootstrap' #--------------------------- DEFINE param functions -------------------------------------------- def _defineParams(self, form): form.addSection('Input') form.addParam('inputODE', params.PointerParam, label="Input ODE model", pointerClass='ProtPKPDMonoCompartment, ProtPKPDMonoCompartmentUrine, ProtPKPDTwoCompartments, '\ 'ProtPKPDTwoCompartmentsAutoinduction, ProtPKPDTwoCompartmentsClint, '\ 'ProtPKPDTwoCompartmentsClintMetabolite, ProtPKPDTwoCompartmentsUrine', help='Select a run of an ODE model') form.addParam('Nbootstrap', params.IntParam, label="Bootstrap samples", default=200, expertLevel=LEVEL_ADVANCED, help='Number of bootstrap realizations for each sample') form.addParam('sampleLength', params.IntParam, label="Sample length", default=-1, expertLevel=LEVEL_ADVANCED, help='If the input experiment represents a population, the bootstrap sample is so overdetermined '\ 'that the bootstrap parameter estimate seldom moves from the original values. In this case, '\ 'you may use the sample length to generate bootstrap samples of the same length as the indiviudals '\ 'taking part of the population. If this value is set to -1, then the length of the bootstrap sample '\ 'will be the same as the one in the input experiment. If set to any other value, e.g. 8, then '\ 'each bootstrap sample will have this length') form.addParam('confidenceInterval', params.FloatParam, label="Confidence interval", default=95, expertLevel=LEVEL_ADVANCED, help='Confidence interval for the fitted parameters') form.addParam('deltaT', params.FloatParam, default=2, label='Step (min)', expertLevel=LEVEL_ADVANCED) #--------------------------- INSERT steps functions -------------------------------------------- def _insertAllSteps(self): self._insertFunctionStep('runFit',self.inputODE.get().getObjId(), self.Nbootstrap.get(), self.confidenceInterval.get()) self._insertFunctionStep('createOutputStep') #--------------------------- STEPS functions -------------------------------------------- def parseBounds(self, boundsString): if boundsString!="" and boundsString!=None: tokens=boundsString.split(';') if len(tokens)!=self.getNumberOfParameters(): raise Exception("The number of bound intervals does not match the number of parameters") self.boundsList=[] for token in tokens: values = token.strip().split(',') self.boundsList.append((float(values[0][1:]),float(values[1][:-1]))) def setBounds(self,sample): self.parseBounds(self.protODE.bounds.get()) self.setBoundsFromBoundsList() def setBoundsFromBoundsList(self): Nbounds = len(self.boundsList) Nsource = self.drugSource.getNumberOfParameters() Nmodel = self.model.getNumberOfParameters() if Nbounds!=Nsource+Nmodel: raise "The number of parameters (%d) and bounds (%d) are different"%(Nsource+Nmodel,Nbounds) self.boundsSource = self.boundsList[0:Nsource] self.boundsPK = self.boundsList[Nsource:] self.model.bounds = self.boundsPK def getBounds(self): return self.boundsList def runFit(self, objId, Nbootstrap, confidenceInterval): self.protODE = self.inputODE.get() self.experiment = self.readExperiment(self.protODE.outputExperiment.fnPKPD) self.fitting = self.readFitting(self.protODE.outputFitting.fnFitting) # Get the X and Y variable names self.varNameX = self.fitting.predictor.varName if type(self.fitting.predicted)==list: self.varNameY = [v.varName for v in self.fitting.predicted] else: self.varNameY = self.fitting.predicted.varName self.protODE.experiment = self.experiment self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY # Create output object self.fitting = PKPDFitting("PKPDSampleFitBootstrap") self.fitting.fnExperiment.set(self.experiment.fnPKPD.get()) self.fitting.predictor=self.experiment.variables[self.varNameX] if type(self.varNameY)==list: self.fitting.predicted=[self.experiment.variables[v] for v in self.varNameY] else: self.fitting.predicted=self.experiment.variables[self.varNameY] self.fitting.modelParameterUnits = None # Actual fitting if self.protODE.fitType.get()==0: fitType = "linear" elif self.protODE.fitType.get()==1: fitType = "log" elif self.protODE.fitType.get()==2: fitType = "relative" parameterNames = None for groupName, group in self.experiment.groups.iteritems(): self.printSection("Fitting "+groupName) self.protODE.clearGroupParameters() self.clearGroupParameters() for sampleName in group.sampleList: print(" Sample "+sampleName) sample = self.experiment.samples[sampleName] self.protODE.createDrugSource() self.protODE.setupModel() # Setup self model self.drugSource = self.protODE.drugSource self.drugSourceList = self.protODE.drugSourceList self.model = self.protODE.model self.modelList = self.protODE.modelList self.model.deltaT = self.deltaT.get() self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) # Get the values to fit x, y = sample.getXYValues(self.varNameX,self.varNameY) print("X= "+str(x)) print("Y= "+str(y)) firstX=x[0] # From [array(...)] to array(...) firstY=y[0] # From [array(...)] to array(...) # Interpret the dose self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY self.protODE.model = self.model self.protODE.setTimeRange(sample) sample.interpretDose() self.drugSource.setDoses(sample.parsedDoseList, self.model.t0, self.model.tF) self.protODE.configureSource(self.drugSource) self.model.drugSource = self.drugSource # Prepare the model self.model.setSample(sample) self.calculateParameterUnits(sample) if self.fitting.modelParameterUnits==None: self.fitting.modelParameterUnits = self.parameterUnits # Get the initial parameters if parameterNames==None: parameterNames = self.getParameterNames() parameters0 = [] for parameterName in parameterNames: parameters0.append(float(sample.descriptors[parameterName])) print("Initial solution: %s"%str(parameters0)) print(" ") # Set bounds self.setBounds(sample) # Output object sampleFit = PKPDSampleFitBootstrap() sampleFit.sampleName = sample.sampleName sampleFit.parameters = np.zeros((self.Nbootstrap.get(),len(parameters0)),np.double) sampleFit.xB = [] sampleFit.yB = [] # Bootstrap samples idx = [k for k in range(0,len(firstX))] for n in range(0,self.Nbootstrap.get()): ok = False while not ok: if self.sampleLength.get()>0: lenToUse = self.sampleLength.get() else: lenToUse = len(idx) idxB = sorted(np.random.choice(idx,lenToUse)) xB = [np.asarray([firstX[i] for i in idxB])] yB = [np.asarray([firstY[i] for i in idxB])] print("Bootstrap sample %d"%n) print("X= "+str(xB)) print("Y= "+str(yB)) self.clearXYLists() self.setXYValues(xB, yB) self.parameters = parameters0 optimizer2 = PKPDLSOptimizer(self,fitType) optimizer2.verbose = 0 try: optimizer2.optimize() ok=True except Exception as e: print(e) raise(e) ok=False # Evaluate the quality on the whole data set self.clearXYLists() self.setXYValues(x, y) optimizer2.evaluateQuality() print(optimizer2.optimum) print(" R2 = %f R2Adj=%f AIC=%f AICc=%f BIC=%f"%(optimizer2.R2,optimizer2.R2adj,optimizer2.AIC,\ optimizer2.AICc,optimizer2.BIC)) # Keep this result sampleFit.parameters[n,:] = optimizer2.optimum sampleFit.xB.append(str(xB[0])) sampleFit.yB.append(str(yB[0])) sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) self.fitting.modelParameters = self.getParameterNames() self.fitting.modelDescription = self.getDescription() self.fitting.write(self._getPath("bootstrapPopulation.pkpd")) def createOutputStep(self): self._defineOutputs(outputPopulation=self.fitting) self._defineSourceRelation(self.inputODE.get(), self.fitting) #--------------------------- INFO functions -------------------------------------------- def _summary(self): msg = [] msg.append("Number of bootstrap realizations: %d"%self.Nbootstrap.get()) msg.append("Confidence interval: %f"%self.confidenceInterval.get()) return msg def _validate(self): return []
class ProtPKPDODEBase(ProtPKPD,PKPDModelBase2): """ Base ODE protocol""" def __init__(self,**kwargs): ProtPKPD.__init__(self,**kwargs) self.boundsList = None #--------------------------- DEFINE param functions -------------------------------------------- def _defineParams1(self, form, addXY=False, defaultPredictor="", defaultPredicted=""): form.addSection('Input') form.addParam('inputExperiment', params.PointerParam, label="Input experiment", pointerClass='PKPDExperiment', help='Select an experiment with samples') if addXY: form.addParam('predictor', params.StringParam, label="Predictor variable (X)", default=defaultPredictor, help='Y is predicted as an exponential function of X, Y=f(X)') form.addParam('predicted', params.StringParam, label="Predicted variable (Y)", default=defaultPredicted, help='Y is predicted as an exponential function of X, Y=f(X)') fromTo = form.addLine('Simulation length', expertLevel = LEVEL_ADVANCED, help='Minimum and maximum time (in hours) and step size (in minutes). ' 'If minimum and maximum are not given (set to -1), they are estimated from the sample') fromTo.addParam('t0', params.StringParam, default="", label='Min (h)') fromTo.addParam('tF', params.StringParam, default="", label='Max (h)') fromTo.addParam('deltaT', params.FloatParam, default=0.5, label='Step (min)') form.addParam('fitType', params.EnumParam, choices=["Linear","Logarithmic","Relative"], label="Fit mode", default=1, expertLevel=LEVEL_ADVANCED, help='Linear: sum (Cobserved-Cpredicted)^2\nLogarithmic: sum(log10(Cobserved)-log10(Cpredicted))^2\n'\ "Relative: sum ((Cobserved-Cpredicted)/Cobserved)^2") form.addParam('confidenceInterval', params.FloatParam, label="Confidence interval", default=95, expertLevel=LEVEL_ADVANCED, help='Confidence interval for the fitted parameters') form.addParam('reportX', params.StringParam, label="Evaluate at X", default="", expertLevel=LEVEL_ADVANCED, help='Evaluate the model at these X values\nExample 1: [0,5,10,20,40,100]\nExample 2: 0:0.55:10, from 0 to 10 in steps of 0.5') form.addParam('globalSearch', params.BooleanParam, label="Global search", default=True, expertLevel=LEVEL_ADVANCED, help='Global search looks for the best parameters within bounds. If it is not performed, the ' 'middle of the bounding box is used as initial parameter for a local optimization') #--------------------------- INSERT steps functions -------------------------------------------- def getListOfFormDependencies(self): retval = [self.fitType.get(), self.confidenceInterval.get(), self.reportX.get()] if hasattr(self,"predictor"): retval.append(self.predictor.get()) retval.append(self.predicted.get()) if hasattr(self,"bounds"): retval.append(self.bounds.get()) return retval def _insertAllSteps(self): self._insertFunctionStep('runFit',self.getInputExperiment().getObjId(),self.getListOfFormDependencies()) self._insertFunctionStep('createOutputStep') #--------------------------- STEPS functions -------------------------------------------- def getInputExperiment(self): if hasattr(self,"inputExperiment"): return self.inputExperiment.get() else: return None def getXYvars(self): if hasattr(self,"predictor"): self.varNameX=self.predictor.get() else: self.varNameX=None if hasattr(self,"predicted"): self.varNameY=self.predicted.get() else: self.varNameY=None def configureSource(self, drugSource): pass def createModel(self): pass def setupModel(self): # Setup model self.model = self.createModel() self.model.setExperiment(self.experiment) self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) self.modelList.append(self.model) def getResponseDimension(self): return self.model.getResponseDimension() def getStateDimension(self): return self.model.getStateDimension() def setBounds(self, sample): if hasattr(self,"bounds"): self.model.setBounds(self.bounds.get()) def prepareForSampleAnalysis(self, sampleName): pass def postSampleAnalysis(self, sampleName): pass def setTimeRange(self, sample): if self.t0.get()=="" or self.tF.get()=="": tmin, tmax = sample.getRange(self.varNameX) else: tmin = self.t0.get() tmax = self.tF.get() if self.tmin==None: self.tmin=tmin else: self.tmin=min(tmin,self.tmin) if self.tmax==None: self.tmax=tmax else: self.tmax=max(tmax,self.tmax) if self.t0.get()=="": self.model.t0 = min(-10,self.tmin-10) # 10 minutes before else: self.model.t0 = min(-10,float(self.t0.get())*60) if self.tF.get()=="": self.model.tF = self.tmax+10 # 10 minutes later else: self.model.tF = float(self.tF.get())*60 if hasattr(self,"deltaT"): self.model.deltaT = self.deltaT.get() # As model -------------------------------------------- def clearGroupParameters(self): self.tmin = None self.tmax = None self.sampleList = [] self.modelList = [] self.drugSourceList = [] self.clearXYLists() def clearXYLists(self): self.XList = [] self.YList = [] def parseBounds(self, boundsString): self.boundsList = [] if boundsString!="" and boundsString!=None: tokens = boundsString.split(';') if len(tokens)!=self.getNumberOfParameters(): raise Exception("The number of bound intervals does not match the number of parameters") for token in tokens: values = token.strip().split(',') self.boundsList.append((float(values[0][1:]),float(values[1][:-1]))) def setBounds(self, sample): self.parseBounds(self.bounds.get()) self.setBoundsFromBoundsList() def setBoundsFromBoundsList(self): Nbounds = len(self.boundsList) Nsource = self.drugSource.getNumberOfParameters() Nmodel = self.model.getNumberOfParameters() if Nbounds!=Nsource+Nmodel: raise Exception("The number of parameters (%d) and bounds (%d) are different"%(Nsource+Nmodel,Nbounds)) self.boundsSource = self.boundsList[0:Nsource] self.boundsPK = self.boundsList[Nsource:] self.model.bounds = self.boundsPK def getBounds(self): return self.boundsList def getParameterBounds(self): """ Return a dictionary where the parameter name is the key and the bounds are its values. """ boundsDict = OrderedDict() self.parseBounds(self.bounds.get()) # after this we have boundsList parameterNames = self.getParameterNames() for paramName, bound in izip(parameterNames, self.getBounds()): boundsDict[paramName] = bound # Set None as bound for parameters not matched for paramName in parameterNames: if paramName not in boundsDict: boundsDict[paramName] = None return boundsDict def setParameters(self, parameters): self.parameters = parameters self.parametersPK = self.parameters[-self.NparametersModel:] for n in range(len(self.modelList)): if self.NparametersSource>0: self.drugSourceList[n].setParameters(self.parameters[0:self.NparametersSource]) self.modelList[n].setParameters(self.parametersPK) def setXYValues(self, x, y): PKPDModelBase.setXYValues(self,x,y) self.model.setXYValues(x, y) self.XList.append(x) self.YList.append(y) def mergeLists(self, iny): if len(self.XList)>1: outy=[] for m in range(len(iny[0])): outy.append(np.empty(shape=[0])) for m in range(len(outy)): for n in range(len(iny)): outy[m]=np.concatenate((outy[m],iny[n][m])) return outy else: return iny[0] def separateLists(self,iny): outy=[] Nsamples=len(self.YList) if Nsamples==0: return Nmeasurements = self.model.getResponseDimension() idx=[0]*Nmeasurements for n in range(Nsamples): yn=self.YList[n] perSampleIn = [] for j in range(Nmeasurements): ynDim = yn[j].size ysample = iny[j][idx[j]:(idx[j]+ynDim)] perSampleIn.append(ysample) idx[j]+=ynDim outy.append(perSampleIn) return outy def addSample(self, sample): self.sampleList.append(sample) self.model.setSample(sample) def forwardModel(self, parameters, x=None): self.setParameters(parameters) yPredictedList = [] for n in range(len(self.modelList)): self.modelList[n].forwardModel(self.parametersPK,x) yPredictedList.append(self.modelList[n].yPredicted) self.yPredicted = self.mergeLists(yPredictedList) return copy.copy(self.yPredicted) def imposeConstraints(self,yt): self.model.imposeConstraints(yt) def getEquation(self): return self.drugSource.getEquation()+" and "+self.model.getEquation() def getModelEquation(self): return self.drugSource.getModelEquation()+" and "+self.model.getModelEquation() def getDescription(self): return self.drugSource.getDescription()+"; "+self.model.getDescription() def getParameterNames(self): retval = [] parametersSource = self.drugSource.getParameterNames() self.NparametersSource = len(parametersSource) retval += parametersSource parametersModel = self.model.getParameterNames() self.NparametersModel = len(parametersModel) retval += parametersModel return retval def calculateParameterUnits(self,sample): retval = [] retval += self.drugSource.calculateParameterUnits(sample) retval += self.model.calculateParameterUnits(sample) self.parameterUnits = retval def areParametersSignificant(self, lowerBound, upperBound): retval = [] idx=0 if len(self.boundsSource)>0: retval+=self.drugSource.areParametersSignificant(lowerBound[idx:len(self.boundsSource)], upperBound[idx:len(self.boundsSource)]) retval+=self.model.areParametersSignificant(lowerBound[len(self.boundsSource):], upperBound[len(self.boundsSource):]) return retval def areParametersValid(self, p): return self.drugSource.areParametersValid(p[0:len(self.boundsSource)]) and \ self.model.areParametersValid(p[len(self.boundsSource):]) def createDrugSource(self): self.drugSource = DrugSource() self.drugSourceList.append(self.drugSource) return self.drugSource # Really fit --------------------------------------------------------- def runFit(self, objId, otherDependencies): reportX = parseRange(self.reportX.get()) self.setInputExperiment() # Setup model self.getXYvars() # Create output object self.fitting = PKPDFitting() self.fitting.fnExperiment.set(self._getPath("experiment.pkpd")) self.fitting.predictor=self.experiment.variables[self.varNameX] if type(self.varNameY)==list: self.fitting.predicted=[] for y in self.varNameY: self.fitting.predicted.append(self.experiment.variables[y]) else: self.fitting.predicted=self.experiment.variables[self.varNameY] self.fitting.modelParameterUnits = None # Actual fitting if self.fitType.get()==0: fitType = "linear" elif self.fitType.get()==1: fitType = "log" elif self.fitType.get()==2: fitType = "relative" for groupName, group in self.experiment.groups.iteritems(): self.printSection("Fitting "+groupName) self.clearGroupParameters() for sampleName in group.sampleList: print(" Sample "+sampleName) sample = self.experiment.samples[sampleName] self.createDrugSource() self.setupModel() # Get the values to fit x, y = sample.getXYValues(self.varNameX,self.varNameY) print("X= "+str(x)) print("Y= "+str(y)) print(" ") # Interpret the dose self.setTimeRange(sample) sample.interpretDose() self.drugSource.setDoses(sample.parsedDoseList, self.model.t0, self.model.tF) self.configureSource(self.drugSource) self.model.drugSource = self.drugSource # Prepare the model self.setBounds(sample) self.setXYValues(x, y) self.addSample(sample) self.prepareForSampleAnalysis(sampleName) self.calculateParameterUnits(sample) if self.fitting.modelParameterUnits==None: self.fitting.modelParameterUnits = self.parameterUnits self.printSetup() self.x = self.mergeLists(self.XList) self.y = self.mergeLists(self.YList) if self.globalSearch: optimizer1 = PKPDDEOptimizer(self,fitType) optimizer1.optimize() else: self.parameters = np.zeros(len(self.boundsList),np.double) n = 0 for bound in self.boundsList: self.parameters[n] = 0.5*(bound[0]+bound[1]) n += 1 try: optimizer2 = PKPDLSOptimizer(self,fitType) optimizer2.optimize() except Exception as e: msg=str(e) msg+="Errors in the local optimizer may be caused by starting from a bad initial guess\n" msg+="Try performing a global search first or changing the bounding box" raise Exception("Error in the local optimizer\n"+msg) optimizer2.setConfidenceInterval(self.confidenceInterval.get()) self.setParameters(optimizer2.optimum) optimizer2.evaluateQuality() self.yPredictedList=self.separateLists(self.yPredicted) self.yPredictedLowerList=self.separateLists(self.yPredictedLower) self.yPredictedUpperList=self.separateLists(self.yPredictedUpper) n=0 for sampleName in group.sampleList: sample = self.experiment.samples[sampleName] # Keep this result sampleFit = PKPDSampleFit() sampleFit.sampleName = sample.sampleName sampleFit.x = self.XList[n] sampleFit.y = self.YList[n] sampleFit.yp = self.yPredictedList[n] sampleFit.yl = self.yPredictedLowerList[n] sampleFit.yu = self.yPredictedUpperList[n] sampleFit.parameters = self.parameters sampleFit.modelEquation = self.getEquation() sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) # Add the parameters to the sample and experiment for varName, varUnits, description, varValue in izip(self.getParameterNames(), self.parameterUnits, self.getParameterDescriptions(), self.parameters): self.experiment.addParameterToSample(sampleName, varName, varUnits, description, varValue) self.postSampleAnalysis(sampleName) if reportX!=None: print("Evaluation of the model at specified time points") self.model.tF = np.max(reportX) yreportX = self.model.forwardModel(self.model.parameters, reportX) print("==========================================") print("X Ypredicted log10(Ypredicted)") print("==========================================") for n in range(0,reportX.shape[0]): aux = 0 if yreportX[n]>0: aux = math.log10(yreportX[n]) print("%f %f %f"%(reportX[n],yreportX[n],aux)) print(' ') n+=1 self.fitting.modelParameters = self.getParameterNames() self.fitting.modelDescription=self.getDescription() self.fitting.write(self._getPath("fitting.pkpd")) self.experiment.write(self._getPath("experiment.pkpd")) def createOutputStep(self): self._defineOutputs(outputFitting=self.fitting) self._defineOutputs(outputExperiment=self.experiment) self._defineSourceRelation(self.getInputExperiment(), self.fitting) self._defineSourceRelation(self.getInputExperiment(), self.experiment) #--------------------------- INFO functions -------------------------------------------- def _summary(self): msg = [] self.getXYvars() if self.varNameX!=None: msg.append('Predicting %s from %s'%(self.varNameX,self.varNameY)) return msg def _validate(self): self.getXYvars() errors=[] if self.varNameX!=None: experiment = self.readExperiment(self.getInputExperiment().fnPKPD, False) if not self.varNameX in experiment.variables: errors.append("Cannot find %s as variable"%self.varNameX) if type(self.varNameY)==list: for y in self.varNameY: if not y in experiment.variables: errors.append("Cannot find %s as variable"%y) else: if not self.varNameY in experiment.variables: errors.append("Cannot find %s as variable"%self.varNameY) if self.bounds.get()=="": errors.append("Bounds are required") return errors def _citations(self): return ['Spiess2010'] def filterVarForWizard(self, v): """ Define the type of variables required (used in wizard). """ return v.isNumeric() and (v.isTime() or v.isMeasurement())
def runFit(self, objId, deltaT): self.protODE = self.inputODE.get() self.experiment = self.readExperiment( self.protODE.outputExperiment.fnPKPD) self.fitting = self.readFitting(self.protODE.outputFitting.fnFitting) # Get the X and Y variable names self.varNameX = self.fitting.predictor.varName if type(self.fitting.predicted) == list: self.varNameY = [v.varName for v in self.fitting.predicted] else: self.varNameY = self.fitting.predicted.varName self.protODE.experiment = self.experiment self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY # Create output object self.fitting = PKPDFitting() self.fitting.fnExperiment.set(self.experiment.fnPKPD.get()) self.fitting.predictor = self.experiment.variables[self.varNameX] self.fitting.predicted = self.experiment.variables[self.varNameY] self.fitting.modelParameterUnits = None # Actual fitting if self.protODE.fitType.get() == 0: fitType = "linear" elif self.protODE.fitType.get() == 1: fitType = "log" elif self.protODE.fitType.get() == 2: fitType = "relative" parameterNames = None for groupName, group in self.experiment.groups.iteritems(): self.printSection("Fitting " + groupName) self.protODE.clearGroupParameters() self.clearGroupParameters() for sampleName in group.sampleList: print(" Sample " + sampleName) sample = self.experiment.samples[sampleName] self.protODE.createDrugSource() self.protODE.setupModel() # Setup self model self.drugSource = self.protODE.drugSource self.drugSourceList = self.protODE.drugSourceList self.model = self.protODE.model self.modelList = self.protODE.modelList self.model.deltaT = self.deltaT.get() self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) # Get the values to fit x, y = sample.getXYValues(self.varNameX, self.varNameY) print("X= " + str(x)) print("Y= " + str(y)) # Interpret the dose self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY self.protODE.model = self.model self.protODE.setTimeRange(sample) sample.interpretDose() self.drugSource.setDoses(sample.parsedDoseList, self.model.t0, self.model.tF) self.protODE.configureSource(self.drugSource) self.model.drugSource = self.drugSource # Prepare the model self.model.setSample(sample) self.calculateParameterUnits(sample) if self.fitting.modelParameterUnits == None: self.fitting.modelParameterUnits = self.parameterUnits # Get the initial parameters if parameterNames == None: parameterNames = self.getParameterNames() parameters0 = [] for parameterName in parameterNames: parameters0.append(float( sample.descriptors[parameterName])) print("Initial solution: %s" % str(parameters0)) print(" ") # Set bounds self.setBounds(sample) self.setXYValues(x, y) self.parameters = parameters0 self.printSetup() self.x = self.mergeLists(self.XList) self.y = self.mergeLists(self.YList) optimizer2 = PKPDLSOptimizer(self, fitType) optimizer2.optimize() optimizer2.setConfidenceInterval( self.protODE.confidenceInterval.get()) self.setParameters(optimizer2.optimum) n = 0 for sampleName in group.sampleList: sample = self.experiment.samples[sampleName] # Keep this result sampleFit = PKPDSampleFit() sampleFit.sampleName = sample.sampleName sampleFit.x = x sampleFit.y = y sampleFit.yp = self.yPredicted sampleFit.yl = self.yPredictedLower sampleFit.yu = self.yPredictedUpper sampleFit.parameters = self.parameters sampleFit.modelEquation = self.getEquation() sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) # Add the parameters to the sample and experiment for varName, varUnits, description, varValue in izip( self.getParameterNames(), self.parameterUnits, self.getParameterDescriptions(), self.parameters): self.experiment.addParameterToSample( sampleName, varName, varUnits, description, varValue) n += 1 self.fitting.modelParameters = self.getParameterNames() self.fitting.modelDescription = self.getDescription() self.fitting.write(self._getPath("fitting.pkpd")) self.experiment.write(self._getPath("experiment.pkpd"))
def runFit(self, objId, Nbootstrap, confidenceInterval): self.protODE = self.inputODE.get() self.experiment = self.readExperiment(self.protODE.outputExperiment.fnPKPD) self.fitting = self.readFitting(self.protODE.outputFitting.fnFitting) # Get the X and Y variable names self.varNameX = self.fitting.predictor.varName if type(self.fitting.predicted)==list: self.varNameY = [v.varName for v in self.fitting.predicted] else: self.varNameY = self.fitting.predicted.varName self.protODE.experiment = self.experiment self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY # Create output object self.fitting = PKPDFitting("PKPDSampleFitBootstrap") self.fitting.fnExperiment.set(self.experiment.fnPKPD.get()) self.fitting.predictor=self.experiment.variables[self.varNameX] if type(self.varNameY)==list: self.fitting.predicted=[self.experiment.variables[v] for v in self.varNameY] else: self.fitting.predicted=self.experiment.variables[self.varNameY] self.fitting.modelParameterUnits = None # Actual fitting if self.protODE.fitType.get()==0: fitType = "linear" elif self.protODE.fitType.get()==1: fitType = "log" elif self.protODE.fitType.get()==2: fitType = "relative" parameterNames = None for groupName, group in self.experiment.groups.iteritems(): self.printSection("Fitting "+groupName) self.protODE.clearGroupParameters() self.clearGroupParameters() for sampleName in group.sampleList: print(" Sample "+sampleName) sample = self.experiment.samples[sampleName] self.protODE.createDrugSource() self.protODE.setupModel() # Setup self model self.drugSource = self.protODE.drugSource self.drugSourceList = self.protODE.drugSourceList self.model = self.protODE.model self.modelList = self.protODE.modelList self.model.deltaT = self.deltaT.get() self.model.setXVar(self.varNameX) self.model.setYVar(self.varNameY) # Get the values to fit x, y = sample.getXYValues(self.varNameX,self.varNameY) print("X= "+str(x)) print("Y= "+str(y)) firstX=x[0] # From [array(...)] to array(...) firstY=y[0] # From [array(...)] to array(...) # Interpret the dose self.protODE.varNameX = self.varNameX self.protODE.varNameY = self.varNameY self.protODE.model = self.model self.protODE.setTimeRange(sample) sample.interpretDose() self.drugSource.setDoses(sample.parsedDoseList, self.model.t0, self.model.tF) self.protODE.configureSource(self.drugSource) self.model.drugSource = self.drugSource # Prepare the model self.model.setSample(sample) self.calculateParameterUnits(sample) if self.fitting.modelParameterUnits==None: self.fitting.modelParameterUnits = self.parameterUnits # Get the initial parameters if parameterNames==None: parameterNames = self.getParameterNames() parameters0 = [] for parameterName in parameterNames: parameters0.append(float(sample.descriptors[parameterName])) print("Initial solution: %s"%str(parameters0)) print(" ") # Set bounds self.setBounds(sample) # Output object sampleFit = PKPDSampleFitBootstrap() sampleFit.sampleName = sample.sampleName sampleFit.parameters = np.zeros((self.Nbootstrap.get(),len(parameters0)),np.double) sampleFit.xB = [] sampleFit.yB = [] # Bootstrap samples idx = [k for k in range(0,len(firstX))] for n in range(0,self.Nbootstrap.get()): ok = False while not ok: if self.sampleLength.get()>0: lenToUse = self.sampleLength.get() else: lenToUse = len(idx) idxB = sorted(np.random.choice(idx,lenToUse)) xB = [np.asarray([firstX[i] for i in idxB])] yB = [np.asarray([firstY[i] for i in idxB])] print("Bootstrap sample %d"%n) print("X= "+str(xB)) print("Y= "+str(yB)) self.clearXYLists() self.setXYValues(xB, yB) self.parameters = parameters0 optimizer2 = PKPDLSOptimizer(self,fitType) optimizer2.verbose = 0 try: optimizer2.optimize() ok=True except Exception as e: print(e) raise(e) ok=False # Evaluate the quality on the whole data set self.clearXYLists() self.setXYValues(x, y) optimizer2.evaluateQuality() print(optimizer2.optimum) print(" R2 = %f R2Adj=%f AIC=%f AICc=%f BIC=%f"%(optimizer2.R2,optimizer2.R2adj,optimizer2.AIC,\ optimizer2.AICc,optimizer2.BIC)) # Keep this result sampleFit.parameters[n,:] = optimizer2.optimum sampleFit.xB.append(str(xB[0])) sampleFit.yB.append(str(yB[0])) sampleFit.copyFromOptimizer(optimizer2) self.fitting.sampleFits.append(sampleFit) self.fitting.modelParameters = self.getParameterNames() self.fitting.modelDescription = self.getDescription() self.fitting.write(self._getPath("bootstrapPopulation.pkpd"))