def load_file_and_apply(self, filename, ws_name, offset): 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) MaskDetectors(Workspace=ws_name, MaskedWorkspace='__sa') if offset != 0: if self.getProperty('SetGoniometer').value: SetGoniometer( Workspace=ws_name, Goniometers=self.getProperty('Goniometers').value, Axis0='{},0,1,0,1'.format(offset), Axis1=self.getProperty('Axis0').value, Axis2=self.getProperty('Axis1').value, Axis3=self.getProperty('Axis2').value) else: SetGoniometer(Workspace=ws_name, Axis0='{},0,1,0,1'.format(offset), Axis1='omega,0,1,0,1', Axis2='chi,0,0,1,1', Axis3='phi,0,1,0,1') else: if self.getProperty('SetGoniometer').value: SetGoniometer( Workspace=ws_name, Goniometers=self.getProperty('Goniometers').value, Axis0=self.getProperty('Axis0').value, Axis1=self.getProperty('Axis1').value, Axis2=self.getProperty('Axis2').value) ConvertUnits(InputWorkspace=ws_name, OutputWorkspace=ws_name, Target='Momentum') CropWorkspaceForMDNorm(InputWorkspace=ws_name, OutputWorkspace=ws_name, XMin=self.XMin, XMax=self.XMax)
def test_handles_inaccurate_goniometer(self): peaks1 = CreatePeaksWorkspace(InstrumentWorkspace=self.ws, NumberOfPeaks=0, OutputWorkspace="SXD_peaks3") peaks2 = CloneWorkspace(InputWorkspace=peaks1, OutputWorkspace="SXD_peaks4") # set different gonio on each run rot = 5 SetGoniometer(Workspace=peaks1, Axis0=f'{-rot},0,1,0,1') SetGoniometer(Workspace=peaks2, Axis0=f'{rot},0,1,0,1') # Add peaks at QLab corresponding to slightly different gonio rotations UB = np.diag([0.25, 0.25, 0.1]) # alatt = [4,4,10] for h in range(0, 3): for k in range(0, 3): hkl = np.array([h, k, 4]) qlab = 2 * np.pi * np.matmul( np.matmul(getR(-(rot + 1), [0, 1, 0]), UB), hkl) pk = peaks1.createPeak(qlab) peaks1.addPeak(pk) qlab = 2 * np.pi * np.matmul( np.matmul(getR(rot + 1, [0, 1, 0]), UB), hkl) pk = peaks2.createPeak(qlab) peaks2.addPeak(pk) FindGlobalBMatrix(PeakWorkspaces=[peaks1, peaks2], a=4.15, b=3.95, c=10, alpha=88, beta=88, gamma=89, Tolerance=0.15) # check lattice - shouldn't be effected by error in goniometer self.assert_lattice([peaks1, peaks2], 4.0, 4.0, 10.0, 90.0, 90.0, 90.0, delta_latt=2e-2, delta_angle=2.5e-1) self.assert_matrix([peaks1], getBMatrix(peaks2), getBMatrix, delta=1e-10) # should have same B matrix self.assert_matrix([peaks1, peaks2], np.eye(3), getUMatrix, delta=5e-2)
def prepare_background(input_md, reference_sample_mde, background_md: str): """Prepare background MDEventWorkspace from reduced sample Matrix This is the previous solution to merge all the ExperimentInfo """ dgs_data = CloneWorkspace(input_md) data_MDE = mtd[reference_sample_mde] if mtd.doesExist('background_MDE'): DeleteWorkspace('background_MDE') for i in range(data_MDE.getNumExperimentInfo()): phi, chi, omega = data_MDE.getExperimentInfo( i).run().getGoniometer().getEulerAngles('YZY') AddSampleLogMultiple(Workspace=dgs_data, LogNames='phi, chi, omega', LogValues='{},{},{}'.format(phi, chi, omega)) SetGoniometer(Workspace=dgs_data, Goniometers='Universal') ConvertToMD(InputWorkspace=dgs_data, QDimensions='Q3D', dEAnalysisMode='Direct', Q3DFrames="Q_sample", MinValues='-11,-11,-11,-25', MaxValues='11,11,11,49', PreprocDetectorsWS='-', OverwriteExisting=False, OutputWorkspace=background_md)
def test_HFIRCalculateGoniometer_HB3A_phi(self): omega = np.deg2rad(42) chi = np.deg2rad(-3) phi = np.deg2rad(23) R1 = np.array([ [np.cos(omega), 0, -np.sin(omega)], # omega 0,1,0,-1 [0, 1, 0], [np.sin(omega), 0, np.cos(omega)] ]) R2 = np.array([ [np.cos(chi), np.sin(chi), 0], # chi 0,0,1,-1 [-np.sin(chi), np.cos(chi), 0], [0, 0, 1] ]) R3 = np.array([ [np.cos(phi), 0, -np.sin(phi)], # phi 0,1,0,-1 [0, 1, 0], [np.sin(phi), 0, np.cos(phi)] ]) R = np.dot(np.dot(R1, R2), R3) wl = 1.54 k = 2 * np.pi / wl theta = np.deg2rad(47) phi = np.deg2rad(13) q_lab = np.array([ -np.sin(theta) * np.cos(phi), -np.sin(theta) * np.sin(phi), 1 - np.cos(theta) ]) * k q_sample = np.dot(np.linalg.inv(R), q_lab) peaks = CreatePeaksWorkspace(OutputType="LeanElasticPeak", NumberOfPeaks=0) AddSampleLog(peaks, "Wavelength", str(wl), "Number") SetGoniometer(peaks, Axis0='42,0,1,0,-1', Axis1='-3,0,0,1,-1') # don't set phi p = peaks.createPeakQSample(q_sample) peaks.addPeak(p) HFIRCalculateGoniometer(peaks, OverrideProperty=True, InnerGoniometer=True) g = Goniometer() g.setR(peaks.getPeak(0).getGoniometerMatrix()) YZY = g.getEulerAngles('YZY') self.assertAlmostEqual(YZY[0], -42, delta=1e-10) # omega self.assertAlmostEqual(YZY[1], 3, delta=1e-10) # chi self.assertAlmostEqual(YZY[2], -23, delta=1e-1) # phi self.assertAlmostEqual(peaks.getPeak(0).getWavelength(), 1.54, delta=1e-10)
def test_qtohkl_corelli(self): Load(Filename='CORELLI_29782.nxs', OutputWorkspace='data') SetGoniometer(Workspace='data', Axis0='BL9:Mot:Sample:Axis1,0,1,0,1') LoadIsawUB(InputWorkspace='data', Filename='SingleCrystalDiffuseReduction_UB.mat') ConvertToMD(InputWorkspace='data', QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='HKL', QConversionScales='HKL', OutputWorkspace='HKL', Uproj='1,1,0', Vproj='1,-1,0', Wproj='0,0,1', MinValues='-20,-20,-20', MaxValues='20,20,20') hkl_binned = BinMD('HKL', AlignedDim0='[H,H,0],-10.05,10.05,201', AlignedDim1='[H,-H,0],-10.05,10.05,201', AlignedDim2='[0,0,L],-1.05,1.05,21') ConvertToMD(InputWorkspace='data', QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='Q_sample', OutputWorkspace='q_sample', MinValues='-20,-20,-20', MaxValues='20,20,20') hkl = ConvertQtoHKLMDHisto( InputWorkspace=mtd["q_sample"], Uproj="1,1,0", Vproj="1,-1,0", Wproj="0,0,1", Extents="-10.05,10.05,-10.05,10.05,-1.05,1.05", Bins="201,201,21") for i in range(hkl.getNumDims()): self.assertEqual( hkl_binned.getDimension(i).name, hkl.getDimension(i).name) orig_sig = hkl_binned.getSignalArray() new_sig = hkl.getSignalArray() np.testing.assert_allclose(np.asarray(new_sig), np.asarray(orig_sig), rtol=1.0e-5, atol=3)
def loadIntegrateData(filename, OutputWorkspace='__ws', wavelength=1.488): LoadEventNexus(Filename=filename, OutputWorkspace=OutputWorkspace, LoadMonitors=True) Integration(InputWorkspace=OutputWorkspace, OutputWorkspace=OutputWorkspace) MaskDetectors(OutputWorkspace, DetectorList=range(16384)) mtd[OutputWorkspace].getAxis(0).setUnit("Wavelength") w = np.array([wavelength - 0.001, wavelength + 0.001]) for idx in range(mtd[OutputWorkspace].getNumberHistograms()): mtd[OutputWorkspace].setX(idx, w) SetGoniometer(OutputWorkspace, Axis0="HB2C:Mot:s1,0,1,0,1") AddSampleLog(OutputWorkspace, LogName="gd_prtn_chrg", LogType='Number', NumberType='Double', LogText=str(mtd[OutputWorkspace + '_monitors'].getNumberEvents())) return OutputWorkspace
def PyExec(self): filename = self.getProperty("Filename").value wavelength = self.getProperty("wavelength").value outWS = self.getPropertyValue("OutputWorkspace") LoadEventNexus(Filename=filename, OutputWorkspace=outWS, LoadMonitors=True) Integration(InputWorkspace=outWS, OutputWorkspace=outWS) if self.getProperty("ApplyMask").value: MaskBTP(outWS, Bank='8', Tube='449-480') MaskBTP(outWS, Pixel='1,2,511,512') mtd[outWS].getAxis(0).setUnit("Wavelength") w = [wavelength - 0.001, wavelength + 0.001] for idx in range(mtd[outWS].getNumberHistograms()): mtd[outWS].setX(idx, w) SetGoniometer(outWS, Axis0="HB2C:Mot:s1,0,1,0,1") AddSampleLog(outWS, LogName="gd_prtn_chrg", LogType='Number', NumberType='Double', LogText=str(mtd[outWS + '_monitors'].getNumberEvents())) DeleteWorkspace(outWS + '_monitors') AddSampleLog(outWS, LogName="Wavelength", LogType='Number', NumberType='Double', LogText=str(wavelength)) AddSampleLog(outWS, LogName="Ei", LogType='Number', NumberType='Double', LogText=str( UnitConversion.run('Wavelength', 'Energy', wavelength, 0, 0, 0, Elastic, 0))) self.setProperty('OutputWorkspace', outWS)
def PyExec(self): fn = self.getPropertyValue("Filename") wsn = self.getPropertyValue("OutputWorkspace") monitor_workspace_name = self.getPropertyValue( "OutputMonitorWorkspace") if monitor_workspace_name == "": self.setPropertyValue("OutputMonitorWorkspace", wsn + '_Monitors') # print (fn, wsn) self.override_angle = self.getPropertyValue("AngleOverride") self.fxml = self.getPropertyValue("InstrumentXML") # load data parms_dict, det_udet, det_count, det_tbc, data = self.read_file(fn) nrows = int(parms_dict['NDET']) # nbins=int(parms_dict['NTC']) xdata = np.array(det_tbc) xdata_mon = np.linspace(xdata[0], xdata[-1], len(xdata)) ydata = data.astype(float) ydata = ydata.reshape(nrows, -1) edata = np.sqrt(ydata) # CreateWorkspace(OutputWorkspace=wsn,DataX=xdata,DataY=ydata,DataE=edata, # NSpec=nrows,UnitX='TOF',WorkspaceTitle='Data',YUnitLabel='Counts') nr, nc = ydata.shape ws = WorkspaceFactory.create("Workspace2D", NVectors=nr, XLength=nc + 1, YLength=nc) for i in range(nrows): ws.setX(i, xdata) ws.setY(i, ydata[i]) ws.setE(i, edata[i]) ws.getAxis(0).setUnit('tof') AnalysisDataService.addOrReplace(wsn, ws) # self.setProperty("OutputWorkspace", wsn) # print ("ws:", wsn) # ws=mtd[wsn] # fix the x values for the monitor for i in range(nrows - 2, nrows): ws.setX(i, xdata_mon) self.log().information("set detector IDs") # set detetector IDs for i in range(nrows): ws.getSpectrum(i).setDetectorID(det_udet[i]) # Sample_logs the header values are written into the sample logs log_names = [ str(sl.encode('ascii', 'ignore').decode()) for sl in parms_dict.keys() ] log_values = [ str(sl.encode('ascii', 'ignore').decode()) if isinstance( sl, UnicodeType) else str(sl) for sl in parms_dict.values() ] for i in range(len(log_values)): if ('nan' in log_values[i]) or ('NaN' in log_values[i]): log_values[i] = '-1.0' AddSampleLogMultiple(Workspace=wsn, LogNames=log_names, LogValues=log_values) SetGoniometer(Workspace=wsn, Goniometers='Universal') if (self.fxml == ""): LoadInstrument(Workspace=wsn, InstrumentName="Exed", RewriteSpectraMap=True) else: LoadInstrument(Workspace=wsn, Filename=self.fxml, RewriteSpectraMap=True) try: RotateInstrumentComponent( Workspace=wsn, ComponentName='Tank', Y=1, Angle=-float(parms_dict['phi'].encode('ascii', 'ignore')), RelativeRotation=False) except: self.log().warning( "The instrument does not contain a 'Tank' component. " "This means that you are using a custom XML instrument definition. " "OMEGA_MAG will be ignored.") self.log().warning( "Please make sure that the detector positions in the instrument definition are correct." ) # Separate monitors into seperate workspace __temp_monitors = ExtractSpectra( InputWorkspace=wsn, WorkspaceIndexList=','.join( [str(s) for s in range(nrows - 2, nrows)]), OutputWorkspace=self.getPropertyValue("OutputMonitorWorkspace")) # ExtractSpectra(InputWorkspace = wsn, WorkspaceIndexList = ','.join([str(s) for s in range(nrows-2, nrows)]), # OutputWorkspace = wsn + '_Monitors') MaskDetectors(Workspace=wsn, WorkspaceIndexList=','.join( [str(s) for s in range(nrows - 2, nrows)])) RemoveMaskedSpectra(InputWorkspace=wsn, OutputWorkspace=wsn) self.setProperty("OutputWorkspace", wsn) self.setProperty("OutputMonitorWorkspace", __temp_monitors)
def PyExec(self): _load_inst = bool(self.getProperty("LoadInstrument").value) _detcal = bool(self.getProperty("DetCal").value) _masking = bool(self.getProperty("MaskFile").value) _outWS_name = self.getPropertyValue("OutputWorkspace") _UB = bool(self.getProperty("UBMatrix").value) MinValues = self.getProperty("MinValues").value MaxValues = self.getProperty("MaxValues").value if self.getProperty("OverwriteExisting").value: if mtd.doesExist(_outWS_name): DeleteWorkspace(_outWS_name) progress = Progress(self, 0.0, 1.0, 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, FilterByTimeStop=self.getProperty("FilterByTimeStop").value) if _load_inst: LoadInstrument( Workspace='__run', Filename=self.getProperty("LoadInstrument").value, RewriteSpectraMap=False) if _detcal: LoadIsawDetCal(InputWorkspace='__run', Filename=self.getProperty("DetCal").value) if _masking: if not mtd.doesExist('__mask'): LoadMask(Instrument=mtd['__run'].getInstrument().getName(), InputFile=self.getProperty("MaskFile").value, OutputWorkspace='__mask') MaskDetectors(Workspace='__run', MaskedWorkspace='__mask') 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) if _UB: LoadIsawUB(InputWorkspace='__run', Filename=self.getProperty("UBMatrix").value) if len(MinValues) == 0 or len(MaxValues) == 0: MinValues, MaxValues = ConvertToMDMinMaxGlobal( '__run', dEAnalysisMode='Elastic', Q3DFrames='HKL', QDimensions='Q3D') ConvertToMD( InputWorkspace='__run', OutputWorkspace=_outWS_name, 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, SplitInto=self.getProperty('SplitInto').value, SplitThreshold=self.getProperty('SplitThreshold').value, MaxRecursionDepth=self.getProperty( 'MaxRecursionDepth').value, OverwriteExisting=False) else: if len(MinValues) == 0 or len(MaxValues) == 0: MinValues, MaxValues = ConvertToMDMinMaxGlobal( '__run', dEAnalysisMode='Elastic', Q3DFrames='Q', QDimensions='Q3D') ConvertToMD( InputWorkspace='__run', OutputWorkspace=_outWS_name, QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='Q_sample', Uproj=self.getProperty('Uproj').value, Vproj=self.getProperty('Vproj').value, Wproj=self.getProperty('Wproj').value, MinValues=MinValues, MaxValues=MaxValues, SplitInto=self.getProperty('SplitInto').value, SplitThreshold=self.getProperty('SplitThreshold').value, MaxRecursionDepth=self.getProperty( 'MaxRecursionDepth').value, OverwriteExisting=False) DeleteWorkspace('__run') progress.report() if mtd.doesExist('__mask'): DeleteWorkspace('__mask') self.setProperty("OutputWorkspace", mtd[_outWS_name])
def PyExec(self): load_van = not self.getProperty("VanadiumFile").isDefault load_files = not self.getProperty("Filename").isDefault output = self.getProperty("OutputType").value if load_files: datafiles = self.getProperty("Filename").value else: datafiles = list( map(str.strip, self.getProperty("InputWorkspaces").value.split(","))) prog = Progress(self, 0.0, 1.0, len(datafiles) + 1) vanadiumfile = self.getProperty("VanadiumFile").value vanws = self.getProperty("VanadiumWorkspace").value height = self.getProperty("DetectorHeightOffset").value distance = self.getProperty("DetectorDistanceOffset").value wslist = [] out_ws = self.getPropertyValue("OutputWorkspace") out_ws_name = out_ws if load_van: vanws = LoadMD(vanadiumfile, StoreInADS=False) has_multiple = len(datafiles) > 1 for in_file in datafiles: if load_files: scan = LoadMD(in_file, LoadHistory=False, OutputWorkspace="__scan") else: scan = mtd[in_file] # Make sure the workspace has experiment info, otherwise SetGoniometer will add some, causing issues. if scan.getNumExperimentInfo() == 0: raise RuntimeError( "No experiment info was found in '{}'".format(in_file)) prog.report() self.log().information("Processing '{}'".format(in_file)) SetGoniometer(Workspace=scan, Axis0='omega,0,1,0,-1', Axis1='chi,0,0,1,-1', Axis2='phi,0,1,0,-1', Average=False) # If processing multiple files, append the base name to the given output name if has_multiple: if load_files: out_ws_name = out_ws + "_" + os.path.basename( in_file).strip(',.nxs') else: out_ws_name = out_ws + "_" + in_file wslist.append(out_ws_name) exp_info = scan.getExperimentInfo(0) self.__move_components(exp_info, height, distance) # Get the wavelength from experiment info if it exists, or fallback on property value wavelength = self.__get_wavelength(exp_info) # set the run number to be the same as scan number, this will be used for peaks if not exp_info.run().hasProperty('run_number') and exp_info.run( ).hasProperty('scan'): try: exp_info.mutableRun().addProperty( 'run_number', int(exp_info.run().getProperty('scan').value), True) except ValueError: # scan must be a int pass # Use ConvertHFIRSCDtoQ (and normalize van), or use ConvertWANDSCtoQ which handles normalization itself if output == "Q-sample events": norm_data = self.__normalization(scan, vanws, load_files) minvals = self.getProperty("MinValues").value maxvals = self.getProperty("MaxValues").value merge = self.getProperty("MergeInputs").value ConvertHFIRSCDtoMDE(InputWorkspace=norm_data, Wavelength=wavelength, MinValues=minvals, MaxValues=maxvals, OutputWorkspace=out_ws_name) DeleteWorkspace(norm_data) elif output == 'Q-sample histogram': bin0 = self.getProperty("BinningDim0").value bin1 = self.getProperty("BinningDim1").value bin2 = self.getProperty("BinningDim2").value # Convert to Q space and normalize with from the vanadium ConvertWANDSCDtoQ( InputWorkspace=scan, NormalisationWorkspace=vanws, Frame='Q_sample', Wavelength=wavelength, NormaliseBy=self.getProperty("NormaliseBy").value, BinningDim0=bin0, BinningDim1=bin1, BinningDim2=bin2, OutputWorkspace=out_ws_name) if load_files: DeleteWorkspace(scan) else: norm_data = self.__normalization(scan, vanws, load_files) RenameWorkspace(norm_data, OutputWorkspace=out_ws_name) if has_multiple: out_ws_name = out_ws if output == "Q-sample events" and merge: MergeMD(InputWorkspaces=wslist, OutputWorkspace=out_ws_name) DeleteWorkspaces(wslist) else: GroupWorkspaces(InputWorkspaces=wslist, OutputWorkspace=out_ws_name) # Don't delete workspaces if they were passed in if load_van: DeleteWorkspace(vanws) self.setProperty("OutputWorkspace", out_ws_name)
def _determine_single_crystal_diffraction(self): """ All work related to the determination of the diffraction pattern """ a, b, c = self.getProperty('LatticeSizes').value alpha, beta, gamma = self.getProperty('LatticeAngles').value u = self.getProperty('VectorU').value v = self.getProperty('VectorV').value uproj = self.getProperty('Uproj').value vproj = self.getProperty('Vproj').value wproj = self.getProperty('Wproj').value n_bins = self.getProperty('NBins').value self._n_bins = (n_bins, n_bins, 1) axis0 = '{},0,1,0,1'.format(self.getProperty('PsiAngleLog').value) axis1 = '{},0,1,0,1'.format(self.getProperty('PsiOffset').value) # Options for SetUB independent of run ub_args = dict(a=a, b=b, c=c, alpha=alpha, beta=beta, gamma=gamma, u=u, v=v) min_values = None # Options for algorithm ConvertToMD independent of run convert_to_md_kwargs = dict(QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='HKL', QConversionScales='HKL', Uproj=uproj, Vproj=vproj, Wproj=wproj) md_norm_scd_kwargs = None # Options for algorithm MDNormSCD # Find solid angle and flux if self._vanadium_files: kwargs = dict(Filename='+'.join(self._vanadium_files), MaskFile=self.getProperty("MaskFile").value, MomentumMin=self._momentum_range[0], MomentumMax=self._momentum_range[1]) _t_solid_angle, _t_int_flux = \ MDNormSCDPreprocessIncoherent(**kwargs) else: _t_solid_angle = self.nominal_solid_angle('_t_solid_angle') _t_int_flux = self.nominal_integrated_flux('_t_int_flux') # Process a sample at a time run_numbers = self._getRuns(self.getProperty("RunNumbers").value, doIndiv=True) run_numbers = list(itertools.chain.from_iterable(run_numbers)) diffraction_reporter = Progress(self, start=0.0, end=1.0, nreports=len(run_numbers)) for i_run, run in enumerate(run_numbers): _t_sample = self._mask_t0_crop(run, '_t_sample') # Set Goniometer and UB matrix SetGoniometer(_t_sample, Axis0=axis0, Axis1=axis1) SetUB(_t_sample, **ub_args) if self._bkg: self._bkg.run().getGoniometer().\ setR(_t_sample.run().getGoniometer().getR()) SetUB(self._bkg, **ub_args) # Determine limits for momentum transfer in HKL space. Needs to be # done only once. We use the first run. if min_values is None: kwargs = dict(QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='HKL') min_values, max_values = ConvertToMDMinMaxGlobal( _t_sample, **kwargs) convert_to_md_kwargs.update({ 'MinValues': min_values, 'MaxValues': max_values }) # Convert to MD _t_md = ConvertToMD(_t_sample, OutputWorkspace='_t_md', **convert_to_md_kwargs) if self._bkg: _t_bkg_md = ConvertToMD(self._bkg, OutputWorkspace='_t_bkg_md', **convert_to_md_kwargs) # Determine aligned dimensions. Need to be done only once if md_norm_scd_kwargs is None: aligned = list() for i_dim in range(3): kwargs = { 'name': _t_md.getDimension(i_dim).name, 'min': min_values[i_dim], 'max': max_values[i_dim], 'n_bins': self._n_bins[i_dim] } aligned.append( '{name},{min},{max},{n_bins}'.format(**kwargs)) md_norm_scd_kwargs = dict(AlignedDim0=aligned[0], AlignedDim1=aligned[1], AlignedDim2=aligned[2], FluxWorkspace=_t_int_flux, SolidAngleWorkspace=_t_solid_angle, SkipSafetyCheck=True) # Normalize sample by solid angle and integrated flux; # Accumulate runs into the temporary workspaces MDNormSCD(_t_md, OutputWorkspace='_t_data', OutputNormalizationWorkspace='_t_norm', TemporaryDataWorkspace='_t_data' if mtd.doesExist('_t_data') else None, TemporaryNormalizationWorkspace='_t_norm' if mtd.doesExist('_t_norm') else None, **md_norm_scd_kwargs) if self._bkg: MDNormSCD(_t_bkg_md, OutputWorkspace='_t_bkg_data', OutputNormalizationWorkspace='_t_bkg_norm', TemporaryDataWorkspace='_t_bkg_data' if mtd.doesExist('_t_bkg_data') else None, TemporaryNormalizationWorkspace='_t_bkg_norm' if mtd.doesExist('_t_bkg_norm') else None, **md_norm_scd_kwargs) message = 'Processing sample {} of {}'.\ format(i_run+1, len(run_numbers)) diffraction_reporter.report(message) self._temps.workspaces.append('PreprocessedDetectorsWS') # to remove # Iteration over the sample runs is done. # Division by vanadium, subtract background, and rename workspaces name = self.getPropertyValue("OutputWorkspace") _t_data = DivideMD(LHSWorkspace='_t_data', RHSWorkspace='_t_norm') if self._bkg: _t_bkg_data = DivideMD(LHSWorkspace='_t_bkg_data', RHSWorkspace='_t_bkg_norm') _t_scale = CreateSingleValuedWorkspace(DataValue=self._bkg_scale) _t_bkg_data = MultiplyMD(_t_bkg_data, _t_scale) ws = MinusMD(_t_data, _t_bkg_data) RenameWorkspace(_t_data, OutputWorkspace=name + '_dat') RenameWorkspace(_t_bkg_data, OutputWorkspace=name + '_bkg') else: ws = _t_data RenameWorkspace(ws, OutputWorkspace=name) self.setProperty("OutputWorkspace", ws) diffraction_reporter.report(len(run_numbers), 'Done')
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 runTest(self): S = np.random.random(32 * 240 * 100) ConvertWANDSCDtoQTest_data = CreateMDHistoWorkspace( Dimensionality=3, Extents='0.5,32.5,0.5,240.5,0.5,100.5', SignalInput=S.ravel('F'), ErrorInput=np.sqrt(S.ravel('F')), NumberOfBins='32,240,100', Names='y,x,scanIndex', Units='bin,bin,number') ConvertWANDSCDtoQTest_dummy = CreateSingleValuedWorkspace() LoadInstrument(ConvertWANDSCDtoQTest_dummy, InstrumentName='WAND', RewriteSpectraMap=False) ConvertWANDSCDtoQTest_data.addExperimentInfo( ConvertWANDSCDtoQTest_dummy) log = FloatTimeSeriesProperty('s1') for t, v in zip(range(100), np.arange(0, 50, 0.5)): log.addValue(t, v) ConvertWANDSCDtoQTest_data.getExperimentInfo(0).run()['s1'] = log ConvertWANDSCDtoQTest_data.getExperimentInfo(0).run().addProperty( 'duration', [60.] * 100, True) ConvertWANDSCDtoQTest_data.getExperimentInfo(0).run().addProperty( 'monitor_count', [120000.] * 100, True) ConvertWANDSCDtoQTest_data.getExperimentInfo(0).run().addProperty( 'twotheta', list(np.linspace(np.pi * 2 / 3, 0, 240).repeat(32)), True) ConvertWANDSCDtoQTest_data.getExperimentInfo(0).run().addProperty( 'azimuthal', list(np.tile(np.linspace(-0.15, 0.15, 32), 240)), True) peaks = CreatePeaksWorkspace(NumberOfPeaks=0, OutputType='LeanElasticPeak') SetUB(ConvertWANDSCDtoQTest_data, 5, 5, 7, 90, 90, 120, u=[-1, 0, 1], v=[1, 0, 1]) SetGoniometer(ConvertWANDSCDtoQTest_data, Axis0='s1,0,1,0,1', Average=False) CopySample(InputWorkspace=ConvertWANDSCDtoQTest_data, OutputWorkspace=peaks, CopyName=False, CopyMaterial=False, CopyEnvironment=False, CopyShape=False, CopyLattice=True) Q = ConvertWANDSCDtoQ(InputWorkspace=ConvertWANDSCDtoQTest_data, UBWorkspace=peaks, Wavelength=1.486, Frame='HKL', Uproj='1,1,0', Vproj='-1,1,0', BinningDim0='-6.04,6.04,151', BinningDim1='-6.04,6.04,151', BinningDim2='-6.04,6.04,151') data_norm = ConvertHFIRSCDtoMDE(ConvertWANDSCDtoQTest_data, Wavelength=1.486, MinValues='-6.04,-6.04,-6.04', MaxValues='6.04,6.04,6.04') HKL = ConvertQtoHKLMDHisto(data_norm, PeaksWorkspace=peaks, Uproj='1,1,0', Vproj='-1,1,0', Extents='-6.04,6.04,-6.04,6.04,-6.04,6.04', Bins='151,151,151') for i in range(HKL.getNumDims()): print(HKL.getDimension(i).getUnits(), Q.getDimension(i).getUnits()) np.testing.assert_equal( HKL.getDimension(i).getUnits(), Q.getDimension(i).getUnits()) hkl_data = mtd["HKL"].getSignalArray() Q_data = mtd["Q"].getSignalArray() print(np.isnan(Q_data).sum()) print(np.isclose(hkl_data, 0).sum()) xaxis = mtd["HKL"].getXDimension() yaxis = mtd["HKL"].getYDimension() zaxis = mtd["HKL"].getZDimension() x, y, z = np.meshgrid( np.linspace(xaxis.getMinimum(), xaxis.getMaximum(), xaxis.getNBins()), np.linspace(yaxis.getMinimum(), yaxis.getMaximum(), yaxis.getNBins()), np.linspace(zaxis.getMinimum(), zaxis.getMaximum(), zaxis.getNBins()), indexing="ij", copy=False, ) print( x[~np.isnan(Q_data)].mean(), y[~np.isnan(Q_data)].mean(), z[~np.isnan(Q_data)].mean(), ) print( x[~np.isclose(hkl_data, 0)].mean(), y[~np.isclose(hkl_data, 0)].mean(), z[~np.isclose(hkl_data, 0)].mean(), ) np.testing.assert_almost_equal(x[~np.isnan(Q_data)].mean(), x[~np.isclose(hkl_data, 0)].mean(), decimal=2) np.testing.assert_almost_equal(y[~np.isnan(Q_data)].mean(), y[~np.isclose(hkl_data, 0)].mean(), decimal=2) np.testing.assert_almost_equal(z[~np.isnan(Q_data)].mean(), z[~np.isclose(hkl_data, 0)].mean(), decimal=1)
def setUpClass(cls): def gaussian(x, y, z, x0, y0, z0, ox, oy, oz, A): return A * np.exp(-(x - x0)**2 / (2 * ox**2) - (y - y0)**2 / (2 * oy**2) - (z - z0)**2 / (2 * oz**2)) def peaks(i, j, k): return gaussian(i, j, k, 16, 100, 50, 2, 2, 2, 20) + gaussian( i, j, k, 16, 150, 50, 1, 1, 1, 10) S = np.fromfunction(peaks, (32, 240, 100)) ConvertWANDSCDtoQTest_data = CreateMDHistoWorkspace( Dimensionality=3, Extents='0.5,32.5,0.5,240.5,0.5,100.5', SignalInput=S.ravel('F'), ErrorInput=np.sqrt(S.ravel('F')), NumberOfBins='32,240,100', Names='y,x,scanIndex', Units='bin,bin,number') ConvertWANDSCDtoQTest_dummy = CreateSingleValuedWorkspace() ConvertWANDSCDtoQTest_data.addExperimentInfo( ConvertWANDSCDtoQTest_dummy) log = FloatTimeSeriesProperty('s1') for t, v in zip(range(100), np.arange(0, 50, 0.5)): log.addValue(t, v) ConvertWANDSCDtoQTest_data.getExperimentInfo(0).run()['s1'] = log ConvertWANDSCDtoQTest_data.getExperimentInfo(0).run().addProperty( 'duration', [60.] * 100, True) ConvertWANDSCDtoQTest_data.getExperimentInfo(0).run().addProperty( 'monitor_count', [120000.] * 100, True) ConvertWANDSCDtoQTest_data.getExperimentInfo(0).run().addProperty( 'twotheta', list(np.linspace(np.pi * 2 / 3, 0, 240).repeat(32)), True) ConvertWANDSCDtoQTest_data.getExperimentInfo(0).run().addProperty( 'azimuthal', list(np.tile(np.linspace(-0.15, 0.15, 32), 240)), True) SetUB(ConvertWANDSCDtoQTest_data, 5, 5, 7, 90, 90, 120, u=[-1, 0, 1], v=[1, 0, 1]) SetGoniometer(ConvertWANDSCDtoQTest_data, Axis0='s1,0,1,0,1', Average=False) # Create Normalisation workspace S = np.ones((32, 240, 1)) ConvertWANDSCDtoQTest_norm = CreateMDHistoWorkspace( Dimensionality=3, Extents='0.5,32.5,0.5,240.5,0.5,1.5', SignalInput=S, ErrorInput=S, NumberOfBins='32,240,1', Names='y,x,scanIndex', Units='bin,bin,number') ConvertWANDSCDtoQTest_dummy2 = CreateSingleValuedWorkspace() ConvertWANDSCDtoQTest_norm.addExperimentInfo( ConvertWANDSCDtoQTest_dummy2) ConvertWANDSCDtoQTest_norm.getExperimentInfo(0).run().addProperty( 'monitor_count', [100000.], True)
wavelength = data.attrs['wavelength'] s1 = data.attrs['s1'] s2 = data.attrs['s2'] detz = data.attrs['detz'] y = data["y"].value e = data["e"].value t1 = time.time() CreateWorkspace(OutputWorkspace='ws', DataX=wavelength, DataY=y, DataE=e, NSpec=y.size, UnitX='Wavelength') SetGoniometer('ws', Axis0="{},0,1,0,1".format(s1)) AddSampleLog('ws', LogName='HB2C:Mot:s2.RBV', LogText=str(s2), LogType='Number Series') AddSampleLog('ws', LogName='HB2C:Mot:detz.RBV', LogText=str(detz), LogType='Number Series') LoadInstrument('ws', InstrumentName=instrument, RewriteSpectraMap=True) t2 = time.time() print("t1={}".format(t1 - t0)) print("t2={}".format(t2 - t1))
max_Q = "30" num_peaks_to_find = 400 min_d = 8 max_d = 20 tolerance = 0.12 minVals = "-" + max_Q + ",-" + max_Q + ",-" + max_Q maxVals = max_Q + "," + max_Q + "," + max_Q distance_threshold = 0.9 * 6.28 / float(max_d) for f in files: data = Load(f) SetGoniometer(data, Axis0="BL9:Mot:Sample:Axis1,0,1,0,1") MDEW = ConvertToMD(InputWorkspace=data, QDimensions="Q3D", dEAnalysisMode="Elastic", QConversionScales="Q in A^-1", LorentzCorrection='0', MinValues=minVals, MaxValues=maxVals, SplitInto='2', SplitThreshold='50', MaxRecursionDepth='11') peaks_ws = FindPeaksMD(MDEW, MaxPeaks=num_peaks_to_find, PeakDistanceThreshold=distance_threshold, AppendPeaks=True)
def runTest(self): """ This is the old way to do MDNorm to sample, background and finally clean background from sample Now it serves as a benchmark to generate expected result for enhanced MDNorm Current status: To task 88 no accumulation Next status: To task 89 no accumulation To task 88 with accumulation To task 89 with accumulation """ # Set facility that load data config.setFacility('SNS') Load(Filename='HYS_13656', OutputWorkspace='sum') SetGoniometer(Workspace='sum', Axis0='s1,0,1,0,1') # prepare sample MD: in test must between 10 and 12 to match the gold data dgs_red_group_name1 = self.prepare_md(input_ws_name='sum', merged_md_name='merged1', min_log_value=10, max_log_value=12, log_step=LOG_VALUE_STEP, prefix='step1') # 1-1 Existing method (but to keep) benchmark = self.run_old_solution('merged1', f'{dgs_red_group_name1}_1', 'oldstep1') self._old_clean = str(benchmark.cleaned) # Prepare background workspace self.prepare_single_exp_info_background( input_md_name=f'{dgs_red_group_name1}_1', output_md_name='bkgd_md1', target_qframe='Q_lab') # Test new solutions r = MDNorm(InputWorkspace='merged1', BackgroundWorkspace='bkgd_md1', Dimension0Name='QDimension1', Dimension0Binning='-5,0.05,5', Dimension1Name='QDimension2', Dimension1Binning='-5,0.05,5', Dimension2Name='DeltaE', Dimension2Binning='-2,2', Dimension3Name='QDimension0', Dimension3Binning='-0.5,0.5', SymmetryOperations=SYMMETRY_OPERATION, OutputWorkspace='clean_data', OutputDataWorkspace='dataMD', OutputNormalizationWorkspace='normMD', OutputBackgroundDataWorkspace='background_dataMD', OutputBackgroundNormalizationWorkspace='background_normMD') # Test solution assert hasattr(r, 'OutputBackgroundNormalizationWorkspace' ), 'MDNorm does not execute.' # Compare workspaces: binned background data workspace rc = CompareMDWorkspaces(Workspace1=benchmark.bkgd_data, Workspace2='background_dataMD') assert rc.Equals, f'Error message: {rc.Result}' # Compare workspaces: background normalization workspace r89 = CompareMDWorkspaces(Workspace1=benchmark.bkgd_norm, Workspace2='background_normMD', Tolerance=1E-9) assert r89.Equals, f'Incompatible background normalization workspaces: {r89.Result}' # Compare the cleaned MD r_out = CompareMDWorkspaces(Workspace1=benchmark.cleaned, Workspace2='clean_data', Tolerance=1E-16) if not r_out.Equals: raise ValueError( f'Sample output data does not match: {r_out.Result}') # Round 2: Test accumulation mode dgs_red_group_name1 = self.prepare_md(input_ws_name='sum', merged_md_name='merged2', min_log_value=13, max_log_value=15, log_step=LOG_VALUE_STEP, prefix='step2') # Old solution benchmark2 = self.run_old_solution('merged2', f'{dgs_red_group_name1}_2', 'oldstep2', benchmark) # 1-2 Test new solutions self.prepare_single_exp_info_background( input_md_name=f'{dgs_red_group_name1}_2', output_md_name='bkgd_md2', target_qframe='Q_lab') r = MDNorm( InputWorkspace='merged2', BackgroundWorkspace='bkgd_md2', TemporaryDataWorkspace='dataMD', TemporaryNormalizationWorkspace='normMD', TemporaryBackgroundDataWorkspace='background_dataMD', TemporaryBackgroundNormalizationWorkspace='background_normMD', Dimension0Name='QDimension1', Dimension0Binning='-5,0.05,5', Dimension1Name='QDimension2', Dimension1Binning='-5,0.05,5', Dimension2Name='DeltaE', Dimension2Binning='-2,2', Dimension3Name='QDimension0', Dimension3Binning='-0.5,0.5', SymmetryOperations=SYMMETRY_OPERATION, OutputWorkspace='clean_data_2', OutputDataWorkspace='dataMD2', OutputNormalizationWorkspace='normMD2', OutputBackgroundDataWorkspace='background_dataMD2', OutputBackgroundNormalizationWorkspace='background_normMD2') # Compare data workspace r_sd = CompareMDWorkspaces(Workspace1=benchmark2.sample_data, Workspace2='dataMD', Tolerance=1E-7) assert r_sd.Equals, f'Sample binned data MD not equal: {r_sd.Result}' # Compare gold (old solution) and new: passed test in #88 r = CompareMDWorkspaces(Workspace1=benchmark2.bkgd_data, Workspace2='background_dataMD2') if not r.Equals: raise ValueError( f'Accumulation mode: Background binned data MD: {r.Result}') # Compare gold (old solution) and new: passed test in #88 r_bn = CompareMDWorkspaces(Workspace1=benchmark2.bkgd_norm, Workspace2='background_normMD2', Tolerance=1E-9) if not r_bn.Equals: raise ValueError( f'Accumulation mode: Background normalization MD: {r_bn.Result}' ) # Test MDNorm's checking on inputs # Note that this test must be put after all the tests because # it will modify some workspaces and thus mess some experimental data set up to verify self.test_property_setup('merged1', f'{dgs_red_group_name1}_1')
def PyExec(self): fn = self.getPropertyValue("Filename") wsn = self.getPropertyValue("OutputWorkspace") #print (fn, wsn) self.fxml = self.getPropertyValue("InstrumentXML") #load data parms_dict, det_udet, det_count, det_tbc, data = self.read_file(fn) nrows = int(parms_dict['NDET']) #nbins=int(parms_dict['NTC']) xdata = np.array(det_tbc) xdata_mon = np.linspace(xdata[0], xdata[-1], len(xdata)) ydata = data.astype(np.float) ydata = ydata.reshape(nrows, -1) edata = np.sqrt(ydata) #CreateWorkspace(OutputWorkspace=wsn,DataX=xdata,DataY=ydata,DataE=edata, # NSpec=nrows,UnitX='TOF',WorkspaceTitle='Data',YUnitLabel='Counts') nr, nc = ydata.shape ws = WorkspaceFactory.create("Workspace2D", NVectors=nr, XLength=nc + 1, YLength=nc) for i in range(nrows): ws.setX(i, xdata) ws.setY(i, ydata[i]) ws.setE(i, edata[i]) ws.getAxis(0).setUnit('tof') AnalysisDataService.addOrReplace(wsn, ws) #self.setProperty("OutputWorkspace", wsn) #print ("ws:", wsn) #ws=mtd[wsn] # fix the x values for the monitor for i in range(nrows - 2, nrows): ws.setX(i, xdata_mon) self.log().information("set detector IDs") #set detetector IDs for i in range(nrows): ws.getSpectrum(i).setDetectorID(det_udet[i]) #Sample_logs the header values are written into the sample logs log_names = [sl.encode('ascii', 'ignore') for sl in parms_dict.keys()] log_values = [ sl.encode('ascii', 'ignore') if isinstance(sl, types.UnicodeType) else str(sl) for sl in parms_dict.values() ] AddSampleLogMultiple(Workspace=wsn, LogNames=log_names, LogValues=log_values) SetGoniometer(Workspace=wsn, Goniometers='Universal') if (self.fxml == ""): LoadInstrument(Workspace=wsn, InstrumentName="Exed", RewriteSpectraMap=True) else: LoadInstrument(Workspace=wsn, Filename=self.fxml, RewriteSpectraMap=True) RotateInstrumentComponent( Workspace=wsn, ComponentName='Tank', Y=1, Angle=-float(parms_dict['phi'].encode('ascii', 'ignore')), RelativeRotation=False) # Separate monitors into seperate workspace ExtractSpectra(InputWorkspace=wsn, WorkspaceIndexList=','.join( [str(s) for s in range(nrows - 2, nrows)]), OutputWorkspace=wsn + '_Monitors') MaskDetectors(Workspace=wsn, WorkspaceIndexList=','.join( [str(s) for s in range(nrows - 2, nrows)])) RemoveMaskedSpectra(InputWorkspace=wsn, OutputWorkspace=wsn) self.setProperty("OutputWorkspace", wsn)
def PyExec(self): input_workspaces = self._expand_groups() outWS = self.getPropertyValue("OutputWorkspace") CreatePeaksWorkspace(OutputType='LeanElasticPeak', InstrumentWorkspace=input_workspaces[0], NumberOfPeaks=0, OutputWorkspace=outWS, EnableLogging=False) method = self.getProperty("Method").value n_bkgr_pts = self.getProperty("NumBackgroundPts").value n_fwhm = self.getProperty("WidthScale").value scale = self.getProperty("ScaleFactor").value chisqmax = self.getProperty("ChiSqMax").value signalNoiseMin = self.getProperty("SignalNoiseMin").value ll = self.getProperty("LowerLeft").value ur = self.getProperty("UpperRight").value startX = self.getProperty('StartX').value endX = self.getProperty('EndX').value use_lorentz = self.getProperty("ApplyLorentz").value optmize_q = self.getProperty("OptimizeQVector").value output_fit = self.getProperty("OutputFitResults").value if output_fit and method != "Counts": fit_results = WorkspaceGroup() AnalysisDataService.addOrReplace(outWS + "_fit_results", fit_results) for inWS in input_workspaces: tmp_inWS = '__tmp_' + inWS IntegrateMDHistoWorkspace(InputWorkspace=inWS, P1Bin=f'{ll[1]},{ur[1]}', P2Bin=f'{ll[0]},{ur[0]}', OutputWorkspace=tmp_inWS, EnableLogging=False) ConvertMDHistoToMatrixWorkspace(tmp_inWS, OutputWorkspace=tmp_inWS, EnableLogging=False) data = ConvertToPointData(tmp_inWS, OutputWorkspace=tmp_inWS, EnableLogging=False) run = mtd[inWS].getExperimentInfo(0).run() scan_log = 'omega' if np.isclose(run.getTimeAveragedStd('phi'), 0.0) else 'phi' scan_axis = run[scan_log].value scan_step = (scan_axis[-1] - scan_axis[0]) / (scan_axis.size - 1) data.setX(0, scan_axis) y = data.extractY().flatten() x = data.extractX().flatten() __tmp_pw = CreatePeaksWorkspace(OutputType='LeanElasticPeak', InstrumentWorkspace=inWS, NumberOfPeaks=0, EnableLogging=False) if method != "Counts": # fit against gaussian with flat background for both the Fitted and CountsWithFitting methods fit_result = self._fit_gaussian(inWS, data, x, y, startX, endX, output_fit) if fit_result and fit_result.OutputStatus == 'success' and fit_result.OutputChi2overDoF < chisqmax: B, A, peak_centre, sigma, _ = fit_result.OutputParameters.toDict( )['Value'] _, errA, _, errs, _ = fit_result.OutputParameters.toDict( )['Error'] if method == "Fitted": integrated_intensity = A * sigma * np.sqrt(2 * np.pi) # Convert correlation back into covariance cor_As = ( fit_result.OutputNormalisedCovarianceMatrix.cell( 1, 4) / 100 * fit_result.OutputParameters.cell(1, 2) * fit_result.OutputParameters.cell(3, 2)) # σ^2 = 2π (A^2 σ_s^2 + σ_A^2 s^2 + 2 A s σ_As) integrated_intensity_error = np.sqrt( 2 * np.pi * (A**2 * errs**2 + sigma**2 * errA**2 + 2 * A * sigma * cor_As)) elif method == "CountsWithFitting": y = y[slice( np.searchsorted( x, peak_centre - 2.3548 * sigma * n_fwhm / 2), np.searchsorted( x, peak_centre + 2.3548 * sigma * n_fwhm / 2))] # subtract out the fitted flat background integrated_intensity = (y.sum() - B * y.size) * scan_step integrated_intensity_error = np.sum( np.sqrt(y)) * scan_step # update the goniometer position based on the fitted peak center if scan_log == 'omega': SetGoniometer(Workspace=__tmp_pw, Axis0=f'{peak_centre},0,1,0,-1', Axis1='chi,0,0,1,-1', Axis2='phi,0,1,0,-1', EnableLogging=False) else: SetGoniometer(Workspace=__tmp_pw, Axis0='omega,0,1,0,-1', Axis1='chi,0,0,1,-1', Axis2=f'{peak_centre},0,1,0,-1', EnableLogging=False) else: self.log().warning( "Failed to fit workspace {}: Output Status={}, ChiSq={}" .format(inWS, fit_result.OutputStatus, fit_result.OutputChi2overDoF)) self._delete_tmp_workspaces(str(__tmp_pw), tmp_inWS) continue else: integrated_intensity, integrated_intensity_error = self._counts_integration( data, n_bkgr_pts, scan_step) # set the goniometer position to use the average of the scan SetGoniometer(Workspace=__tmp_pw, Axis0='omega,0,1,0,-1', Axis1='chi,0,0,1,-1', Axis2='phi,0,1,0,-1', EnableLogging=False) integrated_intensity *= scale integrated_intensity_error *= scale peak = __tmp_pw.createPeakHKL([ run['h'].getStatistics().median, run['k'].getStatistics().median, run['l'].getStatistics().median ]) peak.setWavelength(float(run['wavelength'].value)) peak.setIntensity(integrated_intensity) peak.setSigmaIntensity(integrated_intensity_error) if integrated_intensity / integrated_intensity_error > signalNoiseMin: __tmp_pw.addPeak(peak) # correct q-vector using CentroidPeaksMD if optmize_q: __tmp_q_ws = HB3AAdjustSampleNorm(InputWorkspaces=inWS, NormaliseBy='None', EnableLogging=False) __tmp_pw = CentroidPeaksMD(__tmp_q_ws, __tmp_pw, EnableLogging=False) DeleteWorkspace(__tmp_q_ws, EnableLogging=False) if use_lorentz: # ILL Neutron Data Booklet, Second Edition, Section 2.9, Part 4.1, Equation 7 peak = __tmp_pw.getPeak(0) lorentz = abs( np.sin(peak.getScattering() * np.cos(peak.getAzimuthal()))) peak.setIntensity(peak.getIntensity() * lorentz) peak.setSigmaIntensity(peak.getSigmaIntensity() * lorentz) CombinePeaksWorkspaces(outWS, __tmp_pw, OutputWorkspace=outWS, EnableLogging=False) if output_fit and method != "Counts": fit_results.addWorkspace( RenameWorkspace(tmp_inWS + '_Workspace', outWS + "_" + inWS + '_Workspace', EnableLogging=False)) fit_results.addWorkspace( RenameWorkspace(tmp_inWS + '_Parameters', outWS + "_" + inWS + '_Parameters', EnableLogging=False)) fit_results.addWorkspace( RenameWorkspace( tmp_inWS + '_NormalisedCovarianceMatrix', outWS + "_" + inWS + '_NormalisedCovarianceMatrix', EnableLogging=False)) fit_results.addWorkspace( IntegrateMDHistoWorkspace( InputWorkspace=inWS, P1Bin=f'{ll[1]},0,{ur[1]}', P2Bin=f'{ll[0]},0,{ur[0]}', P3Bin='0,{}'.format( mtd[inWS].getDimension(2).getNBins()), OutputWorkspace=outWS + "_" + inWS + "_ROI", EnableLogging=False)) else: self.log().warning( "Skipping peak from {} because Signal/Noise={:.3f} which is less than {}" .format(inWS, integrated_intensity / integrated_intensity_error, signalNoiseMin)) self._delete_tmp_workspaces(str(__tmp_pw), tmp_inWS) self.setProperty("OutputWorkspace", mtd[outWS])
from mantid.simpleapi import Load, SetGoniometer, ConvertToMD import numpy as np run1 = 'CORELLI_48505' run2 = 'CORELLI_48513' run1 = 'CORELLI_48508' run2 = 'CORELLI_48516' ws1 = Load(run1) ws2 = Load(run2) SetGoniometer(ws1, Axis0="BL9:Mot:Sample:Axis2,0,1,0,1") SetGoniometer(ws2, Axis0="BL9:Mot:Sample:Axis2,0,1,0,1") md1 = ConvertToMD(ws1, QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='Q_sample', MinValues=[-10, -10, -10], MaxValues=[10, 10, 10]) md2 = ConvertToMD(ws2, QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='Q_sample', MinValues=[-10, -10, -10], MaxValues=[10, 10, 10]) bin1 = BinMD(md1, AlignedDim0='Q_sample_x,-10,10,1000', AlignedDim1='Q_sample_z,-10,10,1000',
def PyExec(self): 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) self._masking = bool(self.getProperty("MaskFile").value) _outWS_name = self.getPropertyValue("OutputWorkspace") _UB = bool(self.getProperty("UBMatrix").value) self.XMin = self.getProperty("MomentumMin").value self.XMax = self.getProperty("MomentumMax").value MinValues = self.getProperty("MinValues").value MaxValues = self.getProperty("MaxValues").value if self.getProperty("OverwriteExisting").value: if mtd.doesExist(_outWS_name): DeleteWorkspace(_outWS_name) progress = Progress(self, 0.0, 1.0, len(self.getProperty("Filename").value)) for run in self.getProperty("Filename").value: logger.notice("Working on " + run) self.load_file_and_apply(run, '__run') 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) if _UB: LoadIsawUB(InputWorkspace='__run', Filename=self.getProperty("UBMatrix").value) if len(MinValues) == 0 or len(MaxValues) == 0: MinValues, MaxValues = ConvertToMDMinMaxGlobal( '__run', dEAnalysisMode='Elastic', Q3DFrames='Q' if self.getProperty('QFrame').value == 'Q_sample' else 'HKL', QDimensions='Q3D') ConvertToMD( InputWorkspace='__run', OutputWorkspace=_outWS_name, QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames=self.getProperty('QFrame').value, QConversionScales='Q in A^-1' if self.getProperty('QFrame').value == 'Q_sample' else 'HKL', Uproj=self.getProperty('Uproj').value, Vproj=self.getProperty('Vproj').value, Wproj=self.getProperty('Wproj').value, MinValues=MinValues, MaxValues=MaxValues, SplitInto=self.getProperty('SplitInto').value, SplitThreshold=self.getProperty('SplitThreshold').value, MaxRecursionDepth=self.getProperty('MaxRecursionDepth').value, OverwriteExisting=False) DeleteWorkspace('__run') progress.report() if mtd.doesExist('__mask'): DeleteWorkspace('__mask') self.setProperty("OutputWorkspace", mtd[_outWS_name])
def PyExec(self): # Facility and database configuration config_new_options = { 'default.facility': 'SNS', 'default.instrument': 'BASIS', 'datasearch.searcharchive': 'On' } # Find valid incoming momentum range self._lambda_range = np.array(self.getProperty('LambdaRange').value) self._momentum_range = np.sort(2 * np.pi / self._lambda_range) # implement with ContextDecorator after python2 is deprecated) with pyexec_setup(config_new_options) as self._temps: # Load the mask to a temporary workspace self._t_mask = LoadMask( Instrument='BASIS', InputFile=self.getProperty('MaskFile').value, OutputWorkspace='_t_mask') # Pre-process the background runs if self.getProperty('BackgroundRuns').value: bkg_run_numbers = self._getRuns( self.getProperty('BackgroundRuns').value, doIndiv=True) bkg_run_numbers = \ list(itertools.chain.from_iterable(bkg_run_numbers)) background_reporter = Progress(self, start=0.0, end=1.0, nreports=len(bkg_run_numbers)) for i, run in enumerate(bkg_run_numbers): if self._bkg is None: self._bkg = self._mask_t0_crop(run, '_bkg') self._temps.workspaces.append('_bkg') else: _ws = self._mask_t0_crop(run, '_ws') self._bkg += _ws if '_ws' not in self._temps.workspaces: self._temps.workspaces.append('_ws') message = 'Pre-processing background: {} of {}'.\ format(i+1, len(bkg_run_numbers)) background_reporter.report(message) SetGoniometer(self._bkg, Axis0='0,0,1,0,1') self._bkg_scale = self.getProperty('BackgroundScale').value background_reporter.report(len(bkg_run_numbers), 'Done') # Pre-process the vanadium run(s) by removing the delayed # emission time from the moderator and then saving to file(s) if self.getProperty('VanadiumRuns').value: run_numbers = self._getRuns( self.getProperty('VanadiumRuns').value, doIndiv=True) run_numbers = list(itertools.chain.from_iterable(run_numbers)) vanadium_reporter = Progress(self, start=0.0, end=1.0, nreports=len(run_numbers)) self._vanadium_files = list() for i, run in enumerate(run_numbers): self._vanadium_files.append(self._save_t0(run)) message = 'Pre-processing vanadium: {} of {}'. \ format(i+1, len(run_numbers)) vanadium_reporter.report(message) vanadium_reporter.report(len(run_numbers), 'Done') # Determination of single crystal diffraction self._determine_single_crystal_diffraction()
LogText='%.4f' % omega_modified, LogType='Number Series') AddSampleLog(Workspace=event_ws, LogName='omegaRequest', LogText='%.4f' % omega_modified, LogType='Number Series') # chi = event_ws.getRun()['chi'].value[0] chi_modified = float(chi) - float(x_offset) AddSampleLog(Workspace=event_ws, LogName='chi', LogText='%.4f' % chi_modified, LogType='Number Series') phi = event_ws.getRun()['phi'].value[0] # SetGoniometer(Workspace='event_ws', Goniometers='Universal') print 'TOPAZ_%s Events =%20d Phi =%9.4f Chi = %9.4f Omega = %9.4f\n' % ( run, event_ws.getNumberEvents(), phi, chi_modified, omega_modified) SaveNexus(InputWorkspace='event_ws', Filename=os.path.join(output_directory, instrument + "_" + run + ".nxs.h5")) # # Load calibration file(s) if specified. NOTE: The file name passed in to LoadIsawDetCal # can not be None. TOPAZ has one calibration file, but SNAP may have two. # if (calibration_file_1 is not None) or (calibration_file_2 is not None): if (calibration_file_1 is None): calibration_file_1 = "" if (calibration_file_2 is None):
def PyExec(self): runs = self.getProperty("Filename").value if not runs: ipts = self.getProperty("IPTS").value runs = [ '/HFIR/HB2C/IPTS-{}/nexus/HB2C_{}.nxs.h5'.format(ipts, run) for run in self.getProperty("RunNumbers").value ] wavelength = self.getProperty("wavelength").value outWS = self.getPropertyValue("OutputWorkspace") group_names = [] grouping = self.getProperty("Grouping").value if grouping == 'None': grouping = 1 else: grouping = 2 if grouping == '2x2' else 4 for i, run in enumerate(runs): data = np.zeros((512 * 480 * 8), dtype=np.int64) with h5py.File(run, 'r') as f: monitor_count = f['/entry/monitor1/total_counts'].value[0] run_number = f['/entry/run_number'].value[0] for b in range(8): data += np.bincount(f['/entry/bank' + str(b + 1) + '_events/event_id'].value, minlength=512 * 480 * 8) data = data.reshape((480 * 8, 512)) if grouping == 2: data = data[::2, ::2] + data[ 1::2, ::2] + data[::2, 1::2] + data[1::2, 1::2] elif grouping == 4: data = (data[::4, ::4] + data[1::4, ::4] + data[2::4, ::4] + data[3::4, ::4] + data[::4, 1::4] + data[1::4, 1::4] + data[2::4, 1::4] + data[3::4, 1::4] + data[::4, 2::4] + data[1::4, 2::4] + data[2::4, 2::4] + data[3::4, 2::4] + data[::4, 3::4] + data[1::4, 3::4] + data[2::4, 3::4] + data[3::4, 3::4]) CreateWorkspace(DataX=[wavelength - 0.001, wavelength + 0.001], DataY=data, DataE=np.sqrt(data), UnitX='Wavelength', YUnitLabel='Counts', NSpec=1966080 // grouping**2, OutputWorkspace='__tmp_load', EnableLogging=False) LoadNexusLogs('__tmp_load', Filename=run, EnableLogging=False) AddSampleLog('__tmp_load', LogName="monitor_count", LogType='Number', NumberType='Double', LogText=str(monitor_count), EnableLogging=False) AddSampleLog('__tmp_load', LogName="gd_prtn_chrg", LogType='Number', NumberType='Double', LogText=str(monitor_count), EnableLogging=False) AddSampleLog('__tmp_load', LogName="Wavelength", LogType='Number', NumberType='Double', LogText=str(wavelength), EnableLogging=False) AddSampleLog('__tmp_load', LogName="Ei", LogType='Number', NumberType='Double', LogText=str( UnitConversion.run('Wavelength', 'Energy', wavelength, 0, 0, 0, Elastic, 0)), EnableLogging=False) AddSampleLog('__tmp_load', LogName="run_number", LogText=run_number, EnableLogging=False) if grouping > 1: # Fix detector IDs per spectrum before loading instrument __tmp_load = mtd['__tmp_load'] for n in range(__tmp_load.getNumberHistograms()): s = __tmp_load.getSpectrum(n) for i in range(grouping): for j in range(grouping): s.addDetectorID( int(n * grouping % 512 + n // (512 / grouping) * 512 * grouping + j + i * 512)) LoadInstrument('__tmp_load', InstrumentName='WAND', RewriteSpectraMap=False, EnableLogging=False) else: LoadInstrument('__tmp_load', InstrumentName='WAND', RewriteSpectraMap=True, EnableLogging=False) SetGoniometer('__tmp_load', Axis0="HB2C:Mot:s1,0,1,0,1", EnableLogging=False) if self.getProperty("ApplyMask").value: MaskBTP('__tmp_load', Pixel='1,2,511,512', EnableLogging=False) if mtd['__tmp_load'].getRunNumber( ) > 26600: # They changed pixel mapping and bank name order here MaskBTP('__tmp_load', Bank='1', Tube='479-480', EnableLogging=False) MaskBTP('__tmp_load', Bank='8', Tube='1-2', EnableLogging=False) else: MaskBTP('__tmp_load', Bank='8', Tube='475-480', EnableLogging=False) if len(runs) == 1: RenameWorkspace('__tmp_load', outWS, EnableLogging=False) else: outName = outWS + "_" + str(mtd['__tmp_load'].getRunNumber()) group_names.append(outName) RenameWorkspace('__tmp_load', outName, EnableLogging=False) if len(runs) > 1: GroupWorkspaces(group_names, OutputWorkspace=outWS, EnableLogging=False) self.setProperty('OutputWorkspace', outWS)
def PyExec(self): input_workspaces = self._expand_groups() outWS = self.getPropertyValue("OutputWorkspace") CreatePeaksWorkspace(OutputType='LeanElasticPeak', InstrumentWorkspace=input_workspaces[0], NumberOfPeaks=0, OutputWorkspace=outWS, EnableLogging=False) scale = self.getProperty("ScaleFactor").value chisqmax = self.getProperty("ChiSqMax").value signalNoiseMin = self.getProperty("SignalNoiseMin").value ll = self.getProperty("LowerLeft").value ur = self.getProperty("UpperRight").value startX = self.getProperty('StartX').value endX = self.getProperty('EndX').value use_lorentz = self.getProperty("ApplyLorentz").value optmize_q = self.getProperty("OptimizeQVector").value output_fit = self.getProperty("OutputFitResults").value if output_fit: fit_results = WorkspaceGroup() AnalysisDataService.addOrReplace(outWS + "_fit_results", fit_results) for inWS in input_workspaces: tmp_inWS = '__tmp_' + inWS IntegrateMDHistoWorkspace(InputWorkspace=inWS, P1Bin=f'{ll[1]},{ur[1]}', P2Bin=f'{ll[0]},{ur[0]}', OutputWorkspace=tmp_inWS, EnableLogging=False) ConvertMDHistoToMatrixWorkspace(tmp_inWS, OutputWorkspace=tmp_inWS, EnableLogging=False) data = ConvertToPointData(tmp_inWS, OutputWorkspace=tmp_inWS, EnableLogging=False) run = mtd[inWS].getExperimentInfo(0).run() scan_log = 'omega' if np.isclose(run.getTimeAveragedStd('phi'), 0.0) else 'phi' scan_axis = run[scan_log].value data.setX(0, scan_axis) y = data.extractY().flatten() x = data.extractX().flatten() function = f"name=FlatBackground, A0={np.nanmin(y)};" \ f"name=Gaussian, PeakCentre={x[np.nanargmax(y)]}, Height={np.nanmax(y)-np.nanmin(y)}, Sigma=0.25" constraints = f"f0.A0 > 0, f1.Height > 0, {x.min()} < f1.PeakCentre < {x.max()}" try: fit_result = Fit(function, data, Output=str(data), IgnoreInvalidData=True, OutputParametersOnly=not output_fit, Constraints=constraints, StartX=startX, EndX=endX, EnableLogging=False) except RuntimeError as e: self.log().warning("Failed to fit workspace {}: {}".format( inWS, e)) continue if fit_result.OutputStatus == 'success' and fit_result.OutputChi2overDoF < chisqmax: __tmp_pw = CreatePeaksWorkspace(OutputType='LeanElasticPeak', InstrumentWorkspace=inWS, NumberOfPeaks=0, EnableLogging=False) _, A, x, s, _ = fit_result.OutputParameters.toDict()['Value'] _, errA, _, errs, _ = fit_result.OutputParameters.toDict( )['Error'] if scan_log == 'omega': SetGoniometer(Workspace=__tmp_pw, Axis0=f'{x},0,1,0,-1', Axis1='chi,0,0,1,-1', Axis2='phi,0,1,0,-1', EnableLogging=False) else: SetGoniometer(Workspace=__tmp_pw, Axis0='omega,0,1,0,-1', Axis1='chi,0,0,1,-1', Axis2=f'{x},0,1,0,-1', EnableLogging=False) peak = __tmp_pw.createPeakHKL([ run['h'].getStatistics().median, run['k'].getStatistics().median, run['l'].getStatistics().median ]) peak.setWavelength(float(run['wavelength'].value)) integrated_intensity = A * s * np.sqrt(2 * np.pi) * scale peak.setIntensity(integrated_intensity) # Convert correlation back into covariance cor_As = ( fit_result.OutputNormalisedCovarianceMatrix.cell(1, 4) / 100 * fit_result.OutputParameters.cell(1, 2) * fit_result.OutputParameters.cell(3, 2)) # σ^2 = 2π (A^2 σ_s^2 + σ_A^2 s^2 + 2 A s σ_As) integrated_intensity_error = np.sqrt( 2 * np.pi * (A**2 * errs**2 + s**2 * errA**2 + 2 * A * s * cor_As)) * scale peak.setSigmaIntensity(integrated_intensity_error) if integrated_intensity / integrated_intensity_error > signalNoiseMin: __tmp_pw.addPeak(peak) # correct q-vector using CentroidPeaksMD if optmize_q: __tmp_q_ws = HB3AAdjustSampleNorm(InputWorkspaces=inWS, NormaliseBy='None', EnableLogging=False) __tmp_pw = CentroidPeaksMD(__tmp_q_ws, __tmp_pw, EnableLogging=False) DeleteWorkspace(__tmp_q_ws, EnableLogging=False) if use_lorentz: # ILL Neutron Data Booklet, Second Edition, Section 2.9, Part 4.1, Equation 7 peak = __tmp_pw.getPeak(0) lorentz = abs( np.sin(peak.getScattering() * np.cos(peak.getAzimuthal()))) peak.setIntensity(peak.getIntensity() * lorentz) peak.setSigmaIntensity(peak.getSigmaIntensity() * lorentz) CombinePeaksWorkspaces(outWS, __tmp_pw, OutputWorkspace=outWS, EnableLogging=False) DeleteWorkspace(__tmp_pw, EnableLogging=False) if output_fit: fit_results.addWorkspace( RenameWorkspace(tmp_inWS + '_Workspace', outWS + "_" + inWS + '_Workspace', EnableLogging=False)) fit_results.addWorkspace( RenameWorkspace(tmp_inWS + '_Parameters', outWS + "_" + inWS + '_Parameters', EnableLogging=False)) fit_results.addWorkspace( RenameWorkspace(tmp_inWS + '_NormalisedCovarianceMatrix', outWS + "_" + inWS + '_NormalisedCovarianceMatrix', EnableLogging=False)) fit_results.addWorkspace( IntegrateMDHistoWorkspace( InputWorkspace=inWS, P1Bin=f'{ll[1]},0,{ur[1]}', P2Bin=f'{ll[0]},0,{ur[0]}', P3Bin='0,{}'.format( mtd[inWS].getDimension(2).getNBins()), OutputWorkspace=outWS + "_" + inWS + "_ROI", EnableLogging=False)) else: self.log().warning( "Skipping peak from {} because Signal/Noise={:.3f} which is less than {}" .format( inWS, integrated_intensity / integrated_intensity_error, signalNoiseMin)) else: self.log().warning( "Failed to fit workspace {}: Output Status={}, ChiSq={}". format(inWS, fit_result.OutputStatus, fit_result.OutputChi2overDoF)) for tmp_ws in (tmp_inWS, tmp_inWS + '_Workspace', tmp_inWS + '_Parameters', tmp_inWS + '_NormalisedCovarianceMatrix'): if mtd.doesExist(tmp_ws): DeleteWorkspace(tmp_ws, EnableLogging=False) self.setProperty("OutputWorkspace", mtd[outWS])