Пример #1
0
def test_gaussian_kernel():
    """Test the gaussian kernel.
    """
    ker = gaussian(1111, 200, 50, 10)
    assert_allclose(np.linalg.norm(ker), 1)
    assert_equal(ker >= 0., True)
Пример #2
0
def high_gamma_estimation(block_path, bands_vals, new_file=''):
    """
    Takes preprocessed LFP data and calculates High-Gamma power from the
    averaged power of standard Hilbert transform on 70~150 Hz bands.

    Parameters
    ----------
    block_path : str
        subject file path
    bands_vals : [2,nBands] numpy array with Gaussian filter parameters, where:
        bands_vals[0,:] = filter centers [Hz]
        bands_vals[1,:] = filter sigmas [Hz]
    new_file : str
        if this argument is of form 'path/to/new_file.nwb', High Gamma power
        will be saved in a new file. If it is an empty string, '', High Gamma
        power will be saved in the current NWB file.

    Returns
    -------
    Saves High Gamma power (TimeSeries) in the current or new NWB file.
    Only if container for this data do not exist in the file.
    """

    # Get filter parameters
    band_param_0 = bands_vals[0, :]
    band_param_1 = bands_vals[1, :]

    with NWBHDF5IO(block_path, 'r+', load_namespaces=True) as io:
        nwb = io.read()
        lfp = nwb.processing['ecephys'].data_interfaces[
            'LFP'].electrical_series['preprocessed']
        rate = lfp.rate

        nBands = len(band_param_0)
        nSamples = lfp.data.shape[0]
        nChannels = lfp.data.shape[1]
        Xp = np.zeros(
            (nBands, nChannels, nSamples))  # power (nBands,nChannels,nSamples)

        # Apply Hilbert transform ---------------------------------------------
        print('Running High Gamma estimation...')
        start = time.time()
        for ch in np.arange(nChannels):
            Xch = lfp.data[:,
                           ch] * 1e6  # 1e6 scaling helps with numerical accuracy
            Xch = Xch.reshape(1, -1)
            Xch = Xch.astype('float32')  # signal (nChannels,nSamples)
            X_fft_h = None
            for ii, (bp0, bp1) in enumerate(zip(band_param_0, band_param_1)):
                kernel = gaussian(Xch.shape[-1], rate, bp0, bp1)
                X_analytic, X_fft_h = hilbert_transform(Xch,
                                                        rate,
                                                        kernel,
                                                        phase=None,
                                                        X_fft_h=X_fft_h)
                Xp[ii, ch, :] = abs(X_analytic).astype('float32')
        print(
            'High Gamma estimation finished in {} seconds'.format(time.time() -
                                                                  start))

        # data: (ndarray) dims: num_times * num_channels * num_bands
        Xp = np.swapaxes(Xp, 0, 2)
        HG = np.mean(Xp, 2)  # average of high gamma bands

        # Storage of High Gamma on NWB file -----------------------------
        if new_file == '' or new_file is None:  # on current file
            # make electrodes table
            nElecs = HG.shape[1]
            ecephys_module = nwb.processing['ecephys']

            # first check for a table among the file's data_interfaces
            ####
            if lfp.electrodes.table.name in ecephys_module.data_interfaces:
                LFP_dynamic_table = ecephys_module.data_interfaces[
                    lfp.electrodes.table.name]
            else:
                # othewise use the electrodes as the table
                LFP_dynamic_table = nwb.electrodes
            ####
            elecs_region = LFP_dynamic_table.create_region(
                name='electrodes',
                region=[i for i in range(nChannels)],
                description='all electrodes')
            hg = ElectricalSeries(name='high_gamma',
                                  data=HG,
                                  electrodes=elecs_region,
                                  rate=rate,
                                  description='')

            ecephys_module.add_data_interface(hg)
            io.write(nwb)
            print('High Gamma power saved in ' + block_path)
        else:  # on new file
            with NWBHDF5IO(new_file, 'r+', load_namespaces=True) as io_new:
                nwb_new = io_new.read()
                # make electrodes table
                nElecs = HG.shape[1]
                elecs_region = nwb_new.electrodes.create_region(
                    name='electrodes',
                    region=np.arange(nElecs).tolist(),
                    description='all electrodes')
                hg = ElectricalSeries(name='high_gamma',
                                      data=HG,
                                      electrodes=elecs_region,
                                      rate=rate,
                                      description='')

                try:  # if ecephys module already exists
                    ecephys_module = nwb_new.processing['ecephys']
                except:  # creates ecephys ProcessingModule
                    ecephys_module = ProcessingModule(
                        name='ecephys',
                        description='Extracellular electrophysiology data.')
                    nwb_new.add_processing_module(ecephys_module)

                ecephys_module.add_data_interface(hg)
                io_new.write(nwb_new)
                print('High Gamma power saved in ' + new_file)
Пример #3
0
    def test_hilbert_return(self):
        filters = [
            gaussian(50, self.rate, 10, 2),
            hamming(50, self.rate, 10, 15)
        ]
        Xh = hilbert_transform(self.X, self.rate, filters)

        Xh_expected = (np.array(
            [
                [
                    -0.21311015 - 0.0607549j, 0.19600701 - 0.01539358j,
                    -0.173067 + 0.05698152j, 0.16533213 - 0.11073435j,
                    -0.11528449 + 0.19558509j, -0.01099088 - 0.23956958j,
                    0.14327258 + 0.17653984j, -0.18458968 - 0.04880616j,
                    0.13415315 - 0.03647032j, -0.0869473 + 0.04084354j,
                    0.10334343 - 0.03818917j, -0.12906154 + 0.10043456j,
                    0.08385944 - 0.19477458j, 0.03056594 + 0.24082505j,
                    -0.15400577 - 0.2042584j, 0.22998364 + 0.10362084j,
                    -0.23235176 + 0.0114163j, 0.18106783 - 0.09160866j,
                    -0.11846912 + 0.12803714j, 0.0616374 - 0.14137947j,
                    -0.00263204 + 0.13730891j, -0.05106666 - 0.10123634j,
                    0.06800086 + 0.04061233j, -0.04404788 + 0.00171742j,
                    0.0226942 - 0.0115417j, -0.0187925 + 0.03051893j,
                    -0.01429313 - 0.07107013j, 0.09650135 + 0.07795065j,
                    -0.174921 - 0.01024875j, 0.18714607 - 0.10299498j,
                    -0.12381878 + 0.19594172j, 0.0300773 - 0.22737868j,
                    0.04435296 + 0.21050902j, -0.08900898 - 0.18207646j,
                    0.12224477 + 0.15960843j, -0.15896489 - 0.13540482j,
                    0.19442573 + 0.09691784j, -0.21726567 - 0.04694222j,
                    0.22820716 - 0.00885319j, -0.22209987 + 0.07472441j,
                    0.18310959 - 0.13794065j, -0.12027016 + 0.17057613j,
                    0.06293843 - 0.16911559j, -0.02503065 + 0.15016524j,
                    0.01000077 - 0.12699406j, -0.0166137 + 0.12012645j,
                    0.01741438 - 0.1460833j, 0.02050994 + 0.18394571j,
                    -0.09605629 - 0.19316342j, 0.17592968 + 0.14807635j
                ],
                [
                    0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
                    0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
                    0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
                    0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
                    0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
                    0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
                    0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
                    0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j, 0. + 0.j,
                    0. + 0.j, 0. + 0.j
                ]
            ]),
                       np.array([[
                           12.66153466 + 0.j, -8.52937982 + 2.82208427j,
                           14.7942873 + 7.52162635j, 11.10045364 + 3.52566249j,
                           -4.45306874 + 1.51630448j,
                           -15.9713513 + 6.17519069j,
                           -12.79444213 - 3.10589728j,
                           7.48901625 + 4.52892871j,
                           -26.31533498 - 14.97259445j,
                           -13.34218938 - 5.91763703j,
                           -6.37207362 - 7.78666016j, 9.73243576 + 0.81983001j,
                           -7.31044034 - 10.82940129j, -13.95317074 +
                           6.17574407j, -13.04640635 - 4.2499415j,
                           -8.50946101 + 23.85947587j,
                           3.63491644 + 8.31427148j, 10.54954233 + 5.55684696j,
                           -7.73593253 - 7.06994243j,
                           -3.63069263 - 4.01064809j,
                           -0.58244679 - 0.45476267j, 0.3190497 - 17.87031979j,
                           -16.3983279 + 10.94541315j, -15.21443532 +
                           3.27680235j, 0.55694424 - 9.41396278j, 0. + 0.j,
                           0. + 0.j, 0. - 0.j, 0. - 0.j, 0. + 0.j, -0. + 0.j,
                           -0. + 0.j, -0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 0.j,
                           -0. + 0.j, 0. - 0.j, -0. + 0.j, 0. + 0.j, -0. + 0.j,
                           -0. + 0.j, -0. + 0.j, 0. + 0.j, -0. + 0.j, 0. - 0.j,
                           0. - 0.j, 0. + 0.j, 0. + 0.j, 0. - 0.j
                       ]]))

        np.testing.assert_almost_equal(Xh[0], Xh_expected[0])
        np.testing.assert_almost_equal(Xh[1], Xh_expected[1])

        Xh = hilbert_transform(self.X, self.rate)

        Xh_expected = (
            np.array(
                [
                    -2.06641947 - 0.01287173j, 0.51412168 - 1.48267793j,
                    1.09878248 - 0.2770345j, 1.51753214 + 1.04348296j,
                    -1.17911981 + 1.40558571j, 0.14574649 - 1.35839109j,
                    1.24439672 + 1.55083418j, -1.71511502 + 0.64355861j,
                    0.08780536 - 1.05022613j, 0.68712687 + 0.47911231j,
                    -0.49986941 + 1.32336045j, -2.4298324 - 0.32441863j,
                    0.02200754 - 2.43445411j, 0.53061521 - 0.23437869j,
                    0.25228739 - 1.73350628j, 2.02750313 + 0.27984872j,
                    -0.62058197 + 0.45810456j, 0.55911732 - 0.78389594j,
                    0.11008321 - 0.06264994j, 0.72111797 - 0.74545203j,
                    0.38719571 + 0.13653827j, 0.59216716 - 1.05822436j,
                    1.88259492 + 0.22982255j, 0.45529182 + 1.40341331j,
                    -0.87420952 + 0.45050791j, -0.46801216 - 1.17055015j,
                    1.41085796 - 1.23975681j, 1.54165835 + 0.78468877j,
                    0.01297562 + 0.11350984j, 1.75234722 + 0.23771566j,
                    -0.32490902 + 1.84850866j, -0.40531575 - 0.56893904j,
                    0.2552225 + 0.44197517j, -0.01341803 - 0.68464856j,
                    0.8537156 + 0.27623658j, 0.43782839 - 0.38555419j,
                    1.48900852 + 1.13057857j, -0.60367646 + 1.05556027j,
                    -0.04352692 + 0.77890928j, -1.61591018 - 0.01930377j,
                    0.62662236 - 1.11621127j, -0.04878076 + 0.60438919j,
                    -0.07048588 - 0.4217956j, -0.52055125 + 0.12783525j,
                    -0.3065798 - 1.47275369j, 0.87571683 - 1.19296222j,
                    2.02126317 - 0.75806081j, 1.38610296 + 1.35508274j,
                    0.56164995 + 0.43484911j, 0.40738592 + 1.99470883j
                ]),
            np.array([[
                12.66153466 + 0.j,
                -8.52937982 + 2.82208427j, 14.7942873 + 7.52162635j,
                11.10045364 + 3.52566249j, -4.45306874 + 1.51630448j,
                -15.9713513 + 6.17519069j, -12.79444213 - 3.10589728j,
                7.48901625 + 4.52892871j, -26.31533498 -
                14.97259445j, -13.34218938 - 5.91763703j,
                -6.37207362 - 7.78666016j, 9.73243576 + 0.81983001j,
                -7.31044034 - 10.82940129j, -13.95317074 +
                6.17574407j, -13.04640635 - 4.2499415j,
                -8.50946101 + 23.85947587j, 3.63491644 + 8.31427148j,
                10.54954233 + 5.55684696j, -7.73593253 - 7.06994243j,
                -3.63069263 - 4.01064809j, -0.58244679 - 0.45476267j,
                0.3190497 - 17.87031979j, -16.3983279 + 10.94541315j,
                -15.21443532 + 3.27680235j, 0.55694424 - 9.41396278j, 0. + 0.j,
                0. + 0.j, 0. - 0.j, 0. - 0.j, 0. + 0.j, -0. + 0.j, -0. + 0.j,
                -0. + 0.j, 0. + 0.j, 0. + 0.j, 0. - 0.j, -0. + 0.j, 0. - 0.j,
                -0. + 0.j, 0. + 0.j, -0. + 0.j, -0. + 0.j, -0. + 0.j, 0. + 0.j,
                -0. + 0.j, 0. - 0.j, 0. - 0.j, 0. + 0.j, 0. + 0.j, 0. - 0.j
            ]]))

        np.testing.assert_almost_equal(Xh[0], Xh_expected[0])
        np.testing.assert_almost_equal(Xh[1], Xh_expected[1])
Пример #4
0
def spectral_decomposition(block_path, bands_vals):
    """
    Takes preprocessed LFP data and does the standard Hilbert transform on
    different bands. Takes about 20 minutes to run on 1 10-min block.

    Parameters
    ----------
    block_path : str
        subject file path
    bands_vals : [2,nBands] numpy array with Gaussian filter parameters, where:
        bands_vals[0,:] = filter centers [Hz]
        bands_vals[1,:] = filter sigmas [Hz]

    Returns
    -------
    Saves spectral power (DecompositionSeries) in the current NWB file.
    Only if container for this data do not exist in the file.
    """

    # Get filter parameters
    band_param_0 = bands_vals[0, :]
    band_param_1 = bands_vals[1, :]

    with NWBHDF5IO(block_path, 'r+', load_namespaces=True) as io:
        nwb = io.read()
        lfp = nwb.processing['ecephys'].data_interfaces[
            'LFP'].electrical_series['preprocessed']
        rate = lfp.rate

        nBands = len(band_param_0)
        nSamples = lfp.data.shape[0]
        nChannels = lfp.data.shape[1]
        Xp = np.zeros(
            (nBands, nChannels, nSamples))  # power (nBands,nChannels,nSamples)

        # Apply Hilbert transform ---------------------------------------------
        print('Running Spectral Decomposition...')
        start = time.time()
        for ch in np.arange(nChannels):
            Xch = lfp.data[:,
                           ch] * 1e6  # 1e6 scaling helps with numerical accuracy
            Xch = Xch.reshape(1, -1)
            Xch = Xch.astype('float32')  # signal (nChannels,nSamples)
            X_fft_h = None
            for ii, (bp0, bp1) in enumerate(zip(band_param_0, band_param_1)):
                kernel = gaussian(Xch.shape[-1], rate, bp0, bp1)
                X_analytic, X_fft_h = hilbert_transform(Xch,
                                                        rate,
                                                        kernel,
                                                        phase=None,
                                                        X_fft_h=X_fft_h)
                Xp[ii, ch, :] = abs(X_analytic).astype('float32')
        print('Spectral Decomposition finished in {} seconds'.format(
            time.time() - start))

        # data: (ndarray) dims: num_times * num_channels * num_bands
        Xp = np.swapaxes(Xp, 0, 2)

        # Spectral band power
        # bands: (DynamicTable) frequency bands that signal was decomposed into
        band_param_0V = VectorData(
            name='filter_param_0',
            description='frequencies for bandpass filters',
            data=band_param_0)
        band_param_1V = VectorData(
            name='filter_param_1',
            description='frequencies for bandpass filters',
            data=band_param_1)
        bandsTable = DynamicTable(
            name='bands',
            description='Series of filters used for Hilbert transform.',
            columns=[band_param_0V, band_param_1V],
            colnames=['filter_param_0', 'filter_param_1'])
        decs = DecompositionSeries(
            name='DecompositionSeries',
            data=Xp,
            description='Analytic amplitude estimated with Hilbert transform.',
            metric='amplitude',
            unit='V',
            bands=bandsTable,
            rate=rate,
            source_timeseries=lfp)

        # Storage of spectral decomposition on NWB file ------------------------
        ecephys_module = nwb.processing['ecephys']
        ecephys_module.add_data_interface(decs)
        io.write(nwb)
        print('Spectral decomposition saved in ' + block_path)