def do_fit(self, curvetype: str): xmin, xmax = self.plot1d.get_zoom_xrange() assert isinstance(self._curve, Curve) try: x = self._curve.q y = self._curve.Intensity idx = (x >= xmin) & (x <= xmax) x = x[idx] y = y[idx] dy = self._curve.Error[idx] pos, hwhm, baseline, ampl = findpeak_single(x, y, dy) x_ = np.linspace(x.min(), x.max(), len(x) * 10) assert isinstance(x_, np.ndarray) if curvetype == 'Gauss': y_ = ampl * np.exp(-0.5 * (x_ - pos) ** 2 / hwhm ** 2) + baseline elif curvetype == 'Lorentz': y_ = ampl * hwhm ** 2 / (hwhm ** 2 + (pos - x_) ** 2) + baseline else: raise ValueError(curvetype) self.builder.get_object('uncalval_adjustment').set_value(pos.val) self.builder.get_object('uncalerr_adjustment').set_value(pos.err) self.plot1d.axes.plot(x_, y_, 'r-') self.plot1d.axes.text(pos.val, ampl.val + baseline.val, pos.tostring(plusminus=' \u00b1 '), ha='center', va='bottom') self.plot1d.canvas.draw() except Exception as exc: error_message(self.widget, 'Error while fitting', str(exc) + traceback.format_exc())
def do_fit(self, left): if (self._xdata is None) or (self._ydata is None): return xmin, xmax, ymin, ymax = self.axes.axis() x = self._xdata y = self._ydata idx = (x >= xmin) & (x <= xmax) & (y >= ymin) & (y <= ymax) x = x[idx] y = y[idx] if left: signs = (-1,) else: signs = (1,) try: pos, hwhm, y0, amplitude = findpeak_single(x, y, signs=signs, curve='Lorentz') except ValueError: self.error_message('Fitting error, not enough points in the selected range.') return x = np.linspace(x.min(), x.max(), 100 * len(x)) curve = self.axes.plot(x, amplitude * hwhm ** 2 / (hwhm ** 2 + (pos - x) ** 2) + y0, 'r-', label='')[0] if left: try: self._negpeak_curve.remove() self._negpeak_text.remove() self._negpeak_text = None except AttributeError: pass assert self._negpeak_text is None self._negpeak_curve = curve self._negpeak_text = self.axes.text(pos.val, amplitude.val + y0.val, str(pos), ha='center', va='top') else: try: self._pospeak_curve.remove() self._pospeak_text.remove() self._pospeak_text = None except AttributeError: pass assert self._pospeak_text is None self._pospeak_curve = curve self._pospeak_text = self.axes.text(pos.val, amplitude.val + y0.val, str(pos), ha='center', va='bottom') self.canvas.draw_idle() if left: self.builder.get_object('leftval_adjustment').set_value(pos.val) self.builder.get_object('lefterr_adjustment').set_value(pos.err) self._negpeak_pos = pos else: self.builder.get_object('rightval_adjustment').set_value(pos.val) self.builder.get_object('righterr_adjustment').set_value(pos.err) self._pospeak_pos = pos if (self._negpeak_pos is not None) and (self._pospeak_pos is not None): self._thickness = (self._pospeak_pos - self._negpeak_pos).abs() self._position = (self._pospeak_pos + self._negpeak_pos) * 0.5 self.builder.get_object('thickness_label').set_text(str(self._thickness) + ' mm') self.builder.get_object('position_label').set_text(str(self._position)) self.builder.get_object('saveposition_button').set_sensitive(True) self.builder.get_object('savethickness_button').set_sensitive(True) self.builder.get_object('saveall_button').set_sensitive(True)
def on_fitpeak(self, menuentry: Gtk.MenuItem): curvetype = menuentry.get_name()[:-1] if menuentry.get_name().endswith('0'): signs = (1, -1) elif menuentry.get_name().endswith('+'): signs = (1,) elif menuentry.get_name().endswith('-'): signs = (-1,) else: raise ValueError(menuentry.get_name()) model, it = self.builder.get_object('counterview').get_selection().get_selected() if it is None: return False signalname = model[it][0] abscissa = self.abscissa signal = self._data[signalname] left, right, bottom, top = self.axes.axis() index = (abscissa >= left) & (abscissa <= right) & (signal <= top) & (signal >= bottom) try: position, hwhm, baseline, amplitude, stat = findpeak_single(abscissa[index], signal[index], None, return_stat=True, curve=curvetype, signs=signs) except ValueError: self.error_message('Fitting error: Probably no points of the selected curve are in the zoomed area.') return x = np.linspace(abscissa[index].min(), abscissa[index].max(), index.sum() * 5) assert isinstance(x, np.ndarray) if curvetype == 'Gaussian': y = amplitude * np.exp(-0.5 * (x - position) ** 2 / hwhm ** 2) + baseline elif curvetype == 'Lorentzian': y = amplitude * hwhm ** 2 / (hwhm ** 2 + (position - x) ** 2) + baseline else: raise ValueError(curvetype) self.axes.plot(x, y, 'r-', label='Fit') self.axes.text(position.val, amplitude.val + baseline.val, str(position), ha='center', va='bottom') self.canvas.draw() self._lastpeakposition = position self.builder.get_object('move_to_peak_button').set_sensitive(True)