def run_emg_peak_fit(self, t_peak_start: float, t_peak_max: float, t_peak_end: float, relative_threshold: float): rt_mean, sigma, skew = calc_emg_parameters_from_peak_shape( t_peak_start, t_peak_max, t_peak_end, relative_threshold ) v = peak_shapes.emg(np.array([t_peak_start, t_peak_max, t_peak_end]), rt_mean, sigma, skew) # try: self.assertAlmostEqual(v[0], relative_threshold * v[1], 4) self.assertAlmostEqual(v[2], relative_threshold * v[1], 4) # except AssertionError as ex: # print(ex) # t = np.linspace(0, t_peak_end * 5, 10000) # p = peak_shapes.emg(t, rt_mean, sigma, skew) # from bokeh.plotting import figure, show # plt_1 = figure(plot_width=690, plot_height=350) # plt_1.line(t, p, line_width=2, color='green') # plt_1.line(t_peak_start * np.ones(2), # np.array([0, p.max()]), # line_width=2, color='black') # plt_1.line(t_peak_max * np.ones(2), # np.array([0, p.max()]), # line_width=2, color='green') # plt_1.line(t_peak_end * np.ones(2), # np.array([0, p.max()]), # line_width=2, color='green') # show(plt_1) t = np.linspace(0, t_peak_end * 5, 10000) p = peak_shapes.emg(t, rt_mean, sigma, skew) self.assertAlmostEqual(p.max(), v[1], 3)
def setUp(self) -> None: self.t = np.linspace(0, 100, 1500) self.dt = self.t[1] - self.t[0] self.log = TestLogger() self.rtd_rt_mean = 50 self.rtd = peak_shapes.emg(self.t, rt_mean=self.rtd_rt_mean, sigma=20, skew=0.5) self.rtd_norm = self.rtd / self.rtd.sum() / self.dt self.assertAlmostEqual(self.rtd_norm.sum() * self.dt, 1) # define pre-fill self.pre_fill = np.ones([3, 1]) self.pre_fill[1] = 0 self.pre_fill[2] = 0.23 # define wash self.wash = np.ones([3, 1]) self.wash[0] = 0.45 self.wash[1] = 0.32 # define in c profile self.c_in = np.ones([3, self.t.size]) self.c_in[0, :] = 0.1 self.c_in[1, :] = 0.5 self.c_in[:, -self.rtd. size:] = 0 # clip the end in order to prevent the spill
def get_emg_pdf_with_cutoff(t, rt_mean, sigma, skew, cutoff) -> np.ndarray: p: np.ndarray = peak_shapes.emg(t, rt_mean, sigma, skew) # cut at end p = p[:true_end(p >= cutoff * p.max())] # set to 0 at front p[:true_start(p >= cutoff * p.max())] = 0 # return normalized profile (integral = 1) return p / p.sum() / t[1]
def score_func(x): # x == [sigma, skew] _sigma, _skew = x _rt_mean = get_rt_mean(_sigma, _skew) _p = _peak_shapes.emg(_t, _rt_mean, _sigma, _skew) scr = (relative_threshold - _p[0] / _p[1]) ** 2 * 10 + \ (relative_threshold - _p[2] / _p[1]) ** 2 # print(_rt_mean, _sigma, _skew, scr) return scr
def _calc_pdf(self, kw_pars: dict) -> _np.ndarray: # Get `rt_mean` from parameters. rt_mean = kw_pars['rt_mean'] if 'rt_mean' in kw_pars.keys() \ else kw_pars['v_void'] / kw_pars['f'] # Get `skew` from parameters if provided. skew = kw_pars['skew'] if 'skew' in kw_pars.keys() else self.skew # Calc `sigma`. sigma = (rt_mean * self.dispersion_index)**0.5 # Calc probability distribution (`p`). t = _np.arange(0, self._t_steps_max * self._dt, self._dt) p = _peak_shapes.emg(t, rt_mean, sigma, skew, self.log) return p
from bio_rtd import pdf, peak_shapes, peak_fitting t = np.linspace(0, 10, 201) # Calc rt_mean, sigma and skew from peak points. rt, sigma, skew = peak_fitting.calc_emg_parameters_from_peak_shape( t_peak_start=0.6, t_peak_max=1.4, t_peak_end=3.9, relative_threshold=0.1) # Define pdf. pdf_emg = pdf.ExpModGaussianFixedDispersion(t, sigma**2 / rt, skew) pdf_emg.update_pdf(rt_mean=rt) p_emg = pdf_emg.get_p() # Generate noisy data. y = peak_shapes.emg(t, 2, 0.3, 1.0) # clean signal y_noisy = y + (np.random.random(y.shape) - 0.5) * y.max() / 10 # Plot. p = figure(plot_width=690, plot_height=350, title="Probability Distribution", x_axis_label="t [min]", y_axis_label="c [mg/mL]") p.line(t, y_noisy, line_width=2, color='green', alpha=0.6, legend_label='c [mg/mL] (data)') p.line(t, p_emg, line_width=2, color='black', alpha=1, legend_label='p (pdf)')
def test_emg(self) -> None: t = np.linspace(0, 100, 1000) rt_mean = 20 p = peak_shapes.emg(t, rt_mean=rt_mean, sigma=2, skew=1, logger=self.log) # validations self.validate_rt_mean(t, p, rt_mean) self.validate_point_on_slope(t, p, 15.33, 0.1 * p.max()) self.validate_point_on_slope(t, p, 24.80, 0.1 * p.max()) self.validate_point_on_slope(t, p, 17.35, 0.5 * p.max()) self.validate_point_on_slope(t, p, 22.47, 0.5 * p.max()) self.validate_max(t, p, 19.82) # warnings with self.assertWarns(Warning, msg="EMG peak: sigma + 1 / skew < 4 * dt"): peak_shapes.emg(t, rt_mean=rt_mean, sigma=4 * t[1] - 0.1 - 0.01, skew=10, logger=self.log) with self.assertRaises(RuntimeError, msg="Peak shape: integral: 0.7723355216030109"): with self.assertWarns(Warning, msg="EMG peak: rt_mean + 3 * sigma > t[-1]"): peak_shapes.emg(t, rt_mean=rt_mean, sigma=(t[-1] - rt_mean) / 3 + 0.01, skew=1, logger=self.log) with self.assertWarns( Warning, msg="EMG peak: t0 < 3 * sigma; t0 = rt_mean - 1 / skew"): skew = 0.8 t0 = rt_mean - 1 / skew peak_shapes.emg(t, rt_mean=rt_mean, sigma=t0 / 3 - 0.01, skew=1, logger=self.log) with self.assertRaises(RuntimeError, msg="Peak shape: integral: 0.5483504934228841"): with self.assertWarns(Warning, msg="EMG peak: skew < 1/40"): peak_shapes.emg(t, rt_mean=rt_mean, sigma=2, skew=1 / 41, logger=self.log) with self.assertWarns(Warning, msg="EMG peak: skew > 10"): peak_shapes.emg(t, rt_mean=rt_mean, sigma=2, skew=10.1, logger=self.log) with self.assertRaises( RuntimeError, msg="Peak shape: relative value at start: 0.1359995541938657"): with self.assertWarns(Warning, msg="EMG peak: exp argument (p) > 200"): skew = 2 sigma = 10 t0 = rt_mean - 1 / skew assert np.any(skew / 2 * (2 * (t0 - t) + skew * sigma**2) > 200) peak_shapes.emg(t, rt_mean=rt_mean, sigma=sigma, skew=skew, logger=self.log) with self.assertRaises( RuntimeError, msg="Peak shape: integral: 0.0069704155745190025"): with self.assertWarns(Warning, msg="EMG peak: exp argument (p) < -200"): skew = 40 sigma = 1 t0 = rt_mean - 1 / skew assert np.any(skew / 2 * (2 * (t0 - t) + skew * sigma**2) < -200) peak_shapes.emg(t, rt_mean=rt_mean, sigma=sigma, skew=skew, logger=self.log) # 2nd test t = np.linspace(0, 150, 5000) rt_mean = 40 p = peak_shapes.emg(t, rt_mean, 7.4, 0.26, self.log) # validations self.validate_rt_mean(t, p, rt_mean) self.validate_point_on_slope(t, p, 22.62725, 0.1 * p.max()) self.validate_point_on_slope(t, p, 57.90722, 0.1 * p.max()) self.validate_point_on_slope(t, p, 30.12018, 0.5 * p.max()) self.validate_point_on_slope(t, p, 49.14717, 0.5 * p.max()) self.validate_max(t, p, 39.41918)