Exemplo n.º 1
0
 def create_timeseries_ecephys(self):
     """
     create SpikeEventSeries, ElectricalSeries, Spectrum datatypes within nwbfile>processing>ecephys
     """
     if self.no_probes == 0:
         return
     if not self.electrode_table_exist:
         self.create_electrode_table_ecephys()
     if 'ecephys' not in self.nwbfile.processing:
         mod = self.nwbfile.create_processing_module(
             'ecephys', 'Processed electrophysiology data of IBL')
     else:
         mod = self.nwbfile.get_processing_module('ecephys')
     for neurodata_type_name, neurodata_type_args_list in self.nwb_metadata[
             'Ecephys']['Ecephys'].items():
         data_retrieved_args_list = self._get_data(
             neurodata_type_args_list
         )  # list of dicts with keys as argument names
         for no, neurodata_type_args in enumerate(data_retrieved_args_list):
             ibl_dataset_name = neurodata_type_args_list[no]['data']
             if 'ElectricalSeries' in neurodata_type_name:
                 timestamps_names = self._one_data.data_attrs_dump[
                     '_iblqc_ephysTimeRms.timestamps']
                 data_names = self._one_data.data_attrs_dump[
                     '_iblqc_ephysTimeRms.rms']
                 for data_idx, data in enumerate(
                         neurodata_type_args['data']):
                     probe_no = [
                         j for j in range(self.no_probes)
                         if self.nwb_metadata['Probes'][j]['name'] in
                         data_names[data_idx]
                     ][0]
                     if data.shape[1] > self._one_data.data_attrs_dump[
                             'electrode_table_length'][probe_no]:
                         if 'channels.rawInd' in self._one_data.loaded_datasets:
                             channel_idx = self._one_data.loaded_datasets[
                                 'channels.rawInd'][probe_no].data.astype(
                                     'int')
                         else:
                             warnings.warn('could not find channels.rawInd')
                             break
                     else:
                         channel_idx = slice(None)
                     mod.add(
                         ElectricalSeries(
                             name=data_names[data_idx],
                             description=neurodata_type_args['description'],
                             timestamps=neurodata_type_args['timestamps']
                             [timestamps_names.index(data_names[data_idx])],
                             data=data[:, channel_idx],
                             electrodes=self.probe_dt_region[probe_no]))
             elif 'Spectrum' in neurodata_type_name:
                 if ibl_dataset_name in '_iblqc_ephysSpectralDensity.power':
                     freqs_names = self._one_data.data_attrs_dump[
                         '_iblqc_ephysSpectralDensity.freqs']
                     data_names = self._one_data.data_attrs_dump[
                         '_iblqc_ephysSpectralDensity.power']
                     for data_idx, data in enumerate(
                             neurodata_type_args['data']):
                         mod.add(
                             Spectrum(name=data_names[data_idx],
                                      frequencies=neurodata_type_args[
                                          'frequencies'][freqs_names.index(
                                              data_names[data_idx])],
                                      power=data))
             elif 'SpikeEventSeries' in neurodata_type_name:
                 neurodata_type_args.update(
                     dict(electrodes=self.probe_dt_region_all))
                 mod.add(
                     pynwb.ecephys.SpikeEventSeries(**neurodata_type_args))
Exemplo n.º 2
0
def copy_obj(obj_old, nwb_old, nwb_new):
    """ Creates a copy of obj_old. """

    # ElectricalSeries --------------------------------------------------------
    if type(obj_old) is ElectricalSeries:
        nChannels = obj_old.electrodes.table['x'].data.shape[0]
        elecs_region = nwb_new.electrodes.create_region(
            name='electrodes',
            region=np.arange(nChannels).tolist(),
            description=''
        )
        return ElectricalSeries(
            name=obj_old.name,
            data=obj_old.data[:],
            electrodes=elecs_region,
            rate=obj_old.rate,
            description=obj_old.description
        )

    # DynamicTable ------------------------------------------------------------
    if type(obj_old) is DynamicTable:
        return DynamicTable(
            name=obj_old.name,
            description=obj_old.description,
            colnames=obj_old.colnames,
            columns=obj_old.columns,
        )

    # LFP ---------------------------------------------------------------------
    if type(obj_old) is LFP:
        obj = LFP(name=obj_old.name)
        assert len(obj_old.electrical_series) == 1, (
                'Expected precisely one electrical series, got %i!' %
                len(obj_old.electrical_series))
        els = list(obj_old.electrical_series.values())[0]
        nChannels = els.data.shape[1]

        ####
        # first check for a table among the new file's data_interfaces
        if els.electrodes.table.name in nwb_new.processing[
            'ecephys'].data_interfaces:
            LFP_dynamic_table = nwb_new.processing['ecephys'].data_interfaces[
                els.electrodes.table.name]
        else:
            # othewise use the electrodes as the table
            LFP_dynamic_table = nwb_new.electrodes
        ####

        elecs_region = LFP_dynamic_table.create_region(
            name='electrodes',
            region=[i for i in range(nChannels)],
            description=els.electrodes.description
        )

        obj_ts = obj.create_electrical_series(
            name=els.name,
            comments=els.comments,
            conversion=els.conversion,
            data=els.data[:],
            description=els.description,
            electrodes=elecs_region,
            rate=els.rate,
            resolution=els.resolution,
            starting_time=els.starting_time
        )

        return obj

    # TimeSeries --------------------------------------------------------------
    if type(obj_old) is TimeSeries:
        return TimeSeries(
            name=obj_old.name,
            description=obj_old.description,
            data=obj_old.data[:],
            rate=obj_old.rate,
            resolution=obj_old.resolution,
            conversion=obj_old.conversion,
            starting_time=obj_old.starting_time,
            unit=obj_old.unit
        )

    # DecompositionSeries -----------------------------------------------------
    if type(obj_old) is DecompositionSeries:
        list_columns = []
        for item in obj_old.bands.columns:
            bp = VectorData(
                name=item.name,
                description=item.description,
                data=item.data[:]
            )
            list_columns.append(bp)
        bandsTable = DynamicTable(
            name=obj_old.bands.name,
            description=obj_old.bands.description,
            columns=list_columns,
            colnames=obj_old.bands.colnames
        )
        return DecompositionSeries(
            name=obj_old.name,
            data=obj_old.data[:],
            description=obj_old.description,
            metric=obj_old.metric,
            unit=obj_old.unit,
            rate=obj_old.rate,
            # source_timeseries=lfp,
            bands=bandsTable,
        )

    # Spectrum ----------------------------------------------------------------
    if type(obj_old) is Spectrum:
        file_elecs = nwb_new.electrodes
        nChannels = len(file_elecs['x'].data[:])
        elecs_region = file_elecs.create_region(
            name='electrodes',
            region=np.arange(nChannels).tolist(),
            description=''
        )
        return Spectrum(
            name=obj_old.name,
            frequencies=obj_old.frequencies[:],
            power=obj_old.power,
            electrodes=elecs_region
        )
Exemplo n.º 3
0
from ndx_spectrum import Spectrum
from datetime import datetime
from pynwb import NWBFile, NWBHDF5IO

nwb = NWBFile('session_description', 'identifier', datetime.now().astimezone())

spectrum = Spectrum('test_spectrum', frequencies=[1., 2., 3.],
                    power=[1., 2., 3.],
                    phase=[1., 2., 3.])

with NWBHDF5IO('test_spectrum.nwb', 'w') as io:
    io.write(nwb)

with NWBHDF5IO('test_spectrum.nwb', 'r', load_namespaces=True) as io:
    io.read()
Exemplo n.º 4
0
def psd_estimate(src_file, type):
    """
    Estimates Power Spectral Density from signals.

    Parameters
    ----------
    src_file : str or path
        Full path to the current NWB file.
    type : str
        ElectricalSeries source. 'raw' or 'preprocessed'.
    """

    # Open file
    with NWBHDF5IO(src_file, mode='r+', load_namespaces=True) as io:
        nwb = io.read()

        # Source ElectricalSeries
        if type == 'raw':
            # Check if there is ElectricalSeries in acquisition group
            for i in list(nwb.acquisition.keys()):
                if isinstance(nwb.acquisition[i], ElectricalSeries):
                    data_obj = nwb.acquisition[i]
        elif type == 'preprocessed':
            data_obj = nwb.processing['ecephys'].data_interfaces['LFP'].electrical_series['preprocessed']

        nChannels = data_obj.data.shape[1]
        nSamples = data_obj.data.shape[0]
        fs = data_obj.rate
        # Welch - window length as power of 2 and keeps dF~0.05 Hz
        dF = .05            # Frequency bin size
        win_len_welch = 2**(np.ceil(np.log2(fs / dF)).astype('int'))   # dF = fs/nfft
        # FFT - using a power of 2 number of samples improves performance
        nfft = int(2**(np.floor(np.log2(nSamples)).astype('int')))
        fx_lim = 200.
        for ch in np.arange(nChannels):  # Iterate over channels
            trace = data_obj.data[:, ch]
            fx_w, py_w = sgn.welch(trace, fs=fs, nperseg=win_len_welch)
            fx_f, py_f = sgn.periodogram(trace, fs=fs, nfft=nfft)
            # saves PSD up to 200 Hz
            py_w = py_w[fx_w < fx_lim]
            fx_w = fx_w[fx_w < fx_lim]
            py_f = py_f[fx_f < fx_lim]
            fx_f = fx_f[fx_f < fx_lim]
            if ch == 0:
                PY_welch = py_w.reshape(-1, 1)
                PY_fft = py_f.reshape(-1, 1)
            else:
                PY_welch = np.append(PY_welch, py_w.reshape(-1, 1), axis=1)
                PY_fft = np.append(PY_fft, py_f.reshape(-1, 1), axis=1)

        # vElectrodes
        elecs_region = nwb.electrodes.create_region(name='electrodes',
                                                    region=np.arange(nChannels).tolist(),
                                                    description='all electrodes')

        # vPSD shape: ('frequency', 'channel')
        spectrum_module_welch = Spectrum(name='Spectrum_welch_' + type,
                                         frequencies=fx_w,
                                         power=PY_welch,
                                         source_timeseries=data_obj,
                                         electrodes=elecs_region)

        spectrum_module_fft = Spectrum(name='Spectrum_fft_' + type,
                                       frequencies=fx_f,
                                       power=PY_fft,
                                       source_timeseries=data_obj,
                                       electrodes=elecs_region)

        # Processing module
        try:      # if ecephys module already exists
            ecephys_module = nwb.processing['ecephys']
        except:   # creates ecephys ProcessingModule
            ecephys_module = ProcessingModule(name='ecephys',
                                              description='Extracellular electrophysiology data.')
            # Add module to NWB file
            nwb.add_processing_module(ecephys_module)
            print('Created ecephys')
        ecephys_module.add_data_interface(spectrum_module_welch)
        ecephys_module.add_data_interface(spectrum_module_fft)

        io.write(nwb)
        print('Spectrum_welch_' + type + ' added to file.')
        print('Spectrum_fft_' + type + ' added to file.')
Exemplo n.º 5
0
def copy_obj(obj_old, nwb_old, nwb_new):
    """ Creates a copy of obj_old. """

    obj = None
    obj_type = type(obj_old).__name__

    #ElectricalSeries ----------------------------------------------------------
    if obj_type == 'ElectricalSeries':
        nChannels = obj_old.electrodes.table['x'].data.shape[0]
        elecs_region = nwb_new.electrodes.create_region(
            name='electrodes',
            region=np.arange(nChannels).tolist(),
            description='')
        obj = ElectricalSeries(name=obj_old.name,
                               data=obj_old.data[:],
                               electrodes=elecs_region,
                               rate=obj_old.rate,
                               description=obj_old.description)

    #LFP -----------------------------------------------------------------------
    if obj_type == 'LFP':
        obj = LFP(name=obj_old.name)
        els_name = list(obj_old.electrical_series.keys())[0]
        els = obj_old.electrical_series[els_name]
        nChannels = els.data.shape[1]
        elecs_region = nwb_new.electrodes.create_region(
            name='electrodes',
            region=np.arange(nChannels).tolist(),
            description='')
        obj_ts = obj.create_electrical_series(name=els.name,
                                              comments=els.comments,
                                              conversion=els.conversion,
                                              data=els.data[:],
                                              description=els.description,
                                              electrodes=elecs_region,
                                              rate=els.rate,
                                              resolution=els.resolution,
                                              starting_time=els.starting_time)

    #TimeSeries ----------------------------------------------------------------
    elif obj_type == 'TimeSeries':
        obj = TimeSeries(name=obj_old.name,
                         description=obj_old.description,
                         data=obj_old.data[:],
                         rate=obj_old.rate,
                         resolution=obj_old.resolution,
                         conversion=obj_old.conversion,
                         starting_time=obj_old.starting_time,
                         unit=obj_old.unit)

    #DecompositionSeries -------------------------------------------------------
    elif obj_type == 'DecompositionSeries':
        list_columns = []
        for item in obj_old.bands.columns:
            bp = VectorData(name=item.name,
                            description=item.description,
                            data=item.data[:])
            list_columns.append(bp)
        bandsTable = DynamicTable(name=obj_old.bands.name,
                                  description=obj_old.bands.description,
                                  columns=list_columns,
                                  colnames=obj_old.bands.colnames)
        obj = DecompositionSeries(
            name=obj_old.name,
            data=obj_old.data[:],
            description=obj_old.description,
            metric=obj_old.metric,
            unit=obj_old.unit,
            rate=obj_old.rate,
            #source_timeseries=lfp,
            bands=bandsTable,
        )

    #Spectrum ------------------------------------------------------------------
    elif obj_type == 'Spectrum':
        file_elecs = nwb_new.electrodes
        nChannels = len(file_elecs['x'].data[:])
        elecs_region = file_elecs.create_region(
            name='electrodes',
            region=np.arange(nChannels).tolist(),
            description='')
        obj = Spectrum(name=obj_old.name,
                       frequencies=obj_old.frequencies[:],
                       power=obj_old.power,
                       electrodes=elecs_region)

    return obj
Exemplo n.º 6
0
def copy_obj(obj_old, nwb_old, nwb_new):
    """ Creates a copy of obj_old. """

    # ElectricalSeries --------------------------------------------------------
    if type(obj_old) is ElectricalSeries:
        # If reference electrodes table is bipolar scheme
        if isinstance(obj_old.electrodes.table, BipolarSchemeTable):
            bst_old = obj_old.electrodes.table
            bst_old_df = bst_old.to_dataframe()
            bst_new = nwb_new.lab_meta_data['ecephys_ext'].bipolar_scheme_table

            for id, row in bst_old_df.iterrows():
                index_anodes = row['anodes'].index.tolist()
                index_cathodes = row['cathodes'].index.tolist()
                bst_new.add_row(anodes=index_anodes, cathodes=index_cathodes)
            bst_new.anodes.table = nwb_new.electrodes
            bst_new.cathodes.table = nwb_new.electrodes

            # if there are custom columns
            new_cols = list(bst_old_df.columns)
            default_cols = ['anodes', 'cathodes']
            [new_cols.remove(col) for col in default_cols]
            for col in new_cols:
                col_data = list(bst_old[col].data[:])
                bst_new.add_column(name=str(col),
                                   description=str(bst_old[col].description),
                                   data=col_data)

            elecs_region = DynamicTableRegion(name='electrodes',
                                              data=bst_old_df.index.tolist(),
                                              description='desc',
                                              table=bst_new)
        else:
            region = np.array(obj_old.electrodes.table.id[:])[
                obj_old.electrodes.data[:]].tolist()
            elecs_region = nwb_new.create_electrode_table_region(
                name='electrodes', region=region, description='')
        els = ElectricalSeries(name=obj_old.name,
                               data=obj_old.data[:],
                               electrodes=elecs_region,
                               rate=obj_old.rate,
                               description=obj_old.description)
        return els

    # DynamicTable ------------------------------------------------------------
    if type(obj_old) is DynamicTable:
        return DynamicTable(
            name=obj_old.name,
            description=obj_old.description,
            colnames=obj_old.colnames,
            columns=obj_old.columns,
        )

    # LFP ---------------------------------------------------------------------
    if type(obj_old) is LFP:
        obj = LFP(name=obj_old.name)
        assert len(obj_old.electrical_series) == 1, (
            'Expected precisely one electrical series, got %i!' %
            len(obj_old.electrical_series))
        els = list(obj_old.electrical_series.values())[0]

        ####
        # first check for a table among the new file's data_interfaces
        if els.electrodes.table.name in nwb_new.processing[
                'ecephys'].data_interfaces:
            LFP_dynamic_table = nwb_new.processing['ecephys'].data_interfaces[
                els.electrodes.table.name]
        else:
            # othewise use the electrodes as the table
            LFP_dynamic_table = nwb_new.electrodes
        ####

        region = np.array(
            els.electrodes.table.id[:])[els.electrodes.data[:]].tolist()
        elecs_region = LFP_dynamic_table.create_region(
            name='electrodes',
            region=region,
            description=els.electrodes.description)

        obj.create_electrical_series(name=els.name,
                                     comments=els.comments,
                                     conversion=els.conversion,
                                     data=els.data[:],
                                     description=els.description,
                                     electrodes=elecs_region,
                                     rate=els.rate,
                                     resolution=els.resolution,
                                     starting_time=els.starting_time)

        return obj

    # TimeSeries --------------------------------------------------------------
    if type(obj_old) is TimeSeries:
        return TimeSeries(name=obj_old.name,
                          description=obj_old.description,
                          data=obj_old.data[:],
                          rate=obj_old.rate,
                          resolution=obj_old.resolution,
                          conversion=obj_old.conversion,
                          starting_time=obj_old.starting_time,
                          unit=obj_old.unit)

    # DecompositionSeries -----------------------------------------------------
    if type(obj_old) is DecompositionSeries:
        list_columns = []
        for item in obj_old.bands.columns:
            bp = VectorData(name=item.name,
                            description=item.description,
                            data=item.data[:])
            list_columns.append(bp)
        bandsTable = DynamicTable(name=obj_old.bands.name,
                                  description=obj_old.bands.description,
                                  columns=list_columns,
                                  colnames=obj_old.bands.colnames)
        return DecompositionSeries(
            name=obj_old.name,
            data=obj_old.data[:],
            description=obj_old.description,
            metric=obj_old.metric,
            unit=obj_old.unit,
            rate=obj_old.rate,
            # source_timeseries=lfp,
            bands=bandsTable,
        )

    # Spectrum ----------------------------------------------------------------
    if type(obj_old) is Spectrum:
        file_elecs = nwb_new.electrodes
        nChannels = len(file_elecs['x'].data[:])
        elecs_region = file_elecs.create_region(
            name='electrodes',
            region=np.arange(nChannels).tolist(),
            description='')
        return Spectrum(name=obj_old.name,
                        frequencies=obj_old.frequencies[:],
                        power=obj_old.power,
                        electrodes=elecs_region)

    # Survey tables ------------------------------------------------------------
    if obj_old.neurodata_type == 'SurveyTable':
        if obj_old.name == 'nrs_survey_table':
            n_rows = len(obj_old['nrs_pain_intensity_rating'].data)
            for i in range(n_rows):
                nrs_survey_table.add_row(
                    **{c: obj_old[c][i]
                       for c in obj_old.colnames})
            return nrs_survey_table

        elif obj_old.name == 'vas_survey_table':
            n_rows = len(obj_old['vas_pain_intensity_rating'].data)
            for i in range(n_rows):
                vas_survey_table.add_row(
                    **{c: obj_old[c][i]
                       for c in obj_old.colnames})
            return vas_survey_table

        elif obj_old.name == 'mpq_survey_table':
            n_rows = len(obj_old['throbbing'].data)
            for i in range(n_rows):
                mpq_survey_table.add_row(
                    **{c: obj_old[c][i]
                       for c in obj_old.colnames})
            return mpq_survey_table