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)
Exemple #3
0
    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()
Exemple #6
0
 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()
Exemple #8
0
    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()
Exemple #11
0
    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()
Exemple #13
0
 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()
Exemple #14
0
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)
Exemple #17
0
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
Exemple #19
0
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