def test_set_placeholder_text_raises_error_if_workspaces_have_no_common_spectra( self): spectra_1 = ExtractSpectra(InputWorkspace=self._multi_spec_ws, StartWorkspaceIndex=0, EndWorkspaceIndex=5) spectra_2 = ExtractSpectra(InputWorkspace=self._multi_spec_ws, StartWorkspaceIndex=6, EndWorkspaceIndex=10) workspaces = [spectra_1, spectra_2] self.assertRaises(Exception, 'Error: Workspaces have no common spectra.', SpectraSelectionDialog, workspaces)
def _extract_region(workspace: MatrixWorkspace, xmin: float, xmax: float, indexmin: int, indexmax: int, name: str, log_algorithm_calls: bool = True): """ Assuming a MatrixWorkspace crop a region with the given parameters :param workspace: A MatrixWorkspace with a vertical SpectraAxis :param xmin: X min for bounded region :param xmax: X max for bounded region :param ymin: Y min for bounded region :param ymax: Y max for bounded region :param name: A name for the workspace """ if not workspace.isCommonBins(): # rebin to a common grid using the resolution from the spectrum # with the lowest resolution to avoid overbinning workspace = _rebin_to_common_grid(workspace, None, None, log_algorithm_calls) return ExtractSpectra(InputWorkspace=workspace, OutputWorkspace=name, XMin=xmin, XMax=xmax, StartWorkspaceIndex=indexmin, EndWorkspaceIndex=indexmax, EnableLogging=log_algorithm_calls)
def test_get_spectra_selection_does_not_use_dialog_for_multiple__single_spectrum( self, dialog_mock): spectra_1 = ExtractSpectra(InputWorkspace=self._multi_spec_ws, StartWorkspaceIndex=0, EndWorkspaceIndex=0) spectra_2 = ExtractSpectra(InputWorkspace=self._multi_spec_ws, StartWorkspaceIndex=1, EndWorkspaceIndex=1) dialog_mock.get_compatible_workspaces.return_value = [ spectra_1, spectra_2 ] selection = get_spectra_selection([spectra_1, spectra_2]) dialog_mock.assert_not_called() self.assertEqual([0], selection.wksp_indices) self.assertEqual([spectra_1, spectra_2], selection.workspaces)
def runTest(self): ws_2d_tubes = self.d2b_2d_tubes_test() ws_2d = self.d2b_2d_test() ws_1d = self.d2b_1d_test() # Check loading and merging, and keeping files separate gives the same results ws_2d_merge = self.d2b_2d_tubes_test_using_merge() result_merge = CompareWorkspaces(Workspace1=ws_2d, Workspace2=ws_2d_merge) self.assertTrue(result_merge) # Check height range given is a subset of a full 2D option ws_2d_height = self.d2b_2d_height_test() ws_2d_cropped = ExtractSpectra(InputWorkspace=ws_2d[0], StartWorkspaceIndex=43, EndWorkspaceIndex=84) result_height = CompareWorkspaces(Workspace1=ws_2d_cropped, Workspace2=ws_2d_height) self.assertTrue(result_height) GroupWorkspaces([ws_2d_tubes[0], ws_2d[0], ws_1d[0]], OutputWorkspace='grouped_output')
def PyExec(self): raw_ws = self.getProperty('InputWorkspace').value sample_geometry = self.getPropertyValue('SampleGeometry') sample_material = self.getPropertyValue('SampleMaterial') cal_file_name = self.getPropertyValue('CalFileName') SetSample(InputWorkspace=raw_ws, Geometry=sample_geometry, Material=sample_material) # find the closest monitor to the sample for incident spectrum raw_spec_info = raw_ws.spectrumInfo() incident_index = None for i in range(raw_spec_info.size()): if raw_spec_info.isMonitor(i): l2 = raw_spec_info.position(i)[2] if not incident_index: incident_index = i else: if raw_spec_info.position(incident_index)[2] < l2 < 0: incident_index = i monitor = ExtractSpectra(InputWorkspace=raw_ws, WorkspaceIndexList=[incident_index]) monitor = ConvertUnits(InputWorkspace=monitor, Target="Wavelength") x_data = monitor.dataX(0) min_x = np.min(x_data) max_x = np.max(x_data) width_x = (max_x - min_x) / x_data.size fit_spectra = FitIncidentSpectrum( InputWorkspace=monitor, BinningForCalc=[min_x, 1 * width_x, max_x], BinningForFit=[min_x, 10 * width_x, max_x], FitSpectrumWith="CubicSpline") self_scattering_correction = CalculatePlaczekSelfScattering( InputWorkspace=raw_ws, IncidentSpecta=fit_spectra) cal_workspace = LoadCalFile(InputWorkspace=self_scattering_correction, CalFileName=cal_file_name, Workspacename='cal_workspace', MakeOffsetsWorkspace=False, MakeMaskWorkspace=False) self_scattering_correction = DiffractionFocussing( InputWorkspace=self_scattering_correction, GroupingFilename=cal_file_name) n_pixel = np.zeros(self_scattering_correction.getNumberHistograms()) for i in range(cal_workspace.getNumberHistograms()): grouping = cal_workspace.dataY(i) if grouping[0] > 0: n_pixel[int(grouping[0] - 1)] += 1 correction_ws = CreateWorkspace( DataY=n_pixel, DataX=[0, 1], NSpec=self_scattering_correction.getNumberHistograms()) self_scattering_correction = Divide( LHSWorkspace=self_scattering_correction, RHSWorkspace=correction_ws) ConvertToDistribution(Workspace=self_scattering_correction) self_scattering_correction = ConvertUnits( InputWorkspace=self_scattering_correction, Target="MomentumTransfer", EMode='Elastic') DeleteWorkspace('cal_workspace_group') DeleteWorkspace(correction_ws) DeleteWorkspace(fit_spectra) DeleteWorkspace(monitor) DeleteWorkspace(raw_ws) self.setProperty('OutputWorkspace', self_scattering_correction)
def cc_calibrate_groups(data_ws, group_ws, output_basename="_tmp_group_cc_calibration", previous_calibration=None, Step=0.001, DReference=1.2615, Xmin=1.22, Xmax=1.30, MaxDSpaceShift=None, OffsetThreshold=1E-4, SkipCrossCorrelation=[], PeakFunction="Gaussian", SmoothNPoints=0): """This will perform the CrossCorrelate/GetDetectorOffsets on a group of detector pixel. It works by looping over the different groups in the group_ws, extracting all unmasked spectra of a group, then running CrossCorrelate and GetDetectorOffsets on just that group, and combinning the results at the end. When running a group, CrossCorrelate and GetDetectorOffsets could be cycled until converging of offsets is reached, given the user input offset threshold. If offset threshold is specified to be equal to or larger than 1.0, no cycling will be carried out. The first unmasked spectra of the group will be used for the ReferenceSpectra in CrossCorrelate. :param data_ws: Input calibration raw data (in TOF), assumed to already be correctly masked :param group_ws: grouping workspace, e.g. output from LoadDetectorsGroupingFile :param output_basename: Optional name to use for temporay and output workspace :param previous_calibration: Optional previous diffcal workspace :param Step: step size for binning of data and input for GetDetectorOffsets, default 0.001 :param DReference: Derefernce parameter for GetDetectorOffsets, default 1.2615 :param Xmin: Xmin parameter for CrossCorrelate, default 1.22 :param Xmax: Xmax parameter for CrossCorrelate, default 1.30 :param MaxDSpaceShift: MaxDSpaceShift paramter for CrossCorrelate, default None :param OffsetThreshold: Convergence threshold for cycling cross correlation, default 1E-4 :param SkipCrossCorrelation: Skip cross correlation for specified groups :param PeakFunction: Peak function to use for extracting the offset :param SmoothNPoints: Number of points for smoothing spectra, for cross correlation ONLY :return: Combined DiffCal workspace from all the different groups """ if previous_calibration: ApplyDiffCal(data_ws, CalibrationWorkspace=previous_calibration) data_d = ConvertUnits(data_ws, Target='dSpacing', OutputWorkspace='data_d') group_list = np.unique(group_ws.extractY()) _accum_cc = None to_skip = [] for group in group_list: # Figure out input parameters for CrossCorrelate and GetDetectorOffset, specifically # for those parameters for which both a single value and a list is accepted. If a # list is given, that means different parameter setup will be used for different groups. Xmin_group = Xmin[int(group) - 1] if type(Xmin) == list else Xmin Xmax_group = Xmax[int(group) - 1] if type(Xmax) == list else Xmax MDS_group = MaxDSpaceShift[int(group) - 1] if type(MaxDSpaceShift) == list else MaxDSpaceShift DRef_group = DReference[int(group) - 1] if type(DReference) == list else DReference OT_group = OffsetThreshold[int(group) - 1] if type(OffsetThreshold) == list else OffsetThreshold pf_group = PeakFunction[int(group) - 1] if type(PeakFunction) == list else PeakFunction snpts_group = SmoothNPoints[int(group) - 1] if type(SmoothNPoints) == list else SmoothNPoints cycling = OT_group < 1.0 indexes = np.where(group_ws.extractY().flatten() == group)[0] sn = np.array(group_ws.getSpectrumNumbers())[indexes] try: ws_indexes = [data_d.getIndexFromSpectrumNumber(int(i)) for i in sn] except RuntimeError: # data does not contain spectrum in group continue if group in SkipCrossCorrelation: to_skip.extend(ws_indexes) ExtractSpectra(data_d, WorkspaceIndexList=ws_indexes, OutputWorkspace='_tmp_group_cc') ExtractUnmaskedSpectra('_tmp_group_cc', OutputWorkspace='_tmp_group_cc') ExtractSpectra(data_ws, WorkspaceIndexList=ws_indexes, OutputWorkspace='_tmp_group_cc_raw') ExtractUnmaskedSpectra('_tmp_group_cc_raw', OutputWorkspace='_tmp_group_cc_raw') num_spectra = mtd['_tmp_group_cc'].getNumberHistograms() if num_spectra < 2: continue Rebin('_tmp_group_cc', Params=f'{Xmin_group},{Step},{Xmax_group}', OutputWorkspace='_tmp_group_cc') if snpts_group >= 3: SmoothData('_tmp_group_cc', NPoints=snpts_group, OutputWorkspace='_tmp_group_cc') # Figure out brightest spectra to be used as the reference for cross correlation. CloneWorkspace('_tmp_group_cc_raw', OutputWorkspace='_tmp_group_cc_raw_tmp') intg = Integration('_tmp_group_cc_raw_tmp', StartWorkspaceIndex=0, EndWorkspaceIndex=num_spectra-1, OutputWorkspace='_tmp_group_intg') brightest_spec_index = int(np.argmax(np.array([intg.readY(i)[0] for i in range(num_spectra)]))) # Cycling cross correlation. At each step, we will use the obtained offsets and DIFC's from # previous step to obtain new DIFC's. In this way, spectra in group will come closer and closer # to each other as the cycle goes. This will continue until converging criterion is reached. The # converging criterion is set in such a way that the median value of all the non-zero offsets # should be smaller than the threshold (user tuned parameter, default to 1E-4, meaning 0.04% # relative offset). num_cycle = 1 while True: CrossCorrelate('_tmp_group_cc', Xmin=Xmin_group, XMax=Xmax_group, MaxDSpaceShift=MDS_group, ReferenceSpectra=brightest_spec_index, WorkspaceIndexMin=0, WorkspaceIndexMax=num_spectra-1, OutputWorkspace='_tmp_group_cc') bin_range = (Xmax_group-Xmin_group)/Step GetDetectorOffsets(InputWorkspace='_tmp_group_cc', Step=Step, Xmin=-bin_range, XMax=bin_range, DReference=DRef_group, MaxOffset=1, PeakFunction=pf_group, OutputWorkspace='_tmp_group_cc') if group not in SkipCrossCorrelation: offsets_tmp = [] for item in ws_indexes: if abs(mtd['_tmp_group_cc'].readY(item)) != 0: offsets_tmp.append(abs(mtd['_tmp_group_cc'].readY(item))) offsets_tmp = np.array(offsets_tmp) logger.notice(f'Running group-{group}, cycle-{num_cycle}.') logger.notice(f'Median offset (no sign) = {np.median(offsets_tmp)}') logger.notice(f'Running group-{group}, cycle-{num_cycle}.') logger.notice(f'Median offset (no sign) = {np.median(offsets_tmp)}') converged = np.median(offsets_tmp) < OT_group else: for item in ws_indexes: mtd['_tmp_group_cc'].dataY(item)[0] = 0.0 logger.notice(f'Cross correlation skipped for group-{group}.') converged = True if not cycling or converged: if cycling and converged: if group not in SkipCrossCorrelation: logger.notice(f'Cross correlation for group-{group} converged, ') logger.notice(f'with offset threshold {OT_group}.') break else: previous_calibration = ConvertDiffCal('_tmp_group_cc', PreviousCalibration=previous_calibration, OutputWorkspace='_tmp_group_cc_diffcal') ApplyDiffCal('_tmp_group_cc_raw', CalibrationWorkspace='_tmp_group_cc_diffcal') ConvertUnits('_tmp_group_cc_raw', Target='dSpacing', OutputWorkspace='_tmp_group_cc') Rebin('_tmp_group_cc', Params=f'{Xmin_group},{Step},{Xmax_group}', OutputWorkspace='_tmp_group_cc') num_cycle += 1 if not _accum_cc: _accum_cc = RenameWorkspace('_tmp_group_cc') else: _accum_cc += mtd['_tmp_group_cc'] # DeleteWorkspace('_tmp_group_cc') previous_calibration = ConvertDiffCal('_accum_cc', PreviousCalibration=previous_calibration, OutputWorkspace=f'{output_basename}_cc_diffcal') DeleteWorkspace('_accum_cc') DeleteWorkspace('_tmp_group_cc') DeleteWorkspace('_tmp_group_cc_raw') if cycling and '_tmp_group_cc_diffcal' in mtd: DeleteWorkspace('_tmp_group_cc_diffcal') return mtd[f'{output_basename}_cc_diffcal'], to_skip
def pdcalibration_groups(data_ws, group_ws, cc_diffcal, to_skip, output_basename="_tmp_group_pd_calibration", previous_calibration=None, PeakPositions=DIAMOND, TofBinning=(300,-.001,16666.7), PeakFunction='IkedaCarpenterPV', PeakWindow=0.1, PeakWidthPercent=None, BadCalibThreshold=100): """This will perform PDCalibration of the group data and combine the results with the results of `cc_calibrate_groups`. This works by converting the data into d-spacing using the diffcal from the cross-correlation, then grouping the data using DiffractionFocussing after which it's converted back into TOF using an arbitarty diffcal (the combined of all detectors in the group). PDCalibration is performed on this grouped workspace after which the diffcal's are all combined according to .. math:: DIFC_{effective} = DIFC_{PD} * DIFC_{CC} / DIFC_{arbitarty} :param data_ws: Input calibration raw data (in TOF), assumed to already be correctly masked :param group_ws: grouping workspace, e.g. output from LoadDetectorsGroupingFile :param cc_diffcal: DiffCal workspace which is the output from cc_calibrate_groups :param to_skip: Groups to skip the cross correlation stage :param output_basename: Optional name to use for temporay and output workspace :param previous_calibration: Optional previous diffcal workspace :param PeakPositions: PeakPositions parameter of PDCalibration, default Diamond peaks :param TofBinning: TofBinning parameter of PDCalibration, default (300,-.001,16666.7) :param PeakFunction: PeakFunction parameter of PDCalibration, default 'IkedaCarpenterPV' :param PeakWindow: PeakWindow parameter of PDCalibration, default 0.1 :param PeakWidthPercent: PeakWidthPercent parameter of PDCalibration, default None :param BadCalibThreshold: Threshold for relative difference between calibrated DIFC and engineering value. :return: tuple of DiffCal and Mask (both as TableWorkspace objects) holding the combined DiffCal. """ CreateDetectorTable(data_ws, DetectorTableWorkspace="calib_table_bak") ApplyDiffCal(data_ws, CalibrationWorkspace=cc_diffcal) ConvertUnits(data_ws, Target='dSpacing', OutputWorkspace='_tmp_data_aligned') DiffractionFocussing('_tmp_data_aligned', GroupingWorkspace=group_ws, OutputWorkspace='_tmp_data_aligned') ConvertUnits('_tmp_data_aligned', Target='TOF', OutputWorkspace='_tmp_data_aligned') instrument = data_ws.getInstrument().getName() if instrument != 'POWGEN': PDCalibration(InputWorkspace='_tmp_data_aligned', TofBinning=TofBinning, PreviousCalibrationTable=previous_calibration, PeakFunction=PeakFunction, PeakPositions=PeakPositions, PeakWindow=PeakWindow, PeakWidthPercent=PeakWidthPercent, OutputCalibrationTable=f'{output_basename}_pd_diffcal', DiagnosticWorkspaces=f'{output_basename}_pd_diag') if to_skip: ExtractSpectra(data_ws, WorkspaceIndexList=to_skip, OutputWorkspace='_tmp_group_to_skip') ExtractUnmaskedSpectra('_tmp_group_to_skip', OutputWorkspace='_tmp_group_to_skip') PDCalibration(InputWorkspace='_tmp_group_to_skip', TofBinning=TofBinning, PreviousCalibrationTable=previous_calibration, PeakFunction=PeakFunction, PeakPositions=PeakPositions, PeakWindow=PeakWindow, PeakWidthPercent=PeakWidthPercent, OutputCalibrationTable=f'{output_basename}_pd_diffcal_skip', DiagnosticWorkspaces=f'{output_basename}_pd_diag_skip') else: pdcalib_for_powgen(mtd['_tmp_data_aligned'], TofBinning, previous_calibration, PeakFunction, PeakPositions, PeakWindow, PeakWidthPercent, f'{output_basename}_pd_diffcal', f'{output_basename}_pd_diag') if to_skip: ExtractSpectra(data_ws, WorkspaceIndexList=to_skip, OutputWorkspace='_tmp_group_to_skip') ExtractUnmaskedSpectra('_tmp_group_to_skip', OutputWorkspace='_tmp_group_to_skip') pdcalib_for_powgen(mtd['_tmp_group_to_skip'], [300,-0.0008,16667], previous_calibration, PeakFunction, PeakPositions, PeakWindow, PeakWidthPercent, f'{output_basename}_pd_diffcal_skip', f'{output_basename}_pd_diag_skip') CombineDiffCal(PixelCalibration=cc_diffcal, GroupedCalibration=f'{output_basename}_pd_diffcal', CalibrationWorkspace='_tmp_data_aligned', MaskWorkspace=f'{output_basename}_pd_diffcal_mask', OutputWorkspace=f'{output_basename}_cc_pd_diffcal_tmp') DeleteWorkspace('_tmp_data_aligned') out_table = CreateEmptyTableWorkspace(OutputWorkspace=f'{output_basename}_cc_pd_diffcal') out_table.addColumn("int", "detid") out_table.addColumn("double", "difc") out_table.addColumn("double", "difa") out_table.addColumn("double", "tzero") num_hist = data_ws.getNumberHistograms() for i in range(num_hist): difc_bak = mtd['calib_table_bak'].row(i)['DIFC'] if i in to_skip: difc_calib = mtd[f'{output_basename}_pd_diffcal_skip'].row(i)['difc'] else: difc_calib = mtd[f'{output_basename}_cc_pd_diffcal_tmp'].row(i)['difc'] if mtd[f'{output_basename}_pd_diffcal_mask'].readY(i)[0] == 0.0: diff_difc = abs(difc_bak - difc_calib) / difc_calib * 100.0 else: diff_difc = np.inf if diff_difc >= BadCalibThreshold: difc_calib = difc_bak new_row = { 'detid': mtd[f'{output_basename}_cc_pd_diffcal_tmp'].row(i)['detid'], 'difc': difc_calib, 'difa': mtd[f'{output_basename}_cc_pd_diffcal_tmp'].row(i)['difa'], 'tzero': mtd[f'{output_basename}_cc_pd_diffcal_tmp'].row(i)['tzero'] } out_table.addRow(new_row) DeleteWorkspace(f'{output_basename}_cc_pd_diffcal_tmp') return mtd[f'{output_basename}_cc_pd_diffcal']
def _extract_spectra(workspace, indices): return ExtractSpectra(InputWorkspace=workspace, WorkspaceIndexList=indices, OutputWorkspace="__extracted", StoreInADS=False, EnableLogging=False)
def PyExec(self): inputWS = self.getProperty("InputWorkspace").value outputWS = self.getProperty("OutputWorkspace").valueAsStr xmins = self.getProperty("XMin").value xmaxs = self.getProperty("XMax").value deltas = self.getProperty("Delta").value preserveEvents = self.getProperty("PreserveEvents").value if self.__use_simple_rebin(xmins, xmaxs, deltas): # plain old rebin should have been used name = "__{}_rebinned_".format(outputWS) params = (xmins[0], deltas[0], xmaxs[0]) Rebin(InputWorkspace=inputWS, OutputWorkspace=name, Params=params, PreserveEvents=preserveEvents) self.setProperty("OutputWorkspace", mtd[name]) DeleteWorkspace(name) else: numSpec = inputWS.getNumberHistograms() # fill out the values for min and max as appropriate xmins = self.__extend_value(numSpec, xmins, replaceNan=True) xmaxs = self.__extend_value(numSpec, xmaxs, replaceNan=True) deltas = self.__extend_value(numSpec, deltas, replaceNan=False) self.log().debug("MIN: " + str(xmins)) self.log().debug("DELTA:" + str(deltas)) self.log().debug("MAX: " + str(xmaxs)) # temporary workspaces should be hidden names = [ "__{}_spec_{}".format(outputWS, i) for i in range(len(xmins)) ] # how much the progress bar moves forward for each spectrum progStep = float(1) / float(3 * numSpec) # crop out each spectra and conjoin to a temporary workspace accumulationWS = None for i, (name, xmin, xmax, delta) in enumerate(zip(names, xmins, xmaxs, deltas)): # don't go beyond the range of the data x = inputWS.readX(i) if xmin == Property.EMPTY_DBL: xmin = x[0] if xmax == Property.EMPTY_DBL: xmax = x[-1] progStart = 3 * i * progStep try: # extract the range of the spectrum requested ExtractSpectra(InputWorkspace=inputWS, OutputWorkspace=name, StartWorkspaceIndex=i, EndWorkspaceIndex=i, XMin=xmin, XMax=xmax, startProgress=progStart, endProgress=(progStart + progStep), EnableLogging=False) # rebin the data Rebin(InputWorkspace=name, OutputWorkspace=name, Params=(xmin, delta, xmax), PreserveEvents=preserveEvents, startProgress=progStart, endProgress=(progStart + progStep), EnableLogging=False) except Exception as e: raise RuntimeError('for index={}: {}'.format(i, e)) from e # accumulate if accumulationWS is None: accumulationWS = name # messes up progress during very first step else: # this deletes both input workspaces ConjoinWorkspaces(InputWorkspace1=accumulationWS, InputWorkspace2=name, startProgress=(progStart + 2 * progStep), endProgress=(progStart + 3 * progStep), EnableLogging=False) self.setProperty("OutputWorkspace", mtd[accumulationWS]) DeleteWorkspace(accumulationWS, EnableLogging=False)
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): raw_ws = self.getProperty('InputWorkspace').value sample_geometry = self.getPropertyValue('SampleGeometry') sample_material = self.getPropertyValue('SampleMaterial') cal_file_name = self.getPropertyValue('CalFileName') SetSample(InputWorkspace=raw_ws, Geometry=sample_geometry, Material=sample_material) # find the closest monitor to the sample for incident spectrum raw_spec_info = raw_ws.spectrumInfo() incident_index = None for i in range(raw_spec_info.size()): if raw_spec_info.isMonitor(i): l2 = raw_spec_info.position(i)[2] if not incident_index: incident_index = i else: if raw_spec_info.position(incident_index)[2] < l2 < 0: incident_index = i monitor = ExtractSpectra(InputWorkspace=raw_ws, WorkspaceIndexList=[incident_index]) monitor = ConvertUnits(InputWorkspace=monitor, Target="Wavelength") x_data = monitor.dataX(0) min_x = np.min(x_data) max_x = np.max(x_data) width_x = (max_x - min_x) / x_data.size fit_spectra = FitIncidentSpectrum(InputWorkspace=monitor, BinningForCalc=[min_x, 1 * width_x, max_x], BinningForFit=[min_x, 10 * width_x, max_x], FitSpectrumWith="CubicSpline") self_scattering_correction = CalculatePlaczekSelfScattering(InputWorkspace=raw_ws, IncidentSpectra=fit_spectra, ScaleByPackingFraction=False, Version=1) # Convert to Q self_scattering_correction = ConvertUnits(InputWorkspace=self_scattering_correction, Target="MomentumTransfer", EMode='Elastic') cal_workspace = LoadCalFile(InputWorkspace=self_scattering_correction, CalFileName=cal_file_name, Workspacename='cal_workspace', MakeOffsetsWorkspace=False, MakeMaskWorkspace=False, MakeGroupingWorkspace=True) ssc_min_x, ssc_max_x = float('inf'), float('-inf') for index in range(self_scattering_correction.getNumberHistograms()): spec_info = self_scattering_correction.spectrumInfo() if not spec_info.isMasked(index) and not spec_info.isMonitor(index): ssc_x_data = np.ma.masked_invalid(self_scattering_correction.dataX(index)) if np.min(ssc_x_data) < ssc_min_x: ssc_min_x = np.min(ssc_x_data) if np.max(ssc_x_data) > ssc_max_x: ssc_max_x = np.max(ssc_x_data) ssc_width_x = (ssc_max_x - ssc_min_x) / ssc_x_data.size # TO DO: calculate rebin parameters per group # and run GroupDetectors on each separately self_scattering_correction = Rebin(InputWorkspace=self_scattering_correction, Params=[ssc_min_x, ssc_width_x, ssc_max_x], IgnoreBinErrors=True) self_scattering_correction = GroupDetectors(InputWorkspace=self_scattering_correction, CopyGroupingFromWorkspace='cal_workspace_group') n_pixel = np.zeros(self_scattering_correction.getNumberHistograms()) for i in range(cal_workspace.getNumberHistograms()): grouping = cal_workspace.dataY(i) if grouping[0] > 0: n_pixel[int(grouping[0] - 1)] += 1 correction_ws = CreateWorkspace(DataY=n_pixel, DataX=[0, 1], NSpec=self_scattering_correction.getNumberHistograms()) self_scattering_correction = Divide(LHSWorkspace=self_scattering_correction, RHSWorkspace=correction_ws) DeleteWorkspace('cal_workspace_group') DeleteWorkspace(correction_ws) DeleteWorkspace(fit_spectra) DeleteWorkspace(monitor) DeleteWorkspace(raw_ws) self.setProperty('OutputWorkspace', self_scattering_correction)
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)