def _table_to_workspace( input_workspace: Union[str, TableWorkspace], output_workspace: Optional[str] = None) -> MaskWorkspace: r""" @brief Convert a CORELLI calibration mask table to a MaskWorkspace :param input_workspace : the table containing the detector ID's for the masked detectors :param output_workspace : name of the output MaskWorkspace :return: handle to the MaskWorkspace """ table_handle = mtd[str(input_workspace)] detectors_masked = table_handle.column(0) # list of masked detectors if output_workspace is None: output_workspace = str(input_workspace) LoadEmptyInstrument(InstrumentName='CORELLI', OutputWorkspace=output_workspace) ClearMaskFlag(Workspace=output_workspace) # for good measure MaskDetectors( Workspace=output_workspace, DetectorList=detectors_masked) # output_workspace is a Workspace2D # output_workspace is converted to a MaskWorkspace, where the Y-values of the spectra are now either 0 or 1 ExtractMask(InputWorkspace=output_workspace, OutputWorkspace=output_workspace) return mtd[output_workspace]
def _createMaskWS(ws, name, algorithmLogging): """Return a single bin workspace with same number of histograms as ws.""" maskWS, detList = ExtractMask(InputWorkspace=ws, OutputWorkspace=name, EnableLogging=algorithmLogging) maskWS *= 0.0 return maskWS
def _locate_global_xlimit(self): """Find the global bin from all spectrum""" input_workspaces = self.getProperty("InputWorkspace").value mask = self.getProperty("MaskWorkspace").value maks_angle = self.getProperty("MaskAngle").value target = self.getProperty("Target").value e_fixed = self.getProperty("EFixed").value # NOTE: # Due to range difference among incoming spectra, a common bin para is needed # such that all data can be binned exactly the same way. _xMin, _xMax = 1e16, -1e16 # BEGIN_FOR: located_global_xMin&xMax for n, _wsn in enumerate(input_workspaces): _ws = AnalysisDataService.retrieve(_wsn) _mskn = f"__mask_{n}" self.temp_workspace_list.append(_mskn) ExtractMask(_ws, OutputWorkspace=_mskn, EnableLogging=False) if maks_angle != Property.EMPTY_DBL: MaskAngle( Workspace=_mskn, MinAngle=maks_angle, Angle="Phi", EnableLogging=False, ) if mask is not None: BinaryOperateMasks( InputWorkspace1=_mskn, InputWorkspace2=mask, OperationType="OR", OutputWorkspace=_mskn, EnableLogging=False, ) _ws_tmp = ExtractUnmaskedSpectra( InputWorkspace=_ws, MaskWorkspace=_mskn, EnableLogging=False ) if isinstance(mtd["_ws_tmp"], IEventWorkspace): _ws_tmp = Integration(InputWorkspace=_ws_tmp, EnableLogging=False) _ws_tmp = ConvertSpectrumAxis( InputWorkspace=_ws_tmp, Target=target, EFixed=e_fixed, EnableLogging=False, ) _ws_tmp = Transpose( InputWorkspace=_ws_tmp, OutputWorkspace=f"__ws_{n}", EnableLogging=False ) _xMin = min(_xMin, _ws_tmp.readX(0).min()) _xMax = max(_xMax, _ws_tmp.readX(0).max()) # END_FOR: located_global_xMin&xMax return _xMin, _xMax
def _createMaskWS(ws, name, algorithmLogging): """Return a single bin workspace with same number of histograms as ws.""" extractResult = ExtractMask(InputWorkspace=ws, OutputWorkspace=name, EnableLogging=algorithmLogging) maskWS = Scale(InputWorkspace=extractResult.OutputWorkspace, Factor=0., OutputWorkspace=name, EnableLogging=algorithmLogging) return maskWS
def _createMaskWS(ws, name, algorithmLogging): """Return a single bin workspace with same number of histograms as ws.""" extractResult = ExtractMask(InputWorkspace=ws, OutputWorkspace=name, EnableLogging=algorithmLogging) zeroWS = CreateSingleValuedWorkspace(DataValue=0., ErrorValue=0., EnableLogging=algorithmLogging, StoreInADS=False) maskWS = Multiply(LHSWorkspace=extractResult.OutputWorkspace, RHSWorkspace=zeroWS, OutputWorkspace=name, EnableLogging=algorithmLogging) return maskWS
def _userMask(self, mainWS, wsNames, wsCleanup, algorithmLogging): """Return combined masked spectra and components.""" userMask = self.getProperty(common.PROP_USER_MASK).value maskComponents = self.getProperty(common.PROP_USER_MASK_COMPONENTS).value maskWSName = wsNames.withSuffix('user_mask') maskWS = _createMaskWS(mainWS, maskWSName, algorithmLogging) MaskDetectors(Workspace=maskWS, DetectorList=userMask, ComponentList=maskComponents, EnableLogging=algorithmLogging) maskWS, detectorLsit = ExtractMask(InputWorkspace=maskWS, OutputWorkspace=maskWSName, EnableLogging=algorithmLogging) return maskWS
def _userMask(self, mainWS): """Return combined masked spectra and components.""" userMask = self.getProperty(common.PROP_USER_MASK).value maskComponents = self.getProperty( common.PROP_USER_MASK_COMPONENTS).value maskWSName = self._names.withSuffix('user_mask') maskWS = _createMaskWS(mainWS, maskWSName, self._subalgLogging) MaskDetectors(Workspace=maskWS, DetectorList=userMask, ComponentList=maskComponents, EnableLogging=self._subalgLogging) extractResult = ExtractMask(InputWorkspace=maskWS, OutputWorkspace=maskWSName, EnableLogging=self._subalgLogging) return extractResult.OutputWorkspace
def _convert_data(self, input_workspaces): mask = self.getProperty("MaskWorkspace").value mask_angle = self.getProperty("MaskAngle").value outname = self.getProperty("OutputWorkspace").valueAsStr # NOTE: # Due to range difference among incoming spectra, a common bin para is needed # such that all data can be binned exactly the same way. # BEGIN_FOR: located_global_xMin&xMax output_workspaces = [ f"{outname}{n+1}" for n in range(len(input_workspaces)) ] mask_workspaces = [] for n, (_wksp_in, _wksp_out) in enumerate( zip(input_workspaces, output_workspaces)): _wksp_in = str(_wksp_in) _mask_n = f"__mask_{n}" # mask for n-th self.temp_workspace_list.append(_mask_n) # cleanup later ExtractMask(InputWorkspace=_wksp_in, OutputWorkspace=_mask_n, EnableLogging=False) if mask_angle != Property.EMPTY_DBL: MaskAngle( Workspace=_mask_n, MinAngle=mask_angle, Angle="Phi", EnableLogging=False, ) if mask is not None: # might be a bug if the mask angle isn't set BinaryOperateMasks( InputWorkspace1=_mask_n, InputWorkspace2=mask, OperationType="OR", OutputWorkspace=_mask_n, EnableLogging=False, ) self._to_spectrum_axis(_wksp_in, _wksp_out, _mask_n) # append to the list of processed workspaces mask_workspaces.append(_mask_n) return output_workspaces, mask_workspaces
def get_state(self): """ Returns an object with the state of the interface """ m = ReductionOptions() m.instrument_name = self._summary.instr_name_label.text() # Absolute scaling m.scaling_factor = util._check_and_get_float_line_edit( self._summary.scale_edit) m.calculate_scale = self._summary.scale_chk.isChecked() m.scaling_direct_file = unicode(self._summary.scale_data_edit.text()) m.scaling_att_trans = util._check_and_get_float_line_edit( self._summary.scale_att_trans_edit) m.scaling_beam_diam = util._check_and_get_float_line_edit( self._summary.scale_beam_radius_edit, min=0.0) m.manual_beam_diam = self._summary.beamstop_chk.isChecked() # ## If total detector distance is checked, ignore the other 3 distances: # if self._summary.total_detector_distance_chk.isChecked(): # m.sample_total_distance = util._check_and_get_float_line_edit(self._summary.total_detector_distance_edit) # else: # # Detector offset input # if self._summary.detector_offset_chk.isChecked(): # m.detector_offset = util._check_and_get_float_line_edit(self._summary.detector_offset_edit) # # Sample-detector distance # if self._summary.sample_dist_chk.isChecked(): # m.sample_detector_distance = util._check_and_get_float_line_edit(self._summary.sample_dist_edit) # # Sample-Si-window # if self._summary.sample_si_dist_chk.isChecked(): # m.sample_si_window_distance = util._check_and_get_float_line_edit(self._summary.sample_si_dist_edit) # Workaround: # Offset is not used # The detector_distanc will be used as sample_total_distance m.sample_detector_distance = util._check_and_get_float_line_edit( self._summary.total_detector_distance_edit) m.detector_offset = 0 # Wavelength value wavelength = util._check_and_get_float_line_edit( self._summary.wavelength_edit, min=0.0) if self._summary.wavelength_chk.isChecked(): m.wavelength = wavelength m.wavelength_spread = util._check_and_get_float_line_edit( self._summary.wavelength_spread_edit) # Solid angle correction m.solid_angle_corr = self._summary.solid_angle_chk.isChecked() # Dark current m.dark_current_corr = self._summary.dark_current_check.isChecked() m.dark_current_data = unicode(self._summary.dark_file_edit.text()) # Normalization if self._summary.normalization_none_radio.isChecked(): m.normalization = m.NORMALIZATION_NONE elif self._summary.normalization_time_radio.isChecked(): m.normalization = m.NORMALIZATION_TIME elif self._summary.normalization_monitor_radio.isChecked(): m.normalization = m.NORMALIZATION_MONITOR # Q range m.n_q_bins = util._check_and_get_int_line_edit( self._summary.n_q_bins_edit) m.n_sub_pix = util._check_and_get_int_line_edit( self._summary.n_sub_pix_edit) m.log_binning = self._summary.log_binning_radio.isChecked() m.align_log_with_decades = self._summary.align_check.isChecked() m.error_weighting = self._summary.error_weighting_check.isChecked() m.n_wedges = util._check_and_get_int_line_edit( self._summary.n_wedges_edit) m.wedge_angle = util._check_and_get_float_line_edit( self._summary.wedge_angle_edit) m.wedge_offset = util._check_and_get_float_line_edit( self._summary.wedge_offset_edit) # Detector side masking if self._summary.mask_side_front_radio.isChecked(): m.masked_side = 'Front' elif self._summary.mask_side_back_radio.isChecked(): m.masked_side = 'Back' else: m.masked_side = None # Mask detector IDs m.use_mask_file = self._summary.mask_check.isChecked() m.mask_file = unicode(self._summary.mask_edit.text()) m.detector_ids = self._masked_detectors if AnalysisDataService.doesExist(self.mask_ws): _, masked_detectors = ExtractMask(InputWorkspace=self.mask_ws, OutputWorkspace="__edited_mask") m.detector_ids = [int(i) for i in masked_detectors] self._settings.emit_key_value("DARK_CURRENT", str(self._summary.dark_file_edit.text())) return m
def PyExec(self): data = self.getProperty("InputWorkspace").value cal = self.getProperty("CalibrationWorkspace").value bkg = self.getProperty("BackgroundWorkspace").value mask = self.getProperty("MaskWorkspace").value target = self.getProperty("Target").value eFixed = self.getProperty("EFixed").value xMin = self.getProperty("XMin").value xMax = self.getProperty("XMax").value numberBins = self.getProperty("NumberBins").value normaliseBy = self.getProperty("NormaliseBy").value maskAngle = self.getProperty("MaskAngle").value outWS = self.getPropertyValue("OutputWorkspace") data_scale = 1 cal_scale = 1 bkg_scale = 1 if normaliseBy == "Monitor": data_scale = data.run().getProtonCharge() elif normaliseBy == "Time": data_scale = data.run().getLogData('duration').value ExtractMask(data, OutputWorkspace='__mask_tmp', EnableLogging=False) if maskAngle != Property.EMPTY_DBL: MaskAngle(Workspace='__mask_tmp', MinAngle=maskAngle, Angle='Phi', EnableLogging=False) if mask is not None: BinaryOperateMasks(InputWorkspace1='__mask_tmp', InputWorkspace2=mask, OperationType='OR', OutputWorkspace='__mask_tmp', EnableLogging=False) ExtractUnmaskedSpectra(InputWorkspace=data, MaskWorkspace='__mask_tmp', OutputWorkspace='__data_tmp', EnableLogging=False) if isinstance(mtd['__data_tmp'], IEventWorkspace): Integration(InputWorkspace='__data_tmp', OutputWorkspace='__data_tmp', EnableLogging=False) ConvertSpectrumAxis(InputWorkspace='__data_tmp', Target=target, EFixed=eFixed, OutputWorkspace=outWS, EnableLogging=False) Transpose(InputWorkspace=outWS, OutputWorkspace=outWS, EnableLogging=False) ResampleX(InputWorkspace=outWS, OutputWorkspace=outWS, XMin=xMin, XMax=xMax, NumberBins=numberBins, EnableLogging=False) if cal is not None: ExtractUnmaskedSpectra(InputWorkspace=cal, MaskWorkspace='__mask_tmp', OutputWorkspace='__cal_tmp', EnableLogging=False) if isinstance(mtd['__cal_tmp'], IEventWorkspace): Integration(InputWorkspace='__cal_tmp', OutputWorkspace='__cal_tmp', EnableLogging=False) CopyInstrumentParameters(data, '__cal_tmp', EnableLogging=False) ConvertSpectrumAxis(InputWorkspace='__cal_tmp', Target=target, EFixed=eFixed, OutputWorkspace='__cal_tmp', EnableLogging=False) Transpose(InputWorkspace='__cal_tmp', OutputWorkspace='__cal_tmp', EnableLogging=False) ResampleX(InputWorkspace='__cal_tmp', OutputWorkspace='__cal_tmp', XMin=xMin, XMax=xMax, NumberBins=numberBins, EnableLogging=False) Divide(LHSWorkspace=outWS, RHSWorkspace='__cal_tmp', OutputWorkspace=outWS, EnableLogging=False) if normaliseBy == "Monitor": cal_scale = cal.run().getProtonCharge() elif normaliseBy == "Time": cal_scale = cal.run().getLogData('duration').value Scale(InputWorkspace=outWS, OutputWorkspace=outWS, Factor=cal_scale / data_scale, EnableLogging=False) if bkg is not None: ExtractUnmaskedSpectra(InputWorkspace=bkg, MaskWorkspace='__mask_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False) if isinstance(mtd['__bkg_tmp'], IEventWorkspace): Integration(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False) CopyInstrumentParameters(data, '__bkg_tmp', EnableLogging=False) ConvertSpectrumAxis(InputWorkspace='__bkg_tmp', Target=target, EFixed=eFixed, OutputWorkspace='__bkg_tmp', EnableLogging=False) Transpose(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False) ResampleX(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', XMin=xMin, XMax=xMax, NumberBins=numberBins, EnableLogging=False) if cal is not None: Divide(LHSWorkspace='__bkg_tmp', RHSWorkspace='__cal_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False) if normaliseBy == "Monitor": bkg_scale = bkg.run().getProtonCharge() elif normaliseBy == "Time": bkg_scale = bkg.run().getLogData('duration').value Scale(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', Factor=cal_scale / bkg_scale, EnableLogging=False) Scale(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', Factor=self.getProperty('BackgroundScale').value, EnableLogging=False) Minus(LHSWorkspace=outWS, RHSWorkspace='__bkg_tmp', OutputWorkspace=outWS, EnableLogging=False) self.setProperty("OutputWorkspace", outWS) # remove temp workspaces [ DeleteWorkspace(ws, EnableLogging=False) for ws in self.temp_workspace_list if mtd.doesExist(ws) ]
def get_state(self): """ Returns an object with the state of the interface """ m = ReductionOptions() m.instrument_name = self._summary.instr_name_label.text() # Absolute scaling m.scaling_factor = util._check_and_get_float_line_edit(self._summary.scale_edit) m.calculate_scale = self._summary.scale_chk.isChecked() m.scaling_direct_file = unicode(self._summary.scale_data_edit.text()) m.scaling_att_trans = util._check_and_get_float_line_edit(self._summary.scale_att_trans_edit) m.scaling_beam_diam = util._check_and_get_float_line_edit(self._summary.scale_beam_radius_edit, min=0.0) m.manual_beam_diam = self._summary.beamstop_chk.isChecked() # Detector offset input if self._summary.detector_offset_chk.isChecked(): m.detector_offset = util._check_and_get_float_line_edit(self._summary.detector_offset_edit) # Sample-detector distance if self._summary.sample_dist_chk.isChecked(): m.sample_detector_distance = util._check_and_get_float_line_edit(self._summary.sample_dist_edit) # Solid angle correction m.solid_angle_corr = self._summary.solid_angle_chk.isChecked() # Dark current m.dark_current_corr = self._summary.dark_current_check.isChecked() m.dark_current_data = unicode(self._summary.dark_file_edit.text()) # Q range m.n_q_bins = util._check_and_get_int_line_edit(self._summary.n_q_bins_edit) m.log_binning = self._summary.log_binning_radio.isChecked() # TOF cuts m.use_config_cutoff = self._summary.tof_cut_chk.isChecked() m.low_TOF_cut = util._check_and_get_float_line_edit(self._summary.low_tof_edit) m.high_TOF_cut = util._check_and_get_float_line_edit(self._summary.high_tof_edit) # Config Mask m.use_config_mask = self._summary.config_mask_chk.isChecked() # Mask detector IDs m.use_mask_file = self._summary.mask_check.isChecked() m.mask_file = unicode(self._summary.mask_edit.text()) m.detector_ids = self._masked_detectors if AnalysisDataService.doesExist(self.mask_ws): ws, masked_detectors = ExtractMask(InputWorkspace=self.mask_ws, OutputWorkspace="__edited_mask") m.detector_ids = [int(i) for i in masked_detectors] # Resolution parameters m.compute_resolution = self._summary.resolution_chk.isChecked() m.sample_aperture_diameter = util._check_and_get_float_line_edit(self._summary.sample_apert_edit) m.perform_TOF_correction = self._summary.tof_correction_chk.isChecked() m.use_beam_monitor = self._summary.beam_monitor_chk.isChecked() m.beam_monitor_reference = unicode(self._summary.beam_monitor_edit.text()) # Output directory m.use_data_directory = self._summary.use_data_dir_radio.isChecked() m.output_directory = str(self._summary.output_dir_edit.text()) self._settings.data_output_dir = m.output_directory self._settings.emit_key_value("DARK_CURRENT", str(self._summary.dark_file_edit.text())) self._settings.emit_key_value("OUTPUT_DIR", m.output_directory) return m