def _save_window_state(self):
     """
     Save the state of this mainwindow’s toolbars and dockwidgets to
     the config.
     """
     hexstate = qbytearray_to_hexstate(self.saveState())
     CONF.set('main', 'window/state', hexstate)
def dwnld_manager(qtbot, mocker, workdir):
    """A fixture for the WeatherDataGapfiller."""
    # We need to reset the configs to defaults after each test to make sure
    # they can be run independently one from another.
    CONF.reset_to_defaults()

    dwnld_manager = WeatherStationDownloader()
    qtbot.addWidget(dwnld_manager)
    assert dwnld_manager._database_isloading is True
    qtbot.waitUntil(lambda: dwnld_manager._database_isloading is False,
                    timeout=5000)
    assert osp.exists(DATABASE_FILEPATH)

    # Check that the number of stations displayed in the table is as expected.
    nstations = len(dwnld_manager.stn_finder_worker._data)
    assert len(dwnld_manager.station_table.get_stationlist()) == nstations
    assert len(dwnld_manager.stn_finder_worker.get_stationlist()) == nstations

    # Check default falues for the proximity filter.
    assert dwnld_manager.prox_grpbox.isChecked() is False
    assert dwnld_manager.lat_spinBox.value() == 0
    assert dwnld_manager.lon_spinBox.value() == 0
    assert dwnld_manager.radius_SpinBox.currentText() == '25 km'

    # Check default falues for the data availability filter.
    assert dwnld_manager.year_widg.isChecked() is False
    assert dwnld_manager.nbrYear.value() == 3
    assert dwnld_manager.minYear.value() == 1840
    assert dwnld_manager.maxYear.value() == datetime.now().year

    return dwnld_manager
Beispiel #3
0
def set_select_file_dialog_dir(directory):
    """"
    Save in the user configs the directory that should be displayed
    by default in file dialogs.
    """
    if directory is None or not osp.exists(directory):
        directory = get_home_dir()
    CONF.set('main', 'select_file_dialog_dir', directory)
 def set_workdir(self, workdir):
     if osp.exists(workdir):
         self._workdir = workdir
         CONF.set('main', 'working_dir', workdir)
         self.workdir_ledit.setText(workdir)
         if self.data_downloader is not None:
             self.data_downloader.workdir = workdir
         self.gapfiller.set_workdir(workdir)
     else:
         self.set_workdir(get_home_dir())
Beispiel #5
0
    def _create_station_selection_criteria(self):
        Nmax_label = QLabel('Nbr. of stations :')
        self.Nmax = QSpinBox()
        self.Nmax.setRange(0, 99)
        self.Nmax.setMinimum(1)
        self.Nmax.setValue(CONF.get('gapfill_data', 'nbr_of_station', 4))
        self.Nmax.setAlignment(Qt.AlignCenter)

        ttip = ('<p>Distance limit beyond which neighboring stations'
                ' are excluded from the gapfilling procedure.</p>'
                '<p>This condition is ignored if set to -1.</p>')
        distlimit_label = QLabel('Max. Distance :')
        distlimit_label.setToolTip(ttip)
        self.distlimit = QSpinBox()
        self.distlimit.setRange(-1, 9999)
        self.distlimit.setSingleStep(1)
        self.distlimit.setValue(
            CONF.get('gapfill_data', 'max_horiz_dist', 100))
        self.distlimit.setToolTip(ttip)
        self.distlimit.setSuffix(' km')
        self.distlimit.setAlignment(Qt.AlignCenter)
        self.distlimit.valueChanged.connect(self._update_corrcoeff_table)

        ttip = ('<p>Altitude difference limit over which neighboring '
                ' stations are excluded from the gapfilling procedure.</p>'
                '<p>This condition is ignored if set to -1.</p>')
        altlimit_label = QLabel('Max. Elevation Diff. :')
        altlimit_label.setToolTip(ttip)
        self.altlimit = QSpinBox()
        self.altlimit.setRange(-1, 9999)
        self.altlimit.setSingleStep(1)
        self.altlimit.setValue(
            CONF.get('gapfill_data', 'max_vert_dist', 350))
        self.altlimit.setToolTip(ttip)
        self.altlimit.setSuffix(' m')
        self.altlimit.setAlignment(Qt.AlignCenter)
        self.altlimit.valueChanged.connect(self._update_corrcoeff_table)

        # Setup the main widget.
        widget = QGroupBox('Stations Selection Criteria')
        layout = QGridLayout(widget)

        layout.addWidget(Nmax_label, 0, 0)
        layout.addWidget(self.Nmax, 0, 1)
        layout.addWidget(distlimit_label, 1, 0)
        layout.addWidget(self.distlimit, 1, 1)
        layout.addWidget(altlimit_label, 2, 0)
        layout.addWidget(self.altlimit, 2, 1)
        layout.setColumnStretch(0, 1)

        return widget
Beispiel #6
0
 def close(self):
     CONF.set('gapfill_data', 'nbr_of_station', self.Nmax.value())
     CONF.set('gapfill_data', 'max_horiz_dist', self.distlimit.value())
     CONF.set('gapfill_data', 'max_vert_dist', self.altlimit.value())
     CONF.set('gapfill_data', 'regression_model',
              'OLS' if self.RMSE_regression.isChecked() else 'LAD')
     super().close()
Beispiel #7
0
    def _create_regression_model_settings(self):
        self.RMSE_regression = QRadioButton('Ordinary Least Squares')
        self.RMSE_regression.setChecked(
            CONF.get('gapfill_data', 'regression_model', 'OLS') == 'OLS')

        self.ABS_regression = QRadioButton('Least Absolute Deviations')
        self.ABS_regression.setChecked(
            CONF.get('gapfill_data', 'regression_model', 'OLS') == 'LAD')

        widget = QGroupBox('Regression Model')
        layout = QGridLayout(widget)
        layout.addWidget(self.RMSE_regression, 0, 0)
        layout.addWidget(self.ABS_regression, 1, 0)

        return widget
Beispiel #8
0
def get_select_file_dialog_dir():
    """"
    Return the directory that should be displayed by default
    in file dialogs.
    """
    directory = CONF.get('main', 'select_file_dialog_dir', get_home_dir())
    directory = directory if osp.exists(directory) else get_home_dir()
    return directory
 def _restore_window_state(self):
     """
     Restore the state of this mainwindow’s toolbars and dockwidgets from
     the value saved in the config.
     """
     # Then we appply saved configuration if it exists.
     hexstate = CONF.get('main', 'window/state', None)
     if hexstate:
         hexstate = hexstate_to_qbytearray(hexstate)
         self.restoreState(hexstate)
Beispiel #10
0
 def _restore_window_geometry(self):
     """
     Restore the geometry of this mainwindow from the value saved
     in the config.
     """
     hexstate = CONF.get('download_data', 'window/geometry', None)
     if hexstate:
         hexstate = hexstate_to_qbytearray(hexstate)
         self.restoreGeometry(hexstate)
     else:
         self.resize(1000, 450)
 def _restore_window_geometry(self):
     """
     Restore the geometry of this mainwindow from the value saved
     in the config.
     """
     hexstate = CONF.get('main', 'window/geometry', None)
     if hexstate:
         hexstate = hexstate_to_qbytearray(hexstate)
         self.restoreGeometry(hexstate)
     else:
         from cdprep.config.gui import INIT_MAINWINDOW_SIZE
         self.resize(*INIT_MAINWINDOW_SIZE)
    def __init__(self):
        super().__init__()
        self.setWindowTitle(__namever__)
        self.setWindowIcon(get_icon('master'))
        self.setContextMenuPolicy(Qt.NoContextMenu)

        if platform.system() == 'Windows':
            import ctypes
            myappid = 'climate_data_preprocessing_tool'  # arbitrary string
            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
                myappid)

        self.data_downloader = None

        # Setup the toolbar.
        self.show_data_downloader_btn = QToolButton()
        self.show_data_downloader_btn.setIcon(get_icon('search_weather_data'))
        self.show_data_downloader_btn.setAutoRaise(True)
        self.show_data_downloader_btn.setToolTip("Download Data")
        self.show_data_downloader_btn.clicked.connect(
            self.show_data_downloader)

        toolbar = QToolBar('Main')
        toolbar.setObjectName('main_toolbar')
        toolbar.setFloatable(False)
        toolbar.setMovable(False)
        toolbar.setIconSize(get_iconsize('normal'))
        self.addToolBar(Qt.TopToolBarArea, toolbar)

        toolbar.addWidget(self.show_data_downloader_btn)
        toolbar.addWidget(create_toolbar_stretcher())
        toolbar.addWidget(self._create_workdir_manager())

        # Setup the main widget.
        self.gapfiller = WeatherDataGapfiller()
        self.setCentralWidget(self.gapfiller)

        self._restore_window_geometry()
        self._restore_window_state()
        self.set_workdir(CONF.get('main', 'working_dir', get_home_dir()))
 def _save_window_geometry(self):
     """
     Save the geometry of this mainwindow to the config.
     """
     hexstate = qbytearray_to_hexstate(self.saveGeometry())
     CONF.set('main', 'window/geometry', hexstate)
Beispiel #14
0
    def closeEvent(self, event):
        self._save_window_geometry()

        # Proximity Filter Options.
        CONF.set('download_data', 'proximity_filter',
                 self.prox_grpbox.isChecked())
        CONF.set('download_data', 'latitude', self.lat)
        CONF.set('download_data', 'longitude', self.lon)
        CONF.set('download_data', 'radius_index',
                 self.radius_SpinBox.currentIndex())
        CONF.set('download_data', 'province_index',
                 self.prov_widg.currentIndex())

        # Data Availability Filter Options.
        CONF.set('download_data', 'data_availability_filter',
                 self.year_widg.isChecked())
        CONF.set('download_data', 'min_nbr_of_years', self.nbrYear.value())
        CONF.set('download_data', 'year_range_left_bound',
                 self.minYear.value())
        CONF.set('download_data', 'year_range_right_bound',
                 self.maxYear.value())
        event.accept()
Beispiel #15
0
    def __initUI__(self):
        self.setWindowTitle('Download Weather Data')
        self.setWindowIcon(get_icon('master'))
        self.setWindowFlags(Qt.Window)

        now = datetime.now()

        # Setup the proximity filter group.
        self.lat_spinBox = QDoubleSpinBox()
        self.lat_spinBox.setAlignment(Qt.AlignCenter)
        self.lat_spinBox.setSingleStep(0.1)
        self.lat_spinBox.setDecimals(3)
        self.lat_spinBox.setValue(CONF.get('download_data', 'latitude', 0))
        self.lat_spinBox.setMinimum(0)
        self.lat_spinBox.setMaximum(180)
        self.lat_spinBox.setSuffix(u' °')
        self.lat_spinBox.valueChanged.connect(self.proximity_grpbox_toggled)

        self.lon_spinBox = QDoubleSpinBox()
        self.lon_spinBox.setAlignment(Qt.AlignCenter)
        self.lon_spinBox.setSingleStep(0.1)
        self.lon_spinBox.setDecimals(3)
        self.lon_spinBox.setValue(CONF.get('download_data', 'longitude', 0))
        self.lon_spinBox.setMinimum(0)
        self.lon_spinBox.setMaximum(180)
        self.lon_spinBox.setSuffix(u' °')
        self.lon_spinBox.valueChanged.connect(self.proximity_grpbox_toggled)

        self.radius_SpinBox = QComboBox()
        self.radius_SpinBox.addItems(['25 km', '50 km', '100 km', '200 km'])
        self.radius_SpinBox.setCurrentIndex(
            CONF.get('download_data', 'radius_index', 0))
        self.radius_SpinBox.currentIndexChanged.connect(
            self.search_filters_changed)

        self.prox_grpbox = QGroupBox("Proximity Filter")
        self.prox_grpbox.setCheckable(True)
        self.prox_grpbox.setChecked(
            CONF.get('download_data', 'proximity_filter', False))
        self.prox_grpbox.toggled.connect(self.proximity_grpbox_toggled)

        prox_search_grid = QGridLayout(self.prox_grpbox)
        prox_search_grid.addWidget(QLabel('Latitude:'), 0, 0)
        prox_search_grid.addWidget(self.lat_spinBox, 0, 1)
        prox_search_grid.addWidget(QLabel('North'), 0, 2)
        prox_search_grid.addWidget(QLabel('Longitude:'), 1, 0)
        prox_search_grid.addWidget(self.lon_spinBox, 1, 1)
        prox_search_grid.addWidget(QLabel('West'), 1, 2)
        prox_search_grid.addWidget(QLabel('Search Radius:'), 2, 0)
        prox_search_grid.addWidget(self.radius_SpinBox, 2, 1)
        prox_search_grid.setColumnStretch(0, 100)
        prox_search_grid.setRowStretch(3, 100)

        # ---- Province filter
        self.prov_widg = QComboBox()
        self.prov_widg.addItems(['All'] + self.PROV_NAME)
        self.prov_widg.setCurrentIndex(
            CONF.get('download_data', 'province_index', 0))
        self.prov_widg.currentIndexChanged.connect(self.search_filters_changed)

        prov_grpbox = QGroupBox()
        prov_layout = QGridLayout(prov_grpbox)
        prov_layout.addWidget(QLabel('Province:'), 0, 0)
        prov_layout.addWidget(self.prov_widg, 0, 1)
        prov_layout.setColumnStretch(0, 1)
        prov_layout.setRowStretch(1, 1)

        # ---- Data availability filter

        # Number of years with data
        self.nbrYear = QSpinBox()
        self.nbrYear.setAlignment(Qt.AlignCenter)
        self.nbrYear.setSingleStep(1)
        self.nbrYear.setMinimum(0)
        self.nbrYear.setValue(CONF.get('download_data', 'min_nbr_of_years', 3))
        self.nbrYear.valueChanged.connect(self.search_filters_changed)

        subgrid1 = QGridLayout()
        subgrid1.setContentsMargins(0, 0, 0, 0)
        subgrid1.addWidget(QLabel('for at least'), 0, 0)
        subgrid1.addWidget(self.nbrYear, 0, 1)
        subgrid1.addWidget(QLabel('year(s)'), 0, 2)
        subgrid1.setColumnStretch(3, 100)
        subgrid1.setHorizontalSpacing(5)

        # Year range
        self.minYear = QSpinBox()
        self.minYear.setAlignment(Qt.AlignCenter)
        self.minYear.setSingleStep(1)
        self.minYear.setMinimum(1840)
        self.minYear.setMaximum(now.year)
        self.minYear.setValue(
            CONF.get('download_data', 'year_range_left_bound', 1840))
        self.minYear.valueChanged.connect(self.minYear_changed)

        label_and = QLabel('and')
        label_and.setAlignment(Qt.AlignCenter)

        self.maxYear = QSpinBox()
        self.maxYear.setAlignment(Qt.AlignCenter)
        self.maxYear.setSingleStep(1)
        self.maxYear.setMinimum(1840)
        self.maxYear.setMaximum(now.year)
        self.maxYear.setValue(
            CONF.get('download_data', 'year_range_right_bound', now.year))

        self.maxYear.valueChanged.connect(self.maxYear_changed)

        subgrid2 = QGridLayout()
        subgrid2.addWidget(QLabel('between'), 0, 0)
        subgrid2.addWidget(self.minYear, 0, 1)
        subgrid2.addWidget(label_and, 0, 2)
        subgrid2.addWidget(self.maxYear, 0, 3)
        subgrid2.setContentsMargins(0, 0, 0, 0)
        subgrid2.setColumnStretch(4, 100)
        subgrid2.setHorizontalSpacing(5)

        # Subgridgrid assembly
        self.year_widg = QGroupBox("Data Availability filter")
        self.year_widg.setCheckable(True)
        self.year_widg.setChecked(
            CONF.get('download_data', 'data_availability_filter', False))
        self.year_widg.toggled.connect(self.search_filters_changed)

        grid = QGridLayout(self.year_widg)
        grid.setRowMinimumHeight(0, 10)
        grid.addWidget(QLabel('Search for stations with data available'), 1, 0)
        grid.addLayout(subgrid1, 2, 0)
        grid.addLayout(subgrid2, 3, 0)
        grid.setRowStretch(4, 100)
        grid.setVerticalSpacing(8)

        # Setup the toolbar.
        self.btn_addSta = QPushButton('Add')
        self.btn_addSta.setIcon(get_icon('add2list'))
        self.btn_addSta.setIconSize(get_iconsize('small'))
        self.btn_addSta.setToolTip(
            'Add selected stations to the current list of weather stations.')
        self.btn_addSta.clicked.connect(self.btn_addSta_isClicked)
        self.btn_addSta.hide()

        btn_save = QPushButton('Save')
        btn_save.setToolTip('Save the list of selected stations to a file.')
        btn_save.clicked.connect(self.btn_save_isClicked)
        btn_save.hide()

        self.btn_download = QPushButton('Download')
        self.btn_download.clicked.connect(self.start_download_process)

        btn_close = QPushButton('Close')
        btn_close.clicked.connect(self.close)

        self.btn_fetch = btn_fetch = QPushButton('Refresh')
        btn_fetch.setToolTip(
            "Update the list of climate stations by fetching it from "
            "the ECCC remote location.")
        btn_fetch.clicked.connect(self.btn_fetch_isClicked)

        toolbar_widg = QWidget()
        toolbar_grid = QGridLayout(toolbar_widg)
        toolbar_grid.addWidget(self.btn_addSta, 1, 1)
        toolbar_grid.addWidget(btn_save, 1, 2)
        toolbar_grid.addWidget(btn_fetch, 1, 3)
        toolbar_grid.addWidget(self.btn_download, 1, 4)
        toolbar_grid.addWidget(btn_close, 1, 5)
        toolbar_grid.setColumnStretch(0, 100)
        toolbar_grid.setContentsMargins(0, 10, 0, 0)

        # Setup the left panel.
        self.left_panel = QFrame()
        left_panel_grid = QGridLayout(self.left_panel)
        left_panel_grid.setContentsMargins(0, 0, 0, 0)
        left_panel_grid.addWidget(QLabel('Search Criteria'), 0, 0)
        left_panel_grid.addWidget(prov_grpbox, 1, 0)
        left_panel_grid.addWidget(self.prox_grpbox, 2, 0)
        left_panel_grid.addWidget(self.year_widg, 3, 0)
        left_panel_grid.setRowStretch(3, 100)

        # Setup the progress bar.
        self.progressbar = QProgressBar()
        self.progressbar.setValue(0)
        self.progressbar.hide()

        # Setup the central widget.
        main_widget = QWidget()
        main_layout = QGridLayout(main_widget)
        main_layout.addWidget(self.left_panel, 0, 0)
        main_layout.addWidget(self.station_table, 0, 1)
        main_layout.addWidget(self.waitspinnerbar, 0, 1)
        main_layout.addWidget(toolbar_widg, 1, 0, 1, 2)
        main_layout.addWidget(self.progressbar, 2, 0, 1, 2)
        main_layout.setColumnStretch(1, 100)

        self.setCentralWidget(main_widget)