Exemple #1
0
    def submit_run(self, summary_rb_number, run_number, file_name):
        """
        Submit a run to ActiveMQ
        :param summary_rb_number: RB number of the experiment as read from the summary file
        :param run_number: Run number as it appears in lastrun.txt
        :param file_name: File name e.g. GEM1234.nxs
        """
        # Check to see if the last run exists, if not then raise an exception
        file_path = os.path.join(self.data_dir, CYCLE_FOLDER, file_name)

        if os.path.isfile(file_path):
            # Attempt to read an RB number from the Nexus file. This is most
            # useful for high frequency instruments like ENGINX where reading
            # from the summary is unreliable.
            rb_number = read_rb_number_from_nexus_file(file_path)
            if rb_number is None:
                rb_number = summary_rb_number
            EORM_LOG.info("Submitting '%s' with RB number '%s'", file_name,
                          rb_number)
            message = Message(instrument=self.instrument_name,
                              rb_number=rb_number,
                              run_number=run_number,
                              data=file_path,
                              started_by=0)  # Autoreduction service code
            message.validate('/queue/DataReady')
            self.client.send('/queue/DataReady', message, priority='9')
        else:
            raise FileNotFoundError(
                "File does not exist '{}'".format(file_path))
Exemple #2
0
    def find_reason_to_skip_run(reduction_run, message: Message,
                                instrument) -> Optional[str]:
        """
        Determines whether the processing should be skippped.

        The run will be skipped if the message validation fails or if the instrument is paused
        """
        if reduction_run.script == "":
            return "Script text for current instrument is empty"
        try:
            message.validate("/queue/DataReady")
        except RuntimeError as validation_err:
            return f"Validation error from handler: {str(validation_err)}"

        if instrument.is_paused:
            return f"Run {message.run_number} has been skipped because the instrument {instrument.name} is paused"

        return None
Exemple #3
0
 def test_validate_data_ready_valid(self):
     """
     Test: No exception is raised
     When: Calling validate for data_ready with a valid message
     """
     message = Message(instrument='GEM',
                       run_number=111,
                       rb_number=222,
                       data='file/path',
                       facility="ISIS",
                       started_by=0)
     try:
         self.assertIsNone(message.validate('/queue/DataReady'))
     except RuntimeError:
         self.fail()
    def data_ready(self, message: Message):
        """
        Called when destination queue was data_ready.
        Updates the reduction run in the database.
        """
        self._logger.info("Data ready for processing run %s on %s",
                          message.run_number, message.instrument)
        if not validate_rb_number(message.rb_number):
            # rb_number is invalid so send message to skip queue and early return
            message.message = f"Found non-integer RB number: {message.rb_number}"
            self._logger.warning("%s. Skipping %s%s.", message.message,
                                 message.instrument, message.run_number)
            message.rb_number = 0

        run_no = str(message.run_number)
        instrument = self._get_and_activate_db_inst(message.instrument)

        status = self._utils.status.get_skipped() if instrument.is_paused \
            else self._utils.status.get_queued()

        # This must be done before looking up the run version to make sure
        # the record exists
        experiment = db_access.get_experiment(message.rb_number, create=True)
        run_version = db_access.find_highest_run_version(run_number=run_no,
                                                         experiment=experiment)
        run_version += 1
        message.run_version = run_version

        # Get the script text for the current instrument. If the script text
        # is null then send to
        # error queue
        script_text = self._utils. \
            instrument_variable.get_current_script_text(instrument.name)[0]
        if script_text is None:
            self.reduction_error(message)
            raise InvalidStateException(
                "Script text for current instrument is null")

        # Make the new reduction run with the information collected so far
        # and add it into the database
        reduction_run = db_records.create_reduction_run_record(
            experiment=experiment,
            instrument=instrument,
            message=message,
            run_version=run_version,
            script_text=script_text,
            status=status)
        db_access.save_record(reduction_run)

        # Create a new data location entry which has a foreign key linking
        # it to the current
        # reduction run. The file path itself will point to a datafile
        # (e.g. "\isis\inst$\NDXWISH\Instrument\data\cycle_17_1\WISH00038774
        # .nxs")
        data_location = self._data_model.DataLocation(
            file_path=message.data, reduction_run_id=reduction_run.id)
        db_access.save_record(data_location)

        # We now need to create all of the variables for the run such that
        # the script can run
        # through in the desired way
        self._logger.info('Creating variables for run')
        variables = self._utils.instrument_variable.create_variables_for_run(
            reduction_run)
        if not variables:
            self._logger.warning(
                "No instrument variables found on %s for run %s",
                instrument.name, message.run_number)

        self._logger.info('Getting script and arguments')
        reduction_script, arguments = self._utils.reduction_run. \
            get_script_and_arguments(reduction_run)
        message.reduction_script = reduction_script
        message.reduction_arguments = arguments

        # Make sure the RB number is valid
        try:
            message.validate("/queue/DataReady")
        except RuntimeError as validation_err:
            self._logger.error("Validation error from handler: %s",
                               str(validation_err))
            self._client.send_message('/queue/ReductionSkipped', message)
            return

        if instrument.is_paused:
            self._logger.info("Run %s has been skipped", message.run_number)
        else:
            self._client.send_message('/queue/ReductionPending', message)
            self._logger.info("Run %s ready for reduction", message.run_number)