def run_conversion(self, nwbfile: NWBFile, metadata: dict): file_path = self.source_data['file_path'] file = h5py.File(file_path, 'r') cell_info = file['cell_info'] cell_ids = [ ''.join([chr(x[0]) for x in file[x[0]]]) for x in cell_info['cell_id'] ] times = get_data(file, 'time') body_pos = get_data(file, 'body_position') body_speed = get_data(file, 'body_speed') horizontal_eye_pos = get_data(file, 'horizontal_eye_position') vertial_eye_pos = get_data(file, 'vertical_eye_position') horizontal_eye_vel = get_data(file, 'horiztonal_eye_velocity') vertial_eye_vel = get_data(file, 'vertical_eye_velocity') all_spike_times = [ file[x[0]][:].ravel() for x in cell_info['spike_times'] ] behavior = nwbfile.create_processing_module( name='behavior', description='contains processed behavioral data') spatial_series = SpatialSeries( name='position', data=body_pos, timestamps=times, conversion=.01, reference_frame='on track. Position is in VR.') behavior.add(Position(spatial_series=spatial_series)) behavior.add( TimeSeries(name='body_speed', data=body_speed, timestamps=spatial_series, unit='cm/s')) behavior.add( EyeTracking( spatial_series=SpatialSeries(name='eye_position', data=np.c_[horizontal_eye_pos, vertial_eye_pos], timestamps=spatial_series, reference_frame='unknown'))) behavior.add( TimeSeries(name='eye_velocity', data=np.c_[horizontal_eye_vel, vertial_eye_vel], timestamps=spatial_series, unit='unknown')) for spike_times, cell_id in zip(all_spike_times, cell_ids): id_ = int(cell_id.split('_')[-1]) nwbfile.add_unit(spike_times=spike_times, id=id_) return nwbfile
def setUp(self) -> None: data = np.random.rand(100, 3) timestamps = [0.0] for _ in range(data.shape[0]): timestamps.append(timestamps[-1] + 0.75 + 0.25 * np.random.rand()) self.spatial_series_rate = SpatialSeries( name="position_rate", data=data, starting_time=0.0, rate=1.0, reference_frame="starting gate", ) self.spatial_series_ts = SpatialSeries( name="position_ts", data=data, timestamps=np.array(timestamps), reference_frame="starting gate", ) self.time_intervals = TimeIntervals(name="Test Time Interval") n_intervals = 10 for start_time in np.linspace(0, 75, n_intervals + 1): if start_time < 75: stt = start_time + np.random.rand() spt = stt + 7 - np.random.rand() self.time_intervals.add_interval(start_time=stt, stop_time=spt) self.time_intervals.add_column(name="temp", description="desc", data=np.random.randint( 2, size=n_intervals)) self.time_intervals.add_column( name="temp2", description="desc", data=np.random.randint(10, size=n_intervals), )
def generate_position_data(filename): ''' Read position data from .bin or .pos file and convert to pynwb.behavior.SpatialSeries objects. Parameters: ------- filename (Path or Str): Full filename of Axona file with any extension. Returns: ------- position (pynwb.behavior.Position) ''' position = Position() position_channel_names = 't,x1,y1,x2,y2,numpix1,numpix2,unused'.split(',') position_data = read_bin_file_position_data(filename) position_timestamps = position_data[:, 0] for ichan in range(0, position_data.shape[1]): spatial_series = SpatialSeries( name=position_channel_names[ichan], timestamps=position_timestamps, data=position_data[:, ichan], reference_frame='start of raw aquisition (.bin file)') position.add_spatial_series(spatial_series) return position
def write_position(nwbfile, f, name='Trajectory 100'): """ Parameters ---------- nwbfile: pynwb.NWBFile f: h5py.File name: str (optional) Returns ------- pynwb.core.ProcessingModule """ obj = f[name] behavior_mod = check_module(nwbfile, 'behavior') spatial_series = SpatialSeries('Position', data=np.array([obj['x'], obj['y']]).T, reference_frame='NA', conversion=1 / 100., resolution=np.nan, rate=float(1 / np.diff(obj['t'][:2]) * 1000)) behavior_mod.add_data_interface(Position(spatial_series)) return behavior_mod
def setUp(self): self.spatial_series = SpatialSeries( name="position", data=np.linspace(0, 1, 20), rate=50.0, reference_frame="starting gate", )
def setUp(self): self.spatial_series = SpatialSeries(name='position', data=np.array([np.linspace(0, 1, 20), np.linspace(0, 1, 20), np.linspace(0, 1, 20)]).T, rate=50., reference_frame='starting gate')
def test_init(self): sS = SpatialSeries('test_sS', np.ones((2, 2)), 'reference_frame', timestamps=[1., 2., 3.]) pc = Position(sS) self.assertEqual(pc.spatial_series.get('test_sS'), sS)
def test_init(self): sS = SpatialSeries('test_sS', np.ones((2, 2)), 'reference_frame', timestamps=[1., 2., 3.]) cd = CompassDirection(sS) self.assertEqual(cd.spatial_series['test_sS'], sS)
def test_init(self): sS = SpatialSeries('test_sS', np.ones((2, 2)), 'reference_frame', timestamps=[1., 2., 3.]) et = EyeTracking(sS) self.assertEqual(et.spatial_series['test_sS'], sS)
def test_init(self): sS = SpatialSeries('test_sS', np.ones((2, 2)), 'reference_frame', timestamps=[1., 2., 3.]) self.assertEqual(sS.name, 'test_sS') self.assertEqual(sS.unit, 'meters') self.assertEqual(sS.reference_frame, 'reference_frame')
def test_init(self): sS = SpatialSeries('test_sS', 'a hypothetical source', list(), 'reference_frame', timestamps=list()) cd = CompassDirection('test_cd', sS) self.assertEqual(cd.source, 'test_cd') self.assertEqual(cd.spatial_series, [sS])
def test_init(self): sS = SpatialSeries('test_sS', 'a hypothetical source', list(), 'reference_frame', timestamps=list()) pc = Position('test_pc', sS) self.assertEqual(pc.source, 'test_pc') self.assertEqual(pc.spatial_series, [sS])
def test_init(self): sS = SpatialSeries('test_sS', 'a hypothetical source', list(), 'reference_frame', timestamps=list()) self.assertEqual(sS.name, 'test_sS') self.assertEqual(sS.source, 'a hypothetical source') self.assertEqual(sS.unit, 'meters') self.assertEqual(sS.reference_frame, 'reference_frame')
def test_init(self): sS = SpatialSeries('test_sS', 'a hypothetical source', list(), 'reference_frame', timestamps=list()) et = EyeTracking('test_et', sS) self.assertEqual(et.source, 'test_et') self.assertEqual(et.spatial_series, [sS])
def add_position_data(nwbfile, session_path, fs=1250. / 32., names=('x0', 'y0', 'x1', 'y1')): """Read raw position sensor data from .whl file Parameters ---------- nwbfile: pynwb.NWBFile session_path: str fs: float sampling rate names: iterable names of column headings """ session_name = os.path.split(session_path)[1] whl_path = os.path.join(session_path, session_name + '.whl') if not os.path.isfile(whl_path): print(whl_path + ' file not found!') return print('warning: time may not be aligned') df = pd.read_csv(whl_path, sep='\t', names=names) df.index = np.arange(len(df)) / fs df.index.name = 'tt (sec)' nwbfile.add_acquisition( SpatialSeries('position_sensor0', H5DataIO(df[['x0', 'y0']].values, compression='gzip'), 'unknown', description='raw sensor data from sensor 0', timestamps=H5DataIO(df.index.values, compression='gzip'), resolution=np.nan)) nwbfile.add_acquisition( SpatialSeries('position_sensor1', H5DataIO(df[['x1', 'y1']].values, compression='gzip'), 'unknown', description='raw sensor data from sensor 1', timestamps=H5DataIO(df.index.values, compression='gzip'), resolution=np.nan))
def create_spatial_series(nwbfile, param, spatial_data, spatial_timestamps, epoch_list): spatial_ts = SpatialSeries(param["name"], param["source"], spatial_data, param["reference_frame"], timestamps=spatial_timestamps, resolution=param["resolution"], comments=param["comments"], description=param["description"]) nwbfile.add_acquisition(spatial_ts, epoch_list) return spatial_ts
def add_position_data(nwbfile: NWBFile, session_path: str, fs: float = 1250. / 32., names=('x0', 'y0', 'x1', 'y1')): """Read raw position sensor data from .whl file. Parameters ---------- nwbfile: pynwb.NWBFile session_path: str fs: float sampling rate names: iterable names of column headings """ session_name = os.path.split(session_path)[1] whl_path = os.path.join(session_path, session_name + '.whl') if not os.path.isfile(whl_path): print(whl_path + ' file not found!') return df = pd.read_csv(whl_path, sep='\t', names=names) nwbfile.add_acquisition( SpatialSeries('position_sensor0', H5DataIO(df[['x0', 'y0']].values, compression='gzip'), 'unknown', description='raw sensor data from sensor 0', starting_time=0., rate=fs, resolution=np.nan)) nwbfile.add_acquisition( SpatialSeries('position_sensor1', H5DataIO(df[['x1', 'y1']].values, compression='gzip'), 'unknown', description='raw sensor data from sensor 1', starting_time=0., rate=fs, resolution=np.nan))
def setUp(self): data = np.random.rand(160, 3) self.ts_multi = SpatialSeries( name="test_timeseries", data=data, reference_frame="lowerleft", starting_time=0.0, rate=1.0, ) self.ts_single = TimeSeries( name="test_timeseries", data=data[:, 0], unit="m", starting_time=0.0, rate=1.0, )
def peyrache_spatial_series(name: str, description: str, data: np.array, conversion: float, pos_sf: float = 1250 / 32): """Specific constructor for Peyrache style spatial series.""" return SpatialSeries( name=name, description=description, data=H5DataIO(data, compression="gzip"), conversion=conversion, reference_frame="Unknown", starting_time=0.0, rate=pos_sf, resolution=np.nan, )
def add_position_data( nwbfile: NWBFile, session_path: str, whl_file_path: OptionalPathType = None, starting_time: float = 0.0, fs: float = 1250.0 / 32.0, names=("x0", "y0", "x1", "y1"), ): """ Read and write raw position sensor data from .whl file. Parameters ---------- nwbfile: pynwb.NWBFile session_path: str fs: float sampling rate names: iterable names of column headings """ session_id = Path(session_path).name if whl_file_path is None: whl_path = session_path / f"{session_id}.whl" assert whl_file_path.is_file(), f".whl file ({whl_path}) not found!" df = pd.read_csv(whl_file_path, sep="\t", names=names) for x in [0, 1]: nwbfile.add_acquisition( SpatialSeries( name=f"PositionSensor{x}", description=f"Raw sensor data from sensor {x}.", data=H5DataIO(df[[f"x{x}", f"y{x}"]].values, compression="gzip"), reference_frame="Unknown", conversion=np.nan, # whl is in arbitrary units starting_time=starting_time, rate=fs, resolution=np.nan, ))
def main(): import os.path # prerequisites: start import numpy as np rate = 10.0 np.random.seed(1234) data_len = 1000 ephys_data = np.random.rand(data_len) ephys_timestamps = np.arange(data_len) / rate spatial_timestamps = ephys_timestamps[::10] spatial_data = np.cumsum(np.random.normal(size=(2, len(spatial_timestamps))), axis=-1).T # prerequisites: end # create-nwbfile: start from datetime import datetime from dateutil.tz import tzlocal from pynwb import NWBFile f = NWBFile( 'the PyNWB tutorial', 'my first synthetic recording', 'EXAMPLE_ID', datetime.now(tzlocal()), experimenter='Dr. Bilbo Baggins', lab='Bag End Laboratory', institution='University of Middle Earth at the Shire', experiment_description= 'I went on an adventure with thirteen dwarves to reclaim vast treasures.', session_id='LONELYMTN') # create-nwbfile: end # save-nwbfile: start from pynwb import NWBHDF5IO filename = "example.h5" io = NWBHDF5IO(filename, mode='w') io.write(f) io.close() # save-nwbfile: end os.remove(filename) # create-device: start device = f.create_device(name='trodes_rig123', source="a source") # create-device: end # create-electrode-groups: start electrode_name = 'tetrode1' source = "an hypothetical source" description = "an example tetrode" location = "somewhere in the hippocampus" electrode_group = f.create_electrode_group(electrode_name, source=source, description=description, location=location, device=device) # create-electrode-groups: end # create-electrode-table-region: start for idx in [1, 2, 3, 4]: f.add_electrode(idx, x=1.0, y=2.0, z=3.0, imp=float(-idx), location='CA1', filtering='none', description='channel %s' % idx, group=electrode_group) electrode_table_region = f.create_electrode_table_region( [0, 2], 'the first and third electrodes') # create-electrode-table-region: end # create-timeseries: start from pynwb.ecephys import ElectricalSeries from pynwb.behavior import SpatialSeries ephys_ts = ElectricalSeries( 'test_ephys_data', 'an hypothetical source', ephys_data, electrode_table_region, timestamps=ephys_timestamps, # Alternatively, could specify starting_time and rate as follows # starting_time=ephys_timestamps[0], # rate=rate, resolution=0.001, comments= "This data was randomly generated with numpy, using 1234 as the seed", description="Random numbers generated with numpy.random.rand") f.add_acquisition(ephys_ts) spatial_ts = SpatialSeries( 'test_spatial_timeseries', 'a stumbling rat', spatial_data, 'origin on x,y-plane', timestamps=spatial_timestamps, resolution=0.1, comments="This data was generated with numpy, using 1234 as the seed", description="This 2D Brownian process generated with " "np.cumsum(np.random.normal(size=(2, len(spatial_timestamps))), axis=-1).T" ) f.add_acquisition(spatial_ts) # create-timeseries: end # create-data-interface: start from pynwb.ecephys import LFP from pynwb.behavior import Position lfp = f.add_acquisition(LFP('a hypothetical source')) ephys_ts = lfp.create_electrical_series( 'test_ephys_data', 'an hypothetical source', ephys_data, electrode_table_region, timestamps=ephys_timestamps, resolution=0.001, comments= "This data was randomly generated with numpy, using 1234 as the seed", # noqa: E501 description="Random numbers generated with numpy.random.rand") pos = f.add_acquisition(Position('a hypothetical source')) spatial_ts = pos.create_spatial_series( 'test_spatial_timeseries', 'a stumbling rat', spatial_data, 'origin on x,y-plane', timestamps=spatial_timestamps, resolution=0.1, comments="This data was generated with numpy, using 1234 as the seed", description="This 2D Brownian process generated with " "np.cumsum(np.random.normal(size=(2, len(spatial_timestamps))), axis=-1).T" ) # noqa: E501 # create-data-interface: end # create-epochs: start epoch_tags = ('example_epoch', ) f.add_epoch(name='epoch1', start_time=0.0, stop_time=1.0, tags=epoch_tags, description="the first test epoch", timeseries=[ephys_ts, spatial_ts]) f.add_epoch(name='epoch2', start_time=0.0, stop_time=1.0, tags=epoch_tags, description="the second test epoch", timeseries=[ephys_ts, spatial_ts]) # create-epochs: end # create-compressed-timeseries: start from pynwb.ecephys import ElectricalSeries from pynwb.behavior import SpatialSeries from pynwb.form.backends.hdf5 import H5DataIO ephys_ts = ElectricalSeries( 'test_compressed_ephys_data', 'an hypothetical source', H5DataIO(ephys_data, compress=True), electrode_table_region, timestamps=H5DataIO(ephys_timestamps, compress=True), resolution=0.001, comments= "This data was randomly generated with numpy, using 1234 as the seed", description="Random numbers generated with numpy.random.rand") f.add_acquisition(ephys_ts) spatial_ts = SpatialSeries( 'test_compressed_spatial_timeseries', 'a stumbling rat', H5DataIO(spatial_data, compress=True), 'origin on x,y-plane', timestamps=H5DataIO(spatial_timestamps, compress=True), resolution=0.1, comments="This data was generated with numpy, using 1234 as the seed", description="This 2D Brownian process generated with " "np.cumsum(np.random.normal(size=(2, len(spatial_timestamps))), axis=-1).T" ) f.add_acquisition(spatial_ts)
def yuta2nwb(session_path='/Users/bendichter/Desktop/Buzsaki/SenzaiBuzsaki2017/YutaMouse41/YutaMouse41-150903', subject_xls=None, include_spike_waveforms=True, stub=True): subject_path, session_id = os.path.split(session_path) fpath_base = os.path.split(subject_path)[0] identifier = session_id mouse_number = session_id[9:11] if '-' in session_id: subject_id, date_text = session_id.split('-') b = False else: subject_id, date_text = session_id.split('b') b = True if subject_xls is None: subject_xls = os.path.join(subject_path, 'YM' + mouse_number + ' exp_sheet.xlsx') else: if not subject_xls[-4:] == 'xlsx': subject_xls = os.path.join(subject_xls, 'YM' + mouse_number + ' exp_sheet.xlsx') session_start_time = dateparse(date_text, yearfirst=True) df = pd.read_excel(subject_xls) subject_data = {} for key in ['genotype', 'DOB', 'implantation', 'Probe', 'Surgery', 'virus injection', 'mouseID']: names = df.iloc[:, 0] if key in names.values: subject_data[key] = df.iloc[np.argmax(names == key), 1] if isinstance(subject_data['DOB'], datetime): age = session_start_time - subject_data['DOB'] else: age = None subject = Subject(subject_id=subject_id, age=str(age), genotype=subject_data['genotype'], species='mouse') nwbfile = NWBFile(session_description='mouse in open exploration and theta maze', identifier=identifier, session_start_time=session_start_time.astimezone(), file_create_date=datetime.now().astimezone(), experimenter='Yuta Senzai', session_id=session_id, institution='NYU', lab='Buzsaki', subject=subject, related_publications='DOI:10.1016/j.neuron.2016.12.011') print('reading and writing raw position data...', end='', flush=True) ns.add_position_data(nwbfile, session_path) shank_channels = ns.get_shank_channels(session_path)[:8] all_shank_channels = np.concatenate(shank_channels) print('setting up electrodes...', end='', flush=True) hilus_csv_path = os.path.join(fpath_base, 'early_session_hilus_chans.csv') lfp_channel = get_reference_elec(subject_xls, hilus_csv_path, session_start_time, session_id, b=b) print(lfp_channel) custom_column = [{'name': 'theta_reference', 'description': 'this electrode was used to calculate LFP canonical bands', 'data': all_shank_channels == lfp_channel}] ns.write_electrode_table(nwbfile, session_path, custom_columns=custom_column, max_shanks=max_shanks) print('reading LFPs...', end='', flush=True) lfp_fs, all_channels_data = ns.read_lfp(session_path, stub=stub) lfp_data = all_channels_data[:, all_shank_channels] print('writing LFPs...', flush=True) # lfp_data[:int(len(lfp_data)/4)] lfp_ts = ns.write_lfp(nwbfile, lfp_data, lfp_fs, name='lfp', description='lfp signal for all shank electrodes') for name, channel in special_electrode_dict.items(): ts = TimeSeries(name=name, description='environmental electrode recorded inline with neural data', data=all_channels_data[channel], rate=lfp_fs, unit='V', conversion=np.nan, resolution=np.nan) nwbfile.add_acquisition(ts) # compute filtered LFP print('filtering LFP...', end='', flush=True) all_lfp_phases = [] for passband in ('theta', 'gamma'): lfp_fft = filter_lfp(lfp_data[:, all_shank_channels == lfp_channel].ravel(), lfp_fs, passband=passband) lfp_phase, _ = hilbert_lfp(lfp_fft) all_lfp_phases.append(lfp_phase[:, np.newaxis]) data = np.dstack(all_lfp_phases) print('done.', flush=True) if include_spike_waveforms: print('writing waveforms...', end='', flush=True) for shankn in np.arange(1, 9, dtype=int): ns.write_spike_waveforms(nwbfile, session_path, shankn, stub=stub) print('done.', flush=True) decomp_series = DecompositionSeries(name='LFPDecompositionSeries', description='Theta and Gamma phase for reference LFP', data=data, rate=lfp_fs, source_timeseries=lfp_ts, metric='phase', unit='radians') decomp_series.add_band(band_name='theta', band_limits=(4, 10)) decomp_series.add_band(band_name='gamma', band_limits=(30, 80)) check_module(nwbfile, 'ecephys', 'contains processed extracellular electrophysiology data').add_data_interface(decomp_series) [nwbfile.add_stimulus(x) for x in ns.get_events(session_path)] # create epochs corresponding to experiments/environments for the mouse sleep_state_fpath = os.path.join(session_path, '{}--StatePeriod.mat'.format(session_id)) exist_pos_data = any(os.path.isfile(os.path.join(session_path, '{}__{}.mat'.format(session_id, task_type['name']))) for task_type in task_types) if exist_pos_data: nwbfile.add_epoch_column('label', 'name of epoch') for task_type in task_types: label = task_type['name'] file = os.path.join(session_path, session_id + '__' + label + '.mat') if os.path.isfile(file): print('loading position for ' + label + '...', end='', flush=True) pos_obj = Position(name=label + '_position') matin = loadmat(file) tt = matin['twhl_norm'][:, 0] exp_times = find_discontinuities(tt) if 'conversion' in task_type: conversion = task_type['conversion'] else: conversion = np.nan for pos_type in ('twhl_norm', 'twhl_linearized'): if pos_type in matin: pos_data_norm = matin[pos_type][:, 1:] spatial_series_object = SpatialSeries( name=label + '_{}_spatial_series'.format(pos_type), data=H5DataIO(pos_data_norm, compression='gzip'), reference_frame='unknown', conversion=conversion, resolution=np.nan, timestamps=H5DataIO(tt, compression='gzip')) pos_obj.add_spatial_series(spatial_series_object) check_module(nwbfile, 'behavior', 'contains processed behavioral data').add_data_interface(pos_obj) for i, window in enumerate(exp_times): nwbfile.add_epoch(start_time=window[0], stop_time=window[1], label=label + '_' + str(i)) print('done.') # there are occasional mismatches between the matlab struct and the neuroscope files # regions: 3: 'CA3', 4: 'DG' df_unit_features = get_UnitFeatureCell_features(fpath_base, session_id, session_path) celltype_names = [] for celltype_id, region_id in zip(df_unit_features['fineCellType'].values, df_unit_features['region'].values): if celltype_id == 1: if region_id == 3: celltype_names.append('pyramidal cell') elif region_id == 4: celltype_names.append('granule cell') else: raise Exception('unknown type') elif not np.isfinite(celltype_id): celltype_names.append('missing') else: celltype_names.append(celltype_dict[celltype_id]) custom_unit_columns = [ { 'name': 'cell_type', 'description': 'name of cell type', 'data': celltype_names}, { 'name': 'global_id', 'description': 'global id for cell for entire experiment', 'data': df_unit_features['unitID'].values}, { 'name': 'max_electrode', 'description': 'electrode that has the maximum amplitude of the waveform', 'data': get_max_electrodes(nwbfile, session_path), 'table': nwbfile.electrodes }] ns.add_units(nwbfile, session_path, custom_unit_columns, max_shanks=max_shanks) trialdata_path = os.path.join(session_path, session_id + '__EightMazeRun.mat') if os.path.isfile(trialdata_path): trials_data = loadmat(trialdata_path)['EightMazeRun'] trialdatainfo_path = os.path.join(fpath_base, 'EightMazeRunInfo.mat') trialdatainfo = [x[0] for x in loadmat(trialdatainfo_path)['EightMazeRunInfo'][0]] features = trialdatainfo[:7] features[:2] = 'start_time', 'stop_time', [nwbfile.add_trial_column(x, 'description') for x in features[4:] + ['condition']] for trial_data in trials_data: if trial_data[3]: cond = 'run_left' else: cond = 'run_right' nwbfile.add_trial(start_time=trial_data[0], stop_time=trial_data[1], condition=cond, error_run=trial_data[4], stim_run=trial_data[5], both_visit=trial_data[6]) """ mono_syn_fpath = os.path.join(session_path, session_id+'-MonoSynConvClick.mat') matin = loadmat(mono_syn_fpath) exc = matin['FinalExcMonoSynID'] inh = matin['FinalInhMonoSynID'] #exc_obj = CatCellInfo(name='excitatory_connections', # indices_values=[], cell_index=exc[:, 0] - 1, indices=exc[:, 1] - 1) #module_cellular.add_container(exc_obj) #inh_obj = CatCellInfo(name='inhibitory_connections', # indices_values=[], cell_index=inh[:, 0] - 1, indices=inh[:, 1] - 1) #module_cellular.add_container(inh_obj) """ if os.path.isfile(sleep_state_fpath): matin = loadmat(sleep_state_fpath)['StatePeriod'] table = TimeIntervals(name='states', description='sleep states of animal') table.add_column(name='label', description='sleep state') data = [] for name in matin.dtype.names: for row in matin[name][0][0]: data.append({'start_time': row[0], 'stop_time': row[1], 'label': name}) [table.add_row(**row) for row in sorted(data, key=lambda x: x['start_time'])] check_module(nwbfile, 'behavior', 'contains behavioral data').add_data_interface(table) if stub: out_fname = session_path + '_stub.nwb' else: out_fname = session_path + '.nwb' print('writing NWB file...', end='', flush=True) with NWBHDF5IO(out_fname, mode='w') as io: io.write(nwbfile) print('done.') print('testing read...', end='', flush=True) # test read with NWBHDF5IO(out_fname, mode='r') as io: io.read() print('done.')
all_shank_channels = np.concatenate(shank_channels) nchannels = sum(len(x) for x in channel_groups) lfp_fs = ns.get_lfp_sampling_rate(xml_filepath) lfp_channel = 0 # value taken from Yuta's spreadsheet print('reading raw position data...', end='', flush=True) pos_df = ns.get_position_data(fpath, fname) print('done.') print('setting up raw position data...', end='', flush=True) # raw position sensors file pos0 = nwbfile.add_acquisition( SpatialSeries('position sensor0', 'raw sensor data from sensor 0', gzip(pos_df[['x0', 'y0']].values), 'unknown', timestamps=gzip(pos_df.index.values), resolution=np.nan)) all_ts.append(pos0) pos1 = nwbfile.add_acquisition( SpatialSeries('position sensor1', 'raw sensor data from sensor 1', gzip(pos_df[['x1', 'y1']].values), 'unknown', timestamps=gzip(pos_df.index.values), resolution=np.nan)) all_ts.append(pos1) print('done.') print('setting up electrodes...', end='', flush=True)
def convert_data( self, nwbfile: NWBFile, metadata_dict: dict, stub_test: bool = False, include_spike_waveforms: bool = False, ): """Convert the behavioral portion of a particular session of the GrosmarkAD dataset.""" session_path = self.input_args["folder_path"] subject_path, session_id = os.path.split(session_path) # Stimuli [nwbfile.add_stimulus(x) for x in get_events(session_path)] # States sleep_state_fpath = os.path.join(session_path, "{session_id}.SleepState.states.mat") # label renaming specific to Watson state_label_names = dict(WAKEstate="Awake", NREMstate="Non-REM", REMstate="REM") if os.path.isfile(sleep_state_fpath): matin = loadmat(sleep_state_fpath)["SleepState"]["ints"][0][0] table = TimeIntervals(name="states", description="Sleep states of animal.") table.add_column(name="label", description="Sleep state.") data = [] for name in matin.dtype.names: for row in matin[name][0][0]: data.append( dict( start_time=row[0], stop_time=row[1], label=state_label_names[name], )) [ table.add_row(**row) for row in sorted(data, key=lambda x: x["start_time"]) ] check_module(nwbfile, "behavior", "contains behavioral data").add_data_interface(table) # Position pos_filepath = Path( session_path) / f"{session_id}.position.behavior.mat" pos_mat = loadmat(str(pos_filepath.absolute())) starting_time = float( pos_mat["position"]["timestamps"][0][0] [0]) # confirmed to be a regularly sampled series rate = float( pos_mat["position"]["timestamps"][0][0][1]) - starting_time if pos_mat["position"]["units"][0][0][0] == "m": conversion = 1.0 else: warnings.warn( f"Spatial units ({pos_mat['position']['units'][0][0][0]}) not listed in meters; " "setting conversion to nan.") conversion = np.nan pos_data = [[x[0], y[0]] for x, y in zip( pos_mat["position"]["position"][0][0]["x"][0][0], pos_mat["position"]["position"][0][0]["y"][0][0], )] linearized_data = [[ lin[0] ] for lin in pos_mat["position"]["position"][0][0]["lin"][0][0]] label = pos_mat["position"]["behaviorinfo"][0][0]["MazeType"][0][0][ 0].replace(" ", "") pos_obj = Position(name=f"{label}Position") spatial_series_object = SpatialSeries( name=f"{label}SpatialSeries", description= "(x,y) coordinates tracking subject movement through the maze.", data=H5DataIO(pos_data, compression="gzip"), reference_frame="unknown", conversion=conversion, starting_time=starting_time, rate=rate, resolution=np.nan, ) pos_obj.add_spatial_series(spatial_series_object) check_module( nwbfile, "behavior", "contains processed behavioral data").add_data_interface(pos_obj) lin_pos_obj = Position(name=f"{label}LinearizedPosition") lin_spatial_series_object = SpatialSeries( name=f"{label}LinearizedTimeSeries", description= "Linearized position, defined as starting at the edge of reward area, " "and increasing clockwise, terminating at the opposing edge of the reward area.", data=H5DataIO(linearized_data, compression="gzip"), reference_frame="unknown", conversion=conversion, starting_time=starting_time, rate=rate, resolution=np.nan, ) lin_pos_obj.add_spatial_series(lin_spatial_series_object) check_module(nwbfile, "behavior", "contains processed behavioral data").add_data_interface( lin_pos_obj) # Epochs epoch_names = list(pos_mat["position"]["Epochs"][0][0].dtype.names) epoch_windows = [[float(start), float(stop)] for x in pos_mat["position"]["Epochs"][0][0][0][0] for start, stop in x] nwbfile.add_epoch_column("label", "name of epoch") for j, epoch_name in enumerate(epoch_names): nwbfile.add_epoch( start_time=epoch_windows[j][0], stop_time=epoch_windows[j][1], label=epoch_name, )
#################### # You can add objects to a data interface as a method of the data interface: position.create_spatial_series(name='position1', data=np.linspace(0, 1, 20), rate=50., reference_frame='starting gate') #################### # or you can add pre-existing objects: from pynwb.behavior import SpatialSeries spatial_series = SpatialSeries(name='position2', data=np.linspace(0, 1, 20), rate=50., reference_frame='starting gate') position.add_spatial_series(spatial_series) #################### # or include the object during construction: spatial_series = SpatialSeries(name='position2', data=np.linspace(0, 1, 20), rate=50., reference_frame='starting gate') position = Position(spatial_series=spatial_series) ####################
def run_conversion(self, nwbfile: NWBFile, metadata: dict): mat_file_path = self.source_data["mat_file_path"] mat_file = loadmat(mat_file_path) trial_info = mat_file["SessionNP"] nwbfile.add_trial_column( name="reward_time", description="Time when subject began consuming reward.") nwbfile.add_trial_column( name="left_or_right", description="Time when subject began consuming reward.") l_r_dict = {1: "Right", 2: "Left"} for trial in trial_info: nwbfile.add_trial(start_time=trial[0], stop_time=trial[1], reward_time=trial[2], left_or_right=l_r_dict[int(trial[3])]) # Position pos_info = mat_file["whlrl"] pos_data = [pos_info[:, 0:1], pos_info[:, 2:3]] starting_time = 0.0 rate = 20000 / 512 # from CRCNS info conversion = np.nan # whl are arbitrary units pos_obj = Position(name="Position") for j in range(2): spatial_series_object = SpatialSeries( name=f"SpatialSeries{j+1}", description= "(x,y) coordinates tracking subject movement through the maze.", data=H5DataIO(pos_data[j], compression="gzip"), reference_frame="unknown", conversion=conversion, starting_time=starting_time, rate=rate, resolution=np.nan, ) pos_obj.add_spatial_series(spatial_series_object) get_module(nwbfile=nwbfile, name="behavior", description="Contains processed behavioral data." ).add_data_interface(pos_obj) linearized_pos = mat_file["whlrld"][:, 6] lin_pos_obj = Position(name="LinearizedPosition") lin_spatial_series_object = SpatialSeries( name="LinearizedTimeSeries", description= ("Linearized position, with '1' defined as start position (the position at the time of last nose-poking " "in the trial), and d=2 being the end position (position at the tiome just before reward consumption). " "d=0 means subject is not performing working memory trials."), data=H5DataIO(linearized_pos, compression="gzip"), reference_frame="unknown", conversion=conversion, starting_time=starting_time, rate=rate, resolution=np.nan, ) lin_pos_obj.add_spatial_series(lin_spatial_series_object) get_module(nwbfile=nwbfile, name="behavior").add_data_interface(lin_pos_obj)
electrode_group, timestamps=ephys_timestamps, # Alternatively, could specify starting_time and rate as follows # starting_time=ephys_timestamps[0], # rate=rate, resolution=0.001, comments= "This data was randomly generated with numpy, using 1234 as the seed", description="Random numbers generated with numpy.randon.rand") spatial_ts = SpatialSeries( 'test_spatial_data', 'a stumbling rat', spatial_data, 'origin on x,y-plane', timestamps=spatial_timestamps, resolution=0.1, comments="This data was generated with numpy, using 1234 as the seed", description="This 2D Brownian process generated with \ numpy.cumsum(numpy.random.normal(size=(2,len(spatial_timestamps))), axis=-1).T" ) # Create experimental epochs epoch_tags = ('test_example', ) ep1 = f.add_epoch('epoch1', ephys_timestamps[100], ephys_timestamps[200], tags=epoch_tags, description="the first test epoch") ep2 = f.add_epoch('epoch2', ephys_timestamps[600],
def test_init(self): sS = SpatialSeries('test_sS', list(), 'reference_frame', timestamps=list()) pc = Position(sS) self.assertEqual(pc.spatial_series.get('test_sS'), sS)
def test_init(self): sS = SpatialSeries('test_sS', list(), 'reference_frame', timestamps=list()) cd = CompassDirection(sS) self.assertEqual(cd.spatial_series['test_sS'], sS)
def test_init(self): sS = SpatialSeries('test_sS', list(), 'reference_frame', timestamps=list()) et = EyeTracking(sS) self.assertEqual(et.spatial_series['test_sS'], sS)