Example #1
0
 def export_pipeline(self):
     exp = ExportDialog(self._settings.segmentation_pipelines,
                        ProfileDictViewer)
     if not exp.exec_():
         return
     dial = QFileDialog(self, "Export pipeline segment")
     dial.setFileMode(QFileDialog.AnyFile)
     dial.setAcceptMode(QFileDialog.AcceptSave)
     dial.setDirectory(self._settings.get("io.save_directory", ""))
     dial.setNameFilter("Segment pipeline (*.json)")
     dial.setDefaultSuffix("json")
     dial.selectFile("segment_pipeline.json")
     dial.setHistory(dial.history() + self._settings.get_path_history())
     if dial.exec_():
         file_path = dial.selectedFiles()[0]
         data = {
             x: self._settings.segmentation_pipelines[x]
             for x in exp.get_export_list()
         }
         with open(file_path, "w") as ff:
             json.dump(data,
                       ff,
                       cls=self._settings.json_encoder_class,
                       indent=2)
         self._settings.set("io.save_directory", os.path.dirname(file_path))
         self._settings.add_path_history(os.path.dirname(file_path))
 def export_plans(self):
     choose = ExportDialog(self.settings.batch_plans, PlanPreview)
     if not choose.exec_():
         return
     dial = QFileDialog(self, "Export calculation plans")
     dial.setFileMode(QFileDialog.AnyFile)
     dial.setAcceptMode(QFileDialog.AcceptSave)
     dial.setDirectory(
         dial.setDirectory(
             self.settings.get("io.batch_plan_directory",
                               str(Path.home()))))
     dial.setNameFilter("Calculation plans (*.json)")
     dial.setDefaultSuffix("json")
     dial.selectFile("calculation_plans.json")
     dial.setHistory(dial.history() + self.settings.get_path_history())
     if dial.exec_():
         file_path = str(dial.selectedFiles()[0])
         self.settings.set("io.batch_plan_directory",
                           os.path.dirname(file_path))
         self.settings.add_path_history(os.path.dirname(file_path))
         data = {
             x: self.settings.batch_plans[x]
             for x in choose.get_export_list()
         }
         with open(file_path, "w") as ff:
             json.dump(data,
                       ff,
                       cls=self.settings.json_encoder_class,
                       indent=2)
Example #3
0
    def export_measurement_profiles(self):
        exp = ExportDialog(self.settings.measurement_profiles, StringViewer)
        if not exp.exec_():
            return
        dial = QFileDialog(self, "Export settings profiles")
        dial.setDirectory(self.settings.get("io.export_directory", ""))
        dial.setFileMode(QFileDialog.AnyFile)
        dial.setAcceptMode(QFileDialog.AcceptSave)
        dial.setNameFilter("measurement profile (*.json)")
        dial.setDefaultSuffix("json")
        dial.selectFile("measurements_profile.json")

        if dial.exec_():
            file_path = str(dial.selectedFiles()[0])
            self.settings.set("io.export_directory", file_path)
            data = {
                x: self.settings.measurement_profiles[x]
                for x in exp.get_export_list()
            }
            with open(file_path, "w") as ff:
                json.dump(data,
                          ff,
                          cls=self.settings.json_encoder_class,
                          indent=2)
            self.settings.set("io.save_directory", os.path.dirname(file_path))
Example #4
0
 def import_profiles(self):
     dial = QFileDialog(self, "Import profile segment")
     dial.setFileMode(QFileDialog.ExistingFile)
     dial.setAcceptMode(QFileDialog.AcceptOpen)
     dial.setDirectory(
         self._settings.get("io.save_directory", str(Path.home())))
     dial.setNameFilter("Segment profile (*.json)")
     dial.setHistory(dial.history() + self._settings.get_path_history())
     if dial.exec_():
         file_path = dial.selectedFiles()[0]
         save_dir = os.path.dirname(file_path)
         self._settings.set("io.save_directory", save_dir)
         self._settings.add_path_history(save_dir)
         profs, err = self._settings.load_part(file_path)
         if err:
             QMessageBox.warning(
                 self, "Import error",
                 "error during importing, part of data were filtered.")
         profiles_dict = self._settings.segmentation_profiles
         imp = ImportDialog(profs, profiles_dict, ProfileDictViewer)
         if not imp.exec_():
             return
         for original_name, final_name in imp.get_import_list():
             profiles_dict[final_name] = profs[original_name]
         self._settings.dump()
         self.update_profile_list()
Example #5
0
    def select_file(self):
        dial = QFileDialog()
        dial.setFileMode(QFileDialog.ExistingFile)
        dial.setAcceptMode(QFileDialog.AcceptOpen)

        if dial.exec_():
            self.first_text.setText(dial.selectedFiles()[0])
Example #6
0
 def folder_dialog(self, *args, **kwargs):
     dialog = QFileDialog(self)
     if not self._is_file_dialog_opened:
         # set the initial directory to HOME
         dialog.setDirectory(os.path.expanduser("~"))
         self._is_file_dialog_opened = True
     dir_name = None
     dialog.setWindowTitle("Open .edi Directory...")
     dialog.setFileMode(QFileDialog.DirectoryOnly)
     while dir_name is None:
         if dialog.exec_() == QDialog.Accepted:
             dir_name = dialog.selectedFiles()[0]
             dir_name = str(dir_name)
             file_list = [
                 os.path.join(dir_name, edi) for edi in os.listdir(dir_name)
                 if edi.endswith("edi")
             ]
             if not file_list:
                 # empty list
                 QMessageBox.information(
                     self, "NOTE",
                     "Directory does not contain any .edi file, please select again."
                 )
                 dir_name = None  # will read again
             else:
                 self._progress_bar.setMaximumValue(len(file_list))
                 self._progress_bar.onStart()
                 self._add_files(file_list, os.path.basename(dir_name))
                 self._update_tree_view()
                 self._progress_bar.onFinished()
         else:
             break
 def import_plans(self):
     dial = QFileDialog(self, "Import calculation plans")
     dial.setFileMode(QFileDialog.ExistingFile)
     dial.setAcceptMode(QFileDialog.AcceptOpen)
     dial.setDirectory(
         self.settings.get("io.open_directory", str(Path.home())))
     dial.setNameFilter("Calculation plans (*.json)")
     dial.setDefaultSuffix("json")
     dial.setHistory(dial.history() + self.settings.get_path_history())
     if dial.exec_():
         file_path = dial.selectedFiles()[0]
         plans, err = self.settings.load_part(file_path)
         self.settings.set("io.batch_plan_directory",
                           os.path.dirname(file_path))
         self.settings.add_path_history(os.path.dirname(file_path))
         if err:
             QMessageBox.warning(
                 self, "Import error",
                 "error during importing, part of data were filtered.")
         choose = ImportDialog(plans, self.settings.batch_plans,
                               PlanPreview)
         if choose.exec_():
             for original_name, final_name in choose.get_import_list():
                 self.settings.batch_plans[final_name] = plans[
                     original_name]
             self.update_plan_list()
Example #8
0
 def select_manual_output_folder(self):
     # _current_folder = self.main_window.current_folder
     dlg = QFileDialog(parent=self.main_window,
                       caption="Select or Define Output Directory")
     dlg.setFileMode(QFileDialog.Directory)
     if dlg.exec_():
         output_folder_name = str(dlg.selectedFiles()[0])
         self.main_window.autonom_ui.manual_output_folder_field.setText(output_folder_name)
Example #9
0
def open_a_file_dialog(parent=None,
                       default_suffix=None,
                       directory=None,
                       file_filter=None,
                       accept_mode=None,
                       file_mode=None):
    """
    Open a dialog asking for a file location and name to and return it
    :param parent: QWidget; The parent QWidget of the created dialog
    :param default_suffix: String; The default suffix to be passed
    :param directory: String; Directory to which the dialog will open
    :param file_filter: String; The filter name and file type e.g. "Python files (*.py)"
    :param accept_mode: enum AcceptMode; Defines the AcceptMode of the dialog, check QFileDialog Class for details
    :param file_mode: enum FileMode; Defines the FileMode of the dialog, check QFileDialog Class for details
    :return: String; The filename that was selected, it is possible to return a directory so look out for that
    """
    global _LAST_SAVE_DIRECTORY
    dialog = QFileDialog(parent)

    # It is the intention to only save the user's last used directory until workbench is restarted similar to other
    # applications (VSCode, Gedit etc)
    if _LAST_SAVE_DIRECTORY is not None and directory is None:
        dialog.setDirectory(_LAST_SAVE_DIRECTORY)
    elif directory is not None:
        dialog.setDirectory(directory)
    else:
        dialog.setDirectory(os.path.expanduser("~"))

    if file_filter is not None:
        dialog.setFilter(QDir.Files)
        dialog.setNameFilter(file_filter)

    if default_suffix is not None:
        dialog.setDefaultSuffix(default_suffix)

    if file_mode is not None:
        dialog.setFileMode(file_mode)

    if accept_mode is not None:
        dialog.setAcceptMode(accept_mode)

    # Connect the actual filename setter
    dialog.fileSelected.connect(_set_last_save)

    # Wait for dialog to finish before allowing continuation of code
    if dialog.exec_() == QDialog.Rejected:
        return None

    filename = _LAST_SAVE_DIRECTORY

    # Make sure that the _LAST_SAVE_DIRECTORY is set as a directory
    if _LAST_SAVE_DIRECTORY is not None and not os.path.isdir(
            _LAST_SAVE_DIRECTORY):
        # Remove the file for last directory
        _LAST_SAVE_DIRECTORY = os.path.dirname(
            os.path.abspath(_LAST_SAVE_DIRECTORY))

    return filename
Example #10
0
 def choose_data_prefix(self):
     dial = QFileDialog()
     dial.setAcceptMode(QFileDialog.AcceptOpen)
     dial.setFileMode(QFileDialog.Directory)
     dial.setDirectory(self.base_prefix.text())
     dial.setHistory(dial.history() + self.settings.get_path_history())
     if dial.exec_():
         dir_path = str(dial.selectedFiles()[0])
         self.base_prefix.setText(dir_path)
 def select_directory(self):
     dial = QFileDialog(self, "Select directory")
     dial.setDirectory(
         self.settings.get("io.batch_directory", self.settings.get("io.load_image_directory", str(Path.home())))
     )
     dial.setFileMode(QFileDialog.Directory)
     if dial.exec_():
         self.paths_input.setText(dial.selectedFiles()[0])
         self.settings.set("io.batch_directory", str(dial.selectedFiles()[0]))
Example #12
0
 def choose_result_prefix(self):
     dial = QFileDialog()
     dial.setOption(QFileDialog.DontUseNativeDialog, True)
     dial.setAcceptMode(QFileDialog.AcceptOpen)
     dial.setFileMode(QFileDialog.Directory)
     dial.setDirectory(self.result_prefix.text())
     dial.setHistory(dial.history() + self.settings.get_path_history())
     if dial.exec_():
         dir_path = str(dial.selectedFiles()[0])
         self.result_prefix.setText(dir_path)
Example #13
0
 def mapping_dialog():
     dial = QFileDialog(self, "Select file")
     dial.setHistory(dial.history() + self.settings.get_path_history())
     base_path = str(self.base_prefix.text()).strip()
     if base_path != "":
         dial.setDirectory(base_path)
     dial.setFileMode(QFileDialog.ExistingFile)
     if dial.exec_():
         path = str(dial.selectedFiles())
         self.mask_path_list[i].setText(path)
         file_mapper: MaskFile = self.mask_mapper_list[pos]
         file_mapper.set_map_path(path)
Example #14
0
def open_a_file_dialog(parent=None,  default_suffix=None, directory=None, file_filter=None, accept_mode=None,
                       file_mode=None):
    """
    Open a dialog asking for a file location and name to and return it
    :param parent: QWidget; The parent QWidget of the created dialog
    :param default_suffix: String; The default suffix to be passed
    :param directory: String; Directory to which the dialog will open
    :param file_filter: String; The filter name and file type e.g. "Python files (*.py)"
    :param accept_mode: enum AcceptMode; Defines the AcceptMode of the dialog, check QFileDialog Class for details
    :param file_mode: enum FileMode; Defines the FileMode of the dialog, check QFileDialog Class for details
    :return: String; The filename that was selected, it is possible to return a directory so look out for that
    """
    global _LAST_SAVE_DIRECTORY
    dialog = QFileDialog(parent)

    # It is the intention to only save the user's last used directory until workbench is restarted similar to other
    # applications (VSCode, Gedit etc)
    if _LAST_SAVE_DIRECTORY is not None and directory is None:
        dialog.setDirectory(_LAST_SAVE_DIRECTORY)
    elif directory is not None:
        dialog.setDirectory(directory)
    else:
        dialog.setDirectory(os.path.expanduser("~"))

    if file_filter is not None:
        dialog.setFilter(QDir.Files)
        dialog.setNameFilter(file_filter)

    if default_suffix is not None:
        dialog.setDefaultSuffix(default_suffix)

    if file_mode is not None:
        dialog.setFileMode(file_mode)

    if accept_mode is not None:
        dialog.setAcceptMode(accept_mode)

    # Connect the actual filename setter
    dialog.fileSelected.connect(_set_last_save)

    # Wait for dialog to finish before allowing continuation of code
    if dialog.exec_() == QDialog.Rejected:
        return None

    filename = _LAST_SAVE_DIRECTORY

    # Make sure that the _LAST_SAVE_DIRECTORY is set as a directory
    if _LAST_SAVE_DIRECTORY is not None and not os.path.isdir(_LAST_SAVE_DIRECTORY):
        # Remove the file for last directory
        _LAST_SAVE_DIRECTORY = os.path.dirname(os.path.abspath(_LAST_SAVE_DIRECTORY))

    return filename
 def select_files(self):
     dial = QFileDialog(self, "Select files")
     dial.setDirectory(
         self.settings.get("io.batch_directory", self.settings.get("io.load_image_directory", str(Path.home())))
     )
     dial.setFileMode(QFileDialog.ExistingFiles)
     if dial.exec_():
         self.settings.set("io.batch_directory", os.path.dirname(str(dial.selectedFiles()[0])))
         new_paths = sorted(set(map(str, dial.selectedFiles())) - self.files_to_proceed)
         for path in new_paths:
             self.selected_files.addItem(FileListItem(path))
         self.files_to_proceed.update(new_paths)
         self.file_list_changed.emit(self.files_to_proceed)
Example #16
0
    def stl_dialog(self):
        dialog = QFileDialog(self)
        dialog.setWindowTitle('Open STL Tool file')
        dialog.setNameFilter('(*.stl)')

        filename = None

        if dialog.exec_() == QDialog.Accepted:
            filename = dialog.selectedFiles()

        if filename:
            self.setFilename(filename[0])
        else:
            self.clearFilename()
Example #17
0
def showSelectProjectDialog(parent: QWidget = None) -> Optional[Path]:
    dialog = QFileDialog(parent, Qt.Dialog)
    dialog.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.Dialog)
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setLabelText(QFileDialog.LookIn, "Select project folder")
    dialog.setFileMode(QFileDialog.Directory)
    dialog.setOption(QFileDialog.ShowDirsOnly, True)
    dialog.setViewMode(QFileDialog.Detail)
    dialog.setDirectory(QDir.homePath())

    if dialog.exec_():
        paths = dialog.selectedFiles()
        assert len(paths) == 1
        path = Path(paths[0])
        return path
Example #18
0
 def file_dialog(self, *args, **kwargs):
     dialog = QFileDialog(self)
     if not self._is_file_dialog_opened:
         # set the initial directory to HOME
         dialog.setDirectory(os.path.expanduser("~"))
         self._is_file_dialog_opened = True
     dialog.setWindowTitle('Open .edi Files...')
     dialog.setNameFilter('.edi files (*.edi)')
     dialog.setFileMode(QFileDialog.ExistingFiles)
     if dialog.exec_() == QDialog.Accepted:
         file_list = dialog.selectedFiles()
         self._progress_bar.setMaximumValue(len(file_list))
         self._progress_bar.onStart()
         self._add_files(file_list, DEFAULT_GROUP_NAME)
         self._update_tree_view()
         self._progress_bar.onFinished()
Example #19
0
    def _export_shape_file(self, *args, **kwargs):
        # show files
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Information)
        msg.setText("You are about to create shape files.")
        msg.setInformativeText(
            "Please select an output directory after click \"OK\"\n"
            "For the list of .edi files (stations) included in the creation, please click \"Show Details\""
        )
        msg.setWindowTitle("Note")
        msg.setDetailedText("\n".join([
            "{station} ({fn})".format(
                station=station, fn=self._file_handler.station2ref(station))
            for station in self._station_viewer.selected_stations
        ]))
        msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)

        if msg.exec_() == QMessageBox.Ok:
            dialog = QFileDialog(self)
            dir_name = None
            dialog.setWindowTitle("Selecting Output Directory ...")
            dialog.setFileMode(QFileDialog.DirectoryOnly)
            while dir_name is None:
                if dialog.exec_() == QDialog.Accepted:
                    dir_name = dialog.selectedFiles()[0]
                    dir_name = str(dir_name)
                    if not os.path.isdir(dir_name):
                        QMessageBox.information(
                            self, "NOTE",
                            "Please select a directory to save the created shape files."
                        )
                        dir_name = None  # will read again
                else:
                    break
            if dir_name is not None:
                collect = EdiCollection(mt_objs=[
                    self._file_handler.get_MT_obj(
                        self._file_handler.station2ref(station))
                    for station in self._station_viewer.selected_stations
                ])
                collect.create_mt_station_gdf(dir_name)
                QMessageBox.information(self, "Creation Completed",
                                        "Output written to %s" % dir_name)
                webbrowser.open(dir_name)
 def select_files(self):
     dial = QFileDialog(self, "Select files")
     dial.setDirectory(
         self.settings.get(
             "io.batch_directory",
             self.settings.get("io.load_image_directory",
                               str(Path.home()))))
     dial.setFileMode(QFileDialog.ExistingFiles)
     if dial.exec_():
         self.settings.set("io.batch_directory",
                           os.path.dirname(str(dial.selectedFiles()[0])))
         new_paths = sorted(
             set(map(str, dial.selectedFiles())) - self.files_to_proceed)
         for path in new_paths:
             size = os.stat(path).st_size
             size = float(size) / (1024**2)
             lwi = QListWidgetItem("{:s} ({:.2f} MB)".format(path, size))
             lwi.setTextAlignment(Qt.AlignRight)
             self.selected_files.addItem(lwi)
         self.files_to_proceed.update(new_paths)
         self.file_list_changed.emit(self.files_to_proceed)
Example #21
0
 def import_measurement_profiles(self):
     dial = QFileDialog(self, "Import settings profiles")
     dial.setDirectory(self.settings.get("io.export_directory", ""))
     dial.setFileMode(QFileDialog.ExistingFile)
     dial.setNameFilter("measurement profile (*.json)")
     if dial.exec_():
         file_path = str(dial.selectedFiles()[0])
         self.settings.set("io.export_directory", file_path)
         stat, err = self.settings.load_part(file_path)
         if err:
             QMessageBox.warning(
                 self, "Import error",
                 "error during importing, part of data were filtered.")
         measurement_dict = self.settings.measurement_profiles
         imp = ImportDialog(stat, measurement_dict, StringViewer)
         if not imp.exec_():
             return
         for original_name, final_name in imp.get_import_list():
             measurement_dict[final_name] = stat[original_name]
         self.profile_list.clear()
         self.profile_list.addItems(list(sorted(measurement_dict.keys())))
         self.settings.dump()
Example #22
0
    def run_opensbml(self,
                     filenames=None,
                     goto=None,
                     word='',
                     editorwindow=None,
                     processevents=True):
        """Prompt the user to load a SBML file, translate to antimony, and 
        display in a new window"""
        editor = self.main.editor
        editor0 = editor.get_current_editor()
        if editor0 is not None:
            position0 = editor0.get_position('cursor')
            filename0 = editor.get_current_filename()
        else:
            position0, filename0 = None, None
        if not filenames:
            # Recent files action
            action = editor.sender()
            if isinstance(action, QAction):
                filenames = from_qvariant(action.data(), to_text_string)
        if not filenames:
            basedir = getcwd()
            if editor.edit_filetypes is None:
                editor.edit_filetypes = get_edit_filetypes()
            if editor.edit_filters is None:
                editor.edit_filters = get_edit_filters()

            c_fname = editor.get_current_filename()
            if c_fname is not None and c_fname != editor.TEMPFILE_PATH:
                basedir = os.path.dirname(c_fname)
            editor.redirect_stdio.emit(False)
            parent_widget = editor.get_current_editorstack()
            if filename0 is not None:
                selectedfilter = get_filter(editor.edit_filetypes,
                                            os.path.splitext(filename0)[1])
            else:
                selectedfilter = ''
            if not running_under_pytest():
                customfilters = 'SBML files (*.sbml *.xml);;All files (*.*)'
                filenames, _sf = getopenfilenames(
                    parent_widget,
                    _("Open SBML file"),
                    basedir,
                    customfilters,
                    selectedfilter=selectedfilter,
                    options=QFileDialog.HideNameFilterDetails)
            else:
                # Use a Qt (i.e. scriptable) dialog for pytest
                dialog = QFileDialog(parent_widget,
                                     _("Open SBML file"),
                                     options=QFileDialog.DontUseNativeDialog)
                if dialog.exec_():
                    filenames = dialog.selectedFiles()
            editor.redirect_stdio.emit(True)
            if filenames:
                filenames = [os.path.normpath(fname) for fname in filenames]
            else:
                return

        focus_widget = QApplication.focusWidget()
        if editor.dockwidget and\
           (not editor.dockwidget.isAncestorOf(focus_widget)\
            and not isinstance(focus_widget, CodeEditor)):
            editor.dockwidget.setVisible(True)
            editor.dockwidget.setFocus()
            editor.dockwidget.raise_()

        def _convert(fname):
            fname = os.path.abspath(encoding.to_unicode_from_fs(fname))
            if os.name == 'nt' and len(fname) >= 2 and fname[1] == ':':
                fname = fname[0].upper() + fname[1:]
            return fname

        if hasattr(filenames, 'replaceInStrings'):
            # This is a QStringList instance (PyQt API #1), converting to list:
            filenames = list(filenames)
        if not isinstance(filenames, list):
            filenames = [_convert(filenames)]
        else:
            filenames = [_convert(fname) for fname in list(filenames)]

        if isinstance(goto, int):
            goto = [goto]
        elif goto is not None and len(goto) != len(filenames):
            goto = None

        for index, filename in enumerate(filenames):
            p = re.compile('(.xml$|.sbml$)')
            pythonfile = p.sub('_antimony.py', filename)
            if (pythonfile == filename):
                pythonfile = filename + "_antimony.py"
            # -- Do not open an already opened file
            current_editor = editor.set_current_filename(
                pythonfile, editorwindow)
            if current_editor is None:
                # -- Not a valid filename:
                if not os.path.isfile(filename):
                    continue
                # --
                current_es = editor.get_current_editorstack(editorwindow)

                # Creating the editor widget in the first editorstack (the one
                # that can't be destroyed), then cloning this editor widget in
                # all other editorstacks:
                finfo, newname = self.load_and_translate(
                    filename, pythonfile, editor)
                finfo.path = editor.main.get_spyder_pythonpath()
                editor._clone_file_everywhere(finfo)
                current_editor = current_es.set_current_filename(newname)

                current_es.analyze_script()
            if goto is not None:  # 'word' is assumed to be None as well
                current_editor.go_to_line(goto[index], word=word)
                position = current_editor.get_position('cursor')
                editor.cursor_moved(filename0, position0, filename, position)
            if (current_editor is not None):
                current_editor.clearFocus()
                current_editor.setFocus()
                current_editor.window().raise_()
            if processevents:
                QApplication.processEvents()
Example #23
0
class VMainWindow(VMainWindowBaseClass, Ui_VMainWindowClass):
    #                      str, DataFrame, DataType
    data_selected = Signal(str, object, object)
    predicted_data_selected = Signal(dict)
    ground_truth_data_selected = Signal(dict)
    image_data_selected = Signal([str, list], [str])
    file_loaded = Signal(object)

    def __init__(self):
        super(VMainWindow, self).__init__()
        self.setupUi(self)

        self._widget_setup()
        self._signals_setup()

    def __enter__(self):
        return self

    def __exit__(self, *args, **kwargs):
        try:
            self.controller.cleanup()
        except AttributeError:
            pass

    def _widget_setup(self):
        self._error_dialog = VErrorMessageBox(self)

        self._file_dialog = QFileDialog(self, self.tr('Open File'), '')
        self._file_dialog.setOption(QFileDialog.DontUseNativeDialog)

        # type(self.marker_options_groupbox) -> widgets.VMarkerOptionsGroupBox
        self.marker_options_groupbox.add_widget(
            'Predicted', DataType.PREDICTED)
        self.marker_options_groupbox.add_widget(
            'Ground Truth', DataType.GROUND_TRUTH)

        shapes = (Shape.CIRCLE, Shape.DIAMOND)
        icons = (QIcon(r':/circle'), QIcon(r':/diamond'))
        for widget in self.marker_options_groupbox.widgets.values():
            for icon, shape in zip(icons, shapes):
                widget.add_marker_shape(shape, icon)

        scene = VGraphicsScene()
        self.graphics_view.setScene(scene)

        self.controller = Controller(scene, self.tables_tab_widget, self.marker_options_groupbox)

    def _signals_setup(self) -> None:
        self.action_open_ground_truth.triggered.connect(
            lambda: self.open(DataType.GROUND_TRUTH))
        self.action_open_predicted.triggered.connect(
            lambda: self.open(DataType.PREDICTED))
        self.action_open_image.triggered.connect(
            lambda: self.open(DataType.IMAGE))

        self.graphics_view_scrollbar.value_changed[int].connect(
            self.controller.set_index)

        self.file_loaded[object].connect(self.marker_options_groupbox.enable)
        self.file_loaded[object].connect(
            lambda d: self.menu_open_data.setEnabled(True) if d & DataType.IMAGE else None)

    def _parse_filename(self, filelist: Sequence[str], dtype: DataType) -> str:
        """
        Checks for errors in the list of filenames, i.e if list is empty, or if
        list has more than one filename. If the list passes the checks, we
        proceed to load the file. For now, we reject TIFF files because loading
        TIFF images is not implemented.
        """
        def create_error_dialog(message):
            self._error_dialog.message = message
            self._error_dialog.exec_()

        if len(filelist) > 1:
            return create_error_dialog(
                '{} files were selected '.format(len(filelist)) +
                'but we can only load one file at a time.')
        elif len(filelist) == 0:
            return create_error_dialog('No files were selected.')
        else:
            filename = filelist[0]
        # temporary to reject loaded tif images because loading them
        # hasn't been implemented yet
        print('***parsing filename***')
        filename_ext = splitext(filename)[-1]
        if filename_ext in EXTENSIONS[DataType.TIFF_IMAGE][0]:
            create_error_dialog('tiff files not yet supported.')
            return ''
        else:
            return filename

    def open(self, dtype: DataType) -> None:
        """
        Opens a QDialog in which the user selects an HDF5 or TIFF file.
        """
        # we must first create a properly-formated regexp string for the
        # 'filter' argument of the 'setNameFilter' method in our already-
        # instantiated but not shown QDialog.
        extensions = OrderedDict(zip(FILETYPES[dtype], EXTENSIONS[dtype]))
        ext = [[''] + list(ext) for ext in extensions.values()]
        extlist = [self.tr(k) + " (" + ' *'.join(e) + ")" for k, e in zip(extensions, ext)]
        filter_ = ';;'.join(extlist)
        # example filter_ string:
        # Tiff Files (*.tif, *.tiff, *.ome.tif);;HDF5 Files (*.h5, *.hdf5, *.hf5, *.hd5)
        self._file_dialog.setNameFilter(filter_)
        # closing the QDialog returns an enum, either "Accepted" or "Rejected"
        # depending on whether the "Ok" or "Cancel" button was pressed,
        # respectively
        result = self._file_dialog.exec_()
        if result == QFileDialog.Accepted:
            filename = self._parse_filename(
                self._file_dialog.selectedFiles(), dtype)
            if filename:
                self.open_inspection_widget(filename, dtype)

    def open_inspection_widget(self, filename: str, dtype: DataType):
        list_widget_columns = ['name', 'directory']
        ground_truth_titles = OrderedDict(
            [('Ground Truth Coordinates', list_widget_columns)])
        predicted_titles = OrderedDict(
            [('Predicted Coordinates', list_widget_columns),
             ('Probabilities', list_widget_columns)])
        image_titles = OrderedDict(
            [('Images', list_widget_columns)])

        list_widget_args = EnumDict([
            (DataType.GROUND_TRUTH, ground_truth_titles),
            (DataType.PREDICTED, predicted_titles),
            (DataType.HDF_IMAGE, image_titles)])

        args = list_widget_args[dtype][0]
        dialog = make_dialog(filename, args, dtype)
        result = dialog.exec_()
        if result == QFileDialog.Accepted:
            self.load(filename, dtype, dialog.get_data('directory'))

    def load(self, filename: str, dtype: DataType, handles: DataFrame):
        if dtype & DataType.HDF_IMAGE:
            req = HDF5Request1D(filename, handles, axis=0)
            self.graphics_view_scrollbar.setEnabled(True)
        elif dtype & DataType.DATA:
            req = HDF5Request2D(filename, handles)
        else:
            raise NotImplementedError('Loading {} not yet implemented.'.format(dtype))

        print(filename)
        print(dtype)
        print(handles)
        source = HDF5DataSource(filename, req)
        self.controller.set_datasource(source, dtype)
        self.graphics_view_scrollbar.setMaximum(len(source) - 1)
        self.file_loaded.emit(dtype)

    @Slot()
    def save(self):
        pass

    @Slot()
    def save_as(self):
        pass

    @Slot()
    def quit(self):
        sys.exit(0)
Example #24
0
class ExportDialog(QDialog):
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        self.ui = Ui_Dialog_Export()
        self.ui.setupUi(self)
        self._fig = None

        # setup file types
        for frmt in IMAGE_FORMATS:
            self.ui.comboBox_fileType.addItem("{0[1]} (.{0[0]})".format(frmt))

        self._file_name_changed()  # select the default format

        # setup directory and dir dialog
        self._dir_dialog = QFileDialog(self)
        # self._dir_dialog.setDirectory(os.path.expanduser("~"))
        self._dir_dialog.setFileMode(QFileDialog.DirectoryOnly)
        self._dir_dialog.setWindowTitle("Save to ...")
        self.ui.comboBox_directory.addItem(os.path.expanduser("~"))
        self.ui.pushButton_browse.clicked.connect(self._browse)

        self._dir_validator = DirectoryValidator()
        self.ui.comboBox_directory.lineEdit().setValidator(self._dir_validator)

        # file name
        self.ui.comboBox_fileName.currentIndexChanged.connect(
            self._file_name_changed)

        # file type
        self.ui.comboBox_fileType.currentIndexChanged.connect(
            self._file_type_changed)

        # cancel button
        self.ui.pushButton_cancel.clicked.connect(self._cancel_button_clicked)
        # export button
        self.ui.pushButton_export.clicked.connect(self._export_button_clicked)
        # preview button
        self.ui.pushButton_preview.clicked.connect(
            self._preview_button_clicked)

        # dpi
        self.ui.spinBox_dpi.valueChanged.connect(self._dpi_changed)
        # inches
        self.ui.doubleSpinBox_width_inches.valueChanged.connect(
            self._width_inches_changed)
        self.ui.doubleSpinBox_height_inches.valueChanged.connect(
            self._height_inches_changed)
        # pixels
        self.ui.spinBox_width_pixels.valueChanged.connect(
            self._width_pixels_changed)
        self.ui.spinBox_height_pixels.valueChanged.connect(
            self._height_pixels_changed)

        # message box for when the file already exist
        self._msg_box = QMessageBox(self)
        self._msg_box.setWindowTitle("Export...")
        self._msg_box_button_overwrite = self._msg_box.addButton(
            self.tr("Overwrite"), QMessageBox.AcceptRole)
        self._msg_box_button_save_as = self._msg_box.addButton(
            self.tr("Save As"), QMessageBox.ActionRole)
        self._msg_box_button_cancel = self._msg_box.addButton(
            QMessageBox.Cancel)
        self._msg_box.setDefaultButton(self._msg_box_button_save_as)

    _orientation = ['portrait', 'landscape']

    _no_alpha_channel_formats = ('jpg', 'jpeg')  # ("png", "gif", "psd")

    def _dpi_changed(self, dpi):
        self.ui.doubleSpinBox_height_inches.blockSignals(True)
        self.ui.doubleSpinBox_width_inches.blockSignals(True)
        self.ui.spinBox_height_pixels.setValue(
            self.ui.doubleSpinBox_height_inches.value() * dpi)
        self.ui.spinBox_width_pixels.setValue(
            self.ui.doubleSpinBox_width_inches.value() * dpi)
        self.ui.doubleSpinBox_height_inches.blockSignals(False)
        self.ui.doubleSpinBox_width_inches.blockSignals(False)

    def _width_pixels_changed(self, width):
        self.ui.doubleSpinBox_width_inches.blockSignals(True)
        new_width_inches = width / float(self.ui.spinBox_dpi.value())
        self.ui.doubleSpinBox_width_inches.setValue(new_width_inches)
        self.ui.doubleSpinBox_width_inches.blockSignals(False)

    def _height_pixels_changed(self, height):
        self.ui.doubleSpinBox_height_inches.blockSignals(True)
        new_height_inches = height / float(self.ui.spinBox_dpi.value())
        self.ui.doubleSpinBox_height_inches.setValue(new_height_inches)
        self.ui.doubleSpinBox_height_inches.blockSignals(False)

    def _width_inches_changed(self, width):
        self.ui.spinBox_width_pixels.blockSignals(True)
        self.ui.spinBox_width_pixels.setValue(width *
                                              self.ui.spinBox_dpi.value())
        self.ui.spinBox_width_pixels.blockSignals(False)

    def _height_inches_changed(self, height):
        self.ui.spinBox_height_pixels.blockSignals(True)
        self.ui.spinBox_height_pixels.setValue(height *
                                               self.ui.spinBox_dpi.value())
        self.ui.spinBox_height_pixels.blockSignals(False)

    def _cancel_button_clicked(self, b):
        self.reject()

    def _export_button_clicked(self, b):
        self.accept()

    def _preview_button_clicked(self):
        if self._fig:
            # set figures
            self._fig.set_size_inches(self.get_size_inches_width(),
                                      self.get_size_inches_height())
            params = self.get_savefig_params()
            self._fig.set_dpi(params['dpi'])
            self._fig.set_tight_layout(True if params['bbox_inches'] ==
                                       'tight' else False)

            canvas = FigureCanvas(self._fig)
            canvas.show()

            # dialog
            preview_dialog = PreviewDialog(self, self._fig)
            preview_dialog.exec_()

    def _file_type_changed(self, *args, **kwargs):
        index = self.ui.comboBox_fileType.currentIndex()
        ext, _ = IMAGE_FORMATS[index]
        filename = str(self.ui.comboBox_fileName.currentText())
        filename, _ = os.path.splitext(filename)

        if ext in self._no_alpha_channel_formats:  # enable transparent if the format supports
            self.ui.checkBox_transparent.setEnabled(False)
        else:
            self.ui.checkBox_transparent.setEnabled(True)

        # update file name
        filename = "%s.%s" % (filename, ext)
        index = self.ui.comboBox_fileName.findText(filename)
        if index == -1:
            self.ui.comboBox_fileName.addItem(filename)
        self.ui.comboBox_fileName.setCurrentIndex(
            index if index >= 0 else self.ui.comboBox_fileName.
            findText(filename))

    def _file_name_changed(self, *args, **kwargs):
        filename = str(self.ui.comboBox_fileName.currentText())
        filename, extension = os.path.splitext(filename)
        extension = extension[1:]  # get ride of .
        # check if the extension is supported
        index = [
            i for i, (ext, dsc) in enumerate(IMAGE_FORMATS) if ext == extension
        ]
        if index:
            self.ui.comboBox_fileType.setCurrentIndex(index[0])
        elif extension:
            # no extension
            pass
        else:
            # extension not supported:
            pass

    def _browse(self, *args, **kwargs):
        if self._dir_dialog.exec_() == QDialog.Accepted:
            dirs = self._dir_dialog.selectedFiles(
            )  # behave differently in pyqt4 and pyqt5
            directory = str(dirs[0] if dirs else self._dir_dialog.directory().
                            absolutePath())  # this makes the behave the same
            # update directory
            index = self.ui.comboBox_directory.findText(directory)
            if index == -1:
                self.ui.comboBox_directory.addItem(directory)
            self.ui.comboBox_directory.setCurrentIndex(
                index if index >= 0 else self.ui.comboBox_directory.
                findText(directory))

    def export_to_file(self, fig):
        self._fig = fig
        respawn = True
        while respawn:
            respawn = False
            self.ui.spinBox_dpi.setValue(fig.get_dpi())
            self.ui.doubleSpinBox_width_inches.setValue(fig.get_figwidth())
            self.ui.doubleSpinBox_height_inches.setValue(fig.get_figheight())
            response = self.exec_()
            if response == QDialog.Accepted:
                # saving files
                fname = self.get_save_file_name()

                if os.path.exists(fname):
                    new_name = generate_unique_file_name(fname)
                    self._show_file_exist_message(fname, new_name)
                    if self._msg_box.clickedButton(
                    ) == self._msg_box_button_cancel:
                        respawn = True
                        continue
                    elif self._msg_box.clickedButton(
                    ) == self._msg_box_button_save_as:
                        fname = new_name  # save_as
                    else:
                        pass  # use the original name to overwrite

                params = self.get_savefig_params()
                # change size
                fig.set_size_inches(self.get_size_inches_width(),
                                    self.get_size_inches_height())
                try:
                    fig.savefig(fname, **params)
                except IOError as err:
                    if 'RGBA' in err.message:
                        # if the problem is RGBA as the alpha channel is not supported in the selected format
                        # save to png then save as
                        basename = os.path.basename(fname)
                        tmp_dir = tempfile.gettempdir()
                        filename, ext = os.path.splitext(basename)
                        png_file = filename + ".png"
                        final_format = params['format']
                        params['format'] = 'png'
                        new_fname = os.path.join(tmp_dir, png_file)
                        fig.savefig(new_fname, **params)
                        with Image.open(new_fname) as im:
                            rgb_im = im.convert('RGB')
                            # make sure the fname is ended with the right extension
                            fname, _ = os.path.splitext(fname)
                            fname += "." + final_format
                            rgb_im.save(fname)
                    else:
                        raise err

                if self.ui.checkBox_open_after_export.isChecked():
                    # open with the system default application, this should work on all platforms
                    webbrowser.open(fname)
                return fname
                # elif response == QtGu

    def get_size_inches_width(self):
        return self.ui.doubleSpinBox_width_inches.value()

    def get_size_inches_height(self):
        return self.ui.doubleSpinBox_height_inches.value()

    def _show_file_exist_message(self, fname, new_name):
        self._msg_box.setText(
            "<p>File \"{0}\" already exists. Do you want to overwrite the existing, or save to \"{1}\" instead?<\p>"
            .format(fname, new_name))
        self._msg_box.exec_()

    def get_save_file_name(self):
        name = os.path.join(str(self.ui.comboBox_directory.currentText()),
                            str(self.ui.comboBox_fileName.currentText()))
        return os.path.normpath(name)

    def get_savefig_params(self):
        params = {
            'dpi': self.ui.spinBox_dpi.value(),
            'orientation': self.get_orientation(),
            'format': self.get_file_format()[0],
            'transparent': self.get_transparent(),
            'bbox_inches': self.get_bbox_inches()
        }
        return params

    def get_transparent(self):
        return self.ui.checkBox_transparent.isEnabled(
        ) and self.ui.checkBox_transparent.isChecked()

    def get_file_format(self):
        return IMAGE_FORMATS[self.ui.comboBox_fileType.currentIndex()]

    def get_bbox_inches(self):
        return 'tight' if self.ui.checkBox_tightBbox.isChecked() else None

    def get_orientation(self):
        return self._orientation[self.ui.comboBox_orientation.currentIndex()]

    def keyPressEvent(self, event):
        """Capture and ignore all key press events.

        This is used so that return key event does not trigger any button
        from the dialog. We need to allow the return key to be used in filters
        in the widget."""
        if event.key() == QtCore.Qt.Key_Escape:
            # call reject if Escape is pressed.
            self.reject()
        pass
Example #25
0
class ExportDialogModEm(QWizard):
    def __init__(self, parent=None):
        QWizard.__init__(self, parent)
        self.ui = Ui_Wizard_esport_modem()
        self.ui.setupUi(self)

        self._logger = MtPyLog.get_mtpy_logger(self.__class__.__name__)
        # setup gui
        # self.setWindowTitle("ModEM input file generator")

        # add math label
        self._math_label_sign_impedances = MathTextLabel(
            self,
            self._math_label_sign_text.format(
                "+" if self.ui.radioButton_impedance_sign_plus.isChecked() else "-"
            )
        )
        self.ui.horizontalLayout_sign_impedance.addWidget(self._math_label_sign_impedances)
        self._math_label_sign_vertical = MathTextLabel(
            self,
            self._math_label_sign_text.format(
                "+" if self.ui.radioButton_vertical_sign_plus.isChecked() else "-"
            )
        )
        self.ui.horizontalLayout_sign_vertical.addWidget(self._math_label_sign_vertical)

        # add math formulae of each error type
        self._math_label_elbert = MathTextLabel(
            self,
            "$E_{egbert}=e_Z\\times |Z_{xy}\\times Z_{yx}|^\\frac{1}{2}$",
        )
        self.ui.verticalLayout_error_types.addWidget(self._math_label_elbert)

        self._math_label_mean = MathTextLabel(self, "$E_{mean} = e_Z\\times mean(|Z_{xy}, Z_{yx}|)$")
        self._math_label_mean.setHidden(True)
        self.ui.verticalLayout_error_types.addWidget(self._math_label_mean)

        self._math_label_eigen = MathTextLabel(self, "$E_{eigen} = e_Z\\times eigenvalues(Z)$")
        self._math_label_eigen.setHidden(True)
        self.ui.verticalLayout_error_types.addWidget(self._math_label_eigen)

        self._math_label_median = MathTextLabel(self, "$E_{median} = e_Z\\times median(|Z_{xx},Z_{xy},Z_{yx},Z_{yy}|)$")
        self._math_label_median.setHidden(True)
        self.ui.verticalLayout_error_types.addWidget(self._math_label_median)

        self._math_label_error_type_note = MathTextLabel(self, "where $E$ is the error and $e$ is the error value (z).")
        self.ui.verticalLayout_error_types.addWidget(self._math_label_error_type_note)

        # add period selection
        self._period_select_ui = FrequencySelection(
            self.ui.wizardPage_period,
            show_period=True,
            show_frequency=False,
            allow_range_select=True,
            select_multiple=True
        )
        self._period_select_ui.ui.checkBox_show_existing.setChecked(True)
        self._period_select_ui.setEnabled(False)
        self._period_select_ui.setHidden(True)
        self.ui.wizardPage_period.layout().addWidget(self._period_select_ui)

        self._period_select_from_file_ui = FrequencySelectionFromFile(self.ui.wizardPage_period)
        self._period_select_from_file_ui.setEnabled(False)
        self._period_select_from_file_ui.setHidden(True)
        self.ui.wizardPage_period.layout().addWidget(self._period_select_from_file_ui)

        # add rotation
        self._rotation_ui = Rotation(self.ui.wizardPage_data)
        self._rotation_ui.setTitle('Data Rotation Angle')
        self.ui.horizontalLayout_data.addWidget(self._rotation_ui)

        self._mesh_rotation_ui = Rotation(self.ui.wizardPage_mesh)
        self._mesh_rotation_ui.setTitle('Mesh Rotation Angle')
        self.ui.gridLayout_mesh.addWidget(self._mesh_rotation_ui)

        # hide error percents
        self._component_error_type_z_changed()

        # hide bottom in vertical mesh as it is not used in mesh gen
        self.ui.doubleSpinBox_bottom.hide()
        self.ui.label_bottom.hide()

        # epsg
        self.ui.comboBox_epsg.addItems(
            [str(epsg) for epsg in sorted(epsg_dict.keys())]
        )

        # set validators
        self._double_validator = QDoubleValidator(-np.inf, np.inf, 1000)
        self._double_validator.setNotation(QDoubleValidator.ScientificNotation)
        self.ui.lineEdit_resistivity_init.setValidator(self._double_validator)
        self.ui.lineEdit_resistivity_air.setValidator(self._double_validator)
        self.ui.lineEdit_resistivity_sea.setValidator(self._double_validator)

        self._file_validator = FileValidator()
        self.ui.comboBox_topography_file.lineEdit().setValidator(self._file_validator)
        self.ui.comboBox_topography_file.lineEdit().setMaxLength(256)

        self._dir_validator = DirectoryValidator()
        self.ui.comboBox_directory.lineEdit().setValidator(self._dir_validator)

        # setup directory and dir dialog
        self._dir_dialog = QFileDialog(self)
        # self._dir_dialog.setDirectory(os.path.expanduser("~"))
        self.ui.comboBox_directory.addItem(os.path.expanduser("~"))
        self._update_full_output()

        # set maximum
        # self.ui.spinBox_cell_num_ew.setMaximum(0xFFFFFFFF)
        # self.ui.spinBox_cell_num_ns.setMaximum(0xFFFFFFFF)

        # tooltip for error types
        for index, tooltip in enumerate(self._error_type_z_tool_tip):
            self.ui.comboBox_error_type_z.setItemData(index, tooltip, QtCore.Qt.ToolTipRole)
            self.ui.comboBox_error_type_zxx.setItemData(index, tooltip, QtCore.Qt.ToolTipRole)
            self.ui.comboBox_error_type_zxy.setItemData(index, tooltip, QtCore.Qt.ToolTipRole)
            self.ui.comboBox_error_type_zyx.setItemData(index, tooltip, QtCore.Qt.ToolTipRole)
            self.ui.comboBox_error_type_zyy.setItemData(index, tooltip, QtCore.Qt.ToolTipRole)

        # hide parts
        self.ui.groupBox_component_error_types.setHidden(True)
        self.ui.label_component_error_types.setHidden(True)

        # connect signals
        self.ui.radioButton_impedance_sign_plus.toggled.connect(
            lambda is_checked: self._math_label_sign_impedances.set_math_text(
                self._math_label_sign_text.format("+" if is_checked else "-"))
        )
        self.ui.radioButton_vertical_sign_plus.toggled.connect(
            lambda is_checked: self._math_label_sign_vertical.set_math_text(
                self._math_label_sign_text.format("+" if is_checked else "-")
            )
        )

        self.ui.radioButton_impedance_full.toggled.connect(self._impedance_full_toggled)
        self.ui.radioButton_impedance_off_diagonal.toggled.connect(self._impedance_off_diagonal_toggled)
        self.ui.radioButton_impedance_none.toggled.connect(self._impedance_none_toggled)
        self.ui.radioButton_vertical_full.toggled.connect(self._vertical_full_toggled)

        self.ui.comboBox_error_type_z.currentIndexChanged.connect(self._error_type_z_changed)
        for component in self._impedance_components:
            combobox = getattr(self.ui, 'comboBox_error_type_{}'.format(component))
            checkbox = getattr(self.ui, 'checkBox_{}'.format(component))
            combobox.currentIndexChanged.connect(self._component_error_type_z_changed)
            checkbox.toggled.connect(self._error_component_checkbox_toggled(combobox))

        self.ui.comboBox_output_name.currentIndexChanged.connect(self._update_full_output)
        self.ui.comboBox_output_name.lineEdit().editingFinished.connect(self._output_name_changed)
        self.ui.comboBox_output_name.editTextChanged.connect(self._update_full_output)
        self.ui.comboBox_directory.currentIndexChanged.connect(self._update_full_output)
        self.ui.comboBox_directory.lineEdit().editingFinished.connect(self._output_dir_changed)
        self.ui.comboBox_directory.editTextChanged.connect(self._update_full_output)
        self.ui.pushButton_browse.clicked.connect(self._browse)

        # self.ui.doubleSpinBox_target_depth.valueChanged.connect(self._target_depth_changed)
        self.ui.doubleSpinBox_target_depth.lineEdit().editingFinished.connect(self._target_depth_changed)
        self.ui.doubleSpinBox_bottom.lineEdit().editingFinished.connect(self._bottom_changed)
        # self.ui.doubleSpinBox_bottom.valueChanged.connect(self._bottom_changed)

        # self.ui.comboBox_topography_file.currentIndexChanged.connect()
        self.ui.comboBox_topography_file.lineEdit().editingFinished.connect(
            self._topography_file_changed
        )
        self.ui.pushButton_browse_topography_file.clicked.connect(self._browse_topography_file)

        self.ui.pushButton_test.clicked.connect(self._test_button_clicked)

        self.ui.checkBox_cell_num_ew.stateChanged.connect(
            lambda p_int: self.ui.spinBox_cell_num_ew.setEnabled(p_int != 0)
        )
        self.ui.checkBox_cell_num_ns.stateChanged.connect(
            lambda p_int: self.ui.spinBox_cell_num_ns.setEnabled(p_int != 0)
        )

        self.ui.checkBox_component_error_types.setEnabled(False)  # disabled due to missing implementations todo implement this option in modem.Data
        self.ui.checkBox_component_error_types.toggled.connect(self._component_error_type_toggled)
        self.ui.radioButton_select_period_percent.toggled.connect(
            lambda checked: self.ui.doubleSpinBox_select_period_percent.setEnabled(checked))
        self.ui.radioButton_select_period.toggled.connect(
            lambda checked: self._period_select_ui.setEnabled(checked))
        self.ui.radioButton_select_period.toggled.connect(
            lambda checked: self._period_select_ui.setHidden(not checked))
        self.ui.radioButton_select_by_file.toggled.connect(
            lambda checked: self._period_select_from_file_ui.setEnabled(checked))
        self.ui.radioButton_select_by_file.toggled.connect(
            lambda checked: self._period_select_from_file_ui.setHidden(not checked))

        # register fields
        self.ui.wizardPage_output.registerField('output_path*', self.ui.lineEdit_full_output)
        self.ui.wizardPage_topography.registerField('topography_file*', self.ui.comboBox_topography_file)
        self.ui.wizardPage_topography.registerField('sea_resistivity',
                                                    self.ui.lineEdit_resistivity_sea)
        self.ui.wizardPage_topography.registerField('air_resistivity',
                                                    self.ui.lineEdit_resistivity_air)

        # attribute
        self._mt_objs = None

        self._progress_bar = ProgressBar()

    _impedance_components = ['zxx', 'zxy', 'zyx', 'zyy']
    _vertical_components = ['tx', 'ty']
    _math_label_sign_text = "$exp({}i\\omega t)$"

    _error_type_z = [
        'egbert',  # 0
        'mean_od',  # 1
        'eigen',  # 2
        'median',  # 3
    ]

    _error_type_z_tool_tip = [
        'sets error to the value of Error Egbert * sqrt(abs(zxy*zyx), see Egbert & Kelbert',
        'sets error to error_value_z * mean([Zxy, Zyx]) (non zeros)',
        'sets error to error_value_z * eigenvalues(Z[ii])',
        'sets error to error_value_z * median([Zxx, Zxy, Zyx, Zyy]) (non zeros)'
    ]

    _error_type_tipper = [
        'abs',
        'floor'
    ]

    def _component_error_type_toggled(self, is_checked):
        self.ui.label_component_error_types.setHidden(not is_checked)
        self.ui.groupBox_component_error_types.setHidden(not is_checked)

    def _target_depth_changed(self, *args):
        value = self.ui.doubleSpinBox_target_depth.value()
        # target depth has too be at least as deep as the bottom
        if self.ui.doubleSpinBox_bottom.value() < value:
            self.ui.doubleSpinBox_bottom.setValue(value)

    def _bottom_changed(self, *args):
        value = self.ui.doubleSpinBox_bottom.value()
        # bottom as to be at least at least as deep as the target depth
        if self.ui.doubleSpinBox_target_depth.value() > value:
            self.ui.doubleSpinBox_target_depth.setValue(value)

    def _impedance_full_toggled(self, checked):
        if checked:
            for comp in self._impedance_components:
                checkbox = getattr(self.ui, 'checkBox_{}'.format(comp))
                checkbox.setEnabled(True)
            self.ui.radioButton_vertical_none.setEnabled(True)
            self.ui.groupBox_sign_impedance.setEnabled(True)

    def _impedance_off_diagonal_toggled(self, checked):
        if checked:
            for comp in self._impedance_components:
                checkbox = getattr(self.ui, 'checkBox_{}'.format(comp))
                checkbox.setEnabled(comp == 'zxy' or comp == 'zyx')
            self.ui.radioButton_vertical_none.setEnabled(True)
            self.ui.groupBox_sign_impedance.setEnabled(True)

    def _impedance_none_toggled(self, checked):
        if checked:
            for comp in self._impedance_components:
                checkbox = getattr(self.ui, 'checkBox_{}'.format(comp))
                checkbox.setEnabled(False)
            self.ui.radioButton_vertical_none.setEnabled(False)
            self.ui.groupBox_sign_impedance.setEnabled(False)

    def _vertical_full_toggled(self, checked):
        self.ui.doubleSpinBox_error_value_tipper.setEnabled(checked)
        self.ui.radioButton_impedance_none.setEnabled(checked)
        self.ui.groupBox_sign_vertical.setEnabled(checked)

    def _error_component_checkbox_toggled(self, combobox):
        def _checkbox_toggled(checked):
            combobox.setEnabled(checked)
            self._component_error_type_z_changed()

        return _checkbox_toggled

    def _component_error_type_z_changed(self, error_type_index=-1):
        # types = {self.ui.comboBox_error_type_z.currentIndex()}
        # for component in self._impedance_components:
        #     combobox = getattr(self.ui, 'comboBox_error_type_{}'.format(component))
        #     if combobox.isEnabled():
        #         types.add(combobox.currentIndex())
        #
        # hidden = bool(0 not in types)
        # self.ui.label_error_floor.setHidden(hidden)
        # self.ui.doubleSpinBox_error_floor.setHidden(hidden)
        # hidden = bool(2 not in types and 3 not in types)
        # self.ui.label_error_egbert.setHidden(hidden)
        # self.ui.doubleSpinBox_error_egbert.setHidden(hidden)
        # self._math_label_elbert.setHidden(hidden)
        # hidden = bool(1 not in types)
        # self.ui.label_error_value.setHidden(hidden)
        # self.ui.doubleSpinBox_error_value.setHidden(hidden)
        pass  # todo re-enable after the sub-type for each component is implemented

    def _error_type_z_changed(self, error_type_index):
        # sync the component error types with default
        # for component in self._impedance_components:
        #     combobox = getattr(self.ui, 'comboBox_error_type_{}'.format(component))
        #     if not combobox.isEnabled():
        #         combobox.blockSignals(True)
        #         combobox.setCurrentIndex(error_type_index)
        #         combobox.blockSignals(False)
        # self._component_error_type_z_changed()
        pass  # todo re-enable after the sub-type for each component is implemented

        self._math_label_elbert.setHidden(error_type_index != 0)
        self._math_label_mean.setHidden(error_type_index != 1)
        self._math_label_eigen.setHidden(error_type_index != 2)
        self._math_label_median.setHidden(error_type_index != 3)

    def _output_name_changed(self, *args, **kwargs):
        output_name = str(self.ui.comboBox_output_name.currentText())
        index = self.ui.comboBox_output_name.findText(output_name)
        if index == -1:
            self.ui.comboBox_output_name.addItem(output_name)
        self.ui.comboBox_output_name.setCurrentIndex(
            index if index >= 0 else self.ui.comboBox_output_name.findText(output_name)
        )

    def _output_dir_changed(self, *args, **kwargs):
        directory = str(self.ui.comboBox_directory.currentText())
        directory = os.path.normpath(directory)
        # update directory
        index = self.ui.comboBox_directory.findText(directory)
        if index == -1:
            self.ui.comboBox_directory.addItem(directory)
        self.ui.comboBox_directory.setCurrentIndex(index
                                                   if index >= 0
                                                   else self.ui.comboBox_directory.findText(directory))

    def _update_full_output(self, *args, **kwargs):
        directory = str(self.ui.comboBox_directory.currentText())
        output_name = str(self.ui.comboBox_output_name.currentText())
        full_output = os.path.normpath(os.path.join(directory, output_name))
        self.ui.lineEdit_full_output.setText(full_output)

    def _browse(self, *args, **kwargs):
        self._dir_dialog.setFileMode(QFileDialog.DirectoryOnly)
        self._dir_dialog.setWindowTitle("Save to ...")
        if self._dir_dialog.exec_() == QDialog.Accepted:
            directory = str(self._dir_dialog.selectedFiles()[0])
            self.ui.comboBox_directory.setEditText(directory)
            self._output_dir_changed()

    def _topography_file_changed(self, *args, **kwargs):
        topo_file = str(self.ui.comboBox_topography_file.currentText())
        topo_file = os.path.normpath(topo_file)
        # update
        index = self.ui.comboBox_topography_file.findText(topo_file)
        if index == -1:
            self.ui.comboBox_topography_file.addItem(topo_file)
        self.ui.comboBox_topography_file.setCurrentIndex(
            index if index >= 0 else self.ui.comboBox_topography_file.findText(topo_file)
        )

    def _browse_topography_file(self, *args, **kwargs):
        self._dir_dialog.setFileMode(QFileDialog.AnyFile)
        self._dir_dialog.setWindowTitle("Find Topography File...")
        if self._dir_dialog.exec_() == QDialog.Accepted:
            file_path = str(self._dir_dialog.selectedFiles()[0])
            self.ui.comboBox_topography_file.setEditText(file_path)
            self._topography_file_changed()

    def _test_button_clicked(self, *args, **kwargs):
        self.export_data(True)

    def set_data(self, mt_objs):
        self._mt_objs = mt_objs
        self._period_select_ui.set_data(self._mt_objs)
        self._period_select_from_file_ui.set_data(self._mt_objs)
        self.ui.listWidget_edi_files.clear()
        for mt_obj in mt_objs:
            self.ui.listWidget_edi_files.addItem("{mt.station} ({mt.fn})".format(mt=mt_obj))

    def get_inversion_mode(self):
        if self.ui.radioButton_impedance_full.isChecked():
            return '1' if self.ui.radioButton_vertical_full.isChecked() else '2'
        elif self.ui.radioButton_impedance_off_diagonal.isChecked():
            return '3' if self.ui.radioButton_vertical_full.isChecked() else '4'
        else:
            return '5'

    def _get_error_type_z(self):
        type = self._error_type_z[self.ui.comboBox_error_type_z.currentIndex()]
        if self.ui.checkBox_error_type_z_floor.isChecked():
            type += "_floor"
        return type

    def get_data_kwargs(self):
        kwargs = {
            'error_type_z': self._get_error_type_z(),
            'error_value_z': self.ui.doubleSpinBox_error_value_z.value(),
            'error_type_tipper': self._error_type_tipper[self.ui.comboBox_error_type_tipper.currentIndex()],
            'error_value_tipper': self.ui.doubleSpinBox_error_value_tipper.value() / 100.,
            'save_path': self.get_save_file_path(),
            'format': '1' if self.ui.radioButton_format_1.isChecked() else '2',
            'rotation_angle': self._rotation_ui.get_rotation_in_degree(),
            'model_epsg': self.get_epsg(),
            'inv_mode': self.get_inversion_mode()
        }

        # comp_error_type
        if any(
                [getattr(self.ui, 'comboBox_error_type_{}'.format(component)).isEnabled()
                 for component in self._impedance_components]
        ):
            kwargs['comp_error_type'] = dict(
                [
                    (
                        component,
                        self._error_type_z[
                            getattr(self.ui, 'comboBox_error_type_{}'.format(component)).currentIndex()
                        ]
                    )
                    for component in self._impedance_components
                    if getattr(self.ui, 'comboBox_error_type_{}'.format(component)).isEnabled()
                ]
            )

        # wave signs
        if self.ui.groupBox_sign_impedance.isEnabled():
            kwargs['wave_sign_impedance'] = '+' if self.ui.radioButton_impedance_sign_plus.isChecked() \
                else '-'
        if self.ui.groupBox_sign_vertical.isEnabled():
            kwargs['wave_sign_tipper'] = '+' if self.ui.radioButton_vertical_sign_plus.isChecked() \
                else '-'

        # units
        kwargs['units'] = '[mV/km]/[nT]' if self.ui.radioButton_unit_mvkmnt.isChecked() \
            else '[V/m]/[T]' if self.ui.radioButton_unit_vmt.isChecked() \
            else 'Ohm'

        return kwargs

    def get_model_kwargs(self):
        kwargs = {
            'save_path': self.get_save_file_path(),
            'cell_size_east': self.ui.doubleSpinBox_cell_size_east.value(),
            'cell_size_north': self.ui.doubleSpinBox_cell_szie_north.value(),
            'pad_east': self.ui.spinBox_pad_east.value(),
            'pad_north': self.ui.spinBox_pad_north.value(),
            'pad_z': self.ui.spinBox_pad_z.value(),
            'pad_stretch_h': self.ui.doubleSpinBox_pad_stretch_h.value(),
            'pad_stretch_v': self.ui.doubleSpinBox_pad_stretch_v.value(),
            'z1_layer': self.ui.doubleSpinBox_z1_thickness.value(),
            'z_target_depth': self.ui.doubleSpinBox_target_depth.value(),
            'z_bottom': self.ui.doubleSpinBox_bottom.value(),
            'n_layers': self.ui.spinBox_num_layers.value(),
            'n_air_layers': self.ui.spinBox_num_air_layers.value(),
            'res_model': self.get_initial_resistivity(),
            'mesh_rotation_angle': self._mesh_rotation_ui.get_rotation_in_degree(),
            'cell_number_ew': self.ui.spinBox_cell_num_ew.value()
            if self.ui.checkBox_cell_num_ew.isChecked() else None,
            'cell_number_ns': self.ui.spinBox_cell_num_ns.value()
            if self.ui.checkBox_cell_num_ns.isChecked() else None
        }
        return kwargs

    def get_save_file_path(self):
        return str(self.ui.lineEdit_full_output.text())

    def get_initial_resistivity(self):
        return float(str(self.ui.lineEdit_resistivity_init.text()))

    def get_air_resistivity(self):
        return float(str(self.ui.lineEdit_resistivity_air.text()))

    def get_sea_resistivity(self):
        return float(str(self.ui.lineEdit_resistivity_sea.text()))

    def get_topography_2_mesh_args(self):
        kwargs = {
            'topography_file': str(self.ui.comboBox_topography_file.currentText()),
            'topography_array': None,
            'interp_method': 'nearest' if self.ui.radioButton_interpo_method_nearest.isChecked()
            else 'linear' if self.ui.radioButton_interpo_method_linear.isChecked()
            else 'cubic',
            'air_resistivity': self.get_air_resistivity(),
            'sea_resistivity': self.get_sea_resistivity()
        }

        return kwargs

    def get_covariance_kwargs(self):
        kwargs = {
            'smoothing_east': self.ui.doubleSpinBox_smoothing_east.value(),
            'smoothing_north': self.ui.doubleSpinBox_smoothing_north.value(),
            'smoothing_z': self.ui.doubleSpinBox_smoothing_z.value(),
            'smoothing_num': self.ui.spinBox_smoothing_number.value(),
            'save_path': self.get_save_file_path()
        }
        return kwargs

    def get_select_period_kwargs(self):
        period_list = None
        if self.ui.radioButton_select_period.isChecked():
            period_list = self._period_select_ui.get_frequencies()
        elif self.ui.radioButton_select_by_file.isChecked():
            period_list = self._period_select_from_file_ui.get_selected_periods()
        elif self.ui.radioButton_select_by_decade.isChecked():
            period_list = []
            unique_periods = set()
            for mt in self._mt_objs:
                unique_periods.update(1. /mt.Z.freq)
            unique_periods = np.array(sorted(list(unique_periods), reverse=True))
            num = self.ui.spinBox_num_per_decade.value()
            decade_min = 10. ** int(np.log(unique_periods[0]))
            decade_max = decade_min * 10.
            while unique_periods[-1] < decade_min:  # todo this block of code can be more efficient
                indexes = np.where((unique_periods <= decade_max) & (unique_periods > decade_min))[0]
                if len(indexes) < num:
                    self._logger.warn("Selecting {} periods per decade, but there is only {} in [{},{}]".format(num, len(indexes), decade_min, decade_max))
                else:
                    # sample n
                    np.random.shuffle(indexes)
                    indexes = indexes[0:num]
                period_list += list(unique_periods[indexes])
                decade_max = decade_min
                decade_min /= 10.

        kwargs = {
            'period_list': period_list,
            'percentage': self.ui.doubleSpinBox_select_period_percent.value()
        }
        return kwargs

    def get_epsg(self):
        return int(str(self.ui.comboBox_epsg.currentText()))

    def export_data(self, test=False):
        if self._mt_objs is None:
            return
        # self._progress_bar.progressbar.setRange(0, 1)
        self._progress_bar.progressbar.setRange(0, 0)
        self._progress_bar.onStart()

        self._update_full_output()

        worker = ModEMWorker(
            self,
            show=test,
            edi_list=[mt_obj.fn for mt_obj in self._mt_objs],
            select_period_kwargs=self.get_select_period_kwargs(),
            data_kwargs=self.get_data_kwargs(),
            mesh_kwargs=self.get_model_kwargs(),
            topo_args=self.get_topography_2_mesh_args(),
            covariance_kwargs=self.get_covariance_kwargs()
        )

        if test:
            worker.figure_updated.connect(self._show_figure)
        self._progress_bar.setWindowTitle(
            'Testing ModEM Data...' if test else 'Generating ModEM Data...'
        )
        # worker.started.connect(self._progress_bar.onStart)
        # worker.finished.connect(self._progress_bar.onFinished)
        worker.status_updated.connect(self._update_progress_bar_text)
        worker.export_error.connect(self._export_error)
        # self._plot_opened.connect(worker.pause)

        # worker.start()
        # worker.wait()
        worker.run()

        # clean up
        worker.deleteLater()
        if self.ui.checkBox_open_output_dir.isChecked():
            webbrowser.open(self.get_save_file_path())

        self._progress_bar.onFinished()
        self._progress_bar.progressbar.setRange(0, 1)

    # _plot_opened = pyqtSignal(bool)

    def _update_progress_bar_text(self, text):
        self._progress_bar.incrementValue()
        self._progress_bar.updateIndicatorText(text)

    def _show_figure(self, string, fig):
        # self._plot_opened.emit(True)
        # print "plot_opened"
        preview_dialog = PreviewDialog(None, fig)
        preview_dialog.setWindowTitle(string)
        preview_dialog.exec_()
        preview_dialog.deleteLater()
        # self._plot_opened.emit(False)

    def _export_error(self, message):
        QMessageBox.critical(self,
                             'Export Error', message,
                             QMessageBox.Close)
Example #26
0
 def openDirDialog(self):
     dialog = QFileDialog(self)
     dialog.setFileMode(QFileDialog.DirectoryOnly)
     if dialog.exec_():
         directory = dialog.selectedFiles()[0]
         self.openDir(directory)