def append_spectrum(single, composite):
    """
    Append a single spectrum to a matrix workspace.
    Caveat to solve: single and composite have different number of bins
    :param single: workspace containing the single new spectrum
    :param composite: workspace matrix containing the processed spectra
    """
    # Find binning triad for the single and composite workspaces
    qs = single.dataX(0)
    qsm, dqs, qsM = qs[0], (qs[-1]-qs[0])/(len(qs)-1), qs[-1]
    qc = composite.dataX(0)
    qcm, dqc, qcM = qc[0], (qc[-1]-qc[0])/(len(qc)-1), qc[-1]
    # Find the biggest range and finer binning
    qmin = qsm if qsm < qcm else qcm
    dq = dqs if dqs < dqc else dqc
    qmax = qsM if qsM < qcM else qcM
    # Rebin when necessary
    delete_single = False
    if [qsm, dqs, qsM] != [qmin, dq, qmax]:
        delete_single = True
        single = Rebin(single, [qmin, dq, qmax])
    if [qcm, dqc, qcM] != [qmin, dq, qmax]:
        composite = Rebin(composite, [qmin, dq, qmax], OutputWorkspace=composite.name())
    composite = AppendSpectra(composite, single, OutputWorkspace=composite.name())
    if delete_single:
        DeleteWorkspace(single)
    return composite
Beispiel #2
0
 def test_isCommonLogBins(self):
     self.assertFalse(self._test_ws.isCommonLogBins())
     ws = CreateSampleWorkspace('Event')
     ws = Rebin(ws, '1,-1,10000')
     self.assertTrue(ws.isCommonLogBins())
     ws = Rebin(ws, '1,-0.1,10000')
     self.assertTrue(ws.isCommonLogBins())
def rebin_reduction(workspace_name, rebin_string, multi_frame_rebin_string, num_bins):
    """
    @param workspace_name Name of workspace to rebin
    @param rebin_string Rebin parameters
    @param multi_frame_rebin_string Rebin string for multiple frame rebinning
    @param num_bins Max number of bins in input frames
    """
    from mantid.simpleapi import (Rebin, RebinToWorkspace, SortXAxis)

    if rebin_string is not None:
        if multi_frame_rebin_string is not None and num_bins is not None:
            # Multi frame data
            if mtd[workspace_name].blocksize() == num_bins:
                Rebin(InputWorkspace=workspace_name,
                      OutputWorkspace=workspace_name,
                      Params=rebin_string)
            else:
                Rebin(InputWorkspace=workspace_name,
                      OutputWorkspace=workspace_name,
                      Params=multi_frame_rebin_string)
        else:
            # Regular data
            SortXAxis(InputWorkspace=workspace_name,
                      OutputWorkspace=workspace_name)
            Rebin(InputWorkspace=workspace_name,
                  OutputWorkspace=workspace_name,
                  Params=rebin_string)
    else:
        try:
            # If user does not want to rebin then just ensure uniform binning across spectra
            RebinToWorkspace(WorkspaceToRebin=workspace_name,
                             WorkspaceToMatch=workspace_name,
                             OutputWorkspace=workspace_name)
        except RuntimeError:
            logger.warning('Rebinning failed, will try to continue anyway.')
    def PyExec(self):
        ws_list = self.getProperty('InputWorkspaces').value
        x_min = self.getProperty('XMin').value
        x_max = self.getProperty('XMax').value
        scale_bool = self.getProperty('CalculateScale').value
        offset_bool = self.getProperty('CalculateOffset').value
        flattened_list = self.unwrap_groups(ws_list)
        largest_range_spectrum, rebin_param = self.get_common_bin_range_and_largest_spectra(flattened_list)
        CloneWorkspace(InputWorkspace=flattened_list[0], OutputWorkspace='ws_conjoined')
        Rebin(InputWorkspace='ws_conjoined', OutputWorkspace='ws_conjoined', Params=rebin_param)
        for ws in flattened_list[1:]:
            temp = CloneWorkspace(InputWorkspace=ws)
            temp = Rebin(InputWorkspace=temp, Params=rebin_param)
            ConjoinWorkspaces(InputWorkspace1='ws_conjoined',
                              InputWorkspace2=temp,
                              CheckOverlapping=False)
        ws_conjoined = AnalysisDataService.retrieve('ws_conjoined')
        ref_spec = ws_conjoined.getSpectrum(largest_range_spectrum).getSpectrumNo()
        ws_conjoined, offset, scale, chisq = MatchSpectra(InputWorkspace=ws_conjoined,
                                                          ReferenceSpectrum=ref_spec,
                                                          CalculateScale=scale_bool,
                                                          CalculateOffset=offset_bool)
        x_min, x_max, bin_width = self.fit_x_lims_to_match_histogram_bins(ws_conjoined, x_min, x_max)

        ws_conjoined = CropWorkspaceRagged(InputWorkspace=ws_conjoined, XMin=x_min, XMax=x_max)
        ws_conjoined = Rebin(InputWorkspace=ws_conjoined, Params=[min(x_min), bin_width, max(x_max)])
        merged_ws = SumSpectra(InputWorkspace=ws_conjoined, WeightedSum=True, MultiplyBySpectra=False, StoreInADS=False)
        DeleteWorkspace(ws_conjoined)
        self.setProperty('OutputWorkspace', merged_ws)
Beispiel #5
0
    def PyExec(self):
        self._setup()
        if self._binning_for_calc.size == 0:
            x = np.array(self._input_ws.readX(self._incident_index))
            self._binning_for_calc = [
                i for i in [min(x), x[1] -
                            x[0], max(x) + x[1] - x[0]]
            ]
        else:
            x = np.arange(self._binning_for_calc[0], self._binning_for_calc[2],
                          self._binning_for_calc[1])
        if self._binning_for_fit.size == 0:
            x_fit = np.array(self._input_ws.readX(self._incident_index))
            y_fit = np.array(self._input_ws.readY(self._incident_index))
        else:
            rebinned = Rebin(InputWorkspace=self._input_ws,
                             Params=self._binning_for_fit,
                             PreserveEvents=True,
                             StoreInADS=False)
            x_fit = np.array(rebinned.readX(self._incident_index))
            y_fit = np.array(rebinned.readY(self._incident_index))

        rebin_norm = x.size / x_fit.size
        x_bin_centers = 0.5 * (x[:-1] + x[1:])
        if len(x_fit) != len(y_fit):
            x_fit = 0.5 * (x_fit[:-1] + x_fit[1:])

        if self._fit_spectrum_with == 'CubicSpline':
            # Fit using cubic spline
            fit, fit_prime = self.fit_cubic_spline(x_fit,
                                                   y_fit,
                                                   x_bin_centers,
                                                   s=1e7)
        elif self._fit_spectrum_with == 'CubicSplineViaMantid':
            # Fit using cubic spline via Mantid
            fit, fit_prime = self.fit_cubic_spline_via_mantid_spline_smoothing(
                self._input_ws,
                params_input=self._binning_for_fit,
                params_output=self._binning_for_calc,
                Error=0.0001,
                MaxNumberOfBreaks=0)
        elif self._fit_spectrum_with == 'GaussConvCubicSpline':
            # Fit using Gauss conv cubic spline
            fit, fit_prime = self.fit_cubic_spline_with_gauss_conv(
                x_fit, y_fit, x_bin_centers, sigma=0.5)

        # Create output workspace
        unit = self._input_ws.getAxis(0).getUnit().unitID()
        output_workspace = CreateWorkspace(DataX=x,
                                           DataY=np.append(fit, fit_prime) /
                                           rebin_norm,
                                           UnitX=unit,
                                           NSpec=2,
                                           Distribution=False,
                                           ParentWorkspace=self._input_ws,
                                           StoreInADS=False)
        self.setProperty("OutputWorkspace", output_workspace)
Beispiel #6
0
def load_and_rebin(runs: List[int],
                   output_workspace: str,
                   rebin_params: List[float],
                   banks: Optional[List[int]] = None) -> Workspace2D:
    r"""
    @brief Load a list of run numbers and rebin

    This function assumes the runs are large and events cannot be all loaded into memory. Hence, a run is loaded
    at a time, rebinned to TOF counts, events are dropped, and counts are added to the cumulative histogram
    resulting from loading the previous runs.

    @param runs : list of run numbers
    @param rebin_params : a triad of first, step, and last. A negative step indicates logarithmic binning
    @param output_workspace : the name of the output `MatrixWorkspace`
    @param banks : list of bank numbers, if one wants to load only certain banks.
    @return handle to the output workspace
    """
    instrument = 'CORELLI'
    kwargs = {} if banks is None else {
        'BankName': ','.join([f'bank{b}' for b in banks])
    }

    # Load the first run
    logger.information(
        f'Loading run {runs[0]}. {len(runs)} runs remaining to be loaded')
    LoadEventNexus(Filename=f'{instrument}_{runs[0]}',
                   OutputWorkspace=output_workspace,
                   LoadLogs=False,
                   **kwargs)
    if rebin_params is not None:
        Rebin(InputWorkspace=output_workspace,
              OutputWorkspace=output_workspace,
              Params=rebin_params,
              PreserveEvents=False)
    # Iteratively load the remaining run, adding to the final workspace each time
    try:
        single_run = '__single_run_' + output_workspace
        for i, run in enumerate(runs[1:]):
            logger.information(
                f'Loading run {run}. {len(runs) - 1 - i} runs remaining to be loaded'
            )
            LoadEventNexus(Filename=f'{instrument}_{run}',
                           OutputWorkspace=single_run,
                           LoadLogs=False,
                           **kwargs)
            if rebin_params is not None:
                Rebin(InputWorkspace=single_run,
                      OutputWorkspace=single_run,
                      Params=rebin_params,
                      PreserveEvents=False)
            Plus(LHSWorkspace=output_workspace,
                 RHSWorkspace=single_run,
                 OutputWorkspace=output_workspace)
            DeleteWorkspace(single_run)  # save memory as quick as possible
    except RuntimeError:
        DeleteWorkspace(single_run)  # a bit of clean-up
    return mtd[output_workspace]
Beispiel #7
0
def handle_saving_event_workspace_when_saving_as_histogram(binning, runs, def_type, inst):
    ws_in_monitor = mtd[ADD_FILES_SUM_TEMPORARY_MONITORS]
    if binning == 'Monitors':
        mon_x = ws_in_monitor.dataX(0)
        binning = str(mon_x[0])
        bin_gap = mon_x[1] - mon_x[0]
        binning = binning + "," + str(bin_gap)
        for j in range(2, len(mon_x)):
            next_bin_gap = mon_x[j] - mon_x[j-1]
            if next_bin_gap != bin_gap:
                bin_gap = next_bin_gap
                binning = binning + "," + str(mon_x[j-1]) + "," + str(bin_gap)
        binning = binning + "," + str(mon_x[len(mon_x)-1])

    sanslog.notice(binning)
    Rebin(InputWorkspace=ADD_FILES_SUM_TEMPORARY, OutputWorkspace='AddFilesSumTemporary_Rebin', Params=binning,
          PreserveEvents=False)

    # loading the nexus file using LoadNexus is necessary because it has some metadata
    # that is not in LoadEventNexus. This must be fixed.
    filename, ext = _make_filename(runs[0], def_type, inst)
    workspace_type = get_workspace_type(filename)
    if workspace_type is WorkspaceType.MultiperiodEvent:
        # If we are dealing with multi-period event workspaces then there is no way of getting any other
        # sample log information hence we use make a copy of the monitor workspace and use that instead
        # of the reloading the first file again
        CloneWorkspace(InputWorkspace=ADD_FILES_SUM_TEMPORARY_MONITORS, OutputWorkspace=ADD_FILES_SUM_TEMPORARY)
    else:
        LoadNexus(Filename=filename, OutputWorkspace=ADD_FILES_SUM_TEMPORARY,
                  SpectrumMax=ws_in_monitor.getNumberHistograms())
    # User may have selected a binning which is different from the default
    Rebin(InputWorkspace=ADD_FILES_SUM_TEMPORARY, OutputWorkspace=ADD_FILES_SUM_TEMPORARY, Params=binning)
    # For now the monitor binning must be the same as the detector binning
    # since otherwise both cannot exist in the same output histogram file
    Rebin(InputWorkspace=ADD_FILES_SUM_TEMPORARY_MONITORS, OutputWorkspace=ADD_FILES_SUM_TEMPORARY_MONITORS,
          Params=binning)

    ws_in_monitor = mtd[ADD_FILES_SUM_TEMPORARY_MONITORS]
    wsOut = mtd[ADD_FILES_SUM_TEMPORARY]
    ws_in_detector = mtd['AddFilesSumTemporary_Rebin']

    # We loose added sample log information since we reload a single run workspace
    # and conjoin with the added workspace. In order to preserve some added sample
    # logs we need to transfer them at this point
    transfer_special_sample_logs(from_ws=ws_in_detector, to_ws=wsOut)

    mon_n = ws_in_monitor.getNumberHistograms()
    for i in range(mon_n):
        wsOut.setY(i, ws_in_monitor.dataY(i))
        wsOut.setE(i, ws_in_monitor.dataE(i))
    ConjoinWorkspaces(wsOut, ws_in_detector, CheckOverlapping=True)

    if 'AddFilesSumTemporary_Rebin' in mtd:
        DeleteWorkspace('AddFilesSumTemporary_Rebin')
 def _create_flat_background_test_workspace(workspace_name):
     LoadNexusProcessed(Filename="LOQ48127", OutputWorkspace=workspace_name)
     workspace = AnalysisDataService.retrieve(workspace_name)
     # Rebin to only have four values at 11, 31, 51, 70.5
     workspace = Rebin(workspace, "1,20,80")
     # For each spectrum we set the first two entries to 2 and the other two entries to 4.
     for index in range(workspace.getNumberHistograms()):
         data_y = workspace.dataY(index)
         data_y[0] = 2.
         data_y[1] = 2.
         data_y[2] = 4.
         data_y[3] = 4.
     return workspace
    def _prepare_workspace(workspace, data=None):
        """
        Creates a test monitor workspace with 4 bins
        """
        workspace = Rebin(InputWorkspace=workspace, Params="5000, 5000, 25000", OutputWorkspace=workspace)

        # Now set specified monitors to specified values
        if data is not None:
            for key, value in list(data.items()):
                data_y = workspace.dataY(key)
                for index in range(len(data_y)):
                    data_y[index] = value[index]
        return workspace
Beispiel #10
0
 def _create_flat_background_test_workspace(workspace_name):
     LoadNexusProcessed(Filename="LOQ48127", OutputWorkspace=workspace_name)
     workspace = AnalysisDataService.retrieve(workspace_name)
     # Rebin to only have four values at 11, 31, 51, 70.5
     workspace = Rebin(workspace, "1,20,80")
     # For each spectrum we set the first two entries to 2 and the other two entries to 4.
     for index in range(workspace.getNumberHistograms()):
         data_y = workspace.dataY(index)
         data_y[0] = 2.
         data_y[1] = 2.
         data_y[2] = 4.
         data_y[3] = 4.
     return workspace
Beispiel #11
0
 def _prepare_trans_data(self, ws, value):
     rebin_string = "{0}, {1}, {2}".format(self.test_tof_min,
                                           self.test_tof_width,
                                           self.test_tof_max)
     ws = Rebin(InputWorkspace=ws, Params=rebin_string, StoreInADS=False)
     # Set all entries to value
     for hist in range(ws.getNumberHistograms()):
         data_y = ws.dataY(hist)
         for index in range(len(data_y)):
             data_y[index] = value
         # This will be the background bin
         data_y[0] = 0.1
     return ws
Beispiel #12
0
def rebin_reduction(workspace_name, rebin_string, multi_frame_rebin_string,
                    num_bins):
    """
    @param workspace_name Name of workspace to rebin
    @param rebin_string Rebin parameters
    @param multi_frame_rebin_string Rebin string for multiple frame rebinning
    @param num_bins Max number of bins in input frames
    """
    from mantid.simpleapi import (Rebin, SortXAxis, RemoveSpectra)

    if rebin_string is not None:
        if multi_frame_rebin_string is not None and num_bins is not None:
            # Multi frame data
            if mtd[workspace_name].blocksize() == num_bins:
                Rebin(InputWorkspace=workspace_name,
                      OutputWorkspace=workspace_name,
                      Params=rebin_string)
            else:
                Rebin(InputWorkspace=workspace_name,
                      OutputWorkspace=workspace_name,
                      Params=multi_frame_rebin_string)
        else:
            # Regular data
            RemoveSpectra(InputWorkspace=workspace_name,
                          OutputWorkspace=workspace_name,
                          RemoveSpectraWithNoDetector=True)
            SortXAxis(InputWorkspace=workspace_name,
                      OutputWorkspace=workspace_name)
            Rebin(InputWorkspace=workspace_name,
                  OutputWorkspace=workspace_name,
                  Params=rebin_string)
    else:
        try:
            # If user does not want to rebin then just ensure uniform binning across spectra
            # extract the binning parameters from the first spectrum.
            # there is probably a better way to calculate the binning parameters, but this
            # gets the right answer.
            xaxis = mtd[workspace_name].readX(0)
            params = []
            for i, x in enumerate(xaxis):
                params.append(x)
                if i < len(xaxis) - 1:
                    params.append(xaxis[i + 1] - x)  # delta
            Rebin(InputWorkspace=workspace_name,
                  OutputWorkspace=workspace_name,
                  Params=params)
        except RuntimeError:
            logger.warning('Rebinning failed, will try to continue anyway.')
Beispiel #13
0
def _create_single_test_workspace(fwhm, output_name, i):
    function = "name=Lorentzian,Amplitude=100,PeakCentre=27500,FWHM=" + str(
        fwhm)

    CreateSampleWorkspace(Function='User Defined',
                          UserDefinedFunction=function,
                          XMin=27000,
                          XMax=28000,
                          BinWidth=10,
                          NumBanks=1,
                          OutputWorkspace=output_name)
    ConvertUnits(InputWorkspace=output_name,
                 OutputWorkspace=output_name,
                 Target='DeltaE',
                 EMode='Indirect',
                 EFixed=1.5)
    Rebin(InputWorkspace=output_name,
          OutputWorkspace=output_name,
          Params=[-0.2, 0.004, 0.2])
    LoadInstrument(Workspace=output_name,
                   InstrumentName='IRIS',
                   RewriteSpectraMap=True)
    SetInstrumentParameter(Workspace=output_name,
                           ParameterName='Efixed',
                           DetectorList=range(1, 113),
                           ParameterType='Number',
                           Value='1.5')

    output = AnalysisDataService.retrieve(output_name)
    output.mutableRun()['run_number'] = i + 1
    output.mutableRun()['sample'] = [1, 2, 3]
    output.mutableRun()['sample'].units = " "
Beispiel #14
0
    def _apply_corrections(self, w, target='sample'):
        """
        Apply a series of corrections and normalizations to the input
        workspace

        Parameters
        ----------
        w: Mantid.EventsWorkspace
            Input workspace
        target: str
            Specify the entity the workspace refers to. Valid options are
            'sample', 'background', and 'vanadium'

        Returns
        -------
        Mantid.EventsWorkspace
        """
        MaskDetectors(w, MaskedWorkspace=self._t_mask)
        _t_corr = ModeratorTzeroLinear(w)  # delayed emission from moderator
        _t_corr = self.add_previous_pulse(_t_corr)
        _t_corr = ConvertUnits(_t_corr, Target='Wavelength', Emode='Elastic')
        l_s, l_e = self._wavelength_band[0], self._wavelength_band[1]
        _t_corr = CropWorkspace(_t_corr, XMin=l_s, XMax=l_e)
        _t_corr = Rebin(_t_corr,
                        Params=[l_s, self._wavelength_dl, l_e],
                        PreserveEvents=False)
        if self.getProperty('MonitorNormalization').value is True:
            _t_corr = self._monitor_normalization(_t_corr, target)
        return _t_corr
Beispiel #15
0
    def _calculate_wavelength_band(self):
        """
        Calculate the wavelength band using the monitors from the sample runs

        Consider wavelenghts with an associated intensity above a certain
        fraction of the maximum observed intensity.
        """
        _t_w = self._load_monitors('sample')
        _t_w = ConvertUnits(_t_w, Target='Wavelength', Emode='Elastic')
        l_min, l_max = 0.0, 20.0
        _t_w = CropWorkspace(_t_w, XMin=l_min, XMax=l_max)
        _t_w = OneMinusExponentialCor(_t_w,
                                      C='0.20749999999999999',
                                      C1='0.001276')
        _t_w = Scale(_t_w, Factor='1e-06', Operation='Multiply')
        _t_w = Rebin(_t_w,
                     Params=[l_min, self._wavelength_dl, l_max],
                     PreserveEvents=False)
        y = _t_w.readY(0)
        k = np.argmax(y)  # y[k] is the maximum observed intensity
        factor = 0.8  # 80% of the maximum intensity
        i_s = k - 1
        while y[i_s] > factor * y[k]:
            i_s -= 1
        i_e = k + 1
        while y[i_e] > factor * y[k]:
            i_e += 1
        x = _t_w.readX(0)
        self._wavelength_band = [x[i_s], x[i_e]]
 def runTest(self):
     flood = CreateFloodWorkspace('OFFSPEC00035946.nxs', StartSpectrum=250, EndSpectrum=600,
                                  ExcludeSpectra=[260, 261, 262, 516, 517, 518], OutputWorkspace='flood')
     data = Load('OFFSPEC00044998.nxs')
     data = Rebin(data, [0,1000,100000], PreserveEvents=False)
     data = ConvertUnits(data, 'Wavelength')
     ApplyFloodWorkspace(InputWorkspace=data, FloodWorkspace=flood, OutputWorkspace=self.out_ws_name)
Beispiel #17
0
def _rebin(ws, params, wsNames, algorithmLogging):
    """Rebin a workspace."""
    rebinnedWSName = wsNames.withSuffix('rebinned')
    rebinnedWS = Rebin(InputWorkspace=ws,
                       OutputWorkspace=rebinnedWSName,
                       Params=params,
                       EnableLogging=algorithmLogging)
    return rebinnedWS
def save_reduction(workspace_names, formats, x_units='DeltaE'):
    """
    Saves the workspaces to the default save directory.

    @param workspace_names List of workspace names to save
    @param formats List of formats to save in
    @param x_units X units
    """
    from mantid.simpleapi import (SaveSPE, SaveNexusProcessed, SaveNXSPE,
                                  SaveAscii, Rebin, DeleteWorkspace,
                                  ConvertSpectrumAxis, SaveDaveGrp)

    for workspace_name in workspace_names:
        if 'spe' in formats:
            SaveSPE(InputWorkspace=workspace_name,
                    Filename=workspace_name + '.spe')

        if 'nxs' in formats:
            SaveNexusProcessed(InputWorkspace=workspace_name,
                               Filename=workspace_name + '.nxs')

        if 'nxspe' in formats:
            SaveNXSPE(InputWorkspace=workspace_name,
                      Filename=workspace_name + '.nxspe')

        if 'ascii' in formats:

            # Changed to version 2 to enable re-loading of files into mantid
            saveAsciiAlg = AlgorithmManager.createUnmanaged('SaveAscii', 2)
            saveAsciiAlg.initialize()
            saveAsciiAlg.setProperty('InputWorkspace', workspace_name)
            saveAsciiAlg.setProperty('Filename', workspace_name + '.dat')
            saveAsciiAlg.execute()

        if 'aclimax' in formats:
            if x_units == 'DeltaE_inWavenumber':
                bins = '24, -0.005, 4000'  #cm-1
            else:
                bins = '3, -0.005, 500'  #meV

            Rebin(InputWorkspace=workspace_name,
                  OutputWorkspace=workspace_name + '_aclimax_save_temp',
                  Params=bins)
            SaveAscii(InputWorkspace=workspace_name + '_aclimax_save_temp',
                      Filename=workspace_name + '_aclimax.dat',
                      Separator='Tab')
            DeleteWorkspace(Workspace=workspace_name + '_aclimax_save_temp')

        if 'davegrp' in formats:
            ConvertSpectrumAxis(InputWorkspace=workspace_name,
                                OutputWorkspace=workspace_name +
                                '_davegrp_save_temp',
                                Target='ElasticQ',
                                EMode='Indirect')
            SaveDaveGrp(InputWorkspace=workspace_name + '_davegrp_save_temp',
                        Filename=workspace_name + '.grp')
            DeleteWorkspace(Workspace=workspace_name + '_davegrp_save_temp')
Beispiel #19
0
 def setUp(self) -> None:
     r"""Fixture runs at the beginning of every test method"""
     spacings_reference = [
         0.9179, 0.9600, 1.0451, 1.2458, 1.3576, 1.5677, 1.6374, 3.1353
     ]  # silicon
     # add one Gaussian peak for every reference d-spacing
     peak_functions = list()
     for spacing in spacings_reference:
         peak_function = f'name=Gaussian, PeakCentre={spacing}, Height={10 * np.sqrt(spacing)}, Sigma={0.003 * spacing}'
         peak_functions.append(peak_function)
     function = ';'.join(peak_functions)
     begin, end, bin_width = spacings_reference[
         0] - 0.5, spacings_reference[-1] + 0.5, 0.0001
     # Single 10x10 rectangular detector, located 4m downstream the sample along the X-axis
     # Each detector has the same histogram of intensities, showing eight Gaussian peaks with centers at the
     # reference d-spacings
     CreateSampleWorkspace(WorkspaceType='Histogram',
                           Function='User Defined',
                           UserDefinedFunction=function,
                           XUnit='dSpacing',
                           XMin=begin,
                           XMax=end,
                           BinWidth=bin_width,
                           NumBanks=1,
                           PixelSpacing=0.02,
                           SourceDistanceFromSample=10.0,
                           BankDistanceFromSample=4.0,
                           OutputWorkspace='test_workspace_dSpacing')
     RotateInstrumentComponent(Workspace='test_workspace_dSpacing',
                               ComponentName='bank1',
                               X=0.,
                               Y=1.,
                               z=0.,
                               Angle=90,
                               RelativeRotation=True)
     MoveInstrumentComponent(Workspace='test_workspace_dSpacing',
                             ComponentName='bank1',
                             X=4.0,
                             y=0.0,
                             z=0.0,
                             RelativePosition=False)
     # Eight peaks now in TOF. Only when the instrument is located 4m downstream along the X-axis will we obtain
     # the correct d-Spacings if we convert back to dSpacings units. If we perturb the instrument and convert
     # back to dSpacing units, we'll obtain eight peaks centered at d-spacings sligthly different than the
     # reference values
     ConvertUnits(InputWorkspace='test_workspace_dSpacing',
                  Target='TOF',
                  EMode='Elastic',
                  OutputWorkspace='test_workspace_TOF')
     Rebin(InputWorkspace='test_workspace_TOF',
           Params=[300, 1.0, 16666.7],
           OutputWorkspace='test_workspace_TOF')
     ConvertUnits(InputWorkspace='test_workspace_TOF',
                  Target='dSpacing',
                  EMode='Elastic',
                  OutputWorkspace='test_workspace_dSpacing')
     self.spacings_reference = spacings_reference
def GetIncidentSpectrumFromMonitor(Filename,
                                   OutputWorkspace="IncidentWorkspace",
                                   IncidentIndex=0,
                                   TransmissionIndex=1,
                                   Binning=".1,6000,2.9",
                                   BinType="ResampleX"):

    # -------------------------------------------------
    # Joerg's read_bm.pro code

    # Loop workspaces to get each incident spectrum
    monitor = 'monitor'
    LoadNexusMonitors(Filename=Filename, OutputWorkspace=monitor)
    ConvertUnits(InputWorkspace=monitor,
                 OutputWorkspace=monitor,
                 Target='Wavelength',
                 EMode='Elastic')
    lambdaMin, lambdaBinning, lambdaMax = [
        float(x) for x in Binning.split(',')
    ]
    for x in [lambdaMin, lambdaBinning, lambdaMax]:
        print(x, type(x))
    if BinType == 'ResampleX':
        ResampleX(
            InputWorkspace=monitor,
            OutputWorkspace=monitor,
            XMin=[lambdaMin],  # TODO change ResampleX
            XMax=[lambdaMax],
            NumberBins=abs(int(lambdaBinning)),
            LogBinning=(int(lambdaBinning) < 0),
            PreserveEvents=True)
    elif BinType == 'Rebin':
        Rebin(InputWorkspace=monitor,
              OutputWorkspace=monitor,
              Params=[lambdaMin, lambdaBinning, lambdaMax],
              PreserveEvents=True)
    ConvertToPointData(InputWorkspace=monitor, OutputWorkspace=monitor)

    lam = mtd[monitor].readX(IncidentIndex)  # wavelength in A
    bm = mtd[monitor].readY(IncidentIndex)  # neutron counts / microsecond
    p = 0.000794807  # Pressure
    thickness = .1  # 1 mm = .1 cm
    abs_xs_3He = 5333.0  # barns for lambda == 1.798 A
    p_to_rho = 2.43e-5  # pressure to rho (atoms/angstroms^3)
    # p is set to give efficiency of 1.03 10^-5 at 1.8 A
    e0 = abs_xs_3He * lam / 1.798 * p_to_rho * p * thickness
    print('Efficiency:', 1. - np.exp(-e0))
    bmeff = bm / (1. - np.exp(-e0))  # neutron counts / microsecond
    print(bmeff)
    # bmeff = bmeff / constants.micro      # neutron counts / second

    CreateWorkspace(DataX=lam,
                    DataY=bmeff,
                    OutputWorkspace=OutputWorkspace,
                    UnitX='Wavelength')
    mtd[OutputWorkspace].setYUnit('Counts')
    return mtd[OutputWorkspace]
Beispiel #21
0
def save_reduction(worksspace_names, formats, x_units='DeltaE'):
    """
    Saves the workspaces to the default save directory.

    @param worksspace_names List of workspace names to save
    @param formats List of formats to save in
    @param Output X units
    """
    from mantid.simpleapi import (SaveSPE, SaveNexusProcessed, SaveNXSPE,
                                  SaveAscii, Rebin, DeleteWorkspace,
                                  ConvertSpectrumAxis, SaveDaveGrp)

    for workspace_name in worksspace_names:
        if 'spe' in formats:
            SaveSPE(InputWorkspace=workspace_name,
                    Filename=workspace_name + '.spe')

        if 'nxs' in formats:
            SaveNexusProcessed(InputWorkspace=workspace_name,
                               Filename=workspace_name + '.nxs')

        if 'nxspe' in formats:
            SaveNXSPE(InputWorkspace=workspace_name,
                      Filename=workspace_name + '.nxspe')

        if 'ascii' in formats:
            # Version 1 of SaveAscii produces output that works better with excel/origin
            # For some reason this has to be done with an algorithm object, using the function
            # wrapper with Version did not change the version that was run
            saveAsciiAlg = AlgorithmManager.createUnmanaged('SaveAscii', 1)
            saveAsciiAlg.initialize()
            saveAsciiAlg.setProperty('InputWorkspace', workspace_name)
            saveAsciiAlg.setProperty('Filename', workspace_name + '.dat')
            saveAsciiAlg.execute()

        if 'aclimax' in formats:
            if x_units == 'DeltaE_inWavenumber':
                bins = '24, -0.005, 4000' #cm-1
            else:
                bins = '3, -0.005, 500' #meV

            Rebin(InputWorkspace=workspace_name,
                  OutputWorkspace=workspace_name + '_aclimax_save_temp',
                  Params=bins)
            SaveAscii(InputWorkspace=workspace_name + '_aclimax_save_temp',
                      Filename=workspace_name + '_aclimax.dat',
                      Separator='Tab')
            DeleteWorkspace(Workspace=workspace_name + '_aclimax_save_temp')

        if 'davegrp' in formats:
            ConvertSpectrumAxis(InputWorkspace=workspace_name,
                                OutputWorkspace=workspace_name + '_davegrp_save_temp',
                                Target='ElasticQ',
                                EMode='Indirect')
            SaveDaveGrp(InputWorkspace=workspace_name + '_davegrp_save_temp',
                        Filename=workspace_name + '.grp')
            DeleteWorkspace(Workspace=workspace_name + '_davegrp_save_temp')
    def PyExec(self):
        self._setup()
        if not self.getProperty("InputWorkspace").isDefault:
            self._output_ws = CloneWorkspace(Inputworkspace=self._input_ws,
                                             OutputWorkspace=self._output_ws,
                                             StoreInADS=False)
        else:
            self._output_ws = CreateWorkspace(NSpec=1, DataX=[0], DataY=[0],
                                              UnitX='Wavelength', Distribution=False,
                                              StoreInADS=False)
            self._output_ws = Rebin(InputWorkspace=self._output_ws,
                                    Params=self._bin_params,
                                    StoreInADS=False)

        if self._output_ws.isDistribution():
            ConvertFromDistribution(Workspace=self._output_ws,
                                    StoreInADS=False)

        self._output_ws = ConvertToPointData(InputWorkspace=self._output_ws,
                                             StoreInADS=False)
        self._output_ws = ConvertUnits(InputWorkspace=self._output_ws,
                                       Target='Wavelength',
                                       EMode='Elastic',
                                       StoreInADS=False)

        if self.getProperty('Alpha').isDefault:
            if self._density_type == 'Mass Density':
                SetSampleMaterial(
                    InputWorkspace=self._output_ws,
                    ChemicalFormula=self._chemical_formula,
                    SampleMassDensity=self._density,
                    StoreInADS=False)
                self._density = self._output_ws.sample().getMaterial().numberDensityEffective
            elif self._density_type == 'Number Density':
                SetSampleMaterial(
                    InputWorkspace=self._output_ws,
                    ChemicalFormula=self._chemical_formula,
                    SampleNumberDensity=self._density,
                    StoreInADS=False)
            else:
                raise RuntimeError(f'Unknown "DensityType": {self._density_type}')
            if self.getProperty('MeasuredEfficiency').isDefault:
                self._calculate_area_density_from_density()
            else:
                self._calculate_area_density_from_efficiency()
            self._calculate_alpha_absXS_term()
            if self._xsection_type == "TotalXSection":
                self._calculate_alpha_scatXS_term()

        wavelengths = self._output_ws.readX(0)
        efficiency = self._calculate_efficiency(wavelengths)
        for histo in range(self._output_ws.getNumberHistograms()):
            self._output_ws.setY(histo, efficiency)

        self.setProperty('OutputWorkspace', self._output_ws)
def fitCubicSplineViaMantidSplineSmoothing(InputWorkspace, Params, **kwargs):
    Rebin(InputWorkspace=InputWorkspace,
          OutputWorkspace='fit',
          Params=Params,
          PreserveEvents=True)
    SplineSmoothing(InputWorkspace='fit',
                    OutputWorkspace='fit',
                    OutputWorkspaceDeriv='fit_prime',
                    DerivOrder=1,
                    **kwargs)
    return mtd['fit'].readY(0), mtd['fit_prime_1'].readY(0)
Beispiel #24
0
def append_spectrum(single, composite):
    """
    Append a single spectrum to a matrix workspace.
    Caveat to solve: single and composite have different number of bins
    :param single: workspace containing the single new spectrum
    :param composite: workspace matrix containing the processed spectra
    """
    # Find binning triad for the single and composite workspaces
    qs = single.dataX(0)
    qsm, dqs, qsM = qs[0], (qs[-1] - qs[0]) / (len(qs) - 1), qs[-1]
    qc = composite.dataX(0)
    qcm, dqc, qcM = qc[0], (qc[-1] - qc[0]) / (len(qc) - 1), qc[-1]
    # Find the biggest range and finer binning
    qmin = qsm if qsm < qcm else qcm
    dq = dqs if dqs < dqc else dqc
    qmax = qsM if qsM < qcM else qcM
    # Rebin when necessary
    delete_single = False
    if [qsm, dqs, qsM] != [qmin, dq, qmax]:
        delete_single = True
        single = Rebin(single, [qmin, dq, qmax])
    if [qcm, dqc, qcM] != [qmin, dq, qmax]:
        composite = Rebin(composite, [qmin, dq, qmax],
                          OutputWorkspace=composite.name())
    composite = AppendSpectra(composite,
                              single,
                              OutputWorkspace=composite.name())
    if delete_single:
        DeleteWorkspace(single)
    return composite
Beispiel #25
0
def save_reduction(workspace_names, formats, x_units='DeltaE'):
    """
    Saves the workspaces to the default save directory.

    @param workspace_names List of workspace names to save
    @param formats List of formats to save in
    @param x_units X units
    """
    from mantid.simpleapi import (SaveSPE, SaveNexusProcessed, SaveNXSPE,
                                  SaveAscii, Rebin, DeleteWorkspace,
                                  ConvertSpectrumAxis, SaveDaveGrp)

    for workspace_name in workspace_names:
        if 'spe' in formats:
            SaveSPE(InputWorkspace=workspace_name,
                    Filename=workspace_name + '.spe')

        if 'nxs' in formats:
            SaveNexusProcessed(InputWorkspace=workspace_name,
                               Filename=workspace_name + '.nxs')

        if 'nxspe' in formats:
            SaveNXSPE(InputWorkspace=workspace_name,
                      Filename=workspace_name + '.nxspe')

        if 'ascii' in formats:
            _save_ascii(workspace_name, workspace_name + ".dat")

        if 'aclimax' in formats:
            if x_units == 'DeltaE_inWavenumber':
                bins = '24, -0.005, 4000'  # cm-1
            else:
                bins = '3, -0.005, 500'  # meV

            Rebin(InputWorkspace=workspace_name,
                  OutputWorkspace=workspace_name + '_aclimax_save_temp',
                  Params=bins)
            SaveAscii(InputWorkspace=workspace_name + '_aclimax_save_temp',
                      Filename=workspace_name + '_aclimax.dat',
                      Separator='Tab')
            DeleteWorkspace(Workspace=workspace_name + '_aclimax_save_temp')

        if 'davegrp' in formats:
            ConvertSpectrumAxis(InputWorkspace=workspace_name,
                                OutputWorkspace=workspace_name +
                                '_davegrp_save_temp',
                                Target='ElasticQ',
                                EMode='Indirect')
            SaveDaveGrp(InputWorkspace=workspace_name + '_davegrp_save_temp',
                        Filename=workspace_name + '.grp')
            DeleteWorkspace(Workspace=workspace_name + '_davegrp_save_temp')
 def _create_event_workspace(self,
                             run_number,
                             prefix='',
                             includeMonitors=True):
     name = prefix + str(run_number)
     CreateSampleWorkspace(WorkspaceType='Event',
                           NumBanks=1,
                           NumMonitors=3,
                           BankPixelWidth=2,
                           XMin=200,
                           OutputWorkspace=name)
     if includeMonitors:
         CropWorkspace(InputWorkspace=name,
                       StartWorkspaceIndex=0,
                       EndWorkspaceIndex=2,
                       OutputWorkspace=name + '_monitors')
         Rebin(InputWorkspace=name + '_monitors',
               Params='0,200,20000',
               OutputWorkspace=name + '_monitors',
               PreserveEvents=False)
     CropWorkspace(InputWorkspace=name,
                   StartWorkspaceIndex=3,
                   EndWorkspaceIndex=4,
                   OutputWorkspace=name)
     AddSampleLog(Workspace=name,
                  LogName='run_number',
                  LogText=str(run_number))
     AddTimeSeriesLog(Workspace=name,
                      Name="proton_charge",
                      Time="2010-01-01T00:00:00",
                      Value=100)
     AddTimeSeriesLog(Workspace=name,
                      Name="proton_charge",
                      Time="2010-01-01T00:10:00",
                      Value=100)
     AddTimeSeriesLog(Workspace=name,
                      Name="proton_charge",
                      Time="2010-01-01T00:20:00",
                      Value=80)
     AddTimeSeriesLog(Workspace=name,
                      Name="proton_charge",
                      Time="2010-01-01T00:30:00",
                      Value=80)
     AddTimeSeriesLog(Workspace=name,
                      Name="proton_charge",
                      Time="2010-01-01T00:40:00",
                      Value=15)
     AddTimeSeriesLog(Workspace=name,
                      Name="proton_charge",
                      Time="2010-01-01T00:50:00",
                      Value=100)
def FitIncidentSpectrum(InputWorkspace,
                        OutputWorkspace,
                        FitSpectrumWith='GaussConvCubicSpline',
                        BinningForFit="0.15,0.05,3.2",
                        BinningForCalc=None,
                        PlotDiagnostics=False):

    incident_ws = mtd[InputWorkspace]

    # Fit Incident Spectrum
    # Get axis for actual calc (either provided in BinningForCalc or extracted
    # from incident wksp)
    incident_index = 0
    if BinningForCalc is None:
        x = incident_ws.readX(incident_index)
    else:
        try:
            params = [float(x) for x in BinningForCalc.split(',')]
        except AttributeError:
            params = [float(x) for x in BinningForCalc]
        xlo, binsize, xhi = params
        x = np.arange(xlo, xhi, binsize)

    Rebin(incident_ws,
          OutputWorkspace='fit',
          Params=BinningForFit,
          PreserveEvents=True)
    x_fit = np.array(mtd['fit'].readX(incident_index))
    y_fit = np.array(mtd['fit'].readY(incident_index))

    if FitSpectrumWith == 'CubicSpline':
        fit, fit_prime = fitCubicSpline(x_fit, y_fit, x, s=1e7)
    elif FitSpectrumWith == 'CubicSplineViaMantid':
        fit, fit_prime = fitCubicSplineViaMantidSplineSmoothing(
            InputWorkspace, Params=BinningForFit, MaxNumberOfBreaks=8)
    elif FitSpectrumWith == 'HowellsFunction':
        fit, fit_prime = fitHowellsFunction(x_fit, y_fit, x)
    elif FitSpectrumWith == 'GaussConvCubicSpline':
        fit, fit_prime = fitCubicSplineWithGaussConv(x_fit, y_fit, x, sigma=2)
    else:
        raise Exception("Unknown method for fitting incident spectrum")
        return

    CreateWorkspace(DataX=x,
                    DataY=np.append(fit, fit_prime),
                    OutputWorkspace=OutputWorkspace,
                    UnitX='Wavelength',
                    NSpec=2,
                    Distribution=False)
    return mtd[OutputWorkspace]
Beispiel #28
0
def extract_cuts_matrix(workspace: MatrixWorkspace,
                        xmin: float,
                        xmax: float,
                        ymin: float,
                        ymax: float,
                        xcut_name: str,
                        ycut_name: str,
                        log_algorithm_calls: bool = True):
    """
    Assuming a MatrixWorkspace with vertical numeric axis, extract 1D cuts from the region defined
    by the given parameters
    :param workspace: A MatrixWorkspace with a vertical NumericAxis
    :param xmin: X min for bounded region
    :param xmax: X max for bounded region
    :param ymin: Y min for bounded region
    :param ymax: Y max for bounded region
    :param xcut_name: Name of the X cut. Empty indicates it should be skipped
    :param ycut_name: Name of the Y cut. Empty indicates it should be skipped
    :param log_algorithm_calls: Log the algorithm call or be silent
    """
    tmp_crop_region = '__tmp_sv_region_extract'
    transpose = False
    roi = extract_roi_matrix(workspace, xmin, xmax, ymin, ymax, transpose,
                             tmp_crop_region, log_algorithm_calls)

    # perform ycut first so xcut can reuse tmp workspace for rebinning if necessary
    if ycut_name:
        Rebin(InputWorkspace=roi,
              OutputWorkspace=ycut_name,
              Params=[xmin, xmax - xmin, xmax],
              EnableLogging=log_algorithm_calls)
        Transpose(InputWorkspace=ycut_name,
                  OutputWorkspace=ycut_name,
                  EnableLogging=log_algorithm_calls)

    if xcut_name:
        if not roi.isCommonBins():
            # rebin to a common grid using the resolution from the spectrum
            # with the lowest resolution to avoid overbinning
            roi = _rebin_to_common_grid(roi, xmin, xmax, log_algorithm_calls)
        SumSpectra(InputWorkspace=roi,
                   OutputWorkspace=xcut_name,
                   EnableLogging=log_algorithm_calls)

    try:
        DeleteWorkspace(tmp_crop_region, EnableLogging=log_algorithm_calls)
    except ValueError:
        pass
Beispiel #29
0
    def _convert_to_q(self, w):
        """
        Convert to momentum transfer with the desired binning

        Parameters
        ----------
        w: Mantid.MatrixWorkspace2D

        Returns
        -------
        Mantid.MatrixWorkspace2D
        """
        _t_w = ConvertUnits(w, Target='MomentumTransfer', Emode='Elastic')
        _t_w = Rebin(_t_w, Params=self._qbins, PreserveEvents=False)
        _t_w = SumSpectra(_t_w, OutputWorkspace=w.name())
        return _t_w
Beispiel #30
0
    def _alignAndFocus(self, params, calib, cal_File, group):
        # loading the ISAW detcal file will override the default instrument
        if calib == 'DetCal File':
            LoadIsawDetCal(InputWorkspace='WS', Filename=cal_File)

        if calib in ['Convert Units', 'DetCal File']:
            ConvertUnits(InputWorkspace='WS',
                         Target='dSpacing', OutputWorkspace='WS_d')
        else:
            self.log().notice("\n calibration file : %s" % cal_File)
            AlignDetectors(InputWorkspace='WS', CalibrationFile=cal_File,
                           Outputworkspace='WS_d')

        Rebin(InputWorkspace='WS_d', Params=params, Outputworkspace='WS_d')

        DiffractionFocussing(InputWorkspace='WS_d', GroupingWorkspace=group,
                             PreserveEvents=False, OutputWorkspace='WS_red')
Beispiel #31
0
    def _apply_corrections(self, w, target='sample'):
        """
        Apply a series of corrections and normalizations to the input
        workspace

        Parameters
        ----------
        w: Mantid.EventsWorkspace
            Input workspace
        target: str
            Specify the entity the workspace refers to. Valid options are
            'sample', 'background', and 'vanadium'

        Returns
        -------
        Mantid.EventsWorkspace
        """
        MaskDetectors(w, MaskedWorkspace=self._t_mask)
        local_name = tws('corr')
        _t_corr = ModeratorTzeroLinear(w,
                                       Gradient=self._tzero['gradient'],
                                       Intercept=self._tzero['intercept'],
                                       OutputWorkspace=local_name)
        # Correct old DAS shift of fast neutrons. See GitHub issue 23855
        if self._das_version == VDAS.v1900_2018:
            _t_corr = self.add_previous_pulse(_t_corr)

        _t_corr = ConvertUnits(_t_corr,
                               Target='Wavelength',
                               Emode='Elastic',
                               OutputWorkspace=local_name)
        l_s, l_e = self._wavelength_band[0], self._wavelength_band[1]
        _t_corr = CropWorkspace(_t_corr,
                                XMin=l_s,
                                XMax=l_e,
                                OutputWorkspace=local_name)
        _t_corr = Rebin(_t_corr,
                        Params=[l_s, self._wavelength_dl, l_e],
                        PreserveEvents=False,
                        OutputWorkspace=local_name)

        if self.getProperty('DoFluxNormalization').value is True:
            _t_corr = self._flux_normalization(_t_corr, target)
        RenameWorkspace(_t_corr, OutputWorkspace=w.name())
        return _t_corr
    def fitted_in_dspacing(self,
                           fitted_in_tof: Union[str, Workspace2D],
                           workspace_with_instrument: Union[str, Workspace],
                           output_workspace: str,
                           dspacing_bin_width: float = 0.001,
                           grouping_workspace: Optional[str] = None) -> None:
        r"""
        Create one spectra of fitted peaks in d-spacing for each pixel or group of detectors

        This algorithm will perform a unit converstion from TOF to d-spacing. The instrument geometry
        for the conversion is proviged by the instrument embedded in `workspace_with_instrument`,
        instead of the instrument embedded in `fitted_in_tof`.

        @param fitted_in_tof : fitted spectra in TOF, one per pixel
        @param workspace_with_instrument : workspace providing the instrument with the desired geometry
        @param output_workspace : name of the workspace containing the spectra in d-spacing
        @param dspacing_bin_width : bin width for the spectra of `output_workspace`
        @param grouping_workspace: if provided, generate one spectra in d-spacing for each of the
            groups specified in this grouping workspace.
        """
        CloneWorkspace(InputWorkspace=fitted_in_tof,
                       OutputWorkspace=output_workspace)
        CopyInstrumentParameters(InputWorkspace=workspace_with_instrument,
                                 OutputWorkspace=output_workspace)
        ConvertUnits(InputWorkspace=output_workspace,
                     OutputWorkspace=output_workspace,
                     Target='dSpacing',
                     Emode='Elastic')
        # Rebin spectra to common bin boundaries. This is required if grouping is desired
        peak_centers_reference = self.getProperty('PeakPositions').value
        dspacing_extra = 1.0  # 1 Angstrom
        dspacing_min = max(0, min(peak_centers_reference) - dspacing_extra)
        dspacing_max = max(peak_centers_reference) + dspacing_extra
        Rebin(InputWorkspace=output_workspace,
              OutputWorkspace=output_workspace,
              Params=[dspacing_min, dspacing_bin_width,
                      dspacing_max])  # bin width is 0.001 Angstroms
        # Optional groping into banks
        if grouping_workspace is not None:
            GroupDetectors(InputWorkspace=output_workspace,
                           OutputWorkspace=output_workspace,
                           CopyGroupingFromWorkspace=grouping_workspace)
            insert_bank_numbers(
                output_workspace,
                grouping_workspace)  # label each spectrum with the bank number