def TransfitRebin(self, inputWS, outputWSName, foilType, divE): ws2D = mtd[inputWS] # Expand the limits for rebinning to prevent potential issues at the boundaries startE = self.ResParamsDict[foilType + '_startE'] endE = self.ResParamsDict[foilType + '_endE'] startEp = 0.99 * startE endEp = 1.01 * endE CropWorkspace(InputWorkspace=ws2D, OutputWorkspace=ws2D, XMin=1000 * startEp, XMax=1000 * endEp) numPts = np.int(((endEp - startEp) / divE) + 1) xData_out = [] xData_in = ws2D.readX(0) yData_in = ws2D.readY(0) # Deals with issues in Mantid where Xdata mark start of bin, not true x position # calculates the bin width and then takes middle of bin as x value current_bin_widths = [] xActual = [] for x in range(0, len(xData_in) - 1): current_bin_widths.append(xData_in[x + 1] - xData_in[x]) xActual.append(xData_in[x] + 0.5 * (xData_in[x + 1] - xData_in[x])) # Make xData with uniform binning defined by divE for j in range(numPts): xData_out.append(1000 * (startEp + j * divE)) yData_out = [0] * (len(xData_out)) # Normalise output ydata accordingly based on surrounding values yNorm = [0] * (len(xData_out)) for j in range(0, len(yData_in)): currentBin = np.int((xActual[j] - startEp * 1000) / (divE * 1000)) scale1 = 1 - ((xActual[j] - xData_out[currentBin]) / (divE * 1000)) yData_out[currentBin] += yData_in[j] * scale1 yNorm[currentBin] += scale1 if currentBin < (len(xData_out) - 1): yData_out[currentBin + 1] += yData_in[j] * (1 - scale1) yNorm[currentBin + 1] += 1 - scale1 # Apply the normalisation, with a catch for any potential divide by zero errors for i in range(len(yData_out)): if yNorm[i] != 0: yData_out[i] = yData_out[i] / yNorm[i] else: print('Empty bin') outputWS = CreateWorkspace(DataX=xData_out, DataY=yData_out, NSpec=1, UnitX='meV') CropWorkspace(InputWorkspace=outputWS, OutputWorkspace=outputWS, XMin=1000 * startE, XMax=1000 * endE) RenameWorkspace(InputWorkspace=outputWS, OutputWorkspace=outputWSName)
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 _load_and_sum_runs(self, spectra): """Load the input set of runs & sum them if there is more than one. @param spectra :: The list of spectra to load @returns a tuple of length 2 containing (main_detector_ws, monitor_ws) """ isis = config.getFacility("ISIS") inst_prefix = isis.instrument("VESUVIO").shortName() runs = self._get_runs() self.summed_ws, self.summed_mon = "__loadraw_evs", "__loadraw_evs_monitors" for index, run in enumerate(runs): run = inst_prefix + str(run) if index == 0: out_name, out_mon = SUMMED_WS, SUMMED_MON else: out_name, out_mon = SUMMED_WS + 'tmp', SUMMED_MON + 'tmp' # Load data LoadRaw(Filename=run, SpectrumList=spectra, OutputWorkspace=out_name, LoadMonitors='Exclude', EnableLogging=_LOGGING_) LoadRaw(Filename=run, SpectrumList=self._mon_spectra, OutputWorkspace=out_mon, EnableLogging=_LOGGING_) if index > 0: # sum Plus(LHSWorkspace=SUMMED_WS, RHSWorkspace=out_name, OutputWorkspace=SUMMED_WS, EnableLogging=_LOGGING_) Plus(LHSWorkspace=SUMMED_MON, RHSWorkspace=out_mon, OutputWorkspace=SUMMED_MON, EnableLogging=_LOGGING_) DeleteWorkspace(out_name, EnableLogging=_LOGGING_) DeleteWorkspace(out_mon, EnableLogging=_LOGGING_) CropWorkspace(Inputworkspace=SUMMED_WS, OutputWorkspace=SUMMED_WS, XMax=self._tof_max, EnableLogging=_LOGGING_) CropWorkspace(Inputworkspace=SUMMED_MON, OutputWorkspace=SUMMED_MON, XMax=self._mon_tof_max, EnableLogging=_LOGGING_) return mtd[SUMMED_WS], mtd[SUMMED_MON]
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 crop_workspaces(workspace_names, spec_min, spec_max, extract_monitors=True, monitor_index=0): """ Crops the workspaces with the specified workspace names, from the specified minimum spectra to the specified maximum spectra. :param workspace_names: The names of the workspaces to crop :param spec_min: The minimum spectra of the cropping region :param spec_max: The maximum spectra of the cropping region :param extract_monitors: If True, extracts monitors from the workspaces :param monitor_index: The index of the monitors in the workspaces """ from mantid.simpleapi import ExtractSingleSpectrum, CropWorkspace for workspace_name in workspace_names: if extract_monitors: # Get the monitor spectrum monitor_ws_name = workspace_name + '_mon' ExtractSingleSpectrum(InputWorkspace=workspace_name, OutputWorkspace=monitor_ws_name, WorkspaceIndex=monitor_index) # Crop to the detectors required workspace = mtd[workspace_name] CropWorkspace(InputWorkspace=workspace_name, OutputWorkspace=workspace_name, StartWorkspaceIndex=workspace.getIndexFromSpectrumNumber(int(spec_min)), EndWorkspaceIndex=workspace.getIndexFromSpectrumNumber(int(spec_max)))
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 _mask_t0_crop(self, run_number, name): """ Load a run into a workspace with: 1. Masked detectors 2. Delayed emission time from moderator removed 3. Conversion of units to momentum 4. Remove events outside the valid momentum range :param run_number: BASIS run number :param name: name for the output workspace :return: workspace object """ ws = self._load_single_run(run_number, name) MaskDetectors(ws, MaskedWorkspace=self._t_mask) ws = ModeratorTzeroLinear(InputWorkspace=ws.name(), Gradient=self._tzero['gradient'], Intercept=self._tzero['intercept'], OutputWorkspace=ws.name()) # Correct old DAS shift of fast neutrons. See GitHub issue 23855 if self._das_version == VDAS.v1900_2018: ws = self.add_previous_pulse(ws) ws = ConvertUnits(ws, Target='Momentum', OutputWorkspace=ws.name()) ws = CropWorkspace(ws, OutputWorkspace=ws.name(), XMin=self._momentum_range[0], XMax=self._momentum_range[1]) return ws
def runTest(self): config['default.facility'] = 'ILL' config['default.instrument'] = 'IN4' DirectILLCollectData(Run='ILL/IN4/085801-085802.nxs', OutputWorkspace='vanadium', OutputEPPWorkspace='vanadium-epps', OutputRawWorkspace='vanadium-raw', MonitorPeakWidthInSigmas=3.0) DirectILLIntegrateVanadium(InputWorkspace='vanadium', OutputWorkspace='integrated', EPPWorkspace='vanadium-epps') DirectILLDiagnostics( InputWorkspace='vanadium-raw', OutputWorkspace='diagnostics', SubalgorithmLogging='Logging ON', EPPWorkspace='vanadium-epps', ) # Samples DirectILLCollectData(Run='ILL/IN4/087294+087295.nxs', OutputWorkspace='sample', OutputIncidentEnergyWorkspace='Ei', OutputElasticChannelWorkspace='Elp', MonitorPeakWidthInSigmas=3.0) # Containers DirectILLCollectData(Run='ILL/IN4/087306-087309.nxs', OutputWorkspace='container', IncidentEnergyWorkspace='Ei', ElasticChannelWorkspace='Elp', MonitorPeakWidthInSigmas=3.0) geometry = { 'Shape': 'HollowCylinder', 'Height': 4.0, 'InnerRadius': 1.9, 'OuterRadius': 2.0, 'Center': [0.0, 0.0, 0.0] } material = {'ChemicalFormula': 'Cd S', 'SampleNumberDensity': 0.01} SetSample('sample', geometry, material) DirectILLSelfShielding(InputWorkspace='sample', OutputWorkspace='corrections', EventsPerPoint=20000) DirectILLApplySelfShielding( InputWorkspace='sample', OutputWorkspace='corrected', SelfShieldingCorrectionWorkspace='corrections', EmptyContainerWorkspace='container') DirectILLReduction(InputWorkspace='corrected', OutputWorkspace='SofQW', IntegratedVanadiumWorkspace='integrated', DiagnosticsWorkspace='diagnostics') CropWorkspace(InputWorkspace='SofQW', OutputWorkspace='cropped', XMin=1., XMax=2.75, StartWorkspaceIndex=83, EndWorkspaceIndex=222) # The 'run_title' property has been deliberately erased from the test numor. # We need to add it manually because Save/LoadNexus will do the same for # the reference file. mtd['cropped'].mutableRun().addProperty('run_title', '', True)
def _calibrate_runs_in_map(self, drange_map): for d_range, wrksp in drange_map.items(): normalised = NormaliseByCurrent( InputWorkspace=wrksp, OutputWorkspace="normalised_sample", StoreInADS=False, EnableLogging=False) aligned = AlignDetectors(InputWorkspace=normalised, CalibrationFile=self._cal, OutputWorkspace="aligned_sample", StoreInADS=False, EnableLogging=False) focussed = DiffractionFocussing(InputWorkspace=aligned, GroupingFileName=self._cal, OutputWorkspace="focussed_sample", StoreInADS=False, EnableLogging=False) drange_map[d_range] = CropWorkspace( InputWorkspace=focussed, XMin=d_range[0], XMax=d_range[1], OutputWorkspace="calibrated_sample", StoreInADS=False, EnableLogging=False)
def monitorTransfit(self, files, foilType, divE): isFirstFile = True isSingleFile = len(files) == 1 firstFileName = "" for file in files: discard, fileName = path.split(file) fnNoExt = path.splitext(fileName)[0] if isFirstFile: firstFileName = fnNoExt fileName_Raw = fnNoExt + '_raw' fileName_3 = fnNoExt + '_3' LoadRaw(Filename=file, OutputWorkspace=fileName_Raw) CropWorkspace(InputWorkspace=fileName_Raw, OutputWorkspace=fileName_Raw, XMin=100, XMax=19990) NormaliseByCurrent(InputWorkspace=fileName_Raw, OutputWorkspace=fileName_Raw) ExtractSingleSpectrum(InputWorkspace=fileName_Raw, OutputWorkspace=fileName_3, WorkspaceIndex=3) DeleteWorkspace(fileName_Raw) ConvertUnits(InputWorkspace=fileName_3, Target='Energy', OutputWorkspace=fileName_3) self.TransfitRebin(fileName_3, fileName_3, foilType, divE) if not isFirstFile: Plus(LHSWorkspace=firstFileName + '_3', RHSWorkspace=fileName_3, OutputWorkspace=firstFileName + '_3') DeleteWorkspace(fileName_3) else: isFirstFile = False if isSingleFile: RenameWorkspace(InputWorkspace=firstFileName + '_3', OutputWorkspace=firstFileName + '_monitor') else: noFiles = len(files) ** (-1) CreateSingleValuedWorkspace(OutputWorkspace='scale', DataValue=noFiles) Multiply(LHSWorkspace=firstFileName + '_3', RHSWorkspace='scale', OutputWorkspace=firstFileName + '_monitor') DeleteWorkspace('scale') DeleteWorkspace(firstFileName + '_3')
def _monitor_normalization(self, w, target): """ Divide data by integrated monitor intensity Parameters ---------- w: Mantid.EventsWorkspace Input workspace target: str Specify the entity the workspace refers to. Valid options are 'sample', 'background', and 'vanadium' Returns ------- Mantid.EventWorkspace """ _t_mon = self._load_monitors(target) _t_mon = ConvertUnits(_t_mon, Target='Wavelength', Emode='Elastic') _t_mon = CropWorkspace(_t_mon, XMin=self._wavelength_band[0], XMax=self._wavelength_band[1]) _t_mon = OneMinusExponentialCor(_t_mon, C='0.20749999999999999', C1='0.001276') _t_mon = Scale(_t_mon, Factor='1e-06', Operation='Multiply') _t_mon = Integration(_t_mon) # total monitor count _t_w = Divide(w, _t_mon, OutputWorkspace=w.name()) return _t_w
def test_filling_workspace_details_multiple_workspaces_of_different_sizes(self): ws1 = CreateSampleWorkspace(OutputWorkspace='ws', NumBanks=1, StoreInADS=False) ws1 = CropWorkspace(ws1, StartWorkspaceIndex=50) ws2 = CreateSampleWorkspace(OutputWorkspace='ws', StoreInADS=False) dlg = PlotSelectionDialog([ws1, ws2]) self.assertEqual("valid range: 51-100", dlg._ui.specNums.placeholderText()) self.assertEqual("valid range: 0-49", dlg._ui.wkspIndices.placeholderText())
def _applyWavelengthRange(self, ws): """Cut wavelengths outside the wavelength range from a TOF workspace.""" wRange = self.getProperty(Prop.WAVELENGTH_RANGE).value rangeProp = {'XMin': wRange[0]} if len(wRange) == 2: rangeProp['XMax'] = wRange[1] croppedWSName = self._names.withSuffix('cropped') croppedWS = CropWorkspace(InputWorkspace=ws, OutputWorkspace=croppedWSName, EnableLogging=self._subalgLogging, **rangeProp) self._cleanup.cleanup(ws) return croppedWS
def load_data_and_normalise(filename, spectrumMin=1, spectrumMax=19461, outputWorkspace="sample"): """ Function to load in raw data, crop and normalise :param filename: file path to .raw :param spectrumMin: min spec to load (default incl. all monitors) :param spectrumMax: max spec to load (default includes only bank 1) :param outputWorkspace: name of output workspace (can be specified to stop workspaces being overwritten) :return: normalised and cropped data with xunit wavelength (excl. monitors) """ sample, mon = LoadRaw(Filename=filename, SpectrumMin=spectrumMin, SpectrumMax=spectrumMax, LoadMonitors="Separate", OutputWorkspace=outputWorkspace) for ws in [sample, mon]: CropWorkspace(InputWorkspace=ws, OutputWorkspace=ws, XMin=6000, XMax=99000) NormaliseByCurrent(InputWorkspace=ws, OutputWorkspace=ws) ConvertUnits(InputWorkspace=ws, OutputWorkspace=ws, Target='Wavelength') NormaliseToMonitor(InputWorkspace=sample, OutputWorkspace=sample, MonitorWorkspaceIndex=3, MonitorWorkspace=mon) ReplaceSpecialValues(InputWorkspace=sample, OutputWorkspace=sample, NaNValue=0, InfinityValue=0) CropWorkspace(InputWorkspace=sample, OutputWorkspace=sample, XMin=0.8, XMax=9.3) return sample
def _applyWavelengthRange(self, ws, beamPosWS): """Cut wavelengths outside the wavelength range from a TOF workspace.""" wRange = self.getProperty(Prop.WAVELENGTH_RANGE).value xMin = self._wavelengthToTOF(wRange[0], ws, self._foregroundCentre(beamPosWS)) xMax = self._wavelengthToTOF(wRange[1], ws, self._foregroundCentre(beamPosWS)) croppedWSName = self._names.withSuffix('cropped') croppedWS = CropWorkspace(InputWorkspace=ws, OutputWorkspace=croppedWSName, XMin=xMin, XMax=xMax, EnableLogging=self._subalgLogging) self._cleanup.cleanup(ws) return croppedWS
def runTest(self): config['default.facility'] = 'ILL' config['default.instrument'] = 'IN5' DirectILLCollectData( Run='ILL/IN5/095893.nxs', OutputWorkspace='vanadium', OutputEPPWorkspace='vanadium-epps', ) DirectILLDiagnostics(InputWorkspace='vanadium', OutputWorkspace='diagnostics', MaskedComponents='tube_320') DirectILLTubeBackground(InputWorkspace='vanadium', OutputWorkspace='bkg', EPPWorkspace='vanadium-epps', DiagnosticsWorkspace='diagnostics') Subtract(LHSWorkspace='vanadium', RHSWorkspace='bkg', OutputWorkspace='vanadium') DeleteWorkspace('bkg') DirectILLIntegrateVanadium(InputWorkspace='vanadium', OutputWorkspace='integrated', EPPWorkspace='vanadium-epps') DeleteWorkspace('vanadium') DeleteWorkspace('vanadium-epps') DirectILLCollectData(Run='ILL/IN5/096003.nxs', OutputWorkspace='sample', OutputEppWorkspace='epps') DirectILLTubeBackground(InputWorkspace='sample', OutputWorkspace='bkg', EPPWorkspace='epps', DiagnosticsWorkspace='diagnostics') Subtract(LHSWorkspace='sample', RHSWorkspace='bkg', OutputWorkspace='sample') DirectILLReduction(InputWorkspace='sample', OutputWorkspace='SofQW', IntegratedVanadiumWorkspace='integrated', DiagnosticsWorkspace='diagnostics') CropWorkspace(InputWorkspace='SofQW', OutputWorkspace='cropped', XMin=0.5, XMax=2.1, StartWorkspaceIndex=375, EndWorkspaceIndex=720) # The 'run_title' property has been deliberately erased from the test numor. # We need to add it manually because Save/LoadNexus will do the same for # the reference file. mtd['cropped'].mutableRun().addProperty('run_title', '', True)
def runTest(self): config['default.facility'] = 'ILL' config['default.instrument'] = 'IN6' DirectILLCollectData(Run='ILL/IN6/164192.nxs', OutputWorkspace='vanadium', OutputEPPWorkspace='vanadium-epps', OutputRawWorkspace='vanadium-raw') DirectILLIntegrateVanadium(InputWorkspace='vanadium', OutputWorkspace='integrated', EPPWorkspace='vanadium-epps') DirectILLDiagnostics( InputWorkspace='vanadium-raw', OutputWorkspace='diagnostics', EPPWorkspace='vanadium-epps', ) # Simulate sample with vanadium DirectILLCollectData(Run='ILL/IN6/164192.nxs', OutputWorkspace='sample') DirectILLReduction(InputWorkspace='sample', OutputWorkspace='SofQW', IntegratedVanadiumWorkspace='integrated', EnergyRebinningParams='-100, 0.01, 4.', DiagnosticsWorkspace='diagnostics') CropWorkspace(InputWorkspace='SofQW', OutputWorkspace='cropped', XMin=0.7, XMax=2.1, StartWorkspaceIndex=9588, EndWorkspaceIndex=10280) # GetEiMonDet produces slightly different results on different system. We better # check the calibrated energy logs here and set them to fixed values to # enable CompareWorkspaces to do its job. This hack could be removed later if # CompareWorkspaces supported tolerances for sample log comparison. ws = mtd['cropped'] run = ws.mutableRun() self.assertAlmostEqual(run.getProperty('Ei').value, 4.72233, places=4) run.addProperty('Ei', 4.72, True) self.assertAlmostEqual(run.getProperty('wavelength').value, 4.16207, places=4) run.addProperty('wavelength', 4.16, True) # The 'run_title' property has been deliberately erased from the test numor. # We need to add it manually because Save/LoadNexus will do the same for # the reference file. mtd['cropped'].mutableRun().addProperty('run_title', '', True)
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 PyExec(self): from mantid.simpleapi import CropWorkspace, Integration, DeleteWorkspace in_ws = self.getPropertyValue("InputWorkspace") min_wavelength = self.getPropertyValue("StartWavelength") keep_workspaces = self.getPropertyValue("KeepIntermediateWorkspaces") # Crop off lower wavelengths where the signal is also lower. cropped_ws = CropWorkspace(InputWorkspace=in_ws, XMin=float(min_wavelength)) # Integrate over the higher wavelengths after cropping. summed_ws = Integration(InputWorkspace=cropped_ws) # Loop through each histogram, and fetch out each intensity value from the single bin to generate a list of all values. n_histograms = summed_ws.getNumberHistograms() y_data = np.empty([n_histograms]) for i in range(0, n_histograms): intensity = summed_ws.readY(i)[0] y_data[i] = intensity #Remove the background y_data = self.__remove_background(y_data) #Find the peaks peak_index_list = self.__find_peak_spectrum_numbers(y_data, summed_ws) #Reverse the order so that it goes from high spec number to low spec number peak_index_list.reverse() n_peaks_found = len(peak_index_list) output_ws = WorkspaceFactory.createTable("TableWorkspace") output_ws.addColumn("int", "Reflected Spectrum Number") if n_peaks_found > 2: raise PeakFindingException("Found more than two peaks.") elif n_peaks_found == 0: raise PeakFindingException("No peaks found") elif n_peaks_found == 1: output_ws.addRow(peak_index_list) elif n_peaks_found == 2: output_ws.addColumn("int", "Transmission Spectrum Number") output_ws.addRow(peak_index_list) if int(keep_workspaces) == 0: DeleteWorkspace(Workspace=cropped_ws) DeleteWorkspace(Workspace=summed_ws) self.setProperty("OutputWorkspace", output_ws)
def setUp(self): # Simulation of the creation of the Sample data nb = 102 xd = 10 yd = 10 data = numpy.random.normal(size=xd*yd*nb)/2.0 + 5.0 xvalues = numpy.linspace(3500,43500,nb+1) tv = numpy.linspace(7e-2,6e-2,nb) Sample = CreateWorkspace(xvalues,data,NSpec=xd*yd) LoadInstrument(Sample, InstrumentName='SANS2D') Sample = CropWorkspace(Sample,StartWorkspaceIndex=8)#remove the monitors # create a transmission workspace Trans = CropWorkspace(Sample,StartWorkspaceIndex=10,EndWorkspaceIndex=10) x_v = Trans.dataX(0)[:-1] y_v = numpy.linspace(0.743139, 0.6,nb) e_v = y_v/58.0 Trans.setY(0,y_v) Trans.setE(0,e_v) self._sample = Sample self._trans = Trans self.n_det = xd*yd
def calibrator(d_range, workspace): normalised = NormaliseByCurrent(InputWorkspace=workspace, OutputWorkspace="normalised_sample", StoreInADS=False, EnableLogging=False) aligned = AlignDetectors(InputWorkspace=normalised, CalibrationFile=calibration_file, OutputWorkspace="aligned_sample", StoreInADS=False, EnableLogging=False) focussed = DiffractionFocussing(InputWorkspace=aligned, GroupingFileName=calibration_file, OutputWorkspace="focussed_sample", StoreInADS=False, EnableLogging=False) return CropWorkspace(InputWorkspace=focussed, XMin=d_range[0], XMax=d_range[1], OutputWorkspace="calibrated_sample", StoreInADS=False, EnableLogging=False)
def strip_NaNs(output_workspace, base_output_name): """ Strip NaNs from the 1D OutputWorkspace """ # add isinf data = output_workspace.readY(0) start_index = next( (index for index in range(len(data)) if not math.isnan(data[index])), None) end_index = next((index for index in range(len(data) - 1, -1, -1) if not math.isnan(data[index])), None) q_values = output_workspace.readX(0) start_q = q_values[start_index] end_q = q_values[end_index] CropWorkspace(InputWorkspace=output_workspace, XMin=start_q, XMax=end_q, OutputWorkspace=base_output_name) return base_output_name
def _createFlatBkg(ws, wsType, windowWidth, wsNames, algorithmLogging): """Return a flat background workspace.""" if wsType == common.WS_CONTENT_DETS: bkgWSName = wsNames.withSuffix('flat_bkg_for_detectors') else: bkgWSName = wsNames.withSuffix('flat_bkg_for_monitors') bkgWS = CalculateFlatBackground(InputWorkspace=ws, OutputWorkspace=bkgWSName, Mode='Moving Average', OutputMode='Return Background', SkipMonitors=False, NullifyNegativeValues=False, AveragingWindowWidth=windowWidth, EnableLogging=algorithmLogging) firstBinStart = bkgWS.dataX(0)[0] firstBinEnd = bkgWS.dataX(0)[1] bkgWS = CropWorkspace(InputWorkspace=bkgWS, OutputWorkspace=bkgWS, XMin=firstBinStart, XMax=firstBinEnd, EnableLogging=algorithmLogging) return bkgWS
def _mask_t0_crop(self, run_number, name): """ Load a run into a workspace with: 1. Masked detectors 2. Delayed emission time from moderator removed 3. Conversion of units to momentum 4. Remove events outside the valid momentum range :param run_number: BASIS run number :param name: name for the output workspace :return: workspace object """ ws = LoadEventNexus(Filename=self._makeRunFile(run_number), NXentryName='entry-diff', SingleBankPixelsOnly=False, OutputWorkspace=name) MaskDetectors(ws, MaskedWorkspace=self._t_mask) ws = ModeratorTzeroLinear(InputWorkspace=ws.name(), OutputWorkspace=ws.name()) ws = ConvertUnits(ws, Target='Momentum', OutputWorkspace=ws.name()) ws = CropWorkspace(ws, OutputWorkspace=ws.name(), XMin=self._momentum_range[0], XMax=self._momentum_range[1]) return ws
def PyExec(self): _background = bool(self.getProperty("Background").value) _load_inst = bool(self.getProperty("LoadInstrument").value) _norm_current = bool(self.getProperty("NormaliseByCurrent").value) _detcal = bool(self.getProperty("DetCal").value) _masking = bool(self.getProperty("MaskFile").value) _grouping = bool(self.getProperty("GroupingFile").value) _anvred = bool(self.getProperty("SphericalAbsorptionCorrection").value) _SA_name = self.getPropertyValue("SolidAngleOutputWorkspace") _Flux_name = self.getPropertyValue("FluxOutputWorkspace") XMin = self.getProperty("MomentumMin").value XMax = self.getProperty("MomentumMax").value rebin_param = ','.join([str(XMin), str(XMax), str(XMax)]) Load(Filename=self.getPropertyValue("Filename"), OutputWorkspace='__van', FilterByTofMin=self.getProperty("FilterByTofMin").value, FilterByTofMax=self.getProperty("FilterByTofMax").value) if _norm_current: NormaliseByCurrent(InputWorkspace='__van', OutputWorkspace='__van') if _background: Load(Filename=self.getProperty("Background").value, OutputWorkspace='__bkg', FilterByTofMin=self.getProperty("FilterByTofMin").value, FilterByTofMax=self.getProperty("FilterByTofMax").value) if _norm_current: NormaliseByCurrent(InputWorkspace='__bkg', OutputWorkspace='__bkg') else: pc_van = mtd['__van'].run().getProtonCharge() pc_bkg = mtd['__bkg'].run().getProtonCharge() mtd['__bkg'] *= pc_van / pc_bkg mtd['__bkg'] *= self.getProperty('BackgroundScale').value Minus(LHSWorkspace='__van', RHSWorkspace='__bkg', OutputWorkspace='__van') DeleteWorkspace('__bkg') if _load_inst: LoadInstrument(Workspace='__van', Filename=self.getProperty("LoadInstrument").value, RewriteSpectraMap=False) if _detcal: LoadIsawDetCal(InputWorkspace='__van', Filename=self.getProperty("DetCal").value) if _masking: LoadMask(Instrument=mtd['__van'].getInstrument().getName(), InputFile=self.getProperty("MaskFile").value, OutputWorkspace='__mask') MaskDetectors(Workspace='__van', MaskedWorkspace='__mask') DeleteWorkspace('__mask') ConvertUnits(InputWorkspace='__van', OutputWorkspace='__van', Target='Momentum') Rebin(InputWorkspace='__van', OutputWorkspace='__van', Params=rebin_param) CropWorkspace(InputWorkspace='__van', OutputWorkspace='__van', XMin=XMin, XMax=XMax) if _anvred: AnvredCorrection(InputWorkspace='__van', OutputWorkspace='__van', LinearScatteringCoef=self.getProperty( "LinearScatteringCoef").value, LinearAbsorptionCoef=self.getProperty( "LinearAbsorptionCoef").value, Radius=self.getProperty("Radius").value, OnlySphericalAbsorption='1', PowerLambda='0') # Create solid angle Rebin(InputWorkspace='__van', OutputWorkspace=_SA_name, Params=rebin_param, PreserveEvents=False) # Create flux if _grouping: GroupDetectors(InputWorkspace='__van', OutputWorkspace='__van', MapFile=self.getProperty("GroupingFile").value) else: SumSpectra(InputWorkspace='__van', OutputWorkspace='__van') Rebin(InputWorkspace='__van', OutputWorkspace='__van', Params=rebin_param) flux = mtd['__van'] for i in range(flux.getNumberHistograms()): el = flux.getSpectrum(i) if flux.readY(i)[0] > 0: el.divide(flux.readY(i)[0], flux.readE(i)[0]) SortEvents(InputWorkspace='__van', SortBy="X Value") IntegrateFlux(InputWorkspace='__van', OutputWorkspace=_Flux_name, NPoints=10000) DeleteWorkspace('__van') self.setProperty("SolidAngleOutputWorkspace", mtd[_SA_name]) self.setProperty("FluxOutputWorkspace", mtd[_Flux_name])
def _crop_workspace(self, workspace): return CropWorkspace(InputWorkspace=workspace, XMin=self._instrument.tof_range[0], XMax=self._instrument.tof_range[1], OutputWorkspace="cropped", StoreInADS=False)
def PyExec(self): # Retrieve all relevant notice in_Runs = self.getProperty("RunNumbers").value maskWSname = self._getMaskWSname() # either type of file-based calibration is stored in the same variable calib = self.getProperty("Calibration").value if calib == "Calibration File": cal_File = self.getProperty("CalibrationFilename").value elif calib == 'DetCal File': cal_File = self.getProperty('DetCalFilename').value cal_File = ','.join(cal_File) else: cal_File = None params = self.getProperty("Binning").value norm = self.getProperty("Normalization").value if norm == "From Processed Nexus": norm_File = self.getProperty("NormalizationFilename").value LoadNexusProcessed(Filename=norm_File, OutputWorkspace='normWS') normWS = 'normWS' elif norm == "From Workspace": normWS = str(self.getProperty("NormalizationWorkspace").value) else: normWS = None group_to_real = { 'Banks': 'Group', 'Modules': 'bank', '2_4 Grouping': '2_4Grouping' } group = self.getProperty('GroupDetectorsBy').value real_name = group_to_real.get(group, group) if not mtd.doesExist(group): if group == '2_4 Grouping': group = '2_4_Grouping' CreateGroupingWorkspace(InstrumentName='SNAP', GroupDetectorsBy=real_name, OutputWorkspace=group) Process_Mode = self.getProperty("ProcessingMode").value prefix = self.getProperty("OptionalPrefix").value # --------------------------- REDUCE DATA ----------------------------- Tag = 'SNAP' for r in in_Runs: self.log().notice("processing run %s" % r) self.log().information(str(self.get_IPTS_Local(r))) if self.getProperty("LiveData").value: Tag = 'Live' LoadPreNexusLive(Instrument='SNAP', OutputWorkspace='WS') else: Load(Filename='SNAP' + str(r), OutputWorkspace='WS') NormaliseByCurrent(InputWorkspace='WS', OutputWorkspace='WS') CompressEvents(InputWorkspace='WS', OutputWorkspace='WS') CropWorkspace(InputWorkspace='WS', OutputWorkspace='WS', XMax=50000) RemovePromptPulse(InputWorkspace='WS', OutputWorkspace='WS', Width='1600', Frequency='60.4') if maskWSname is not None: MaskDetectors(Workspace='WS', MaskedWorkspace=maskWSname) self._alignAndFocus(params, calib, cal_File, group) normWS = self._generateNormalization('WS_red', norm, normWS) WS_nor = None if normWS is not None: WS_nor = 'WS_nor' Divide(LHSWorkspace='WS_red', RHSWorkspace=normWS, OutputWorkspace='WS_nor') ReplaceSpecialValues(Inputworkspace='WS_nor', OutputWorkspace='WS_nor', NaNValue='0', NaNError='0', InfinityValue='0', InfinityError='0') new_Tag = Tag if len(prefix) > 0: new_Tag += '_' + prefix # Edit instrument geomety to make final workspace smaller on disk det_table = PreprocessDetectorsToMD( Inputworkspace='WS_red', OutputWorkspace='__SNAP_det_table') polar = np.degrees(det_table.column('TwoTheta')) azi = np.degrees(det_table.column('Azimuthal')) EditInstrumentGeometry(Workspace='WS_red', L2=det_table.column('L2'), Polar=polar, Azimuthal=azi) if WS_nor is not None: EditInstrumentGeometry(Workspace='WS_nor', L2=det_table.column('L2'), Polar=polar, Azimuthal=azi) mtd.remove('__SNAP_det_table') # Save requested formats basename = '%s_%s_%s' % (new_Tag, r, group) self._save(r, basename, norm) # temporary workspace no longer needed DeleteWorkspace(Workspace='WS') # rename everything as appropriate and determine output workspace name RenameWorkspace(Inputworkspace='WS_d', OutputWorkspace='%s_%s_d' % (new_Tag, r)) RenameWorkspace(Inputworkspace='WS_red', OutputWorkspace=basename + '_red') if norm == 'None': outputWksp = basename + '_red' else: outputWksp = basename + '_nor' RenameWorkspace(Inputworkspace='WS_nor', OutputWorkspace=basename + '_nor') if norm == "Extracted from Data": RenameWorkspace(Inputworkspace='peak_clip_WS', OutputWorkspace='%s_%s_normalizer' % (new_Tag, r)) # delte some things in production if Process_Mode == "Production": DeleteWorkspace(Workspace='%s_%s_d' % (new_Tag, r)) # was 'WS_d' if norm != "None": DeleteWorkspace(Workspace=basename + '_red') # was 'WS_red' if norm == "Extracted from Data": DeleteWorkspace(Workspace='%s_%s_normalizer' % (new_Tag, r)) # was 'peak_clip_WS' propertyName = 'OutputWorkspace_' + str(outputWksp) self.declareProperty( WorkspaceProperty(propertyName, outputWksp, Direction.Output)) self.setProperty(propertyName, outputWksp)
def PyExec(self): # remove possible old temp workspaces [ DeleteWorkspace(ws) for ws in self.temp_workspace_list if mtd.doesExist(ws) ] _background = bool(self.getProperty("Background").value) _load_inst = bool(self.getProperty("LoadInstrument").value) _detcal = bool(self.getProperty("DetCal").value) _masking = bool(self.getProperty("MaskFile").value) _outWS_name = self.getPropertyValue("OutputWorkspace") UBList = self._generate_UBList() dim0_min, dim0_max, dim0_bins = self.getProperty('BinningDim0').value dim1_min, dim1_max, dim1_bins = self.getProperty('BinningDim1').value dim2_min, dim2_max, dim2_bins = self.getProperty('BinningDim2').value MinValues = "{},{},{}".format(dim0_min, dim1_min, dim2_min) MaxValues = "{},{},{}".format(dim0_max, dim1_max, dim2_max) AlignedDim0 = ",{},{},{}".format(dim0_min, dim0_max, int(dim0_bins)) AlignedDim1 = ",{},{},{}".format(dim1_min, dim1_max, int(dim1_bins)) AlignedDim2 = ",{},{},{}".format(dim2_min, dim2_max, int(dim2_bins)) LoadNexus(Filename=self.getProperty("SolidAngle").value, OutputWorkspace='__sa') LoadNexus(Filename=self.getProperty("Flux").value, OutputWorkspace='__flux') if _masking: LoadMask(Instrument=mtd['__sa'].getInstrument().getName(), InputFile=self.getProperty("MaskFile").value, OutputWorkspace='__mask') MaskDetectors(Workspace='__sa', MaskedWorkspace='__mask') DeleteWorkspace('__mask') XMin = mtd['__sa'].getXDimension().getMinimum() XMax = mtd['__sa'].getXDimension().getMaximum() if _background: Load(Filename=self.getProperty("Background").value, OutputWorkspace='__bkg', FilterByTofMin=self.getProperty("FilterByTofMin").value, FilterByTofMax=self.getProperty("FilterByTofMax").value) if _load_inst: LoadInstrument( Workspace='__bkg', Filename=self.getProperty("LoadInstrument").value, RewriteSpectraMap=False) if _detcal: LoadIsawDetCal(InputWorkspace='__bkg', Filename=self.getProperty("DetCal").value) MaskDetectors(Workspace='__bkg', MaskedWorkspace='__sa') ConvertUnits(InputWorkspace='__bkg', OutputWorkspace='__bkg', Target='Momentum') CropWorkspace(InputWorkspace='__bkg', OutputWorkspace='__bkg', XMin=XMin, XMax=XMax) progress = Progress( self, 0.0, 1.0, len(UBList) * len(self.getProperty("Filename").value)) for run in self.getProperty("Filename").value: logger.notice("Working on " + run) Load(Filename=run, OutputWorkspace='__run', FilterByTofMin=self.getProperty("FilterByTofMin").value, FilterByTofMax=self.getProperty("FilterByTofMax").value) if _load_inst: LoadInstrument( Workspace='__run', Filename=self.getProperty("LoadInstrument").value, RewriteSpectraMap=False) if _detcal: LoadIsawDetCal(InputWorkspace='__run', Filename=self.getProperty("DetCal").value) MaskDetectors(Workspace='__run', MaskedWorkspace='__sa') ConvertUnits(InputWorkspace='__run', OutputWorkspace='__run', Target='Momentum') CropWorkspace(InputWorkspace='__run', OutputWorkspace='__run', XMin=XMin, XMax=XMax) if self.getProperty('SetGoniometer').value: SetGoniometer( Workspace='__run', Goniometers=self.getProperty('Goniometers').value, Axis0=self.getProperty('Axis0').value, Axis1=self.getProperty('Axis1').value, Axis2=self.getProperty('Axis2').value) # Set background Goniometer to be the same as data if _background: mtd['__bkg'].run().getGoniometer().setR( mtd['__run'].run().getGoniometer().getR()) for ub in UBList: SetUB(Workspace='__run', UB=ub) ConvertToMD(InputWorkspace='__run', OutputWorkspace='__md', QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='HKL', QConversionScales='HKL', Uproj=self.getProperty('Uproj').value, Vproj=self.getProperty('Vproj').value, Wproj=self.getProperty('wproj').value, MinValues=MinValues, MaxValues=MaxValues) MDNormSCD( InputWorkspace=mtd['__md'], FluxWorkspace='__flux', SolidAngleWorkspace='__sa', OutputWorkspace='__data', SkipSafetyCheck=True, TemporaryDataWorkspace='__data' if mtd.doesExist('__data') else None, OutputNormalizationWorkspace='__norm', TemporaryNormalizationWorkspace='__norm' if mtd.doesExist('__norm') else None, AlignedDim0=mtd['__md'].getDimension(0).name + AlignedDim0, AlignedDim1=mtd['__md'].getDimension(1).name + AlignedDim1, AlignedDim2=mtd['__md'].getDimension(2).name + AlignedDim2) DeleteWorkspace('__md') if _background: SetUB(Workspace='__bkg', UB=ub) ConvertToMD(InputWorkspace='__bkg', OutputWorkspace='__bkg_md', QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='HKL', QConversionScales='HKL', Uproj=self.getProperty('Uproj').value, Vproj=self.getProperty('Vproj').value, Wproj=self.getProperty('Wproj').value, MinValues=MinValues, MaxValues=MaxValues) MDNormSCD( InputWorkspace='__bkg_md', FluxWorkspace='__flux', SolidAngleWorkspace='__sa', SkipSafetyCheck=True, OutputWorkspace='__bkg_data', TemporaryDataWorkspace='__bkg_data' if mtd.doesExist('__bkg_data') else None, OutputNormalizationWorkspace='__bkg_norm', TemporaryNormalizationWorkspace='__bkg_norm' if mtd.doesExist('__bkg_norm') else None, AlignedDim0=mtd['__bkg_md'].getDimension(0).name + AlignedDim0, AlignedDim1=mtd['__bkg_md'].getDimension(1).name + AlignedDim1, AlignedDim2=mtd['__bkg_md'].getDimension(2).name + AlignedDim2) DeleteWorkspace('__bkg_md') progress.report() DeleteWorkspace('__run') if _background: # outWS = data / norm - bkg_data / bkg_norm * BackgroundScale DivideMD(LHSWorkspace='__data', RHSWorkspace='__norm', OutputWorkspace=_outWS_name + '_normalizedData') DivideMD(LHSWorkspace='__bkg_data', RHSWorkspace='__bkg_norm', OutputWorkspace=_outWS_name + '_normalizedBackground') CreateSingleValuedWorkspace( OutputWorkspace='__scale', DataValue=self.getProperty('BackgroundScale').value) MultiplyMD(LHSWorkspace=_outWS_name + '_normalizedBackground', RHSWorkspace='__scale', OutputWorkspace='__scaled_background') DeleteWorkspace('__scale') MinusMD(LHSWorkspace=_outWS_name + '_normalizedData', RHSWorkspace='__scaled_background', OutputWorkspace=_outWS_name) if self.getProperty('KeepTemporaryWorkspaces').value: RenameWorkspaces(InputWorkspaces=[ '__data', '__norm', '__bkg_data', '__bkg_norm' ], WorkspaceNames=[ _outWS_name + '_data', _outWS_name + '_normalization', _outWS_name + '_background_data', _outWS_name + '_background_normalization' ]) else: # outWS = data / norm DivideMD(LHSWorkspace='__data', RHSWorkspace='__norm', OutputWorkspace=_outWS_name) if self.getProperty('KeepTemporaryWorkspaces').value: RenameWorkspaces(InputWorkspaces=['__data', '__norm'], WorkspaceNames=[ _outWS_name + '_data', _outWS_name + '_normalization' ]) self.setProperty("OutputWorkspace", mtd[_outWS_name]) # remove temp workspaces [ DeleteWorkspace(ws) for ws in self.temp_workspace_list if mtd.doesExist(ws) ]
def PyExec(self): inputWS = self.getProperty('InputWorkspace').value outputWS = self.getProperty('OutputWorkspace').valueAsStr xmins = self.getProperty('XMin').value xmaxs = self.getProperty('XMax').value if len(xmins) == 1 and len(xmaxs) == 1: name = '__{}_cropped_'.format(outputWS) CropWorkspace(InputWorkspace=inputWS, OutputWorkspace=name, XMin=xmins[0], XMax=xmaxs[0]) self.setProperty('OutputWorkspace', mtd[name]) DeleteWorkspace(name) else: numSpec = inputWS.getNumberHistograms() # fill out the values for min and max as appropriate # numpy 1.7 (on rhel7) doesn't have np.full if len(xmins) == 0: xmins = np.array([Property.EMPTY_DBL] * numSpec) elif len(xmins) == 1: xmins = np.array([xmins[0]] * numSpec) if len(xmaxs) == 0: xmaxs = np.array([Property.EMPTY_DBL] * numSpec) elif len(xmaxs) == 1: xmaxs = np.array([xmaxs[0]] * numSpec) # replace nan with EMPTY_DBL in xmin/xmax indices = np.where(np.invert(np.isfinite(xmins))) xmins[indices] = Property.EMPTY_DBL indices = np.where(np.invert(np.isfinite(xmaxs))) xmaxs[indices] = Property.EMPTY_DBL self.log().information('MIN: ' + str(xmins)) self.log().information('MAX: ' + str(xmaxs)) # temporary workspaces should be hidden names = [ '__{}_spec_{}'.format(outputWS, i) for i in range(len(xmins)) ] # how much the progress bar moves forward for each spectrum progStep = float(1) / float(2 * numSpec) # crop out each spectra and conjoin to a temporary workspace accumulationWS = None for i, (name, xmin, xmax) in enumerate(zip(names, xmins, xmaxs)): # don't go beyond the range of the data x = inputWS.readX(i) if xmin < x[0]: xmin = Property.EMPTY_DBL if xmax > x[-1]: xmax = Property.EMPTY_DBL progStart = 2 * i * progStep # extract the range of the spectrum requested CropWorkspace(InputWorkspace=inputWS, OutputWorkspace=name, StartWorkspaceIndex=i, EndWorkspaceIndex=i, XMin=xmin, XMax=xmax, startProgress=progStart, endProgress=(progStart + progStep), EnableLogging=False) # accumulate if accumulationWS is None: accumulationWS = name # messes up progress during very first step else: ConjoinWorkspaces(InputWorkspace1=accumulationWS, InputWorkspace2=name, startProgress=(progStart + progStep), endProgress=(progStart + 2 * progStep), EnableLogging=False) self.setProperty('OutputWorkspace', mtd[accumulationWS]) DeleteWorkspace(accumulationWS)
def PyExec(self): # remove possible old temp workspaces [ DeleteWorkspace(ws) for ws in self.temp_workspace_list if mtd.doesExist(ws) ] _background = bool(self.getProperty("Background").value) self._load_inst = bool(self.getProperty("LoadInstrument").value) self._apply_cal = bool(self.getProperty("ApplyCalibration").value) self._detcal = bool(self.getProperty("DetCal").value) self._copy_params = bool( self.getProperty("CopyInstrumentParameters").value) _masking = bool(self.getProperty("MaskFile").value) _outWS_name = self.getPropertyValue("OutputWorkspace") _UB = self.getProperty("UBMatrix").value if len(_UB) == 1: _UB = np.tile(_UB, len(self.getProperty("Filename").value)) _offsets = self.getProperty("OmegaOffset").value if len(_offsets) == 0: _offsets = np.zeros(len(self.getProperty("Filename").value)) if self.getProperty("ReuseSAFlux").value and mtd.doesExist( '__sa') and mtd.doesExist('__flux'): logger.notice( "Reusing previously loaded SolidAngle and Flux workspaces. " "Set ReuseSAFlux to False if new files are selected or you change the momentum range." ) else: logger.notice("Loading SolidAngle and Flux from file") LoadNexus(Filename=self.getProperty("SolidAngle").value, OutputWorkspace='__sa') LoadNexus(Filename=self.getProperty("Flux").value, OutputWorkspace='__flux') if _masking: LoadMask(Instrument=mtd['__sa'].getInstrument().getName(), InputFile=self.getProperty("MaskFile").value, OutputWorkspace='__mask') MaskDetectors(Workspace='__sa', MaskedWorkspace='__mask') DeleteWorkspace('__mask') self.XMin = mtd['__sa'].getXDimension().getMinimum() self.XMax = mtd['__sa'].getXDimension().getMaximum() newXMin = self.getProperty("MomentumMin").value newXMax = self.getProperty("MomentumMax").value if newXMin != Property.EMPTY_DBL or newXMax != Property.EMPTY_DBL: if newXMin != Property.EMPTY_DBL: self.XMin = max(self.XMin, newXMin) if newXMax != Property.EMPTY_DBL: self.XMax = min(self.XMax, newXMax) logger.notice("Using momentum range {} to {} A^-1".format( self.XMin, self.XMax)) CropWorkspace(InputWorkspace='__flux', OutputWorkspace='__flux', XMin=self.XMin, XMax=self.XMax) for spectrumNumber in range(mtd['__flux'].getNumberHistograms()): Y = mtd['__flux'].readY(spectrumNumber) mtd['__flux'].setY(spectrumNumber, (Y - Y.min()) / (Y.max() - Y.min())) MinValues = [-self.XMax * 2] * 3 MaxValues = [self.XMax * 2] * 3 if _background: self.load_file_and_apply( self.getProperty("Background").value, '__bkg', 0) progress = Progress(self, 0.0, 1.0, len(self.getProperty("Filename").value)) for n, run in enumerate(self.getProperty("Filename").value): logger.notice("Working on " + run) self.load_file_and_apply(run, '__run', _offsets[n]) LoadIsawUB('__run', _UB[n]) ConvertToMD(InputWorkspace='__run', OutputWorkspace='__md', QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='Q_sample', MinValues=MinValues, MaxValues=MaxValues) RecalculateTrajectoriesExtents(InputWorkspace='__md', OutputWorkspace='__md') MDNorm( InputWorkspace='__md', FluxWorkspace='__flux', SolidAngleWorkspace='__sa', OutputDataWorkspace='__data', TemporaryDataWorkspace='__data' if mtd.doesExist('__data') else None, OutputNormalizationWorkspace='__norm', TemporaryNormalizationWorkspace='__norm' if mtd.doesExist('__norm') else None, OutputWorkspace=_outWS_name, QDimension0=self.getProperty('QDimension0').value, QDimension1=self.getProperty('QDimension1').value, QDimension2=self.getProperty('QDimension2').value, Dimension0Binning=self.getProperty('Dimension0Binning').value, Dimension1Binning=self.getProperty('Dimension1Binning').value, Dimension2Binning=self.getProperty('Dimension2Binning').value, SymmetryOperations=self.getProperty( 'SymmetryOperations').value) DeleteWorkspace('__md') if _background: # Set background Goniometer and UB to be the same as data CopySample(InputWorkspace='__run', OutputWorkspace='__bkg', CopyName=False, CopyMaterial=False, CopyEnvironment=False, CopyShape=False, CopyLattice=True) mtd['__bkg'].run().getGoniometer().setR( mtd['__run'].run().getGoniometer().getR()) ConvertToMD(InputWorkspace='__bkg', OutputWorkspace='__bkg_md', QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='Q_sample', MinValues=MinValues, MaxValues=MaxValues) RecalculateTrajectoriesExtents(InputWorkspace='__bkg_md', OutputWorkspace='__bkg_md') MDNorm(InputWorkspace='__bkg_md', FluxWorkspace='__flux', SolidAngleWorkspace='__sa', OutputDataWorkspace='__bkg_data', TemporaryDataWorkspace='__bkg_data' if mtd.doesExist('__bkg_data') else None, OutputNormalizationWorkspace='__bkg_norm', TemporaryNormalizationWorkspace='__bkg_norm' if mtd.doesExist('__bkg_norm') else None, OutputWorkspace='__normalizedBackground', QDimension0=self.getProperty('QDimension0').value, QDimension1=self.getProperty('QDimension1').value, QDimension2=self.getProperty('QDimension2').value, Dimension0Binning=self.getProperty( 'Dimension0Binning').value, Dimension1Binning=self.getProperty( 'Dimension1Binning').value, Dimension2Binning=self.getProperty( 'Dimension2Binning').value, SymmetryOperations=self.getProperty( 'SymmetryOperations').value) DeleteWorkspace('__bkg_md') progress.report() DeleteWorkspace('__run') if _background: # outWS = data / norm - bkg_data / bkg_norm * BackgroundScale CreateSingleValuedWorkspace( OutputWorkspace='__scale', DataValue=self.getProperty('BackgroundScale').value) MultiplyMD(LHSWorkspace='__normalizedBackground', RHSWorkspace='__scale', OutputWorkspace='__normalizedBackground') DeleteWorkspace('__scale') MinusMD(LHSWorkspace=_outWS_name, RHSWorkspace='__normalizedBackground', OutputWorkspace=_outWS_name) if self.getProperty('KeepTemporaryWorkspaces').value: RenameWorkspaces(InputWorkspaces=[ '__data', '__norm', '__bkg_data', '__bkg_norm' ], WorkspaceNames=[ _outWS_name + '_data', _outWS_name + '_normalization', _outWS_name + '_background_data', _outWS_name + '_background_normalization' ]) else: if self.getProperty('KeepTemporaryWorkspaces').value: RenameWorkspaces(InputWorkspaces=['__data', '__norm'], WorkspaceNames=[ _outWS_name + '_data', _outWS_name + '_normalization' ]) self.setProperty("OutputWorkspace", mtd[_outWS_name]) # remove temp workspaces [ DeleteWorkspace(ws) for ws in self.temp_workspace_list if mtd.doesExist(ws) ]