Skip to content

Commit 4c0c80e

Browse files
authored
Merge pull request #43 from nathanecross/master
Updates to Wamsley2012 spindle detection
2 parents 5fd9a82 + 9c65e54 commit 4c0c80e

1 file changed

Lines changed: 46 additions & 9 deletions

File tree

wonambi/detect/spindle.py

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,12 @@ def __init__(self, method='Moelle2011', frequency=None, duration=None,
115115
if self.frequency is None:
116116
self.frequency = (12, 15)
117117
self.duration = (0.3, 3)
118-
self.det_wavelet = {'f0': mean(self.frequency),
119-
'sd': .8,
120-
'dur': 1.,
121-
'output': 'complex'
122-
}
118+
# cmor parameters to approximate MATLAB cwt_temp('cmorFb-Fc')
119+
self.det_cmor = {'fb': 13.5,
120+
'fc': 0.5,
121+
'fc_scaled': mean(self.frequency),
122+
'dur': 6.0
123+
}
123124
self.smooth = {'dur': .1,
124125
'win': 'flat'}
125126
self.det_thresh = 4.5
@@ -602,8 +603,8 @@ def detect_Nir2011(dat_orig, s_freq, time, opts):
602603

603604

604605
def detect_Wamsley2012(dat_orig, s_freq, time, opts):
605-
"""Spindle detection based on Wamsley et al. 2012
606-
606+
"""Spindle detection based on Wamsley et al. 2012 (cmor-style wavelet).
607+
607608
Parameters
608609
----------
609610
dat_orig : ndarray (dtype='float')
@@ -634,7 +635,7 @@ def detect_Wamsley2012(dat_orig, s_freq, time, opts):
634635
----------
635636
Wamsley, E. J. et al. Biol. Psychiatry 71, 154-61 (2012).
636637
"""
637-
dat_wav = transform_signal(dat_orig, s_freq, 'morlet', opts.det_wavelet)
638+
dat_wav = transform_signal(dat_orig, s_freq, 'cmor_wamsley', opts.det_cmor)
638639
dat_det = real(dat_wav ** 2) ** 2
639640
dat_det = transform_signal(dat_det, s_freq, 'smooth', opts.smooth)
640641

@@ -650,7 +651,7 @@ def detect_Wamsley2012(dat_orig, s_freq, time, opts):
650651

651652
power_peaks = peak_in_power(events, dat_orig, s_freq, opts.power_peaks)
652653
powers = power_in_band(events, dat_orig, s_freq, opts.frequency)
653-
sp_in_chan = make_spindles(events, power_peaks, powers,
654+
sp_in_chan = make_spindles(events, power_peaks, powers,
654655
absolute(dat_wav), dat_orig, time, s_freq)
655656

656657
else:
@@ -1421,6 +1422,17 @@ def transform_signal(dat, s_freq, method, method_opt=None, dat2=None):
14211422
b, a = butter(N, Wn, btype='lowpass')
14221423
dat = filtfilt(b, a, dat)
14231424

1425+
if 'cmor_wamsley' == method:
1426+
fb = method_opt['fb']
1427+
fc = method_opt['fc']
1428+
fc_scaled = method_opt.get('fc_scaled', fc)
1429+
dur = method_opt.get('dur', 6.0)
1430+
1431+
# scale in samples, as in MATLAB cwt_temp
1432+
scale = fc * s_freq / fc_scaled
1433+
wm = _cmor_wamsley(fb, fc, scale, dur)
1434+
dat = fftconvolve(dat, wm, mode='same')
1435+
14241436
if 'morlet' == method:
14251437
f0 = method_opt['f0']
14261438
sd = method_opt['sd']
@@ -2232,6 +2244,31 @@ def _merge_close(dat, events, time, min_interval):
22322244
return new_events
22332245

22342246

2247+
def _cmor_wamsley(fb, fc, scale, dur=6.0):
2248+
"""Complex Morlet wavelet approximating MATLAB cmor with CWT scaling.
2249+
2250+
Parameters
2251+
----------
2252+
fb : float
2253+
bandwidth parameter (MATLAB cmor Fb)
2254+
fc : float
2255+
center frequency parameter (MATLAB cmor Fc)
2256+
scale : float
2257+
CWT scale (in samples) to target desired center frequency
2258+
dur : float
2259+
number of std-devs of the Gaussian envelope to include on each side
2260+
"""
2261+
sigma_t = sqrt(fb / 2.0)
2262+
half_len = int(dur * sigma_t * scale)
2263+
if half_len < 1:
2264+
half_len = 1
2265+
t = arange(-half_len, half_len + 1)
2266+
tau = t / scale
2267+
norm = (pi * fb) ** (-0.5)
2268+
w = norm * exp(2j * pi * fc * tau) * exp(-(tau ** 2) / fb) / sqrt(scale)
2269+
return w
2270+
2271+
22352272
def _wmorlet(f0, sd, sampling_rate, ns=5):
22362273
"""Adapted from nitime
22372274

0 commit comments

Comments
 (0)