def openAfterMaybeSave(self): """ This is the method that initiates file opening. It is called by actionOpenSlot to spawn a QFileDialog and connect it to a callback method. """ path = self._file_open_path if util.isWindows(): # required for native looking file window#"/", fname = QFileDialog.getOpenFileName( None, "Open Document", path, "cadnano1 / cadnano2 Files (*.nno *.json *.cadnano)") self.filesavedialog = None self.openAfterMaybeSaveCallback(fname) else: # access through non-blocking callback fdialog = QFileDialog( self.win, "Open Document", path, "cadnano1 / cadnano2 Files (*.nno *.json *.cadnano)") fdialog.setAcceptMode(QFileDialog.AcceptOpen) fdialog.setWindowFlags(Qt.Sheet) fdialog.setWindowModality(Qt.WindowModal) self.fileopendialog = fdialog self.fileopendialog.filesSelected.connect(self.openAfterMaybeSaveCallback) fdialog.open()
def open_file_handler(self): if self.link_flag in [self.ServerTCP, self.ClientTCP, self.ClientUDP]: # 打开文本文件,加载到发送PlainTextEdit def read_file(file_dir): if file_dir: try: with open(file_dir, 'r', encoding='UTF8') as f: self.__ui.SendPlainTextEdit.clear() self.__ui.SendPlainTextEdit.appendPlainText( f.read()) except UnicodeDecodeError: # 如果不能用UTF8解码 mb = QMessageBox(QMessageBox.Critical, '无法读取文件', '无法读取文件,请检查输入', QMessageBox.Ok, self) mb.open() fd = QFileDialog(self, "选择一个文件", "./", "文本文件(*, *)") fd.setAcceptMode(QFileDialog.AcceptOpen) fd.setFileMode(QFileDialog.ExistingFile) fd.fileSelected.connect(read_file) fd.open() elif self.link_flag == self.NoLink and self.protocol_type == 'Web Server': self.dir = QFileDialog.getExistingDirectory( self, "选择index.html所在路径", './') self.__ui.SendPlainTextEdit.clear() self.__ui.SendPlainTextEdit.appendPlainText(str(self.dir)) self.__ui.SendPlainTextEdit.setEnabled(False)
def browse(self, type_='process'): """Open a dialog to choose either .mgf or metadata.txt file""" dialog = QFileDialog(self) dialog.setFileMode(QFileDialog.ExistingFile) if type_ == 'process': dialog.setNameFilters(["All supported formats (*.mgf *.msp)", "Mascot Generic Format (*.mgf)", "NIST Text Format of Individual Spectra (*.msp)", "All files (*)"]) elif type_ == 'metadata': dialog.setNameFilters(["Metadata File (*.csv *.tsv *.txt *.xls *.xlsx *.xlsm *.xlsb *.ods)", "Microsoft Excel spreadsheets (*.xls *.xlsx, *.xlsm *.xlsb)", "OpenDocument spreadsheets (*.ods)", "All files (*)"]) def on_dialog_finished(result): if result == QDialog.Accepted: filename = dialog.selectedFiles()[0] if type_ == 'process': self.editProcessFile.setText(filename) self.editProcessFile.setPalette(self.style().standardPalette()) else: self.on_show_options_dialog(filename) dialog.finished.connect(on_dialog_finished) dialog.open()
def saveFileDialog(self): fname = self.filename() if fname == None: directory = "." else: directory = QFileInfo(fname).path() if util.isWindows(): # required for native looking file window fname = QFileDialog.getSaveFileName( self.win, "%s - Save As" % QApplication.applicationName(), directory, "%s (*.json)" % QApplication.applicationName()) self.writeDocumentToFile(fname) else: # access through non-blocking callback fdialog = QFileDialog( self.win, "%s - Save As" % QApplication.applicationName(), directory, "%s (*.json)" % QApplication.applicationName()) fdialog.setAcceptMode(QFileDialog.AcceptSave) fdialog.setWindowFlags(Qt.Sheet) fdialog.setWindowModality(Qt.WindowModal) self.filesavedialog = fdialog self.filesavedialog.filesSelected.connect( self.saveFileDialogCallback) fdialog.open()
def addPlugin(self): fdialog = QFileDialog(self.widget, "Install Plugin", util.this_path(), "Cadnano Plugins (*.cnp)") fdialog.setAcceptMode(QFileDialog.AcceptOpen) fdialog.setWindowFlags(Qt.Sheet) fdialog.setWindowModality(Qt.WindowModal) fdialog.filesSelected.connect(self.addPluginAtPath) self.fileopendialog = fdialog fdialog.open()
def actionExportStaplesSlot(self): """ Triggered by clicking Export Staples button. Opens a file dialog to determine where the staples should be saved. The callback is exportStaplesCallback which collects the staple sequences and exports the file. """ # Validate that no staple oligos are loops. part = self.activePart() if part is None: return stap_loop_olgs = part.getStapleLoopOligos() if stap_loop_olgs: from ui.dialogs.ui_warning import Ui_Warning dialog = QDialog() dialogWarning = Ui_Warning() # reusing this dialog, should rename dialog.setStyleSheet("QDialog { background-image: url(ui/dialogs/images/cadnano2-about.png); background-repeat: none; }") dialogWarning.setupUi(dialog) locs = ", ".join([o.locString() for o in stap_loop_olgs]) msg = "Part contains staple loop(s) at %s.\n\nUse the break tool to introduce 5' & 3' ends before exporting. Loops have been colored red; use undo to revert." % locs dialogWarning.title.setText("Staple validation failed") dialogWarning.message.setText(msg) for o in stap_loop_olgs: o.applyColor(styles.stapColors[0].name()) dialog.exec_() return # Proceed with staple export. fname = self.filename() if fname == None: directory = "." else: directory = QFileInfo(fname).path() if util.isWindows(): # required for native looking file window fname = QFileDialog.getSaveFileName( self.win, "%s - Export As" % QApplication.applicationName(), directory, "(*.csv)") self.saveStaplesDialog = None self.exportStaplesCallback(fname) else: # access through non-blocking callback fdialog = QFileDialog( self.win, "%s - Export As" % QApplication.applicationName(), directory, "(*.csv)") fdialog.setAcceptMode(QFileDialog.AcceptSave) fdialog.setWindowFlags(Qt.Sheet) fdialog.setWindowModality(Qt.WindowModal) self.saveStaplesDialog = fdialog self.saveStaplesDialog.filesSelected.connect(self.exportStaplesCallback) fdialog.open()
def actionExportSequencesSlot(self): """ Triggered by clicking Export Staples button. Opens a file dialog to determine where the staples should be saved. The callback is exportStaplesCallback which collects the staple sequences and exports the file. """ # Validate that no staple oligos are circular. part = self._document.activePart() if part is None: return circ_olgs = part.getCircularOligos() if circ_olgs: from cadnano.gui.ui.dialogs.ui_warning import Ui_Warning dialog = QDialog() dialogWarning = Ui_Warning() # reusing this dialog, should rename dialog.setStyleSheet( "QDialog { background-image: url(ui/dialogs/images/cadnano2-about.png); background-repeat: none; }" ) dialogWarning.setupUi(dialog) locs = ", ".join([o.locString() for o in circ_olgs]) msg = "Part contains staple loop(s) at %s.\n\nUse the break tool to introduce 5' & 3' ends before exporting. Loops have been colored red; use undo to revert." % locs dialogWarning.title.setText("Staple validation failed") dialogWarning.message.setText(msg) for o in circ_olgs: o.applyColor(styles.stapColors[0]) dialog.exec_() return # Proceed with staple export. fname = self.fileName() if fname is None: directory = "." else: directory = QFileInfo(fname).path() if util.isWindows(): # required for native looking file window fname = QFileDialog.getSaveFileName( self.win, "%s - Export As" % QApplication.applicationName(), directory, "(*.txt)") self.saveStaplesDialog = None self.exportStaplesCallback(fname) else: # access through non-blocking callback fdialog = QFileDialog( self.win, "%s - Export As" % QApplication.applicationName(), directory, "(*.txt)") fdialog.setAcceptMode(QFileDialog.AcceptSave) fdialog.setWindowFlags(Qt.Sheet) fdialog.setWindowModality(Qt.WindowModal) self.saveStaplesDialog = fdialog self.saveStaplesDialog.filesSelected.connect( self.exportStaplesCallback) fdialog.open()
class FileChooserButton(QPushButton): path_chosen_signal = pyqtSignal(Path) # emits the selected path def __init__(self, text, file_mode=QFileDialog.AnyFile, name_filters=None): super().__init__() self.file_mode = file_mode self.name_filters = name_filters self.selection_made = False self.path = None self.setText(text) self.clicked.connect(self.open_dialog) def open_dialog(self): """ Opens a file chooser dialog to the user. """ # regarding #setFileMode and why we don't use it: # QFileDialog.ExistingFiles appears to override QFileDialog.Directory, # so I don't see a way to support selecting multiple files and selecting # directories in the same widget, unless we make our own QDialog class. self.dialog = QFileDialog(self) self.dialog.setFileMode(self.file_mode) if self.name_filters: self.dialog.setNameFilters(self.name_filters) self.start_dir = self.dialog.directory().absolutePath() # recommended over #exec by qt https://doc.qt.io/qt-5/qdialog.html#exec self.dialog.open() self.dialog.finished.connect(self.process_selection) def process_selection(self): """ process whatever the user has chosen (either a folder, file, or multiple files). """ files = self.dialog.selectedFiles() # will only be 1 file at most, but could be 0 (if the user canceled) if not files: self.selection_made = False return path = files[0] self.selection_made = path != self.start_dir # TODO truncate path, ideally with qt size policies but might not be # possible with those alone path = Path(path) self.path = path self.path_chosen_signal.emit(path)
def actionSVGSlot(self): """docstring for actionSVGSlot""" fname = os.path.basename(str(self.fileName())) if fname is None: directory = "." else: directory = QFileInfo(fname).path() fdialog = QFileDialog(self.win, "%s - Save As" % QApplication.applicationName(), directory, "%s (*.svg)" % QApplication.applicationName()) fdialog.setAcceptMode(QFileDialog.AcceptSave) fdialog.setWindowFlags(Qt.Sheet) fdialog.setWindowModality(Qt.WindowModal) self.svgsavedialog = fdialog self.svgsavedialog.filesSelected.connect(self.saveSVGDialogCallback) fdialog.open()
def openAfterMaybeSave(self): '''This is the method that initiates file opening. It is called by actionOpenSlot to spawn a QFileDialog and connect it to a callback method. ''' path = self._file_open_path if util.isWindows(): # required for native looking file window#"/", fname = QFileDialog.getOpenFileName( None, "Open Document", path, "cadnano1 / cadnano2 Files (*.nno *.json *.c25)") self.filesavedialog = None self.openAfterMaybeSaveCallback(fname) else: # access through non-blocking callback fdialog = QFileDialog( self.win, "Open Document", path, "cadnano1 / cadnano2 Files (*.nno *.json *.c25)") fdialog.setAcceptMode(QFileDialog.AcceptOpen) fdialog.setWindowFlags(Qt.Sheet) fdialog.setWindowModality(Qt.WindowModal) self.fileopendialog = fdialog self.fileopendialog.filesSelected.connect( self.openAfterMaybeSaveCallback) fdialog.open()
def saveFileDialog(self): fname = self.fileName() if fname is None: directory = "." else: directory = QFileInfo(fname).path() if util.isWindows(): # required for native looking file window fname = QFileDialog.getSaveFileName( self.win, "%s - Save As" % QApplication.applicationName(), directory, "%s (*.json)" % QApplication.applicationName()) if isinstance(fname, (list, tuple)): fname = fname[0] self.writeDocumentToFile(fname) else: # access through non-blocking callback fdialog = QFileDialog( self.win, "%s - Save As" % QApplication.applicationName(), directory, "%s (*.json)" % QApplication.applicationName()) fdialog.setAcceptMode(QFileDialog.AcceptSave) fdialog.setWindowFlags(Qt.Sheet) fdialog.setWindowModality(Qt.WindowModal) self.filesavedialog = fdialog self.filesavedialog.filesSelected.connect( self.saveFileDialogCallback) fdialog.open()
class Ui(QtWidgets.QDialog): def __init__(self): super(Ui, self).__init__() uic.loadUi('PETCalculator.ui', self) self.show() self.runButton.clicked.connect(self.start_calculation) self.pushButtonSave.clicked.connect(self.folder_path_out) self.fileDialog = QFileDialog() self.fileDialog.setFileMode(QFileDialog.Directory) self.fileDialog.setOption(QFileDialog.ShowDirsOnly, True) self.pushButtonImportMetData.clicked.connect(self.met_file) self.fileDialogMet = QFileDialog() self.fileDialogMet.setNameFilter("(*.txt)") self.CheckBoxHumanDefault.clicked.connect(self.set_Default_human) self.CheckBoxEnvironDefault.clicked.connect(self.set_Default_environ) self.comboBoxSky.currentIndexChanged.connect(self.setRadiation) self.CheckBoxBoxSkyCondition.clicked.connect(self.set_clear) self.outputfile = None def folder_path_out(self): self.outputfile = self.fileDialog.getSaveFileName( None, "Save File As:", None, "Text Files (*.txt)") if not self.outputfile[0]: QMessageBox.critical( None, "Error", "An output text file (.txt) must be specified") return else: self.textOutput.setText(self.outputfile[0]) def met_file(self): self.fileDialogMet.open() result = self.fileDialogMet.exec_() if result == 1: self.folderPathMet = self.fileDialogMet.selectedFiles() self.textInputMetdata.setText(self.folderPathMet[0]) def set_clear(self): self.comboBoxSky.setCurrentIndex(1) self.setRadiation() def setRadiation(self): Ta = self.doubleSpinBoxTa.value() RH = self.doubleSpinBoxRH.value() date = self.calendarWidget.selectedDate() year = date.year() month = date.month() day = date.day() time = self.spinBoxTimeEdit.time() hour = time.hour() minu = time.minute() doy = self.day_of_year(year, month, day) lat = self.doubleSpinBoxLatitude.value() lon = self.doubleSpinBoxLongitude.value() if lon > 180.: lon = lon - 180. metdata = np.zeros((1, 24)) - 999. metdata[0, 0] = year metdata[0, 1] = doy metdata[0, 2] = hour metdata[0, 3] = minu metdata[0, 11] = Ta metdata[0, 10] = RH UTC = self.spinBoxUTC.value() location = {'longitude': lon, 'latitude': lat, 'altitude': 3.} P = -999. radG = 40. YYYY, altitude, azimuth, zen, jday, leafon, dectime, altmax = metload.Solweig_2015a_metdata_noload( metdata, location, UTC) if altitude > 0.: I0, _, Kt, _, _ = ci.clearnessindex_2013b(zen, jday, Ta, RH / 100., radG, location, P) if self.comboBoxSky.currentIndex() == 1: radG = I0 elif self.comboBoxSky.currentIndex() == 2: radG = I0 * 0.8 elif self.comboBoxSky.currentIndex() == 3: radG = I0 * 0.6 else: radG = I0 * 0.4 I0, _, Kt, _, _ = ci.clearnessindex_2013b(zen, jday, Ta, RH / 100., radG, location, P) radI, radD = df.diffusefraction(radG, altitude, Kt, Ta, RH) else: radG = 0. radD = 0. radI = 0. self.doubleSpinBoxradG.setValue(radG) self.doubleSpinBoxradD.setValue(radD) self.doubleSpinBoxradI.setValue(radI) def day_of_year(self, yyyy, month, day): if (yyyy % 4) == 0: if (yyyy % 100) == 0: if (yyyy % 400) == 0: leapyear = 1 else: leapyear = 0 else: leapyear = 1 else: leapyear = 0 if leapyear == 1: dayspermonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] else: dayspermonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] doy = np.sum(dayspermonth[0:month - 1]) + day return doy def set_Default_human(self): self.doubleSpinBoxShortwaveHuman.setValue(0.70) self.doubleSpinBoxLongwaveHuman.setValue(0.95) self.comboBox_posture.setCurrentIndex(0) self.doubleSpinBoxWeight.setValue(75) self.doubleSpinBoxHeight.setValue(180) self.doubleSpinBoxClo.setValue(0.9) self.doubleSpinBoxAge.setValue(35) self.doubleSpinBoxActivity.setValue(80) self.comboBoxGender.setCurrentIndex(0) self.CheckBoxBox.setChecked(True) def set_Default_environ(self): self.doubleSpinBoxAlbedo_w.setValue(0.2) self.doubleSpinBoxAlbedo_g.setValue(0.15) self.doubleSpinBoxEmis_w.setValue(0.9) self.doubleSpinBoxEmis_g.setValue(0.95) self.doubleSpinBoxSVF.setValue(0.6) def read_metdata(self): headernum = 1 delim = ' ' try: self.metdata = np.loadtxt(self.folderPathMet[0], skiprows=headernum, delimiter=delim) except: QMessageBox.critical( self, "Import Error", "Make sure format of meteorological file is correct. You can " "prepare your data by using 'Prepare Existing Data' in " "the Pre-processor") return if self.metdata.shape[1] == 24: test = 4 else: QMessageBox.critical( self, "Import Error", "Wrong number of columns in meteorological data. You can " "prepare your data by using 'Prepare Existing Data'") return def start_calculation(self): sh = 1. # 0 if shadowed by building vegsh = 1. # 0 if shadowed by tree svfveg = 1. svfaveg = 1. trans = 1. elvis = 0 # Location and time settings UTC = self.spinBoxUTC.value() lat = self.doubleSpinBoxLatitude.value() lon = self.doubleSpinBoxLongitude.value() if lon > 180.: lon = lon - 180. # Human parameter data if self.CheckBoxHumanDefault.isChecked(): absK = 0.70 absL = 0.95 pos = 0 mbody = 75. ht = 180 / 100. clo = 0.9 age = 35 activity = 80. sex = 1 else: absK = self.doubleSpinBoxShortwaveHuman.value() absL = self.doubleSpinBoxLongwaveHuman.value() pos = self.comboBox_posture.currentIndex() mbody = self.doubleSpinBoxWeight.value() ht = self.doubleSpinBoxHeight.value() / 100 clo = self.doubleSpinBoxClo.value() age = self.doubleSpinBoxAge.value() activity = self.doubleSpinBoxActivity.value() sex = self.comboBoxGender.currentIndex() + 1 if pos == 0: Fside = 0.22 Fup = 0.06 height = 1.1 Fcyl = 0.28 else: Fside = 0.166666 Fup = 0.166666 height = 0.75 Fcyl = 0.2 if self.CheckBoxBox.isChecked(): cyl = 1 else: cyl = 0 ani = 1 # Environmental data albedo_b = self.doubleSpinBoxAlbedo_w.value() albedo_g = self.doubleSpinBoxAlbedo_g.value() ewall = self.doubleSpinBoxEmis_w.value() eground = self.doubleSpinBoxEmis_g.value() svf = self.doubleSpinBoxSVF.value() # Meteorological data sensorheight = self.doubleSpinBoxWsHt.value() onlyglobal = 0 if self.CheckBoxMetData.isChecked(): self.read_metdata() metfileexist = 1 PathMet = self.folderPathMet[0] if self.checkBoxUseOnlyGlobal.isChecked(): onlyglobal = 1 else: onlyglobal = 0 else: metfileexist = 0 PathMet = None self.metdata = np.zeros((1, 24)) - 999. date = self.calendarWidget.selectedDate() year = date.year() month = date.month() day = date.day() time = self.spinBoxTimeEdit.time() hour = time.hour() minu = time.minute() doy = self.day_of_year(year, month, day) Ta = self.doubleSpinBoxTa.value() RH = self.doubleSpinBoxRH.value() radG = self.doubleSpinBoxradG.value() radD = self.doubleSpinBoxradD.value() radI = self.doubleSpinBoxradI.value() Ws = self.doubleSpinBoxWs.value() self.metdata[0, 0] = year self.metdata[0, 1] = doy self.metdata[0, 2] = hour self.metdata[0, 3] = minu self.metdata[0, 11] = Ta self.metdata[0, 10] = RH self.metdata[0, 14] = radG self.metdata[0, 21] = radD self.metdata[0, 22] = radI self.metdata[0, 9] = Ws location = {'longitude': lon, 'latitude': lat, 'altitude': 3.} YYYY, altitude, azimuth, zen, jday, leafon, dectime, altmax = metload.Solweig_2015a_metdata_noload( self.metdata, location, UTC) svfalfa = np.arcsin(np.exp((np.log((1. - svf)) / 2.))) # %Creating vectors from meteorological input DOY = self.metdata[:, 1] hours = self.metdata[:, 2] minu = self.metdata[:, 3] Ta = self.metdata[:, 11] RH = self.metdata[:, 10] radG = self.metdata[:, 14] radD = self.metdata[:, 21] radI = self.metdata[:, 22] P = self.metdata[:, 12] Ws = self.metdata[:, 9] TgK = 0.37 Tstart = -3.41 TmaxLST = 15 TgK_wall = 0.58 Tstart_wall = -3.41 TmaxLST_wall = 15 # Check if diffuse and direct radiation exist if metfileexist == 1: if onlyglobal == 0: if np.min(radD) == -999: QMessageBox.critical( self, "Diffuse radiation include NoData values", 'Tick in the box "Estimate diffuse and direct shortwave..." or aqcuire ' 'observed values from external data sources.') return if np.min(radI) == -999: QMessageBox.critical( self, "Direct radiation include NoData values", 'Tick in the box "Estimate diffuse and direct shortwave..." or aqcuire ' 'observed values from external data sources.') return self.progressBar.setRange(0, Ta.__len__()) # If metfile starts at night CI = 1. if ani == 1: skyvaultalt = np.atleast_2d([]) skyvaultazi = np.atleast_2d([]) skyvaultaltint = [6, 18, 30, 42, 54, 66, 78] skyvaultaziint = [12, 12, 15, 15, 20, 30, 60] for j in range(7): for k in range(1, int(360 / skyvaultaziint[j]) + 1): skyvaultalt = np.append(skyvaultalt, skyvaultaltint[j]) skyvaultalt = np.append(skyvaultalt, 90) diffsh = np.zeros((145)) svfalfadeg = svfalfa / (np.pi / 180.) for k in range(0, 145): if skyvaultalt[k] > svfalfadeg: diffsh[k] = 1 else: diffsh = [] numformat = '%3d %2d %3d %2d %6.5f ' + '%6.2f ' * 29 poi_save = np.zeros((1, 34)) if self.CheckBoxMetData.isChecked(): header = 'yyyy id it imin dectime altitude azimuth kdir kdiff kglobal kdown kup keast ksouth ' \ 'kwest knorth ldown lup least lsouth lwest lnorth Ta Tg RH Esky Tmrt ' \ 'I0 CI Shadow SVF_b KsideI PET UTCI' if not self.outputfile: QMessageBox.critical( None, "No specified output information", "An output text file (.txt) must be specified") return else: data_out = self.outputfile[0] np.savetxt(data_out, [], delimiter=' ', header=header, comments='') # fmt=numformat, for i in np.arange(0, Ta.__len__()): #print(i) # Daily water body temperature if (dectime[i] - np.floor(dectime[i])) == 0 or (i == 0): Twater = np.mean(Ta[jday[0] == np.floor(dectime[i])]) # Nocturnal cloudfraction from Offerle et al. 2003 if (dectime[i] - np.floor(dectime[i])) == 0: daylines = np.where(np.floor(dectime) == dectime[i]) alt = altitude[0][daylines] alt2 = np.where(alt > 1) rise = alt2[0][0] [_, CI, _, _, _] = ci.clearnessindex_2013b( zen[0, i + rise + 1], jday[0, i + rise + 1], Ta[i + rise + 1], RH[i + rise + 1] / 100., radG[i + rise + 1], location, P[i + rise + 1]) if (CI > 1) or (CI == np.inf): CI = 1 Tmrt, Kdown, Kup, Ldown, Lup, Tg, ea, esky, I0, CI, Keast, Ksouth, Kwest, Knorth, Least, Lsouth, Lwest, \ Lnorth, KsideI, radIo, radDo, shadow = so.Solweig1D_2019a_calc(svf, svfveg, svfaveg, sh, vegsh, albedo_b, absK, absL, ewall, Fside, Fup, Fcyl, altitude[0][i], azimuth[0][i], zen[0][i], jday[0][i], onlyglobal, location, dectime[i], altmax[0][i], cyl, elvis, Ta[i], RH[i], radG[i], radD[i], radI[i], P[i], Twater, TgK, Tstart, albedo_g, eground, TgK_wall, Tstart_wall, TmaxLST, TmaxLST_wall, svfalfa, CI, ani, diffsh, trans) self.progressBar.setValue(i + 1) # Write to array poi_save[0, 0] = YYYY[0][i] poi_save[0, 1] = jday[0][i] poi_save[0, 2] = hours[i] poi_save[0, 3] = minu[i] poi_save[0, 4] = dectime[i] poi_save[0, 5] = altitude[0][i] poi_save[0, 6] = azimuth[0][i] poi_save[0, 7] = radIo poi_save[0, 8] = radDo poi_save[0, 9] = radG[i] poi_save[0, 10] = Kdown poi_save[0, 11] = Kup poi_save[0, 12] = Keast poi_save[0, 13] = Ksouth poi_save[0, 14] = Kwest poi_save[0, 15] = Knorth poi_save[0, 16] = Ldown poi_save[0, 17] = Lup poi_save[0, 18] = Least poi_save[0, 19] = Lsouth poi_save[0, 20] = Lwest poi_save[0, 21] = Lnorth poi_save[0, 22] = Ta[i] poi_save[0, 23] = Tg + Ta[i] poi_save[0, 24] = RH[i] poi_save[0, 25] = esky poi_save[0, 26] = Tmrt poi_save[0, 27] = I0 poi_save[0, 28] = CI poi_save[0, 29] = shadow poi_save[0, 30] = svf poi_save[0, 31] = KsideI # Recalculating wind speed based on pwerlaw WsPET = (1.1 / sensorheight)**0.2 * Ws[i] WsUTCI = (10. / sensorheight)**0.2 * Ws[i] resultPET = p._PET(Ta[i], RH[i], Tmrt, WsPET, mbody, age, ht, activity, clo, sex) poi_save[0, 32] = resultPET resultUTCI = utci.utci_calculator(Ta[i], RH[i], Tmrt, WsUTCI) poi_save[0, 33] = resultUTCI if self.CheckBoxMetData.isChecked(): self.lineEditTmrt.setText('See textfile') self.lineEditPET.setText('See textfile') self.lineEditUTCI.setText('See textfile') f_handle = open(data_out, 'ab') np.savetxt(f_handle, poi_save, fmt=numformat) f_handle.close() else: self.lineEditTmrt.setText('%3.1f' % (Tmrt)) self.lineEditPET.setText('%3.1f' % (resultPET)) self.lineEditUTCI.setText('%3.1f' % (resultUTCI))
class ImportMetadataDialog(ImportMetadataDialogBase, ImportMetadataDialogUI): # noinspection PyUnusedLocal def __init__(self, *args, filename=None, delimiter=None, **kwargs): super().__init__(*args, **kwargs) self.setupUi(self) self._dialog = None self._workers = WorkerQueue(self, ProgressDialog(self)) self._column_index = -1 # Set completer for input files completer = QCompleter(self.editMetadataFile) if sys.platform.startswith('win'): completer.setCaseSensitivity(Qt.CaseInsensitive) model = QFileSystemModel(completer) model.setFilter(QDir.AllDirs | QDir.Files | QDir.NoDotAndDotDot) model.setRootPath(QDir.currentPath()) completer.setModel(model) self.editMetadataFile.setCompleter(completer) # Create palette used when validating input files self._error_palette = QPalette() self._error_palette.setColor(QPalette.Base, QColor(Qt.red).lighter(150)) # Connect Delimiter ComboBox to delimiter LineEdit self.cbCsvDelimiter.setOtherEditWidget(self.editCsvDelimiter) # Connect events self.btBrowseMetadataFile.clicked.connect(self.browse) self.chkComment.clicked.connect( lambda: self.editComment.setEnabled(self.chkComment.isChecked())) self.editMetadataFile.textChanged.connect( self.on_metadata_file_changed) self.cbCsvDelimiter.delimiterChanged.connect(self.populate_table) self.chkUseFirstLineAsHeader.clicked.connect(self.populate_table) self.spinSkipRows.valueChanged.connect(self.populate_table) self.editComment.textChanged.connect(self.populate_table) self.chkComment.clicked.connect(self.populate_table) self.btRefresh.clicked.connect(self.populate_table) self.chkComment.clicked.connect(self.populate_table) self.btSelectAll.clicked.connect(self.twMetadata.selectAll) self.btSelectNone.clicked.connect(self.twMetadata.clearSelection) self.btSelectInvert.clicked.connect(self.invert_selection) self.cbIndexColumn.currentIndexChanged.connect( self.on_column_index_changed) if filename is not None: self.editMetadataFile.setText(filename) def done(self, r): if r == QDialog.Accepted: metadata_file = self.editMetadataFile.text() if os.path.exists(metadata_file) and os.path.isfile(metadata_file): super().done(r) else: self.editMetadataFile.setPalette(self._error_palette) else: super().done(r) def browse(self): self._dialog = QFileDialog(self) self._dialog.setFileMode(QFileDialog.ExistingFile) self._dialog.setNameFilters([ "Metadata File (*.csv *.tsv *.txt *.xls *.xlsx *.xlsm *.xlsb *.ods)", "Microsoft Excel spreadsheets (*.xls *.xlsx, *.xlsm *.xlsb)", "OpenDocument spreadsheets (*.ods)", "All files (*)" ]) def set_filename(result): if result == QDialog.Accepted: filename = self._dialog.selectedFiles()[0] with SignalBlocker(self.editMetadataFile): self.editMetadataFile.setText(filename) self.editMetadataFile.setPalette( self.style().standardPalette()) self.on_metadata_file_changed(filename) self._dialog.finished.connect(set_filename) self._dialog.open() def selection(self): model = self.twMetadata.model() first = model.index(0, 0) last = model.index(self.twMetadata.model().rowCount() - 1, self.twMetadata.model().columnCount() - 1) return QItemSelection(first, last) def selected_columns(self): return [ index.column() for index in self.twMetadata.selectionModel().selectedColumns() ] def invert_selection(self): self.twMetadata.selectionModel().select(self.selection(), QItemSelectionModel.Toggle) def on_metadata_file_changed(self, text): self.twMetadata.clear() # Check that selected metadata file is a valid csv file and try to get delimiter try: with open(text, 'r') as f: line = f.readline() sniffer = csv.Sniffer() delimiter = sniffer.sniff(line).delimiter has_header = sniffer.has_header(line) except (OSError, FileNotFoundError, csv.Error, UnicodeDecodeError): # not a csv file (excel or odf) self.cbCsvDelimiter.setEnabled(False) self.editCsvDelimiter.setEnabled(False) with SignalBlocker(self.chkUseFirstLineAsHeader): self.chkUseFirstLineAsHeader.setChecked(True) else: self.cbCsvDelimiter.setEnabled(True) self.editCsvDelimiter.setEnabled(True) with SignalBlocker(self.cbCsvDelimiter, self.chkUseFirstLineAsHeader): self.cbCsvDelimiter.setDelimiter(delimiter) self.chkUseFirstLineAsHeader.setChecked(has_header) finally: self.populate_table() def on_column_index_changed(self, index: int): index = self.cbIndexColumn.itemData(index) index = index if index is not None else -1 self._column_index = index for column in range( self.twMetadata.horizontalHeader().model().columnCount()): item = self.twMetadata.horizontalHeaderItem(column) if item is None: return if column == index: item.setData(Qt.DecorationRole, QIcon(":/icons/images/key.svg")) else: item.setData(Qt.DecorationRole, None) def populate_table(self): filename = self.editMetadataFile.text() if not os.path.exists(filename): return def file_read(): nonlocal worker df = worker.result() self.twMetadata.clear() self.twMetadata.setRowCount(0) self.cbIndexColumn.clear() if df is None or df.shape[0] == 0 or df.shape[1] == 0: self.twMetadata.setLoading(False) return try: self.twMetadata.setRowCount(df.shape[0]) self.twMetadata.setColumnCount(df.shape[1]) self.twMetadata.setHorizontalHeaderLabels( df.columns.astype(str)) for column, (_, item) in enumerate(df.items()): for row, data in enumerate(item.values): witem = QTableWidgetItem(str(data)) self.twMetadata.setItem(row, column, witem) self.cbIndexColumn.addItem("") for col in df.select_dtypes( include=['int', 'int64']).columns.astype(str): self.cbIndexColumn.addItem( col, userData=df.columns.get_loc(col)) except KeyError: self.twMetadata.clear() self.twMetadata.setRowCount(0) self.twMetadata.setColumnCount(0) self.cbIndexColumn.clear() finally: self.twMetadata.setLoading(False) # Try to find the index column (choose the first one with int data type) for i, dtype in enumerate(df.dtypes): if dtype.kind == 'i': self.cbIndexColumn.setCurrentIndex(i + 1) break def error(e): self.twMetadata.setLoading(False) if isinstance(e, ImportError): QMessageBox.information(self, None, str(e)) options = self.prepare_options(preview=True) if options is not None: worker = ReadMetadataWorker(filename, options, track_progress=False) if worker is not None: worker.finished.connect(file_read) worker.error.connect(error) self.twMetadata.setLoading(True) self._workers.append(worker) self._workers.start() def prepare_options(self, preview=True): delimiter = self.cbCsvDelimiter.delimiter() if delimiter is not None: options = ReadMetadataOptions() options.sep = delimiter options.header = 'infer' if self.chkUseFirstLineAsHeader.isChecked( ) else None options.comment = self.editComment.text( ) if self.chkComment.isChecked() else '' options.comment = options.comment if len( options.comment) == 1 else None options.skiprows = self.spinSkipRows.value() - 1 if preview: options.nrows = 100 else: selected_cols = self.selected_columns() options.usecols = selected_cols if len( selected_cols) > 0 else None options.index_col = self._column_index if self._column_index >= 0 else None return options def getValues(self): return self.editMetadataFile.text(), self.prepare_options( preview=False)
def browseMethod(self): browseDialog = QFileDialog(self) browseDialog.open() configFilename = browseDialog.getOpenFileName() browseDialog.close() print(configFilename)
class Ui(QtWidgets.QDialog): def __init__(self): super(Ui, self).__init__() uic.loadUi('metdata_processor_dialog_base.ui', self) self.show() self.pushButtonImport.clicked.connect(self.import_file) self.pushButtonExport.clicked.connect(self.start_progress) self.helpButton.clicked.connect(self.help) self.fileDialog = QFileDialog() def import_file(self): if self.checkBoxEPW.isChecked(): result = self.fileDialog.exec_() self.pushButtonExport.setEnabled(True) self.folderPath = self.fileDialog.selectedFiles() self.textInput.setText(self.folderPath[0]) if result == 1: try: self.data = np.genfromtxt(self.folderPath[0], skip_header=8, delimiter=',', filling_values=99999) QMessageBox.information(self, "EPW file imported", "No time or meteorological variables need to be specified. " "Press 'Export data' to continue to generate a formatted text-file.") except Exception as e: QMessageBox.critical(self, "Error: Check the number of columns in each line", str(e)) return else: self.comboBox_yyyy.clear() self.comboBox_doy.clear() self.comboBox_month.clear() self.comboBox_dom.clear() self.comboBox_dectime.clear() self.comboBox_hour.clear() self.comboBox_minute.clear() self.comboBox_RH.clear() self.comboBox_Tair.clear() self.comboBox_Wd.clear() self.comboBox_Wuh.clear() self.comboBox_fcld.clear() self.comboBox_kdiff.clear() self.comboBox_kdir.clear() self.comboBox_kdown.clear() self.comboBox_lai.clear() self.comboBox_ldown.clear() self.comboBox_pres.clear() self.comboBox_qe.clear() self.comboBox_qf.clear() self.comboBox_qh.clear() self.comboBox_qn.clear() self.comboBox_qs.clear() self.comboBox_rain.clear() self.comboBox_snow.clear() self.comboBox_ws.clear() self.comboBox_xsmd.clear() self.fileDialog.open() result = self.fileDialog.exec_() if result == 1: self.pushButtonExport.setEnabled(True) self.folderPath = self.fileDialog.selectedFiles() self.textInput.setText(self.folderPath[0]) headernum = self.spinBoxHeader.value() delimnum = self.comboBox_sep.currentIndex() delim = None if delimnum == 0: delim = ',' elif delimnum == 1: delim = None # space elif delimnum == 2: delim = None # '\t' elif delimnum == 3: delim = ';' elif delimnum == 4: delim = ':' f = open(self.folderPath[0]) header = f.readline().split(delim) for i in range(0, header.__len__()): self.comboBox_yyyy.addItem(header[i]) self.comboBox_doy.addItem(header[i]) self.comboBox_month.addItem(header[i]) self.comboBox_dom.addItem(header[i]) self.comboBox_dectime.addItem(header[i]) self.comboBox_hour.addItem(header[i]) self.comboBox_minute.addItem(header[i]) self.comboBox_RH.addItem(header[i]) self.comboBox_Tair.addItem(header[i]) self.comboBox_Wd.addItem(header[i]) self.comboBox_Wuh.addItem(header[i]) self.comboBox_fcld.addItem(header[i]) self.comboBox_kdiff.addItem(header[i]) self.comboBox_kdir.addItem(header[i]) self.comboBox_kdown.addItem(header[i]) self.comboBox_lai.addItem(header[i]) self.comboBox_ldown.addItem(header[i]) self.comboBox_pres.addItem(header[i]) self.comboBox_qe.addItem(header[i]) self.comboBox_qf.addItem(header[i]) self.comboBox_qh.addItem(header[i]) self.comboBox_qn.addItem(header[i]) self.comboBox_qs.addItem(header[i]) self.comboBox_rain.addItem(header[i]) self.comboBox_snow.addItem(header[i]) self.comboBox_ws.addItem(header[i]) self.comboBox_xsmd.addItem(header[i]) try: self.data = np.genfromtxt(self.folderPath[0], skip_header=headernum, delimiter=delim, filling_values=99999) QMessageBox.information(self, "File imported", "If invalid data was detected such as strings or " "other non-numrical characters, these data points could " "result in that the MetdataProcessor " "will fail to create your formatted inputdata.") #, 'Continue' except Exception as e: QMessageBox.critical(self, "Error: Check the number of columns in each line", str(e)) return def epw2umep(self, met_old): met_new = np.zeros((met_old.shape[0], 24)) - 999 # yyyy met_new[:, 0] = 1985 met_new[met_old.shape[0] - 1, 0] = 1986 # hour met_new[:, 2] = met_old[:, 3] test = met_new[:, 2] == 24 met_new[test, 2] = 0 # day of year mm = met_old[:, 1] dd = met_old[:, 2] rownum = met_old.shape[0] for i in range(0, rownum): yy = int(met_new[i, 0]) if (yy % 4) == 0: if (yy % 100) == 0: if (yy % 400) == 0: leapyear = 1 else: leapyear = 0 else: leapyear = 1 else: leapyear = 0 if leapyear == 1: dayspermonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] else: dayspermonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] met_new[i, 1] = sum(dayspermonth[0:int(mm[i] - 1)]) + dd[i] test2 = np.where(met_new[:, 2] == 0) met_new[np.where(met_new[:, 2] == 0), 1] = met_new[np.where(met_new[:, 2] == 0), 1] + 1 met_new[met_old.shape[0] - 1, 1] = 1 # minute met_new[:, 3] = 0 # met variables met_new[:, 11] = met_old[:, 6] # Ta met_new[:, 10] = met_old[:, 8] # Rh met_new[:, 12] = met_old[:, 9] / 1000. # P met_new[:, 16] = met_old[:, 12] # Ldown met_new[:, 14] = met_old[:, 13] # Kdown met_new[:, 22] = met_old[:, 14] # Kdir met_new[:, 21] = met_old[:, 15] # Kdiff met_new[:, 23] = met_old[:, 20] # Wdir met_new[:, 9] = met_old[:, 21] # Ws met_new[:, 13] = met_old[:, 33] # Rain met_new[np.where(met_new[:, 13] == 999), 13] = 0 return met_new def start_progress(self): outputfile = self.fileDialog.getSaveFileName(None, "Save File As:", None, "Text Files (*.txt)") if not outputfile[0]: QMessageBox.critical(None, "Error", "An output text file (.txt) must be specified") return met_old = self.data met_new = np.zeros((met_old.shape[0], 24)) - 999 if self.checkBoxEPW.isChecked(): self.progressBar.setRange(0, 23) met_new = self.epw2umep(met_old) norain = np.sum(met_new[:, 13]) if norain == 0: QMessageBox.critical(None, "Value error", "No precipitation found in EPW-file. Find alternative " "data source if rain is required (e.g. SUEWS).") # if np.min(met_new[:, 9]) == 0.0: # QMessageBox.critical(None, "Wind speed = 0.0", "The SUEWS model cannot found in EPW-file. Find alternative " # "data source if rain is required (e.g. SUEWS).") self.progressBar.setValue(23) else: self.progressBar.setRange(0, 23) rownum = self.data.shape[0] if self.checkBoxYear.isChecked(): yyyy_col = self.comboBox_yyyy.currentIndex() met_new[:, 0] = met_old[:, yyyy_col] else: met_new[:, 0] = self.spinBoxYear.value() self.progressBar.setValue(1) if self.checkBoxDOY.isChecked(): doy_col = self.comboBox_doy.currentIndex() met_new[:, 1] = met_old[:, doy_col] else: mm = met_old[:, self.comboBox_month.currentIndex()] dd = met_old[:, self.comboBox_dom.currentIndex()] for i in range(0, rownum): yy = int(met_new[i, 0]) if (yy % 4) == 0: if (yy % 100) == 0: if (yy % 400) == 0: leapyear = 1 else: leapyear = 0 else: leapyear = 1 else: leapyear = 0 if leapyear == 1: dayspermonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] else: dayspermonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] met_new[i, 1] = sum(dayspermonth[0:int(mm[i] - 1)]) + dd[i] self.progressBar.setValue(2) if self.checkBoxDectime.isChecked(): dectime_col = self.comboBox_dectime.currentIndex() timeres_old = np.round((met_old[1, dectime_col] - met_old[0, dectime_col]) * (60. * 24.)) nsh = int(timeres_old / 5) # QMessageBox.information(None, "Metdata pre-processor", str(timeres_old)) first_hour = (met_old[0, dectime_col] - np.floor(met_old[0, dectime_col])) * 24 met_new[0, 2] = first_hour first_min = np.round((met_new[0, 2] - np.floor(met_new[0, 2])) * 60) met_new[0, 3] = first_min for t in range(1, rownum): # min_now = first_hour + timeres_old met_new[t, 3] = met_new[(t - 1), 3] + timeres_old met_new[t, 2] = met_new[(t - 1), 2] if (met_new[t, 3] >= 60) and (met_new[t, 3] < 120): met_new[t, 3] = int(met_new[t, 3] - 60) met_new[t, 2] = met_new[t, 2] + 1 if (met_new[t, 3] >= 120) and (met_new[t, 3] < 180): met_new[t, 3] = int(met_new[t, 3] - 120) met_new[t, 2] = met_new[t, 2] + 2 if met_new[t, 3] >= 180: met_new[t, 3] = int(met_new[t, 3] - 180) met_new[t, 2] = met_new[t, 2] + 3 if met_new[t, 2] >= 24: met_new[t, 2] = 0 # else: # met_new[t, 2] = met_new[(t - 1), 2] # dechour = (met_old[:, dectime_col] - np.floor(met_old[:, dectime_col])) * 24 # met_new[:, 2] = dechour # minute = np.round((dechour - np.floor(dechour)) * 60) # minute[(minute == 60)] = 0 # changehour = np.where(minute == 60) # dechour[changehour] = dechour + 1 # met_new[:, 3] = minute else: met_new[:, 2] = met_old[:, self.comboBox_hour.currentIndex()] met_new[:, 3] = met_old[:, self.comboBox_minute.currentIndex()] nshhh= int(abs((met_new[1, 2] - met_new[0, 2])) * 12) nshmin = int(abs((met_new[1, 3] - met_new[0, 3])) / 5) nsh = nshhh + nshmin # Check if time gap exists #for i in range(0, met_new.shape[0] - 1): # dectime0 = met_new[i, 0] + met_new[i, 1] + met_new[i, 2] / 24. + met_new[i, 3] / (60. * 24.) # dectime1 = met_new[i + 1, 0] + met_new[i + 1, 1] + met_new[i + 1, 2] / 24. + met_new[i + 1, 3] / (60. * 24.) # timeres_old = np.round((dectime1 - dectime0) * (60. * 24.)) # nshtest = int(timeres_old / 5) # if nshtest > nsh: # QMessageBox.critical(None, "Input data is not continuous", "There seems to be a time gap at line:" # " \n" + str(i + 1)) # return self.progressBar.setValue(3) # Met variables if self.checkBox_kdown.isChecked(): met_new[:, 14] = met_old[:, self.comboBox_kdown.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 14] < 0.0) | (met_new[:, 14] > 1200.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Kdown - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 14] = -999.0 self.progressBar.setValue(4) if self.checkBox_ws.isChecked(): met_new[:, 9] = met_old[:, self.comboBox_ws.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 9] <= 0) | (met_new[:, 9] > 60.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Wind speed - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 9] = -999.0 self.progressBar.setValue(5) if self.checkBox_Tair.isChecked(): met_new[:, 11] = met_old[:, self.comboBox_Tair.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 11] < -30.0) | (met_new[:, 11] > 55.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Air temperature - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 11] = -999.0 self.progressBar.setValue(6) if self.checkBox_RH.isChecked(): met_new[:, 10] = met_old[:, self.comboBox_RH.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 10] < 0.00) | (met_new[:, 10] > 100.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Relative humidity - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 10] = -999.0 self.progressBar.setValue(7) if self.checkBox_pres.isChecked(): met_new[:, 12] = met_old[:, self.comboBox_pres.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 12] < 70.0) | (met_new[:, 12] > 107.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Pressure - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 12] = -999.0 self.progressBar.setValue(8) if self.checkBox_rain.isChecked(): met_new[:, 13] = met_old[:, self.comboBox_rain.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where(((met_new[:, 13] / nsh) < 0.0) | ((met_new[:, 13] / nsh) > 30.0)) #QMessageBox.critical(None, "Test", met_new[0, 13] / nsh) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Rain - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 13] = -999.0 self.progressBar.setValue(9) if self.checkBox_snow.isChecked(): met_new[:, 15] = met_old[:, self.comboBox_snow.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where(((met_new[:, 15] / nsh) < 0.0) | ((met_new[:, 15] / nsh) > 300.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Snow - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 15] = -999.0 self.progressBar.setValue(10) if self.checkBox_ldown.isChecked(): met_new[:, 16] = met_old[:, self.comboBox_ldown.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 16] < 100.0) | (met_new[:, 16] > 600.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Ldown - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 16] = -999.0 self.progressBar.setValue(11) if self.checkBox_fcld.isChecked(): met_new[:, 17] = met_old[:, self.comboBox_fcld.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 17] < 0.0) | (met_new[:, 17] > 1.01)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Fraction of cloud - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 17] = -999.0 self.progressBar.setValue(12) if self.checkBox_Wuh.isChecked(): met_new[:, 18] = met_old[:, self.comboBox_Wuh.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where(((met_new[:, 18] / nsh) < 0.0) | ((met_new[:, 18] / nsh) > 10.01)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "External water use - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 18] = -999.0 self.progressBar.setValue(13) if self.checkBox_xcmd.isChecked(): met_new[:, 19] = met_old[:, self.comboBox_xcmd.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 19] < 0.01) | (met_new[:, 19] > 0.5)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Soil moisture - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 19] = -999.0 self.progressBar.setValue(14) if self.checkBox_lai.isChecked(): met_new[:, 20] = met_old[:, self.comboBox_lai.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 20] < 0.0) | (met_new[:, 20] > 15.01)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Leaf area index - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 20] = -999.0 self.progressBar.setValue(15) if self.checkBox_kdiff.isChecked(): met_new[:, 21] = met_old[:, self.comboBox_kdiff.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 21] < 0.0) | (met_new[:, 21] > 600.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Diffuse shortwave radiation - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 21] = -999.0 self.progressBar.setValue(16) if self.checkBox_kdir.isChecked(): met_new[:, 22] = met_old[:, self.comboBox_kdir.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 22] < 0.0) | (met_new[:, 22] > 1200.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Direct shortwave radiation - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 22] = -999.0 self.progressBar.setValue(17) if self.checkBox_Wd.isChecked(): met_new[:, 23] = met_old[:, self.comboBox_Wd.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 23] < 0.0) | (met_new[:, 23] > 360.01)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Wind directions - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 23] = -999.0 self.progressBar.setValue(18) if self.checkBox_qn.isChecked(): met_new[:, 4] = met_old[:, self.comboBox_qn.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 4] < -200.0) | (met_new[:, 4] > 800.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Net radiation - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 4] = -999.0 self.progressBar.setValue(19) if self.checkBox_qh.isChecked(): met_new[:, 5] = met_old[:, self.comboBox_qh.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 5] < -200.0) | (met_new[:, 5] > 750.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Sensible heat flux - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 5] = -999.0 self.progressBar.setValue(20) if self.checkBox_qe.isChecked(): met_new[:, 6] = met_old[:, self.comboBox_qe.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 6] < -100.0) | (met_new[:, 6] > 650.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Latent heat flux - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 6] = -999.0 self.progressBar.setValue(21) if self.checkBox_qs.isChecked(): met_new[:, 7] = met_old[:, self.comboBox_qs.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 7] < -200.0) | (met_new[:, 7] > 650.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Storage heat flux - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 7] = -999.0 self.progressBar.setValue(22) if self.checkBox_qf.isChecked(): met_new[:, 8] = met_old[:, self.comboBox_qf.currentIndex()] if self.checkBoxQuality.isChecked(): testwhere = np.where((met_new[:, 8] < 0.0) | (met_new[:, 8] > 1500.0)) if testwhere[0].__len__() > 0: QMessageBox.critical(None, "Value error", "Anthropogenic heat flux - beyond what is expected at line:" " \n" + str(testwhere[0] + 1)) return else: met_new[:, 8] = -999.0 self.progressBar.setValue(23) # Quality control # if self.checkBoxSOLWEIG.isChecked(): #NOT READY # # Moving one hour # Ta[1:np.size(Ta)] = Ta[0:np.size(Ta) - 1] # Ta[0] = Ta[1] # RH[1:np.size(RH)] = RH[0:np.size(RH) - 1] # RH[0] = RH[1] # G[1:np.size(G)] = G[0:np.size(G) - 1] # G[0] = G[1] # D[1:np.size(D)] = D[0:np.size(D) - 1] # D[0] = D[1] # I[1:np.size(I)] = I[0:np.size(I) - 1] # I[0] = I[1] # Ws[1:np.size(Ws)] = Ws[0:np.size(Ws) - 1] # Ws[0] = Ws[1] # header = '%iy id it imin Q* QH QE Qs Qf Wind RH Td press rain ' \ ' Kdn snow ldown fcld wuh xsmd lai_hr Kdiff Kdir Wd' # #Save as text files # numformat = '%3d %2d %3d %2d %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f ' \ # '%6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f' numformat = '%d %d %d %d %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f ' \ '%.2f %.2f %.2f %.2f %.2f %.2f %.2f' np.savetxt(outputfile[0], met_new, fmt=numformat, header=header, comments='') self.progressBar.setValue(23) QMessageBox.information(None, "Metdata pre-processor", "Input data to PET-calculator generated") def run(self): """Run method that performs all the real work""" # show the dialog self.show() self.exec_() def help(self): url = 'https://umep-docs.readthedocs.io/en/latest/pre-processor/Meteorological%20Data%20MetPreprocessor.html' webbrowser.open_new_tab(url)
class ImportUserDatabaseDialog(ImportUserDatabaseDialogBase, ImportUserDatabaseDialogUI): def __init__(self, *args, base_path=None, **kwargs): super().__init__(*args, **kwargs) self.base_path = base_path self.setupUi(self) self.btBrowseInputFile.setFocus() self._dialog = None self._workers = WorkerQueue(self, ProgressDialog(self)) # Add import button self.btImport = self.buttonBox.addButton("&Import", QDialogButtonBox.ActionRole) self.btImport.setIcon(QIcon(":/icons/images/import-database.svg")) self.btImport.setEnabled(False) # Set Close button as default bt_close = self.buttonBox.button(QDialogButtonBox.Close) if bt_close is not None: bt_close.setDefault(True) # Create palette used when validating input files self._error_palette = QPalette() self._error_palette.setColor(QPalette.Base, QColor(Qt.red).lighter(150)) # Set completer for input files # TODO: completer makes the dialog freeze for seconds on show, disable it until fixed # completer = QCompleter(self.editInputFile) # if sys.platform.startswith('win'): # completer.setCaseSensitivity(Qt.CaseInsensitive) # model = QFileSystemModel(completer) # model.setFilter(QDir.AllDirs | QDir.Files | QDir.NoDotAndDotDot) # model.setNameFilterDisables(False) # model.setNameFilters(['*.mgf', '*.msp']) # model.setRootPath(QDir.currentPath()) # completer.setModel(model) self.editInputFile.setText(QDir.currentPath()) # self.editInputFile.setCompleter(completer) # Connect events self.btBrowseInputFile.clicked.connect(self.browse) self.btImport.clicked.connect(self.import_database) self.editInputFile.textChanged.connect(self.check_import_possible) self.editDatabaseName.textChanged.connect(self.check_import_possible) def check_import_possible(self): self.btImport.setEnabled(len(self.editInputFile.text()) > 0 and len(self.editDatabaseName.text()) > 0) def browse(self): """Open a dialog to choose .mgf file""" self._dialog = QFileDialog(self) self._dialog.setFileMode(QFileDialog.ExistingFile) self._dialog.setNameFilters(["All supported formats (*.mgf *.msp)", "Mascot Generic Format (*.mgf)", "NIST Text Format of Individual Spectra (*.msp)", "All files (*)"]) def set_filename(result): if result == QDialog.Accepted: filename = self._dialog.selectedFiles()[0] self.editInputFile.setText(filename) self.editDatabaseName.setText(os.path.splitext(os.path.basename(filename))[0]) self.editInputFile.setPalette(self.style().standardPalette()) self._dialog.finished.connect(set_filename) self._dialog.open() def import_database(self): try: os.makedirs(self.base_path, exist_ok=True) except PermissionError: QMessageBox.critical(self, None, 'Unable to import database because the destination folder is not writable.') input_file = self.editInputFile.text() if len(input_file) == 0 or not os.path.exists(input_file) \ or os.path.splitext(input_file)[1].lower() not in ('.mgf', '.msp'): self.editInputFile.setPalette(self._error_palette) name = self.editDatabaseName.text() if len(name) == 0: self.editDatabaseName.setPalette(self._error_palette) id_ = {'User': {name: [input_file]}} worker = self.prepare_convert_database_worker(id_) if worker is not None: self._workers.append(worker) self._workers.start() def prepare_convert_database_worker(self, id_): def error(e): if isinstance(e, NotImplementedError): QMessageBox.warning(self, None, "File format is not supported.") else: QMessageBox.warning(self, None, str(e)) def finished(): QMessageBox.information(self, None, "Database was successfully imported.") worker = ConvertDatabasesWorker(id_, output_path=self.base_path) worker.error.connect(error) worker.finished.connect(finished) return worker
class ExportDBResultsDialog(ExportDBResultsDialogBase, ExportDBResultsDialogUI): # noinspection PyUnusedLocal def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setupUi(self) self._dialog = None self._workers = WorkerQueue(self, ProgressDialog(self)) super().__init__(*args, **kwargs) self.setupUi(self) self._dialog = None # Set completer for output files completer = QCompleter(self.editExportFile) if sys.platform.startswith('win'): completer.setCaseSensitivity(Qt.CaseInsensitive) model = QFileSystemModel(completer) model.setFilter(QDir.AllDirs | QDir.Files | QDir.NoDotAndDotDot) model.setRootPath(QDir.currentPath()) completer.setModel(model) self.editExportFile.setCompleter(completer) # Create palette used when validating input files self._error_palette = QPalette() self._error_palette.setColor(QPalette.Base, QColor(Qt.red).lighter(150)) self.cbFieldSeparator.setOtherEditWidget(self.editFieldSeparator) self.cbFieldSeparator.setCurrentText("Semicolon (;)") # Connect events self.btBrowseExportFile.clicked.connect(self.browse) self.btSelectAllStandards.clicked.connect( lambda: self.select(self.lstStandards, 'all')) self.btSelectNodeStandards.clicked.connect( lambda: self.select(self.lstStandards, 'none')) self.btInvertSelectionStandards.clicked.connect( lambda: self.select(self.lstStandards, 'invert')) self.btSelectAllAnalogs.clicked.connect( lambda: self.select(self.lstAnalogs, 'all')) self.btSelectNodeAnalogs.clicked.connect( lambda: self.select(self.lstAnalogs, 'none')) self.btInvertSelectionAnalogs.clicked.connect( lambda: self.select(self.lstAnalogs, 'invert')) self.editExportFile.textChanged.connect(self.validate_export_filename) self.editFieldSeparator.textChanged.connect(self.validate_separator) def validate_export_filename(self): output_file = self.editExportFile.text() if os.access(os.path.dirname(output_file), os.W_OK): self.editExportFile.setPalette(self.style().standardPalette()) return True else: self.editExportFile.setPalette(self._error_palette) return False def validate_separator(self): if len(self.editFieldSeparator.text()) == 1: self.editFieldSeparator.setPalette(self.style().standardPalette()) return True else: self.editFieldSeparator.setPalette(self._error_palette) return False def done(self, r): if r == QDialog.Accepted: if self.validate_export_filename() and self.validate_separator(): super().done(r) else: super().done(r) def browse(self): self._dialog = QFileDialog(self) self._dialog.setAcceptMode(QFileDialog.AcceptSave) self._dialog.setNameFilters( ["Comma separated values (*.csv *.tsv *.txt)"]) def set_filename(result): if result == QDialog.Accepted: filename = self._dialog.selectedFiles()[0] self.editExportFile.setText(filename) self._dialog.finished.connect(set_filename) self._dialog.open() def select(self, list_widget: QListWidget, type_: str): for i in range(list_widget.count()): item = list_widget.item(i) if type_ == 'all': item.setCheckState(Qt.Checked) elif type_ == 'none': item.setCheckState(Qt.Unchecked) elif type_ == 'invert': item.setCheckState(Qt.Checked if item.checkState() == Qt.Unchecked else Qt.Unchecked) def getValues(self) -> (str, str, int, Dict[str, List[str]]): attributes = {'standards': [], 'analogs': []} for type_, list_widget in (('standards', self.lstStandards), ('analogs', self.lstAnalogs)): for i in range(list_widget.count()): item = list_widget.item(i) if item.checkState() == Qt.Checked: attributes[type_].append(item.data(Qt.DisplayRole)) return self.editExportFile.text(), self.editFieldSeparator.delimiter( ), self.spinNumHits.value(), attributes