Ejemplo n.º 1
0
    def runAdjust(self, targetWeight):
        scaleModel = PKPDAllometricScale()
        scaleModel.load(self.inputAllometric.get().fnScale.get())

        self.population = self.readFitting(self.inputPopulation.get().fnFitting,cls="PKPDSampleFitBootstrap")
        self.experiment = PKPDExperiment()
        self.experiment.load(self.population.fnExperiment.get())

        for sampleFit in self.population.sampleFits:
            sample = self.experiment.samples[sampleFit.sampleName]
            sampleWeight = float(sample.getDescriptorValue(scaleModel.predictor))
            sample.setDescriptorValue(scaleModel.predictor,targetWeight)

            for varName, varUnits in scaleModel.averaged_vars:
                if varName in self.population.modelParameters:
                    idx = self.population.modelParameters.index(varName)
                    targetValue = scaleModel.models[varName][0]
                    sampleFit.parameters[0][idx] = targetValue

            for varName, varUnits in scaleModel.scaled_vars:
                if varName in self.population.modelParameters:
                    idx = self.population.modelParameters.index(varName)
                    k = scaleModel.models[varName][0]
                    a = scaleModel.models[varName][1]
                    targetValue = k*math.pow(targetWeight,a)
                    currentValue = k*math.pow(sampleWeight,a)
                    for j in range(sampleFit.parameters.shape[0]):
                        sampleFit.parameters[j][idx] *= targetValue/currentValue

        self.experiment.write(self._getPath("experiment.pkpd"))
        self.population.fnExperiment.set(self._getPath("experiment.pkpd"))
        self.population.write(self._getPath("bootstrapPopulation.pkpd"))
Ejemplo n.º 2
0
 def readExperiment(self,fnIn, show=True):
     experiment = PKPDExperiment()
     experiment.load(fnIn)
     if show:
         self.printSection("Reading %s"%fnIn)
         experiment._printToStream(sys.stdout)
     return experiment
Ejemplo n.º 3
0
    def _validate(self):
        import re
        errors = []
        if self.prefix1.get() == self.prefix2.get():
            experiment1 = PKPDExperiment()
            experiment1.load(self.inputExperiment1.get().fnPKPD)
            experiment2 = PKPDExperiment()
            experiment2.load(self.inputExperiment2.get().fnPKPD)

            # Check if there are repeated doses
            for doseName1 in experiment1.doses:
                if doseName1 in experiment2.doses:
                    errors.append("Dose %s is repeated in both experiments" %
                                  doseName1)

            # Check if there are repeated samples
            for sampleName1 in experiment1.samples:
                if sampleName1 in experiment2.samples:
                    errors.append("Sample %s is repeated in both experiments" %
                                  sampleName1)
        # if self.prefix1.get()!="" and not re.match("[_A-Za-z][_a-zA-Z0-9]*$",self.prefix1.get()):
        #     errors.append("Prefix1 is not well formatted")
        # if self.prefix2.get()!="" and not re.match("[_A-Za-z][_a-zA-Z0-9]*$",self.prefix2.get()):
        #     errors.append("Prefix2 is not well formatted")
        if len(errors) > 0:
            errors.append("Use the prefixes in the Advanced options")
        return errors
Ejemplo n.º 4
0
 def createOutputStep(self, inputPath):
     localPath = self._getPath(basename(inputPath))
     experiment = PKPDExperiment()
     experiment.load(inputPath, verifyIntegrity=False)
     experiment._printToStream(sys.stdout)
     experiment.write(localPath)
     self._defineOutputs(outputExperiment=experiment)
Ejemplo n.º 5
0
 def setupUnderlyingProtocol(self,prot):
     prot.getXYvars()
     prot.experiment=PKPDExperiment()
     prot.experiment.load(prot.outputExperiment.fnPKPD.get())
     prot.clearGroupParameters()
     prot.createDrugSource()
     prot.setupModel()
     return prot.experiment
Ejemplo n.º 6
0
    def runDrop(self, objId, varsToDrop):
        import copy
        experiment = self.readExperiment(self.inputExperiment.get().fnPKPD)

        self.printSection("Dropping variables")
        varsToDrop = []
        for varName in self.varsToDrop.get().split(','):
            varsToDrop.append(varName.strip())

        filteredExperiment = PKPDExperiment()
        filteredExperiment.general = copy.copy(experiment.general)
        filteredExperiment.variables = {}
        for varName, variable in experiment.variables.iteritems():
            if not varName in varsToDrop:
                filteredExperiment.variables[varName] = copy.copy(variable)
        filteredExperiment.samples = {}
        filteredExperiment.doses = copy.copy(experiment.doses)

        for sampleKey, sample in experiment.samples.iteritems():
            candidateSample = PKPDSample()
            candidateSample.variableDictPtr    = filteredExperiment.variables
            candidateSample.doseDictPtr        = filteredExperiment.doses
            candidateSample.sampleName          = copy.copy(sample.sampleName)
            candidateSample.doseList           = copy.copy(sample.doseList)
            candidateSample.descriptors        = copy.copy(sample.descriptors)
            candidateSample.measurementPattern = []
            for varName in sample.measurementPattern:
                if not varName in varsToDrop:
                    candidateSample.measurementPattern.append(varName)
                    exec("candidateSample.measurement_%s = copy.copy(sample.measurement_%s)"%(varName,varName))
            filteredExperiment.samples[candidateSample.varName] = candidateSample

        self.writeExperiment(filteredExperiment,self._getPath("experiment.pkpd"))
        self.experiment = filteredExperiment
Ejemplo n.º 7
0
 def createOutputStep(self, inputPath):
     localPath = self._getPath(basename(inputPath))
     experiment = PKPDExperiment()
     experiment.load(inputPath, verifyIntegrity=False)
     experiment._printToStream(sys.stdout)
     experiment.write(localPath)
     self._defineOutputs(outputExperiment=experiment)
Ejemplo n.º 8
0
    def runJoin(self, objId1, objId2, prefix1, prefix2):
        experiment1 = self.readExperiment(self.inputExperiment1.get().fnPKPD)
        experiment2 = self.readExperiment(self.inputExperiment2.get().fnPKPD)
        self.printSection("Joining")

        self.experiment = PKPDExperiment()

        # General
        if self.title != None:
            self.experiment.general["title"] = self.title.get()
        if self.comment != None:
            self.experiment.general["comment"] = self.comment.get()
        for key, value in experiment1.general.iteritems():
            if not (key in self.experiment.general):
                self.experiment.general[key] = copy.copy(value)
        for key, value in experiment2.general.iteritems():
            if not (key in self.experiment.general):
                self.experiment.general[key] = copy.copy(value)

        # Variables
        for key, value in experiment1.variables.iteritems():
            if not (key in self.experiment.variables):
                self.experiment.variables[key] = copy.copy(value)
        for key, value in experiment2.variables.iteritems():
            if not (key in self.experiment.variables):
                self.experiment.variables[key] = copy.copy(value)

        # Doses
        for key, value in experiment1.doses.iteritems():
            dose = copy.copy(value)
            dose.varName = "%s%s" % (self.prefix1.get(), key)
            self.experiment.doses[dose.varName] = dose
        for key, value in experiment2.doses.iteritems():
            dose = copy.copy(value)
            dose.varName = "%s%s" % (self.prefix2.get(), key)
            self.experiment.doses[dose.varName] = dose

        # Samples
        for key, value in experiment1.samples.iteritems():
            sample = copy.copy(value)
            sample.sampleName = "%s%s" % (self.prefix1.get(), key)
            sample.doseList = [
                "%s%s" % (self.prefix1.get(), doseName)
                for doseName in sample.doseList
            ]
            self.experiment.samples[sample.sampleName] = sample
        for key, value in experiment2.samples.iteritems():
            sample = copy.copy(value)
            sample.sampleName = "%s%s" % (self.prefix2.get(), key)
            sample.doseList = [
                "%s%s" % (self.prefix2.get(), doseName)
                for doseName in sample.doseList
            ]
            self.experiment.samples[sample.sampleName] = sample

        # Print and save
        self.writeExperiment(self.experiment, self._getPath("experiment.pkpd"))
    def runFilter(self, objId, filterType, condition):
        import copy
        experiment = self.readExperiment(self.inputExperiment.get().fnPKPD)

        self.printSection("Filtering")
        if self.filterType.get()==0:
            filterType="exclude"
        elif self.filterType.get()==1:
            filterType="keep"
        else:
            filterType="rmNA"

        filteredExperiment = PKPDExperiment()
        filteredExperiment.general = copy.copy(experiment.general)
        filteredExperiment.variables = copy.copy(experiment.variables)
        filteredExperiment.samples = {}
        filteredExperiment.doses = {}

        # http://stackoverflow.com/questions/701802/how-do-i-execute-a-string-containing-python-code-in-python
        safe_list = ['descriptors']
        safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
        usedDoses = []
        for sampleKey, sample in experiment.samples.iteritems():
            ok = filterType=="rmNA"
            try:
                if filterType == "rmNA":
                    conditionPython = "True"
                else:
                    conditionPython = copy.copy(condition)
                conditionPython = conditionPython.replace('$(sampleName)','"%s"'%sample.sampleName)
                for key, variable in experiment.variables.iteritems():
                    if key in sample.descriptors:
                        value = sample.descriptors[key]
                        if value=="NA":
                            conditionPython="False"
                        else:
                            if filterType!="rmNA":
                                if variable.varType == PKPDVariable.TYPE_NUMERIC:
                                    conditionPython = conditionPython.replace("$(%s)"%key,"%f"%float(sample.descriptors[key]))
                                else:
                                    conditionPython = conditionPython.replace("$(%s)"%key,"'%s'"%sample.descriptors[key])
                ok=eval(conditionPython, {"__builtins__" : {"True": True, "False": False} }, {})
            except:
                print sys.exc_info()[0]
                pass
            if (ok and (filterType=="keep" or filterType=="rmNA")) or (not ok and filterType=="exclude"):
                filteredExperiment.samples[sampleKey] = copy.copy(sample)
                for doseName in sample.doseList:
                    usedDoses.append(doseName)

        if len(usedDoses)>0:
            for doseName in usedDoses:
                filteredExperiment.doses[doseName] = copy.copy(experiment.doses[doseName])

        self.writeExperiment(filteredExperiment,self._getPath("experiment.pkpd"))
        self.experiment = filteredExperiment
Ejemplo n.º 10
0
 def readExperiment(self, fnIn, show=True):
     experiment = PKPDExperiment()
     experiment.load(fnIn)
     if show:
         self.printSection("Reading %s" % fnIn)
         experiment._printToStream(sys.stdout)
     return experiment
    def _validate(self):
        import re
        errors = []
        if self.prefix1.get()==self.prefix2.get():
            experiment1 = PKPDExperiment()
            experiment1.load(self.inputExperiment1.get().fnPKPD)
            experiment2 = PKPDExperiment()
            experiment2.load(self.inputExperiment2.get().fnPKPD)

            # Check if there are repeated doses
            for doseName1 in experiment1.doses:
                if doseName1 in experiment2.doses:
                    errors.append("Dose %s is repeated in both experiments"%doseName1)

            # Check if there are repeated samples
            for sampleName1 in experiment1.samples:
                if sampleName1 in experiment2.samples:
                    errors.append("Sample %s is repeated in both experiments"%sampleName1)
        # if self.prefix1.get()!="" and not re.match("[_A-Za-z][_a-zA-Z0-9]*$",self.prefix1.get()):
        #     errors.append("Prefix1 is not well formatted")
        # if self.prefix2.get()!="" and not re.match("[_A-Za-z][_a-zA-Z0-9]*$",self.prefix2.get()):
        #     errors.append("Prefix2 is not well formatted")
        if len(errors)>0:
            errors.append("Use the prefixes in the Advanced options")
        return errors
Ejemplo n.º 12
0
    def createOutputStep(self):
        experiment = self.readExperiment(self.inputExperiment.get().fnPKPD)
        newExperiment = PKPDExperiment()

        # General
        newExperiment.general["title"] = self.newTitle.get().strip()
        newExperiment.general["comment"] = self.newComment.get().strip()
        for key, value in experiment.general.iteritems():
            if not (key in newExperiment.general):
                newExperiment.general[key] = copy.copy(value)

        # Variables
        for key, value in experiment.variables.iteritems():
            if not (key in newExperiment.variables):
                newExperiment.variables[key] = copy.copy(value)

        # Doses
        viasSubset = []
        for key, value in experiment.doses.iteritems():
            dose = copy.copy(value)
            newExperiment.doses[dose.doseName] = dose
            viasSubset.append(dose.via.viaName)

        # Vias
        for via in viasSubset:
            newExperiment.vias[via] = experiment.vias[via]

        # Samples and groups
        newExperiment.groups = {}
        for sampleName in self.listOfSamples.get().split(';'):
            sample = copy.copy(experiment.samples[sampleName])
            for groupName, group in experiment.groups.iteritems():
                if sampleName in group.sampleList:
                    if not groupName in newExperiment.groups.keys():
                        newExperiment.groups[groupName] = PKPDGroup(groupName)
                    newExperiment.groups[groupName].sampleList.append(
                        sampleName)
            newExperiment.samples[sample.sampleName] = sample

        self.writeExperiment(newExperiment, self._getPath("experiment.pkpd"))
        self._defineOutputs(outputExperiment=newExperiment)
        self._defineSourceRelation(self.inputExperiment, newExperiment)
    def createOutputStep(self):
        experiment = self.readExperiment(self.inputExperiment.get().fnPKPD)
        newExperiment = PKPDExperiment()

        # General
        newExperiment.general["title"]=self.newTitle.get().strip()
        newExperiment.general["comment"]=self.newComment.get().strip()
        for key, value in experiment.general.iteritems():
            if not (key in newExperiment.general):
                newExperiment.general[key] = copy.copy(value)

        # Variables
        for key, value in experiment.variables.iteritems():
            if not (key in newExperiment.variables):
                newExperiment.variables[key] = copy.copy(value)

        # Doses
        viasSubset = []
        for key, value in experiment.doses.iteritems():
            dose = copy.copy(value)
            newExperiment.doses[dose.doseName] = dose
            viasSubset.append(dose.via.viaName)

        # Vias
        for via in viasSubset:
            newExperiment.vias[via] = experiment.vias[via]

        # Samples and groups
        newExperiment.groups = {}
        for sampleName in self.listOfSamples.get().split(';'):
            sample = copy.copy(experiment.samples[sampleName])
            for groupName, group in experiment.groups.iteritems():
                if sampleName in group.sampleList:
                    if not groupName in newExperiment.groups.keys():
                        newExperiment.groups[groupName]=PKPDGroup(groupName)
                    newExperiment.groups[groupName].sampleList.append(sampleName)
            newExperiment.samples[sample.sampleName] = sample

        self.writeExperiment(newExperiment,self._getPath("experiment.pkpd"))
        self._defineOutputs(outputExperiment=newExperiment)
        self._defineSourceRelation(self.inputExperiment, newExperiment)
Ejemplo n.º 14
0
    def runFit(self, predictor, avgParameters, confidenceInterval):
        self.scaleModel = PKPDAllometricScale()
        self.scaleModel.confidence = float(self.confidenceInterval.get())
        self.scaleModel.predictor = self.predictor.get()

        if self.allometricParameters.get().strip()!="":
            for token in self.allometricParameters.get().split(','):
                self.scaleModel.scaled_vars.append(token.strip())
        if self.avgParameters.get().strip()!="":
            for token in self.avgParameters.get().split(','):
                self.scaleModel.averaged_vars.append(token.strip())

        X=[]
        Y={}
        for varName in self.scaleModel.scaled_vars+self.scaleModel.averaged_vars:
            Y[varName]=[]

        for experimentPtr in self.inputExps:
            # Load experiment
            experiment = PKPDExperiment()
            experiment.load(experimentPtr.get().fnPKPD)

            # Get the first sample
            sample = experiment.samples.values()[0]

            # Extract X
            retval = sample.getDescriptorValue(self.predictor.get())
            if retval:
                X.append(float(retval))
            else:
                raise Exception("Cannot find %s in %s"%(self.predictor.get(),experiment.fnPKPD))

            # Extract Y
            for varName in self.scaleModel.scaled_vars+self.scaleModel.averaged_vars:
                retval = sample.getDescriptorValue(varName)
                if retval:
                    Y[varName].append(float(retval))
                else:
                    raise Exception("Cannot find %s in %s"%(varName,experiment.fnPKPD))

        self.scaleModel.predictorUnits = strUnit(experiment.variables[self.predictor.get()].units.unit)
        varList = []
        for varName in self.scaleModel.scaled_vars:
            varList.append((varName,strUnit(experiment.variables[varName].units.unit)))
        self.scaleModel.scaled_vars = copy.copy(varList)
        varList = []
        for varName in self.scaleModel.averaged_vars:
            varList.append((varName,strUnit(experiment.variables[varName].units.unit)))
        self.scaleModel.averaged_vars = copy.copy(varList)

        print("X: %s"%str(X))
        logx=np.log10(np.asarray(X))
        self.scaleModel.X = X
        self.scaleModel.Y = Y

        fhSummary=open(self._getPath("summary.txt"),"w")
        fhSummary.write("Predictor variable: %s\n"%self.predictor.get())
        fhSummary.write("Parameters to average: %s\n"%self.avgParameters.get())
        fhSummary.write("Confidence interval: %f\n"%self.confidenceInterval.get())
        for varName, varUnits in self.scaleModel.scaled_vars:
            print("%s: %s"%(varName,str(Y[varName])))
            y = np.asarray(Y[varName])
            logy = np.log10(y)

            A=np.ones((logx.size,2))
            A[:,0]=logx.T
            F=np.linalg.inv(np.dot(A.T,A))
            p = np.dot(F,np.dot(A.T,logy.T))
            logyPredicted=np.dot(A,p)
            e=logy-logyPredicted
            sigma2=np.var(e)
            V=sigma2*F

            # We manually implement the regression because np.polyfit has an unbiased estimator of V that
            # does not work well with 4 samples
            # p, V = np.polyfit(logx, logy, 1, cov=True)
            # e = logy - logyPredicted
            R2 = (1 - np.var(e) / np.var(logy))

            from scipy.stats import norm
            nstd = norm.ppf(1-(1-self.scaleModel.confidence/100)/2)
            perr = np.sqrt(np.diag(V))
            lowerBound = p - nstd * perr
            upperBound = p + nstd * perr

            # Back to natural units
            p[1]=math.pow(10.0,p[1])
            lowerBound[1]=math.pow(10.0,lowerBound[1])
            upperBound[1]=math.pow(10.0,upperBound[1])

            self.scaleModel.models[varName] = [p[1],p[0]]
            self.scaleModel.qualifiers[varName] = [R2,lowerBound[1],upperBound[1],lowerBound[0],upperBound[0]]
            self.doublePrint(fhSummary,
                "%s=(%f)*%s^(%f) R2=%f %f%% Confidence intervals (y=k*x^a): k=[%f,%f] a=[%f,%f]; %s" % \
                (varName, p[1], self.predictor, p[0], R2, self.confidenceInterval, lowerBound[1],upperBound[1],lowerBound[0],upperBound[0],
                 varUnits))

        for varName, varUnits in self.scaleModel.averaged_vars:
            print("%s: %s"%(varName,str(Y[varName])))
            y = np.asarray(Y[varName])
            self.scaleModel.models[varName] = [np.mean(y)]
            self.scaleModel.qualifiers[varName] = [np.std(y)]
            self.doublePrint(fhSummary,
                             "%s avg=%f std=%f; %s"%(varName,self.scaleModel.models[varName][0],self.scaleModel.qualifiers[varName][0],varUnits))

        fhSummary.close()
        self.scaleModel.write(self._getPath("allometricScale.pkpd"))
    def runSimulate(self, objId, Nsimulations, confidenceInterval, doses):
        self.protODE = self.inputODE.get()
        if hasattr(self.protODE,"outputExperiment"):
            self.experiment = self.readExperiment(self.protODE.outputExperiment.fnPKPD)
        elif hasattr(self.protODE,"outputExperiment1"):
            self.experiment = self.readExperiment(self.protODE.outputExperiment1.fnPKPD)
        else:
            raise Exception("Cannot find an outputExperiment in the input ODE")
        if self.paramsSource==ProtPKPDODESimulate.PRM_POPULATION:
            self.fitting = self.readFitting(self.inputPopulation.get().fnFitting, cls="PKPDSampleFitBootstrap")
        else:
            if hasattr(self.protODE, "outputFitting"):
                self.fitting = self.readFitting(self.protODE.outputFitting.fnFitting)
            elif hasattr(self.protODE, "outputFitting1"):
                self.fitting = self.readFitting(self.protODE.outputFitting1.fnFitting)
        self.varNameX = self.fitting.predictor.varName
        if type(self.fitting.predicted)!=list:
            self.varNameY = self.fitting.predicted.varName
        else:
            self.varNameY = [var.varName for var in self.fitting.predicted]

        # Create drug source
        self.clearGroupParameters()
        self.createDrugSource()

        # Create output object
        self.outputExperiment = PKPDExperiment()
        tvar = PKPDVariable()
        tvar.varName = "t"
        tvar.varType = PKPDVariable.TYPE_NUMERIC
        tvar.role = PKPDVariable.ROLE_TIME
        tvar.units = createUnit("min")

        self.outputExperiment.variables[self.varNameX] = tvar
        if type(self.fitting.predicted)!=list:
            self.outputExperiment.variables[self.varNameY] = self.experiment.variables[self.varNameY]
        else:
            for varName in self.varNameY:
                self.outputExperiment.variables[varName] = self.experiment.variables[varName]
        self.outputExperiment.general["title"]="Simulated ODE response"
        self.outputExperiment.general["comment"]="Simulated ODE response"
        self.outputExperiment.vias = self.experiment.vias

        # Setup model
        self.model = self.protODE.createModel()
        self.model.setExperiment(self.outputExperiment)
        if hasattr(self.protODE,"deltaT"):
            self.model.deltaT = self.protODE.deltaT.get()
        self.model.setXVar(self.varNameX)
        self.model.setYVar(self.varNameY)
        Nsamples = int(60*math.ceil((self.tF.get()-self.t0.get())/self.model.deltaT))+1
        self.model.x = [self.t0.get()+i*self.model.deltaT for i in range(0,Nsamples)]
        self.modelList.append(self.model)

        # Read the doses
        for line in self.doses.get().replace('\n',';;').split(';;'):
            tokens = line.split(';')
            if len(tokens)<5:
                print("Skipping dose: ",line)
                continue
            dosename = tokens[0].strip()
            self.outputExperiment.doses[dosename] = PKPDDose()
            self.outputExperiment.doses[dosename].parseTokens(tokens,self.experiment.vias)
        auxSample = PKPDSample()
        auxSample.descriptors = {}
        auxSample.doseDictPtr = self.outputExperiment.doses
        auxSample.variableDictPtr = self.outputExperiment.variables
        auxSample.doseList = [dosename]
        auxSample.interpretDose()
        self.drugSource.setDoses(auxSample.parsedDoseList, self.t0.get()-10, self.tF.get()+10)
        self.model.drugSource = self.drugSource

        # Check units
        # Dunits = self.outputExperiment.doses[dosename].dunits
        # Cunits = self.experiment.variables[self.varNameY].units

        # Process user parameters
        if self.paramsSource==ProtPKPDODESimulate.PRM_POPULATION:
            Nsimulations = self.Nsimulations.get()
        else:
            lines = self.prmUser.get().strip().replace('\n',';;').split(';;')
            Nsimulations = len(lines)
            prmUser = []
            for line in lines:
                tokens = line.strip().split(',')
                prmUser.append([float(token) for token in tokens])

        # Simulate the different responses
        simulationsX = self.model.x
        simulationsY = np.zeros((Nsimulations,len(simulationsX),self.getResponseDimension()))
        AUCarray = np.zeros(Nsimulations)
        AUMCarray = np.zeros(Nsimulations)
        MRTarray = np.zeros(Nsimulations)
        CminArray = np.zeros(Nsimulations)
        CmaxArray = np.zeros(Nsimulations)
        CavgArray = np.zeros(Nsimulations)
        fluctuationArray = np.zeros(Nsimulations)
        percentageAccumulationArray = np.zeros(Nsimulations)
        for i in range(0,Nsimulations):
            self.setTimeRange(None)

            if self.paramsSource==ProtPKPDODESimulate.PRM_POPULATION:
                # Take parameters randomly from the population
                nfit = int(random.uniform(0,len(self.fitting.sampleFits)))
                sampleFit = self.fitting.sampleFits[nfit]
                nprm = int(random.uniform(0,sampleFit.parameters.shape[0]))
                parameters = sampleFit.parameters[nprm,:]
            else:
                parameters = np.asarray(prmUser[i],np.double)
            print("Simulated sample %d: %s"%(i,str(parameters)))

            # Prepare source and this object
            self.drugSource.setDoses(auxSample.parsedDoseList, self.model.t0, self.model.tF)
            self.protODE.configureSource(self.drugSource)
            self.model.drugSource = self.drugSource
            parameterNames = self.getParameterNames() # Necessary to count the number of source and PK parameters

            # Prepare the model
            self.setParameters(parameters)
            y = self.forwardModel(parameters, [simulationsX]*self.getResponseDimension())

            # Create AUC, AUMC, MRT variables and units
            if i == 0:
                if type(self.varNameY)!=list:
                    self.Cunits = self.experiment.variables[self.varNameY].units
                else:
                    self.Cunits = self.experiment.variables[self.varNameY[0]].units
                self.AUCunits = multiplyUnits(tvar.units.unit, self.Cunits.unit)
                self.AUMCunits = multiplyUnits(tvar.units.unit, self.AUCunits)

                if self.addStats or self.addIndividuals:
                    AUCvar = PKPDVariable()
                    AUCvar.varName = "AUC0t"
                    AUCvar.varType = PKPDVariable.TYPE_NUMERIC
                    AUCvar.role = PKPDVariable.ROLE_LABEL
                    AUCvar.units = createUnit(strUnit(self.AUCunits))

                    AUMCvar = PKPDVariable()
                    AUMCvar.varName = "AUMC0t"
                    AUMCvar.varType = PKPDVariable.TYPE_NUMERIC
                    AUMCvar.role = PKPDVariable.ROLE_LABEL
                    AUMCvar.units = createUnit(strUnit(self.AUMCunits))

                    MRTvar = PKPDVariable()
                    MRTvar.varName = "MRT"
                    MRTvar.varType = PKPDVariable.TYPE_NUMERIC
                    MRTvar.role = PKPDVariable.ROLE_LABEL
                    MRTvar.units = createUnit("min")

                    self.outputExperiment.variables["AUC0t"] = AUCvar
                    self.outputExperiment.variables["AUMC0t"] = AUMCvar
                    self.outputExperiment.variables["MRT"] = MRTvar

            # Evaluate AUC, AUMC and MRT in the last full period
            self.NCA(self.model.x,y[0])

            # Keep results
            for j in range(self.getResponseDimension()):
                simulationsY[i,:,j] = y[j]
            AUCarray[i] = self.AUC0t
            AUMCarray[i] = self.AUMC0t
            MRTarray[i] = self.MRT
            CminArray[i] = self.Cmin
            CmaxArray[i] = self.Cmax
            CavgArray[i] = self.Cavg
            fluctuationArray[i] = self.fluctuation
            percentageAccumulationArray[i] = self.percentageAccumulation
            if self.addIndividuals or self.paramsSource==ProtPKPDODESimulate.PRM_USER_DEFINED:
                self.addSample("Simulation_%d"%i, dosename, simulationsX, y)

        # Report NCA statistics
        alpha_2 = (100-self.confidenceLevel.get())/2
        limits = np.percentile(AUCarray,[alpha_2,100-alpha_2])
        print("AUC %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.AUCunits),np.mean(AUCarray)))
        limits = np.percentile(AUMCarray,[alpha_2,100-alpha_2])
        print("AUMC %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.AUMCunits),np.mean(AUMCarray)))
        limits = np.percentile(MRTarray,[alpha_2,100-alpha_2])
        print("MRT %f%% confidence interval=[%f,%f] [min] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],np.mean(MRTarray)))
        limits = np.percentile(CminArray,[alpha_2,100-alpha_2])
        print("Cmin %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.Cunits.unit),np.mean(CminArray)))
        limits = np.percentile(CmaxArray,[alpha_2,100-alpha_2])
        print("Cmax %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.Cunits.unit),np.mean(CmaxArray)))
        limits = np.percentile(CavgArray,[alpha_2,100-alpha_2])
        print("Cavg %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.Cunits.unit),np.mean(CavgArray)))
        limits = np.percentile(fluctuationArray,[alpha_2,100-alpha_2])
        print("Fluctuation %f%% confidence interval=[%f,%f] [%%] mean=%f"%(self.confidenceLevel.get(),limits[0]*100,limits[1]*100,np.mean(fluctuationArray)*100))
        limits = np.percentile(percentageAccumulationArray,[alpha_2,100-alpha_2])
        print("Accum(1) %f%% confidence interval=[%f,%f] [%%] mean=%f"%(self.confidenceLevel.get(),limits[0]*100,limits[1]*100,np.mean(percentageAccumulationArray)*100))

        # Calculate statistics
        if self.addStats:
            if self.paramsSource!=ProtPKPDODESimulate.PRM_USER_DEFINED:
                limits = np.percentile(simulationsY,[alpha_2,100-alpha_2],axis=0)

                print("Lower limit NCA")
                self.NCA(simulationsX,limits[0])
                self.addSample("LowerLimit", dosename, simulationsX, limits[0])

            print("Mean profile NCA")
            if self.getResponseDimension()==1:
                mu = np.mean(simulationsY,axis=0)
                self.NCA(simulationsX, mu)
            else:
                mu = []
                for j in range(self.getResponseDimension()):
                    mu.append(np.mean(simulationsY[:,:,j],axis=0))
                self.NCA(simulationsX,mu[0])
            self.addSample("Mean", dosename, simulationsX, mu)

            if self.paramsSource!=ProtPKPDODESimulate.PRM_USER_DEFINED:
                print("Upper limit NCA")
                self.NCA(simulationsX,limits[1])
                self.addSample("UpperLimit", dosename, simulationsX, limits[1])

        self.outputExperiment.write(self._getPath("experiment.pkpd"))
Ejemplo n.º 16
0
    def runSimulate(self, objId, Nsimulations, confidenceInterval, doses):
        self.protODE = self.inputODE.get()
        if hasattr(self.protODE, "outputExperiment"):
            self.experiment = self.readExperiment(
                self.protODE.outputExperiment.fnPKPD)
        elif hasattr(self.protODE, "outputExperiment1"):
            self.experiment = self.readExperiment(
                self.protODE.outputExperiment1.fnPKPD)
        else:
            raise Exception("Cannot find an outputExperiment in the input ODE")
        if self.paramsSource == ProtPKPDODESimulate.PRM_POPULATION:
            self.fitting = self.readFitting(
                self.inputPopulation.get().fnFitting,
                cls="PKPDSampleFitBootstrap")
        else:
            if hasattr(self.protODE, "outputFitting"):
                self.fitting = self.readFitting(
                    self.protODE.outputFitting.fnFitting)
            elif hasattr(self.protODE, "outputFitting1"):
                self.fitting = self.readFitting(
                    self.protODE.outputFitting1.fnFitting)
        self.varNameX = self.fitting.predictor.varName
        if type(self.fitting.predicted) != list:
            self.varNameY = self.fitting.predicted.varName
        else:
            self.varNameY = [var.varName for var in self.fitting.predicted]

        # Create drug source
        self.clearGroupParameters()
        self.createDrugSource()

        # Create output object
        self.outputExperiment = PKPDExperiment()
        tvar = PKPDVariable()
        tvar.varName = "t"
        tvar.varType = PKPDVariable.TYPE_NUMERIC
        tvar.role = PKPDVariable.ROLE_TIME
        tvar.units = createUnit("min")

        self.outputExperiment.variables[self.varNameX] = tvar
        if type(self.fitting.predicted) != list:
            self.outputExperiment.variables[
                self.varNameY] = self.experiment.variables[self.varNameY]
        else:
            for varName in self.varNameY:
                self.outputExperiment.variables[
                    varName] = self.experiment.variables[varName]
        self.outputExperiment.general["title"] = "Simulated ODE response"
        self.outputExperiment.general["comment"] = "Simulated ODE response"
        self.outputExperiment.vias = self.experiment.vias

        # Setup model
        self.model = self.protODE.createModel()
        self.model.setExperiment(self.outputExperiment)
        if hasattr(self.protODE, "deltaT"):
            self.model.deltaT = self.protODE.deltaT.get()
        self.model.setXVar(self.varNameX)
        self.model.setYVar(self.varNameY)
        Nsamples = int(60 * math.ceil(
            (self.tF.get() - self.t0.get()) / self.model.deltaT)) + 1
        self.model.x = [
            self.t0.get() + i * self.model.deltaT for i in range(0, Nsamples)
        ]
        self.modelList.append(self.model)

        # Read the doses
        for line in self.doses.get().replace('\n', ';;').split(';;'):
            tokens = line.split(';')
            if len(tokens) < 5:
                print("Skipping dose: ", line)
                continue
            dosename = tokens[0].strip()
            self.outputExperiment.doses[dosename] = PKPDDose()
            self.outputExperiment.doses[dosename].parseTokens(
                tokens, self.experiment.vias)
        auxSample = PKPDSample()
        auxSample.descriptors = {}
        auxSample.doseDictPtr = self.outputExperiment.doses
        auxSample.variableDictPtr = self.outputExperiment.variables
        auxSample.doseList = [dosename]
        auxSample.interpretDose()
        self.drugSource.setDoses(auxSample.parsedDoseList,
                                 self.t0.get() - 10,
                                 self.tF.get() + 10)
        self.model.drugSource = self.drugSource

        # Check units
        # Dunits = self.outputExperiment.doses[dosename].dunits
        # Cunits = self.experiment.variables[self.varNameY].units

        # Process user parameters
        if self.paramsSource == ProtPKPDODESimulate.PRM_POPULATION:
            Nsimulations = self.Nsimulations.get()
        else:
            lines = self.prmUser.get().strip().replace('\n', ';;').split(';;')
            Nsimulations = len(lines)
            prmUser = []
            for line in lines:
                tokens = line.strip().split(',')
                prmUser.append([float(token) for token in tokens])

        # Simulate the different responses
        simulationsX = self.model.x
        simulationsY = np.zeros(
            (Nsimulations, len(simulationsX), self.getResponseDimension()))
        AUCarray = np.zeros(Nsimulations)
        AUMCarray = np.zeros(Nsimulations)
        MRTarray = np.zeros(Nsimulations)
        CminArray = np.zeros(Nsimulations)
        CmaxArray = np.zeros(Nsimulations)
        CavgArray = np.zeros(Nsimulations)
        fluctuationArray = np.zeros(Nsimulations)
        percentageAccumulationArray = np.zeros(Nsimulations)
        for i in range(0, Nsimulations):
            self.setTimeRange(None)

            if self.paramsSource == ProtPKPDODESimulate.PRM_POPULATION:
                # Take parameters randomly from the population
                nfit = int(random.uniform(0, len(self.fitting.sampleFits)))
                sampleFit = self.fitting.sampleFits[nfit]
                nprm = int(random.uniform(0, sampleFit.parameters.shape[0]))
                parameters = sampleFit.parameters[nprm, :]
            else:
                parameters = np.asarray(prmUser[i], np.double)
            print("Simulated sample %d: %s" % (i, str(parameters)))

            # Prepare source and this object
            self.drugSource.setDoses(auxSample.parsedDoseList, self.model.t0,
                                     self.model.tF)
            self.protODE.configureSource(self.drugSource)
            self.model.drugSource = self.drugSource
            parameterNames = self.getParameterNames(
            )  # Necessary to count the number of source and PK parameters

            # Prepare the model
            self.setParameters(parameters)
            y = self.forwardModel(parameters,
                                  [simulationsX] * self.getResponseDimension())

            # Create AUC, AUMC, MRT variables and units
            if i == 0:
                if type(self.varNameY) != list:
                    self.Cunits = self.experiment.variables[
                        self.varNameY].units
                else:
                    self.Cunits = self.experiment.variables[
                        self.varNameY[0]].units
                self.AUCunits = multiplyUnits(tvar.units.unit,
                                              self.Cunits.unit)
                self.AUMCunits = multiplyUnits(tvar.units.unit, self.AUCunits)

                if self.addStats or self.addIndividuals:
                    AUCvar = PKPDVariable()
                    AUCvar.varName = "AUC0t"
                    AUCvar.varType = PKPDVariable.TYPE_NUMERIC
                    AUCvar.role = PKPDVariable.ROLE_LABEL
                    AUCvar.units = createUnit(strUnit(self.AUCunits))

                    AUMCvar = PKPDVariable()
                    AUMCvar.varName = "AUMC0t"
                    AUMCvar.varType = PKPDVariable.TYPE_NUMERIC
                    AUMCvar.role = PKPDVariable.ROLE_LABEL
                    AUMCvar.units = createUnit(strUnit(self.AUMCunits))

                    MRTvar = PKPDVariable()
                    MRTvar.varName = "MRT"
                    MRTvar.varType = PKPDVariable.TYPE_NUMERIC
                    MRTvar.role = PKPDVariable.ROLE_LABEL
                    MRTvar.units = createUnit("min")

                    self.outputExperiment.variables["AUC0t"] = AUCvar
                    self.outputExperiment.variables["AUMC0t"] = AUMCvar
                    self.outputExperiment.variables["MRT"] = MRTvar

            # Evaluate AUC, AUMC and MRT in the last full period
            self.NCA(self.model.x, y[0])

            # Keep results
            for j in range(self.getResponseDimension()):
                simulationsY[i, :, j] = y[j]
            AUCarray[i] = self.AUC0t
            AUMCarray[i] = self.AUMC0t
            MRTarray[i] = self.MRT
            CminArray[i] = self.Cmin
            CmaxArray[i] = self.Cmax
            CavgArray[i] = self.Cavg
            fluctuationArray[i] = self.fluctuation
            percentageAccumulationArray[i] = self.percentageAccumulation
            if self.addIndividuals or self.paramsSource == ProtPKPDODESimulate.PRM_USER_DEFINED:
                self.addSample("Simulation_%d" % i, dosename, simulationsX, y)

        # Report NCA statistics
        alpha_2 = (100 - self.confidenceLevel.get()) / 2
        limits = np.percentile(AUCarray, [alpha_2, 100 - alpha_2])
        print("AUC %f%% confidence interval=[%f,%f] [%s] mean=%f" %
              (self.confidenceLevel.get(), limits[0], limits[1],
               strUnit(self.AUCunits), np.mean(AUCarray)))
        limits = np.percentile(AUMCarray, [alpha_2, 100 - alpha_2])
        print("AUMC %f%% confidence interval=[%f,%f] [%s] mean=%f" %
              (self.confidenceLevel.get(), limits[0], limits[1],
               strUnit(self.AUMCunits), np.mean(AUMCarray)))
        limits = np.percentile(MRTarray, [alpha_2, 100 - alpha_2])
        print("MRT %f%% confidence interval=[%f,%f] [min] mean=%f" %
              (self.confidenceLevel.get(), limits[0], limits[1],
               np.mean(MRTarray)))
        limits = np.percentile(CminArray, [alpha_2, 100 - alpha_2])
        print("Cmin %f%% confidence interval=[%f,%f] [%s] mean=%f" %
              (self.confidenceLevel.get(), limits[0], limits[1],
               strUnit(self.Cunits.unit), np.mean(CminArray)))
        limits = np.percentile(CmaxArray, [alpha_2, 100 - alpha_2])
        print("Cmax %f%% confidence interval=[%f,%f] [%s] mean=%f" %
              (self.confidenceLevel.get(), limits[0], limits[1],
               strUnit(self.Cunits.unit), np.mean(CmaxArray)))
        limits = np.percentile(CavgArray, [alpha_2, 100 - alpha_2])
        print("Cavg %f%% confidence interval=[%f,%f] [%s] mean=%f" %
              (self.confidenceLevel.get(), limits[0], limits[1],
               strUnit(self.Cunits.unit), np.mean(CavgArray)))
        limits = np.percentile(fluctuationArray, [alpha_2, 100 - alpha_2])
        print("Fluctuation %f%% confidence interval=[%f,%f] [%%] mean=%f" %
              (self.confidenceLevel.get(), limits[0] * 100, limits[1] * 100,
               np.mean(fluctuationArray) * 100))
        limits = np.percentile(percentageAccumulationArray,
                               [alpha_2, 100 - alpha_2])
        print("Accum(1) %f%% confidence interval=[%f,%f] [%%] mean=%f" %
              (self.confidenceLevel.get(), limits[0] * 100, limits[1] * 100,
               np.mean(percentageAccumulationArray) * 100))

        # Calculate statistics
        if self.addStats:
            if self.paramsSource != ProtPKPDODESimulate.PRM_USER_DEFINED:
                limits = np.percentile(simulationsY, [alpha_2, 100 - alpha_2],
                                       axis=0)

                print("Lower limit NCA")
                self.NCA(simulationsX, limits[0])
                self.addSample("LowerLimit", dosename, simulationsX, limits[0])

            print("Mean profile NCA")
            if self.getResponseDimension() == 1:
                mu = np.mean(simulationsY, axis=0)
                self.NCA(simulationsX, mu)
            else:
                mu = []
                for j in range(self.getResponseDimension()):
                    mu.append(np.mean(simulationsY[:, :, j], axis=0))
                self.NCA(simulationsX, mu[0])
            self.addSample("Mean", dosename, simulationsX, mu)

            if self.paramsSource != ProtPKPDODESimulate.PRM_USER_DEFINED:
                print("Upper limit NCA")
                self.NCA(simulationsX, limits[1])
                self.addSample("UpperLimit", dosename, simulationsX, limits[1])

        self.outputExperiment.write(self._getPath("experiment.pkpd"))
class ProtPKPDImportFromText(ProtPKPD):
    #--------------------------- DEFINE param functions --------------------------------------------

    def _defineParams(self, form, type):
        form.addSection('Input')
        inputFileHelp = "Specify a path to desired %s file.\n"%type
        inputFileHelp += "You may specify missing values with NA. You may also use LLOQ and ULOQ (Lower and Upper limit of quantification)\n"
        inputFileHelp += "to specify measurements that are below or above these limits"
        if type=="CSV":
            inputFileHelp += "The field separator must be a semicolon (;), decimal point must be a dot (.).\n"
            inputFileHelp += "The first row must contain the variable names and one of them must be SampleName which will serve as identifier."
        form.addParam('inputFile', params.PathParam,
                      label="File path", allowsNull=False, help=inputFileHelp)
        form.addParam('title', params.StringParam, label="Title", default="My experiment")
        form.addParam('comment', params.StringParam, label="Comment", default="")
        form.addParam('variables', params.TextParam, height=8, width=80, label="Variables", default="",
                      help="Structure: [Variable Name] ; [Units] ; [Type] ; [Role] ; [Comment]\n"\
                           "The variable name should have no space or special character\n"\
                           "Valid units are: h, mg, ug, ug/mL, ...\n"\
                           "Type is either numeric or text\n"\
                           "Role is either time, label or measurement\n"\
                           "The comment may be empty\n"\
                           "\nIt is important that there are three semicolons (none of them may be missing even if the comment is not present).\n"\
                           "Examples:\n"\
                           "t ; h ; numeric ; time ; \n"\
                           "Cp ; ug/mL ; numeric ; measurement ; plasma concentration\n"\
                           "weight ; g ; numeric; label ; weight of the animal\n"\
                           "sex ; none ; text ; label ; sex of the animal\n")
        form.addParam('vias', params.TextParam, height=8, width=80, label="Vias",
                      help="[ViaName]; [ViaType]; [tlag]; [bioavailability]"\
                       "Valid ViaTypes are: iv (intravenous), ev0 (extra-vascular order 0), ev1 (extra-vascular order 1), \n"\
                       "     ev01 (extra-vascular first order 0 and then order 1), evFractional (extra-vascular fractional order)\n"\
                       "Optional parameters are tlag (e.g. tlag=0)\n"\
                       "   and bioavailability (e.g. bioavailability=0.8)\n"\
                       "Examples:\n"\
                       "Intravenous; iv\n"\
                       "Oral; ev1; tlag; bioavailability=1\n")
        addDoseToForm(form)
        form.addParam('dosesToSamples', params.TextParam, height=5, width=70, label="Assign doses to samples", default="",
                      help="Structure: [Sample Name] ; [DoseName1,DoseName2,...] \n"\
                           "The sample name should have no space or special character\n"\
                           "\nIt is important that there is one semicolon.\n"\
                           "Examples:\n"\
                           "FemaleRat1 ; Bolus0,Bolus1,Infusion0\n")


    #--------------------------- INSERT steps functions --------------------------------------------

    def _insertAllSteps(self):
        self._insertFunctionStep('createOutputStep',self.inputFile.get())

    #--------------------------- STEPS functions --------------------------------------------
    def readTextFile(self):
        pass

    def createOutputStep(self, objId):
        fnFile = os.path.basename(self.inputFile.get())
        copyFile(self.inputFile.get(),self._getPath(fnFile))

        self.experiment = PKPDExperiment()
        self.experiment.general["title"]=self.title.get()
        self.experiment.general["comment"]=self.comment.get()

        ok = True

        # Read the variables
        self.listOfVariables = []
        for line in self.variables.get().replace('\n',';;').split(';;'):
            tokens = line.split(';')
            if len(tokens)!=5:
                print("Skipping variable: ",line)
                ok = False
                continue
            varname = tokens[0].strip()
            self.listOfVariables.append(varname)
            self.experiment.variables[varname] = PKPDVariable()
            self.experiment.variables[varname].parseTokens(tokens)

        # Read vias
        for line in self.vias.get().replace('\n',';;').split(';;'):
            if line!="":
                tokens = line.split(';')
                if len(tokens)<2:
                    print("Skipping via: ",line)
                    ok = False
                    continue
                vianame = tokens[0].strip()
                self.experiment.vias[vianame] = PKPDVia()
                self.experiment.vias[vianame].parseTokens(tokens)

        # Read the doses
        for line in self.doses.get().replace('\n',';;').split(';;'):
            if line!="":
                tokens = line.split(';')
                if len(tokens)<5:
                    print("Skipping dose: ",line)
                    ok = False
                    continue
                dosename = tokens[0].strip()
                self.experiment.doses[dosename] = PKPDDose()
                self.experiment.doses[dosename].parseTokens(tokens,self.experiment.vias)

        # Read the sample doses
        for line in self.dosesToSamples.get().replace('\n',';;').split(';;'):
            try:
                tokens = line.split(';')
                samplename = tokens[0].strip()
                if len(tokens)>1:
                    tokens[1]="dose="+tokens[1]
                self.experiment.samples[samplename] = PKPDSample()
                self.experiment.samples[samplename].parseTokens(tokens, self.experiment.variables, self.experiment.doses,
                                                                self.experiment.groups)
            except Exception as e:
                ok = False
                print("Problem with line: ",line,str(e))

        if ok:
            # Read the measurements
            self.readTextFile()
            self.experiment.write(self._getPath("experiment.pkpd"))
            self.experiment._printToStream(sys.stdout)
            self._defineOutputs(outputExperiment=self.experiment)

    #--------------------------- INFO functions --------------------------------------------
    def _summary(self):
        return ["Input file: %s"%self.inputFile.get()]
class ProtPKPDODESimulate(ProtPKPDODEBase):
    """ Simulate a population of ODE parameters.
    These parameters can be specifically given or from a bootstrap population"""

    _label = 'PK simulate'

    PRM_POPULATION = 0
    PRM_USER_DEFINED = 1

    #--------------------------- DEFINE param functions --------------------------------------------
    def _defineParams(self, form):
        form.addSection('Input')
        form.addParam('inputODE', params.PointerParam, label="Input ODE model",
                      pointerClass='ProtPKPDMonoCompartment, ProtPKPDTwoCompartments, ProtPKPDMonoCompartmentPD, ProtPKPDTwoCompartmentsBothPD', help='Select a run of an ODE model')
        form.addParam('paramsSource', params.EnumParam, label="Source of parameters", choices=['ODE Bootstrap','User defined'], default=0,
                      help="Choose a population of parameters or your own")
        form.addParam('inputPopulation', params.PointerParam, label="Input population", condition="paramsSource==0",
                      pointerClass='PKPDFitting', pointerCondition="isPopulation", help='It must be a fitting coming from a bootstrap sample')
        form.addParam('prmUser', params.TextParam, label="Simulation parameters", height=8, default="", condition="paramsSource==1",
                      help='Specify the parameters for the simulation. The parameters must be written in the same order as they are written by the protocol '
                           'that generated the ODE model. Example: \n'
                           'prm1, prm2, prm3, prm4\n'
                           'prmA, prmB, prmC, prmD')
        form.addParam('doses', params.TextParam, label="Doses", height=5, width=50,
                      default="RepeatedBolus ; via=Oral; repeated_bolus; t=0:24:120 h; d=60 mg",
                      help="Structure: [Dose Name] ; [Via] ; [Dose type] ; [time] ; [dose] \n"\
                           "The dose name should have no space or special character\n"\
                           "The via should be one present in the input experiment to the ODE model.\n"\
                           "Valid units are: h, mg, ug, ...\n"\
                           "The description is either a bolus or an infusion as shown in the examples\n"\
                           "\nIt is important that there are two semicolons.\n"\
                           "Examples:\n"\
                           "Infusion0; via=Intravenous; infusion; t=0.500000...0.750000 h; d=60 mg\n"\
                           "Bolus0; via=Oral; bolus; t=0.000000 min; d=60 mg\n"\
                           "RepeatedBolus; via=Oral; repeated_bolus; t=0:24:120 h; d=60 mg")
        form.addParam('t0', params.FloatParam, label="Initial time (h)", default=0)
        form.addParam('tF', params.FloatParam, label="Final time (h)", default=24*7)
        form.addParam('Nsimulations', params.IntParam, label="Simulation samples", default=200, condition="paramsSource==0", expertLevel=LEVEL_ADVANCED,
                      help='Number of simulations')
        form.addParam('addStats', params.BooleanParam, label="Add simulation statistics", default=True, condition="paramsSource==0", expertLevel=LEVEL_ADVANCED,
                      help="Mean, lower and upper confidence levels are added to the output")
        form.addParam('confidenceLevel', params.FloatParam, label="Confidence interval", default=95, expertLevel=LEVEL_ADVANCED,
                      help='Confidence interval for the fitted parameters', condition="addStats and paramsSource==0")
        form.addParam('addIndividuals', params.BooleanParam, label="Add individual simulations", default=False, condition="paramsSource==0", expertLevel=LEVEL_ADVANCED,
                      help="Individual simulations are added to the output")

    #--------------------------- INSERT steps functions --------------------------------------------
    def _insertAllSteps(self):
        self._insertFunctionStep('runSimulate',self.inputODE.get().getObjId(), self.Nsimulations.get(),
                                 self.confidenceLevel.get(), self.doses.get())
        self._insertFunctionStep('createOutputStep')

    #--------------------------- STEPS functions --------------------------------------------
    def addSample(self, sampleName, doseName, simulationsX, y):
        newSample = PKPDSample()
        newSample.sampleName = sampleName
        newSample.variableDictPtr = self.outputExperiment.variables
        newSample.doseDictPtr = self.outputExperiment.doses
        newSample.descriptors = {}
        newSample.doseList = [doseName]
        if type(self.varNameY)!=list:
            newSample.addMeasurementPattern([self.varNameY])
            newSample.addMeasurementColumn("t", simulationsX)
            newSample.addMeasurementColumn(self.varNameY,y)
        else:
            for j in range(len(self.varNameY)):
                newSample.addMeasurementPattern([self.varNameY[j]])
            newSample.addMeasurementColumn("t", simulationsX)
            for j in range(len(self.varNameY)):
                newSample.addMeasurementColumn(self.varNameY[j], y[j])
        newSample.descriptors["AUC0t"] = self.AUC0t
        newSample.descriptors["AUMC0t"] = self.AUMC0t
        newSample.descriptors["MRT"] = self.MRT
        self.outputExperiment.samples[sampleName] = newSample

    def NCA(self,t,C):
        AUClist = []
        AUMClist = []
        Cminlist = []
        Cavglist = []
        Cmaxlist = []
        Tmaxlist = []
        Tminlist = []
        Ndoses=len(self.drugSource.parsedDoseList)
        for ndose in range(0,max(Ndoses-1,1)):
            tperiod0 = self.drugSource.parsedDoseList[ndose].t0
            if ndose+1<Ndoses:
                tperiodF = self.drugSource.parsedDoseList[ndose+1].t0-self.model.deltaT
            else:
                tperiodF =  np.max(t)-1
            idx0 = find_nearest(t,tperiod0)
            idxF = find_nearest(t,tperiodF)

            AUC0t = 0
            AUMC0t = 0
            t0 = t[idx0+1]
            for idx in range(idx0,idxF+1):
                dt = (t[idx+1]-t[idx])
                if C[idx+1]>=C[idx]: # Trapezoidal in the raise
                    AUC0t  += 0.5*dt*(C[idx]+C[idx+1])
                    AUMC0t += 0.5*dt*(C[idx]*t[idx]+C[idx+1]*t[idx+1])
                else: # Log-trapezoidal in the decay
                    decrement = C[idx]/C[idx+1]
                    K = math.log(decrement)
                    B = K/dt
                    AUC0t  += dt*(C[idx]-C[idx+1])/K
                    AUMC0t += (C[idx]*(t[idx]-tperiod0)-C[idx+1]*(t[idx+1]-tperiod0))/B-(C[idx+1]-C[idx])/(B*B)

                if idx==idx0:
                    Cmax=C[idx]
                    Tmax=t[idx]-t0
                    Cmin=C[idx]
                    Tmin=t[idx]-t0
                else:
                    if C[idx]<Cmin:
                        Cmin=C[idx]
                        Tmin=t[idx]-t0
                    elif C[idx]>Cmax:
                        Cmax=C[idx]
                        Tmax=t[idx]-t0
                        if ndose==0:
                            Cmin=C[idx]
                            Tmin=t[idx]-t0
            AUClist.append(AUC0t)
            AUMClist.append(AUMC0t)
            Cminlist.append(Cmin)
            Cmaxlist.append(Cmax)
            Tmaxlist.append(Tmax)
            Tminlist.append(Tmin)
            Cavglist.append(AUC0t/(t[idxF]-t[idx0]))

        print("Fluctuation = Cmax/Cmin")
        print("Accumulation(1) = Cavg(n)/Cavg(1) %")
        print("Accumulation(n) = Cavg(n)/Cavg(n-1) %")
        print("Steady state fraction(n) = Cavg(n)/Cavg(last) %")
        for ndose in range(0,len(AUClist)):
            fluctuation = Cmaxlist[ndose]/Cminlist[ndose]
            if ndose>0:
                accumn = Cavglist[ndose]/Cavglist[ndose-1]
            else:
                accumn = 0
            print("Dose #%d: Cavg= %f [%s] Cmin= %f [%s] Tmin= %d [min] Cmax= %f [%s] Tmax= %d [min] Fluct= %f %% Accum(1)= %f %% Accum(n)= %f %% SSFrac(n)= %f %% AUC= %f [%s] AUMC= %f [%s]"%\
                  (ndose+1,Cavglist[ndose], strUnit(self.Cunits.unit), Cminlist[ndose],strUnit(self.Cunits.unit), int(Tminlist[ndose]), Cmaxlist[ndose], strUnit(self.Cunits.unit),
                   int(Tmaxlist[ndose]), fluctuation*100, Cavglist[ndose]/Cavglist[0]*100, accumn*100, Cavglist[ndose]/Cavglist[-1]*100, AUClist[ndose],strUnit(self.AUCunits),
                   AUMClist[ndose],strUnit(self.AUMCunits)))

        self.AUC0t = AUClist[-1]
        self.AUMC0t = AUMClist[-1]
        self.MRT = self.AUMC0t/self.AUC0t
        self.Cmin = Cminlist[-1]
        self.Cmax = Cmaxlist[-1]
        self.Cavg = Cavglist[-1]
        self.fluctuation = self.Cmax/self.Cmin
        self.percentageAccumulation = Cavglist[-1]/Cavglist[0]

        print("   AUC0t=%f [%s]"%(self.AUC0t,strUnit(self.AUCunits)))
        print("   AUMC0t=%f [%s]"%(self.AUMC0t,strUnit(self.AUMCunits)))
        print("   MRT=%f [min]"%self.MRT)

    def runSimulate(self, objId, Nsimulations, confidenceInterval, doses):
        self.protODE = self.inputODE.get()
        if hasattr(self.protODE,"outputExperiment"):
            self.experiment = self.readExperiment(self.protODE.outputExperiment.fnPKPD)
        elif hasattr(self.protODE,"outputExperiment1"):
            self.experiment = self.readExperiment(self.protODE.outputExperiment1.fnPKPD)
        else:
            raise Exception("Cannot find an outputExperiment in the input ODE")
        if self.paramsSource==ProtPKPDODESimulate.PRM_POPULATION:
            self.fitting = self.readFitting(self.inputPopulation.get().fnFitting, cls="PKPDSampleFitBootstrap")
        else:
            if hasattr(self.protODE, "outputFitting"):
                self.fitting = self.readFitting(self.protODE.outputFitting.fnFitting)
            elif hasattr(self.protODE, "outputFitting1"):
                self.fitting = self.readFitting(self.protODE.outputFitting1.fnFitting)
        self.varNameX = self.fitting.predictor.varName
        if type(self.fitting.predicted)!=list:
            self.varNameY = self.fitting.predicted.varName
        else:
            self.varNameY = [var.varName for var in self.fitting.predicted]

        # Create drug source
        self.clearGroupParameters()
        self.createDrugSource()

        # Create output object
        self.outputExperiment = PKPDExperiment()
        tvar = PKPDVariable()
        tvar.varName = "t"
        tvar.varType = PKPDVariable.TYPE_NUMERIC
        tvar.role = PKPDVariable.ROLE_TIME
        tvar.units = createUnit("min")

        self.outputExperiment.variables[self.varNameX] = tvar
        if type(self.fitting.predicted)!=list:
            self.outputExperiment.variables[self.varNameY] = self.experiment.variables[self.varNameY]
        else:
            for varName in self.varNameY:
                self.outputExperiment.variables[varName] = self.experiment.variables[varName]
        self.outputExperiment.general["title"]="Simulated ODE response"
        self.outputExperiment.general["comment"]="Simulated ODE response"
        self.outputExperiment.vias = self.experiment.vias

        # Setup model
        self.model = self.protODE.createModel()
        self.model.setExperiment(self.outputExperiment)
        if hasattr(self.protODE,"deltaT"):
            self.model.deltaT = self.protODE.deltaT.get()
        self.model.setXVar(self.varNameX)
        self.model.setYVar(self.varNameY)
        Nsamples = int(60*math.ceil((self.tF.get()-self.t0.get())/self.model.deltaT))+1
        self.model.x = [self.t0.get()+i*self.model.deltaT for i in range(0,Nsamples)]
        self.modelList.append(self.model)

        # Read the doses
        for line in self.doses.get().replace('\n',';;').split(';;'):
            tokens = line.split(';')
            if len(tokens)<5:
                print("Skipping dose: ",line)
                continue
            dosename = tokens[0].strip()
            self.outputExperiment.doses[dosename] = PKPDDose()
            self.outputExperiment.doses[dosename].parseTokens(tokens,self.experiment.vias)
        auxSample = PKPDSample()
        auxSample.descriptors = {}
        auxSample.doseDictPtr = self.outputExperiment.doses
        auxSample.variableDictPtr = self.outputExperiment.variables
        auxSample.doseList = [dosename]
        auxSample.interpretDose()
        self.drugSource.setDoses(auxSample.parsedDoseList, self.t0.get()-10, self.tF.get()+10)
        self.model.drugSource = self.drugSource

        # Check units
        # Dunits = self.outputExperiment.doses[dosename].dunits
        # Cunits = self.experiment.variables[self.varNameY].units

        # Process user parameters
        if self.paramsSource==ProtPKPDODESimulate.PRM_POPULATION:
            Nsimulations = self.Nsimulations.get()
        else:
            lines = self.prmUser.get().strip().replace('\n',';;').split(';;')
            Nsimulations = len(lines)
            prmUser = []
            for line in lines:
                tokens = line.strip().split(',')
                prmUser.append([float(token) for token in tokens])

        # Simulate the different responses
        simulationsX = self.model.x
        simulationsY = np.zeros((Nsimulations,len(simulationsX),self.getResponseDimension()))
        AUCarray = np.zeros(Nsimulations)
        AUMCarray = np.zeros(Nsimulations)
        MRTarray = np.zeros(Nsimulations)
        CminArray = np.zeros(Nsimulations)
        CmaxArray = np.zeros(Nsimulations)
        CavgArray = np.zeros(Nsimulations)
        fluctuationArray = np.zeros(Nsimulations)
        percentageAccumulationArray = np.zeros(Nsimulations)
        for i in range(0,Nsimulations):
            self.setTimeRange(None)

            if self.paramsSource==ProtPKPDODESimulate.PRM_POPULATION:
                # Take parameters randomly from the population
                nfit = int(random.uniform(0,len(self.fitting.sampleFits)))
                sampleFit = self.fitting.sampleFits[nfit]
                nprm = int(random.uniform(0,sampleFit.parameters.shape[0]))
                parameters = sampleFit.parameters[nprm,:]
            else:
                parameters = np.asarray(prmUser[i],np.double)
            print("Simulated sample %d: %s"%(i,str(parameters)))

            # Prepare source and this object
            self.drugSource.setDoses(auxSample.parsedDoseList, self.model.t0, self.model.tF)
            self.protODE.configureSource(self.drugSource)
            self.model.drugSource = self.drugSource
            parameterNames = self.getParameterNames() # Necessary to count the number of source and PK parameters

            # Prepare the model
            self.setParameters(parameters)
            y = self.forwardModel(parameters, [simulationsX]*self.getResponseDimension())

            # Create AUC, AUMC, MRT variables and units
            if i == 0:
                if type(self.varNameY)!=list:
                    self.Cunits = self.experiment.variables[self.varNameY].units
                else:
                    self.Cunits = self.experiment.variables[self.varNameY[0]].units
                self.AUCunits = multiplyUnits(tvar.units.unit, self.Cunits.unit)
                self.AUMCunits = multiplyUnits(tvar.units.unit, self.AUCunits)

                if self.addStats or self.addIndividuals:
                    AUCvar = PKPDVariable()
                    AUCvar.varName = "AUC0t"
                    AUCvar.varType = PKPDVariable.TYPE_NUMERIC
                    AUCvar.role = PKPDVariable.ROLE_LABEL
                    AUCvar.units = createUnit(strUnit(self.AUCunits))

                    AUMCvar = PKPDVariable()
                    AUMCvar.varName = "AUMC0t"
                    AUMCvar.varType = PKPDVariable.TYPE_NUMERIC
                    AUMCvar.role = PKPDVariable.ROLE_LABEL
                    AUMCvar.units = createUnit(strUnit(self.AUMCunits))

                    MRTvar = PKPDVariable()
                    MRTvar.varName = "MRT"
                    MRTvar.varType = PKPDVariable.TYPE_NUMERIC
                    MRTvar.role = PKPDVariable.ROLE_LABEL
                    MRTvar.units = createUnit("min")

                    self.outputExperiment.variables["AUC0t"] = AUCvar
                    self.outputExperiment.variables["AUMC0t"] = AUMCvar
                    self.outputExperiment.variables["MRT"] = MRTvar

            # Evaluate AUC, AUMC and MRT in the last full period
            self.NCA(self.model.x,y[0])

            # Keep results
            for j in range(self.getResponseDimension()):
                simulationsY[i,:,j] = y[j]
            AUCarray[i] = self.AUC0t
            AUMCarray[i] = self.AUMC0t
            MRTarray[i] = self.MRT
            CminArray[i] = self.Cmin
            CmaxArray[i] = self.Cmax
            CavgArray[i] = self.Cavg
            fluctuationArray[i] = self.fluctuation
            percentageAccumulationArray[i] = self.percentageAccumulation
            if self.addIndividuals or self.paramsSource==ProtPKPDODESimulate.PRM_USER_DEFINED:
                self.addSample("Simulation_%d"%i, dosename, simulationsX, y)

        # Report NCA statistics
        alpha_2 = (100-self.confidenceLevel.get())/2
        limits = np.percentile(AUCarray,[alpha_2,100-alpha_2])
        print("AUC %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.AUCunits),np.mean(AUCarray)))
        limits = np.percentile(AUMCarray,[alpha_2,100-alpha_2])
        print("AUMC %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.AUMCunits),np.mean(AUMCarray)))
        limits = np.percentile(MRTarray,[alpha_2,100-alpha_2])
        print("MRT %f%% confidence interval=[%f,%f] [min] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],np.mean(MRTarray)))
        limits = np.percentile(CminArray,[alpha_2,100-alpha_2])
        print("Cmin %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.Cunits.unit),np.mean(CminArray)))
        limits = np.percentile(CmaxArray,[alpha_2,100-alpha_2])
        print("Cmax %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.Cunits.unit),np.mean(CmaxArray)))
        limits = np.percentile(CavgArray,[alpha_2,100-alpha_2])
        print("Cavg %f%% confidence interval=[%f,%f] [%s] mean=%f"%(self.confidenceLevel.get(),limits[0],limits[1],strUnit(self.Cunits.unit),np.mean(CavgArray)))
        limits = np.percentile(fluctuationArray,[alpha_2,100-alpha_2])
        print("Fluctuation %f%% confidence interval=[%f,%f] [%%] mean=%f"%(self.confidenceLevel.get(),limits[0]*100,limits[1]*100,np.mean(fluctuationArray)*100))
        limits = np.percentile(percentageAccumulationArray,[alpha_2,100-alpha_2])
        print("Accum(1) %f%% confidence interval=[%f,%f] [%%] mean=%f"%(self.confidenceLevel.get(),limits[0]*100,limits[1]*100,np.mean(percentageAccumulationArray)*100))

        # Calculate statistics
        if self.addStats:
            if self.paramsSource!=ProtPKPDODESimulate.PRM_USER_DEFINED:
                limits = np.percentile(simulationsY,[alpha_2,100-alpha_2],axis=0)

                print("Lower limit NCA")
                self.NCA(simulationsX,limits[0])
                self.addSample("LowerLimit", dosename, simulationsX, limits[0])

            print("Mean profile NCA")
            if self.getResponseDimension()==1:
                mu = np.mean(simulationsY,axis=0)
                self.NCA(simulationsX, mu)
            else:
                mu = []
                for j in range(self.getResponseDimension()):
                    mu.append(np.mean(simulationsY[:,:,j],axis=0))
                self.NCA(simulationsX,mu[0])
            self.addSample("Mean", dosename, simulationsX, mu)

            if self.paramsSource!=ProtPKPDODESimulate.PRM_USER_DEFINED:
                print("Upper limit NCA")
                self.NCA(simulationsX,limits[1])
                self.addSample("UpperLimit", dosename, simulationsX, limits[1])

        self.outputExperiment.write(self._getPath("experiment.pkpd"))

    def createOutputStep(self):
        self._defineOutputs(outputExperiment=self.outputExperiment)
        self._defineSourceRelation(self.inputODE.get(), self.outputExperiment)
        if self.paramsSource==ProtPKPDODESimulate.PRM_POPULATION:
            self._defineSourceRelation(self.inputPopulation.get(), self.outputExperiment)

    #--------------------------- INFO functions --------------------------------------------
    def _summary(self):
        msg = []
        msg.append("Dose: %s"%self.doses.get())
        if self.paramsSource ==  ProtPKPDODESimulate.PRM_POPULATION:
            msg.append("Number of simulations: %d"%self.Nsimulations.get())
            msg.append("Confidence level: %f"%self.confidenceLevel.get())
        else:
            msg.append("Parameters:\n"+self.prmUser.get())
        return msg

    def _validate(self):
        msg=[]
        if self.paramsSource ==  ProtPKPDODESimulate.PRM_POPULATION and \
            not self.inputPopulation.get().fnFitting.get().endswith("bootstrapPopulation.pkpd"):
            msg.append("Population must be a bootstrap sample")
        return msg
Ejemplo n.º 19
0
    def runFilter(self, objId, filterType, condition):
        import copy
        experiment = self.readExperiment(self.inputExperiment.get().fnPKPD)

        self.printSection("Filtering")
        if self.filterType.get()==0:
            filterType="exclude"
        elif self.filterType.get()==1:
            filterType="keep"
        elif self.filterType.get()==2:
            filterType="rmNA"
        elif self.filterType.get()==3:
            filterType="rmLL"
        elif self.filterType.get()==4:
            filterType="subsLL"
        elif self.filterType.get()==5:
            filterType="subsUL"

        filteredExperiment = PKPDExperiment()
        filteredExperiment.general = copy.copy(experiment.general)
        filteredExperiment.variables = copy.copy(experiment.variables)
        filteredExperiment.samples = {}
        filteredExperiment.doses = {}
        filteredExperiment.vias = {}

        usedDoses = []
        for sampleKey, sample in experiment.samples.iteritems():
            candidateSample = PKPDSample()
            candidateSample.variableDictPtr    = copy.copy(sample.variableDictPtr)
            candidateSample.doseDictPtr        = copy.copy(sample.doseDictPtr)
            candidateSample.sampleName         = copy.copy(sample.sampleName)
            candidateSample.doseList           = copy.copy(sample.doseList)
            candidateSample.descriptors        = copy.copy(sample.descriptors)
            candidateSample.measurementPattern = copy.copy(sample.measurementPattern)

            N = 0 # Number of initial measurements
            if len(sample.measurementPattern)>0:
                aux=getattr(sample,"measurement_%s"%sample.measurementPattern[0])
                N = len(aux)
            if N==0:
                continue

            # Create empty output variables
            Nvar = len(sample.measurementPattern)
            convertToFloat = []
            for i in range(0,Nvar):
                exec("candidateSample.measurement_%s = []"%sample.measurementPattern[i])
                convertToFloat.append(sample.variableDictPtr[sample.measurementPattern[i]].varType == PKPDVariable.TYPE_NUMERIC)

            for n in range(0,N):
                toAdd = []
                okToAddTimePoint = True
                conditionPython = copy.copy(condition)
                for i in range(0,Nvar):
                    exec("aux=sample.measurement_%s[%d]"%(sample.measurementPattern[i],n))
                    if filterType=="rmNA":
                        if aux=="NA":
                            okToAddTimePoint = False
                        else:
                            toAdd.append(aux)
                    elif filterType=="rmLL":
                        if aux=="LLOQ" or aux=="ULOQ":
                            okToAddTimePoint = False
                        else:
                            toAdd.append(aux)
                    elif filterType=="subsLL":
                        okToAddTimePoint = True
                        if aux=="LLOQ":
                            toAdd.append(str(self.substitute.get()))
                        else:
                            toAdd.append(aux)
                    elif filterType=="subsUL":
                        okToAddTimePoint = True
                        if aux=="ULOQ":
                            toAdd.append(str(self.substitute.get()))
                        else:
                            toAdd.append(aux)
                    else:
                        # Keep or exclude
                        toAdd.append(aux)
                        varString = "$(%s)"%sample.measurementPattern[i]
                        if varString in conditionPython:
                            if aux=="NA":
                                okToAddTimePoint = False
                            else:
                                if convertToFloat[i]:
                                    conditionPython = conditionPython.replace(varString,"%f"%float(aux))
                                else:
                                    conditionPython = conditionPython.replace(varString,"'%s'"%aux)
                if (filterType=="exclude" or filterType=="keep") and okToAddTimePoint:
                    okToAddTimePoint = eval(conditionPython, {"__builtins__" : None }, {})
                    if filterType=="exclude":
                        okToAddTimePoint = not okToAddTimePoint
                if okToAddTimePoint:
                    for i in range(0,Nvar):
                        exec("candidateSample.measurement_%s.append('%s')"%(sample.measurementPattern[i],toAdd[i]))

            N = len(getattr(sample,"measurement_%s"%sample.measurementPattern[0])) # Number of final measurements
            if N!=0:
                filteredExperiment.samples[candidateSample.sampleName] = candidateSample
                for doseName in candidateSample.doseList:
                    if not doseName in usedDoses:
                        usedDoses.append(doseName)

        if len(usedDoses)>0:
            for doseName in usedDoses:
                filteredExperiment.doses[doseName] = copy.copy(experiment.doses[doseName])
                viaName=experiment.doses[doseName].via.viaName
                if not viaName in filteredExperiment.vias:
                    filteredExperiment.vias[viaName] = copy.copy(experiment.vias[viaName])

        self.writeExperiment(filteredExperiment,self._getPath("experiment.pkpd"))
        self.experiment = filteredExperiment
    def createOutputStep(self, objId):
        fnFile = os.path.basename(self.inputFile.get())
        copyFile(self.inputFile.get(),self._getPath(fnFile))

        self.experiment = PKPDExperiment()
        self.experiment.general["title"]=self.title.get()
        self.experiment.general["comment"]=self.comment.get()

        ok = True

        # Read the variables
        self.listOfVariables = []
        for line in self.variables.get().replace('\n',';;').split(';;'):
            tokens = line.split(';')
            if len(tokens)!=5:
                print("Skipping variable: ",line)
                ok = False
                continue
            varname = tokens[0].strip()
            self.listOfVariables.append(varname)
            self.experiment.variables[varname] = PKPDVariable()
            self.experiment.variables[varname].parseTokens(tokens)

        # Read vias
        for line in self.vias.get().replace('\n',';;').split(';;'):
            if line!="":
                tokens = line.split(';')
                if len(tokens)<2:
                    print("Skipping via: ",line)
                    ok = False
                    continue
                vianame = tokens[0].strip()
                self.experiment.vias[vianame] = PKPDVia()
                self.experiment.vias[vianame].parseTokens(tokens)

        # Read the doses
        for line in self.doses.get().replace('\n',';;').split(';;'):
            if line!="":
                tokens = line.split(';')
                if len(tokens)<5:
                    print("Skipping dose: ",line)
                    ok = False
                    continue
                dosename = tokens[0].strip()
                self.experiment.doses[dosename] = PKPDDose()
                self.experiment.doses[dosename].parseTokens(tokens,self.experiment.vias)

        # Read the sample doses
        for line in self.dosesToSamples.get().replace('\n',';;').split(';;'):
            try:
                tokens = line.split(';')
                samplename = tokens[0].strip()
                if len(tokens)>1:
                    tokens[1]="dose="+tokens[1]
                self.experiment.samples[samplename] = PKPDSample()
                self.experiment.samples[samplename].parseTokens(tokens, self.experiment.variables, self.experiment.doses,
                                                                self.experiment.groups)
            except Exception as e:
                ok = False
                print("Problem with line: ",line,str(e))

        if ok:
            # Read the measurements
            self.readTextFile()
            self.experiment.write(self._getPath("experiment.pkpd"))
            self.experiment._printToStream(sys.stdout)
            self._defineOutputs(outputExperiment=self.experiment)
Ejemplo n.º 21
0
class ProtPKPDImportFromText(ProtPKPD):
    #--------------------------- DEFINE param functions --------------------------------------------

    def _defineParams(self, form, type):
        form.addSection('Input')
        inputFileHelp = "Specify a path to desired %s file.\n" % type
        inputFileHelp += "You may specify missing values with NA. You may also use LLOQ and ULOQ (Lower and Upper limit of quantification)\n"
        inputFileHelp += "to specify measurements that are below or above these limits"
        if type == "CSV":
            inputFileHelp += "The field separator must be a semicolon (;), decimal point must be a dot (.).\n"
            inputFileHelp += "The first row must contain the variable names and one of them must be SampleName which will serve as identifier."
        form.addParam('inputFile',
                      params.PathParam,
                      label="File path",
                      allowsNull=False,
                      help=inputFileHelp)
        form.addParam('title',
                      params.StringParam,
                      label="Title",
                      default="My experiment")
        form.addParam('comment',
                      params.StringParam,
                      label="Comment",
                      default="")
        form.addParam('variables', params.TextParam, height=8, width=80, label="Variables", default="",
                      help="Structure: [Variable Name] ; [Units] ; [Type] ; [Role] ; [Comment]\n"\
                           "The variable name should have no space or special character\n"\
                           "Valid units are: h, mg, ug, ug/mL, ...\n"\
                           "Type is either numeric or text\n"\
                           "Role is either time, label or measurement\n"\
                           "The comment may be empty\n"\
                           "\nIt is important that there are three semicolons (none of them may be missing even if the comment is not present).\n"\
                           "Examples:\n"\
                           "t ; h ; numeric ; time ; \n"\
                           "Cp ; ug/mL ; numeric ; measurement ; plasma concentration\n"\
                           "weight ; g ; numeric; label ; weight of the animal\n"\
                           "sex ; none ; text ; label ; sex of the animal\n")
        form.addParam('vias', params.TextParam, height=8, width=80, label="Vias",
                      help="[ViaName]; [ViaType]; [tlag]; [bioavailability]"\
                       "Valid ViaTypes are: iv (intravenous), ev0 (extra-vascular order 0), ev1 (extra-vascular order 1), \n"\
                       "     ev01 (extra-vascular first order 0 and then order 1), evFractional (extra-vascular fractional order)\n"\
                       "Optional parameters are tlag (e.g. tlag=0)\n"\
                       "   and bioavailability (e.g. bioavailability=0.8)\n"\
                       "Examples:\n"\
                       "Intravenous; iv\n"\
                       "Oral; ev1; tlag; bioavailability=1\n")
        addDoseToForm(form)
        form.addParam('dosesToSamples', params.TextParam, height=5, width=70, label="Assign doses to samples", default="",
                      help="Structure: [Sample Name] ; [DoseName1,DoseName2,...] \n"\
                           "The sample name should have no space or special character\n"\
                           "\nIt is important that there is one semicolon.\n"\
                           "Examples:\n"\
                           "FemaleRat1 ; Bolus0,Bolus1,Infusion0\n")

    #--------------------------- INSERT steps functions --------------------------------------------

    def _insertAllSteps(self):
        self._insertFunctionStep('createOutputStep', self.inputFile.get())

    #--------------------------- STEPS functions --------------------------------------------
    def readTextFile(self):
        pass

    def createOutputStep(self, objId):
        fnFile = os.path.basename(self.inputFile.get())
        copyFile(self.inputFile.get(), self._getPath(fnFile))

        self.experiment = PKPDExperiment()
        self.experiment.general["title"] = self.title.get()
        self.experiment.general["comment"] = self.comment.get()

        ok = True

        # Read the variables
        self.listOfVariables = []
        for line in self.variables.get().replace('\n', ';;').split(';;'):
            tokens = line.split(';')
            if len(tokens) != 5:
                print("Skipping variable: ", line)
                ok = False
                continue
            varname = tokens[0].strip()
            self.listOfVariables.append(varname)
            self.experiment.variables[varname] = PKPDVariable()
            self.experiment.variables[varname].parseTokens(tokens)

        # Read vias
        for line in self.vias.get().replace('\n', ';;').split(';;'):
            if line != "":
                tokens = line.split(';')
                if len(tokens) < 2:
                    print("Skipping via: ", line)
                    ok = False
                    continue
                vianame = tokens[0].strip()
                self.experiment.vias[vianame] = PKPDVia()
                self.experiment.vias[vianame].parseTokens(tokens)

        # Read the doses
        for line in self.doses.get().replace('\n', ';;').split(';;'):
            if line != "":
                tokens = line.split(';')
                if len(tokens) < 5:
                    print("Skipping dose: ", line)
                    ok = False
                    continue
                dosename = tokens[0].strip()
                self.experiment.doses[dosename] = PKPDDose()
                self.experiment.doses[dosename].parseTokens(
                    tokens, self.experiment.vias)

        # Read the sample doses
        for line in self.dosesToSamples.get().replace('\n', ';;').split(';;'):
            try:
                tokens = line.split(';')
                samplename = tokens[0].strip()
                if len(tokens) > 1:
                    tokens[1] = "dose=" + tokens[1]
                self.experiment.samples[samplename] = PKPDSample()
                self.experiment.samples[samplename].parseTokens(
                    tokens, self.experiment.variables, self.experiment.doses,
                    self.experiment.groups)
            except Exception as e:
                ok = False
                print("Problem with line: ", line, str(e))

        if ok:
            # Read the measurements
            self.readTextFile()
            self.experiment.write(self._getPath("experiment.pkpd"))
            self.experiment._printToStream(sys.stdout)
            self._defineOutputs(outputExperiment=self.experiment)

    #--------------------------- INFO functions --------------------------------------------
    def _summary(self):
        return ["Input file: %s" % self.inputFile.get()]
Ejemplo n.º 22
0
    def runFilter(self, objId, filterType, condition):
        import copy
        experiment = self.readExperiment(self.inputExperiment.get().fnPKPD)

        self.printSection("Filtering")
        if self.filterType.get() == 0:
            filterType = "exclude"
        elif self.filterType.get() == 1:
            filterType = "keep"
        else:
            filterType = "rmNA"

        filteredExperiment = PKPDExperiment()
        filteredExperiment.general = copy.copy(experiment.general)
        filteredExperiment.variables = copy.copy(experiment.variables)
        filteredExperiment.samples = {}
        filteredExperiment.doses = {}

        # http://stackoverflow.com/questions/701802/how-do-i-execute-a-string-containing-python-code-in-python
        safe_list = ['descriptors']
        safe_dict = dict([(k, locals().get(k, None)) for k in safe_list])
        usedDoses = []
        for sampleKey, sample in experiment.samples.iteritems():
            ok = filterType == "rmNA"
            try:
                if filterType == "rmNA":
                    conditionPython = "True"
                else:
                    conditionPython = copy.copy(condition)
                conditionPython = conditionPython.replace(
                    '$(sampleName)', '"%s"' % sample.sampleName)
                for key, variable in experiment.variables.iteritems():
                    if key in sample.descriptors:
                        value = sample.descriptors[key]
                        if value == "NA":
                            conditionPython = "False"
                        else:
                            if filterType != "rmNA":
                                if variable.varType == PKPDVariable.TYPE_NUMERIC:
                                    conditionPython = conditionPython.replace(
                                        "$(%s)" % key,
                                        "%f" % float(sample.descriptors[key]))
                                else:
                                    conditionPython = conditionPython.replace(
                                        "$(%s)" % key,
                                        "'%s'" % sample.descriptors[key])
                ok = eval(conditionPython,
                          {"__builtins__": {
                              "True": True,
                              "False": False
                          }}, {})
            except:
                print sys.exc_info()[0]
                pass
            if (ok and (filterType == "keep" or filterType == "rmNA")) or (
                    not ok and filterType == "exclude"):
                filteredExperiment.samples[sampleKey] = copy.copy(sample)
                for doseName in sample.doseList:
                    usedDoses.append(doseName)

        if len(usedDoses) > 0:
            for doseName in usedDoses:
                filteredExperiment.doses[doseName] = copy.copy(
                    experiment.doses[doseName])

        self.writeExperiment(filteredExperiment,
                             self._getPath("experiment.pkpd"))
        self.experiment = filteredExperiment
Ejemplo n.º 23
0
    def createOutputStep(self, objId):
        fnFile = os.path.basename(self.inputFile.get())
        copyFile(self.inputFile.get(), self._getPath(fnFile))

        self.experiment = PKPDExperiment()
        self.experiment.general["title"] = self.title.get()
        self.experiment.general["comment"] = self.comment.get()

        ok = True

        # Read the variables
        self.listOfVariables = []
        for line in self.variables.get().replace('\n', ';;').split(';;'):
            tokens = line.split(';')
            if len(tokens) != 5:
                print("Skipping variable: ", line)
                ok = False
                continue
            varname = tokens[0].strip()
            self.listOfVariables.append(varname)
            self.experiment.variables[varname] = PKPDVariable()
            self.experiment.variables[varname].parseTokens(tokens)

        # Read vias
        for line in self.vias.get().replace('\n', ';;').split(';;'):
            if line != "":
                tokens = line.split(';')
                if len(tokens) < 2:
                    print("Skipping via: ", line)
                    ok = False
                    continue
                vianame = tokens[0].strip()
                self.experiment.vias[vianame] = PKPDVia()
                self.experiment.vias[vianame].parseTokens(tokens)

        # Read the doses
        for line in self.doses.get().replace('\n', ';;').split(';;'):
            if line != "":
                tokens = line.split(';')
                if len(tokens) < 5:
                    print("Skipping dose: ", line)
                    ok = False
                    continue
                dosename = tokens[0].strip()
                self.experiment.doses[dosename] = PKPDDose()
                self.experiment.doses[dosename].parseTokens(
                    tokens, self.experiment.vias)

        # Read the sample doses
        for line in self.dosesToSamples.get().replace('\n', ';;').split(';;'):
            try:
                tokens = line.split(';')
                samplename = tokens[0].strip()
                if len(tokens) > 1:
                    tokens[1] = "dose=" + tokens[1]
                self.experiment.samples[samplename] = PKPDSample()
                self.experiment.samples[samplename].parseTokens(
                    tokens, self.experiment.variables, self.experiment.doses,
                    self.experiment.groups)
            except Exception as e:
                ok = False
                print("Problem with line: ", line, str(e))

        if ok:
            # Read the measurements
            self.readTextFile()
            self.experiment.write(self._getPath("experiment.pkpd"))
            self.experiment._printToStream(sys.stdout)
            self._defineOutputs(outputExperiment=self.experiment)
Ejemplo n.º 24
0
class ProtPKPDODESimulate(ProtPKPDODEBase):
    """ Simulate a population of ODE parameters.
    These parameters can be specifically given or from a bootstrap population"""

    _label = 'PK simulate'

    PRM_POPULATION = 0
    PRM_USER_DEFINED = 1

    #--------------------------- DEFINE param functions --------------------------------------------
    def _defineParams(self, form):
        form.addSection('Input')
        form.addParam(
            'inputODE',
            params.PointerParam,
            label="Input ODE model",
            pointerClass=
            'ProtPKPDMonoCompartment, ProtPKPDTwoCompartments, ProtPKPDMonoCompartmentPD, ProtPKPDTwoCompartmentsBothPD',
            help='Select a run of an ODE model')
        form.addParam('paramsSource',
                      params.EnumParam,
                      label="Source of parameters",
                      choices=['ODE Bootstrap', 'User defined'],
                      default=0,
                      help="Choose a population of parameters or your own")
        form.addParam(
            'inputPopulation',
            params.PointerParam,
            label="Input population",
            condition="paramsSource==0",
            pointerClass='PKPDFitting',
            pointerCondition="isPopulation",
            help='It must be a fitting coming from a bootstrap sample')
        form.addParam(
            'prmUser',
            params.TextParam,
            label="Simulation parameters",
            height=8,
            default="",
            condition="paramsSource==1",
            help=
            'Specify the parameters for the simulation. The parameters must be written in the same order as they are written by the protocol '
            'that generated the ODE model. Example: \n'
            'prm1, prm2, prm3, prm4\n'
            'prmA, prmB, prmC, prmD')
        form.addParam('doses', params.TextParam, label="Doses", height=5, width=50,
                      default="RepeatedBolus ; via=Oral; repeated_bolus; t=0:24:120 h; d=60 mg",
                      help="Structure: [Dose Name] ; [Via] ; [Dose type] ; [time] ; [dose] \n"\
                           "The dose name should have no space or special character\n"\
                           "The via should be one present in the input experiment to the ODE model.\n"\
                           "Valid units are: h, mg, ug, ...\n"\
                           "The description is either a bolus or an infusion as shown in the examples\n"\
                           "\nIt is important that there are two semicolons.\n"\
                           "Examples:\n"\
                           "Infusion0; via=Intravenous; infusion; t=0.500000...0.750000 h; d=60 mg\n"\
                           "Bolus0; via=Oral; bolus; t=0.000000 min; d=60 mg\n"\
                           "RepeatedBolus; via=Oral; repeated_bolus; t=0:24:120 h; d=60 mg")
        form.addParam('t0',
                      params.FloatParam,
                      label="Initial time (h)",
                      default=0)
        form.addParam('tF',
                      params.FloatParam,
                      label="Final time (h)",
                      default=24 * 7)
        form.addParam('Nsimulations',
                      params.IntParam,
                      label="Simulation samples",
                      default=200,
                      condition="paramsSource==0",
                      expertLevel=LEVEL_ADVANCED,
                      help='Number of simulations')
        form.addParam(
            'addStats',
            params.BooleanParam,
            label="Add simulation statistics",
            default=True,
            condition="paramsSource==0",
            expertLevel=LEVEL_ADVANCED,
            help=
            "Mean, lower and upper confidence levels are added to the output")
        form.addParam('confidenceLevel',
                      params.FloatParam,
                      label="Confidence interval",
                      default=95,
                      expertLevel=LEVEL_ADVANCED,
                      help='Confidence interval for the fitted parameters',
                      condition="addStats and paramsSource==0")
        form.addParam('addIndividuals',
                      params.BooleanParam,
                      label="Add individual simulations",
                      default=False,
                      condition="paramsSource==0",
                      expertLevel=LEVEL_ADVANCED,
                      help="Individual simulations are added to the output")

    #--------------------------- INSERT steps functions --------------------------------------------
    def _insertAllSteps(self):
        self._insertFunctionStep('runSimulate',
                                 self.inputODE.get().getObjId(),
                                 self.Nsimulations.get(),
                                 self.confidenceLevel.get(), self.doses.get())
        self._insertFunctionStep('createOutputStep')

    #--------------------------- STEPS functions --------------------------------------------
    def addSample(self, sampleName, doseName, simulationsX, y):
        newSample = PKPDSample()
        newSample.sampleName = sampleName
        newSample.variableDictPtr = self.outputExperiment.variables
        newSample.doseDictPtr = self.outputExperiment.doses
        newSample.descriptors = {}
        newSample.doseList = [doseName]
        if type(self.varNameY) != list:
            newSample.addMeasurementPattern([self.varNameY])
            newSample.addMeasurementColumn("t", simulationsX)
            newSample.addMeasurementColumn(self.varNameY, y)
        else:
            for j in range(len(self.varNameY)):
                newSample.addMeasurementPattern([self.varNameY[j]])
            newSample.addMeasurementColumn("t", simulationsX)
            for j in range(len(self.varNameY)):
                newSample.addMeasurementColumn(self.varNameY[j], y[j])
        newSample.descriptors["AUC0t"] = self.AUC0t
        newSample.descriptors["AUMC0t"] = self.AUMC0t
        newSample.descriptors["MRT"] = self.MRT
        self.outputExperiment.samples[sampleName] = newSample

    def NCA(self, t, C):
        AUClist = []
        AUMClist = []
        Cminlist = []
        Cavglist = []
        Cmaxlist = []
        Tmaxlist = []
        Tminlist = []
        Ndoses = len(self.drugSource.parsedDoseList)
        for ndose in range(0, max(Ndoses - 1, 1)):
            tperiod0 = self.drugSource.parsedDoseList[ndose].t0
            if ndose + 1 < Ndoses:
                tperiodF = self.drugSource.parsedDoseList[
                    ndose + 1].t0 - self.model.deltaT
            else:
                tperiodF = np.max(t) - 1
            idx0 = find_nearest(t, tperiod0)
            idxF = find_nearest(t, tperiodF)

            AUC0t = 0
            AUMC0t = 0
            t0 = t[idx0 + 1]
            for idx in range(idx0, idxF + 1):
                dt = (t[idx + 1] - t[idx])
                if C[idx + 1] >= C[idx]:  # Trapezoidal in the raise
                    AUC0t += 0.5 * dt * (C[idx] + C[idx + 1])
                    AUMC0t += 0.5 * dt * (C[idx] * t[idx] +
                                          C[idx + 1] * t[idx + 1])
                else:  # Log-trapezoidal in the decay
                    decrement = C[idx] / C[idx + 1]
                    K = math.log(decrement)
                    B = K / dt
                    AUC0t += dt * (C[idx] - C[idx + 1]) / K
                    AUMC0t += (C[idx] * (t[idx] - tperiod0) - C[idx + 1] *
                               (t[idx + 1] - tperiod0)) / B - (
                                   C[idx + 1] - C[idx]) / (B * B)

                if idx == idx0:
                    Cmax = C[idx]
                    Tmax = t[idx] - t0
                    Cmin = C[idx]
                    Tmin = t[idx] - t0
                else:
                    if C[idx] < Cmin:
                        Cmin = C[idx]
                        Tmin = t[idx] - t0
                    elif C[idx] > Cmax:
                        Cmax = C[idx]
                        Tmax = t[idx] - t0
                        if ndose == 0:
                            Cmin = C[idx]
                            Tmin = t[idx] - t0
            AUClist.append(AUC0t)
            AUMClist.append(AUMC0t)
            Cminlist.append(Cmin)
            Cmaxlist.append(Cmax)
            Tmaxlist.append(Tmax)
            Tminlist.append(Tmin)
            Cavglist.append(AUC0t / (t[idxF] - t[idx0]))

        print("Fluctuation = Cmax/Cmin")
        print("Accumulation(1) = Cavg(n)/Cavg(1) %")
        print("Accumulation(n) = Cavg(n)/Cavg(n-1) %")
        print("Steady state fraction(n) = Cavg(n)/Cavg(last) %")
        for ndose in range(0, len(AUClist)):
            fluctuation = Cmaxlist[ndose] / Cminlist[ndose]
            if ndose > 0:
                accumn = Cavglist[ndose] / Cavglist[ndose - 1]
            else:
                accumn = 0
            print("Dose #%d: Cavg= %f [%s] Cmin= %f [%s] Tmin= %d [min] Cmax= %f [%s] Tmax= %d [min] Fluct= %f %% Accum(1)= %f %% Accum(n)= %f %% SSFrac(n)= %f %% AUC= %f [%s] AUMC= %f [%s]"%\
                  (ndose+1,Cavglist[ndose], strUnit(self.Cunits.unit), Cminlist[ndose],strUnit(self.Cunits.unit), int(Tminlist[ndose]), Cmaxlist[ndose], strUnit(self.Cunits.unit),
                   int(Tmaxlist[ndose]), fluctuation*100, Cavglist[ndose]/Cavglist[0]*100, accumn*100, Cavglist[ndose]/Cavglist[-1]*100, AUClist[ndose],strUnit(self.AUCunits),
                   AUMClist[ndose],strUnit(self.AUMCunits)))

        self.AUC0t = AUClist[-1]
        self.AUMC0t = AUMClist[-1]
        self.MRT = self.AUMC0t / self.AUC0t
        self.Cmin = Cminlist[-1]
        self.Cmax = Cmaxlist[-1]
        self.Cavg = Cavglist[-1]
        self.fluctuation = self.Cmax / self.Cmin
        self.percentageAccumulation = Cavglist[-1] / Cavglist[0]

        print("   AUC0t=%f [%s]" % (self.AUC0t, strUnit(self.AUCunits)))
        print("   AUMC0t=%f [%s]" % (self.AUMC0t, strUnit(self.AUMCunits)))
        print("   MRT=%f [min]" % self.MRT)

    def runSimulate(self, objId, Nsimulations, confidenceInterval, doses):
        self.protODE = self.inputODE.get()
        if hasattr(self.protODE, "outputExperiment"):
            self.experiment = self.readExperiment(
                self.protODE.outputExperiment.fnPKPD)
        elif hasattr(self.protODE, "outputExperiment1"):
            self.experiment = self.readExperiment(
                self.protODE.outputExperiment1.fnPKPD)
        else:
            raise Exception("Cannot find an outputExperiment in the input ODE")
        if self.paramsSource == ProtPKPDODESimulate.PRM_POPULATION:
            self.fitting = self.readFitting(
                self.inputPopulation.get().fnFitting,
                cls="PKPDSampleFitBootstrap")
        else:
            if hasattr(self.protODE, "outputFitting"):
                self.fitting = self.readFitting(
                    self.protODE.outputFitting.fnFitting)
            elif hasattr(self.protODE, "outputFitting1"):
                self.fitting = self.readFitting(
                    self.protODE.outputFitting1.fnFitting)
        self.varNameX = self.fitting.predictor.varName
        if type(self.fitting.predicted) != list:
            self.varNameY = self.fitting.predicted.varName
        else:
            self.varNameY = [var.varName for var in self.fitting.predicted]

        # Create drug source
        self.clearGroupParameters()
        self.createDrugSource()

        # Create output object
        self.outputExperiment = PKPDExperiment()
        tvar = PKPDVariable()
        tvar.varName = "t"
        tvar.varType = PKPDVariable.TYPE_NUMERIC
        tvar.role = PKPDVariable.ROLE_TIME
        tvar.units = createUnit("min")

        self.outputExperiment.variables[self.varNameX] = tvar
        if type(self.fitting.predicted) != list:
            self.outputExperiment.variables[
                self.varNameY] = self.experiment.variables[self.varNameY]
        else:
            for varName in self.varNameY:
                self.outputExperiment.variables[
                    varName] = self.experiment.variables[varName]
        self.outputExperiment.general["title"] = "Simulated ODE response"
        self.outputExperiment.general["comment"] = "Simulated ODE response"
        self.outputExperiment.vias = self.experiment.vias

        # Setup model
        self.model = self.protODE.createModel()
        self.model.setExperiment(self.outputExperiment)
        if hasattr(self.protODE, "deltaT"):
            self.model.deltaT = self.protODE.deltaT.get()
        self.model.setXVar(self.varNameX)
        self.model.setYVar(self.varNameY)
        Nsamples = int(60 * math.ceil(
            (self.tF.get() - self.t0.get()) / self.model.deltaT)) + 1
        self.model.x = [
            self.t0.get() + i * self.model.deltaT for i in range(0, Nsamples)
        ]
        self.modelList.append(self.model)

        # Read the doses
        for line in self.doses.get().replace('\n', ';;').split(';;'):
            tokens = line.split(';')
            if len(tokens) < 5:
                print("Skipping dose: ", line)
                continue
            dosename = tokens[0].strip()
            self.outputExperiment.doses[dosename] = PKPDDose()
            self.outputExperiment.doses[dosename].parseTokens(
                tokens, self.experiment.vias)
        auxSample = PKPDSample()
        auxSample.descriptors = {}
        auxSample.doseDictPtr = self.outputExperiment.doses
        auxSample.variableDictPtr = self.outputExperiment.variables
        auxSample.doseList = [dosename]
        auxSample.interpretDose()
        self.drugSource.setDoses(auxSample.parsedDoseList,
                                 self.t0.get() - 10,
                                 self.tF.get() + 10)
        self.model.drugSource = self.drugSource

        # Check units
        # Dunits = self.outputExperiment.doses[dosename].dunits
        # Cunits = self.experiment.variables[self.varNameY].units

        # Process user parameters
        if self.paramsSource == ProtPKPDODESimulate.PRM_POPULATION:
            Nsimulations = self.Nsimulations.get()
        else:
            lines = self.prmUser.get().strip().replace('\n', ';;').split(';;')
            Nsimulations = len(lines)
            prmUser = []
            for line in lines:
                tokens = line.strip().split(',')
                prmUser.append([float(token) for token in tokens])

        # Simulate the different responses
        simulationsX = self.model.x
        simulationsY = np.zeros(
            (Nsimulations, len(simulationsX), self.getResponseDimension()))
        AUCarray = np.zeros(Nsimulations)
        AUMCarray = np.zeros(Nsimulations)
        MRTarray = np.zeros(Nsimulations)
        CminArray = np.zeros(Nsimulations)
        CmaxArray = np.zeros(Nsimulations)
        CavgArray = np.zeros(Nsimulations)
        fluctuationArray = np.zeros(Nsimulations)
        percentageAccumulationArray = np.zeros(Nsimulations)
        for i in range(0, Nsimulations):
            self.setTimeRange(None)

            if self.paramsSource == ProtPKPDODESimulate.PRM_POPULATION:
                # Take parameters randomly from the population
                nfit = int(random.uniform(0, len(self.fitting.sampleFits)))
                sampleFit = self.fitting.sampleFits[nfit]
                nprm = int(random.uniform(0, sampleFit.parameters.shape[0]))
                parameters = sampleFit.parameters[nprm, :]
            else:
                parameters = np.asarray(prmUser[i], np.double)
            print("Simulated sample %d: %s" % (i, str(parameters)))

            # Prepare source and this object
            self.drugSource.setDoses(auxSample.parsedDoseList, self.model.t0,
                                     self.model.tF)
            self.protODE.configureSource(self.drugSource)
            self.model.drugSource = self.drugSource
            parameterNames = self.getParameterNames(
            )  # Necessary to count the number of source and PK parameters

            # Prepare the model
            self.setParameters(parameters)
            y = self.forwardModel(parameters,
                                  [simulationsX] * self.getResponseDimension())

            # Create AUC, AUMC, MRT variables and units
            if i == 0:
                if type(self.varNameY) != list:
                    self.Cunits = self.experiment.variables[
                        self.varNameY].units
                else:
                    self.Cunits = self.experiment.variables[
                        self.varNameY[0]].units
                self.AUCunits = multiplyUnits(tvar.units.unit,
                                              self.Cunits.unit)
                self.AUMCunits = multiplyUnits(tvar.units.unit, self.AUCunits)

                if self.addStats or self.addIndividuals:
                    AUCvar = PKPDVariable()
                    AUCvar.varName = "AUC0t"
                    AUCvar.varType = PKPDVariable.TYPE_NUMERIC
                    AUCvar.role = PKPDVariable.ROLE_LABEL
                    AUCvar.units = createUnit(strUnit(self.AUCunits))

                    AUMCvar = PKPDVariable()
                    AUMCvar.varName = "AUMC0t"
                    AUMCvar.varType = PKPDVariable.TYPE_NUMERIC
                    AUMCvar.role = PKPDVariable.ROLE_LABEL
                    AUMCvar.units = createUnit(strUnit(self.AUMCunits))

                    MRTvar = PKPDVariable()
                    MRTvar.varName = "MRT"
                    MRTvar.varType = PKPDVariable.TYPE_NUMERIC
                    MRTvar.role = PKPDVariable.ROLE_LABEL
                    MRTvar.units = createUnit("min")

                    self.outputExperiment.variables["AUC0t"] = AUCvar
                    self.outputExperiment.variables["AUMC0t"] = AUMCvar
                    self.outputExperiment.variables["MRT"] = MRTvar

            # Evaluate AUC, AUMC and MRT in the last full period
            self.NCA(self.model.x, y[0])

            # Keep results
            for j in range(self.getResponseDimension()):
                simulationsY[i, :, j] = y[j]
            AUCarray[i] = self.AUC0t
            AUMCarray[i] = self.AUMC0t
            MRTarray[i] = self.MRT
            CminArray[i] = self.Cmin
            CmaxArray[i] = self.Cmax
            CavgArray[i] = self.Cavg
            fluctuationArray[i] = self.fluctuation
            percentageAccumulationArray[i] = self.percentageAccumulation
            if self.addIndividuals or self.paramsSource == ProtPKPDODESimulate.PRM_USER_DEFINED:
                self.addSample("Simulation_%d" % i, dosename, simulationsX, y)

        # Report NCA statistics
        alpha_2 = (100 - self.confidenceLevel.get()) / 2
        limits = np.percentile(AUCarray, [alpha_2, 100 - alpha_2])
        print("AUC %f%% confidence interval=[%f,%f] [%s] mean=%f" %
              (self.confidenceLevel.get(), limits[0], limits[1],
               strUnit(self.AUCunits), np.mean(AUCarray)))
        limits = np.percentile(AUMCarray, [alpha_2, 100 - alpha_2])
        print("AUMC %f%% confidence interval=[%f,%f] [%s] mean=%f" %
              (self.confidenceLevel.get(), limits[0], limits[1],
               strUnit(self.AUMCunits), np.mean(AUMCarray)))
        limits = np.percentile(MRTarray, [alpha_2, 100 - alpha_2])
        print("MRT %f%% confidence interval=[%f,%f] [min] mean=%f" %
              (self.confidenceLevel.get(), limits[0], limits[1],
               np.mean(MRTarray)))
        limits = np.percentile(CminArray, [alpha_2, 100 - alpha_2])
        print("Cmin %f%% confidence interval=[%f,%f] [%s] mean=%f" %
              (self.confidenceLevel.get(), limits[0], limits[1],
               strUnit(self.Cunits.unit), np.mean(CminArray)))
        limits = np.percentile(CmaxArray, [alpha_2, 100 - alpha_2])
        print("Cmax %f%% confidence interval=[%f,%f] [%s] mean=%f" %
              (self.confidenceLevel.get(), limits[0], limits[1],
               strUnit(self.Cunits.unit), np.mean(CmaxArray)))
        limits = np.percentile(CavgArray, [alpha_2, 100 - alpha_2])
        print("Cavg %f%% confidence interval=[%f,%f] [%s] mean=%f" %
              (self.confidenceLevel.get(), limits[0], limits[1],
               strUnit(self.Cunits.unit), np.mean(CavgArray)))
        limits = np.percentile(fluctuationArray, [alpha_2, 100 - alpha_2])
        print("Fluctuation %f%% confidence interval=[%f,%f] [%%] mean=%f" %
              (self.confidenceLevel.get(), limits[0] * 100, limits[1] * 100,
               np.mean(fluctuationArray) * 100))
        limits = np.percentile(percentageAccumulationArray,
                               [alpha_2, 100 - alpha_2])
        print("Accum(1) %f%% confidence interval=[%f,%f] [%%] mean=%f" %
              (self.confidenceLevel.get(), limits[0] * 100, limits[1] * 100,
               np.mean(percentageAccumulationArray) * 100))

        # Calculate statistics
        if self.addStats:
            if self.paramsSource != ProtPKPDODESimulate.PRM_USER_DEFINED:
                limits = np.percentile(simulationsY, [alpha_2, 100 - alpha_2],
                                       axis=0)

                print("Lower limit NCA")
                self.NCA(simulationsX, limits[0])
                self.addSample("LowerLimit", dosename, simulationsX, limits[0])

            print("Mean profile NCA")
            if self.getResponseDimension() == 1:
                mu = np.mean(simulationsY, axis=0)
                self.NCA(simulationsX, mu)
            else:
                mu = []
                for j in range(self.getResponseDimension()):
                    mu.append(np.mean(simulationsY[:, :, j], axis=0))
                self.NCA(simulationsX, mu[0])
            self.addSample("Mean", dosename, simulationsX, mu)

            if self.paramsSource != ProtPKPDODESimulate.PRM_USER_DEFINED:
                print("Upper limit NCA")
                self.NCA(simulationsX, limits[1])
                self.addSample("UpperLimit", dosename, simulationsX, limits[1])

        self.outputExperiment.write(self._getPath("experiment.pkpd"))

    def createOutputStep(self):
        self._defineOutputs(outputExperiment=self.outputExperiment)
        self._defineSourceRelation(self.inputODE.get(), self.outputExperiment)
        if self.paramsSource == ProtPKPDODESimulate.PRM_POPULATION:
            self._defineSourceRelation(self.inputPopulation.get(),
                                       self.outputExperiment)

    #--------------------------- INFO functions --------------------------------------------
    def _summary(self):
        msg = []
        msg.append("Dose: %s" % self.doses.get())
        if self.paramsSource == ProtPKPDODESimulate.PRM_POPULATION:
            msg.append("Number of simulations: %d" % self.Nsimulations.get())
            msg.append("Confidence level: %f" % self.confidenceLevel.get())
        else:
            msg.append("Parameters:\n" + self.prmUser.get())
        return msg

    def _validate(self):
        msg = []
        if self.paramsSource ==  ProtPKPDODESimulate.PRM_POPULATION and \
            not self.inputPopulation.get().fnFitting.get().endswith("bootstrapPopulation.pkpd"):
            msg.append("Population must be a bootstrap sample")
        return msg
Ejemplo n.º 25
0
class ProtPKPDApplyAllometricScaling(ProtPKPD):
    """ Apply an allometric scaling previously calculated to an incoming experiment. The labels specified by the
        allometric scaling model will be rescaled to the target weight. Note that depending on the exponent of the
        fitting you may want to use a different predictor (weight*maximum lifespan potential, or weight*brain weight)
        see the rule of exponents (Mahmood and Balian 1996). """

    _label = 'apply allometric'

    #--------------------------- DEFINE param functions --------------------------------------------
    def _defineParams(self, form):
        form.addSection('Input')
        form.addParam('inputPopulation', params.PointerParam, label="Input bootstrap population",
                      pointerClass='PKPDFitting',
                      help='The PK parameters of this experiment will be modified according to the allometric scale model.')
        form.addParam('inputAllometric', params.PointerParam, label="Allometric model", pointerClass='PKPDAllometricScale',
                      help='All variables specified by the allometric scale model will be adjusted')
        form.addParam('targetWeight', params.FloatParam, label="Target weight (kg)", default=25,
                      help='The PK parameters will be adjusted to this target weight')

    #--------------------------- INSERT steps functions --------------------------------------------
    def _insertAllSteps(self):
        self._insertFunctionStep('runAdjust', self.targetWeight.get())
        self._insertFunctionStep('createOutputStep')

    #--------------------------- STEPS functions --------------------------------------------
    def runAdjust(self, targetWeight):
        scaleModel = PKPDAllometricScale()
        scaleModel.load(self.inputAllometric.get().fnScale.get())

        self.population = self.readFitting(self.inputPopulation.get().fnFitting,cls="PKPDSampleFitBootstrap")
        self.experiment = PKPDExperiment()
        self.experiment.load(self.population.fnExperiment.get())

        for sampleFit in self.population.sampleFits:
            sample = self.experiment.samples[sampleFit.sampleName]
            sampleWeight = float(sample.getDescriptorValue(scaleModel.predictor))
            sample.setDescriptorValue(scaleModel.predictor,targetWeight)

            for varName, varUnits in scaleModel.averaged_vars:
                if varName in self.population.modelParameters:
                    idx = self.population.modelParameters.index(varName)
                    targetValue = scaleModel.models[varName][0]
                    sampleFit.parameters[0][idx] = targetValue

            for varName, varUnits in scaleModel.scaled_vars:
                if varName in self.population.modelParameters:
                    idx = self.population.modelParameters.index(varName)
                    k = scaleModel.models[varName][0]
                    a = scaleModel.models[varName][1]
                    targetValue = k*math.pow(targetWeight,a)
                    currentValue = k*math.pow(sampleWeight,a)
                    for j in range(sampleFit.parameters.shape[0]):
                        sampleFit.parameters[j][idx] *= targetValue/currentValue

        self.experiment.write(self._getPath("experiment.pkpd"))
        self.population.fnExperiment.set(self._getPath("experiment.pkpd"))
        self.population.write(self._getPath("bootstrapPopulation.pkpd"))

    def createOutputStep(self):
        self._defineOutputs(outputExperiment=self.experiment)
        self._defineOutputs(outputPopulation=self.population)
        self._defineSourceRelation(self.inputPopulation, self.experiment)
        self._defineSourceRelation(self.inputAllometric, self.experiment)
        self._defineSourceRelation(self.inputPopulation, self.population)
        self._defineSourceRelation(self.inputAllometric, self.population)

    #--------------------------- INFO functions --------------------------------------------
    def _summary(self):
        msg = ["Target weight: %f"%self.targetWeight.get()]
        return msg

    def _citations(self):
        return ['Sharma2009','Mahmood1996']