def segment_events_1d(rec, th=0.05, th2=0.1, smoothing=6, min_lenth=3): levels = rec > th labeled, nlab = ndi.label(levels) smrec = l1spline(rec, smoothing) #smrec = l2spline(rec, 6) mxs = np.array(extrema.locextr(smrec, output='max', refine=False)) mns = np.array(extrema.locextr(smrec, output='min', refine=False)) if not len(mxs) or not len(mns) or not np.any(mxs[:, 1] > th2): return labeled, nlab mxs = mxs[mxs[:, 1] > th2] cuts = [] for i in range(1, nlab + 1): mask = labeled == i lmax = [m for m in mxs if mask[int(m[0])]] if len(lmax) > 1: th = np.max([m[1] for m in lmax]) * 0.75 lms = [mn for mn in mns if mask[int(mn[0])] and mn[1] < th] if len(lms): for lm in lms: tmp_mask = mask.copy() tmp_mask[int(lm[0])] = 0 ll_, nl_ = ndi.label(tmp_mask) min_region = np.min( [np.sum(ll_ == i_) for i_ in range(1, nl_ + 1)]) if min_region > min_lenth: cuts.append(lm[0]) levels[int(lm[0])] = False labeled, nlab = ndi.label(levels) #plot(labeled>0) return labeled, nlab
def find_jumps(y, pre_smooth=1.5, top_gradient=95, nhood=10): ys_l1 = l1spline(y, 25) ns = mad_std(y - ys_l1) ys_tv = iterated_tv_chambolle(y, 1 * ns, 5) v = ys_tv - ys_l1 if pre_smooth > 0: v = l2spline(v, pre_smooth) xfit, yfit, der1, maxima, minima = extrema.locextr(v, refine=False, sort_values=False) _, _, _, vvmx, vvmn = extrema.locextr(np.cumsum(v), refine=False, sort_values=False) vv_extrema = np.concatenate([vvmx, vvmn]) g = np.abs(der1) ee = np.array(extrema.locextr(g, refine=False, sort_values=False, output='max')) ee = ee[ee[:, 1] >= np.percentile(g, top_gradient)] all_extrema = np.concatenate([maxima, minima]) extrema_types = {em: (1 if em in maxima else -1) for em in all_extrema} jumps = [] Lee = len(ee) for k, em in enumerate(ee[:, 0]): if np.min(np.abs(em - vv_extrema)) < 2: jumps.append(int(em)) shift = np.zeros(len(v)) L = len(v) for k, j in enumerate(jumps): if j < L - 1: shift[j + 1] = np.mean(ys_tv[j + 1:min(j + nhood + 1, L)]) - np.mean( ys_tv[max(0, j - nhood):j]) return jumps, np.cumsum(shift)
def baseline_als_spl(y, k=0.5, tau=11, smooth=25., p=0.001, niter=100, eps=1e-4, rsd=None, rsd_smoother=None, smoother=l2spline, asymm_ratio=0.9, correct_skew=False): """Asymmetric Least Squares Smoothing baseline correction algorithm (P. Eilers, H. Boelens 2005), via DCT-based spline smoothing """ #npad=int(smooth) nsmooth = np.int(np.ceil(smooth)) npad = nsmooth y = np.pad(y, npad, "reflect") L = len(y) w = np.ones(L) if rsd is None: if rsd_smoother is None: #rsd_smoother = lambda v_: l2spline(v_, 5) #rsd_smoother = lambda v_: ndi.median_filter(y,7) rsd_smoother = partial(ndi.median_filter, size=7) rsd = rolling_sd_pd(y - rsd_smoother(y), input_is_details=True) else: rsd = np.pad(rsd, npad, "reflect") #ys = l1spline(y,tau) ntau = np.int(np.ceil(tau)) ys = ndi.median_filter(y, ntau) s2 = l1spline(y, smooth / 4.) #s2 = l2spline(y,smooth/4.) zprev = None for i in range(niter): z = smoother(ys, s=smooth, weights=w) clip_symm = abs(y - z) > k * rsd clip_asymm = y - z > k * rsd clip_asymm2 = y - z <= -k * rsd r = asymm_ratio #*core.rescale(1./(1e-6+rsd)) #w = p*clip_asymm + (1-p)*(1-r)*(~clip_symm) + (1-p)*r*(clip_asymm2) w = p * (1-r) * clip_asymm + (1-p) * (~clip_symm) + p * r * (clip_asymm2) w[:npad] = (1 - p) w[-npad:] = (1 - p) if zprev is not None: if norm(z - zprev) / norm(zprev) < eps: break zprev = z z = smoother(np.min((z, s2), 0), smooth) if correct_skew: # Correction for skewness introduced by asymmetry. z += r * rsd return z[npad:-npad]
def l1_baseline2(y, smooth=25, median_window=50): npad = median_window // 2 ypad = np.pad(y, npad, 'median', stat_length=smooth // 2) b1 = l1spline(ypad, smooth)[npad:-npad] # get overall trend v = y - b1 vm = ndi.percentile_filter(v, 50, median_window) vmlow = windowed_runmin(vm, 2 * median_window, 2 * median_window // 5) b_add = l2spline(vmlow, smooth / 2) return b1 + b_add
def symmetrized_l1_runmin(y, tv_weight=1, tv_niter=5, l1smooth=50, l2smooth=5): b1 = l1spline(y, l1smooth) ns = mad_std(y - b1) b0 = iterated_tv_chambolle(y, tv_weight * ns, tv_niter) b2a = windowed_runmin(b0 - b1) + b1 b2b = -windowed_runmin(-(b0 - b1)) + b1 b2a, b2b = (iterated_tv_chambolle(b, 1, 5) for b in (b2a, b2b)) # making this too slow? return l2spline(select_most_stable_branch((b2a, b2b)), l2smooth)
def iterated_symm_runmin(v, niters=10, w=350, pre_smooth=10, post_smooth=25): out = v if pre_smooth > 0: out = l1spline(out, pre_smooth) for i in range(niters): #top = -windowed_runmin(-out, w, w//2) #bot = windowed_runmin(out, w, w//2) env = windowed_envelope(out, w, w//2) m = np.mean(env,1) #sk = np.sign(skew(v-m)) sk = np.sign(np.sum(v-m) - np.sum(m-v)) if sk > 0: m = 0.5*m + 0.5*env[:,0] elif sk < 0: m = 0.5*m + 0.5*env[:,1] out = m if post_smooth > 0: out = l1spline(out, post_smooth) return out