def _fit_results_to_dict(self, ws): """ Turn a workspace with one or more fitting results (3 spectra per curve fitted), that comes with all the spectra appended, into a dictionary of individual fitting results. @param ws workspace with fitting results (3 spectra per curve fitted) as provided by Fit for all banks. @returns dictionary with every individual fitting result (3 spectra) """ curves = {} if 0 != (ws.getNumberHistograms() % 3): raise RuntimeError("A workspace without instrument definition has been passed, so it is " "expected to have fitting results, but it does not have a number of " "histograms multiple of 3. Number of hsitograms found: %d" % ws.getNumberHistograms()) for wi in range(0, int(ws.getNumberHistograms()/3)): indiv = EnggUtils.crop_data(self, ws, [wi, wi+2]) # the bank id is +1 because wi starts from 0 bankid = wi + 1 curves.update({bankid: indiv}) return curves
def _fit_results_to_dict(self, ws): """ Turn a workspace with one or more fitting results (3 spectra per curve fitted), that comes with all the spectra appended, into a dictionary of individual fitting results. @param ws workspace with fitting results (3 spectra per curve fitted) as provided by Fit for all banks. @returns dictionary with every individual fitting result (3 spectra) """ curves = {} if 0 != (ws.getNumberHistograms() % 3): raise RuntimeError( "A workspace without instrument definition has been passed, so it is " "expected to have fitting results, but it does not have a number of " "histograms multiple of 3. Number of hsitograms found: %d" % ws.getNumberHistograms()) for wi in range(0, int(ws.getNumberHistograms() / 3)): indiv = EnggUtils.crop_data(self, ws, [wi, wi + 2]) # the bank id is +1 because wi starts from 0 bankid = wi + 1 curves.update({bankid: indiv}) return curves
def PyExec(self): # Get the run workspace input_ws = self.getProperty('InputWorkspace').value # Get spectra indices either from bank or direct list of indices, checking for errors bank = self.getProperty('Bank').value spectra = self.getProperty(self.INDICES_PROP_NAME).value indices = EnggUtils.get_ws_indices_from_input_properties(input_ws, bank, spectra) detector_positions = self.getProperty("DetectorPositions").value n_reports = 8 prog = Progress(self, start=0, end=1, nreports=n_reports) # Leave only the data for the bank/spectra list requested prog.report('Selecting spectra from input workspace') input_ws = EnggUtils.crop_data(self, input_ws, indices) prog.report('Masking some bins if requested') self._mask_bins(input_ws, self.getProperty('MaskBinsXMins').value, self.getProperty('MaskBinsXMaxs').value) prog.report('Applying vanadium corrections') # Leave data for the same bank in the vanadium workspace too vanadium_ws = self.getProperty('VanadiumWorkspace').value van_integration_ws = self.getProperty('VanIntegrationWorkspace').value van_curves_ws = self.getProperty('VanCurvesWorkspace').value EnggUtils.apply_vanadium_corrections(parent=self, ws=input_ws, indices=indices, vanadium_ws=vanadium_ws, van_integration_ws=van_integration_ws, van_curves_ws=van_curves_ws, progress_range=(0.65, 0.8)) prog.report("Applying calibration if requested") # Apply calibration if detector_positions: self._apply_calibration(input_ws, detector_positions) # Convert to dSpacing prog.report("Converting to d") input_ws = EnggUtils.convert_to_d_spacing(self, input_ws) prog.report('Summing spectra') # Sum the values across spectra input_ws = EnggUtils.sum_spectra(self, input_ws) prog.report('Preparing output workspace') # Convert back to time of flight input_ws = EnggUtils.convert_to_TOF(self, input_ws) prog.report('Normalizing input workspace if needed') if self.getProperty('NormaliseByCurrent').value: self._normalize_by_current(input_ws) # OpenGenie displays distributions instead of pure counts (this is done implicitly when # converting units), so I guess that's what users will expect self._convert_to_distribution(input_ws) if bank: self._add_bank_number(input_ws, bank) self.setProperty("OutputWorkspace", input_ws)
def PyExec(self): # Get the run workspace input_ws = self.getProperty('InputWorkspace').value # Get spectra indices either from bank or direct list of indices, checking for errors bank = self.getProperty('Bank').value spectra = self.getProperty(self.INDICES_PROP_NAME).value indices = EnggUtils.get_ws_indices_from_input_properties(input_ws, bank, spectra) detector_positions = self.getProperty("DetectorPositions").value n_reports = 8 prog = Progress(self, start=0, end=1, nreports=n_reports) # Leave only the data for the bank/spectra list requested prog.report('Selecting spectra from input workspace') input_ws = EnggUtils.crop_data(self, input_ws, indices) prog.report('Masking some bins if requested') self._mask_bins(input_ws, self.getProperty('MaskBinsXMins').value, self.getProperty('MaskBinsXMaxs').value) prog.report('Applying vanadium corrections') # Leave data for the same bank in the vanadium workspace too vanadium_ws = self.getProperty('VanadiumWorkspace').value van_integration_ws = self.getProperty('VanIntegrationWorkspace').value van_curves_ws = self.getProperty('VanCurvesWorkspace').value EnggUtils.apply_vanadium_corrections(parent=self, ws=input_ws, indices=indices, vanadium_ws=vanadium_ws, van_integration_ws=van_integration_ws, van_curves_ws=van_curves_ws, progress_range=(0.65, 0.8)) prog.report("Applying calibration if requested") # Apply calibration if detector_positions: self._apply_calibration(input_ws, detector_positions) # Convert to dSpacing prog.report("Converting to d") input_ws = EnggUtils.convert_to_d_spacing(self, input_ws) prog.report('Summing spectra') # Sum the values across spectra input_ws = EnggUtils.sum_spectra(self, input_ws) prog.report('Preparing output workspace') # Convert back to time of flight input_ws = EnggUtils.convert_to_TOF(self, input_ws) prog.report('Normalizing input workspace if needed') if self.getProperty('NormaliseByCurrent').value: self._normalize_by_current(input_ws) # OpenGenie displays distributions instead of pure counts (this is done implicitly when # converting units), so I guess that's what users will expect self._convert_to_distribution(input_ws) self._add_bank_number(input_ws, bank) self.setProperty("OutputWorkspace", input_ws)
def _fit_curves_per_bank(self, vanadium_ws, banks, spline_breaks, prog): """ Fits one curve to every bank (where for every bank the data fitted is the result of summing up all the spectra of the bank). The fitting is done in d-spacing. @param vanadium_ws :: Vanadium run workspace to fit, expected in TOF units as they are archived @param banks :: list of banks to consider which is normally all the banks of the instrument @param spline_breaks :: number of break points when fitting spline functions @param prog :: progress reporter @returns a workspace with fitting results for all banks (3 spectra per bank). The spectra are in dSpacing units. """ curves = {} for bank_number, bank in enumerate(banks): prog.report("Fitting bank {} of {}".format(bank_number + 1, len(banks))) indices = EnggUtils.get_ws_indices_for_bank(vanadium_ws, bank) if not indices: # no indices at all for this bank, not interested in it, don't add it to the dictionary # (as when doing Calibrate (not-full)) which does CropData() the original workspace continue prog.report("Cropping") ws_to_fit = EnggUtils.crop_data(self, vanadium_ws, indices) prog.report("Converting to d-spacing") ws_to_fit = EnggUtils.convert_to_d_spacing(self, ws_to_fit) prog.report("Summing spectra") ws_to_fit = EnggUtils.sum_spectra(self, ws_to_fit) prog.report("Fitting bank {} to curve".format(bank_number)) fit_ws = self._fit_bank_curve(ws_to_fit, bank, spline_breaks, prog) curves.update({bank: fit_ws}) curves_ws = self._prepare_curves_ws(curves) return curves_ws