コード例 #1
0
    def test_start_calibration_worker(self, task):
        instrument, cer = ("test_ins", "test_cer")
        old_pending = CalibrationInfo(sample_path=None, instrument=None)
        self.presenter.pending_calibration = old_pending
        expected_pending = CalibrationInfo(sample_path=cer,
                                           instrument=instrument)
        self.presenter.instrument = instrument

        self.presenter.start_calibration_worker(cer, False, None)

        self.check_calibration_equal(self.presenter.pending_calibration, expected_pending)
コード例 #2
0
    def test_validate_while_searching(self, create_error):
        self.presenter.current_calibration = CalibrationInfo(sample_path="Fake/Path",
                                                             instrument="ENGINX")
        self.view.is_searching.return_value = True

        self.assertEqual(False, self.presenter._validate())
        self.assertEqual(1, create_error.call_count)
コード例 #3
0
    def test_set_current_calibration(self):
        self.presenter.calibration_notifier = MagicMock()
        pending = CalibrationInfo(sample_path="test/set/path/2",
                                  instrument="TEST_INS")
        pendcpy = CalibrationInfo(sample_path="test/set/path/2",
                                  instrument="TEST_INS")
        self.presenter.pending_calibration = pending
        current = CalibrationInfo(sample_path="old/cera",
                                  instrument="ENGINX")
        blank = CalibrationInfo()
        self.presenter.current_calibration = current

        self.presenter.set_current_calibration()

        self.check_calibration_equal(self.presenter.current_calibration, pendcpy)
        self.check_calibration_equal(self.presenter.pending_calibration, blank)
        self.assertEqual(self.presenter.calibration_notifier.notify_subscribers.call_count, 1)
コード例 #4
0
    def __init__(self, model, view):
        self.model = model
        self.view = view
        self.worker = None
        self.calibration_notifier = self.CalibrationNotifier(self)

        self.current_calibration = CalibrationInfo()
        self.pending_calibration = CalibrationInfo()

        self.connect_view_signals()

        # Main Window State Variables
        self.instrument = "ENGINX"
        self.rb_num = None

        # Cropping Options
        self.cropping_widget = CroppingPresenter(parent=self.view, view=self.view.get_cropping_widget())
        self.show_cropping(False)
コード例 #5
0
    def test_validate_with_invalid_calibration(self, create_error):
        self.presenter.current_calibration = CalibrationInfo(sample_path=None,
                                                             instrument=None)
        self.view.is_searching.return_value = False

        self.presenter._validate()
        create_error.assert_called_with(
            self.presenter.view,
            "Create or Load a calibration via the Calibration tab before focusing.")
コード例 #6
0
ファイル: presenter.py プロジェクト: gemmaguest/mantid
    def __init__(self, model, view):
        self.model = model
        self.view = view
        self.worker = None
        self.calibration_observer = CalibrationObserver(self)

        # Observable Setup
        self.focus_run_notifier = GenericObservable()

        # Connect view signals to local methods.
        self.view.set_on_focus_clicked(self.on_focus_clicked)
        self.view.set_enable_controls_connection(self.set_focus_controls_enabled)

        # Variables from other GUI tabs.
        self.current_calibration = CalibrationInfo()
        self.instrument = "ENGINX"
        self.rb_num = None

        last_van_path = get_setting(output_settings.INTERFACES_SETTINGS_GROUP, output_settings.ENGINEERING_PREFIX,
                                    "last_vanadium_run")
        if last_van_path:
            self.view.set_van_file_text_with_search(last_van_path)
コード例 #7
0
    def test_calibrate_clicked_load_invalid_path(self, path, setting):
        self.presenter.calibration_notifier = MagicMock()
        self.view.get_new_checked.return_value = False
        self.view.get_load_checked.return_value = True
        path.return_value = False
        current = CalibrationInfo(sample_path="old/cera",
                                  instrument="ENGINX")
        self.presenter.current_calibration = current

        self.presenter.on_calibrate_clicked()

        self.assertEqual(self.presenter.current_calibration, current)
        self.assertEqual(self.presenter.calibration_notifier.notify_subscribers.call_count, 0)
コード例 #8
0
    def test_worker_started_with_correct_params_custom_crop(self, worker, setting):
        self.presenter.current_calibration = CalibrationInfo(sample_path="Fake/Path",
                                                             instrument="ENGINX")
        self.view.get_focus_filenames.return_value = "305738"
        self.view.get_vanadium_filename.return_value = "307521"
        self.presenter.current_calibration.set_roi_info(None, None, "2-45")
        self.view.get_plot_output.return_value = True
        self.view.is_searching.return_value = False
        rp_dict_cropped = {'Cropped': 'Custom_spectra_grouping'}

        self.presenter.on_focus_clicked()
        worker.assert_called_with("305738", "307521", True, None, rp_dict_cropped)
        self.assertEqual(1, setting.call_count)
コード例 #9
0
    def test_worker_started_with_correct_params(self, worker, setting):
        self.presenter.current_calibration = CalibrationInfo(sample_path="Fake/Path",
                                                             instrument="ENGINX")
        self.view.get_focus_filenames.return_value = "305738"
        self.view.get_vanadium_filename.return_value = "307521"
        # testing south bank roi info is correctly propagated
        self.presenter.current_calibration.set_roi_info('2', None, None)
        self.view.get_plot_output.return_value = True
        self.view.is_searching.return_value = False

        self.presenter.on_focus_clicked()
        grp_dict_south = {'bank_2': 'SouthBank_grouping'}
        worker.assert_called_with("305738", "307521", True, None, grp_dict_south)
        self.assertEqual(1, setting.call_count)
コード例 #10
0
    def test_calibrate_clicked_load_valid_path(self, path, setting):
        self.presenter.calibration_notifier = MagicMock()
        self.view.get_new_checked.return_value = False
        self.view.get_load_checked.return_value = True

        path.return_value = True
        instrument, cer, grp_ws, roi, banks = ("test_ins", "test_cer", "test_grpws", "test_roi",
                                                    ['test'])
        self.model.load_existing_calibration_files.return_value = instrument, cer, grp_ws, roi, banks
        current = CalibrationInfo(sample_path="old/cera",
                                  instrument="ENGINX")
        new = CalibrationInfo(sample_path=cer, instrument=instrument)
        new.set_roi_info_load(banks, grp_ws, roi)
        self.presenter.current_calibration = current

        self.presenter.on_calibrate_clicked()

        self.assertEqual(self.presenter.current_calibration.get_sample(), new.get_sample())
        self.assertEqual(self.presenter.current_calibration.get_instrument(), new.get_instrument())
        self.assertEqual(self.presenter.calibration_notifier.notify_subscribers.call_count, 1)
コード例 #11
0
ファイル: presenter.py プロジェクト: gemmaguest/mantid
class FocusPresenter(object):
    def __init__(self, model, view):
        self.model = model
        self.view = view
        self.worker = None
        self.calibration_observer = CalibrationObserver(self)

        # Observable Setup
        self.focus_run_notifier = GenericObservable()

        # Connect view signals to local methods.
        self.view.set_on_focus_clicked(self.on_focus_clicked)
        self.view.set_enable_controls_connection(self.set_focus_controls_enabled)

        # Variables from other GUI tabs.
        self.current_calibration = CalibrationInfo()
        self.instrument = "ENGINX"
        self.rb_num = None

        last_van_path = get_setting(output_settings.INTERFACES_SETTINGS_GROUP, output_settings.ENGINEERING_PREFIX,
                                    "last_vanadium_run")
        if last_van_path:
            self.view.set_van_file_text_with_search(last_van_path)

    def add_focus_subscriber(self, obs):
        self.focus_run_notifier.add_subscriber(obs)

    def on_focus_clicked(self):
        if not self._validate():
            return
        regions_dict = self.current_calibration.create_focus_roi_dictionary()
        focus_paths = self.view.get_focus_filenames()
        van_path = self.view.get_vanadium_filename()
        if self._number_of_files_warning(focus_paths):
            self.start_focus_worker(focus_paths, van_path, self.view.get_plot_output(), self.rb_num, regions_dict)
        van_run = self.view.get_vanadium_run()
        set_setting(output_settings.INTERFACES_SETTINGS_GROUP, output_settings.ENGINEERING_PREFIX,
                    "last_vanadium_run", van_run)

    def start_focus_worker(self, focus_paths: list, van_path: str, plot_output: bool, rb_num: str, regions_dict: dict) -> None:
        """
        Focus data in a separate thread to stop the main GUI from hanging.
        :param focus_paths: List of paths to the files containing the data to focus.
        :param plot_output: True if the output should be plotted.
        :param rb_num: The RB Number from the main window (often an experiment id)
        :param regions_dict: Dictionary containing the regions to focus over, mapping region_name -> grouping_ws_name
        """
        self.worker = AsyncTask(self.model.focus_run,
                                (focus_paths, van_path, plot_output, self.instrument, rb_num, regions_dict),
                                error_cb=self._on_worker_error,
                                finished_cb=self._on_worker_success)
        self.set_focus_controls_enabled(False)
        self.worker.start()

    def _on_worker_success(self):
        self.emit_enable_button_signal()
        self.focus_run_notifier.notify_subscribers(self.model.get_last_focused_files())

    def set_instrument_override(self, instrument):
        instrument = INSTRUMENT_DICT[instrument]
        self.view.set_instrument_override(instrument)
        self.instrument = instrument

    def set_rb_num(self, rb_num):
        self.rb_num = rb_num

    def _validate(self):
        """
        Ensure that the worker is ready to be started.
        :return: True if the worker can be started safely.
        """
        if self.view.is_searching():
            create_error_message(self.view, "Mantid is searching for data files. Please wait.")
            return False
        if not self.view.get_focus_valid():
            create_error_message(self.view, "Check run numbers/path is valid.")
            return False
        if not self.view.get_vanadium_valid():
            create_error_message(self.view, "Check vanadium run number/path is valid.")
            return False
        if not self.current_calibration.is_valid():
            create_error_message(
                self.view, "Create or Load a calibration via the Calibration tab before focusing.")
            return False
        if self.current_calibration.get_instrument() != self.instrument:
            create_error_message(
                self.view,
                "Please make sure the selected instrument matches instrument for the current calibration.\n"
                "The instrument for the current calibration is: " + self.current_calibration.get_instrument())
            return False
        return True

    def _number_of_files_warning(self, paths):
        if len(paths) > 10:  # Just a guess on the warning for now. May change in future.
            response = QMessageBox.warning(
                self.view, 'Engineering Diffraction - Warning',
                'You are attempting to focus {} workspaces. This may take some time.\n\n Would you like to continue?'
                .format(len(paths)), QMessageBox.Ok | QMessageBox.Cancel)
            return response == QMessageBox.Ok
        else:
            return True

    def _on_worker_error(self, error_info):
        logger.error(str(error_info))
        self.emit_enable_button_signal()

    def set_focus_controls_enabled(self, enabled):
        self.view.set_focus_button_enabled(enabled)
        self.view.set_plot_output_enabled(enabled)

    def emit_enable_button_signal(self):
        self.view.sig_enable_controls.emit(True)

    def update_calibration(self, calibration):
        """
        Update the current calibration following an call from a CalibrationNotifier
        :param calibration: The new current calibration.
        """
        self.current_calibration = calibration
        region_text = calibration.get_roi_text()
        self.view.set_region_display_text(region_text)
コード例 #12
0
class CalibrationPresenter(object):
    def __init__(self, model, view):
        self.model = model
        self.view = view
        self.worker = None
        self.calibration_notifier = self.CalibrationNotifier(self)

        self.current_calibration = CalibrationInfo()
        self.pending_calibration = CalibrationInfo()

        self.connect_view_signals()

        # Main Window State Variables
        self.instrument = "ENGINX"
        self.rb_num = None

        # Cropping Options
        self.cropping_widget = CroppingPresenter(parent=self.view, view=self.view.get_cropping_widget())
        self.show_cropping(False)

    def connect_view_signals(self):
        self.view.set_on_calibrate_clicked(self.on_calibrate_clicked)
        self.view.set_enable_controls_connection(self.set_calibrate_controls_enabled)
        self.view.set_update_field_connection(self.set_field_value)
        self.view.set_on_radio_new_toggled(self.set_create_new_enabled)
        self.view.set_on_radio_existing_toggled(self.set_load_existing_enabled)
        self.view.set_on_check_cropping_state_changed(self.show_cropping)

    def on_calibrate_clicked(self):
        plot_output = self.view.get_plot_output()
        if self.view.get_new_checked() and self._validate():
            sample_file = self.view.get_sample_filename()
            if self.view.get_crop_checked():
                self.start_cropped_calibration_worker(sample_file,
                                                      plot_output, self.rb_num)
            else:
                self.start_calibration_worker(sample_file,plot_output, self.rb_num)
        elif self.view.get_load_checked():
            if not self.validate_path():
                logger.notice("Invalid calibration path")
                return
            filename = self.view.get_path_filename()
            try:
                instrument, sample_file, grp_ws_name, roi_text, banks = \
                    self.model.load_existing_calibration_files(filename)
            except:
                return
            self.pending_calibration.set_calibration(sample_file, instrument)
            self.pending_calibration.set_roi_info_load(banks, grp_ws_name, roi_text)
            self.set_current_calibration()
            set_setting(output_settings.INTERFACES_SETTINGS_GROUP, output_settings.ENGINEERING_PREFIX,
                        "last_calibration_path", filename)

    def start_calibration_worker(self, sample_path, plot_output, rb_num, bank=None, calfile=None,
                                 spectrum_numbers=None):
        """
        Calibrate the data in a separate thread so as to not freeze the GUI.
        :param sample_path: Path to sample data file.
        :param plot_output: Whether to plot the output.
        :param rb_num: The current RB number set in the GUI.
        :param bank: Optional parameter to crop by bank.
        :param calfile: Custom calibration file the user can supply for the calibration region of interest.
        :param spectrum_numbers: Optional parameter to crop by spectrum number.
        """
        self.worker = AsyncTask(self.model.create_new_calibration, (sample_path,),
                                {
                                "plot_output": plot_output,
                                "instrument": self.instrument,
                                "rb_num": rb_num,
                                "bank": bank,
                                "calfile": calfile,
                                "spectrum_numbers": spectrum_numbers
                                },
                                error_cb=self._on_error,
                                success_cb=self._on_success)
        self.pending_calibration.set_calibration(sample_path, self.instrument)
        self.pending_calibration.set_roi_info(bank, calfile, spectrum_numbers)
        self.set_calibrate_controls_enabled(False)
        self.worker.start()

    def start_cropped_calibration_worker(self, sample_path, plot_output, rb_num):
        if self.cropping_widget.get_custom_calfile_enabled():
            calfile = self.cropping_widget.get_custom_calfile()
            self.start_calibration_worker(sample_path, plot_output, rb_num,
                                          calfile=calfile)
        elif self.cropping_widget.get_custom_spectra_enabled():
            spec_nums = self.cropping_widget.get_custom_spectra()
            self.start_calibration_worker(sample_path, plot_output, rb_num,
                                          spectrum_numbers=spec_nums)
        else:
            bank = str(self.cropping_widget.get_bank())
            self.start_calibration_worker(sample_path, plot_output, rb_num,
                                          bank=bank)

    def set_current_calibration(self, success_info=None):
        if success_info:
            logger.information("Thread executed in " + str(success_info.elapsed_time) + " seconds.")
        self.current_calibration = deepcopy(self.pending_calibration)
        self.calibration_notifier.notify_subscribers(self.current_calibration)
        self.pending_calibration.clear()

    def load_last_calibration(self) -> None:
        """
        Loads the most recently created or loaded calibration into the interface instance. To be used on interface
        startup.
        """
        last_cal_path = get_setting(output_settings.INTERFACES_SETTINGS_GROUP, output_settings.ENGINEERING_PREFIX,
                                    "last_calibration_path")
        if last_cal_path:
            self.view.set_load_checked(True)
            self.view.set_file_text_with_search(last_cal_path)

    def set_field_value(self):
        self.view.set_sample_text(self.current_calibration.get_sample())

    def set_instrument_override(self, instrument):
        instrument = INSTRUMENT_DICT[instrument]
        self.view.set_instrument_override(instrument)
        self.instrument = instrument

    def set_rb_num(self, rb_num):
        self.rb_num = rb_num

    def _validate(self):
        # Do nothing if run numbers are invalid or view is searching.
        if self.view.is_searching():
            create_error_message(self.view, "Mantid is searching for data files. Please wait.")
            return False
        if not self.view.get_sample_valid():
            create_error_message(self.view, "Check run numbers/path is valid.")
            return False
        if self.view.get_crop_checked():
            if self.cropping_widget.get_custom_calfile_enabled() and not self.cropping_widget.is_calfile_valid():
                create_error_message(self.view, "Check custom calfile path is valid.")
                return False
            if self.cropping_widget.get_custom_spectra_enabled() and not self.cropping_widget.is_spectra_valid():
                create_error_message(self.view, "Check custom spectra are valid.")
                return False
        return True

    def validate_path(self):
        return self.view.get_path_valid()

    def emit_enable_button_signal(self):
        self.view.sig_enable_controls.emit(True)

    def set_calibrate_controls_enabled(self, enabled):
        self.view.set_calibrate_button_enabled(enabled)

    def _on_error(self, error_info):
        logger.error(str(error_info))
        self.emit_enable_button_signal()

    def _on_success(self, success_info):
        self.set_current_calibration(success_info)
        self.emit_enable_button_signal()

    def set_create_new_enabled(self, enabled):
        self.view.set_sample_enabled(enabled)
        if enabled:
            self.set_calibrate_button_text("Calibrate")
            self.view.set_check_plot_output_enabled(True)
            self.view.set_check_cropping_enabled(True)
            self.find_files()

    def set_load_existing_enabled(self, enabled):
        self.view.set_path_enabled(enabled)
        if enabled:
            self.set_calibrate_button_text("Load")
            self.view.set_check_plot_output_enabled(False)
            self.view.set_check_cropping_enabled(False)
            self.view.set_check_cropping_checked(False)

    def set_calibrate_button_text(self, text):
        self.view.set_calibrate_button_text(text)

    def find_files(self):
        self.view.find_sample_files()

    def show_cropping(self, show):
        self.view.set_cropping_widget_visibility(show)

    # -----------------------
    # Observers / Observables
    # -----------------------
    class CalibrationNotifier(Observable):
        def __init__(self, outer):
            Observable.__init__(self)
            self.outer = outer

        def notify_subscribers(self, *args, **kwargs):
            Observable.notify_subscribers(self, *args)
コード例 #13
0
ファイル: test_focus_model.py プロジェクト: gemmaguest/mantid
 def setUp(self):
     self.test_dir = tempfile.mkdtemp()
     self.model = model.FocusModel()
     self.current_calibration = CalibrationInfo(
         sample_path="this_is_mocked_out_too", instrument="ENGINX")