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
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)
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)
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]
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
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
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.')
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 = " "
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
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)
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')
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]
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)
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
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]
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
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
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')
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