def performOperation(self): lhs_valid, rhs_valid, err_msg = self.validateInputs() if err_msg != str(): return lhs_valid, rhs_valid, err_msg lhs_ws, rhs_ws = self._scale_input_workspaces() try: if self._operation == '+': if self._md_lhs or self._md_rhs: PlusMD(LHSWorkspace=lhs_ws, RHSWorkspace=rhs_ws, OutputWorkspace=self._output_ws) else: Plus(LHSWorkspace=lhs_ws, RHSWorkspace=rhs_ws, OutputWorkspace=self._output_ws) elif self._operation == '-': if self._md_lhs or self._md_rhs: MinusMD(LHSWorkspace=lhs_ws, RHSWorkspace=rhs_ws, OutputWorkspace=self._output_ws) else: Minus(LHSWorkspace=lhs_ws, RHSWorkspace=rhs_ws, OutputWorkspace=self._output_ws) elif self._operation == '*': if self._md_lhs or self._md_rhs: MultiplyMD(LHSWorkspace=lhs_ws, RHSWorkspace=rhs_ws, OutputWorkspace=self._output_ws) else: Multiply(LHSWorkspace=lhs_ws, RHSWorkspace=rhs_ws, OutputWorkspace=self._output_ws) elif self._operation == 'WM': if self._md_lhs or self._md_rhs: WeightedMeanMD(LHSWorkspace=lhs_ws, RHSWorkspace=rhs_ws, OutputWorkspace=self._output_ws) else: WeightedMean(InputWorkspace1=lhs_ws, InputWorkspace2=rhs_ws, OutputWorkspace=self._output_ws) else: if self._md_lhs or self._md_rhs: DivideMD(LHSWorkspace=lhs_ws, RHSWorkspace=rhs_ws, OutputWorkspace=self._output_ws) else: Divide(LHSWorkspace=lhs_ws, RHSWorkspace=rhs_ws, OutputWorkspace=self._output_ws) except (RuntimeError, ValueError) as err: return False, False, str(err) else: self._regularize_output_names(self._output_ws) finally: DeleteWorkspaces(WorkspaceList=[lhs_ws, rhs_ws]) return True, True, ""
def _scale_md(self, ws_name, scale): scale_ws = 'scale_ws' CreateSingleValuedWorkspace(DataValue=scale, OutputWorkspace=scale_ws) if isinstance(mtd[ws_name], WorkspaceGroup): ws_name = self._scale_md_group(ws_name, scale_ws) else: MultiplyMD(LHSWorkspace=ws_name, RHSWorkspace=scale_ws, OutputWorkspace=ws_name) DeleteWorkspace(Workspace=scale_ws)
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 _scale_md_group(ws_group, scale_ws): for entry in mtd[ws_group]: MultiplyMD(LHSWorkspace=entry, RHSWorkspace=scale_ws, OutputWorkspace=entry)
def PyExec(self): # remove possible old temp workspaces [ DeleteWorkspace(ws) for ws in self.temp_workspace_list if mtd.doesExist(ws) ] _background = bool(self.getProperty("Background").value) self._load_inst = bool(self.getProperty("LoadInstrument").value) self._apply_cal = bool(self.getProperty("ApplyCalibration").value) self._detcal = bool(self.getProperty("DetCal").value) self._copy_params = bool( self.getProperty("CopyInstrumentParameters").value) _masking = bool(self.getProperty("MaskFile").value) _outWS_name = self.getPropertyValue("OutputWorkspace") _UB = self.getProperty("UBMatrix").value if len(_UB) == 1: _UB = np.tile(_UB, len(self.getProperty("Filename").value)) _offsets = self.getProperty("OmegaOffset").value if len(_offsets) == 0: _offsets = np.zeros(len(self.getProperty("Filename").value)) if self.getProperty("ReuseSAFlux").value and mtd.doesExist( '__sa') and mtd.doesExist('__flux'): logger.notice( "Reusing previously loaded SolidAngle and Flux workspaces. " "Set ReuseSAFlux to False if new files are selected or you change the momentum range." ) else: logger.notice("Loading SolidAngle and Flux from file") LoadNexus(Filename=self.getProperty("SolidAngle").value, OutputWorkspace='__sa') LoadNexus(Filename=self.getProperty("Flux").value, OutputWorkspace='__flux') if _masking: LoadMask(Instrument=mtd['__sa'].getInstrument().getName(), InputFile=self.getProperty("MaskFile").value, OutputWorkspace='__mask') MaskDetectors(Workspace='__sa', MaskedWorkspace='__mask') DeleteWorkspace('__mask') self.XMin = mtd['__sa'].getXDimension().getMinimum() self.XMax = mtd['__sa'].getXDimension().getMaximum() newXMin = self.getProperty("MomentumMin").value newXMax = self.getProperty("MomentumMax").value if newXMin != Property.EMPTY_DBL or newXMax != Property.EMPTY_DBL: if newXMin != Property.EMPTY_DBL: self.XMin = max(self.XMin, newXMin) if newXMax != Property.EMPTY_DBL: self.XMax = min(self.XMax, newXMax) logger.notice("Using momentum range {} to {} A^-1".format( self.XMin, self.XMax)) CropWorkspace(InputWorkspace='__flux', OutputWorkspace='__flux', XMin=self.XMin, XMax=self.XMax) for spectrumNumber in range(mtd['__flux'].getNumberHistograms()): Y = mtd['__flux'].readY(spectrumNumber) mtd['__flux'].setY(spectrumNumber, (Y - Y.min()) / (Y.max() - Y.min())) MinValues = [-self.XMax * 2] * 3 MaxValues = [self.XMax * 2] * 3 if _background: self.load_file_and_apply( self.getProperty("Background").value, '__bkg', 0) progress = Progress(self, 0.0, 1.0, len(self.getProperty("Filename").value)) for n, run in enumerate(self.getProperty("Filename").value): logger.notice("Working on " + run) self.load_file_and_apply(run, '__run', _offsets[n]) LoadIsawUB('__run', _UB[n]) ConvertToMD(InputWorkspace='__run', OutputWorkspace='__md', QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='Q_sample', MinValues=MinValues, MaxValues=MaxValues) RecalculateTrajectoriesExtents(InputWorkspace='__md', OutputWorkspace='__md') MDNorm( InputWorkspace='__md', FluxWorkspace='__flux', SolidAngleWorkspace='__sa', OutputDataWorkspace='__data', TemporaryDataWorkspace='__data' if mtd.doesExist('__data') else None, OutputNormalizationWorkspace='__norm', TemporaryNormalizationWorkspace='__norm' if mtd.doesExist('__norm') else None, OutputWorkspace=_outWS_name, QDimension0=self.getProperty('QDimension0').value, QDimension1=self.getProperty('QDimension1').value, QDimension2=self.getProperty('QDimension2').value, Dimension0Binning=self.getProperty('Dimension0Binning').value, Dimension1Binning=self.getProperty('Dimension1Binning').value, Dimension2Binning=self.getProperty('Dimension2Binning').value, SymmetryOperations=self.getProperty( 'SymmetryOperations').value) DeleteWorkspace('__md') if _background: # Set background Goniometer and UB to be the same as data CopySample(InputWorkspace='__run', OutputWorkspace='__bkg', CopyName=False, CopyMaterial=False, CopyEnvironment=False, CopyShape=False, CopyLattice=True) mtd['__bkg'].run().getGoniometer().setR( mtd['__run'].run().getGoniometer().getR()) ConvertToMD(InputWorkspace='__bkg', OutputWorkspace='__bkg_md', QDimensions='Q3D', dEAnalysisMode='Elastic', Q3DFrames='Q_sample', MinValues=MinValues, MaxValues=MaxValues) RecalculateTrajectoriesExtents(InputWorkspace='__bkg_md', OutputWorkspace='__bkg_md') MDNorm(InputWorkspace='__bkg_md', FluxWorkspace='__flux', SolidAngleWorkspace='__sa', OutputDataWorkspace='__bkg_data', TemporaryDataWorkspace='__bkg_data' if mtd.doesExist('__bkg_data') else None, OutputNormalizationWorkspace='__bkg_norm', TemporaryNormalizationWorkspace='__bkg_norm' if mtd.doesExist('__bkg_norm') else None, OutputWorkspace='__normalizedBackground', QDimension0=self.getProperty('QDimension0').value, QDimension1=self.getProperty('QDimension1').value, QDimension2=self.getProperty('QDimension2').value, Dimension0Binning=self.getProperty( 'Dimension0Binning').value, Dimension1Binning=self.getProperty( 'Dimension1Binning').value, Dimension2Binning=self.getProperty( 'Dimension2Binning').value, SymmetryOperations=self.getProperty( 'SymmetryOperations').value) DeleteWorkspace('__bkg_md') progress.report() DeleteWorkspace('__run') if _background: # outWS = data / norm - bkg_data / bkg_norm * BackgroundScale CreateSingleValuedWorkspace( OutputWorkspace='__scale', DataValue=self.getProperty('BackgroundScale').value) MultiplyMD(LHSWorkspace='__normalizedBackground', RHSWorkspace='__scale', OutputWorkspace='__normalizedBackground') DeleteWorkspace('__scale') MinusMD(LHSWorkspace=_outWS_name, RHSWorkspace='__normalizedBackground', OutputWorkspace=_outWS_name) if self.getProperty('KeepTemporaryWorkspaces').value: RenameWorkspaces(InputWorkspaces=[ '__data', '__norm', '__bkg_data', '__bkg_norm' ], WorkspaceNames=[ _outWS_name + '_data', _outWS_name + '_normalization', _outWS_name + '_background_data', _outWS_name + '_background_normalization' ]) else: if self.getProperty('KeepTemporaryWorkspaces').value: RenameWorkspaces(InputWorkspaces=['__data', '__norm'], WorkspaceNames=[ _outWS_name + '_data', _outWS_name + '_normalization' ]) self.setProperty("OutputWorkspace", mtd[_outWS_name]) # remove temp workspaces [ DeleteWorkspace(ws) for ws in self.temp_workspace_list if mtd.doesExist(ws) ]