def calcScenarios(self): self.freeze() self.writeTableToFile(self.z3_table, 'z3Samples.smp', len(self.input_table.getUQDiscreteVariables()[0])) self.scenarioFiles = OUU.compress('z3Samples.smp') if self.scenarioFiles is not None: self.scenarioSelect_combo.clear() for i, n in enumerate(sorted(self.scenarioFiles.keys())): self.scenarioSelect_combo.addItem(str(n)) self.scenarioSelect_combo.setItemData(i, '%d bins per dimension' % self.scenarioFiles[n][1], QtCore.Qt.ToolTipRole) self.scenarioSelect_static.setEnabled(True) self.scenarioSelect_combo.setEnabled(True) self.scenariosCalculated = True self.unfreeze()
def analyze(self): dir = os.getcwd() for f in os.listdir(dir): if re.search('psuadeEval.out', f): os.remove(os.path.join(dir, f)) if self.run_button.text() == 'Run OUU': # Run OUU names, indices = self.input_table.getPrimaryVariables() if len(names) == 0: QMessageBox.information(self, 'No Primary Variables', 'At least one input must be a primary variable!') return valid, error = self.input_table.checkValidInputs() if not valid: QMessageBox.information(self, 'Input Table Distributions', 'Input table distributions are either not correct or not filled out completely! %s' % error) return if self.compressSamples_chk.isChecked() and not self.scenariosCalculated: QMessageBox.information(self, 'Compress Samples Not Calculated', 'You have elected to compress samples for discrete random variables (Z3), but have not selected the sample size to use!') return M1 = len(self.input_table.getPrimaryVariables()[0]) M2 = len(self.input_table.getRecourseVariables()[0]) M3 = len(self.input_table.getUQDiscreteVariables()[0]) M4 = len(self.input_table.getContinuousVariables()[0]) Common.initFolder(OUU.dname) self.managePlots() self.clearPlots() self.manageBestValueTable() self.summary_group.setTitle('Best So Far') xtable = self.input_table.getTableValues() # get arguments for ouu() model = copy.deepcopy(self.model) inputNames = model.getInputNames() inputTypes = list(model.getInputTypes()) defaultValues = model.getInputDefaults() for row in xtable: if row['type'] == 'Fixed': modelIndex = inputNames.index(row['name']) inputTypes[modelIndex] = Model.FIXED defaultValues[modelIndex] = row['value'] #print inputTypes #print defaultValues model.setInputTypes(inputTypes) model.setInputDefaults(defaultValues) data = SampleData(model) fname = 'ouuTemp.dat' data.writeToPsuade(fname) # Outputs numOutputs = self.outputs_table.rowCount() y = [] self.useAsConstraint = [False] * numOutputs self.useAsDerivative = [False] * numOutputs for r in range(numOutputs): type = self.outputs_table.cellWidget(r,0).currentText() if type == ouuSetupFrame.ObjFuncText: y.append(r + 1) elif type == ouuSetupFrame.ConstraintText: self.useAsConstraint[r] = True elif type == ouuSetupFrame.DerivativeText: self.useAsDerivative[r] = True if self.mean_radio.isChecked(): phi = {'type':1} elif self.meanWithBeta_radio.isChecked(): beta = self.betaDoubleSpin.value() phi = {'type':2, 'beta':beta} elif self.alpha_radio.isChecked(): alpha = self.alphaDoubleSpin.value() phi = {'type':3, 'alpha':alpha} x3sample = None if M3 > 0: if self.compressSamples_chk.isChecked(): selectedSamples = int(self.scenarioSelect_combo.currentText()) sfile = self.scenarioFiles[selectedSamples][0] else: sfile = 'z3Samples.smp' success = self.writeTableToFile(self.z3_table, sfile, M3) if not success: return if sfile.endswith('.csv'): # Convert .csv file to simple file newFileName = OUU.dname + os.sep + os.path.basename(fname)[:-4] + '.smp' inData = LocalExecutionModule.readDataFromCsvFile(sfile, askForNumInputs=False) LocalExecutionModule.writeSimpleFile(newFileName, inData[0]) sfile = newFileName #print 'x3 file is', sfile x3sample = {'file':sfile} # x3sample file data,_, numInputs, _ = LocalExecutionModule.readDataFromSimpleFile(sfile, hasColumnNumbers=False) if numInputs != M3: QMessageBox.critical(self, "Number of variables don't match", 'The number of variables from the file (%d) does not match the number of Z3 discrete variables (%d). You will not be able to perform analysis until this is corrected.' % (numInputs, M3)) return useRS = self.x4RSMethod_check.isChecked() x4sample = None if self.z4NewSample_radio.isChecked(): method = self.x4SampleScheme_combo.currentText() method = SamplingMethods.getEnumValue(method) N = self.x4SampleSize_spin.value() if method in [SamplingMethods.LH,SamplingMethods.LPTAU]: x4sample = {'method':method, 'nsamples':N} # number of samples (range: [M1+1,1000]) elif method == SamplingMethods.FACT: x4sample = {'method':method, 'nlevels':N} # number of levels (range: [3,100]) else: sfile = 'z4Samples.smp' success = self.writeTableToFile(self.z4_table, sfile, M4) if not success: return if len(sfile) == 0: QMessageBox.critical(self, 'Missing file', 'Z4 sample file not specified!') return if sfile.endswith('.csv'): # Convert .csv file to simple file newFileName = OUU.dname + os.sep + os.path.basename(fname)[:-4] + '.smp' inData = LocalExecutionModule.readDataFromCsvFile(sfile, askForNumInputs=False) LocalExecutionModule.writeSimpleFile(newFileName, inData[0]) sfile = newFileName inData, outData, numInputs, numOutputs = LocalExecutionModule.readDataFromSimpleFile(sfile, hasColumnNumbers=False) numSamples = inData.shape[0] if numInputs != M4: QMessageBox.critical(self, "Number of variables don't match", 'The number of input variables from the file (%d) does not match the number of Z4 continuous variables (%d). You will not be able to perform analysis until this is corrected.' % (numInputs, M4)) return if numSamples <= M4: QMessageBox.critical(self, 'Not enough samples', 'Z4 sample file must have at least %d samples!' % (M4 + 1)) return x4sample = {'file': sfile} # x4sample file, must have at least M4+1 samples if useRS: Nrs = self.z4SubsetSize_spin.value() # add spinbox to get number of samples to generate RS x4sample['nsamplesRS'] = Nrs # TO DO: make sure spinbox has M4+1 as min and x4sample's sample size as max # TODO: Get rid of usebobyqa option. Behavior should be as if usebobyqa is always false # TODO: Change GUI to display optimizer and optimizing with bobyqa # TODO: Get rid of primarySolver_combo completely useBobyqa = False method = self.primarySolver_combo.currentText() if method == "BOBYQA": pass elif method == "NEWUOA": pass if 'simulator' in self.secondarySolver_combo.currentText(): useBobyqa = True # use BOBYQA if driver is a simulator, not an optimizer self.run_button.setText('Stop') optDriver = None ensembleOptDriver = None if self.node_radio.isChecked(): ensembleOptDriver = self.setupPSUADEClient() optDriver = ensembleOptDriver listener = listen.foqusListener(self.dat) variableNames = [] fixedNames = [] for row in xtable: #print row if row['type'] == 'Fixed': fixedNames.append(row['name']) else: variableNames.append(row['name']) #print fixedNames, variableNames #print variableNames + fixedNames listener.inputNames = variableNames + fixedNames outputNames = self.model.getOutputNames() listener.outputNames = [outputNames[yItem-1] for yItem in y] listener.failValue = -111111 self.listenerAddress = listener.address listener.start() # print M1, M2, M3, M4, useBobyqa self.OUUobj = OUU() try: results = self.OUUobj.ouu(fname,y,self.useAsConstraint,self.useAsDerivative,xtable,phi, x3sample=x3sample,x4sample=x4sample,useRS=useRS,useBobyqa=useBobyqa, optDriver = optDriver, ensOptDriver = ensembleOptDriver, plotSignal = self.plotSignal, endFunction=self.finishOUU) except: import traceback traceback.print_exc() if self.node_radio.isChecked(): # stop the listener conn = Client(self.listenerAddress) conn.send(['quit']) conn.close() # enable run button self.run_button.setEnabled(True) return else: # Stop OUU self.OUUobj.stopOUU() self.run_button.setEnabled(False) self.freeze()
class ouuSetupFrame(_ouuSetupFrame, _ouuSetupFrameUI): plotSignal = QtCore.pyqtSignal(dict) NotUsedText = "Not used" ObjFuncText = "Objective Function" ConstraintText = "Inequality Constraint" DerivativeText = "Derivative" def __init__(self, dat = None, parent=None): super(ouuSetupFrame, self).__init__(parent=parent) self.setupUi(self) self.dat = dat self.filesDir = '' self.scenariosCalculated = False self.result = None self.useAsConstraint = None self.plotsToUpdate = [0] self.objLine = None # Refresh table self.refresh() self.plotSignal.connect(self.addPlotValues) self.setFixed_button.setEnabled(False) self.setX1_button.setEnabled(False) self.setX1d_button.setEnabled(False) self.setX2_button.setEnabled(False) self.setX3_button.setEnabled(False) self.setX4_button.setEnabled(False) self.input_table.setColumnHidden(3, True) # Hide scale column self.modelFile_edit.clear() self.modelFile_radio.setChecked(True) self.uqTab = self.tabs.widget(2) self.tabs.removeTab(2) self.tabs.setCurrentIndex(0) self.tabs.setEnabled(False) self.output_label.setHidden(True) self.output_combo.setHidden(True) self.output_combo.setEnabled(False) self.mean_radio.setChecked(True) self.betaDoubleSpin.setValue(0) self.alphaDoubleSpin.setValue(0.5) self.primarySolver_combo.setEnabled(False) self.secondarySolver_combo.setCurrentIndex(0) self.z3_table.setRowCount(1) self.compressSamples_chk.setEnabled(False) self.calcScenarios_button.setEnabled(False) self.scenarioSelect_static.setEnabled(False) self.scenarioSelect_combo.setEnabled(False) self.z4NewSample_radio.setChecked(True) self.x4SampleScheme_combo.setCurrentIndex(0) self.x4SampleSize_label.setText('Sample Size') self.x4SampleSize_spin.setValue(5) self.x4SampleSize_spin.setRange(5,1000) self.x4FileBrowse_button.setEnabled(False) self.x4SampleScheme_combo.clear() self.x4SampleScheme_combo.addItems([SamplingMethods.getFullName(SamplingMethods.LH), SamplingMethods.getFullName(SamplingMethods.LPTAU), SamplingMethods.getFullName(SamplingMethods.FACT)]) self.x4RSMethod_check.setChecked(False) self.z4_table.setEnabled(False) self.z4_table.setRowCount(1) self.z4SubsetSize_label.setEnabled(False) self.z4SubsetSize_spin.setEnabled(False) self.run_button.setEnabled(True) self.summary_group.setMaximumHeight(250) self.progress_group.setMaximumHeight(250) self.setWindowTitle('Optimization Under Uncertainty (OUU)') # Connect signals self.node_radio.toggled.connect(self.chooseNode) self.node_combo.currentIndexChanged.connect(self.loadNodeData) self.modelFile_radio.toggled.connect(self.chooseModel) self.modelFileBrowse_button.clicked.connect(self.loadModelFileData) self.input_table.typeChanged.connect(self.setCounts) #self.input_table.typeChanged.connect(self.managePlots) #self.input_table.typeChanged.connect(self.manageBestValueTable) self.setFixed_button.clicked.connect(self.setFixed) self.setX1_button.clicked.connect(self.setX1) self.setX1d_button.clicked.connect(self.setX1d) self.setX2_button.clicked.connect(self.setX2) self.setX3_button.clicked.connect(self.setX3) self.setX4_button.clicked.connect(self.setX4) self.z4NewSample_radio.toggled.connect(self.chooseZ4NewSample) self.z4LoadSample_radio.toggled.connect(self.chooseZ4LoadSample) self.x4SampleSize_spin.valueChanged.connect(self.setZ4RS) self.z4SubsetSize_spin.valueChanged.connect(self.setZ4RS) self.x3FileBrowse_button.clicked.connect(self.loadX3Sample) self.compressSamples_chk.toggled.connect(self.activateCompressSample) self.calcScenarios_button.clicked.connect(self.calcScenarios) self.x4SampleScheme_combo.currentIndexChanged.connect(self.setX4Label) self.x4FileBrowse_button.clicked.connect(self.loadX4Sample) self.x4RSMethod_check.toggled.connect(self.showZ4Subset) self.run_button.clicked.connect(self.analyze) self.z3_table.cellChanged.connect(self.z3TableCellChanged) self.z4_table.cellChanged.connect(self.z4TableCellChanged) self.progressScrollArea.verticalScrollBar().valueChanged.connect(self.scrollProgressPlots) def freeze(self): QApplication.setOverrideCursor(QCursor(QtCore.Qt.WaitCursor)) def semifreeze(self): QApplication.setOverrideCursor(QCursor(QtCore.Qt.BusyCursor)) def unfreeze(self): QApplication.restoreOverrideCursor() def refresh(self): if self.dat is not None: nodes = sorted(self.dat.flowsheet.nodes.keys()) items = ['Select node'] items.extend(nodes) items.append('Full flowsheet') self.node_combo.clear() self.node_combo.addItems(items) self.node_radio.setChecked(True) else: self.node_radio.setEnabled(False) self.node_combo.setEnabled(False) self.modelFile_radio.setChecked(True) self.input_table.clearContents() self.input_table.setRowCount(0) self.modelFile_edit.clear() self.output_combo.clear() self.bestValue_table.clearContents() self.bestValue_table.setRowCount(2) self.clearPlots() def chooseNode(self, value): if value: self.node_combo.setEnabled(True) self.modelFile_edit.setEnabled(False) self.modelFileBrowse_button.setEnabled(False) def chooseModel(self, value): if value: self.node_combo.setEnabled(False) self.modelFile_edit.setEnabled(True) self.modelFileBrowse_button.setEnabled(True) def loadNodeData(self): nodeName = self.node_combo.currentText() if nodeName in ['', 'Select node']: return if nodeName == 'Full flowsheet': self.model = flowsheetToUQModel(self.dat.flowsheet) else: node = self.dat.flowsheet.nodes[nodeName] self.model = nodeToUQModel(nodeName, node) self.input_table.init(self.model, InputPriorTable.OUU) self.setFixed_button.setEnabled(True) self.setX1_button.setEnabled(True) self.setX1d_button.setEnabled(True) self.setX2_button.setEnabled(True) self.setX3_button.setEnabled(True) self.setX4_button.setEnabled(True) self.initTabs() self.setCounts() def loadModelFileData(self): if platform.system() == 'Windows': allFiles = '*.*' else: allFiles = '*' fname,_ = QFileDialog.getOpenFileName(self, 'Open Model File', self.filesDir, 'Model files (*.in *.dat *.psuade *.filtered);;All files (%s)' % allFiles) if fname == '': return self.filesDir, name = os.path.split(fname) self.modelFile_edit.setText(fname) self.model = LocalExecutionModule.readSampleFromPsuadeFile(fname) self.model = self.model.model self.input_table.init(self.model, InputPriorTable.OUU) self.setFixed_button.setEnabled(True) self.setX1_button.setEnabled(True) self.setX1d_button.setEnabled(True) self.setX2_button.setEnabled(True) self.setX3_button.setEnabled(True) self.setX4_button.setEnabled(True) self.initTabs() self.setCounts() ##### Brenda: Start here! ##### def getSampleFileData(self): if platform.system() == 'Windows': allFiles = '*.*' else: allFiles = '*' fname,_ = QFileDialog.getOpenFileName(self, 'Open Sample File', self.filesDir, "Psuade Simple Files (*.smp);;CSV (Comma delimited) (*.csv);;All files (%s)" % allFiles) if fname == '': return (None, None) self.filesDir, name = os.path.split(fname) try: if fname.endswith('.csv'): data = LocalExecutionModule.readDataFromCsvFile(fname, askForNumInputs=False) else: data = LocalExecutionModule.readDataFromSimpleFile(fname, hasColumnNumbers = False) data = data[0] return (fname, data) except: import traceback traceback.print_exc() QMessageBox.critical(self, 'Incorrect format', 'File does not have the correct format! Please consult the users manual about the format.') return (None, None) def loadX3Sample(self): fname, data = self.getSampleFileData() if fname is None: return numInputs = data.shape[1] M3 = len(self.input_table.getUQDiscreteVariables()[0]) if numInputs != M3: QMessageBox.warning(self, "Number of variables don't match", 'The number of variables from the file (%d) does not match the number of Z3 discrete variables (%d). You will not be able to perform analysis until this is corrected.' % (numInputs, M3)) else: self.compressSamples_chk.setEnabled(True) self.loadTable(self.z3_table, data) def loadTable(self, table, data): numSamples = data.shape[0] numInputs = data.shape[1] table.setRowCount(numSamples + 1) for r in range(numSamples): for c in range(numInputs): item = QTableWidgetItem('%g' % data[r,c]) table.setItem(r, c, item) table.resizeColumnsToContents() def z3TableCellChanged(self, row, col): self.randomVarTableCellChanged(self.z3_table, row, col) self.compressSamples_chk.setEnabled(True) def z4TableCellChanged(self, row, col): self.randomVarTableCellChanged(self.z4_table, row, col) def randomVarTableCellChanged(self, table, row, col): if row == table.rowCount() - 1: table.setRowCount(table.rowCount() + 1) def writeTableToFile(self, table, fileName, numCols): names = {self.z3_table: 'Z3', self.z4_table: 'Z4'} assert(numCols <= table.columnCount()) values = [] for r in range(table.rowCount()): rowVals = [] rowHasData = False rowFull = True for c in range(numCols): item = table.item(r,c) if not item: rowFull = False else: text = item.text() if not text: rowFull = False else: try: rowVals.append(float(text)) rowHasData = True except ValueError: rowFull = False if not rowFull and rowHasData: break if rowFull: values.append(rowVals) if not values or (rowHasData and not rowFull): QMessageBox.warning(self, "Missing data", 'The %s table is missing required data!' % names[table]) return False # Failed LocalExecutionModule.writeSimpleFile(fileName, values, rowLabels = False) return True def activateCompressSample(self, on): if on: rowCount = 0 for r in range(self.z3_table.rowCount()): for c in range(self.z3_table.columnCount()): rowFull = True item = self.z3_table.item(r,c) if item: text = item.text() if not text: rowFull = False break try: float(text) except ValueError: rowFull = False break else: break if rowFull: rowCount += 1 if rowCount < 100: QMessageBox.warning(self, "Not enough samples in file", 'The file requires at least 100 samples for compression.') self.compressSamples_chk.setChecked(False) return self.calcScenarios_button.setEnabled(on) if self.scenariosCalculated: self.scenarioSelect_static.setEnabled(True) self.scenarioSelect_combo.setEnabled(True) def calcScenarios(self): self.freeze() self.writeTableToFile(self.z3_table, 'z3Samples.smp', len(self.input_table.getUQDiscreteVariables()[0])) self.scenarioFiles = OUU.compress('z3Samples.smp') if self.scenarioFiles is not None: self.scenarioSelect_combo.clear() for i, n in enumerate(sorted(self.scenarioFiles.keys())): self.scenarioSelect_combo.addItem(str(n)) self.scenarioSelect_combo.setItemData(i, '%d bins per dimension' % self.scenarioFiles[n][1], QtCore.Qt.ToolTipRole) self.scenarioSelect_static.setEnabled(True) self.scenarioSelect_combo.setEnabled(True) self.scenariosCalculated = True self.unfreeze() def loadX4Sample(self): fname, inData = self.getSampleFileData() if fname is None: return numInputs = inData.shape[1] numSamples = inData.shape[0] self.z4SubsetSize_spin.setMaximum(numSamples) self.z4SubsetSize_spin.setValue(min(numSamples,100)) M4 = len(self.input_table.getContinuousVariables()[0]) if numInputs != M4: QMessageBox.warning(self, "Number of variables don't match", 'The number of input variables from the file (%d) does not match the number of Z4 continuous variables (%d). You will not be able to perform analysis until this is corrected.' % (numInputs, M4)) else: self.loadTable(self.z4_table, inData) def setX4Label(self): method = self.x4SampleScheme_combo.currentText() if method in [SamplingMethods.getFullName(SamplingMethods.LH), SamplingMethods.getFullName(SamplingMethods.LPTAU)]: self.x4SampleSize_label.setText('Sample Size') numM1 = len(self.input_table.getPrimaryVariables()[0]) self.x4SampleSize_spin.setRange(numM1 + 1,1000) self.x4SampleSize_spin.setValue(numM1 + 1) self.x4SampleSize_spin.setSingleStep(1) elif method == SamplingMethods.getFullName(SamplingMethods.FACT): self.x4SampleSize_label.setText('Number of Levels') self.x4SampleSize_spin.setRange(3,100) self.x4SampleSize_spin.setValue(3) self.x4SampleSize_spin.setSingleStep(2) def initTabs(self): self.tabs.setEnabled(True) self.tabs.setCurrentIndex(0) outputNames = self.model.getOutputNames() # Optimization Setup self.output_combo.setEnabled(True) self.output_combo.clear() self.output_combo.addItems(outputNames) self.mean_radio.setChecked(True) self.betaDoubleSpin.setValue(0) self.alphaDoubleSpin.setValue(0.5) self.secondarySolver_combo.setCurrentIndex(0) # Outputs self.outputs_table.blockSignals(True) self.outputs_table.setColumnCount(2) self.outputs_table.setRowCount(len(outputNames)) self.useAsConstraint = [False] * len(outputNames) self.useAsDerivative = [False] * len(outputNames) for r in range(len(outputNames)): # radio = QRadioButton() # if r == 0: # radio.setChecked(True) # radio.setProperty('row', r) # radio.toggled.connect(self.setObjectiveFunction) # self.outputs_table.setCellWidget(r, 0, radio) combobox = QComboBox() combobox.addItems([ouuSetupFrame.NotUsedText, ouuSetupFrame.ObjFuncText, ouuSetupFrame.ConstraintText, ouuSetupFrame.DerivativeText]) if r == 0: combobox.setCurrentIndex(1) self.outputs_table.setCellWidget(r, 0, combobox) item = QTableWidgetItem(outputNames[r]) self.outputs_table.setItem(r, 1, item) # item = QTableWidgetItem() # item.setCheckState(QtCore.Qt.Unchecked) # self.outputs_table.setItem(r, 2, item) # if r == 0: # flags = item.flags() # flags &= (~QtCore.Qt.ItemIsEnabled) # item.setFlags(flags) self.outputs_table.resizeColumnsToContents() self.outputs_table.blockSignals(False) # UQ Setup self.compressSamples_chk.setChecked(False) self.compressSamples_chk.setEnabled(False) self.scenariosCalculated = False self.scenarioSelect_static.setEnabled(False) self.scenarioSelect_combo.setEnabled(False) self.scenarioSelect_combo.clear() self.x4SampleScheme_combo.setCurrentIndex(0) self.x4SampleSize_label.setText('Sample Size') self.x4SampleSize_spin.setValue(5) self.x4SampleSize_spin.setRange(5,1000) self.x4RSMethod_check.setChecked(False) # Launch/Progress self.run_button.setEnabled(True) # TO DO: disable until inputs are validated self.bestValue_table.setColumnCount(1) self.bestValue_table.clearContents() # Plots self.plots_group = QGroupBox() self.plotsLayout = QVBoxLayout() self.plots_group.setLayout(self.plotsLayout) self.progressScrollArea.setMinimumHeight(150) self.progressScrollArea.setWidget(self.plots_group) self.plots_group.setMinimumHeight(150) self.objFig = Figure( figsize=(400,200), dpi=72, facecolor=(1,1,1), edgecolor=(0,0,0), tight_layout = True) self.objCanvas = FigureCanvas(self.objFig) self.objFigAx = self.objFig.add_subplot(111) self.objFigAx.set_title('OUU Progress') self.objFigAx.set_ylabel('Objective') self.objFigAx.set_xlabel('Iteration') self.objLine = None self.plotsLayout.addWidget(self.objCanvas) self.objCanvas.setParent(self.plots_group) self.inputPlots = [] self.objXPoints = [] self.objYPoints = [] self.objPlotPoints = None # def setObjectiveFunction(self, on): # self.outputs_table.blockSignals(True) # row = self.sender().property('row') # item = self.outputs_table.item(row, 2) # Checkbox for inequality constraint # flags = item.flags() # if on: # flags &= ~QtCore.Qt.ItemIsEnabled # item.setCheckState(QtCore.Qt.Unchecked) # else: # flags |= QtCore.Qt.ItemIsEnabled # item.setCheckState(QtCore.Qt.Checked if self.useAsConstraint[row] else QtCore.Qt.Unchecked) # item.setFlags(flags) # def toggleConstraintStatus(self, item): # self.useAsConstraint[item.row()] = (item.checkState() == QtCore.Qt.Checked) # def manageBestValueTable(self): self.bestValue = None names, indices = self.input_table.getPrimaryVariables() self.bestValue_table.setRowCount(len(names) + 2) self.bestValue_table.setVerticalHeaderLabels(['Iteration', 'Objective Value'] + names) self.bestValue_table.clearContents() def setBestValueTable(self, iteration, objValue, inputs): item = self.bestValue_table.item(0, 0) #iteration if item is None: self.bestValue_table.setItem(0, 0, QTableWidgetItem('%d' % iteration)) else: item.setText('%d' % iteration) if self.bestValue == None or objValue < self.bestValue: self.bestValue = objValue item = self.bestValue_table.item(1, 0) #objective value if item is None: self.bestValue_table.setItem(1, 0, QTableWidgetItem('%f' % objValue)) else: item.setText('%f' % objValue) for i, value in enumerate(inputs): item = self.bestValue_table.item(i + 2, 0) #input if item is None: self.bestValue_table.setItem(i + 2, 0, QTableWidgetItem('%f' % value)) else: item.setText('%f' % value) def addPlotValues(self, valuesDict): self.addPointToObjPlot(valuesDict['objective']) self.addToInputPlots(valuesDict['input']) (iteration, objValue) = valuesDict['objective'] self.setBestValueTable(iteration, objValue, valuesDict['input'][1:]) def addPointToObjPlot(self, x): self.objXPoints.append(x[0]) self.objYPoints.append(x[1]) if 0 in self.plotsToUpdate: numPoints = len(self.objXPoints) if numPoints % math.ceil(float(numPoints)/30) == 0: # limit refresh rate as number of points gets large self.updateObjPlot() def updateObjPlot(self): self.objLine, = self.objFigAx.plot(self.objXPoints, self.objYPoints, 'bo') self.objCanvas.draw() def addToInputPlots(self, x): for i in range(len(self.inputPoints)): self.inputPoints[i].append(x[i]) if i > 0 and i in self.plotsToUpdate: numPoints = len(self.inputPoints[i]) if numPoints % math.ceil(float(numPoints)/30) == 0: # limit refresh rate as number of points gets large self.updateInputPlot(i) def updateInputPlot(self, index): # Index starts at 1 for first input plot self.inputPlots[index - 1]['ax'].plot(self.inputPoints[0], self.inputPoints[index], 'bo') self.inputPlots[index - 1]['canvas'].draw() def managePlots(self): names, indices = self.input_table.getPrimaryVariables() if len(self.inputPlots) < len(names): # add plots for i in range(len(self.inputPlots), len(names)): fig = Figure( figsize=(400,200), dpi=72, facecolor=(1,1,1), edgecolor=(0,0,0), tight_layout = True) canvas = FigureCanvas(fig) ax = fig.add_subplot(111) ax.set_xlabel('Iteration') self.inputPlots.append({'fig': fig, 'canvas': canvas, 'ax': ax}) self.plotsLayout.addWidget(canvas) canvas.setParent(self.plots_group) elif len(self.inputPlots) > len(names): #remove plots for i in range(len(names), len(self.inputPlots)): self.inputPlots[i]['fig'].clf() self.inputPlots[i]['canvas'].deleteLater() del self.inputPlots[i] for i, name in enumerate(names): #self.inputPlots[i]['ax'].set_ylabel('Primary Input %s' % name) self.inputPlots[i]['ax'].set_ylabel(name) self.plots_group.setMinimumHeight(190 * (len(names) + 1)) self.inputPoints = [[] for i in range(len(names) + 1)] self.clearPlots() def clearPlots(self): self.objXPoints = [] self.objYPoints = [] if 'objFigAx' in self.__dict__ and len(self.objFigAx.lines) > 0: self.objFigAx.lines = [] self.objFigAx.relim() #self.objFigAx.set_xlim([0.0, 1.0]) self.objCanvas.draw() if 'inputPoints' in self.__dict__: self.inputPoints = [[] for i in range(len(self.inputPoints))] for i in range(1, len(self.inputPoints)): if len(self.inputPlots[i - 1]['ax'].lines) > 0: self.inputPlots[i - 1]['ax'].lines = [] self.inputPlots[i - 1]['canvas'].draw() def scrollProgressPlots(self, value): QApplication.processEvents() names, indices = self.input_table.getPrimaryVariables() numPlots = len(names) + 1 firstPlotToUpdate = int(value/190) firstPlotToUpdate = min(firstPlotToUpdate, numPlots - 1) self.plotsToUpdate = [firstPlotToUpdate] if firstPlotToUpdate < numPlots - 1: self.plotsToUpdate.append(firstPlotToUpdate + 1) #print "Scroll", value,self.plotsToUpdate for index in self.plotsToUpdate: if index == 0: self.updateObjPlot() else: self.updateInputPlot(index) QApplication.processEvents() def setFixed(self): self.input_table.setCheckedToType(0) def setX1(self): self.input_table.setCheckedToType(1) def setX1d(self): self.input_table.setCheckedToType(2) def setX2(self): self.input_table.setCheckedToType(3) def setX3(self): self.input_table.setCheckedToType(4) def setX4(self): self.input_table.setCheckedToType(5) def setCounts(self): # update counts M0 = len(self.input_table.getFixedVariables()[0]) M1 = len(self.input_table.getPrimaryVariables()[0]) M2 = len(self.input_table.getRecourseVariables()[0]) M3Vars = self.input_table.getUQDiscreteVariables()[0] M3 = len(M3Vars) M4Vars = self.input_table.getContinuousVariables()[0] M4 = len(M4Vars) self.fixedCount_static.setText('# Fixed: %d' % M0) self.x1Count_static.setText('# Primary Opt Vars: %d' % M1) self.x2Count_static.setText('# Recourse Opt Vars: %d' % M2) self.x3Count_static.setText('# Discrete RVs: %d' % M3) self.x4Count_static.setText('# Continuous RVs: %d' % M4) hideInnerSolver = (M2 == 0) self.secondarySolver_label.setHidden(hideInnerSolver) self.secondarySolver_combo.setHidden(hideInnerSolver) hideZ3Group = (M3 == 0) hideZ4Group = (M4 == 0) if hideZ3Group and hideZ4Group: #Hide tab if self.tabs.widget(2) == self.uqTab: if self.tabs.currentIndex() == 2: self.tabs.setCurrentIndex(0) self.tabs.removeTab(2) else: #Show tab if self.tabs.widget(2) != self.uqTab: self.tabs.insertTab(2, self.uqTab, 'UQ Setup') numCols = max(len(M3Vars), self.z3_table.columnCount()) self.z3_table.setColumnCount(numCols) self.z3_table.setHorizontalHeaderLabels(M3Vars + ['Unused'] * (numCols - len(M3Vars))) numCols = max(len(M4Vars), self.z4_table.columnCount()) self.z4_table.setColumnCount(numCols) self.z4_table.setHorizontalHeaderLabels(M4Vars + ['Unused'] * (numCols - len(M4Vars))) self.z3_group.setHidden(hideZ3Group) self.z4_group.setHidden(hideZ4Group) if self.x4SampleScheme_combo.currentText() == SamplingMethods.getFullName(SamplingMethods.FACT): self.x4SampleSize_spin.setMinimum(3) else: self.x4SampleSize_spin.setMinimum(M4 + 1) self.z4SubsetSize_spin.setMinimum(M4 + 1) def chooseZ4NewSample(self, value): if value: self.x4SampleScheme_label.setEnabled(True) self.x4SampleScheme_combo.setEnabled(True) self.x4SampleSize_label.setEnabled(True) self.x4SampleSize_spin.setEnabled(True) self.x4FileBrowse_button.setEnabled(False) self.showZ4Subset(False) self.setZ4RS(self.x4SampleSize_spin.value()) self.z4_table.setEnabled(False) def chooseZ4LoadSample(self, value): if value: self.x4SampleScheme_label.setEnabled(False) self.x4SampleScheme_combo.setEnabled(False) self.x4SampleSize_label.setEnabled(False) self.x4SampleSize_spin.setEnabled(False) self.x4FileBrowse_button.setEnabled(True) self.showZ4Subset(True) self.setZ4RS(self.z4SubsetSize_spin.value()) self.z4_table.setEnabled(True) def setZ4RS(self, value): if value <= 300: rs = ResponseSurfaces.getFullName(ResponseSurfaces.KRIGING) elif value <= 600: rs = ResponseSurfaces.getFullName(ResponseSurfaces.RBF) else: rs = ResponseSurfaces.getFullName(ResponseSurfaces.MARS) self.x4RSMethod_check.setText('Use Response Surface (%s)' % rs) def showZ4Subset(self, show): if show and self.x4RSMethod_check.isChecked() and self.z4LoadSample_radio.isChecked(): self.z4SubsetSize_label.setEnabled(True) self.z4SubsetSize_spin.setEnabled(True) else: self.z4SubsetSize_label.setEnabled(False) self.z4SubsetSize_spin.setEnabled(False) def setupPSUADEClient(self): curDir = os.getcwd() mydir = os.path.dirname(__file__) #Copy needed files if os.name == 'nt': dest1 = os.path.join(curDir, 'foqusPSUADEClient.py') src1 = os.path.join(mydir, 'foqusPSUADEClient.py') shutil.copy(src1, dest1) dest = os.path.join(curDir, 'foqusPSUADEClient.bat') src2 = os.path.join(mydir, 'foqusPSUADEClient.bat') shutil.copy(src2, dest) else: dest = os.path.join(curDir, 'foqusPSUADEClient.py') src = os.path.join(mydir, 'foqusPSUADEClient.py') shutil.copy(src, dest) return dest def analyze(self): dir = os.getcwd() for f in os.listdir(dir): if re.search('psuadeEval.out', f): os.remove(os.path.join(dir, f)) if self.run_button.text() == 'Run OUU': # Run OUU names, indices = self.input_table.getPrimaryVariables() if len(names) == 0: QMessageBox.information(self, 'No Primary Variables', 'At least one input must be a primary variable!') return valid, error = self.input_table.checkValidInputs() if not valid: QMessageBox.information(self, 'Input Table Distributions', 'Input table distributions are either not correct or not filled out completely! %s' % error) return if self.compressSamples_chk.isChecked() and not self.scenariosCalculated: QMessageBox.information(self, 'Compress Samples Not Calculated', 'You have elected to compress samples for discrete random variables (Z3), but have not selected the sample size to use!') return M1 = len(self.input_table.getPrimaryVariables()[0]) M2 = len(self.input_table.getRecourseVariables()[0]) M3 = len(self.input_table.getUQDiscreteVariables()[0]) M4 = len(self.input_table.getContinuousVariables()[0]) Common.initFolder(OUU.dname) self.managePlots() self.clearPlots() self.manageBestValueTable() self.summary_group.setTitle('Best So Far') xtable = self.input_table.getTableValues() # get arguments for ouu() model = copy.deepcopy(self.model) inputNames = model.getInputNames() inputTypes = list(model.getInputTypes()) defaultValues = model.getInputDefaults() for row in xtable: if row['type'] == 'Fixed': modelIndex = inputNames.index(row['name']) inputTypes[modelIndex] = Model.FIXED defaultValues[modelIndex] = row['value'] #print inputTypes #print defaultValues model.setInputTypes(inputTypes) model.setInputDefaults(defaultValues) data = SampleData(model) fname = 'ouuTemp.dat' data.writeToPsuade(fname) # Outputs numOutputs = self.outputs_table.rowCount() y = [] self.useAsConstraint = [False] * numOutputs self.useAsDerivative = [False] * numOutputs for r in range(numOutputs): type = self.outputs_table.cellWidget(r,0).currentText() if type == ouuSetupFrame.ObjFuncText: y.append(r + 1) elif type == ouuSetupFrame.ConstraintText: self.useAsConstraint[r] = True elif type == ouuSetupFrame.DerivativeText: self.useAsDerivative[r] = True if self.mean_radio.isChecked(): phi = {'type':1} elif self.meanWithBeta_radio.isChecked(): beta = self.betaDoubleSpin.value() phi = {'type':2, 'beta':beta} elif self.alpha_radio.isChecked(): alpha = self.alphaDoubleSpin.value() phi = {'type':3, 'alpha':alpha} x3sample = None if M3 > 0: if self.compressSamples_chk.isChecked(): selectedSamples = int(self.scenarioSelect_combo.currentText()) sfile = self.scenarioFiles[selectedSamples][0] else: sfile = 'z3Samples.smp' success = self.writeTableToFile(self.z3_table, sfile, M3) if not success: return if sfile.endswith('.csv'): # Convert .csv file to simple file newFileName = OUU.dname + os.sep + os.path.basename(fname)[:-4] + '.smp' inData = LocalExecutionModule.readDataFromCsvFile(sfile, askForNumInputs=False) LocalExecutionModule.writeSimpleFile(newFileName, inData[0]) sfile = newFileName #print 'x3 file is', sfile x3sample = {'file':sfile} # x3sample file data,_, numInputs, _ = LocalExecutionModule.readDataFromSimpleFile(sfile, hasColumnNumbers=False) if numInputs != M3: QMessageBox.critical(self, "Number of variables don't match", 'The number of variables from the file (%d) does not match the number of Z3 discrete variables (%d). You will not be able to perform analysis until this is corrected.' % (numInputs, M3)) return useRS = self.x4RSMethod_check.isChecked() x4sample = None if self.z4NewSample_radio.isChecked(): method = self.x4SampleScheme_combo.currentText() method = SamplingMethods.getEnumValue(method) N = self.x4SampleSize_spin.value() if method in [SamplingMethods.LH,SamplingMethods.LPTAU]: x4sample = {'method':method, 'nsamples':N} # number of samples (range: [M1+1,1000]) elif method == SamplingMethods.FACT: x4sample = {'method':method, 'nlevels':N} # number of levels (range: [3,100]) else: sfile = 'z4Samples.smp' success = self.writeTableToFile(self.z4_table, sfile, M4) if not success: return if len(sfile) == 0: QMessageBox.critical(self, 'Missing file', 'Z4 sample file not specified!') return if sfile.endswith('.csv'): # Convert .csv file to simple file newFileName = OUU.dname + os.sep + os.path.basename(fname)[:-4] + '.smp' inData = LocalExecutionModule.readDataFromCsvFile(sfile, askForNumInputs=False) LocalExecutionModule.writeSimpleFile(newFileName, inData[0]) sfile = newFileName inData, outData, numInputs, numOutputs = LocalExecutionModule.readDataFromSimpleFile(sfile, hasColumnNumbers=False) numSamples = inData.shape[0] if numInputs != M4: QMessageBox.critical(self, "Number of variables don't match", 'The number of input variables from the file (%d) does not match the number of Z4 continuous variables (%d). You will not be able to perform analysis until this is corrected.' % (numInputs, M4)) return if numSamples <= M4: QMessageBox.critical(self, 'Not enough samples', 'Z4 sample file must have at least %d samples!' % (M4 + 1)) return x4sample = {'file': sfile} # x4sample file, must have at least M4+1 samples if useRS: Nrs = self.z4SubsetSize_spin.value() # add spinbox to get number of samples to generate RS x4sample['nsamplesRS'] = Nrs # TO DO: make sure spinbox has M4+1 as min and x4sample's sample size as max # TODO: Get rid of usebobyqa option. Behavior should be as if usebobyqa is always false # TODO: Change GUI to display optimizer and optimizing with bobyqa # TODO: Get rid of primarySolver_combo completely useBobyqa = False method = self.primarySolver_combo.currentText() if method == "BOBYQA": pass elif method == "NEWUOA": pass if 'simulator' in self.secondarySolver_combo.currentText(): useBobyqa = True # use BOBYQA if driver is a simulator, not an optimizer self.run_button.setText('Stop') optDriver = None ensembleOptDriver = None if self.node_radio.isChecked(): ensembleOptDriver = self.setupPSUADEClient() optDriver = ensembleOptDriver listener = listen.foqusListener(self.dat) variableNames = [] fixedNames = [] for row in xtable: #print row if row['type'] == 'Fixed': fixedNames.append(row['name']) else: variableNames.append(row['name']) #print fixedNames, variableNames #print variableNames + fixedNames listener.inputNames = variableNames + fixedNames outputNames = self.model.getOutputNames() listener.outputNames = [outputNames[yItem-1] for yItem in y] listener.failValue = -111111 self.listenerAddress = listener.address listener.start() # print M1, M2, M3, M4, useBobyqa self.OUUobj = OUU() try: results = self.OUUobj.ouu(fname,y,self.useAsConstraint,self.useAsDerivative,xtable,phi, x3sample=x3sample,x4sample=x4sample,useRS=useRS,useBobyqa=useBobyqa, optDriver = optDriver, ensOptDriver = ensembleOptDriver, plotSignal = self.plotSignal, endFunction=self.finishOUU) except: import traceback traceback.print_exc() if self.node_radio.isChecked(): # stop the listener conn = Client(self.listenerAddress) conn.send(['quit']) conn.close() # enable run button self.run_button.setEnabled(True) return else: # Stop OUU self.OUUobj.stopOUU() self.run_button.setEnabled(False) self.freeze() def finishOUU(self): if self.node_radio.isChecked(): # stop the listener conn = Client(self.listenerAddress) conn.send(['quit']) conn.close() # enable run button if not self.run_button.isEnabled(): self.unfreeze() self.run_button.setText('Run OUU') self.run_button.setEnabled(True) if not self.OUUobj.getHadError(): self.summary_group.setTitle('Best Solution') # results.replace('X','Z') # # QMessageBox.information(self, 'OUU Results', results) msgBox = QMessageBox() msgBox.setWindowTitle('FOQUS OUU Finished') msgBox.setText('Optimization under Uncertainty analysis finished') self.result = msgBox.exec_() def getResult(self): return self.result