def leastsq_integrate(ts, peak_list, f='gaussian'): # FIXME: transition from t0, t1, params to params (containing 't0'/'t1' # lookup the peak model function to use for fitting f = {f.__name__: f for f in peak_models}[f] peaks = [] for w, peak_list in _get_windows(peak_list): tr = ts.trace(twin=w) # if there's location info, we can use this for # our inital params if 'x' in peak_list[0][2]: # TODO: should fill in other values? # TODO: should do something with y0 and y1? initc = [i[2] for i in peak_list] else: # TODO: should find peak maxima for rts? rts = [0.5 * (i[0] + i[1]) for i in peak_list] initc = guess_initc(tr, f, rts) params, _ = fit(tr, [f] * len(initc), initc) for p in params: pk_ts = Trace(f(tr.times, **p), tr.times) info = {'name': '{:.2f}'.format(p['x'])} info['p-create'] = '{},leastsq_integrate'.format( peak_list[0][2].get('pf', '')) pk = PeakComponent(info, pk_ts) peaks.append(pk) return peaks
def trace(self): if self.info.get('p-model') not in peak_models: return self._trace else: model = peak_models[self.info.get('p-model')] t = self._trace.index d = model(t=t, **{ k: self.info.get(k) for k in model._peakargs if self.info.get(k) is not None }) d += self.baseline._retime(t) return Trace(d, t, name='')
def refit(self, peak_model=None): # TODO: needs to work with PeakComponents containing DataFrames? self.info['p-model'] = peak_model if peak_model is None: # TODO: remove parameters from self.info? # del self.info['p-model-fit'] return model = peak_models[peak_model] # remove the baseline and create a new series t = self._trace.index d = self._trace.values - self.baseline._retime(t) ts = Trace(d, t) # fit the peak initc = guess_initc(ts, model, [t[d.argmax()]]) params, res = fit(ts, [model], initc) self.info.update(params[0]) self.info['p-model-fit'] = res['r^2']
def simple_integrate(ts, peak_list, base_ts=None, intname='simple'): """ Integrate each peak naively; without regard to overlap. This is used as the terminal step by most of the other integrators. """ peaks = [] for hints in peak_list: t0, t1 = hints['t0'], hints['t1'] hints['int'] = intname pk_ts = ts.twin((t0, t1)) if base_ts is None: # make a two point baseline base = Trace([hints.get('y0', pk_ts[0]), hints.get('y1', pk_ts[-1])], [t0, t1], name=ts.name) else: base = base_ts.twin((t0, t1)) peaks.append(PeakComponent(hints, pk_ts, base)) return peaks
def base(s, slope_tol='5.0', off_tol='5.0'): ic = savitzkygolay(s, 5, 3)[0] slopes = np.diff(ic) / np.diff(s.index) wind = np.array([0.5, 0.5]) offsets = np.convolve(ic, wind, mode='valid') offsets -= slopes * np.convolve(s.index, wind, mode='valid') sl_kern = gaussian_kde(slopes) base_slope = fmin(lambda x: -sl_kern(x), 0, disp=False) k_h = sl_kern(base_slope) * (1.0 - 10 ** -float(slope_tol)) s1 = brentq(lambda x: sl_kern(x) - k_h, min(slopes), base_slope) s2 = brentq(lambda x: sl_kern(x) - k_h, base_slope, max(slopes)) valid = np.logical_and(slopes > s1, slopes < s2) off_kern = gaussian_kde(offsets[valid]) base_off = fmin(lambda x: -off_kern(x), 0, disp=False) k_h = off_kern(base_off) * (1.0 - 10 ** -float(off_tol)) o1 = brentq(lambda x: off_kern(x) - k_h, min(offsets), base_off) o2 = brentq(lambda x: off_kern(x) - k_h, base_off, max(offsets)) msk = np.logical_and(valid, offsets > o1) msk = np.logical_and(valid, offsets < o2) new_ic = np.interp(s.index, s.index[msk], ic[msk]) return Trace(new_ic, s.index)
def total_trace(self, twin=None): f = NetCDFFile(open(self.filename, 'rb')) tme = f.variables['scan_acquisition_time'].data / 60. tic = f.variables['total_intensity'].data return Trace(tic, tme, name='TIC')