@@ -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
604605def 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+
22352272def _wmorlet (f0 , sd , sampling_rate , ns = 5 ):
22362273 """Adapted from nitime
22372274
0 commit comments