neuromodulation / py_neuromodulation

Real-time analysis of intracranial neurophysiology recordings.
https://neuromodulation.github.io/py_neuromodulation/
MIT License
46 stars 11 forks source link

Check in settings.py sampling frequency filter relation #38

Closed timonmerk closed 2 years ago

timonmerk commented 3 years ago

For too low sampling frequencies, the current notch filter will fail. Design filter in settings.py?

Settings.py should be written as class s.t. settings.json, df_M1 and such code isn't part of start_BIDS / start_LSL anymore.

    fs = int(np.ceil(raw_arr.info["sfreq"]))
    line_noise = int(raw_arr.info["line_freq"])

    # read df_M1 / create M1 if None specified
    df_M1 = pd.read_csv(PATH_M1, sep="\t") \
        if PATH_M1 is not None and os.path.isfile(PATH_M1) \
        else define_M1.set_M1(raw_arr.ch_names, raw_arr.get_channel_types())
    ch_names = list(df_M1['name'])
    refs = df_M1['rereference']
    to_ref_idx = np.array(df_M1[(df_M1['used'] == 1)].index)
    cortex_idx = np.where(df_M1.type == 'ecog')[0]
    subcortex_idx = np.array(df_M1[(df_M1["type"] == 'seeg') | (df_M1['type'] == 'dbs')
                                   | (df_M1['type'] == 'lfp')].index)
    ref_here = rereference.RT_rereference(ch_names, refs, to_ref_idx,
                                          cortex_idx, subcortex_idx,
                                          split_data=False)
timonmerk commented 3 years ago

@richardkoehler I am referencing from the PR to this issue here. It's basically not just the notch filter, but also the filter in generell. For the notch filter it might be easy to fix, since we initialize the filter currently in this manner in features.py

data = notch_filter(x=data, Fs=self.fs, trans_bandwidth=15,
                    freqs=arange(self.line_noise, 3*self.line_noise,
                                 self.line_noise),
                    fir_design='firwin', verbose=False,
                    notch_widths=3, filter_length=data.shape[1]-1)

So at least the "3*self.line_noise" needs to be adapted wrt to the used sampling frequency. Maybe the notch / bandpass filter could be defined even in settings.py? In this way we could pass them to features.py instantiation, and the correct filters could be already precalculated.

timonmerk commented 3 years ago

Something more tricky is probably the 'trans_bandwidth', since this heavily depends on the 'filter_length'. Higher 'filter_length' will allow for "sharper" filter functions. So it might be necessary to iteratively increase this parameter until the filter calculation is possible, or a more advanced way is possbile :sweat_smile:

I think this issue comes up mainly with testing modules using openBCI though, since here fs is pretty low

timonmerk commented 2 years ago

Notch filter params are set in relation to fs now