def sel(sample, const): """ Convert workspace into normalised spin echo units Parameters ---------- sample : str The name of the workspace to be converted const : float The spin echo length of a one angstrom neutron in nanometers Returns ------- The name of a workspace with the x coordinate in proper spin echo units and the y coordinate in log(P/P₀)/λ² """ wtemp = mtd[sample] x = wtemp.extractX() y = wtemp.extractY() e = wtemp.extractE() dx = (x[:, 1:] + x[:, :-1]) / 2 wtemp = ConvertUnits(sample, "SpinEchoLength", EFixed=const) wenv = CreateWorkspace(wtemp.extractX(), np.log(y) / dx**2, e / y / dx**2, UnitX="SpinEchoLength", YUnitLabel="Counts") RenameWorkspace(wenv, OutputWorkspace=sample + "_sel")
def _save(self, runnumber, basename, norm): if not self.getProperty("SaveData").value: return saveDir = self.getProperty("OutputDirectory").value.strip() if len(saveDir) <= 0: self.log().notice('Using default save location') saveDir = os.path.join( self.get_IPTS_Local(runnumber), 'shared', 'data') self.log().notice('Writing to \'' + saveDir + '\'') if norm == 'None': SaveNexusProcessed(InputWorkspace='WS_red', Filename=os.path.join(saveDir, 'nexus', basename + '.nxs')) SaveAscii(InputWorkspace='WS_red', Filename=os.path.join(saveDir, 'd_spacing', basename + '.dat')) ConvertUnits(InputWorkspace='WS_red', OutputWorkspace='WS_tof', Target="TOF", AlignBins=False) else: SaveNexusProcessed(InputWorkspace='WS_nor', Filename=os.path.join(saveDir, 'nexus', basename + '.nxs')) SaveAscii(InputWorkspace='WS_nor', Filename=os.path.join(saveDir, 'd_spacing', basename + '.dat')) ConvertUnits(InputWorkspace='WS_nor', OutputWorkspace='WS_tof', Target="TOF", AlignBins=False) SaveGSS(InputWorkspace='WS_tof', Filename=os.path.join(saveDir, 'gsas', basename + '.gsa'), Format='SLOG', SplitFiles=False, Append=False, ExtendedHeader=True) SaveFocusedXYE(InputWorkspace='WS_tof', Filename=os.path.join( saveDir, 'fullprof', basename + '.dat'), SplitFiles=True, Append=False) DeleteWorkspace(Workspace='WS_tof')
def setUp(self): """ Create sample workspaces. """ # Load the sample and can sample_ws = Load('irs26176_graphite002_red.nxs') can_ws = Load('irs26173_graphite002_red.nxs') # Convert sample and can to wavelength sample_ws = ConvertUnits(InputWorkspace=sample_ws, Target='Wavelength', EMode='Indirect', EFixed=1.845) can_ws = ConvertUnits(InputWorkspace=can_ws, Target='Wavelength', EMode='Indirect', EFixed=1.845) self._sample_ws = sample_ws self._can_ws = can_ws # Load the corrections workspace corrections = Load('irs26176_graphite002_cyl_Abs.nxs') # Interpolate each of the correction factor workspaces # Required to use corrections from the old indirect calculate # corrections routines for factor_ws in corrections: SplineInterpolation(WorkspaceToMatch=sample_ws, WorkspaceToInterpolate=factor_ws, OutputWorkspace=factor_ws, OutputWorkspaceDeriv='') self._corrections_ws = corrections
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 _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 __processFile(self, filename, wkspname, file_prog_start, determineCharacterizations): chunks = determineChunking(filename, self.chunkSize) self.log().information('Processing \'%s\' in %d chunks' % (filename, len(chunks))) prog_per_chunk_step = self.prog_per_file * 1./(6.*float(len(chunks))) # for better progress reporting - 6 steps per chunk # inner loop is over chunks for (j, chunk) in enumerate(chunks): prog_start = file_prog_start + float(j) * 5. * prog_per_chunk_step chunkname = "%s_c%d" % (wkspname, j) Load(Filename=filename, OutputWorkspace=chunkname, startProgress=prog_start, endProgress=prog_start+prog_per_chunk_step, **chunk) if determineCharacterizations: self.__determineCharacterizations(filename, chunkname, False) # updates instance variable determineCharacterizations = False prog_start += prog_per_chunk_step if self.filterBadPulses > 0.: FilterBadPulses(InputWorkspace=chunkname, OutputWorkspace=chunkname, LowerCutoff=self.filterBadPulses, startProgress=prog_start, endProgress=prog_start+prog_per_chunk_step) prog_start += prog_per_chunk_step # absorption correction workspace if self.absorption is not None and len(str(self.absorption)) > 0: ConvertUnits(InputWorkspace=chunkname, OutputWorkspace=chunkname, Target='Wavelength', EMode='Elastic') Divide(LHSWorkspace=chunkname, RHSWorkspace=self.absorption, OutputWorkspace=chunkname, startProgress=prog_start, endProgress=prog_start+prog_per_chunk_step) ConvertUnits(InputWorkspace=chunkname, OutputWorkspace=chunkname, Target='TOF', EMode='Elastic') prog_start += prog_per_chunk_step AlignAndFocusPowder(InputWorkspace=chunkname, OutputWorkspace=chunkname, startProgress=prog_start, endProgress=prog_start+2.*prog_per_chunk_step, **self.kwargs) prog_start += 2.*prog_per_chunk_step # AlignAndFocusPowder counts for two steps if j == 0: self.__updateAlignAndFocusArgs(chunkname) RenameWorkspace(InputWorkspace=chunkname, OutputWorkspace=wkspname) else: Plus(LHSWorkspace=wkspname, RHSWorkspace=chunkname, OutputWorkspace=wkspname, ClearRHSWorkspace=self.kwargs['PreserveEvents'], startProgress=prog_start, endProgress=prog_start+prog_per_chunk_step) DeleteWorkspace(Workspace=chunkname) if self.kwargs['PreserveEvents']: CompressEvents(InputWorkspace=wkspname, OutputWorkspace=wkspname)
def test_ILL_reduced(self): ill_red_ws = Load('ILL/IN16B/091515_red.nxs') ill_red_ws = ConvertUnits(ill_red_ws, Target='Wavelength', EMode='Indirect', EFixed=1.845) kwargs = self._arguments corrected = SimpleShapeMonteCarloAbsorption(InputWorkspace=ill_red_ws, Shape='FlatPlate', Width=2.0, Thickness=2.0, **kwargs) x_unit = corrected.getAxis(0).getUnit().unitID() self.assertEquals(x_unit, 'Wavelength') y_unit = corrected.YUnitLabel() self.assertEquals(y_unit, 'Attenuation factor') num_hists = corrected.getNumberHistograms() self.assertEquals(num_hists, 18) blocksize = corrected.blocksize() self.assertEquals(blocksize, 1024) DeleteWorkspace(ill_red_ws)
def processData(self, filename, wsName): if filename != '': if self._SystemTest: Load(Filename=filename, OutputWorkspace=wsName, BankName = 'bank22') else: Load(Filename=filename, OutputWorkspace=wsName) FindDetectorsPar(InputWorkspace=wsName, ReturnLinearRanges=self._returnLinearRanges, ParFile=self._parFile, OutputParTable=self._outputParTable) FilterBadPulses(InputWorkspace=wsName, Outputworkspace=wsName, LowerCutoff=self._lowerCutoff) RemovePromptPulse(InputWorkspace=wsName, OutputWorkspace=wsName, Width=self._width, Frequency=self._frequency) LoadDiffCal(InputWorkspace=wsName, InstrumentName=self._instrumentName, InstrumentFilename=self._instrumentFilename, Filename=self._filename, MakeGroupingWorkspace=self._makeGroupingWorkspace, MakeCalWorkspace=self._makeCalWorkspace, MakeMaskWorkspace=self._makeMaskWorkspace, WorkspaceName=self._workspaceName, TofMin=self._tofMin, TofMax=self._tofMax, FixConversionIssues=self._fixConversionIssues) MaskDetectors(Workspace=wsName, SpectraList=self._spectraList, DetectorList=self._detectorList, WorkspaceIndexList=self._workspaceIndexList, MaskedWorkspace=self._maskedWorkspace, ForceInstrumentMasking=self._forceInstrumentMasking, StartWorkspaceIndex=self._startWorkspaceIndex, EndWorkspaceIndex=self._endWorkspaceIndex, ComponentList=self._componentList) AlignDetectors(InputWorkspace=wsName, OutputWorkspace=wsName, CalibrationFile=self._calibrationFile) ConvertUnits(InputWorkspace=wsName, OutputWorkspace=wsName, Target='Wavelength')
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 setUp(self): red_ws = Load('irs26176_graphite002_red.nxs') red_ws = ConvertUnits(InputWorkspace=red_ws, Target='Wavelength', EMode='Indirect', EFixed=1.845) self._arguments = { 'ChemicalFormula': 'H2-O', 'DensityType': 'Mass Density', 'Density': 1.0, 'EventsPerPoint': 200, 'BeamHeight': 3.5, 'BeamWidth': 4.0, 'Height': 2.0 } self._red_ws = red_ws corrected = SimpleShapeMonteCarloAbsorption( InputWorkspace=self._red_ws, Shape='FlatPlate', Width=2.0, Thickness=2.0, **self._arguments) # store the basic flat plate workspace so it can be compared with others self._corrected_flat_plate = corrected
def test_not_in_deltaE(self): red_ws_not_deltaE = Load('irs26176_graphite002_red.nxs') red_ws_not_deltaE = ConvertUnits(InputWorkspace=self._red_ws, Target='Wavelength', EMode='Indirect', EFixed=1.845) kwargs = { 'ReducedWorkspace': red_ws_not_deltaE, 'SqwWorkspace': self._sqw_ws, 'ChemicalFormula': 'H2-O', 'SampleMassDensity': 1.0, 'NeutronPathsSingle': 50, 'NeutronPathsMultiple': 50, 'Height': 2.0, 'Shape': 'FlatPlate', 'Width': 1.4, 'Thickness': 2.1 } with self.assertRaises(RuntimeError): SimpleShapeDiscusInelastic(**kwargs) DeleteWorkspace(red_ws_not_deltaE)
def test_adsrp_cylinder(self): ash = Cylinder('V', [10, 2]) res = ash.shape self.assertEqual(res['Height'], 10) self.assertEqual(res['Radius'], 2) self.assertTrue(ash._axis_is_default) ash.shape = [5, 1, [0, 1, 0], [0., 0., -0.5]] res = ash.shape self.assertEqual(res['Height'], 5) self.assertEqual(res['Radius'], 1) self.assertEqual(res['Axis'], [0, 1, 0]) self.assertEqual(res['Center'], [0, 0, -0.5]) self.assertFalse(ash._axis_is_default) ash.shape = {'Height': 5, 'Radius': 2, 'Axis': [1, 0, 0], 'Center': [0., 0., 0.]} res = ash.shape self.assertEqual(res['Height'], 5) self.assertEqual(res['Radius'], 2) self.assertEqual(res['Axis'], [1, 0, 0]) self.assertEqual(res['Center'], [0, 0, 0]) test_ws = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=1) test_ws = ConvertUnits(test_ws, 'DeltaE', Emode='Direct', EFixed=2000) cor_ws, corrections = ash.correct_absorption(test_ws, is_fast=True) n_bins = corrections.blocksize() corr_ranges = [n_bins, corrections.readY(0)[0], corrections.readY(0)[n_bins - 1]] np.testing.assert_almost_equal(corr_ranges, [97, 0.0, 0.0], 4) mccor_ws, mc_corr = ash.correct_absorption(test_ws, EventsPerPoint=300) n_bins = mc_corr.blocksize() mccorr_ranges = [n_bins, mc_corr.readY(0)[0], mc_corr.readY(0)[n_bins - 1]] np.testing.assert_almost_equal(mccorr_ranges, [97, 0.266, 0.033], 3)
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 _convert_units(self, workspace, target, emode, efixed): return ConvertUnits(InputWorkspace=workspace, OutputWorkspace="__units_converted", Target=target, EMode=emode, EFixed=efixed, StoreInADS=False)
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 load_files(self, filenames_string, xunit): self._last_added = [] filenames = [name.strip() for name in filenames_string.split(",")] for filename in filenames: ws_name = self._generate_workspace_name(filename, xunit) if ws_name not in self._loaded_workspaces: try: if not ADS.doesExist(ws_name): ws = Load(filename, OutputWorkspace=ws_name) if xunit != "TOF": ConvertUnits(InputWorkspace=ws, OutputWorkspace=ws_name, Target=xunit) else: ws = ADS.retrieve(ws_name) if ws.getNumberHistograms() == 1: self._loaded_workspaces[ws_name] = ws if ws_name not in self._background_workspaces: self._background_workspaces[ws_name] = None self._last_added.append(ws_name) self.add_log_to_table(ws_name, ws) else: logger.warning( f"Invalid number of spectra in workspace {ws_name}. Skipping loading of file.") except RuntimeError as e: logger.error( f"Failed to load file: {filename}. Error: {e}. \n Continuing loading of other files.") else: logger.warning(f"File {ws_name} has already been loaded")
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 _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 runTest(self): ws = DirectILLCollectData('ILL/IN6/164192.nxs', ElasticChannel='Default Elastic Channel', FlatBkg='Flat Bkg OFF', Normalisation='Normalisation OFF') for i in range(ws.getNumberHistograms()): ws.dataY(i).fill(1) dE = ConvertUnits(ws, 'DeltaE', 'Direct') corr = DetectorEfficiencyCorUser(dE) Ei = corr.run().get('Ei').value def det_corr(x): high = x > 5.113 low = x <= 5.113 c = numpy.empty_like(x) c[high] = 0.94 * (1. - numpy.exp(-3.284 / numpy.sqrt(x[high]))) c[low] = numpy.exp(-0.0565 / numpy.sqrt(x[low])) * ( 1. - numpy.exp(-3.284 / numpy.sqrt(x[low]))) return c corr_at_Ei = det_corr(numpy.array([Ei]))[0] for i in range(corr.getNumberHistograms()): x = (corr.readX(i)[:-1] + corr.readX(i)[1:]) / 2. e = Ei - x numpy.testing.assert_almost_equal(corr.readY(i), corr_at_Ei / det_corr(e))
def _save(self, saveDir, basename, outputWksp): if not self.getProperty("SaveData").value: return self.log().notice('Writing to \'' + saveDir + '\'') SaveNexusProcessed(InputWorkspace=outputWksp, Filename=os.path.join(saveDir, 'nexus', basename + '.nxs')) SaveAscii(InputWorkspace=outputWksp, Filename=os.path.join(saveDir, 'd_spacing', basename + '.dat')) ConvertUnits(InputWorkspace=outputWksp, OutputWorkspace='WS_tof', Target="TOF", AlignBins=False) # GSAS and FullProf require data in time-of-flight SaveGSS(InputWorkspace='WS_tof', Filename=os.path.join(saveDir, 'gsas', basename + '.gsa'), Format='SLOG', SplitFiles=False, Append=False, ExtendedHeader=True) SaveFocusedXYE(InputWorkspace='WS_tof', Filename=os.path.join(saveDir, 'fullprof', basename + '.dat'), SplitFiles=True, Append=False) DeleteWorkspace(Workspace='WS_tof')
def test_adsrp_hollow_cylinder(self): ash = HollowCylinder('V', [10, 2, 4]) res = ash.shape self.assertEqual(res['Height'], 10) self.assertEqual(res['InnerRadius'], 2) self.assertEqual(res['OuterRadius'], 4) ash.shape = [5, 1, 2, [1, 0, 0], [0, 0, 0]] res = ash.shape self.assertEqual(res['Height'], 5) self.assertEqual(res['InnerRadius'], 1) self.assertEqual(res['OuterRadius'], 2) self.assertEqual(res['Axis'], [1, 0, 0]) self.assertEqual(res['Center'], [0, 0, 0]) ash.shape = {'Height': 5, 'InnerRadius': 0.01, 'OuterRadius': 2, 'Center': [0., 0., 0.], 'Axis': [0, 1, 0]} res = ash.shape self.assertEqual(res['Height'], 5) self.assertEqual(res['InnerRadius'], 0.01) self.assertEqual(res['OuterRadius'], 2) self.assertEqual(res['Axis'], [0, 1, 0]) self.assertEqual(res['Center'], [0, 0, 0]) test_ws = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=1) test_ws = ConvertUnits(test_ws, 'DeltaE', Emode='Direct', EFixed=2000) cor_ws, corrections = ash.correct_absorption(test_ws, is_fast=True, ElementSize=5) n_bins = corrections.blocksize() corr_ranges = [n_bins, corrections.readY(0)[0], corrections.readY(0)[n_bins - 1]] np.testing.assert_almost_equal(corr_ranges, [97, 0.0, 0.000], 4) mccor_ws, mc_corr = ash.correct_absorption(test_ws, is_mc=True, EventsPerPoint=300) n_bins = mc_corr.blocksize() mccorr_ranges = [n_bins, mc_corr.readY(0)[0], mc_corr.readY(0)[n_bins - 1]] np.testing.assert_almost_equal(mccorr_ranges, [97, 0.27, 0.03], 2)
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 load_file_and_apply(self, filename, ws_name): Load(Filename=filename, OutputWorkspace=ws_name, FilterByTofMin=self.getProperty("FilterByTofMin").value, FilterByTofMax=self.getProperty("FilterByTofMax").value) if self._load_inst: LoadInstrument(Workspace=ws_name, Filename=self.getProperty("LoadInstrument").value, RewriteSpectraMap=False) if self._apply_cal: ApplyCalibration( Workspace=ws_name, CalibrationTable=self.getProperty("ApplyCalibration").value) if self._detcal: LoadIsawDetCal(InputWorkspace=ws_name, Filename=self.getProperty("DetCal").value) if self._copy_params: CopyInstrumentParameters(OutputWorkspace=ws_name, InputWorkspace=self.getProperty( "CopyInstrumentParameters").value) if self._masking: if not mtd.doesExist('__mask'): LoadMask(Instrument=mtd[ws_name].getInstrument().getName(), InputFile=self.getProperty("MaskFile").value, OutputWorkspace='__mask') MaskDetectors(Workspace=ws_name, MaskedWorkspace='__mask') if self.XMin != Property.EMPTY_DBL and self.XMax != Property.EMPTY_DBL: ConvertUnits(InputWorkspace=ws_name, OutputWorkspace=ws_name, Target='Momentum') CropWorkspaceForMDNorm(InputWorkspace=ws_name, OutputWorkspace=ws_name, XMin=self.XMin, XMax=self.XMax)
def calibrate_region_of_interest(ceria_d_ws, roi: str, grouping_kwarg: dict, cal_output: dict) -> None: """ Focus the processed ceria workspace (dSpacing) over the chosen region of interest, and run the calibration using this result :param ceria_d_ws: Workspace containing the processed ceria data converted to dSpacing :param roi: String describing chosen region of interest :param grouping_kwarg: Dict containing kwarg to pass to DiffractionFocussing to select the roi :param cal_output: Dictionary to append with the output of PDCalibration for the chosen roi """ # focus ceria focused_ceria = DiffractionFocussing(InputWorkspace=ceria_d_ws, **grouping_kwarg) ApplyDiffCal(InstrumentWorkspace=focused_ceria, ClearCalibration=True) ConvertUnits(InputWorkspace=focused_ceria, OutputWorkspace=focused_ceria, Target='TOF') # calibration of focused data over chosen region of interest kwargs["InputWorkspace"] = focused_ceria kwargs["OutputCalibrationTable"] = "engggui_calibration_" + roi kwargs["DiagnosticWorkspaces"] = "diag_" + roi cal_roi = run_pd_calibration(kwargs)[0] cal_output[roi] = cal_roi
def runTest(self): ws = DirectILLCollectData('ILL/IN4/084446.nxs', ElasticChannel='Default Elastic Channel', FlatBkg='Flat Bkg OFF', Normalisation='Normalisation OFF') for i in range(ws.getNumberHistograms()): ws.dataY(i).fill(1) dE = ConvertUnits(ws, 'DeltaE', 'Direct') corr = DetectorEfficiencyCorUser(dE) Ei = corr.run().get('Ei').value def rosace_corr(x): return 1.0 - numpy.exp(-6.1343 / numpy.sqrt(x)) def wide_angle_corr(x): return 0.951 * numpy.exp(-0.0887 / numpy.sqrt(x)) * (1 - numpy.exp(-5.597 / numpy.sqrt(x))) def eff_factor(x, corr_func): return corr_func(Ei) / corr_func(x) # Wide-angle detectors are at ws indices 0-299 for i in range(0, 300): x = (corr.readX(i)[:-1] + corr.readX(i)[1:]) / 2. e = Ei - x assert_almost_equal(corr.readY(i), eff_factor(e, wide_angle_corr)) # Rosace detectors are at ws indices 300-395 for i in range(300, 396): x = (corr.readX(i)[:-1] + corr.readX(i)[1:]) / 2. e = Ei - x assert_almost_equal(corr.readY(i), eff_factor(e, rosace_corr))
def _save(self, runnumber, basename, outputWksp): if not self.getProperty("SaveData").value: return # determine where to save the data saveDir = self.getPropertyValue("OutputDirectory").strip() if len(saveDir) <= 0: self.log().notice('Using default save location') saveDir = os.path.join(self.get_IPTS_Local(runnumber), 'shared', 'data') self.log().notice('Writing to \'' + saveDir + '\'') SaveNexusProcessed(InputWorkspace=outputWksp, Filename=os.path.join(saveDir, 'nexus', basename + '.nxs')) SaveAscii(InputWorkspace=outputWksp, Filename=os.path.join(saveDir, 'd_spacing', basename + '.dat')) ConvertUnits(InputWorkspace=outputWksp, OutputWorkspace='WS_tof', Target="TOF", AlignBins=False) # GSAS and FullProf require data in time-of-flight SaveGSS(InputWorkspace='WS_tof', Filename=os.path.join(saveDir, 'gsas', basename + '.gsa'), Format='SLOG', SplitFiles=False, Append=False, ExtendedHeader=True) SaveFocusedXYE(InputWorkspace='WS_tof', Filename=os.path.join( saveDir, 'fullprof', basename + '.dat'), SplitFiles=True, Append=False) DeleteWorkspace(Workspace='WS_tof')
def test_adsrp_Plate(self): ash = FlatPlate('V', [10, 2, 0.1]) res = ash.shape self.assertEqual(res['Height'], 10) self.assertEqual(res['Width'], 2) self.assertEqual(res['Thick'], 0.1) ash.shape = [5, 1, 0.2, [0, 1, 0], 10] res = ash.shape self.assertEqual(res['Height'], 5) self.assertEqual(res['Width'], 1) self.assertEqual(res['Thick'], 0.2) self.assertEqual(res['Center'], [0, 1, 0]) self.assertEqual(res['Angle'], 10) ash.shape = {'Height': 5, 'Width': 1, 'Thick': 2, 'Center': [0., 0., 0.], 'Angle': 20} res = ash.shape self.assertEqual(res['Height'], 5) self.assertEqual(res['Width'], 1) self.assertEqual(res['Thick'], 2) self.assertEqual(res['Center'], [0, 0, 0]) self.assertEqual(res['Angle'], 20) test_ws = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=1) test_ws = ConvertUnits(test_ws, 'DeltaE', Emode='Direct', EFixed=2000) cor_ws, corrections = ash.correct_absorption(test_ws, is_fast=True, ElementSize=5) n_bins = corrections.blocksize() corr_ranges = [n_bins, corrections.readY(0)[0], corrections.readY(0)[n_bins - 1]] np.testing.assert_almost_equal(corr_ranges, [97, 0., 0.], 4) mccor_ws, mc_corr = ash.correct_absorption(test_ws, is_mc=True, EventsPerPoint=300) n_bins = mc_corr.blocksize() mccorr_ranges = [n_bins, mc_corr.readY(0)[0], mc_corr.readY(0)[n_bins - 1]] np.testing.assert_almost_equal(mccorr_ranges, [97, 0.52, 0.13], 2)
def test_adsrp_sphere(self): ash = Sphere('Al', 10) res = ash.shape self.assertEqual(res['Radius'], 10) ash.shape = [5, [1, 0, 0]] res = ash.shape rad = res['Radius'] self.assertEqual(rad, 5) cen = res['Center'] self.assertEqual(cen, [1, 0, 0]) ash.shape = {'Radius': 3, 'Center': [0., 0., 0.]} res = ash.shape rad = res['Radius'] self.assertEqual(rad, 3) cen = res['Center'] self.assertEqual(cen, [0, 0, 0]) test_ws = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=1) test_ws = ConvertUnits(test_ws, 'DeltaE', Emode='Direct', EFixed=2000) cor_ws, corrections = ash.correct_absorption(test_ws, is_fast=True, ElementSize=6) n_bins = corrections.blocksize() corr_ranges = [n_bins, corrections.readY(0)[0], corrections.readY(0)[n_bins - 1]] np.testing.assert_almost_equal(corr_ranges, [97, 0.0, 0.0], 4) cor_ws, corrections = ash.correct_absorption(test_ws, is_fast=True) n_bins = corrections.blocksize() corr_ranges = [n_bins, corrections.readY(0)[0], corrections.readY(0)[n_bins - 1]] np.testing.assert_almost_equal(corr_ranges, [97, 0.0, 0.0], 4) mccor_ws, mc_corr = ash.correct_absorption(test_ws, is_mc=True, EventsPerPoint=300) n_bins = mc_corr.blocksize() mccorr_ranges = [n_bins, mc_corr.readY(0)[0], mc_corr.readY(0)[n_bins - 1]] np.testing.assert_almost_equal(mccorr_ranges, [97, 0.66, 0.51], 2)
def _whole_inst_prefocus(input_workspace, vanadium_integration_ws, full_calib) -> bool: """This is used to perform the operations done on the whole instrument workspace, before the chosen region of interest is focused using _run_focus :param input_workspace: Raw sample run to process prior to focussing over a region of interest :param vanadium_integration_ws: Integral of the supplied vanadium run :param full_calib: Full instrument calibration workspace (table ws output from PDCalibration) :return True if successful, False if aborted """ if input_workspace.getRun().getProtonCharge() > 0: NormaliseByCurrent(InputWorkspace=input_workspace, OutputWorkspace=input_workspace) else: logger.warning( f"Skipping focus of run {input_workspace.name()} because it has invalid proton charge." ) return False input_workspace /= vanadium_integration_ws # replace nans created in sensitivity correction ReplaceSpecialValues(InputWorkspace=input_workspace, OutputWorkspace=input_workspace, NaNValue=0, InfinityValue=0) ApplyDiffCal(InstrumentWorkspace=input_workspace, CalibrationWorkspace=full_calib) ConvertUnits(InputWorkspace=input_workspace, OutputWorkspace=input_workspace, Target='dSpacing') return True
def spacings_recovered(self, input_workspace, calibrate=True): r"""Compare the input_workspace to the reference workspace 'test_workspace_dSpacing' after being converted to TOF units. If calibrate=True, calibrate first and then convert units""" if calibrate: CorelliPowderCalibrationCreate( InputWorkspace='perturbed', OutputWorkspacesPrefix='cal_', TofBinning=[300, 1.0, 16666.7], PeakPositions=self.spacings_reference, SourceToSampleDistance=10.0, ComponentList='bank1', FixY=False, ComponentMaxTranslation=0.03, FixYaw=False, ComponentMaxRotation=6, Minimizer='differential_evolution', MaxIterations=10) ConvertUnits(InputWorkspace='perturbed', Target='dSpacing', EMode='Elastic', OutputWorkspace='perturbed_dS') results = CompareWorkspaces(Workspace1='test_workspace_dSpacing', Workspace2='perturbed_dS', Tolerance=0.001, CheckInstrument=False) DeleteWorkspaces(['perturbed_dS']) return results.Result
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: SetSampleMaterial( InputWorkspace=self._output_ws, ChemicalFormula=self._chemical_formula, SampleNumberDensity=self._density, StoreInADS=False) 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)
class CalculateEfficiencyCorrection(PythonAlgorithm): _input_ws = None _output_ws = None def category(self): return 'CorrectionFunctions\\EfficiencyCorrections' def name(self): return 'CalculateEfficiencyCorrection' def summary(self): return 'Calculate an efficiency correction using various inputs. Can be used to determine \ an incident spectrum after correcting a measured spectrum from beam monitors \ or vanadium measurements.' def seeAlso(self): return [ "He3TubeEfficiency", "CalculateSampleTransmission", "DetectorEfficiencyCor", "DetectorEfficiencyCorUser", "CalculateEfficiency", "ComputeCalibrationCoefVan" ] def PyInit(self): self.declareProperty( MatrixWorkspaceProperty('InputWorkspace', '', direction=Direction.Input, optional=PropertyMode.Optional, validator=CommonBinsValidator()), doc='Input workspace with wavelength range to calculate for the correction.') self.declareProperty(name='WavelengthRange', defaultValue='', doc='Wavelength range to calculate efficiency for.') self.declareProperty( MatrixWorkspaceProperty('OutputWorkspace', '', direction=Direction.Output), doc="Output workspace for the efficiency correction. \ This can be applied by multiplying the OutputWorkspace \ to the workspace that requires the correction.") self.declareProperty( name='ChemicalFormula', defaultValue='None', validator=StringMandatoryValidator(), doc='Sample chemical formula used to determine cross-section term.') self.declareProperty( name='DensityType', defaultValue = 'Mass Density', validator=StringListValidator(['Mass Density', 'Number Density']), doc = 'Use of Mass density (g/cm^3) or Number density (atoms/Angstrom^3)') self.declareProperty( name='Density', defaultValue=0.0, validator=FloatBoundedValidator(0.0), doc='Mass density (g/cm^3) or Number density (atoms/Angstrom^3).') self.declareProperty( name='Thickness', defaultValue=1.0, validator=FloatBoundedValidator(0.0), doc='Sample thickness (cm).') self.declareProperty( name='MeasuredEfficiency', defaultValue=0.0, validator=FloatBoundedValidator(0.0, 1.0), doc="Directly input the efficiency measured at MeasuredEfficiencyWavelength. \ This is used to determine a Density*Thickness term.") self.declareProperty( name='MeasuredEfficiencyWavelength', defaultValue=1.7982, validator=FloatBoundedValidator(0.0), doc="The wavelength at which the MeasuredEfficiency was measured.") self.declareProperty( name='Alpha', defaultValue=0.0, doc="Directly input the alpha term in exponential to multiply by the wavelength. \ XSectionType has no effect if this is used.") self.declareProperty( name='XSectionType', defaultValue="AttenuationXSection", validator=StringListValidator(['AttenuationXSection', 'TotalXSection']), doc = 'Use either the absorption or total cross section in exponential term. \ The absorption cross section is for monitor-type corrections and \ the total cross section is for transmission-type corrections' ) def validateInputs(self): issues = dict() # Check the inputs for wavelength isInWSDefault = self.getProperty('InputWorkspace').isDefault isWlRangeDefault = self.getProperty('WavelengthRange').isDefault if isInWSDefault and isWlRangeDefault: issues['InputWorkspace'] = "Must select either InputWorkspace and WavelengthRange as input" issues['WavelengthRange'] = "Must select either InputWorkspace and WavelengthRange as input" if isInWSDefault and isWlRangeDefault: issues['InputWorkspace'] = "Cannot select both InputWorkspace and WavelengthRange as input" issues['WavelengthRange'] = "Cannot select both InputWorkspace and WavelengthRange as input" # Check the different inputs for the exponential term isDensityDefault = self.getProperty('Density').isDefault isFormulaDefault = self.getProperty('ChemicalFormula').isDefault isEffDefault = self.getProperty('MeasuredEfficiency').isDefault isAlphaDefault = self.getProperty('Alpha').isDefault if not isDensityDefault: if isFormulaDefault: issues['ChemicalFormula'] = "Must specify the ChemicalFormula with Density" if not isEffDefault: if isFormulaDefault: issues['ChemicalFormula'] = "Must specify the ChemicalFormula with MeasuredEfficiency" if not isEffDefault and not isDensityDefault: issues['MeasuredEfficiency'] = "Cannot select both MeasuredEfficiency and Density as input" issues['Density'] = "Cannot select both MeasuredEfficiency and Density as input" if not isAlphaDefault and not isDensityDefault: issues['Alpha'] = "Cannot select both Alpha and Density as input" issues['Density'] = "Cannot select both Alpha and Density as input" if not isEffDefault and not isAlphaDefault: issues['MeasuredEfficiency'] = "Cannot select both MeasuredEfficiency and Alpha as input" issues['Alpha'] = "Cannot select both MeasuredEfficiency and Alpha as input" return issues def _setup(self): self._input_ws = self.getProperty('InputWorkspace').value self._bin_params = self.getPropertyValue('WavelengthRange') self._output_ws = self.getProperty('OutputWorkspace').valueAsStr self._chemical_formula = self.getPropertyValue('ChemicalFormula') self._density_type = self.getPropertyValue('DensityType') self._density = self.getProperty('Density').value self._thickness = self.getProperty('Thickness').value self._efficiency = self.getProperty('MeasuredEfficiency').value self._efficiency_wavelength = self.getProperty('MeasuredEfficiencyWavelength').value self._alpha_absXS = self.getProperty('Alpha').value self._alpha_scatXS = 0.0 self._xsection_type = self.getProperty('XSectionType').value 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: SetSampleMaterial( InputWorkspace=self._output_ws, ChemicalFormula=self._chemical_formula, SampleNumberDensity=self._density, StoreInADS=False) 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 _calculate_area_density_from_efficiency(self): """Calculates area density (atom/cm^2) using efficiency""" material = self._output_ws.sample().getMaterial() ref_absXS = material.absorbXSection() xs_term = ref_absXS * self._efficiency_wavelength / TABULATED_WAVELENGTH if self._xsection_type == "TotalXSection": xs_term += material.totalScatterXSection() self._area_density = - np.log( 1.0 - self._efficiency) / xs_term def _calculate_area_density_from_density(self): """Calculates area density (atom/cm^2) using number density and thickness.""" if self._density_type == 'Mass Density': builder = MaterialBuilder().setFormula(self._chemical_formula) mat = builder.setMassDensity(self._density).build() self._density = mat.numberDensity self._area_density = self._density * self._thickness def _calculate_alpha_absXS_term(self): """Calculates absorption XS alpha term = area_density * absXS / 1.7982""" material = self._output_ws.sample().getMaterial() absXS = material.absorbXSection() / TABULATED_WAVELENGTH self._alpha_absXS = self._area_density * absXS def _calculate_alpha_scatXS_term(self): """Calculates scattering XS alpha term = area_density * scatXS""" material = self._output_ws.sample().getMaterial() scatXS = material.totalScatterXSection() self._alpha_scatXS = self._area_density * scatXS def _calculate_efficiency(self, wavelength): """ Calculates efficiency of a detector / monitor at a given wavelength. If using just the absorption cross section, _alpha_scatXS is == 0. @param wavelength Wavelength at which to calculate (in Angstroms) @return efficiency """ efficiency = 1. / (1.0 - np.exp(-(self._alpha_scatXS + self._alpha_absXS * wavelength))) return efficiency