Esempio n. 1
0
def check_workspaces_exist(run_no) -> bool:
    """
    Check the vanadium workspaces are loaded into the ADS
    :return: True if both are present, false otherwise
    """
    return Ads.doesExist(str(run_no) + '_' +
                         PROCESSED_WORKSPACE_NAME) and Ads.doesExist(
                             str(run_no) + '_' + INTEGRATED_WORKSPACE_NAME)
Esempio n. 2
0
 def _check_region_grouping_ws_exists(grouping_ws_name: str,
                                      inst_ws) -> bool:
     """
     Check that the required grouping workspace for this focus exists, and if not present for a North/South bank
     focus, retrieve them from the user directories or create them (expected if first focus with loaded calibration)
     :param grouping_ws_name: Name of the grouping workspace whose presence in the ADS is being checked
     :param inst_ws: Workspace containing the instrument data for use in making a bank grouping workspace
     :return: True if the required workspace exists (or has just been loaded/created), False if not
     """
     if not Ads.doesExist(grouping_ws_name):
         if "North" in grouping_ws_name:
             logger.notice(
                 "NorthBank grouping workspace not present in ADS, loading")
             EnggUtils.get_bank_grouping_workspace(1, inst_ws)
             return True
         elif "South" in grouping_ws_name:
             logger.notice(
                 "SouthBank grouping workspace not present in ADS, loading")
             EnggUtils.get_bank_grouping_workspace(2, inst_ws)
             return True
         else:
             logger.warning(
                 f"Cannot focus as the grouping workspace \"{grouping_ws_name}\" is not present."
             )
             return False
     return True
Esempio n. 3
0
 def __addNoise(self, mean=0.0, scale=0.1):
     """
     Add some random background noise to the baseline using a normal distribution
     """
     noise_gen = np.random.default_rng(self.noise_seed)
     self.assertTrue(AnalysisDataService.doesExist("Baseline"))
     basews = AnalysisDataService.retrieve("Baseline")
     y = basews.extractY()
     y = np.add(y, noise_gen.normal(mean, scale, self.resolution))
     basews.setY(y)
Esempio n. 4
0
def get_bank_grouping_workspace(bank: int, sample_raw):  # -> GroupingWorkspace
    """
    Retrieve the grouping workspace for the North/South bank from the user directories, or create a new one from the
    sample workspace instrument data if not found
    :param bank: integer denoting the bank, 1 or 2 for North/South respectively
    :param sample_raw: Workspace containing the instrument data that can be used to create a new grouping workspace
    :return: The loaded or created grouping workspace
    """
    if bank == 1:
        try:
            if ADS.doesExist("NorthBank_grouping"):
                return ADS.retrieve("NorthBank_grouping")
            grp_ws = mantid.LoadDetectorsGroupingFile(
                InputFile="ENGINX_North_grouping.xml",
                OutputWorkspace="NorthBank_grouping")
            return grp_ws
        except ValueError:
            logger.notice(
                "NorthBank grouping file not found in user directories - creating one"
            )
        bank_name = "NorthBank"
    elif bank == 2:
        try:
            if ADS.doesExist("SouthBank_grouping"):
                return ADS.retrieve("SouthBank_grouping")
            grp_ws = mantid.LoadDetectorsGroupingFile(
                InputFile="ENGINX_South_grouping.xml",
                OutputWorkspace="SouthBank_grouping")
            return grp_ws
        except ValueError:
            logger.notice(
                "SouthBank grouping file not found in user directories - creating one"
            )
        bank_name = "SouthBank"
    else:
        raise ValueError("Invalid bank number given")
    ws_name = bank_name + "_grouping"
    grp_ws, _, _ = mantid.CreateGroupingWorkspace(InputWorkspace=sample_raw,
                                                  GroupNames=bank_name,
                                                  OutputWorkspace=ws_name)
    return grp_ws
Esempio n. 5
0
def get_detector_ids_for_bank(bank):
    """
    Find the detector IDs for an instrument bank. Note this is at this point specific to
    the ENGINX instrument.

    @param bank :: name/number as a string.

    @returns list of detector IDs corresponding to the specified Engg bank number
    """
    import os
    grouping_file_path = os.path.join(mantid.config.getInstrumentDirectory(),
                                      'Grouping', 'ENGINX_Grouping.xml')

    alg = AlgorithmManager.create('LoadDetectorsGroupingFile')
    alg.initialize()
    alg.setLogging(False)
    alg.setProperty('InputFile', grouping_file_path)
    group_name = '__EnginXGrouping'
    alg.setProperty('OutputWorkspace', group_name)
    alg.execute()

    # LoadDetectorsGroupingFile produces a 'Grouping' workspace.
    # PropertyWithValue<GroupingWorkspace> not working (GitHub issue 13437)
    # => cannot run as child and get outputworkspace property properly
    if not ADS.doesExist(group_name):
        raise RuntimeError(
            'LoadDetectorsGroupingFile did not run correctly. Could not '
            'find its output workspace: ' + group_name)
    grouping = mtd[group_name]

    detector_ids = set()

    # less then zero indicates both banks, from line 98
    bank_int = int(bank)
    if bank_int < 0:
        # both banks, north and south
        bank_int = [1, 2]
    else:
        # make into list so that the `if in` check works
        bank_int = [bank_int]

    for i in range(grouping.getNumberHistograms()):
        if grouping.readY(i)[0] in bank_int:
            detector_ids.add(grouping.getDetector(i).getID())

    mantid.DeleteWorkspace(grouping)

    if len(detector_ids) == 0:
        raise ValueError('Could not find any detector for this bank: ' + bank +
                         '. This looks like an unknown bank')

    return detector_ids
Esempio n. 6
0
 def _check_region_calib_ws_exists(region: str) -> bool:
     """
     Check that the required workspace for use in focussing the provided region of interest exist in the ADS
     :param region: String describing region of interest
     :return: True if present, False if not
     """
     region_ws_name = REGION_CALIB_WS_PREFIX + region
     present = Ads.doesExist(region_ws_name)
     if not present:
         logger.warning(
             f"Cannot focus as the region calibration workspace \"{region_ws_name}\" is not "
             f"present.")
     return present
Esempio n. 7
0
def load_full_instrument_calibration():
    if ADS.doesExist("full_inst_calib"):
        full_calib = ADS.retrieve("full_inst_calib")
    else:
        full_calib_path = get_setting(
            output_settings.INTERFACES_SETTINGS_GROUP,
            output_settings.ENGINEERING_PREFIX, "full_calibration")
        try:
            full_calib = Load(full_calib_path,
                              OutputWorkspace="full_inst_calib")
        except ValueError:
            logger.error(
                "Error loading Full instrument calibration - this is set in the interface settings."
            )
            return
    return full_calib
Esempio n. 8
0
    def __createRandPeaksWS(self, amplitude=1.0):
        """
        Creates a test WS with random peaks added to the baseline function
        """
        # Create a new generator, get a permutation of indices used to add peaks to the data.
        np.random.seed(self.rand_seed)
        peaklist = np.random.randint(self.peak_border_lim,
                                     self.resolution - self.peak_border_lim,
                                     self.npeaks)

        self.assertTrue(AnalysisDataService.doesExist("Baseline"))
        basews = AnalysisDataService.retrieve("Baseline")
        x = basews.extractX()
        y = basews.extractY()

        # Add a simple peak to the indices chosen by the random permutation
        for i in peaklist:
            y[0][i] = y[0][i] + amplitude * np.abs(np.sin(x[0][i]))

        CreateWorkspace(DataX=x, DataY=y, OutputWorkspace="PeakData")
Esempio n. 9
0
def create_vanadium_corrections(vanadium_path: str,
                                instrument: str):  # -> Workspace, Workspace
    """
    Runs the vanadium correction algorithm.
    :param vanadium_path: The path to the vanadium data.
    :return: The integrated workspace and the processed instrument workspace generated.
    """
    try:
        run_no = path_handling.get_run_number_from_path(
            vanadium_path, instrument)
        van_ws = Load(Filename=vanadium_path,
                      OutputWorkspace=str(run_no) + '_' +
                      VANADIUM_INPUT_WORKSPACE_NAME)
    except Exception as e:
        logger.error(
            "Error when loading vanadium sample data. "
            "Could not run Load algorithm with vanadium run number: " +
            str(vanadium_path) + ". Error description: " + str(e))
        raise RuntimeError
    # get full instrument calibration for instrument processing calculation
    if Ads.doesExist("full_inst_calib"):
        full_calib_ws = Ads.retrieve("full_inst_calib")
    else:
        full_calib_path = get_setting(
            output_settings.INTERFACES_SETTINGS_GROUP,
            output_settings.ENGINEERING_PREFIX, "full_calibration")
        try:
            full_calib_ws = Load(full_calib_path,
                                 OutputWorkspace="full_inst_calib")
        except ValueError:
            logger.error(
                "Error loading Full instrument calibration - this is set in the interface settings."
            )
            return
    integral_ws = _calculate_vanadium_integral(van_ws, run_no)
    processed_ws = _calculate_vanadium_processed_instrument(
        van_ws, full_calib_ws, integral_ws, run_no)
    return integral_ws, processed_ws
Esempio n. 10
0
 def _get_van_curves_for_roi(region: str, van_processed_inst_ws,
                             grouping_ws):  # -> Workspace
     """
     Retrieve vanadium curves for this roi from the ADS if they exist, create them if not
     :param region: String describing region of interest
     :param van_processed_inst_ws: Processed instrument workspace of this vanadium run
     :param grouping_ws: Grouping workspace for DiffractionFoucussing
     :return: Curves workspace for this roi
     """
     curves_roi_name = CURVES_PREFIX + region
     # check if van curves for roi in ADS (should exist if not first run in session)
     if Ads.doesExist(curves_roi_name):
         return Ads.retrieve(curves_roi_name)
     else:
         # focus processed instrument ws over specified region of interest, iot produce vanadium curves for roi
         focused_curves = DiffractionFocussing(
             InputWorkspace=van_processed_inst_ws,
             OutputWorkspace=curves_roi_name,
             GroupingWorkspace=grouping_ws)
         EnggEstimateFocussedBackground(InputWorkspace=focused_curves,
                                        OutputWorkspace=focused_curves,
                                        NIterations='15',
                                        XWindow=0.03)
         return focused_curves
Esempio n. 11
0
    def _plotTimeCounts(self, wksp):
        """ Plot time/counts
        """
        import datetime
        # Rebin events by pulse time
        try:
            # Get run start and run stop
            if wksp.getRun().hasProperty("run_start"):
                runstart = wksp.getRun().getProperty("run_start").value
            else:
                runstart = wksp.getRun().getProperty("proton_charge").times[0]
            runstop = wksp.getRun().getProperty("proton_charge").times[-1]

            runstart = str(runstart).split(".")[0].strip()
            runstop = str(runstop).split(".")[0].strip()

            t0 = datetime.datetime.strptime(runstart, "%Y-%m-%dT%H:%M:%S")
            tf = datetime.datetime.strptime(runstop, "%Y-%m-%dT%H:%M:%S")

            # Calcualte
            dt = tf - t0
            timeduration = dt.days * 3600 * 24 + dt.seconds

            timeres = float(timeduration) / MAXTIMEBINSIZE
            if timeres < 1.0:
                timeres = 1.0

            sumwsname = "_Summed_%s" % (str(wksp))
            if AnalysisDataService.doesExist(sumwsname) is False:
                sumws = api.SumSpectra(InputWorkspace=wksp,
                                       OutputWorkspace=sumwsname)
                sumws = api.RebinByPulseTimes(InputWorkspace=sumws,
                                              OutputWorkspace=sumwsname,
                                              Params="%f" % (timeres))
                sumws = api.ConvertToPointData(InputWorkspace=sumws,
                                               OutputWorkspace=sumwsname)
            else:
                sumws = AnalysisDataService.retrieve(sumwsname)
        except RuntimeError as e:
            return str(e)

        vecx = sumws.readX(0)
        vecy = sumws.readY(0)

        xmin = min(vecx)
        xmax = max(vecx)
        ymin = min(vecy)
        ymax = max(vecy)

        # Reset graph
        self.ui.mainplot.set_xlim(xmin, xmax)
        self.ui.mainplot.set_ylim(ymin, ymax)

        self.ui.mainplot.set_xlabel('Time (seconds)', fontsize=13)
        self.ui.mainplot.set_ylabel('Counts', fontsize=13)

        # Set up main line
        setp(self.mainline, xdata=vecx, ydata=vecy)

        # Reset slide
        newslidery = [min(vecy), max(vecy)]

        newleftx = xmin + (xmax - xmin) * self._leftSlideValue * 0.01
        setp(self.leftslideline, xdata=[newleftx, newleftx], ydata=newslidery)

        newrightx = xmin + (xmax - xmin) * self._rightSlideValue * 0.01
        setp(self.rightslideline,
             xdata=[newrightx, newrightx],
             ydata=newslidery)

        self.ui.graphicsView.draw()

        return
Esempio n. 12
0
    def _plotTimeCounts(self, wksp):
        """ Plot time/counts
        """
        import datetime
        # Rebin events by pulse time
        try:
            # Get run start and run stop
            if wksp.getRun().hasProperty("run_start"):
                runstart = wksp.getRun().getProperty("run_start").value
            else:
                runstart = wksp.getRun().getProperty("proton_charge").times[0]
            runstop = wksp.getRun().getProperty("proton_charge").times[-1]

            runstart = str(runstart).split(".")[0].strip()
            runstop = str(runstop).split(".")[0].strip()

            t0 = datetime.datetime.strptime(runstart, "%Y-%m-%dT%H:%M:%S")
            tf = datetime.datetime.strptime(runstop, "%Y-%m-%dT%H:%M:%S")

            # Calcualte
            dt = tf-t0
            timeduration = dt.days*3600*24 + dt.seconds

            timeres = float(timeduration)/MAXTIMEBINSIZE
            if timeres < 1.0:
                timeres = 1.0

            sumwsname = "_Summed_%s"%(str(wksp))
            if AnalysisDataService.doesExist(sumwsname) is False:
                sumws = api.SumSpectra(InputWorkspace=wksp, OutputWorkspace=sumwsname)
                sumws = api.RebinByPulseTimes(InputWorkspace=sumws, OutputWorkspace = sumwsname,
                                              Params="%f"%(timeres))
                sumws = api.ConvertToPointData(InputWorkspace=sumws, OutputWorkspace=sumwsname)
            else:
                sumws = AnalysisDataService.retrieve(sumwsname)
        except RuntimeError as e:
            return str(e)

        vecx = sumws.readX(0)
        vecy = sumws.readY(0)

        xmin = min(vecx)
        xmax = max(vecx)
        ymin = min(vecy)
        ymax = max(vecy)

        # Reset graph
        self.ui.mainplot.set_xlim(xmin, xmax)
        self.ui.mainplot.set_ylim(ymin, ymax)

        self.ui.mainplot.set_xlabel('Time (seconds)', fontsize=13)
        self.ui.mainplot.set_ylabel('Counts', fontsize=13)

        # Set up main line
        setp(self.mainline, xdata=vecx, ydata=vecy)

        # Reset slide
        newslidery = [min(vecy), max(vecy)]

        newleftx = xmin + (xmax-xmin)*self._leftSlideValue*0.01
        setp(self.leftslideline, xdata=[newleftx, newleftx], ydata=newslidery)

        newrightx = xmin + (xmax-xmin)*self._rightSlideValue*0.01
        setp(self.rightslideline, xdata=[newrightx, newrightx], ydata=newslidery)

        self.ui.graphicsView.draw()

        return
Esempio n. 13
0
 def focus_run(self, sample_paths, banks, plot_output, instrument, rb_num,
               spectrum_numbers):
     """
     Focus some data using the current calibration.
     :param sample_paths: The paths to the data to be focused.
     :param banks: The banks that should be focused.
     :param plot_output: True if the output should be plotted.
     :param instrument: The instrument that the data came from.
     :param rb_num: The experiment number, used to create directories. Can be None
     :param spectrum_numbers: The specific spectra that should be focused. Used instead of banks.
     """
     if not Ads.doesExist(vanadium_corrections.INTEGRATED_WORKSPACE_NAME
                          ) and not Ads.doesExist(
                              vanadium_corrections.CURVES_WORKSPACE_NAME):
         return
     integration_workspace = Ads.retrieve(
         vanadium_corrections.INTEGRATED_WORKSPACE_NAME)
     curves_workspace = Ads.retrieve(
         vanadium_corrections.CURVES_WORKSPACE_NAME)
     output_workspaces = []  # List of collated workspaces to plot.
     full_calib_path = get_setting(path_handling.INTERFACES_SETTINGS_GROUP,
                                   path_handling.ENGINEERING_PREFIX,
                                   "full_calibration")
     if full_calib_path is not None and path.exists(full_calib_path):
         full_calib_workspace = LoadAscii(full_calib_path,
                                          OutputWorkspace="det_pos",
                                          Separator="Tab")
     else:
         full_calib_workspace = None
     if spectrum_numbers is None:
         for sample_path in sample_paths:
             sample_workspace = path_handling.load_workspace(sample_path)
             run_no = path_handling.get_run_number_from_path(
                 sample_path, instrument)
             workspaces_for_run = []
             for name in banks:
                 output_workspace_name = str(
                     run_no) + "_" + FOCUSED_OUTPUT_WORKSPACE_NAME + str(
                         name)
                 self._run_focus(sample_workspace, output_workspace_name,
                                 integration_workspace, curves_workspace,
                                 name, full_calib_workspace)
                 workspaces_for_run.append(output_workspace_name)
                 # Save the output to the file system.
                 self._save_output(instrument, sample_path, name,
                                   output_workspace_name, rb_num)
             output_workspaces.append(workspaces_for_run)
     else:
         for sample_path in sample_paths:
             sample_workspace = path_handling.load_workspace(sample_path)
             run_no = path_handling.get_run_number_from_path(
                 sample_path, instrument)
             output_workspace_name = str(
                 run_no) + "_" + FOCUSED_OUTPUT_WORKSPACE_NAME + "cropped"
             self._run_focus(sample_workspace, output_workspace_name,
                             integration_workspace, curves_workspace, None,
                             full_calib_workspace, spectrum_numbers)
             output_workspaces.append([output_workspace_name])
             self._save_output(instrument, sample_path, "cropped",
                               output_workspace_name, rb_num)
     # Plot the output
     if plot_output:
         for ws_names in output_workspaces:
             self._plot_focused_workspaces(ws_names)
Esempio n. 14
0
def check_workspaces_exist():
    return Ads.doesExist(CURVES_WORKSPACE_NAME) and Ads.doesExist(INTEGRATED_WORKSPACE_NAME)
Esempio n. 15
0
    def _plotTimeCounts(self, wksp):
        """ Plot time/counts
        """
        import datetime
        # Rebin events by pulse time
        try:
            # Get run start
            if wksp.getRun().hasProperty("run_start"):
                runstart = wksp.getRun().getProperty("run_start").value
            elif wksp.getRun().hasProperty("proton_charge"):
                runstart = wksp.getRun().getProperty("proton_charge").times[0]
            else:
                runstart = wksp.getRun().getProperty("start_time").value

            # get run stop
            if wksp.getRun().hasProperty("proton_charge"):
                runstop = wksp.getRun().getProperty("proton_charge").times[-1]
                runstop = str(runstop).split(".")[0].strip()
                tf = datetime.datetime.strptime(runstop, "%Y-%m-%dT%H:%M:%S")
            else:
                last_pulse = wksp.getPulseTimeMax().toISO8601String()
                tf = datetime.datetime.strptime(last_pulse[:19],
                                                "%Y-%m-%dT%H:%M:%S")
                tf += datetime.timedelta(0, wksp.getTofMax() / 1000000)

            runstart = str(runstart).split(".")[0].strip()

            t0 = datetime.datetime.strptime(runstart, "%Y-%m-%dT%H:%M:%S")

            # Calculate
            dt = tf - t0
            timeduration = dt.days * 3600 * 24 + dt.seconds
            timeres = float(timeduration) / MAXTIMEBINSIZE
            if timeres < 1.0:
                timeres = 1.0

            sumwsname = '_Summed_{}'.format(wksp)
            if not AnalysisDataService.doesExist(sumwsname):
                sumws = api.SumSpectra(InputWorkspace=wksp,
                                       OutputWorkspace=sumwsname)
                sumws = api.RebinByPulseTimes(InputWorkspace=sumws,
                                              OutputWorkspace=sumwsname,
                                              Params='{}'.format(timeres))
                sumws = api.ConvertToPointData(InputWorkspace=sumws,
                                               OutputWorkspace=sumwsname)
            else:
                sumws = AnalysisDataService.retrieve(sumwsname)
        except RuntimeError as e:
            return str(e)

        vecx = sumws.readX(0)
        vecy = sumws.readY(0)

        # if there is only one xbin in the summed workspace, that means we have an evetn file without pulse,
        # and in this case we use the original workspace time limits
        if len(vecx) == 1:
            xmin = min(wksp.readX(0)) / 1000000
            xmax = max(wksp.readX(0)) / 1000000
        else:
            xmin = min(vecx)
            xmax = max(vecx)

        ymin = min(vecy)
        ymax = max(vecy)

        # Reset graph
        self.ui.mainplot.set_xlim(xmin, xmax)
        self.ui.mainplot.set_ylim(ymin, ymax)

        self.ui.mainplot.set_xlabel('Time (seconds)', fontsize=13)
        self.ui.mainplot.set_ylabel('Counts', fontsize=13)

        # Set up main line
        setp(self.mainline, xdata=vecx, ydata=vecy)

        # Reset slide
        newslidery = [min(vecy), max(vecy)]

        newleftx = xmin + (xmax - xmin) * self._leftSlideValue * 0.01
        setp(self.leftslideline, xdata=[newleftx, newleftx], ydata=newslidery)

        newrightx = xmin + (xmax - xmin) * self._rightSlideValue * 0.01
        setp(self.rightslideline,
             xdata=[newrightx, newrightx],
             ydata=newslidery)
        self.canvas.draw()
Esempio n. 16
0
    def focus_run(self, sample_paths: list, vanadium_path: str,
                  plot_output: bool, instrument: str, rb_num: str,
                  regions_dict: dict) -> None:
        """
        Focus some data using the current calibration.
        :param sample_paths: The paths to the data to be focused.
        :param vanadium_path: Path to the vanadium file from the current calibration
        :param plot_output: True if the output should be plotted.
        :param instrument: The instrument that the data came from.
        :param rb_num: Number to signify the user who is running this focus
        :param regions_dict: dict region name -> grp_ws_name, defining region(s) of interest to focus over
        """
        full_calib_path = get_setting(
            output_settings.INTERFACES_SETTINGS_GROUP,
            output_settings.ENGINEERING_PREFIX, "full_calibration")
        if not Ads.doesExist("full_inst_calib"):
            try:
                full_calib_workspace = Load(full_calib_path,
                                            OutputWorkspace="full_inst_calib")
            except RuntimeError:
                logger.error(
                    "Error loading Full instrument calibration - this is set in the interface settings."
                )
                return
        else:
            full_calib_workspace = Ads.retrieve("full_inst_calib")
        van_integration_ws, van_processed_inst_ws = vanadium_corrections.fetch_correction_workspaces(
            vanadium_path, instrument)

        # check correct region calibration(s) and grouping workspace(s) exists
        inst_ws = path_handling.load_workspace(sample_paths[0])
        for region in regions_dict:
            calib_exists = self._check_region_calib_ws_exists(region)
            grouping_exists = self._check_region_grouping_ws_exists(
                regions_dict[region], inst_ws)
            if not (calib_exists and grouping_exists):
                return

        # loop over samples provided, focus each over region(s) specified in regions_dict
        output_workspaces = []  # List of collated workspaces to plot.
        self._last_focused_files = []
        van_run_no = path_handling.get_run_number_from_path(
            vanadium_path, instrument)
        for sample_path in sample_paths:
            sample_workspace = path_handling.load_workspace(sample_path)
            run_no = path_handling.get_run_number_from_path(
                sample_path, instrument)
            # perform prefocus operations on whole instrument workspace
            prefocus_success = self._whole_inst_prefocus(
                sample_workspace, van_integration_ws, full_calib_workspace)
            if not prefocus_success:
                continue
            sample_plots = [
            ]  # if both banks focused, pass list with both so plotted on same figure
            for region, grouping_kwarg in regions_dict.items():
                tof_output_name = str(
                    run_no) + "_" + FOCUSED_OUTPUT_WORKSPACE_NAME + region
                dspacing_output_name = tof_output_name + "_dSpacing"
                region_calib_ws = self._get_region_calib_ws(region)
                curves = self._get_van_curves_for_roi(region,
                                                      van_processed_inst_ws,
                                                      grouping_kwarg)
                # perform focus over chosen region of interest
                self._run_focus(sample_workspace, tof_output_name, curves,
                                grouping_kwarg, region_calib_ws)
                sample_plots.append(tof_output_name)
                self._save_output(instrument, run_no, van_run_no, region,
                                  tof_output_name, rb_num)
                self._save_output(instrument,
                                  run_no,
                                  van_run_no,
                                  region,
                                  dspacing_output_name,
                                  rb_num,
                                  unit="dSpacing")
                self._output_sample_logs(instrument, run_no, van_run_no,
                                         sample_workspace, rb_num)
            output_workspaces.append(sample_plots)
            DeleteWorkspace(sample_workspace)
        # remove created grouping workspace if present
        if Ads.doesExist("grp_ws"):
            DeleteWorkspace("grp_ws")
        # Plot the output
        if plot_output:
            for ws_names in output_workspaces:
                self._plot_focused_workspaces(ws_names)