def plot_powerspectrum(fname, raw=None, picks=None, dir_plots="plots", tmin=None, tmax=None, fmin=0.0, fmax=450.0, n_fft=4096): ''' ''' import os import matplotlib.pyplot as pl import mne from distutils.dir_util import mkpath if raw is None: assert os.path.isfile(fname), 'ERROR: file not found: ' + fname raw = mne.io.Raw(fname, preload=True) if picks is None: picks = jumeg_base.pick_meg_nobads(raw) dir_plots = os.path.join(os.path.dirname(fname), dir_plots) base_fname = os.path.basename(fname).strip('.fif') mkpath(dir_plots) file_name = fname.split('/')[-1] fnfig = dir_plots + '/' + base_fname + '-psds.png' pl.figure() pl.title('PSDS ' + file_name) ax = pl.axes() fig = raw.plot_psds(fmin=fmin, fmax=fmax, n_fft=n_fft, n_jobs=1, proj=False, ax=ax, color=(0, 0, 1), picks=picks, area_mode='range') pl.ioff() # pl.ion() fig.savefig(fnfig) pl.close() return fname
def apply_create_noise_covariance_data(fname,raw=None,do_filter=True,filter_parameter=None,verbose=False,do_run=True,save=True ): ''' Creates the noise covariance matrix from an empty room file. Parameters ---------- fname : string containing the filename of the empty room file (must be a fif-file) do_filter: bool If true, the empy room file is filtered before calculating the covariance matrix. (Beware, filter settings are fixed.) filter_parameter: dict dict with filter parameter and flags do_run: bool execute this save: bool save output file verbose : bool, str, int, or None If not None, override default verbose level (see mne.verbose). default: verbose=None RETURN --------- full empty room filname as string raw obj of input raw-obj or raw-empty-room obj ''' # ------------------------------------------- # import necessary modules # ------------------------------------------- from mne import compute_raw_data_covariance as cp_covariance from mne import write_cov from mne.io import Raw from mne import pick_types import os mne.verbose = verbose try: (fname_empty_room,raw_empty) = jumeg_base.get_empty_room_fif(fname=fname,raw=raw,preload=do_run) except: return if raw_empty : #--- picks meg channels filter_parameter.picks = jumeg_base.pick_meg_nobads(raw_empty) #--- filter or get filter name filter_parameter.do_run = do_filter if do_filter : print "Filtering empty room fif with noise variance settings...\n" (fname_empty_room,raw_empty) = apply_filter_data(fname_empty_room,raw=raw_empty,**filter_parameter) #--- update file name for saving noise_cov fname_empty_room_cov = fname_empty_room.split('-')[0] + ',empty-cov.fif' #--- calc nois-covariance matrix if do_run : noise_cov_mat = cp_covariance(raw_empty,picks=filter_parameter.picks,verbose=verbose) #--- write noise-covariance matrix to disk if save : write_cov( fname_empty_room_cov, noise_cov_mat) return fname_empty_room_cov
def apply_ica_data(fname,raw=None,do_run=False,verbose=False,save=True,fif_extention=".fif",fif_postfix="-ica",**kwargs): """ apply mne ica return fnica_out : fif filename of mne ica-obj raw : fif-raw obj ICAobj : mne-ica-object Attributes ---------- current_fit : str Flag informing about which data type (raw or epochs) was used for the fit. ch_names : list-like Channel names resulting from initial picking. The number of components used for ICA decomposition. n_components_` : int If fit, the actual number of components used for ICA decomposition. n_pca_components : int See above. max_pca_components : int The number of components used for PCA dimensionality reduction. verbose : bool, str, int, or None See above. pca_components_` : ndarray If fit, the PCA components pca_mean_` : ndarray If fit, the mean vector used to center the data before doing the PCA. pca_explained_variance_` : ndarray If fit, the variance explained by each PCA component mixing_matrix_` : ndarray If fit, the mixing matrix to restore observed data, else None. unmixing_matrix_` : ndarray If fit, the matrix to unmix observed data, else None. exclude : list List of sources indices to exclude, i.e. artifact components identified throughout the ICA solution. Indices added to this list, will be dispatched to the .pick_sources methods. Source indices passed to the .pick_sources method via the 'exclude' argument are added to the .exclude attribute. When saving the ICA also the indices are restored. Hence, artifact components once identified don't have to be added again. To dump this 'artifact memory' say: ica.exclude = [] info : None | instance of mne.io.meas_info.Info The measurement info copied from the object fitted. n_samples_` : int the number of samples used on fit. """ ICAobj = None if do_run : if raw is None: if fname is None: print"ERROR no file foumd!!\n" return raw = mne.io.Raw(fname,preload=True) print"\n" from mne.preprocessing import ICA picks = jumeg_base.pick_meg_nobads(raw) #--- init MNE ICA obj kwargs['global_parameter']['verbose'] = verbose ICAobj = ICA( **kwargs['global_parameter'] ) #--- run mne ica kwargs['fit_parameter']['verbose'] = verbose ICAobj.fit(raw, picks=picks,**kwargs['fit_parameter'] ) fnica_out = fname[:fname.rfind('-raw.fif')] + fif_postfix + fif_extention # fnica_out = fname[0:len(fname)-4]+'-ica.fif' #--- save ICA object if save : ICAobj.save(fnica_out) print "===> Done JuMEG MNE ICA : " + fnica_out print "\n" return (fnica_out,raw,ICAobj)
def noise_reducer_4raw_data(fname_raw, raw=None, signals=[], noiseref=[], detrending=None, tmin=None, tmax=None, reflp=None, refhp=None, refnotch=None, exclude_artifacts=True, checkresults=True, fif_extention="-raw.fif", fif_postfix="nr", reject={ 'grad': 4000e-13, 'mag': 4e-12, 'eeg': 40e-6, 'eog': 250e-6 }, complementary_signal=False, fnout=None, verbose=False, save=True): """Apply noise reduction to signal channels using reference channels. !!! ONLY ONE RAW Obj Interface Version FB !!! Parameters ---------- fname_raw : rawfile name raw : fif raw object signals : list of string List of channels to compensate using noiseref. If empty use the meg signal channels. noiseref : list of string | str List of channels to use as noise reference. If empty use the magnetic reference channsls (default). signals and noiseref may contain regexp, which are resolved using mne.pick_channels_regexp(). All other channels are copied. tmin : lower latency bound for weight-calc [start of trace] tmax : upper latency bound for weight-calc [ end of trace] Weights are calc'd for (tmin,tmax), but applied to entire data set refhp : high-pass frequency for reference signal filter [None] reflp : low-pass frequency for reference signal filter [None] reflp < refhp: band-stop filter reflp > refhp: band-pass filter reflp is not None, refhp is None: low-pass filter reflp is None, refhp is not None: high-pass filter refnotch : (base) notch frequency for reference signal filter [None] use raw(ref)-notched(ref) as reference signal exclude_artifacts: filter signal-channels thru _is_good() [True] (parameters are at present hard-coded!) complementary_signal : replaced signal by traces that would be subtracted [False] (can be useful for debugging) checkresults : boolean to control internal checks and overall success [True] reject = dict for rejection threshold units: grad: T / m (gradiometers) mag: T (magnetometers) eeg/eog: uV (EEG channels) default=>{'grad':4000e-13,'mag':4e-12,'eeg':40e-6,'eog':250e-6} save : save data to fif file Outputfile: ------- <wawa>,nr-raw.fif for input <wawa>-raw.fif Returns ------- TBD Bugs ---- - artifact checking is incomplete (and with arb. window of tstep=0.2s) - no accounting of channels used as signal/reference - non existing input file handled ungracefully """ tc0 = time.clock() tw0 = time.time() if type(complementary_signal) != bool: raise ValueError("Argument complementary_signal must be of type bool") raw, fname_raw = jumeg_base.get_raw_obj(fname_raw, raw=raw) if detrending: raw = perform_detrending(None, raw=raw, save=False) tc1 = time.clock() tw1 = time.time() if verbose: print ">>> loading raw data took %.1f ms (%.2f s walltime)" % ( 1000. * (tc1 - tc0), (tw1 - tw0)) # Time window selection # weights are calc'd based on [tmin,tmax], but applied to the entire data set. # tstep is used in artifact detection # tmin,tmax variables must not be changed here! if tmin is None: itmin = 0 else: itmin = int(floor(tmin * raw.info['sfreq'])) if tmax is None: itmax = raw.last_samp else: itmax = int(ceil(tmax * raw.info['sfreq'])) if itmax - itmin < 2: raise ValueError( "Time-window for noise compensation empty or too short") if verbose: print ">>> Set time-range to [%7.3f,%7.3f]" % \ (raw.index_as_time(itmin)[0], raw.index_as_time(itmax)[0]) if signals is None or len(signals) == 0: sigpick = jumeg_base.pick_meg_nobads(raw) else: sigpick = channel_indices_from_list(raw.info['ch_names'][:], signals, raw.info.get('bads')) nsig = len(sigpick) if nsig == 0: raise ValueError("No channel selected for noise compensation") if noiseref is None or len(noiseref) == 0: # References are not limited to 4D ref-chans, but can be anything, # incl. ECG or powerline monitor. if verbose: print ">>> Using all refchans." refexclude = "bads" refpick = jumeg_base.pick_ref_nobads(raw) else: refpick = channel_indices_from_list(raw.info['ch_names'][:], noiseref, raw.info.get('bads')) nref = len(refpick) if nref == 0: raise ValueError("No channel selected as noise reference") if verbose: print ">>> sigpick: %3d chans, refpick: %3d chans" % (nsig, nref) if reflp is None and refhp is None and refnotch is None: use_reffilter = False use_refantinotch = False else: use_reffilter = True if verbose: print "########## Filter reference channels:" use_refantinotch = False if refnotch is not None: if reflp is None and reflp is None: use_refantinotch = True freqlast = np.min([5.01 * refnotch, 0.5 * raw.info['sfreq']]) if verbose: print ">>> notches at freq %.1f and harmonics below %.1f" % ( refnotch, freqlast) else: raise ValueError("Cannot specify notch- and high-/low-pass" "reference filter together") else: if verbose: if reflp is not None: print ">>> low-pass with cutoff-freq %.1f" % reflp if refhp is not None: print ">>> high-pass with cutoff-freq %.1f" % refhp # Adapt followg drop-chans cmd to use 'all-but-refpick' droplist = [ raw.info['ch_names'][k] for k in xrange(raw.info['nchan']) if not k in refpick ] tct = time.clock() twt = time.time() fltref = raw.drop_channels(droplist, copy=True) if use_refantinotch: rawref = raw.drop_channels(droplist, copy=True) freqlast = np.min([5.01 * refnotch, 0.5 * raw.info['sfreq']]) fltref.notch_filter(np.arange(refnotch, freqlast, refnotch), picks=np.array(xrange(nref)), method='iir') fltref._data = (rawref._data - fltref._data) else: fltref.filter(refhp, reflp, picks=np.array(xrange(nref)), method='iir') tc1 = time.clock() tw1 = time.time() if verbose: print ">>> filtering ref-chans took %.1f ms (%.2f s walltime)" % ( 1000. * (tc1 - tct), (tw1 - twt)) if verbose: print "########## Calculating sig-ref/ref-ref-channel covariances:" # Calculate sig-ref/ref-ref-channel covariance: # (there is no need to calc inter-signal-chan cov, # but there seems to be no appropriat fct available) # Here we copy the idea from compute_raw_data_covariance() # and truncate it as appropriate. tct = time.clock() twt = time.time() # The following reject and infosig entries are only # used in _is_good-calls. # _is_good() from mne-0.9.git-py2.7.egg/mne/epochs.py seems to # ignore ref-channels (not covered by dict) and checks individual # data segments - artifacts across a buffer boundary are not found. #--- !!! FB put to kwargs #reject = dict(grad=4000e-13, # T / m (gradiometers) # mag=4e-12, # T (magnetometers) # eeg=40e-6, # uV (EEG channels) # eog=250e-6) # uV (EOG channels) infosig = copy.copy(raw.info) infosig['chs'] = [raw.info['chs'][k] for k in sigpick] infosig['ch_names'] = [raw.info['ch_names'][k] for k in sigpick] infosig['nchan'] = len(sigpick) idx_by_typesig = channel_indices_by_type(infosig) # Read data in chunks: tstep = 0.2 itstep = int(ceil(tstep * raw.info['sfreq'])) sigmean = 0 refmean = 0 sscovdata = 0 srcovdata = 0 rrcovdata = 0 n_samples = 0 for first in range(itmin, itmax, itstep): last = first + itstep if last >= itmax: last = itmax raw_segmentsig, times = raw[sigpick, first:last] if use_reffilter: raw_segmentref, times = fltref[:, first:last] else: raw_segmentref, times = raw[refpick, first:last] if not exclude_artifacts or \ _is_good(raw_segmentsig, infosig['ch_names'], idx_by_typesig, reject, flat=None, ignore_chs=raw.info['bads']): sigmean += raw_segmentsig.sum(axis=1) refmean += raw_segmentref.sum(axis=1) sscovdata += (raw_segmentsig * raw_segmentsig).sum(axis=1) srcovdata += np.dot(raw_segmentsig, raw_segmentref.T) rrcovdata += np.dot(raw_segmentref, raw_segmentref.T) n_samples += raw_segmentsig.shape[1] else: logger.info("Artefact detected in [%d, %d]" % (first, last)) if n_samples <= 1: raise ValueError('Too few samples to calculate weights') sigmean /= n_samples refmean /= n_samples sscovdata -= n_samples * sigmean[:] * sigmean[:] sscovdata /= (n_samples - 1) srcovdata -= n_samples * sigmean[:, None] * refmean[None, :] srcovdata /= (n_samples - 1) rrcovdata -= n_samples * refmean[:, None] * refmean[None, :] rrcovdata /= (n_samples - 1) sscovinit = np.copy(sscovdata) if verbose: print ">>> Normalize srcov..." rrslope = copy.copy(rrcovdata) for iref in xrange(nref): dtmp = rrcovdata[iref, iref] if dtmp > TINY: srcovdata[:, iref] /= dtmp rrslope[:, iref] /= dtmp else: srcovdata[:, iref] = 0. rrslope[:, iref] = 0. if verbose: print ">>> Number of samples used : %d" % n_samples tc1 = time.clock() tw1 = time.time() print ">>> sigrefchn covar-calc took %.1f ms (%.2f s walltime)" % ( 1000. * (tc1 - tct), (tw1 - twt)) if checkresults: if verbose: print "########## Calculated initial signal channel covariance:" # Calculate initial signal channel covariance: # (only used as quality measure) print ">>> initl rt(avg sig pwr) = %12.5e" % np.sqrt( np.mean(sscovdata)) for i in xrange(5): print ">>> initl signal-rms[%3d] = %12.5e" % ( i, np.sqrt(sscovdata.flatten()[i])) print ">>>" U, s, V = np.linalg.svd(rrslope, full_matrices=True) if verbose: print ">>> singular values:" print s print ">>> Applying cutoff for smallest SVs:" dtmp = s.max() * SVD_RELCUTOFF s *= (abs(s) >= dtmp) sinv = [1. / s[k] if s[k] != 0. else 0. for k in xrange(nref)] if verbose: print ">>> singular values (after cutoff):" print s stat = np.allclose(rrslope, np.dot(U, np.dot(np.diag(s), V))) if verbose: print ">>> Testing svd-result: %s" % stat if not stat: print " (Maybe due to SV-cutoff?)" # Solve for inverse coefficients: # Set RRinv.tr=U diag(sinv) V RRinv = np.transpose(np.dot(U, np.dot(np.diag(sinv), V))) if checkresults: stat = np.allclose(np.identity(nref), np.dot(RRinv, rrslope)) if stat: if verbose: print ">>> Testing RRinv-result (should be unit-matrix): ok" else: print ">>> Testing RRinv-result (should be unit-matrix): failed" print np.transpose(np.dot(RRinv, rrslope)) print ">>>" if verbose: print "########## Calc weight matrix..." # weights-matrix will be somewhat larger than necessary, # (to simplify indexing in compensation loop): weights = np.zeros((raw._data.shape[0], nref)) for isig in xrange(nsig): for iref in xrange(nref): weights[sigpick[isig], iref] = np.dot(srcovdata[isig, :], RRinv[:, iref]) if verbose: print "########## Compensating signal channels:" if complementary_signal: print ">>> Caveat: REPLACING signal by compensation signal" tct = time.clock() twt = time.time() # Work on entire data stream: for isl in xrange(raw._data.shape[1]): slice = np.take(raw._data, [isl], axis=1) if use_reffilter: refslice = np.take(fltref._data, [isl], axis=1) refarr = refslice[:].flatten() - refmean # refarr = fltres[:,isl]-refmean else: refarr = slice[refpick].flatten() - refmean subrefarr = np.dot(weights[:], refarr) if not complementary_signal: raw._data[:, isl] -= subrefarr else: raw._data[:, isl] = subrefarr if (isl % 10000 == 0) and verbose: print "\rProcessed slice %6d" % isl if verbose: print "\nDone." tc1 = time.clock() tw1 = time.time() print ">>> compensation loop took %.1f ms (%.2f s walltime)" % ( 1000. * (tc1 - tct), (tw1 - twt)) if checkresults: if verbose: print "########## Calculating final signal channel covariance:" # Calculate final signal channel covariance: # (only used as quality measure) tct = time.clock() twt = time.time() sigmean = 0 sscovdata = 0 n_samples = 0 for first in range(itmin, itmax, itstep): last = first + itstep if last >= itmax: last = itmax raw_segmentsig, times = raw[sigpick, first:last] # Artifacts found here will probably differ from pre-noisered artifacts! if not exclude_artifacts or \ _is_good(raw_segmentsig, infosig['ch_names'], idx_by_typesig, reject, flat=None, ignore_chs=raw.info['bads']): sigmean += raw_segmentsig.sum(axis=1) sscovdata += (raw_segmentsig * raw_segmentsig).sum(axis=1) n_samples += raw_segmentsig.shape[1] sigmean /= n_samples sscovdata -= n_samples * sigmean[:] * sigmean[:] sscovdata /= (n_samples - 1) if verbose: print ">>> no channel got worse: ", np.all( np.less_equal(sscovdata, sscovinit)) print ">>> final rt(avg sig pwr) = %12.5e" % np.sqrt( np.mean(sscovdata)) for i in xrange(5): print ">>> final signal-rms[%3d] = %12.5e" % ( i, np.sqrt(sscovdata.flatten()[i])) tc1 = time.clock() tw1 = time.time() print ">>> signal covar-calc took %.1f ms (%.2f s walltime)" % ( 1000. * (tc1 - tct), (tw1 - twt)) print ">>>" #--- fb update 21.07.2015 fname_out = jumeg_base.get_fif_name(raw=raw, postfix=fif_postfix, extention=fif_extention) if save: jumeg_base.apply_save_mne_data(raw, fname=fname_out, overwrite=True) tc1 = time.clock() tw1 = time.time() if verbose: print ">>> Total run took %.1f ms (%.2f s walltime)" % (1000. * (tc1 - tc0), (tw1 - tw0)) return raw, fname_out
def noise_reducer_4raw_data(fname_raw,raw=None,signals=[],noiseref=[],detrending=None, tmin=None,tmax=None,reflp=None,refhp=None,refnotch=None, exclude_artifacts=True,checkresults=True, fif_extention="-raw.fif",fif_postfix="nr", reject={'grad':4000e-13,'mag':4e-12,'eeg':40e-6,'eog':250e-6}, complementary_signal=False,fnout=None,verbose=False,save=True): """Apply noise reduction to signal channels using reference channels. !!! ONLY ONE RAW Obj Interface Version FB !!! Parameters ---------- fname_raw : rawfile name raw : fif raw object signals : list of string List of channels to compensate using noiseref. If empty use the meg signal channels. noiseref : list of string | str List of channels to use as noise reference. If empty use the magnetic reference channsls (default). signals and noiseref may contain regexp, which are resolved using mne.pick_channels_regexp(). All other channels are copied. tmin : lower latency bound for weight-calc [start of trace] tmax : upper latency bound for weight-calc [ end of trace] Weights are calc'd for (tmin,tmax), but applied to entire data set refhp : high-pass frequency for reference signal filter [None] reflp : low-pass frequency for reference signal filter [None] reflp < refhp: band-stop filter reflp > refhp: band-pass filter reflp is not None, refhp is None: low-pass filter reflp is None, refhp is not None: high-pass filter refnotch : (base) notch frequency for reference signal filter [None] use raw(ref)-notched(ref) as reference signal exclude_artifacts: filter signal-channels thru _is_good() [True] (parameters are at present hard-coded!) complementary_signal : replaced signal by traces that would be subtracted [False] (can be useful for debugging) checkresults : boolean to control internal checks and overall success [True] reject = dict for rejection threshold units: grad: T / m (gradiometers) mag: T (magnetometers) eeg/eog: uV (EEG channels) default=>{'grad':4000e-13,'mag':4e-12,'eeg':40e-6,'eog':250e-6} save : save data to fif file Outputfile: ------- <wawa>,nr-raw.fif for input <wawa>-raw.fif Returns ------- TBD Bugs ---- - artifact checking is incomplete (and with arb. window of tstep=0.2s) - no accounting of channels used as signal/reference - non existing input file handled ungracefully """ tc0 = time.clock() tw0 = time.time() if type(complementary_signal) != bool: raise ValueError("Argument complementary_signal must be of type bool") raw,fname_raw = jumeg_base.get_raw_obj(fname_raw,raw=raw) if detrending: raw = perform_detrending(None,raw=raw, save=False) tc1 = time.clock() tw1 = time.time() if verbose: print ">>> loading raw data took %.1f ms (%.2f s walltime)" % (1000. * (tc1 - tc0), (tw1 - tw0)) # Time window selection # weights are calc'd based on [tmin,tmax], but applied to the entire data set. # tstep is used in artifact detection # tmin,tmax variables must not be changed here! if tmin is None: itmin = 0 else: itmin = int(floor(tmin * raw.info['sfreq'])) if tmax is None: itmax = raw.last_samp else: itmax = int(ceil(tmax * raw.info['sfreq'])) if itmax - itmin < 2: raise ValueError("Time-window for noise compensation empty or too short") if verbose: print ">>> Set time-range to [%7.3f,%7.3f]" % \ (raw.index_as_time(itmin)[0], raw.index_as_time(itmax)[0]) if signals is None or len(signals) == 0: sigpick = jumeg_base.pick_meg_nobads(raw) else: sigpick = channel_indices_from_list(raw.info['ch_names'][:], signals, raw.info.get('bads')) nsig = len(sigpick) if nsig == 0: raise ValueError("No channel selected for noise compensation") if noiseref is None or len(noiseref) == 0: # References are not limited to 4D ref-chans, but can be anything, # incl. ECG or powerline monitor. if verbose: print ">>> Using all refchans." refexclude = "bads" refpick = jumeg_base.pick_ref_nobads(raw) else: refpick = channel_indices_from_list(raw.info['ch_names'][:], noiseref, raw.info.get('bads')) nref = len(refpick) if nref == 0: raise ValueError("No channel selected as noise reference") if verbose: print ">>> sigpick: %3d chans, refpick: %3d chans" % (nsig, nref) if reflp is None and refhp is None and refnotch is None: use_reffilter = False use_refantinotch = False else: use_reffilter = True if verbose: print "########## Filter reference channels:" use_refantinotch = False if refnotch is not None: if reflp is None and reflp is None: use_refantinotch = True freqlast = np.min([5.01 * refnotch, 0.5 * raw.info['sfreq']]) if verbose: print ">>> notches at freq %.1f and harmonics below %.1f" % (refnotch, freqlast) else: raise ValueError("Cannot specify notch- and high-/low-pass" "reference filter together") else: if verbose: if reflp is not None: print ">>> low-pass with cutoff-freq %.1f" % reflp if refhp is not None: print ">>> high-pass with cutoff-freq %.1f" % refhp # Adapt followg drop-chans cmd to use 'all-but-refpick' droplist = [raw.info['ch_names'][k] for k in xrange(raw.info['nchan']) if not k in refpick] tct = time.clock() twt = time.time() fltref = raw.drop_channels(droplist, copy=True) if use_refantinotch: rawref = raw.drop_channels(droplist, copy=True) freqlast = np.min([5.01 * refnotch, 0.5 * raw.info['sfreq']]) fltref.notch_filter(np.arange(refnotch, freqlast, refnotch), picks=np.array(xrange(nref)), method='iir') fltref._data = (rawref._data - fltref._data) else: fltref.filter(refhp, reflp, picks=np.array(xrange(nref)), method='iir') tc1 = time.clock() tw1 = time.time() if verbose: print ">>> filtering ref-chans took %.1f ms (%.2f s walltime)" % (1000. * (tc1 - tct), (tw1 - twt)) if verbose: print "########## Calculating sig-ref/ref-ref-channel covariances:" # Calculate sig-ref/ref-ref-channel covariance: # (there is no need to calc inter-signal-chan cov, # but there seems to be no appropriat fct available) # Here we copy the idea from compute_raw_data_covariance() # and truncate it as appropriate. tct = time.clock() twt = time.time() # The following reject and infosig entries are only # used in _is_good-calls. # _is_good() from mne-0.9.git-py2.7.egg/mne/epochs.py seems to # ignore ref-channels (not covered by dict) and checks individual # data segments - artifacts across a buffer boundary are not found. #--- !!! FB put to kwargs #reject = dict(grad=4000e-13, # T / m (gradiometers) # mag=4e-12, # T (magnetometers) # eeg=40e-6, # uV (EEG channels) # eog=250e-6) # uV (EOG channels) infosig = copy.copy(raw.info) infosig['chs'] = [raw.info['chs'][k] for k in sigpick] infosig['ch_names'] = [raw.info['ch_names'][k] for k in sigpick] infosig['nchan'] = len(sigpick) idx_by_typesig = channel_indices_by_type(infosig) # Read data in chunks: tstep = 0.2 itstep = int(ceil(tstep * raw.info['sfreq'])) sigmean = 0 refmean = 0 sscovdata = 0 srcovdata = 0 rrcovdata = 0 n_samples = 0 for first in range(itmin, itmax, itstep): last = first + itstep if last >= itmax: last = itmax raw_segmentsig, times = raw[sigpick, first:last] if use_reffilter: raw_segmentref, times = fltref[:, first:last] else: raw_segmentref, times = raw[refpick, first:last] if not exclude_artifacts or \ _is_good(raw_segmentsig, infosig['ch_names'], idx_by_typesig, reject, flat=None, ignore_chs=raw.info['bads']): sigmean += raw_segmentsig.sum(axis=1) refmean += raw_segmentref.sum(axis=1) sscovdata += (raw_segmentsig * raw_segmentsig).sum(axis=1) srcovdata += np.dot(raw_segmentsig, raw_segmentref.T) rrcovdata += np.dot(raw_segmentref, raw_segmentref.T) n_samples += raw_segmentsig.shape[1] else: logger.info("Artefact detected in [%d, %d]" % (first, last)) if n_samples <= 1: raise ValueError('Too few samples to calculate weights') sigmean /= n_samples refmean /= n_samples sscovdata -= n_samples * sigmean[:] * sigmean[:] sscovdata /= (n_samples - 1) srcovdata -= n_samples * sigmean[:, None] * refmean[None, :] srcovdata /= (n_samples - 1) rrcovdata -= n_samples * refmean[:, None] * refmean[None, :] rrcovdata /= (n_samples - 1) sscovinit = np.copy(sscovdata) if verbose: print ">>> Normalize srcov..." rrslope = copy.copy(rrcovdata) for iref in xrange(nref): dtmp = rrcovdata[iref, iref] if dtmp > TINY: srcovdata[:, iref] /= dtmp rrslope[:, iref] /= dtmp else: srcovdata[:, iref] = 0. rrslope[:, iref] = 0. if verbose: print ">>> Number of samples used : %d" % n_samples tc1 = time.clock() tw1 = time.time() print ">>> sigrefchn covar-calc took %.1f ms (%.2f s walltime)" % (1000. * (tc1 - tct), (tw1 - twt)) if checkresults: if verbose: print "########## Calculated initial signal channel covariance:" # Calculate initial signal channel covariance: # (only used as quality measure) print ">>> initl rt(avg sig pwr) = %12.5e" % np.sqrt(np.mean(sscovdata)) for i in xrange(5): print ">>> initl signal-rms[%3d] = %12.5e" % (i, np.sqrt(sscovdata.flatten()[i])) print ">>>" U, s, V = np.linalg.svd(rrslope, full_matrices=True) if verbose: print ">>> singular values:" print s print ">>> Applying cutoff for smallest SVs:" dtmp = s.max() * SVD_RELCUTOFF s *= (abs(s) >= dtmp) sinv = [1. / s[k] if s[k] != 0. else 0. for k in xrange(nref)] if verbose: print ">>> singular values (after cutoff):" print s stat = np.allclose(rrslope, np.dot(U, np.dot(np.diag(s), V))) if verbose: print ">>> Testing svd-result: %s" % stat if not stat: print " (Maybe due to SV-cutoff?)" # Solve for inverse coefficients: # Set RRinv.tr=U diag(sinv) V RRinv = np.transpose(np.dot(U, np.dot(np.diag(sinv), V))) if checkresults: stat = np.allclose(np.identity(nref), np.dot(RRinv, rrslope)) if stat: if verbose: print ">>> Testing RRinv-result (should be unit-matrix): ok" else: print ">>> Testing RRinv-result (should be unit-matrix): failed" print np.transpose(np.dot(RRinv, rrslope)) print ">>>" if verbose: print "########## Calc weight matrix..." # weights-matrix will be somewhat larger than necessary, # (to simplify indexing in compensation loop): weights = np.zeros((raw._data.shape[0], nref)) for isig in xrange(nsig): for iref in xrange(nref): weights[sigpick[isig],iref] = np.dot(srcovdata[isig,:], RRinv[:,iref]) if verbose: print "########## Compensating signal channels:" if complementary_signal: print ">>> Caveat: REPLACING signal by compensation signal" tct = time.clock() twt = time.time() # Work on entire data stream: for isl in xrange(raw._data.shape[1]): slice = np.take(raw._data, [isl], axis=1) if use_reffilter: refslice = np.take(fltref._data, [isl], axis=1) refarr = refslice[:].flatten() - refmean # refarr = fltres[:,isl]-refmean else: refarr = slice[refpick].flatten() - refmean subrefarr = np.dot(weights[:], refarr) if not complementary_signal: raw._data[:, isl] -= subrefarr else: raw._data[:, isl] = subrefarr if (isl % 10000 == 0) and verbose: print "\rProcessed slice %6d" % isl if verbose: print "\nDone." tc1 = time.clock() tw1 = time.time() print ">>> compensation loop took %.1f ms (%.2f s walltime)" % (1000. * (tc1 - tct), (tw1 - twt)) if checkresults: if verbose: print "########## Calculating final signal channel covariance:" # Calculate final signal channel covariance: # (only used as quality measure) tct = time.clock() twt = time.time() sigmean = 0 sscovdata = 0 n_samples = 0 for first in range(itmin, itmax, itstep): last = first + itstep if last >= itmax: last = itmax raw_segmentsig, times = raw[sigpick, first:last] # Artifacts found here will probably differ from pre-noisered artifacts! if not exclude_artifacts or \ _is_good(raw_segmentsig, infosig['ch_names'], idx_by_typesig, reject, flat=None, ignore_chs=raw.info['bads']): sigmean += raw_segmentsig.sum(axis=1) sscovdata += (raw_segmentsig * raw_segmentsig).sum(axis=1) n_samples += raw_segmentsig.shape[1] sigmean /= n_samples sscovdata -= n_samples * sigmean[:] * sigmean[:] sscovdata /= (n_samples - 1) if verbose: print ">>> no channel got worse: ", np.all(np.less_equal(sscovdata, sscovinit)) print ">>> final rt(avg sig pwr) = %12.5e" % np.sqrt(np.mean(sscovdata)) for i in xrange(5): print ">>> final signal-rms[%3d] = %12.5e" % (i, np.sqrt(sscovdata.flatten()[i])) tc1 = time.clock() tw1 = time.time() print ">>> signal covar-calc took %.1f ms (%.2f s walltime)" % (1000. * (tc1 - tct), (tw1 - twt)) print ">>>" #--- fb update 21.07.2015 fname_out = jumeg_base.get_fif_name(raw=raw,postfix=fif_postfix,extention=fif_extention) if save: jumeg_base.apply_save_mne_data(raw,fname=fname_out,overwrite=True) tc1 = time.clock() tw1 = time.time() if verbose: print ">>> Total run took %.1f ms (%.2f s walltime)" % (1000. * (tc1 - tc0), (tw1 - tw0)) return raw,fname_out