def fit_peaks(self, rx, his_id=None): """Fit gaussian peaks to current plot. Returns list of lists: [E, x0, dx, A, dA, s, Area] where E is name of the peak, x0, A and s are fitted parameters and d'something' is its uncertainity. Area is total calculated area. """ peaks = [] for p in self.peaks: if rx[0] <= p.get('E') <= rx[1]: peaks.append(p) PF = PeakFitter(peaks, 'linear', '') if his_id is not None: data = self.hisfile.load_histogram(his_id) if data[0] != 1: print('{} is not a 1D histogram'.format(his_id)) return None x_axis = data[1][rx[0]:rx[1]] data_y = data[3][rx[0]:rx[1]] else: x_axis = self.current['x'][rx[0]:rx[1]] data_y = self.current['y'][rx[0]:rx[1]] data_dy = numpy.zeros(len(data_y)) for iy, y in enumerate(data_y): if y > 0: data_dy[iy] = math.sqrt(y) else: data_dy[iy] = 1 PF.fit(x_axis, data_y, data_dy) print('#{:^7} {:^8} {:^8} {:^8} {:^8} {:^8} {:^8}'.format( 'Peak', 'x0', 'dx', 'A', 'dA', 's', 'Area')) peak_data = [] for i, peak in enumerate(peaks): if peak.get('ignore') == 'True': continue x0 = PF.params['x{}'.format(i)].value dx = PF.params['x{}'.format(i)].stderr A = PF.params['A{}'.format(i)].value dA = PF.params['A{}'.format(i)].stderr s = PF.params['s{}'.format(i)].value Area = PF.find_area(x_axis, i) print( '{:>8} {:>8.2f} {:>8.2f} {:>8.1f} {:>8.1f} {:>8.3f} {:>8.1f}'. format(peaks[i].get('E'), x0, dx, A, dA, s, Area)) peak_data.append([peaks[i].get('E'), x0, dx, A, dA, s, Area]) return peak_data
def fit_peaks(self, rx, his_id=None): """Fit gaussian peaks to current plot. Returns list of lists: [E, x0, dx, A, dA, s, Area] where E is name of the peak, x0, A and s are fitted parameters and d'something' is its uncertainity. Area is total calculated area. """ peaks = [] for p in self.peaks: if rx[0] <= p.get('E') <= rx[1]: peaks.append(p) PF = PeakFitter(peaks, 'linear', '') if his_id is not None: data = self.hisfile.load_histogram(his_id) if data[0] != 1: print('{} is not a 1D histogram'.format(his_id)) return None x_axis = data[1][rx[0]:rx[1]] data_y = data[3][rx[0]:rx[1]] else: x_axis = self.current['x'][rx[0]:rx[1]] data_y = self.current['y'][rx[0]:rx[1]] data_dy = numpy.zeros(len(data_y)) for iy, y in enumerate(data_y): if y > 0: data_dy[iy] = math.sqrt(y) else: data_dy[iy] = 1 PF.fit(x_axis, data_y, data_dy) print('#{:^7} {:^8} {:^8} {:^8} {:^8} {:^8} {:^8}' .format('Peak', 'x0', 'dx', 'A', 'dA', 's', 'Area')) peak_data = [] for i, peak in enumerate(peaks): if peak.get('ignore') == 'True': continue x0 = PF.params['x{}'.format(i)].value dx = PF.params['x{}'.format(i)].stderr A = PF.params['A{}'.format(i)].value dA = PF.params['A{}'.format(i)].stderr s = PF.params['s{}'.format(i)].value Area = PF.find_area(x_axis, i) print('{:>8} {:>8.2f} {:>8.2f} {:>8.1f} {:>8.1f} {:>8.3f} {:>8.1f}' .format(peaks[i].get('E'), x0, dx, A, dA, s, Area)) peak_data.append([peaks[i].get('E'), x0, dx, A, dA, s, Area]) return peak_data
def fit_peaks(self, his=None, rx=None, clear=True): """ Fit gaussian peaks to 1D plot. If his is not given the current plot is used. If rx is not given, the current range is used Returns list of lists: [E, x0, dx, A, dA, s, Area] where E is name of the peak, x0, A and s are fitted parameters and d'something' is its uncertainity. Area is total calculated area. """ if rx is None: rx = Experiment.xlim if len(rx) != 2: print('Please use x range in format rx=(min, max), where', 'min and max are integers.') return None # Deactivate all the plots for p in Experiment.plots: if p.active: p.active = False peaks = [] for p in self.peaks: if rx[0] <= p.get('E') <= rx[1]: peaks.append(p) PF = PeakFitter(peaks, 'linear', '') if his is not None: if hasattr(his,'histogram'): x_axis = his.histogram.x_axis weights = his.histogram.weights title = his.histogram.title if isinstance(his, int): if his > 0: data = self.hisfile.load_histogram(his) if data[0] != 1: print('{} is not a 1D histogram'.format(his)) return None x_axis = data[1] weights = data[3] title = self.hisfile.histograms[his]['title'].strip() title = '{}:{}'.format(his, self._replace_latex_chars(title)) else: try: x_axis = Experiment.plots[his].histogram.x_axis weights = Experiment.plots[his].histogram.weights title = Experiment.plots[his].histogram.title except IndexError: x_axis=0 weights=0 title='Err' print('There is no plot in the registry under the', 'number', his, 'use show_registry() to see', 'available plots') return None else: x_axis = Experiment.plots[-1].histogram.x_axis weights = Experiment.plots[-1].histogram.weights title = Experiment.plots[-1].histogram.title dweights = self._standard_errors_array(weights) if clear: self.clear() histo_data = histogram.Histogram() histo_data.x_axis = x_axis histo_data.weights = weights histo_data.errors = dweights histo_data.title = title plot_data = Plot(histo_data, 'histogram', True) # The histogram data is plotted here so the fit function # may be overlaid on in. However, the plot_data is appended # to the registry after the fit functions so it is on top of the # registry. self.plotter.plot1d(plot_data, xlim=rx) fit_result = PF.fit(x_axis[rx[0]:rx[1]], weights[rx[0]:rx[1]], dweights[rx[0]:rx[1]]) histo_baseline = histogram.Histogram() histo_baseline.x_axis = x_axis[rx[0]:rx[1]] histo_baseline.weights = fit_result['baseline'] histo_baseline.title = 'Baseline' plot_baseline = Plot(histo_baseline, 'function', True) self.plotter.plot1d(plot_baseline, xlim=rx) histo_peaks = histogram.Histogram() histo_peaks.x_axis = fit_result['x_axis'] histo_peaks.weights = fit_result['fit'] histo_peaks.title = 'Fit' plot_peaks = Plot(histo_peaks, 'function', True) # Append all the plots to the registry, but # keep original data at the end, so the next fit_peaks() # call will use then again as default Experiment.plots.append(plot_baseline) Experiment.plots.append(plot_peaks) Experiment.plots.append(plot_data) # Plot the last one with the auto_scale if needed if Experiment.ylim is None: ylim = self._auto_scale_y() else: ylim = Experiment.ylim self.plotter.plot1d(plot_peaks, xlim=rx, ylim=ylim) print('#{:^8} {:^8} {:^8} {:^8} {:^8} {:^8} {:^8}' .format('Peak', 'x0', 'dx', 'A', 'dA', 's', 'Area')) peak_data = [] for i, peak in enumerate(peaks): if peak.get('ignore') == 'True': continue x0 = PF.params['x{}'.format(i)].value dx = PF.params['x{}'.format(i)].stderr A = PF.params['A{}'.format(i)].value dA = PF.params['A{}'.format(i)].stderr s = PF.params['s{}'.format(i)].value Area = PF.find_area(x_axis, i) print('{:>8} {:>8.2f} {:>8.2f} {:>8.1f} {:>8.1f} {:>8.3f} {:>8.1f}' .format(peaks[i].get('E'), x0, dx, A, dA, s, Area)) peak_data.append([peaks[i].get('E'), x0, dx, A, dA, s, Area]) return peak_data
def parse(self, spectrum, show, pause): spectra_ids = spectrum.get('id') id_list = [] if self.file_type == 'his': for element in spectra_ids.split(','): element = element.split('-') if len(element) > 1: new_elements = [] for i in range(int(element[0]), int(element[1]) + 1): id_list.append(i) else: id_list.append(int(element[0])) elif self.file_type == 'txt': if spectra_ids != '': raise GeneralError('Spectrum id not supported for txt files') else: id_list.append('') peaks = spectrum.findall('peak') x_min = int(spectrum.get('min')) x_max = int(spectrum.get('max')) smin = spectrum.get('smin') smax = spectrum.get('smax') for spectrum_id in id_list: plot_name = '{}_{}'.format(self.base_name, spectrum_id) PF = PeakFitter(peaks, spectrum.get('baseline'), plot_name) if self.file_type == 'txt': data_x = self.data_file[x_min:x_max, 0] data_y = self.data_file[x_min:x_max, 1] if self.data_file.shape[1] == 2: data_dy = [] for y in data_y: dy = numpy.sqrt(y) if y > 0 else 1.0 data_dy.append(dy) data_dy = numpy.array(data_dy) else: data_dy = self.data_file[x_min:x_max, 2] for iy, y in enumerate(data_dy): if y <= 0: data_dy[iy] = 1.0 elif self.file_type == 'his': data = self.data_file.load_histogram(spectrum_id) if data[0] != 1: raise GeneralError('Only 1D histograms are supported') data_x = data[1][x_min:x_max] data_y = data[3][x_min:x_max] data_dy = [] for y in data_y: dy = numpy.sqrt(y) if y > 0 else 1.0 data_dy.append(dy) data_dy = numpy.array(data_dy) if smin is not None and smax is not None: width = [float(smin), float(smax)] else: width = None fit_result = PF.fit(data_x, data_y, data_dy, width=width) if show == 'plot' or show == 'svg': plt.clf() plt.xlabel('Channel') plt.ylabel('Counts') plt.plot(data_x, data_y, linestyle='steps-mid') plt.plot(data_x, fit_result['baseline'], linestyle='--') plt.plot(fit_result['x_axis'], fit_result['fit'], linewidth=1.0) if show == 'svg': svg_name = 'fit_{0}_{1}_{2}'.format(plot_name, int(data_x[0]), int(data_x[-1])) svg_name = svg_name.replace('.', '').\ replace('/', '') + '.svg' plt.savefig(svg_name) else: plt.show() plt.draw() time.sleep(pause) elif show == 'quiet': pass for i, peak in enumerate(peaks): if peak.get('ignore') == 'True': continue x0 = PF.params['x{}'.format(i)].value dx = PF.params['x{}'.format(i)].stderr A = PF.params['A{}'.format(i)].value dA = PF.params['A{}'.format(i)].stderr s = PF.params['s{}'.format(i)].value E = peaks[i].get('E') name = peaks[i].get('name') if name is None: name = "" Area = PF.find_area(data_x, i) print('{:>8} {:>8} {:>8.2f} {:>8.2f}'.\ format(name, E, x0, dx), '{:>8.1f} {:>8.1f} {:>8.3f} {:>8.1f}'.\ format(A, dA, s, Area))
def parse(self, spectrum, show, pause): spectra_ids = spectrum.get('id') id_list = [] if self.file_type == 'his': for element in spectra_ids.split(','): element = element.split('-') if len(element) > 1: new_elements = [] for i in range(int(element[0]), int(element[1]) + 1): id_list.append(i) else: id_list.append(int(element[0])) elif self.file_type == 'txt': if spectra_ids != '': raise GeneralError('Spectrum id not supported for txt files') else: id_list.append('') peaks = spectrum.findall('peak') x_min = int(spectrum.get('min')) x_max = int(spectrum.get('max')) smin = spectrum.get('smin') smax = spectrum.get('smax') for spectrum_id in id_list: plot_name = '{}_{}'.format(self.base_name, spectrum_id) PF = PeakFitter(peaks, spectrum.get('baseline'), plot_name) if self.file_type == 'txt': data_x = self.data_file[x_min:x_max, 0] data_y = self.data_file[x_min:x_max, 1] data_dy = self.data_file[x_min:x_max, 2] for iy, y in enumerate(data_dy): if y <= 0: data_dy[iy] = 1.0 elif self.file_type == 'his': data = self.data_file.load_histogram(spectrum_id) if data[0] != 1: raise GeneralError('Only 1D histograms are supported') data_x = data[1][x_min:x_max] data_y = data[3][x_min:x_max] data_dy = [] for y in data_y: dy = numpy.sqrt(y) if y > 0 else 1.0 data_dy.append(dy) data_dy = numpy.array(data_dy) if smin is not None and smax is not None: PF.restrict_width(float(smin), float(smax)) fit_result = PF.fit(data_x, data_y, data_dy, show, pause) if show == 'plot' or show == 'svg': plt.clf() plt.xlabel('Channel') plt.ylabel('Counts') plt.plot(data_x, data_y, linestyle='steps-mid') plt.plot(data_x, fit_result['baseline'], linestyle='--') plt.plot(fit_result['x_axis'], fit_result['fit'], linewidth=1.0) if show == 'svg': svg_name = 'fit_{0}_{1}-{2}'.format( self.plot_name, int(data_x[0]), int(data_x[-1])) svg_name = svg_name.replace('.', '').\ replace('/', '') + '.svg' plt.savefig(svg_name) else: plt.draw() time.sleep(pause) elif show == 'quiet': pass for i, peak in enumerate(peaks): if peak.get('ignore') == 'True': continue x0 = PF.params['x{}'.format(i)].value dx = PF.params['x{}'.format(i)].stderr A = PF.params['A{}'.format(i)].value dA = PF.params['A{}'.format(i)].stderr s = PF.params['s{}'.format(i)].value E = peaks[i].get('E') name = peaks[i].get('name') Area = PF.find_area(data_x, i) print('{:>8} {:>8} {:>8.2f} {:>8.2f}'.\ format(name, E, x0, dx), '{:>8.1f} {:>8.1f} {:>8.3f} {:>8.1f}'.\ format(A, dA, s, Area))
def fit_peaks(self, his=None, rx=None, clear=True): """ Fit gaussian peaks to 1D plot. If his is not given the current plot is used. If rx is not given, the current range is used Returns list of lists: [E, x0, dx, A, dA, s, Area] where E is name of the peak, x0, A and s are fitted parameters and d'something' is its uncertainity. Area is total calculated area. """ if rx is None: rx = Experiment.xlim if len(rx) != 2: print('Please use x range in format rx=(min, max), where', 'min and max are integers.') return None # Deactivate all the plots for p in Experiment.plots: if p.active: p.active = False peaks = [] for p in self.peaks: if rx[0] <= p.get('E') <= rx[1]: peaks.append(p) PF = PeakFitter(peaks, 'linear', '') if his is not None: if isinstance(his, int): if his > 0: data = self.hisfile.load_histogram(his) if data[0] != 1: print('{} is not a 1D histogram'.format(his)) return None x_axis = data[1] weights = data[3] title = self.hisfile.histograms[his]['title'].strip() title = '{}:{}'.format(his, self._replace_latex_chars(title)) else: try: x_axis = Experiment.plots[his].histogram.x_axis weights = Experiment.plots[his].histogram.weights title = Experiment.plots[his].histogram.title except IndexError: print('There is no plot in the registry under the', 'number', his, 'use show_registry() to see', 'available plots') return None else: x_axis = Experiment.plots[-1].histogram.x_axis weights = Experiment.plots[-1].histogram.weights title = Experiment.plots[-1].histogram.title dweights = self._standard_errors_array(weights) if clear: self.clear() histo_data = histogram.Histogram() histo_data.x_axis = x_axis histo_data.weights = weights histo_data.errors = dweights histo_data.title = title plot_data = Plot(histo_data, 'histogram', True) # The histogram data is plotted here so the fit function # may be overlaid on in. However, the plot_data is appended # to the registry after the fit functions so it is on top of the # registry. self.plotter.plot1d(plot_data, xlim=rx) fit_result = PF.fit(x_axis[rx[0]:rx[1]], weights[rx[0]:rx[1]], dweights[rx[0]:rx[1]]) histo_baseline = histogram.Histogram() histo_baseline.x_axis = x_axis[rx[0]:rx[1]] histo_baseline.weights = fit_result['baseline'] histo_baseline.title = 'Baseline' plot_baseline = Plot(histo_baseline, 'function', True) self.plotter.plot1d(plot_baseline, xlim=rx) histo_peaks = histogram.Histogram() histo_peaks.x_axis = fit_result['x_axis'] histo_peaks.weights = fit_result['fit'] histo_peaks.title = 'Fit' plot_peaks = Plot(histo_peaks, 'function', True) # Append all the plots to the registry, but # keep original data at the end, so the next fit_peaks() # call will use then again as default Experiment.plots.append(plot_baseline) Experiment.plots.append(plot_peaks) Experiment.plots.append(plot_data) # Plot the last one with the auto_scale if needed if Experiment.ylim is None: ylim = self._auto_scale_y() else: ylim = Experiment.ylim self.plotter.plot1d(plot_peaks, xlim=rx, ylim=ylim) print('#{:^8} {:^8} {:^8} {:^8} {:^8} {:^8} {:^8}' .format('Peak', 'x0', 'dx', 'A', 'dA', 's', 'Area')) peak_data = [] for i, peak in enumerate(peaks): if peak.get('ignore') == 'True': continue x0 = PF.params['x{}'.format(i)].value dx = PF.params['x{}'.format(i)].stderr A = PF.params['A{}'.format(i)].value dA = PF.params['A{}'.format(i)].stderr s = PF.params['s{}'.format(i)].value Area = PF.find_area(x_axis, i) print('{:>8} {:>8.2f} {:>8.2f} {:>8.1f} {:>8.1f} {:>8.3f} {:>8.1f}' .format(peaks[i].get('E'), x0, dx, A, dA, s, Area)) peak_data.append([peaks[i].get('E'), x0, dx, A, dA, s, Area]) return peak_data