예제 #1
0
파일: OUU.py 프로젝트: elbashandy/FOQUS
    def finishOUU(self, out, error):

        if error:
            return None

        # clean up
        if os.path.exists(OUU.hfile):
            hfile_ = OUU.dname + os.path.sep + OUU.hfile
            os.rename(OUU.hfile, hfile_)
            hfile = hfile_
        for f in os.listdir('.'):
            if 'psuadeOpt' in f:
                os.remove(f)

        # save output for debugging
        f = open('ouu.out', 'w')
        f.write(out)
        f.close()

        # grab optimization results
        if self.ignoreResults:
            self.ignoreResults = False
        else:
            self.results = OUU.getPsuadeResults(out)
            if self.results == None:
                error = 'OUU: Optimization error.'
                Common.showError(error, out)
                return None

        if self.endFunction is not None:
            self.endFunction()
예제 #2
0
파일: SimSetup.py 프로젝트: pn51/FOQUS
    def checkDists(self, tabIndex):
        if tabIndex == 0 or self.ignoreDistributionCheck:
            self.ignoreDistributionCheck = False
            return

        showMessage = False
        if self.distTable.getNumVariables() == 0:
            showMessage = True
            message = "All inputs are fixed! One needs to be variable."
        else:
            valid, error = self.distTable.checkValidInputs()
            if not valid:
                showMessage = True
                message = (
                    "Distribution settings not correct or entirely filled out! %s"
                    % error)
            else:
                rowsToWarnAboutMass = []
                for row in range(self.distTable.rowCount()):
                    for col in [3, 4]:
                        item = self.distTable.item(row, col)
                        if col == 3:
                            minVal = float(item.text())
                        else:
                            maxVal = float(item.text())

                    #### Get distribution parameters
                    for col in [6, 7]:
                        cellTable = self.distTable.cellWidget(row, col)
                        if isinstance(cellTable, QComboBox):
                            continue
                        item = None
                        if cellTable is not None:
                            item = cellTable.item(0, 1)
                        if item is not None and item.text():
                            if col == 6:
                                distParam1 = float(item.text())
                            else:
                                distParam2 = float(item.text())
                        else:
                            if col == 6:
                                distParam1 = None
                            else:
                                distParam2 = None

                    #### Check mass and warn if below 50%
                    # Only collect those that are not fixed to generate inputs
                    combobox = self.distTable.cellWidget(row, 5)
                    dist = combobox.currentIndex()
                    # Create file for psuade input
                    if dist not in [Distribution.UNIFORM, Distribution.SAMPLE]:
                        f = tempfile.SpooledTemporaryFile()
                        for i in range(2):
                            f.write(b"cdf_lookup\n")
                            distNum = dist
                            if dist == Distribution.BETA:
                                distNum = 4
                            elif dist == Distribution.WEIBULL:
                                distNum = 5
                            elif dist == Distribution.GAMMA:
                                distNum = 6
                            elif dist == Distribution.EXPONENTIAL:
                                distNum = 7
                            f.write(b"%d\n" %
                                    distNum)  # Number of distribution
                            f.write(b"%f\n" % distParam1)  # Parameter 1
                            if distParam2 is not None:
                                f.write(b"%f\n" % distParam2)  # Parameter 2
                            if i == 0:
                                val = minVal
                            else:
                                val = maxVal
                            f.write(b"%f\n" % val)  # Min or max value
                        f.write(b"quit\n")
                        f.seek(0)

                        # invoke psuade
                        psuadePath = LocalExecutionModule.getPsuadePath()
                        if psuadePath is None:
                            return
                        p = subprocess.Popen(
                            psuadePath,
                            stdin=f,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            shell=True,
                        )
                        f.close()

                        # process error
                        out, error = p.communicate()
                        if error:
                            Common.showError(error, out)
                            return None

                        # parse output
                        lines = out.splitlines()
                        vals = []
                        for line in lines:
                            if "Cumulative probability = " in line.decode(
                                    "utf-8"):
                                words = line.split()
                                vals.append(float(words[-1]))

                        mass = vals[1] - vals[0]
                        if mass < 0.5:
                            rowsToWarnAboutMass.append(row)

                if len(rowsToWarnAboutMass) > 0:
                    self.samplingTabs.setCurrentIndex(0)
                    for row in rowsToWarnAboutMass:
                        msgbox = QMessageBox()
                        msgbox.setWindowTitle("UQ/Opt GUI Warning")
                        msgbox.setText(
                            "Regarding input " +
                            self.model.getInputNames()[row] +
                            ": Min/max range is narrow for its distribution. "
                            +
                            "This could cause sample generation to take more time.  Continue?"
                        )
                        msgbox.setIcon(QMessageBox.Warning)
                        msgbox.setStandardButtons(QMessageBox.Yes
                                                  | QMessageBox.No)
                        msgbox.setDefaultButton(QMessageBox.Yes)
                        ret = msgbox.exec_()
                        if ret != QMessageBox.Yes:
                            self.distTable.selectRow(row)
                            return
                    self.ignoreDistributionCheck = True
                    self.samplingTabs.setCurrentIndex(1)

        if showMessage:
            self.samplingTabs.setCurrentIndex(0)
            msgbox = QMessageBox()
            msgbox.setWindowTitle("UQ/Opt GUI Warning")
            msgbox.setText(message)
            msgbox.setIcon(QMessageBox.Warning)
            msgbox.exec_()
            return
예제 #3
0
파일: OUU.py 프로젝트: elbashandy/FOQUS
    def writeOUUdata(outfile, outputs, constraints, derivatives, data, xtable,
                     **kwargs):

        # Charles TODO: Handle y is now a list of inputs
        # Charles TODO: Handle derivatives

        # defaults
        rseed = None
        driver = data.getDriverName()
        if driver is None:
            driver = 'NONE'
        optdriver = data.getOptDriverName()
        if optdriver is None:
            optdriver = 'NONE'
        ensoptdriver = data.getEnsembleOptDriverName()
        if ensoptdriver is None:
            ensoptdriver = 'NONE'
        auxdriver = data.getAuxDriverName()
        if auxdriver is None:
            auxdriver = 'NONE'
        inputLB = None
        inputUB = None
        inputDefaults = None
        distributions = None
        init_input = None

        # process keyworded arguments
        for key in kwargs:
            k = key.lower()
            if k == 'randseed':
                rseed = kwargs[key]
            elif k == 'driver':
                driver = kwargs[key]
            elif k == 'optdriver':
                optdriver = kwargs[key]
            elif k == 'ensoptdriver':
                ensoptdriver = kwargs[key]
            elif k == 'auxdriver':
                auxdriver = kwargs[key]
            elif k == 'inputlowerbounds':
                inputLB = kwargs[key]
            elif k == 'inputupperbounds':
                inputUB = kwargs[key]
            elif k == 'inputpdf':
                distributions = kwargs[key]
            elif k == 'init_input':
                init_input = kwargs[key]

        inputTypes = data.getInputTypes()
        nInputs = data.getNumInputs()
        inputNames = data.getInputNames()
        variableInputIndices = []
        for e in xtable:
            if e['type'] != u'Fixed':
                variableInputIndices.append(inputNames.index(e['name']))
        nVariableInputs = len(variableInputIndices)
        nOutputs = len(outputs)
        nSamples = num_fmin = 1  # number of random restarts
        nConstraints = constraints.count(True)
        nDerivatives = derivatives.count(True)
        totalOutputs = nOutputs + nConstraints + nDerivatives

        f = open(outfile, 'w')
        if init_input:
            f.write('PSUADE_IO\n')
            f.write('%d %d %d\n' % (nVariableInputs, totalOutputs, nSamples))
            f.write("1 0\n")  # assume initial point has not been run
            for x in init_input:
                f.write(' % .16e\n' % x)
            for i in xrange(totalOutputs):
                f.write(' 9.9999999999999997e+34\n')
            f.write("PSUADE_IO\n")

        # TO DO: merge with RSAnalyzer.writeRSdata()
        f.write('PSUADE\n')

        # ... input ...
        numFixed = nInputs - nVariableInputs
        f.write('INPUT\n')
        if numFixed > 0:
            f.write('   num_fixed %d\n' % numFixed)
        f.write('   dimension = %d\n' % nVariableInputs)
        if inputLB is None:
            inputLB = data.getInputMins()
        if inputUB is None:
            inputUB = data.getInputMaxs()
        if inputDefaults is None:
            inputDefaults = data.getInputDefaults()
        indices = range(nInputs)
        variableIndex = 1
        fixedIndex = 1
        for i, name, inType, lb, ub, default in zip(indices, inputNames, \
                             inputTypes, inputLB, inputUB, inputDefaults):
            if i in variableInputIndices:  #inType == Model.VARIABLE:
                f.write('   variable %d %s  =  % .16e  % .16e\n' % \
                        (variableIndex, name, lb, ub))
                variableIndex = variableIndex + 1
            else:
                f.write('   fixed %d %s = % .16e\n' %
                        (fixedIndex, name, default))
                fixedIndex = fixedIndex + 1

        # inject discrete variables in psuade
        opttypes = []
        cnt = 0
        for e in xtable:
            cnt = cnt + 1
            t = e['type']
            if t == u'Opt: Primary Discrete (Z1d)':
                opttypes.append(cnt)

        nn = len(opttypes)
        for ii in range(nn):
            jj = opttypes[ii]
            f.write('   discrete %d\n' % (jj))

        if distributions is None:
            distributions = SampleData.getInputDistributions(data)
        for i, inType, dist in zip(indices, inputTypes, distributions):
            if i in variableInputIndices:  #inType == Model.VARIABLE:
                distType = dist.getDistributionType()
                distParams = dist.getParameterValues()
                if distType != Distribution.UNIFORM:
                    f.write('   PDF %d %c' % (i+1, \
                            Distribution.getPsuadeName(distType)))
                    if distType == Distribution.SAMPLE:
                        error = 'OUU: In function writeOUUdata(), '
                        error = error + 'SAMPLE distribution is not supported.'
                        Common.showError(error)
                        return None
                    else:
                        if distParams[0] is not None:
                            f.write(' % .16e' % distParams[0])
                        if distParams[1] is not None:
                            f.write(' % .16e' % distParams[1])
                    f.write('\n')
        f.write('END\n')

        # ... output ...
        outActive = nOutputs
        nConstrs = 0
        nDerivs = 0
        for ii in range(len(constraints)):
            if constraints[ii]:
                outActive = outActive + 1
                nConstrs = nConstrs + 1
        for ii in range(len(derivatives)):
            if derivatives[ii]:
                outActive = outActive + 1
                nDerivs = nDerivs + 1
        if (nOutputs != 1):
            error = 'OUU: In function writeOUUdata(), '
            error = error + 'multi-objective optimization not supported.'
            Common.showError(error)
            return None
        else:
            if ((nConstrs > 0) and (nDerivs > 0)):
                error = 'OUU: In function writeOUUdata(), '
                error = error + 'LBFGS does not support inequality constraints.'
                Common.showError(error)
                return None
            elif ((nDerivs > 0) and (nDerivs != nVariableInputs)):
                error = 'OUU: In function writeOUUdata(), '
                error = error + 'Number of derivatives not correct'
                Common.showError(error)
                return None

        f.write('OUTPUT\n')
        f.write('   dimension = %d\n' % (outActive))
        outputNames = SampleData.getOutputNames(data)
        for ii in range(nOutputs):
            ind = outputs[ii]
            f.write('   variable %d %s\n' % (ii + 1, outputNames[ind - 1]))
            print('   variable %d %s\n' % (ii + 1, outputNames[ind - 1]))
        outActive = nOutputs + 1
        for ii in range(len(constraints)):
            if constraints[ii]:
                f.write('   variable %d %s\n' % (outActive, outputNames[ii]))
                print('   variable %d %s\n' % (outActive, outputNames[ii]))
                outActive = outActive + 1
        for ii in range(len(derivatives)):
            if derivatives[ii]:
                f.write('   variable %d %s\n' % (outActive, outputNames[ii]))
                print('   variable %d %s\n' % (outActive, outputNames[ii]))
                outActive = outActive + 1
        f.write('END\n')

        # ... method ...
        f.write('METHOD\n')
        f.write('   sampling = MC\n')  # OUU uses this to create
        f.write('   num_samples = 1\n')  # initial guess
        if rseed is not None:
            f.write('random_seed = %d\n' % rseed)  # random seed
        f.write('END\n')

        # ... application ...
        f.write('APPLICATION\n')
        if platform.system() == 'Windows':
            import win32api
            if driver != 'NONE' and driver != 'PSUADE_LOCAL':
                driver = win32api.GetShortPathName(driver)
            if optdriver != 'NONE' and optdriver != 'PSUADE_LOCAL':
                optdriver = win32api.GetShortPathName(optdriver)
            if ensoptdriver != 'NONE' and ensoptdriver != 'PSUADE_LOCAL':
                ensoptdriver = win32api.GetShortPathName(ensoptdriver)
            if auxdriver != 'NONE' and auxdriver != 'PSUADE_LOCAL':
                auxdriver = win32api.GetShortPathName(auxdriver)
        f.write('   driver = %s\n' % driver)
        f.write('   opt_driver = %s\n' % optdriver)
        f.write('   ensemble_opt_driver = %s\n' % ensoptdriver)
        f.write('   aux_opt_driver = %s\n' % auxdriver)
        f.write('   launch_interval = 0\n')
        f.write('END\n')

        # ... analysis ...
        f.write('ANALYSIS\n')
        if (nDerivs > 0):
            f.write('   optimization method = ouu_lbfgs\n')
        else:
            f.write('   optimization method = ouu\n')
        f.write('   optimization num_local_minima = 1\n')
        f.write('   optimization max_feval = 1000000\n')
        f.write('   optimization fmin = 0.0\n')
        f.write('   optimization tolerance = 1.000000e-06\n')
        f.write('   optimization num_fmin = %d\n' % num_fmin)
        f.write('   optimization print_level = 3\n')
        #f.write('   analyzer output_id = %d\n' % y)
        f.write('   analyzer output_id = 1\n')
        f.write('   opt_expert\n')
        f.write('   printlevel 0\n')
        f.write('END\n')

        f.write('END\n')
        f.close()

        return outfile
예제 #4
0
파일: OUU.py 프로젝트: elbashandy/FOQUS
    def ouu(self,
            fname,
            y,
            outputsAsConstraint,
            outputsAsDerivative,
            xtable,
            phi,
            x3sample=None,
            x4sample=None,
            useRS=False,
            useBobyqa=True,
            driver=None,
            optDriver=None,
            auxDriver=None,
            ensOptDriver=None,
            plotSignal=None,
            endFunction=None):

        # Function to execute after inference has finished.
        # Function would enable button again and such things.
        self.endFunction = endFunction

        # read data, assumes data already have fixed variables written to file
        data = LocalExecutionModule.readSampleFromPsuadeFile(fname)
        if optDriver == None and ensOptDriver == None and \
               data.getOptDriverName() == None and \
               data.getEnsembleOptDriverName() == None:
            Common.showError('Model file does not have any drivers set!', \
                             showDeveloperHelpMessage = False)
            self.hadError = True
            if endFunction is not None:
                endFunction()
            return
        if driver != None:
            data.setDriverName(driver)
        if optDriver != None:
            data.setOptDriverName(optDriver)
        if auxDriver != None:
            data.setAuxDriverName(auxDriver)
        if ensOptDriver != None:
            data.setEnsembleOptDriverName(ensOptDriver)
        else:
            ensOptDriver = data.getEnsembleOptDriverName()

        # Remove file that tells OUU to stop
        if os.path.exists(OUU.stopFile):
            os.remove(OUU.stopFile)

        # process input table
        dname = OUU.dname
        deleteFiles = True
        if x3sample is not None:
            deleteFiles = not x3sample['file'].startswith(dname)
        #Common.initFolder(dname, deleteFiles = deleteFiles)
        if platform.system() == 'Windows':
            import win32api
            dname = win32api.GetShortPathName(dname)
        fnameOUU = Common.getLocalFileName(dname, fname, '.ouudat')
        p = RSAnalyzer.parsePrior(data, xtable)
        if p is not None:
            inputLB = p['inputLB']
            inputUB = p['inputUB']
            dist = p['dist']

        init_input = []
        vartypes = []
        for e in xtable:
            t = e['type']
            if t == u'Opt: Primary Continuous (Z1)':
                vartypes.append(1)
            elif t == u'Opt: Primary Continuous (Z1c)':
                vartypes.append(1)
            elif t == u'Opt: Primary Discrete (Z1d)':
                vartypes.append(1)
            elif t == u'Opt: Recourse (Z2)':
                vartypes.append(2)
            elif t == u'UQ: Discrete (Z3)':
                vartypes.append(3)
            elif t == u'UQ: Continuous (Z4)':
                vartypes.append(4)
            if t != u'Fixed':
                init_input.append(e['value'])
        M1 = vartypes.count(1)
        M2 = vartypes.count(2)
        M3 = vartypes.count(3)
        M4 = vartypes.count(4)

        # check arguments
        if M1 < 1:
            error = 'OUU: In function ouu(), number of Z1 (design opt) '
            error = error + 'must be at least 1.'
        if M3 > 0:
            if x3sample == None:
                error = 'OUU: In function ouu(), "x3sample" is undefined.'
                Common.showError(error)
                return None

        if M4 > 0:
            if x4sample == None:
                error = 'OUU: In function ouu(), "x4sample" is undefined.'
                Common.showError(error)
                return None
            loadcs = 'file' in x4sample
            if loadcs:
                N = 0  # number of samples in x4sample['file']

                ### TO DO for Jeremy: check sample size in GUI
                with open(x4sample['file']) as f:
                    header = f.readline()
                    header = header.split()
                    N = int(header[0])

                Nmin = M4 + 1  # minimum number of samples
                if N < Nmin:
                    error = 'OUU: In function ouu(), "x4sample file" requires '
                    error = error + 'at least %d samples.' % Nmin
                    Common.showError(error)
                    return None
                if useRS:
                    Nrs = 'nsamplesRS' in x4sample
                    if not Nrs:
                        error = 'OUU: In function ouu(), "x4sample nsamplesRS" is '
                        error = error + 'required for setting up response surface.'
                        Common.showError(error)
                        return None
                    Nrs = x4sample['nsamplesRS']
                    Nrs = min(max(Nrs, Nmin),
                              N)  ### TO DO for Jeremy: check in GUI

        # TO DO: remove randSeed
        ouuFile = OUU.writeOUUdata(fnameOUU,
                                   y,
                                   outputsAsConstraint,
                                   outputsAsDerivative,
                                   data,
                                   xtable,
                                   randSeed=41491431,
                                   inputLowerBounds=inputLB,
                                   inputUpperBounds=inputUB,
                                   inputPDF=dist,
                                   useEnsOptDriver=(ensOptDriver != None),
                                   init_input=init_input)
        if (ouuFile == None):
            return None

        # write script
        f = OUU.writescript(vartypes,
                            fnameOUU,
                            outputsAsConstraint,
                            phi,
                            x3sample,
                            x4sample,
                            useRS,
                            useBobyqa,
                            useEnsOptDriver=(ensOptDriver != None))

        # delete previous history file
        if os.path.exists(OUU.hfile):
            os.remove(OUU.hfile)

        self.textDialog = Common.textDialog()
        self.thread = psuadeThread(self, f, self.finishOUU, self.textDialog,
                                   plotSignal)
        self.thread.start()
예제 #5
0
파일: OUU.py 프로젝트: elbashandy/FOQUS
    def compress(fname):

        N = 0  # number of samples in x3sample['file']
        with open(fname) as f:  ### TO DO for Jeremy: check sample size in GUI
            header = f.readline()
            header = header.split()
            N = int(header[0])
            nInputs = int(header[1])

        Nmin = 100  # psuade minimum for genhistogram
        if N < Nmin:
            warn = 'OUU: In function compress(), "x3sample file" requires '
            warn = warn + 'at least %d samples.' % Nmin
            Common.showError(warn)
            return {N: fname}  # return original sample file

        outfiles = {}
        nbins_max = 20
        nscenarios_max = 1501
        for nbins in xrange(2, nbins_max):

            # write script to invoke scenario compression
            f = tempfile.SpooledTemporaryFile()
            if platform.system() == 'Windows':
                import win32api
                fname = win32api.GetShortPathName(fname)
            f.write('read_std %s\n' % fname)
            f.write('genhistogram\n')
            for x in xrange(nInputs):
                f.write('%d\n' % nbins)
            f.write('quit\n')
            f.seek(0)

            # invoke psuade
            out, error = Common.invokePsuade(f)
            f.close()
            if error:
                return None

            # check output file
            sfile = 'psuade_pdfhist_sample'
            if os.path.exists(sfile):
                Ns = 0  # number of samples in psuade_pdfhist_sample
                with open(sfile) as f:
                    header = f.readline()
                    header = header.split()
                    Ns = int(header[0])
                sfile_ = Common.getLocalFileName(OUU.dname, fname,
                                                 '.compressed' + str(Ns))
                if os.path.exists(sfile_):
                    os.remove(sfile_)
                os.rename(sfile, sfile_)
                sfile = sfile_
            else:
                error = 'OUU: %s does not exist.' % sfile
                Common.showError(error, out)
                return None

            # append scenario file to data structure
            if len(outfiles) > 1 and Ns > min(N, nscenarios_max):
                return outfiles
            else:
                outfiles[Ns] = (sfile, nbins)

        return outfiles