def setUp(self) -> None: data1 = np.array([1, 2, 2, 3, 1, 1, 3, 2, 3]) data2 = np.array([3, 4, 2, 4, 3, 2, 2, 4, 4]) device = Device(name="device") eg_1 = ElectrodeGroup(name="electrodegroup1", description="desc", location="brain", device=device) eg_2 = ElectrodeGroup(name="electrodegroup2", description="desc", location="brain", device=device) data3 = [eg_1, eg_2, eg_1, eg_1, eg_1, eg_1, eg_1, eg_1, eg_1] vd1 = VectorData("Data1", "vector data for creating a DynamicTable", data=data1) vd2 = VectorData("Data2", "vector data for creating a DynamicTable", data=data2) vd3 = VectorData("ElectrodeGroup", "vector data for creating a DynamicTable", data=data3) vd = [vd1, vd2, vd3] self.dynamic_table = DynamicTable( name="test table", description="This is a test table", columns=vd, colnames=["Data1", "Data2", "ElectrodeGroup"], )
def test_electrode_group(self): ut = Units() device = Device('test_device') electrode_group = ElectrodeGroup('test_electrode_group', 'description', 'location', device) ut.add_unit(electrode_group=electrode_group) self.assertEqual(ut['electrode_group'][0], electrode_group)
def addContainer(self, file): table = ElectrodeTable('electrodes') dev1 = Device('dev1', 'a test source') group = ElectrodeGroup('tetrode1', 'a test source', 'tetrode description', 'tetrode location', dev1) table.add_row(1, 1.0, 2.0, 3.0, -1.0, 'CA1', 'none', 'first channel of tetrode', group) table.add_row(2, 1.0, 2.0, 3.0, -2.0, 'CA1', 'none', 'second channel of tetrode', group) table.add_row(3, 1.0, 2.0, 3.0, -3.0, 'CA1', 'none', 'third channel of tetrode', group) table.add_row(4, 1.0, 2.0, 3.0, -4.0, 'CA1', 'none', 'fourth channel of tetrode', group) file.set_device(dev1) file.set_electrode_group(group) file.set_electrode_table(table) region = ElectrodeTableRegion( table, [0, 2], 'the first and third electrodes') # noqa: F405 data = list(zip(range(10), range(10, 20))) timestamps = list(range(10)) es = ElectricalSeries('test_eS', 'a hypothetical source', data, region, timestamps=timestamps) file.add_acquisition(es) return es
def addContainer(self, file): dev1 = Device('dev1', 'a test source') file.set_device(dev1) eg = ElectrodeGroup('elec1', 'a test source', 'a test ElectrodeGroup', 'a nonexistent place', dev1) file.set_electrode_group(eg) return eg
def setUpContainer(self): """ Return the test TetrodeSeries to read/write """ self.device = Device(name='device_name') self.group = ElectrodeGroup(name='electrode_group', description='description', location='location', device=self.device) self.table = get_electrode_table( ) # manually create a table of electrodes for i in range(10): self.table.add_row(x=i, y=i, z=i, imp=np.nan, location='location', filtering='filtering', group=self.group, group_name='electrode_group') all_electrodes = DynamicTableRegion(data=list(range(0, 10)), description='all the electrodes', name='electrodes', table=self.table) data = np.random.rand(100, 3) tetrode_series = TetrodeSeries(name='name', description='description', data=data, rate=1000., electrodes=all_electrodes, trode_id=1) return tetrode_series
def test_init(self): dev1 = Device('dev1') # noqa: F405 group = ElectrodeGroup( # noqa: F405 'elec1', 'electrode description', 'electrode location', dev1) self.assertEqual(group.name, 'elec1') self.assertEqual(group.description, 'electrode description') self.assertEqual(group.location, 'electrode location') self.assertEqual(group.device, dev1)
def setUpContainer(self): """ Return the test ElectrodeGroup to read/write """ self.dev1 = Device(name='dev1') eg = ElectrodeGroup(name='elec1', description='a test ElectrodeGroup', location='a nonexistent place', device=self.dev1) return eg
def test_init_position_none(self): dev1 = Device('dev1') group = ElectrodeGroup('elec1', 'electrode description', 'electrode location', dev1) self.assertEqual(group.name, 'elec1') self.assertEqual(group.description, 'electrode description') self.assertEqual(group.location, 'electrode location') self.assertEqual(group.device, dev1) self.assertIsNone(group.position)
def make_electrode_table(self): """ Make an electrode table, electrode group, and device """ self.table = get_electrode_table() self.dev1 = Device('dev1') self.group = ElectrodeGroup('tetrode1', 'tetrode description', 'tetrode location', self.dev1) for i in range(4): self.table.add_row(x=i, y=2.0, z=3.0, imp=-1.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1')
def test_init(self): dev1 = Device('dev1') # noqa: F405 group = ElectrodeGroup( # noqa: F405, F841 'tetrode1', 'tetrode description', 'tetrode location', dev1) table = make_electrode_table() region = DynamicTableRegion('electrodes', [0, 2], 'the first and third electrodes', table) eS = ElectricalSeries( # noqa: F405 'test_eS', [0, 1, 2, 3], region, timestamps=[0.1, 0.2, 0.3, 0.4]) fe = FilteredEphys(eS) # noqa: F405 self.assertEqual(fe.electrical_series.get('test_eS'), eS) self.assertEqual(fe['test_eS'], fe.electrical_series.get('test_eS'))
def test_add_electrical_series(self): lfp = LFP() # noqa: F405 dev1 = Device('dev1') # noqa: F405 group = ElectrodeGroup( # noqa: F405, F841 'tetrode1', 'tetrode description', 'tetrode location', dev1) table = make_electrode_table() region = DynamicTableRegion('electrodes', [0, 2], 'the first and third electrodes', table) eS = ElectricalSeries( # noqa: F405 'test_eS', [0, 1, 2, 3], region, timestamps=[0.1, 0.2, 0.3, 0.4]) lfp.add_electrical_series(eS) self.assertEqual(lfp.electrical_series.get('test_eS'), eS) self.assertEqual(lfp['test_eS'], lfp.electrical_series.get('test_eS'))
def create_electrode_group(cls, fl_electrode_group: FlElectrodeGroup): validate_parameters_not_none(__name__, fl_electrode_group.name, fl_electrode_group.description, fl_electrode_group.location, fl_electrode_group.device) return ElectrodeGroup( name=fl_electrode_group.name, description=fl_electrode_group.description, location=fl_electrode_group.location, device=fl_electrode_group.device, )
def test_init(self): dev1 = Device('dev1') # noqa: F405 group = ElectrodeGroup( # noqa: F405, F841 'tetrode1', 'tetrode description', 'tetrode location', dev1) table = make_electrode_table() region = DynamicTableRegion('electrodes', [0, 2], 'the first and third electrodes', table) sES = SpikeEventSeries( # noqa: F405 'test_sES', list(range(10)), list(range(10)), region) ew = EventWaveform(sES) # noqa: F405 self.assertEqual(ew.spike_event_series['test_sES'], sES) self.assertEqual(ew['test_sES'], ew.spike_event_series['test_sES'])
def make_electrode_table(self): self.table = get_electrode_table() self.dev1 = Device('dev1', 'a test source') self.group = ElectrodeGroup('tetrode1', 'a test source', 'tetrode description', 'tetrode location', self.dev1) self.table.add_row(id=1, x=1.0, y=2.0, z=3.0, imp=-1.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1') self.table.add_row(id=2, x=1.0, y=2.0, z=3.0, imp=-2.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1') self.table.add_row(id=3, x=1.0, y=2.0, z=3.0, imp=-3.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1') self.table.add_row(id=4, x=1.0, y=2.0, z=3.0, imp=-4.0, location='CA1', filtering='none', group=self.group, group_name='tetrode1')
def make_electrode_table(): table = ElectrodeTable() dev1 = Device('dev1') # noqa: F405 group = ElectrodeGroup('tetrode1', 'tetrode description', 'tetrode location', dev1) # noqa: F405 table.add_row(id=1, x=1.0, y=2.0, z=3.0, imp=-1.0, location='CA1', filtering='none', group=group, group_name='tetrode1') table.add_row(id=2, x=1.0, y=2.0, z=3.0, imp=-2.0, location='CA1', filtering='none', group=group, group_name='tetrode1') table.add_row(id=3, x=1.0, y=2.0, z=3.0, imp=-3.0, location='CA1', filtering='none', group=group, group_name='tetrode1') table.add_row(id=4, x=1.0, y=2.0, z=3.0, imp=-4.0, location='CA1', filtering='none', group=group, group_name='tetrode1') return table
def test_infer_categorical_columns(): data1 = np.array([1, 2, 2, 3, 1, 1, 3, 2, 3]) data2 = np.array([3, 4, 2, 4, 3, 2, 2, 4, 4]) device = Device(name="device") eg_1 = ElectrodeGroup(name="electrodegroup1", description="desc", location="brain", device=device) eg_2 = ElectrodeGroup(name="electrodegroup2", description="desc", location="brain", device=device) data3 = [eg_1, eg_2, eg_1, eg_1, eg_1, eg_1, eg_1, eg_1, eg_1] vd1 = VectorData("Data1", "vector data for creating a DynamicTable", data=data1) vd2 = VectorData("Data2", "vector data for creating a DynamicTable", data=data2) vd3 = VectorData("ElectrodeGroup", "vector data for creating a DynamicTable", data=data3) vd = [vd1, vd2, vd3] dynamic_table = DynamicTable( name="test table", description="This is a test table", columns=vd, colnames=["Data1", "Data2", "ElectrodeGroup"], ) assert dicts_exact_equal( infer_categorical_columns(dynamic_table), { "Data1": data1, "Data2": data2, "ElectrodeGroup": [i.name for i in data3] }, )
def setUpContainer(self): """ Return the test ElectrodeGroup to read/write """ self.dev1 = Device('dev1') eg = ElectrodeGroup('elec1', 'a test ElectrodeGroup', 'a nonexistent place', self.dev1) return eg
def test_init_position_bad(self): dev1 = Device('dev1') with self.assertRaises(TypeError): ElectrodeGroup('elec1', 'electrode description', 'electrode location', dev1, (1, 2))
def neural_data(nwb_file): """ Add in probes as devices and electrode groups. """ probe_descriptions = pd.read_csv('probes.description.tsv', sep='\t') probe_descriptions = list(probe_descriptions['description']) electrode_groups = list() for i in range(len(probe_descriptions)): probe_device = Device(name=str(i)) probe_electrode_group = ElectrodeGroup( name='Probe' + str(i + 1), description='Neuropixels Phase3A opt3', device=probe_device, location='') nwb_file.add_device(probe_device) electrode_groups.append(probe_electrode_group) nwb_file.add_electrode_group(probe_electrode_group) # CHANNELS """ Add channel information into the Electrode Table. """ # Read data insertion_df = pd.read_csv('probes.insertion.tsv', sep='\t') insertion_df['group_name'] = insertion_df.index.values channel_site = read_npy_file('channels.site.npy') channel_brain = pd.read_csv('channels.brainLocation.tsv', sep='\t') channel_probes = read_npy_file('channels.probe.npy') channel_probes = np.ravel(channel_probes.astype(int)) channel_table = pd.DataFrame(columns=['group_name']) channel_table['group_name'] = channel_probes channel_table = channel_table.merge(insertion_df, 'left', 'group_name') entry_point_rl = np.array(channel_table['entry_point_rl']) entry_point_ap = np.array(channel_table['entry_point_ap']) axial_angle = np.array(channel_table['axial_angle']) vertical_angle = np.array(channel_table['vertical_angle']) horizontal_angle = np.array(channel_table['horizontal_angle']) distance_advanced = np.array(channel_table['distance_advanced']) locations = np.array(channel_brain['allen_ontology']) groups = np.asarray([electrode_groups[c] for c in channel_probes]) channel_site_pos = read_npy_file('channels.sitePositions.npy') for i in range(len(groups)): nwb_file.add_electrode(x=float('NaN'), y=float('NaN'), z=float('NaN'), imp=float('NaN'), location=str(locations[i]), group=groups[i], filtering='none') # Add Electrode columns nwb_file.add_electrode_column( name='site_id', description='The site number, in within-probe numbering, of the channel ' '(in practice for this dataset this always starts at zero and ' 'counts up to 383 on each probe so is equivalent to the channel ' 'number - but if switches had been used, the site number could ' 'have been different than the channel number).', data=np.ravel(channel_site)) nwb_file.add_electrode_column( name='site_position', description= 'The x- and y-position of the site relative to the face of the probe ' '(where the first column is across the face of the probe laterally ' 'and the second is the position along the length of the probe; ' 'the sites nearest the tip have second column=0).', data=channel_site_pos) nwb_file.add_electrode_column( name='ccf_ap', description= 'The AP position in Allen Institute\'s Common Coordinate Framework.', data=np.array(channel_brain['ccf_ap'])) nwb_file.add_electrode_column( name='ccf_dv', description= 'The DV position in Allen Institute\'s Common Coordinate Framework.', data=np.array(channel_brain['ccf_dv'])) nwb_file.add_electrode_column( name='ccf_lr', description= 'The LR position in Allen Institute\'s Common Coordinate Framework.', data=np.array(channel_brain['ccf_lr'])) # Insertion nwb_file.add_electrode_column( name='entry_point_rl', description= 'mediolateral position of probe entry point relative to midline (microns). ' 'Positive means right', data=entry_point_rl) nwb_file.add_electrode_column( name='entry_point_ap', description= 'anteroposterior position of probe entry point relative to bregma (microns). ' 'Positive means anterior', data=entry_point_ap) nwb_file.add_electrode_column( name='vertical_angle', description='vertical angle of probe (degrees). Zero means horizontal. ' 'Positive means pointing down', data=vertical_angle) nwb_file.add_electrode_column( name='horizontal_angle', description= 'horizontal angle of probe (degrees), after vertical rotation. ' 'Zero means anterior. Positive means counterclockwise (i.e. left).', data=horizontal_angle) nwb_file.add_electrode_column( name='axial_angle', description= 'axial angle of probe (degrees). Zero means that without vertical and horizontal rotations, ' 'the probe contacts would be pointing up. Positive means "counterclockwise.', data=axial_angle) nwb_file.add_electrode_column( name='distance_advanced', description= 'How far the probe was moved forward from its entry point. (microns).', data=distance_advanced) # CLUSTERS & SPIKES """ Add cluster information into the Unit Table. """ # Read data cluster_probe = read_npy_file('clusters.probes.npy') cluster_probe = np.ravel(cluster_probe.astype(int)) cluster_channel = read_npy_file('clusters.peakChannel.npy') cluster_depths = read_npy_file('clusters.depths.npy') phy_annotations = np.ravel(read_npy_file('clusters._phy_annotation.npy')) waveform_chans = read_npy_file('clusters.templateWaveformChans.npy') waveform_chans = waveform_chans.astype(int) waveform = read_npy_file('clusters.templateWaveforms.npy') waveform_duration = read_npy_file('clusters.waveformDuration.npy') spike_to_clusters = read_npy_file('spikes.clusters.npy') spike_times = read_npy_file('spikes.times.npy') spike_amps = read_npy_file('spikes.amps.npy') spike_depths = read_npy_file('spikes.depths.npy') # Sorting spikes into clusters cluster_info = dict() for i in range(len(spike_to_clusters)): s = int(spike_to_clusters[i]) if s not in cluster_info: cluster_info[s] = [i] else: cluster_info[s].append(i) # Add Unit Columns nwb_file.add_unit_column( name='peak_channel', description= 'The channel number of the location of the peak of the cluster\'s waveform.' ) nwb_file.add_unit_column( name='waveform_duration', description= 'The trough-to-peak duration of the waveform on the peak channel.') nwb_file.add_unit_column( name='phy_annotations', description= '0 = noise (these are already excluded and don\'t appear in this dataset ' 'at all); 1 = MUA (i.e. presumed to contain spikes from multiple neurons; ' 'these are not analyzed in any analyses in the paper); 2 = Good (manually ' 'labeled); 3 = Unsorted. In this dataset \'Good\' was applied in a few but ' 'not all datasets to included neurons, so in general the neurons with ' '_phy_annotation>=2 are the ones that should be included.', ) nwb_file.add_unit_column( name='cluster_depths', description= 'The position of the center of mass of the template of the cluster, ' 'relative to the probe. The deepest channel on the probe is depth=0, ' 'and the most superficial is depth=3820. Units: µm', ) nwb_file.add_unit_column( name='sampling_rate', description='Sampling rate, in Hz.', ) # Add Units by cluster for i in cluster_info: c = cluster_info[i] times = np.array(spike_times[c]) annotations = phy_annotations[i] annotations = annotations.astype(int) channel = cluster_channel[i] channel = channel.astype(int) duration = waveform_duration[i] duration = duration.astype(int) nwb_file.add_unit(spike_times=np.ravel(times), electrodes=waveform_chans[i, :], electrode_group=electrode_groups[cluster_probe[i]], waveform_mean=waveform[i, :, :], id=i, phy_annotations=annotations, peak_channel=channel, waveform_duration=duration, cluster_depths=cluster_depths[i], sampling_rate=30000.0) # Add spike amps and depths amps = {} depths = {} for c in cluster_info.keys(): amps[c] = spike_amps[cluster_info[c]] depths[c] = spike_depths[cluster_info[c]] add_ragged_data_to_dynamic_table( table=nwb_file.units, data=amps, column_name='spike_amps', column_description= 'The peak-to-trough amplitude, obtained from the template and ' 'template-scaling amplitude returned by Kilosort (not from the raw data).' ) add_ragged_data_to_dynamic_table( table=nwb_file.units, data=depths, column_name='spike_depths', column_description= 'The position of the center of mass of the spike on the probe, ' 'determined from the principal component features returned by Kilosort. ' 'The deepest channel on the probe is depth=0, and the most superficial is depth=3820.' )
def setUpContainer(self): self.dev1 = Device('dev1') return ElectrodeGroup('elec1', 'a test ElectrodeGroup', 'a nonexistent place', self.dev1)
passive_stimulus() ################################################################################ # NEURAL DATA # DEVICES & ELECTRODE GROUPS """ Add in probes as devices and electrode groups. """ probe_descriptions = pd.read_csv('probes.description.tsv', sep='\t') probe_descriptions = list(probe_descriptions['description']) electrode_groups = list() for i in range(len(probe_descriptions)): probe_device = Device(name=str(i)) probe_electrode_group = ElectrodeGroup( name='Probe' + str(i + 1), description='Neuropixels Phase3A opt3', device=probe_device, location='') nwb_file.add_device(probe_device) electrode_groups.append(probe_electrode_group) nwb_file.add_electrode_group(probe_electrode_group) # CHANNELS """ Add channel information into the Electrode Table. """ # Read data insertion_df = pd.read_csv('probes.insertion.tsv', sep='\t') insertion_df['group_name'] = insertion_df.index.values channel_site = read_npy_file('channels.site.npy')