import pywt import pandas import matplotlib.pyplot as plt import numpy as np from scipy import stats import statsmodels.api as sm data = pandas.read_csv("c:/users/user/desktop/qbuss6840.csv") k = [] n = 2 for i in data: k.append(data[i]) x1 = k[0][1:137] w1 = pywt.Wavelet('sym3') l = pywt.wavedec(x1, w1, mode='per', level=n) '''y=pywt.waverec(l, w1,mode='per') ''' ''' fig=plt.figure(figsize=(12,8)) ax1=fig.add_subplot(211) fig=sm.graphics.tsa.plot_acf(np.diff(l[2]),lags=20,ax=ax1) plt.show() ''' dl = [] pl = [] for i in l: dl.append(i[1:] - i[:-1]) for i in dl: print(i) am = sm.tsa.ARIMA(i, (1, 0, 0)).fit()
def test_2d_haar_l3(wavelet=pywt.Wavelet('haar')): run_2dtest(wavelet, level=3)
def test_2d_db4(wavelet=pywt.Wavelet('db4')): run_2dtest(wavelet)
r2 = np.arange(N1,N2) r3 = np.arange(N2,N3) r4 = np.arange(N3,N4) r5 = np.arange(N4,N5) x[r1] = r1/float(N1) x[r2] =0.5+ ((r2-float(N1))/float(N2))**2 x[r3] = x[N2-1] t4 = (r4-float(N3))/float(N4) x[r4] = -80*t4**3 + 20*t4**2 + x[N2-1] x[r5] = 0.5*(1-(r5-float(N4))/(float(N5-N4))) x[420:423] =1 plt.plot(x), plt.title('Piecewise polynomial signal') , plt.show() #%% Load the DWT filter w = pywt.Wavelet('db4') Npoints = 2**13 step = 1.0/Npoints HPF = np.fft.fft(w.dec_hi,Npoints) HPF = np.fft.fftshift(HPF) nu = np.arange(-0.5,0.5, step) plt.title('FR of the HPF'), plt.plot(nu,abs(HPF)), plt.show() #% compute derivatives k=1 dh=abs(HPF) dnu = nu while k<=4: dh = np.diff(dh)/step dnu=dnu[1:] print 'Derivative %1d'% k plt.plot(dnu,dh), plt.show()
plt.close() fig = plt.figure() plt.plot(p_test.squeeze().detach().cpu().numpy()) plt.plot( np.abs( (p_test - two_at_power_zero).squeeze().detach().cpu().numpy())) plt.legend(['p_test,', 'err']) tensorboard_writer.add_figure(name + '/wavelet/filters-prl', fig, step, close=True) plt.close() if __name__ == "__main__": print('haar wavelet') w = Wave1D(init_wavelet=pywt.Wavelet('haar')) print('acl', w.alias_cancellation_loss()[0]) print('prl', w.perfect_reconstruction_loss()[0]) print('db6 wavelet') w = Wave1D(init_wavelet=pywt.Wavelet('db6')) print('acl', w.alias_cancellation_loss()[0]) print('prl', w.perfect_reconstruction_loss()[0]) print('sym3 wavelet') w = Wave1D(init_wavelet=pywt.Wavelet('sym3')) print('acl', w.alias_cancellation_loss()[0]) print('prl', w.perfect_reconstruction_loss()[0])
def main(): # Create images folder Path("Imgs").mkdir(exist_ok=True) Path("Imgs/Noise").mkdir(exist_ok=True) Path("Imgs/Sin1").mkdir(exist_ok=True) Path("Imgs/Sin2").mkdir(exist_ok=True) Path("Imgs/Sin3").mkdir(exist_ok=True) Path("Imgs/Sin1_ns").mkdir(exist_ok=True) Path("Imgs/Sin2_ns").mkdir(exist_ok=True) Path("Imgs/Sin3_ns").mkdir(exist_ok=True) Path("Imgs/Sin_pad").mkdir(exist_ok=True) Path("Imgs/Wavelets").mkdir(exist_ok=True) # Init rng rng = default_rng() # Noise ns = rng.normal(0, 1, 6000) # Sine waves # Number of sample points N = 6000 # sampling frequency fs = 100 # Time axis t = np.linspace(0.0, N / fs, N) # Number of frequency interval steps n = 100 # Frequency spans fr1 = np.linspace(1, 50, n) fr2 = np.linspace(0.01, 1, n) # Prealocate wvs1 = [] wvs2 = [] wvs3 = [] for f1, f2 in zip(fr1, fr2): sig1 = np.sin(f1 * 2.0 * np.pi * t) sig2 = np.sin(f2 * 2.0 * np.pi * t) wvs1.append(sig1) wvs2.append(sig2) wvs3.append(sig1 + sig2) wvs1 = np.array(wvs1) wvs2 = np.array(wvs2) wvs3 = np.array(wvs3) wvs1_ns = wvs1 + 0.5 * rng.normal(0, 1, wvs1.shape) wvs2_ns = wvs2 + 0.5 * rng.normal(0, 1, wvs2.shape) wvs3_ns = wvs3 + 0.5 * rng.normal(0, 1, wvs3.shape) # PADDED SINES # Number of intermediate sample points ni = [1000, 2000, 4000, 5000] # Number of points to zero-pad pad = [(N - n) // 2 for n in ni] # Time axis for smaller waves lts = [np.linspace(0.0, nis / fs, nis) for nis in ni] # All frequencies list all_fr = [] # Calculate max period for smaller waves max_periods = [n_points / fs for n_points in ni] # Calculate frequencies for smaller waves for per in max_periods: freqs = [] for i in range(1, int(per) + 1): if per % i == 0: freqs.append(1 / i) all_fr.append(freqs) # Preallocate waves wvs_pad = [] # Generate waves and zero pad for idx, fr_ls in enumerate(all_fr): for fr in fr_ls: wv = np.sin(fr * 2.0 * np.pi * lts[idx]) wv = np.pad(wv, (pad[idx], pad[idx]), 'constant') wvs_pad.append(wv) # Wavelets # Preallocate wavelets lets = [] # Discrete wavelet families discrete_families = ['db', 'sym', 'coif', 'bior', 'rbio'] # Obtain wavelet waveforms, resample and append for fam in discrete_families: for wavelet in pywt.wavelist(fam): wv = pywt.Wavelet(wavelet) if wv.orthogonal: [_, psi, _] = pywt.Wavelet(wavelet).wavefun(level=5) psi = signal.resample(psi, 6000) lets.append(psi) # Plot Sine waveforms # Number of traces to plot n_trtp = 4 # Traces to plot trtp_sin1 = [] trtp_sin2 = [] trtp_sin3 = [] trtp_sin1_ns = [] trtp_sin2_ns = [] trtp_sin3_ns = [] # Traces to plot numbers trtp_ids_sin1 = rng.choice(len(wvs1), size=n_trtp, replace=False) trtp_ids_sin2 = rng.choice(len(wvs2), size=n_trtp, replace=False) trtp_ids_sin3 = rng.choice(len(wvs3), size=n_trtp, replace=False) trtp_ids_sin1_ns = rng.choice(len(wvs1_ns), size=n_trtp, replace=False) trtp_ids_sin2_ns = rng.choice(len(wvs2_ns), size=n_trtp, replace=False) trtp_ids_sin3_ns = rng.choice(len(wvs3_ns), size=n_trtp, replace=False) trtp_ids_sin1.sort() trtp_ids_sin2.sort() trtp_ids_sin3.sort() trtp_ids_sin1_ns.sort() trtp_ids_sin2_ns.sort() trtp_ids_sin3_ns.sort() # Retrieve selected traces for idx, trace in enumerate(wvs1): if idx in trtp_ids_sin1: trtp_sin1.append(trace) for idx, trace in enumerate(wvs2): if idx in trtp_ids_sin2: trtp_sin2.append(trace) for idx, trace in enumerate(wvs3): if idx in trtp_ids_sin3: trtp_sin3.append(trace) for idx, trace in enumerate(wvs1_ns): if idx in trtp_ids_sin1_ns: trtp_sin1_ns.append(trace) for idx, trace in enumerate(wvs2_ns): if idx in trtp_ids_sin2_ns: trtp_sin2_ns.append(trace) for idx, trace in enumerate(wvs3_ns): if idx in trtp_ids_sin3_ns: trtp_sin3_ns.append(trace) # Figure to plot plt.figure() # Plot n random Sin 1 traces for idx, trace in enumerate(trtp_sin1): plt.clf() plt.plot(t, trace) plt.title(f'Senal sinusoides 1 #{trtp_ids_sin1[idx]}') plt.xlabel('Tiempo [s]') plt.ylabel('Amplitud [-]') plt.grid(True) plt.savefig(f'Imgs/Sin1/Sin1_{trtp_ids_sin1[idx]}') # Plot n random Sin 2 traces for idx, trace in enumerate(trtp_sin2): plt.clf() plt.plot(t, trace) plt.title(f'Traza sinusoides 2 #{trtp_ids_sin2[idx]}') plt.xlabel('Tiempo [s]') plt.ylabel('Amplitud [-]') plt.grid(True) plt.savefig(f'Imgs/Sin2/Sin2_{trtp_ids_sin2[idx]}') # Plot n random Sin 3 traces for idx, trace in enumerate(trtp_sin3): plt.clf() plt.plot(t, trace) plt.title(f'Traza sinusoides 3 #{trtp_ids_sin3[idx]}') plt.xlabel('Tiempo [s]') plt.ylabel('Amplitud [-]') plt.grid(True) plt.savefig(f'Imgs/Sin3/Sin3_{trtp_ids_sin3[idx]}') # Plot n random Sin 1 + noise traces for idx, trace in enumerate(trtp_sin1_ns): plt.clf() plt.plot(t, trace) plt.title(f'Traza sinusoides 1 + noise #{trtp_ids_sin1_ns[idx]}') plt.xlabel('Tiempo [s]') plt.ylabel('Amplitud [-]') plt.grid(True) plt.savefig(f'Imgs/Sin1_ns/Sin1_ns_{trtp_ids_sin1_ns[idx]}') # Plot n random Sin 2 + noise traces for idx, trace in enumerate(trtp_sin2_ns): plt.clf() plt.plot(t, trace) plt.title(f'Traza sinusoides 2 #{trtp_ids_sin2_ns[idx]}') plt.xlabel('Tiempo [s]') plt.ylabel('Amplitud [-]') plt.grid(True) plt.savefig(f'Imgs/Sin2_ns/Sin2_ns_{trtp_ids_sin2_ns[idx]}') # Plot n random Sin 3 + noise traces for idx, trace in enumerate(trtp_sin3_ns): plt.clf() plt.plot(t, trace) plt.title(f'Traza sinusoides 3 + noise #{trtp_ids_sin3_ns[idx]}') plt.xlabel('Tiempo [s]') plt.ylabel('Amplitud [-]') plt.grid(True) plt.savefig(f'Imgs/Sin3_ns/Sin3_ns_{trtp_ids_sin3_ns[idx]}') # Plot Padded Sine waveforms # Traces to plot trtp_pad = [] # Traces to plot numbers trtp_ids_pad = rng.choice(len(wvs_pad), size=n_trtp, replace=False) trtp_ids_pad.sort() # Retrieve selected traces for idx, trace in enumerate(wvs_pad): if idx in trtp_ids_pad: trtp_pad.append(trace) # Plot n random Sin 1 traces for idx, trace in enumerate(trtp_pad): plt.clf() plt.plot(t, trace) plt.title(f'Traza sinusoides pad #{trtp_ids_pad[idx]}') plt.xlabel('Tiempo [s]') plt.ylabel('Amplitud [-]') plt.grid(True) plt.savefig(f'Imgs/Sin_pad/Sin_pad_{trtp_ids_pad[idx]}') # Plot wavelet waveforms # Traces to plot trtp_wvlets = [] # Traces to plot numbers trtp_ids_wvlets = rng.choice(len(lets), size=n_trtp, replace=False) trtp_ids_wvlets.sort() # Retrieve selected traces for idx, trace in enumerate(lets): if idx in trtp_ids_wvlets: trtp_wvlets.append(trace) # Plot n random wavelet for idx, trace in enumerate(trtp_wvlets): plt.clf() plt.plot(t, trace) plt.title(f'Wavelet #{trtp_ids_pad[idx]}') plt.xlabel('Muestras [-]') plt.ylabel('Amplitud [-]') plt.grid(True) plt.savefig(f'Imgs/Wavelets/wavelet_{trtp_ids_wvlets[idx]}') # Plot noise plt.clf() plt.plot(ns) plt.xlabel('Muestras [-]') plt.ylabel('Amplitud [-]') plt.title('Ruido blanco') plt.grid(True) plt.savefig(f'Imgs/Noise/noise.png')
plt.grid() print(epochs) #mathed filtration ycn=yc/10 ycn=np.where(np.abs(ycn)!=1,ycn,0) yc1=10*ycn ydc=np.real(scipy.fft.fftshift(scipy.fft.ifft(scipy.fft.fft(yc1)/scipy.fft.fft(yg)))) #input wavelet decompasition in1=ydc #wavelet decompasition using dwt CA11,CD11,CD10,CD9,CD8,CD7,CD6,CD5,CD4,CD3,CD2,CD1=pywt.wavedec(ydc,wavelet=pywt.Wavelet('db2'),level=11) #predict 10 level dwt decompasition coefficient detalisation CD10P=[] for i in range(1): t=np.linspace(0,len(CD10[i,:])/fs,len(ydc)) ca11=np.resize(CD10,CD10.shape[0]) x_train=np.column_stack((ca11,t,t)) x_train=np.asarray(x_train) encoding_dim = 3 input = Input(shape=(3,)) encoded = Dense(encoding_dim, activation='relu')(input)
def process_data(data, channelNames, srate): global f_labels, processed_channel_names # Default RQA parameters embedding = 10 # Embedding dimension tdelay = 2 # Time delay tau = 30 # threshold # Multiscaling is accomplished with a wavelet transform # Options for basis functions: ['haar', 'db', 'sym', 'coif', 'bior', 'rbio', 'dmey'] #wavelet = 'haar' wavelet = 'db4' mode = 'cpd' #mode = pywt.Modes.smooth # Simple array for entropy value ent = np.zeros(1) # Determine the number of levels required so that # the lowest level approximation is roughly the # delta band (freq range 0-4 Hz) if srate <= 128: levels = 4 elif srate <= 256: levels = 5 elif srate <= 512: # subsample srate = srate / 2.0 n = len(data[0]) data = data[0:, 0:n:2] levels = 5 elif srate <= 1024: srate = srate / 4.0 n = len(data[0]) data = data[0:, 0:n:4] levels = 5 nbands = levels wavelet_scale = {} f_limit = {} # The following function returns the highest level (ns) approximation # in dec[0], then details for level ns in dec[1]. Each successive # level of detail coefficients is in dec[2] through dec[ns]. # # level approximation details # 0 original signal -- # 1 - dec[ns] # 2 - dec[ns-1] # 3 - dec[ns-2] # i - dec[ns-i+1] # ns dec[0] dec[1] WRITE_RP_IMAGE_FILE = False # Print screen headers sys.stdout.write("%10s %6s " % ("Sensor", "Freq")) for f in all_features: sys.stdout.write(" %8s " % (f)) sys.stdout.write("\n") D = {} for c, ch in enumerate(channelNames): if ch in master_channel_list: processed_channel_names.append(ch) # Create a raw recurrence plot image for the original signal from this channel if WRITE_RP_IMAGE_FILE: rp_plot_name = filename + "_" + ch + "_" + "rp" + ".png" print(" write rp image file ", rp_plot_name) settings = Settings(data[c], embedding_dimension=embedding, time_delay=tdelay, neighbourhood=FixedRadius(0)) #computation = RQAComputation.create(settings, verbose=False) rp_computation = RecurrencePlotComputation.create( settings, verbose=False) result = rp_computation.run() ImageGenerator.save_recurrence_plot( result.recurrence_matrix_reverse, rp_plot_name) D[ch] = {} #-------------------------------------------------------------------- # Get the wavelet decomposition. See pywavelet (or pywt) documents. # Deconstruct the waveforms # S = An + Dn + Dn-1 + ... + D1 #-------------------------------------------------------------------- w = pywt.Wavelet(wavelet) m = np.mean(data[c]) a_orig = data[c] - m # the original signal, initially a = a_orig ca = [] # all the approximations cd = [] # all the details sqrt2 = np.sqrt(2.0) for i in range(nbands): (a, d) = pywt.dwt(a, w, mode) f = pow(sqrt2, i + 1) ca.append(a / f) cd.append(d / f) if 1 == 0: # this will build full reconstructed signals at every level rec_a = [] # reconstructed approximations rec_d = [] # reconstructed details for i, coeff in enumerate(ca): coeff_list = [coeff, None] + [None] * i rec_a.append(pywt.waverec(coeff_list, w)) for i, coeff in enumerate(cd): coeff_list = [None, coeff] + [None] * i rec_d.append(pywt.waverec(coeff_list, w)) else: rec_a = ca rec_d = cd # Use the details and last approximation to create all the power-of-2 freq bands f_labels = ['A0'] wavelet_scale = {} wavelet_scale['A0'] = 0 f_limit = {} f_limit['A0'] = srate / 2.0 fs = [srate] freqband = [a_orig] # A0 is the original signal N = len(a_orig) f = srate / 4.0 for j, r in enumerate(rec_a): freq_name = 'A' + str(j + 1) wavelet_scale[freq_name] = j + 1 f_limit[freq_name] = f f = f / 2.0 f_labels.append(freq_name) freqband.append(r[0:N]) # wavelet approximation for this band f = srate / 2.0 for j, r in enumerate(rec_d): freq_name = 'D' + str(j + 1) wavelet_scale[freq_name] = j + 1 f_limit[freq_name] = f f = f / 2.0 f_labels.append(freq_name) freqband.append(r[0:N]) # wavelet details for this band #-------------------------------------------------------------------- # Compute features on each of the frequency bands #-------------------------------------------------------------------- for f in all_features: D[ch][f] = {} #---------------------- # Feature set 1: Power for i, y in enumerate(freqband): v = bandpower(y) D[ch]["Power"][f_labels[i]] = v #---------------------- # Feature set 2: Sample Entropy, Hurst parameter, DFA, Lyapunov exponents D[ch]["SampE"][f_labels[i]] = nolds.sampen(y) try: D[ch]["hurst_rs"][f_labels[i]] = nolds.hurst_rs(y) except: D[ch]["hurst_rs"][f_labels[i]] = 0.0 try: D[ch]["dfa"][f_labels[i]] = nolds.dfa(y) except: D[ch]["dfa"][f_labels[i]] = 0.0 try: D[ch]["cd"][f_labels[i]] = nolds.corr_dim(y, embedding) except: D[ch]["cd"][f_labels[i]] = 0.0 try: #lyap = nolds.lyap_e(y, emb_dim= embedding) lyap0 = nolds.lyap_r(y, emb_dim=embedding) except: #lyap = [0.0, 0.0, 0.0] lyap0 = 0.0 D[ch]["lyap0"][f_labels[i]] = lyap0 #---------------------- # Feature set 3: Recurrence Quantitative Analysis (RQA) # This routine seems to be incredibly slow and may need improvement rqa_features = [ "RR", "DET", "LAM", "L_entr", "L_max", "L_mean", "TT" ] pyRQA_names = ['recurrence_rate', 'determinism', 'laminarity', 'entropy_diagonal_lines', \ 'longest_diagonal_line','average_diagonal_line', 'trapping_time' ] # First check to see if RQA values are needed at all compute_RQA = False for r in rqa_features: if r in all_features: compute_RQA = True break if compute_RQA: #for i, y in enumerate(freqband): settings = Settings( y, embedding_dimension=embedding, time_delay=tdelay, neighbourhood=FixedRadius(tau) #similarity_measure=EuclideanMetric, #theiler_corrector=1, #min_diagonal_line_length=2, #min_vertical_line_length=2, #min_white_vertical_line_length=2) ) computation = RQAComputation.create(settings, verbose=False) result = computation.run() # We have to pull out each value w = f_labels[i] D[ch]["RR"][w] = result.recurrence_rate D[ch]["DET"][w] = result.determinism D[ch]["LAM"][w] = result.laminarity D[ch]["L_entr"][w] = result.entropy_diagonal_lines D[ch]["L_max"][w] = result.longest_diagonal_line D[ch]["L_mean"][w] = result.average_diagonal_line D[ch]["TT"][w] = result.trapping_time # Write results from first channel to the screen, to give # visual feedback that the code is running w = f_labels[i] sys.stdout.write("%10s %6s " % (ch, w)) for dyn_inv in all_features: # D[ch].keys(): v = D[ch][dyn_inv][w] sys.stdout.write(" %8.3f " % (v)) sys.stdout.write("\n") return D, srate, wavelet_scale, f_limit
def test_centrfrq_deprecation(): wavelet = pywt.Wavelet('db3') assert_warns(DeprecationWarning, pywt.centrfrq, wavelet)
# JN 2015-01-11 from __future__ import print_function, division, absolute_import import numpy as np import pywt # scipy doesn't have the flexibility yet from .. import options WAVELET = pywt.Wavelet(options['Wavelet']) OUT_DTYPE = np.float32 LEVEL = 4 def wavelet_features(data): """ calculates wavelet transform """ # probably implementing this in cython would # save some computation time first_row = pywt.wavedec(data[0, :], WAVELET, level=LEVEL) aligned = np.hstack(first_row) output = np.empty((data.shape[0], aligned.shape[0]), dtype=OUT_DTYPE) output[0, :] = aligned for i, row in enumerate(data[1:, :]): features = pywt.wavedec(row, WAVELET, level=LEVEL) output[i + 1, :] = np.hstack(features) return output
f = pylab.figure() f.subplots_adjust(hspace=0.2, wspace=0.2, bottom=.02, left=.06, right=.97, top=.94) colors = itertools.cycle('bgrcmyk') wnames = pywt.wavelist(family) print wnames i = iter(wnames) for col in xrange(cols): for row in xrange(rows): try: wavelet = pywt.Wavelet(i.next()) except StopIteration: break phi, psi, x = wavelet.wavefun(iterations) color = colors.next() ax = pylab.subplot(rows, 2 * cols, 1 + 2 * (col + row * cols)) pylab.title(wavelet.name + " phi") pylab.plot(x, phi, color) pylab.xlim(min(x), max(x)) ax = pylab.subplot(rows, 2 * cols, 1 + 2 * (col + row * cols) + 1) pylab.title(wavelet.name + " psi") pylab.plot(x, psi, color) pylab.xlim(min(x), max(x))
import numpy as np import cv2 import pywt img = cv2.imread("DSC1.jpeg", 0) imgA = np.asarray(img) #imgA is the image as an Array filterdim = imgA.shape #dimensions of the original image bc_filt = np.zeros(filterdim, imgA.dtype) wavelet = pywt.Wavelet('haar') def GAN(): #returns gaussian noise row, col = imgA.shape # include ch for colour images mean = 0 var = 0.5 sigma = var**0.5 gauss = np.random.normal(mean, sigma, (row, col)) #ch gauss = gauss.reshape(row, col) #ch return gauss def noise_add(gauss, imgA): noisy = gauss + imgA return noisy def bc_e(img, filterdim, alpha, beta): #brightness and contrast enhancer for y in range(filterdim[0]): for x in range(filterdim[1]): bc_filt[y, x] = np.clip(alpha * img[y, x] + beta, 0, 255) #brightness and contrast filter
def printDetails(): print("Family of wavelets available:") print(pywt.families()) print("\n{0}".format(pywt.Wavelet('haar')))
def binary_mse(X_f, X_o, thr, wavelet="haar"): """Compute an intensity-scale verification as the MSE of the binary error. This method uses PyWavelets for decomposing the error field between the forecasts and observations into multiple spatial scales. Parameters ---------- X_f : array_like Array of shape (m, n) containing the forecast field. X_o : array_like Array of shape (m, n) containing the verification observation field. thr : sequence The intensity threshold for which to compute the verification. wavelet : str, optional The name of the wavelet function to use. Defaults to the Haar wavelet, as described in Casati et al. 2004. See the documentation of PyWavelets for a list of available options. Returns ------- SS : array One-dimensional array containing the binary MSE for each spatial scale. spatial_scale : list References ---------- :cite:`CRS2004` """ if not pywt_imported: raise MissingOptionalDependency( "PyWavelets package is required for the binary MSE spatial " "verification method but it is not installed") if len(X_f.shape) != 2 or len(X_o.shape) != 2 or X_f.shape != X_o.shape: message = "X_f and X_o must be two-dimensional arrays" message += " having the same shape" raise ValueError(message) X_f = X_f.copy() X_f[~np.isfinite(X_f)] = thr - 1 X_o = X_o.copy() X_o[~np.isfinite(X_o)] = thr - 1 w = pywt.Wavelet(wavelet) SS = None I_f = (X_f >= thr).astype(float) I_o = (X_o >= thr).astype(float) E_decomp = _wavelet_decomp(I_f - I_o, w) n_scales = len(E_decomp) eps = 1.0 * np.sum((X_o >= thr).astype(int)) / np.size(X_o) SS = np.empty((n_scales)) for j in range(n_scales): mse = np.mean(E_decomp[j] ** 2) SS[j] = 1 - mse / (2 * eps * (1 - eps) / n_scales) SS[~np.isfinite(SS)] = np.nan scales = pow(2, np.arange(SS.size))[::-1] return SS, scales
channel_stds = [0.229, 0.224, 0.225] perturbation = 'dumb' mask_image_enhance = 100 img_path = 'butterfly.jpg' # img_path = 'car.png' # img_path = 'panda.png' # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # PLOT SELECTED WAVELET w=pywt.Wavelet('bior2.2') # plt.plot(w.dec_hi[::-1], label="dec hi") # plt.plot(w.dec_lo[::-1], label="dec lo") # plt.plot(w.rec_hi, label="rec hi") # plt.plot(w.rec_lo, label="rec lo") # plt.title("Bior 2.2 Wavelets") # plt.legend() # plt.show() # DEFINE WAVELET FILTERS AND WAVELET TRANSFORMS dec_hi = torch.Tensor(w.dec_hi[::-1]) dec_lo = torch.Tensor(w.dec_lo[::-1]) rec_hi = torch.Tensor(w.rec_hi) rec_lo = torch.Tensor(w.rec_lo)
def test_scal2frq_deprecation(): wavelet = pywt.Wavelet('db3') assert_warns(DeprecationWarning, pywt.scal2frq, wavelet, 1)
def _wavelet_threshold(image, wavelet, method=None, threshold=None, sigma=None, mode='soft', wavelet_levels=None): """Perform wavelet thresholding. Parameters ---------- image : ndarray (2d or 3d) of ints, uints or floats Input data to be denoised. `image` can be of any numeric type, but it is cast into an ndarray of floats for the computation of the denoised image. wavelet : string The type of wavelet to perform. Can be any of the options pywt.wavelist outputs. For example, this may be any of ``{db1, db2, db3, db4, haar}``. method : {'BayesShrink', 'VisuShrink'}, optional Thresholding method to be used. The currently supported methods are "BayesShrink" [1]_ and "VisuShrink" [2]_. If it is set to None, a user-specified ``threshold`` must be supplied instead. threshold : float, optional The thresholding value to apply during wavelet coefficient thresholding. The default value (None) uses the selected ``method`` to estimate appropriate threshold(s) for noise removal. sigma : float, optional The standard deviation of the noise. The noise is estimated when sigma is None (the default) by the method in [2]_. mode : {'soft', 'hard'}, optional An optional argument to choose the type of denoising performed. It noted that choosing soft thresholding given additive noise finds the best approximation of the original image. wavelet_levels : int or None, optional The number of wavelet decomposition levels to use. The default is three less than the maximum number of possible decomposition levels (see Notes below). Returns ------- out : ndarray Denoised image. References ---------- .. [1] Chang, S. Grace, Bin Yu, and Martin Vetterli. "Adaptive wavelet thresholding for image denoising and compression." Image Processing, IEEE Transactions on 9.9 (2000): 1532-1546. :DOI:`10.1109/83.862633` .. [2] D. L. Donoho and I. M. Johnstone. "Ideal spatial adaptation by wavelet shrinkage." Biometrika 81.3 (1994): 425-455. :DOI:`10.1093/biomet/81.3.425` """ wavelet = pywt.Wavelet(wavelet) if not wavelet.orthogonal: warn(("Wavelet thresholding was designed for use with orthogonal " "wavelets. For nonorthogonal wavelets such as {}, results are " "likely to be suboptimal.").format(wavelet.name)) # original_extent is used to workaround PyWavelets issue #80 # odd-sized input results in an image with 1 extra sample after waverecn original_extent = tuple(slice(s) for s in image.shape) # Determine the number of wavelet decomposition levels if wavelet_levels is None: # Determine the maximum number of possible levels for image wavelet_levels = pywt.dwtn_max_level(image.shape, wavelet) # Skip coarsest wavelet scales (see Notes in docstring). wavelet_levels = max(wavelet_levels - 3, 1) coeffs = pywt.wavedecn(image, wavelet=wavelet, level=wavelet_levels) # Detail coefficients at each decomposition level dcoeffs = coeffs[1:] if sigma is None: # Estimate the noise via the method in [2]_ detail_coeffs = dcoeffs[-1]['d' * image.ndim] sigma = _sigma_est_dwt(detail_coeffs, distribution='Gaussian') if method is not None and threshold is not None: warn(("Thresholding method {} selected. The user-specified threshold " "will be ignored.").format(method)) if threshold is None: var = sigma**2 if method is None: raise ValueError( "If method is None, a threshold must be provided.") elif method == "BayesShrink": # The BayesShrink thresholds from [1]_ in docstring threshold = [{key: _bayes_thresh(level[key], var) for key in level} for level in dcoeffs] elif method == "VisuShrink": # The VisuShrink thresholds from [2]_ in docstring threshold = _universal_thresh(image, sigma) else: raise ValueError("Unrecognized method: {}".format(method)) if np.isscalar(threshold): # A single threshold for all coefficient arrays denoised_detail = [{key: pywt.threshold(level[key], value=threshold, mode=mode) for key in level} for level in dcoeffs] else: # Dict of unique threshold coefficients for each detail coeff. array denoised_detail = [{key: pywt.threshold(level[key], value=thresh[key], mode=mode) for key in level} for thresh, level in zip(threshold, dcoeffs)] denoised_coeffs = [coeffs[0]] + denoised_detail return pywt.waverecn(denoised_coeffs, wavelet)[original_extent]
def test_intwave_deprecation(): wavelet = pywt.Wavelet('db3') assert_warns(DeprecationWarning, pywt.intwave, wavelet)
def findStimuli(self, data): wavelet = 'haar' filterSize = pywt.Wavelet(wavelet).dec_len pwr = pywt.swt(data, wavelet, 2) pwr2 = array( pwr[0] [1]) # вейвлет коефициенты высокочастотной составляющей сигнала pwr2Std = ar.stdFinder(pwr2[self.deltaLen:], self.defaultFrame) treshold = pwr2Std * 1.5 * log( pwr2.ptp() / pwr2Std) #11 - empirical finding coef try: self.mysql_writer.dbTechInfo_stim(pwr2Std, treshold) except: logger.warn("findStimuli # Error: {0}".format(sys.exc_info())) pwr5 = zeros(len(pwr2)) # pwr5 по сути первая производная от вейвлет коефициентов # высокочастотной составляющей сигнала pwr5[1:] += abs(diff(pwr2)) pwr5[0] = pwr5[1] # оставляем только резкие изменения в высокочастотной составляющей pwr5[pwr5 < treshold] = 0 pwr5[pwr5 > 0] = treshold # dpwr - координаты точек в которых начинались резкие изменения в # высокочастотной составляющей сигнала dpwr = where(diff(pwr5) == treshold)[0] dpwrMask = ones(len(dpwr), dtype='bool') for i in range(len(dpwr) - 1): if dpwr[i + 1] - dpwr[ i] < self.stimulyDuration / 3.0: # если две точки слишком близко, то оставляем первую. dpwrMask[i + 1] = 0 dpwr = dpwr[dpwrMask] dpwrMask = ones(len(dpwr), dtype='bool') for i in range(len(dpwr)): # по характеристикам сигнала в окрестностях этих точек будем # решать является ли это артефактом от электрического стимула. length1 = len( where((abs( diff(pwr2[dpwr[i] + filterSize:dpwr[i] + filterSize + self.stimulyDuration / 2])) >= treshold))[0]) sample1 = data[dpwr[i] + filterSize * 2:dpwr[i] + filterSize * 2 + self.stimulyDuration / 2] sample2 = data[dpwr[i] + filterSize * 2 - self.stimulyDuration / 2:dpwr[i] + filterSize * 2] sample3 = pwr2[dpwr[i] + filterSize:dpwr[i] + filterSize + self.stimulyDuration / 2] sample4 = pwr2[dpwr[i] + filterSize - self.stimulyDuration / 2:dpwr[i] + filterSize] sample5 = data[dpwr[i] + filterSize * 2 - self.stimulyDuration / 2:dpwr[i] + filterSize * 2 + self.stimulyDuration / 2] sampleSumDiff = abs(median(sample1) - median(sample2)) std_diff = sample3.std() / sample4.std() ptp_diff = abs(sample3).mean() / abs(sample4).mean() sampleGlobalStd = median(sample5) / median(sample2) length = length1 * 100000.0 / self.frequency ptp_1 = sample1.ptp() * 0.1 ptp_2 = sample2.ptp() * 0.1 std_1 = sample1.std() std_2 = sample2.std() median_1 = median(sample1) * 0.1 median_2 = median(sample2) * 0.1 mean_1 = sample1.mean() * 0.1 mean_2 = sample2.mean() * 0.1 median_diff_1 = median(diff(sample1 * 1.0)) median_diff_2 = median(diff(sample2 * 1.0)) if sampleSumDiff > 0: neuroTestResult = rInterface.stimNeuroCheck( length, ptp_1, ptp_2, std_1, median_1, mean_1, mean_2, median_2, std_2, median_diff_1, median_diff_2, std_diff, ptp_diff) >= 0.5 try: self.mysql_writer.dbStimProp_write( i, length, ptp_1, ptp_2, std_1, std_2, median_1, median_2, mean_1, mean_2, median_diff_1, median_diff_2, std_diff, ptp_diff, neuroTestResult, 1) except: logger.error( "findStimuli # Error when write stim prop: {0}".format( sys.exc_info())) if neuroTestResult: logger.warn( "findStimul # Accepted! Start: {0}, ptp_diff: {1}, std_diff: {2}, sampleSumDiff: {3}, sampleGlobalStd: {4}" .format(dpwr[i] + filterSize, ptp_diff, std_diff, sampleSumDiff, sampleGlobalStd)) #self.mysql_writer.dbWriteStim(sample2, sample1, length1, i, "1", self.frequency, std_diff, ptp_diff) else: dpwrMask[i] = 0 #self.mysql_writer.dbWriteStim(sample2, sample1, length1, i, "0", self.frequency, std_diff, ptp_diff) logger.warn( "findStimuli # Dropped! Start: {0}, ptp_diff: {1}, std_diff: {2}, sampleSumDiff: {3}, sampleGlobalStd: {4}" .format(dpwr[i] + filterSize, ptp_diff, std_diff, sampleSumDiff, sampleGlobalStd)) else: dpwrMask[i] = 0 #self.mysql_writer.dbWriteStim(sample2, sample1, length1, i, "0", self.frequency, std_diff, ptp_diff) logger.warn( "findStimuli # Dropped! Start: {0}, ptp_diff: {1}, std_diff: {2}, sampleSumDiff: {3}, sampleGlobalStd: {4}" .format(dpwr[i] + filterSize, ptp_diff, std_diff, sampleSumDiff, sampleGlobalStd)) dpwr = dpwr[dpwrMask] logger.info("findStimuli # Number of finded stimuls: {0}".format( len(dpwr))) stimList = [[], []] for i in range(len(dpwr)): start = dpwr[i] + filterSize * 2 length = self.stimulyDuration / 4 if self.stimulyDuration > 35: baseline = ar.histMean( data[start - int(self.stimulyDuration / 7):start]) baseStd = data[start - int(self.stimulyDuration / 7):start].std() else: baseline = data[start - 1] baseStd = data[start - 6:start - 1].std() tmpStop = start + length if tmpStop + self.defaultFrame + 5 > len(data): tmpStop = len(data) - self.defaultFrame - 5 stimMean = data[start:tmpStop].mean() logger.warn( "findStimuli # Baseline: {0}, baseStd: {1}, start: {2}, tmpStop: {3}, stimMean: {4}" .format(baseline, baseStd, start, tmpStop, stimMean)) try: sample = signal.medfilt( data[tmpStop - 5:tmpStop + self.defaultFrame + 5], int(self.stimulyDuration / 20)) except: sample = data[tmpStop - int(self.stimulyDuration / 40):tmpStop + self.defaultFrame + int(self.stimulyDuration / 40)] firstArray = abs(diff(sample)) <= baseStd secondArray = abs(sample[1:] - baseline) < baseStd / 2 fourthArray = ar.stdArray(sample[1:], 5) <= baseStd * 3 fivthArray = abs(sample[1:] - baseline) < baseStd * 4 logger.warn("findStimuli # {0}".format( (any(firstArray), any(secondArray), any(fourthArray), any(fivthArray)))) try: shift = where( (firstArray * fivthArray + secondArray) * fourthArray)[0] if len(shift) > 0: realStop = tmpStop + shift[0] else: realStop = tmpStop logger.warn("findStimuli # Can`t find stimulum end =(") self.softError = 1 except: logger.error( "findSimuli # Unexpected error in finding of stimuli end:{0}" .format(sys.exc_info())) realStop = tmpStop logger.warn( "findStimuli # start {0}, tmpStop {1}, realStop {2}".format( start, tmpStop, realStop)) stimList[0] += [start] stimList[1] += [realStop] self.stimuli = stimList
# # from pandas import read_csv # import pywt dataframe = pd.read_csv('huarui_5min.csv', usecols=[1], engine='python', encoding='utf-8') dataset = dataframe.values import numpy as np import matplotlib.pyplot as plt import pywt x = dataset[40:550, 0] plt.plot(x) plt.show() db1 = pywt.Wavelet('db4') # level = pywt.dwt_max_level(len(x), db1) cA2, cD2, cD1 = pywt.wavedec(x, db1, mode='constant', level=2) plt.plot(cD1) plt.show() plt.plot(cD2) plt.show() # plt.plot(cD3) # plt.show() # plt.plot(cD4) # plt.show() plt.plot(cA2) plt.show() # plt.plot(cD6) # plt.show() # plt.plot(cD7)
# plt.xlabel('xValue', fontsize=14) # plt.ylabel('yValue', fontsize=14) # 设置刻度标记的大小 # plt.tick_params(axis='both', which='major', labelsize=14) # 设置每个坐标轴的取值范围 # plt.axis([0, 1000, 0, 100]) plt.show() ##############画图############################################ # print(data.shape) # print(data) # print(data['RH_6']) ##################去噪######################### db1 = pywt.Wavelet('db1') # [ca3, cd3, cd2, cd1] = pywt.wavedec(x, db1) # print(ca3) # print(cd3) # print(cd2) # print(cd1) # 分解为三层 coeffs = pywt.wavedec(y_values, db1, level=3) print("------------------len of coeffs---------------------") print(len(coeffs)) # print(coeffs) recoeffs = pywt.waverec(coeffs, db1) # print(recoeffs) thcoeffs = [] for i in range(1, len(coeffs)):
import matplotlib.pyplot as plt import pywt import pywt.data from pywt import wavedec from pywt import dwt_max_level # %% # import matlab file using scipy wheat = scipy.io.loadmat('./wheat.mat') Xwave = np.zeros((0, 0)) X = wheat['WHEAT_SPECTRA'] (nVar, nSamp) = (len(X[0]), len(X)) wavelet = pywt.Wavelet('sym2') Lmax = pywt.dwt_max_level(nVar, wavelet) wavelets = [ 'db2', 'db3', 'db4', 'db5', 'db6', 'db7', 'db8', 'db9', 'db10', 'coif1', 'coif2', 'coif3', 'coif4', 'coif5', 'sym4', 'sym5', 'sym6', 'sym7', 'sym8', 'sym9', 'sym10' ] Lmaxs = [] for wave in wavelets: Lmaxs.append(pywt.dwt_max_level(nVar, wave)) Xwave = np.zeros((nSamp, 711)) # for each line in the dataset for i in range(0, nSamp):
return ll if __name__ == "__main__": import scipy import scipy.misc import pywt import time size = 32, 32 level = 3 wavelet_str = "db2" face = np.mean(scipy.misc.face()[: size[0], : size[1]], -1).astype(np.float64) pt_face = torch.tensor(face).cuda() wavelet = pywt.Wavelet(wavelet_str) matrixfwt = MatrixWavedec2(wavelet, level=level) start_time = time.time() mat_coeff = matrixfwt(pt_face.unsqueeze(0)) total = time.time() - start_time print("runtime: {:2.2f}".format(total)) start_time_2 = time.time() mat_coeff2 = matrixfwt(pt_face.unsqueeze(0)) total_2 = time.time() - start_time_2 print("runtime: {:2.2f}".format(total_2)) matrixifwt = MatrixWaverec2(wavelet) reconstruction = matrixifwt(mat_coeff) reconstruction2 = matrixifwt(mat_coeff) # remove the padding if size[0] % 2 != 0: reconstruction = reconstruction[:-1, :]
center_freq = pywt.scale2frequency(wvlt, 1) / Ts # scales = np.arange(1, 128) scales = center_freq / np.linspace(2000, 1, 50) coeff, freq = pywt.cwt(svm_data, scales=scales, wavelet=wvlt, sampling_period=Ts, method='auto', axis=1) power = np.abs(coeff)**2 power = np.reshape(power, (power.shape[0], power.shape[1] * power.shape[2]), order='C') # some random useful functions for DWT stuff # wvlt = 'sym10' wvlt_data = pywt.Wavelet(wvlt) father, mother, coords = wvlt_data.wavefun(level=1) # father=scaling=LPF lpf_coeffs, hpf_coeffs = wvlt_data.filter_bank[0:2] center_freq = pywt.scale2frequency(wvlt, 1) / Ts coeffs = pywt.wavedecn(svm_data, wavelet=wvlt, mode='periodization', level=6, axes=1) coeffs_vec, coeffs_slices = pywt.coeffs_to_array(coeffs, axes=[1]) coeffs_vec = np.abs(coeffs_vec)**2 # first attempt at training SVM with STFT coefficients (note: no normalization of coefficients or k fold CV) # svm_data, YL = get_formatted_data(data_df, group='w') win_len = 256 // 2
def pywt_wavelet(wavelet): """Convert ``wavelet`` to a `pywt.Wavelet` instance.""" if isinstance(wavelet, pywt.Wavelet): return wavelet else: return pywt.Wavelet(wavelet)
def progressive_lowcut_series(series): """Progressively remove low-frequency components of 1D series. Yields sequence in which the low-frequency (large-scale) components of `series` are progressively removed. The sequence is obtained from reconstruction of a multilevel discrete haar wavelet decomposition of `series`. N.B.: The length of `series` is assumed to be a power of 2 (does not check!) Parameters ---------- series : array_like 1D data series with a length that is a power of 2 Yields ------- lowcut_series : array Sequence of progressively lowcut filtered data `series`. The yielded series have the same length as `series`. Notes ----- After an N level discrete wavelet decomposition, a data series S can be reconstructed in terms of wavelet 'approximations' (A) and 'details' (D):: S = A(N) + D(N) + D(N-1) ... D(2) + D(1) = A(N-1) + D(N-1) + ... D(2) + D(1) [A(N-1) = A(N) + D(N)] ... = A(1) + D(1) [(A(1) = A(2) + D(2)] where A(N) represents the 'lowest' level approximation. For the haar wavelet and data S having a length that is a power of 2, A(N) is equal to mean(S)] The sequence returned by this function is:: S - A(N), S - A(N-1), S - A(N-2), ..., S - A(1) This sequence is computed by the equivalent:: S - A(N), S - A(N) - D(N), S - A(N) - D(N) - D(N-1), ..., S - A(N) - D(N) - D(N-1) - ... - D(2), i.e. the details are removed in sequence:: lowcut = S - A(N) for j = N to 2 lowcut -= D(j) """ series_data = np.asarray(series) wavelet = pywt.Wavelet("haar") nlevel = pywt.dwt_max_level(series_data.size, wavelet.dec_len) decomp_coef = pywt.wavedec(series_data, wavelet=wavelet, level=nlevel) cAn, cD = decomp_coef[0], decomp_coef[1:] lowcut_series = series_data - pywt.upcoef("a", cAn, wavelet, level=nlevel) yield lowcut_series for j, cDj in enumerate(cD[:-1]): Dj = pywt.upcoef("d", cDj, wavelet, level=nlevel - j) lowcut_series -= Dj yield lowcut_series
def test_2d_haar_lmax(wavelet=pywt.Wavelet('haar')): run_2dtest(wavelet, level=None)
print(fset_guo) ############################################################################### # Multi-channel time series # ~~~~~~~~~~~~~~~~~~~~~~~~~ # The EEG time series considered here consist of univariate signal measurements along a # uniform time grid. But ``featurize_time_series`` also accepts multi-channel # data; to demonstrate this, we will decompose each signal into five frequency # bands using a discrete wavelet transform as suggested by # `Subasi (2005) <http://www.sciencedirect.com/science/article/pii/S0957417404001745>`_, # and then featurize each band separately using the five functions from above. import pywt n_channels = 5 eeg["dwts"] = [pywt.wavedec(m, pywt.Wavelet('db1'), level=n_channels-1) for m in eeg["measurements"]] fset_dwt = featurize.featurize_time_series(times=None, values=eeg["dwts"], errors=None, features_to_use=list(guo_features.keys()), targets=eeg["classes"], custom_functions=guo_features) print(fset_dwt) ############################################################################### # The output featureset has the same form as before, except now the ``channel`` # coordinate is used to index the features by the corresponding frequency band. # The functions in ``cesium.build_model`` and ``cesium.predict`` all accept # featuresets from single- or multi-channel data, so no additional steps are # required to train models or make predictions for multichannel featuresets # using the ``cesium`` library.
def test_2d_sym5(wavelet=pywt.Wavelet('sym5')): run_2dtest(wavelet)
def udDTCWTLvl1(image, lvl1Filters): # pad the lvl 0 filters lvl1Len = np.max((lvl1Filters[0].shape[0], lvl1Filters[1].shape[0], lvl1Filters[2].shape[0], lvl1Filters[3].shape[0])) fac = 1.0 h0o = np.roll( np.pad(fac * lvl1Filters[0][::1, 0], [3, 3], mode='constant')[::1], 1).tolist() g0o = np.roll( np.pad(fac * lvl1Filters[1][::1, 0], [0, 0], mode='constant')[::1], 0).tolist() h1o = np.roll( np.pad(fac * lvl1Filters[2][::1, 0], [0, 0], mode='constant')[::1], 1).tolist() g1o = np.roll( np.pad(fac * lvl1Filters[3][::1, 0], [3, 3], mode='constant')[::1], 0).tolist() lvl1WvtA = pywt.Wavelet('lvl1', filter_bank=[ np.roll(h0o, 0), np.roll(h1o, 0), np.roll(g0o, 0), np.roll(g1o, 0) ]) #g0o,g1o]) lvl1WvtB = pywt.Wavelet('lvl1', filter_bank=[ np.roll(h0o, 1), np.roll(h1o, 1), np.roll(g0o, 1), np.roll(g1o, 1) ]) # Undecimated "a trous" transform tree AA swtCoeffs = pywt.swt2(image, wavelet=(lvl1WvtA, lvl1WvtA), axes=(0, 1), level=1)[0] AA_LL, (AA_LH, AA_HL, AA_HH) = swtCoeffs # Undecimated "a trous" transform tree AB swtCoeffs = pywt.swt2(image, wavelet=(lvl1WvtA, lvl1WvtB), axes=(0, 1), level=1)[0] AB_LL, (AB_LH, AB_HL, AB_HH) = swtCoeffs # Undecimated "a trous" transform tree BA swtCoeffs = pywt.swt2(image, wavelet=(lvl1WvtB, lvl1WvtA), axes=(0, 1), level=1)[0] BA_LL, (BA_LH, BA_HL, BA_HH) = swtCoeffs # Undecimated "a trous" transform tree BB swtCoeffs = pywt.swt2(image, wavelet=(lvl1WvtB, lvl1WvtB), axes=(0, 1), level=1)[0] BB_LL, (BB_LH, BB_HL, BB_HH) = swtCoeffs fac = np.sqrt(0.5) coeffs1 = fac * (AA_HH - BB_HH) + fac * 1.j * (BA_HH + AB_HH) coeffs4 = fac * (AA_HH + BB_HH) + fac * 1.j * (-BA_HH + AB_HH) coeffs5 = fac * (AA_LH - BB_LH) + fac * 1.j * (BA_LH + AB_LH) coeffs0 = fac * (AA_LH + BB_LH) + fac * 1.j * (-BA_LH + AB_LH) coeffs3 = fac * (AA_HL - BB_HL) + fac * 1.j * (BA_HL + AB_HL) coeffs2 = fac * (AA_HL + BB_HL) + fac * 1.j * (-BA_HL + AB_HL) coeffs = [] coeffs.append((coeffs0, coeffs1, coeffs2, coeffs3, coeffs4, coeffs5)) return coeffs, (AA_LL, AB_LL, BA_LL, BB_LL)