def async_run_code(self, code_obj, result=None, async_=False):
        """A monkey-patched replacement for the InteractiveShell.run_code method.
        It runs the in a separate thread and calls QApplication.processEvents
        periodically until the method finishes.

        :param code_obj : code object
          A compiled code object, to be executed
        :param result : ExecutionResult, optional
          An object to store exceptions that occur during execution.
        :param async_ : Bool (Experimental))
           Attempt to run top-level asynchronous code in a default loop.

        :returns: An AsyncTaskResult object
        """
        # Different target arguments depending on IPython's version
        function_parameters = getfullargspec(orig_run_code)
        if 'result' in function_parameters.args:
            if hasattr(function_parameters, 'kwonlyargs'
                       ) and 'async_' in function_parameters.kwonlyargs:
                return orig_run_code(
                    code_obj, result,
                    async_=async_)  # return coroutine to be awaited
            else:
                task = BlockingAsyncTaskWithCallback(
                    target=orig_run_code,
                    args=(code_obj, result),
                    blocking_cb=QApplication.processEvents)
        else:
            task = BlockingAsyncTaskWithCallback(
                target=orig_run_code,
                args=(code_obj, ),
                blocking_cb=QApplication.processEvents)
        return task.start()
Exemple #2
0
 def _load(self, file_name):
     project_loader = ProjectLoader(self.project_file_ext)
     task = BlockingAsyncTaskWithCallback(
         target=project_loader.load_project,
         args=[file_name],
         blocking_cb=QApplication.processEvents)
     task.start()
Exemple #3
0
    def test_successful_no_arg_operation_without_callback(self):
        def foo():
            return 42

        task = BlockingAsyncTaskWithCallback(foo)

        self.assertEqual(42, task.start())
Exemple #4
0
    def execute_async(self,
                      code_str,
                      line_offset,
                      filename=None,
                      blocking=False):
        """
        Execute the given code string on a separate thread. This function
        returns as soon as the new thread starts

        :param code_str: A string containing code to execute
        :param line_offset: See PythonCodeExecution.execute()
        :param filename: See PythonCodeExecution.execute()
        :param blocking: If True the call will block until the task is finished
        :returns: The created async task, only returns task if the blocking is False
        """
        # Stack is chopped on error to avoid the  AsyncTask.run->self.execute calls appearing
        # as these are not useful for the user in this context
        if not blocking:
            task = AsyncTask(self.execute,
                             args=(code_str, filename, line_offset),
                             success_cb=self._on_success,
                             error_cb=self._on_error)
            task.start()
            self._task = task
            return task
        else:
            self._task = BlockingAsyncTaskWithCallback(
                self.execute,
                args=(code_str, filename, line_offset),
                success_cb=self._on_success,
                error_cb=self._on_error,
                blocking_cb=QApplication.processEvents)
            return self._task.start()
Exemple #5
0
    def test_successful_positional_args_operation(self):
        def foo(shift):
            return 42 + shift

        shift = 2
        task = BlockingAsyncTaskWithCallback(foo, args=(shift, ))

        self.assertEqual(42 + shift, task.start())
Exemple #6
0
    def test_unsuccessful_args_and_kwargs_operation_raises_exception(self):
        def foo(scale, shift):
            raise RuntimeError("Bad operation")

        scale, shift = 2, 4
        task = BlockingAsyncTaskWithCallback(foo,
                                             args=(scale, ),
                                             kwargs={'shift': shift})
        self.assertRaises(RuntimeError, task.start)
Exemple #7
0
    def test_successful_args_and_kwargs_operation(self):
        def foo(scale, shift):
            return scale * 42 + shift

        scale, shift = 2, 4

        task = BlockingAsyncTaskWithCallback(foo,
                                             args=(scale, ),
                                             kwargs={'shift': shift})
        self.assertEqual(scale * 42 + shift, task.start())
Exemple #8
0
 def generate_script_from_workspaces(self):
     if not self.workspacewidget.empty_of_workspaces():
         task = BlockingAsyncTaskWithCallback(target=self._generate_script_from_workspaces,
                                              blocking_cb=QApplication.processEvents)
         task.start()
     else:
         # Tell users they need a workspace to do that
         QMessageBox().warning(None, "No Workspaces!",
                               "In order to generate a recovery script there needs to be some workspaces.",
                               QMessageBox.Ok)
Exemple #9
0
    def _do_show_detectors(self, names):
        successful_workspaces = []
        for ws in self._ads.retrieveWorkspaces(names, unrollGroups=True):
            try:
                task = BlockingAsyncTaskWithCallback(self._run_create_detector_table, [ws],
                                                     blocking_cb=QApplication.processEvents)
                task.start()
            except RuntimeError:
                continue
            else:
                successful_workspaces.append(ws.name())

        self._do_show_data(list(map(lambda x: x + "-Detectors", successful_workspaces)))
Exemple #10
0
    def save_as(self):
        """
        The function that is called if the save as... button is clicked on the mainwindow
        :return: True; if the user cancels.
        """
        path = self._save_file_dialog()
        if path is None:
            # Cancel close dialogs
            return True

        # todo: get a list of workspaces but to be implemented on GUI implementation
        self.last_project_location = path
        task = BlockingAsyncTaskWithCallback(
            target=self._save, blocking_cb=QApplication.processEvents)
        task.start()
Exemple #11
0
 def async_run_code(self, code_obj, result=None):
     """A monkey-patched replacement for the InteractiveShell.run_code method.
     It runs the in a separate thread and calls QApplication.processEvents
     periodically until the method finishes
     """
     # ipython 3.0 introduces a third argument named result
     if len(getfullargspec(orig_run_code).args) == 3:
         args = (code_obj, result)
     else:
         args = (code_obj, )
     task = BlockingAsyncTaskWithCallback(
         target=orig_run_code,
         args=args,
         blocking_cb=QApplication.processEvents)
     return task.start()
Exemple #12
0
    def save(self):
        """
        The function that is called if the save button is clicked on the mainwindow
        :return: True; if the user cancels
        """
        if self.last_project_location is None:
            return self.save_as()
        else:
            # Offer an are you sure? overwriting GUI
            answer = self._offer_overwriting_gui()

            if answer == QMessageBox.Yes:
                # Actually save
                task = BlockingAsyncTaskWithCallback(
                    target=self._save, blocking_cb=QApplication.processEvents)
                task.start()
            elif answer == QMessageBox.No:
                # Save with a new name
                return self.save_as()
            else:
                # Cancel clicked
                return True
Exemple #13
0
    def save(self, conf=None):
        """
        The function that is called if the save button is clicked on the mainwindow
        :param: conf: an optional UserConfig to which the user's input will be saved (if the save dialog is shown).
        :return: True; if the user cancels
        """
        if self.last_project_location is None:
            return self.open_project_save_dialog(conf)
        else:
            # Offer an are you sure? overwriting GUI
            answer = self._offer_overwriting_gui()

            if answer == QMessageBox.Yes:
                # Actually save
                task = BlockingAsyncTaskWithCallback(target=self._save, blocking_cb=QApplication.processEvents)
                task.start()
            elif answer == QMessageBox.No:
                # Save with a new name
                return self.open_project_save_dialog(conf)
            else:
                # Cancel clicked
                return True
Exemple #14
0
 def generate_script_from_workspaces(self):
     task = BlockingAsyncTaskWithCallback(
         target=self._generate_script_from_workspaces,
         blocking_cb=QApplication.processEvents)
     task.start()
Exemple #15
0
 def save_as(self, path):
     self.last_project_location = path
     task = BlockingAsyncTaskWithCallback(
         target=self._save, blocking_cb=QApplication.processEvents)
     task.start()
Exemple #16
0
    def manual_reduce_run(self):
        """

        (simply) reduce a list of runs in same experiment in a batch

        Returns
        -------

        """
        # Files names: NeXus, (output) project, mask, calibration
        run_number = self._current_runnumber()
        if isinstance(run_number, int):
            # use specify run number (integer)
            nexus_file = get_nexus_file(run_number)
        else:
            nexus_file = str(self.ui.lineEdit_runNumber.text()).strip()

            # quit if the input is not NeXus
            if not (os.path.exists(nexus_file)
                    and nexus_file.endswith('.nxs.h5')):
                return
        # END-IF

        # Output HidraProject file
        project_file = str(self.ui.lineEdit_outputDirectory.text().strip())
        # mask file
        mask_file = str(self.ui.lineEdit_maskFile.text().strip())
        if mask_file == '':
            mask_file = None
        # calibration file
        calibration_file = str(self.ui.lineEdit_calibrationFile.text().strip())
        if calibration_file == '':
            calibration_file = None
        # vanadium file
        vanadium_file = str(self.ui.lineEdit_vanRunNumber.text().strip())
        if vanadium_file == '':
            vanadium_file = None

        # Start task
        if True:
            # single thread:
            try:
                hidra_ws = self._controller.reduce_hidra_workflow(
                    nexus_file,
                    project_file,
                    self.ui.progressBar,
                    mask=mask_file,
                    calibration=calibration_file,
                    vanadium_file=vanadium_file)
            except RuntimeError as run_err:
                pop_message(self.parent,
                            'Failed to reduce {}',
                            str(run_err),
                            message_type='error')
                return

            # Update table
            # TODO - Need to fill the table!
            sub_runs = list(hidra_ws.get_sub_runs())
            # for sub_run in sub_runs:
            #     self.ui.rawDataTable.update_reduction_state(sub_run, True)

            # Set the sub runs combo box
            self._set_sub_run_numbers(sub_runs)

        else:
            task = BlockingAsyncTaskWithCallback(
                self._controller.reduce_hidra_workflow,
                args=(nexus_file, project_file, self.ui.progressBar),
                kwargs={
                    'mask': mask_file,
                    'calibration': calibration_file
                },
                blocking_cb=QApplication.processEvents)
            # TODO - catch RuntimeError! ...
            # FIXME - check output directory
            task.start()

        return