Accessing NP Ultra & Psychedelics Data#
Loading Data#
The Neuropixels Ultra & Psychedelics dataset is packaged in nwb format and can be accessed via NWBZarrIO.
from hdmf_zarr import NWBZarrIO
Load an example session:
nwbfile_path_zarr = '/data/ecephys_714527_2024-05-15_13-00-23_nwb_2025-08-03_21-11-22/ecephys_714527_2024-05-15_13-00-23_experiment1_recording1.nwb'
io = NWBZarrIO(nwbfile_path_zarr, "r")
nwbfile_read = io.read()
To quickly walk through the data, use:
from nwbwidgets import nwb2widget
nwb2widget(nwbfile_read)
Loading unit data#
Data for all Kilosort-processed units can be loaded via:
units_table = nwbfile_read.units[:]
units_table.head()
| spike_times | electrodes | waveform_mean | waveform_sd | unit_name | half_width | nn_hit_rate | device_name | estimated_x | spread | ... | decoder_probability | ks_unit_id | decoder_label | presence_ratio | amplitude_cv_range | drift_std | silhouette | amplitude_median | sync_spike_2 | amplitude_cutoff | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | |||||||||||||||||||||
| 0 | [860.7809320374699, 1325.947518695973, 1430.58... | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... | [[-0.4310527741909027, 0.0, 0.1539475172758102... | [[21.599468231201172, 0.0, 19.95810890197754, ... | 482f6f21-16d0-4cee-93ed-fd051303051a | 0.000257 | 0.549020 | ProbeA | 15.97 | 192.0 | ... | 0.94 | 0.0 | mua | 0.389706 | NaN | NaN | 0.260075 | 182.519990 | 0.052632 | NaN |
| 1 | [17.43142939500891, 17.468196021101217, 17.526... | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... | [[-0.636479914188385, 0.0, -1.2869997024536133... | [[15.821245193481445, 0.0, 14.6087064743042, 0... | 84ac590e-47f9-4c52-aaaa-da99c53606ae | 0.000223 | 0.568389 | ProbeA | -16.05 | 192.0 | ... | 0.59 | 1.0 | mua | 1.000000 | NaN | NaN | 0.092592 | 39.780000 | 0.024288 | 0.000080 |
| 2 | [27.352251780071317, 36.339041862565615, 43.51... | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... | [[-1.995410680770874, 0.0, -1.410410761833191,... | [[26.957242965698242, 0.0, 24.961811065673828,... | daf591fc-684f-403a-ab62-3656462428ee | 0.000217 | 0.392670 | ProbeA | -61.38 | 192.0 | ... | 0.85 | 2.0 | mua | 0.720588 | NaN | NaN | 0.057229 | 49.140000 | 0.023973 | NaN |
| 3 | [41.37910296719798, 59.87144922636121, 73.4770... | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... | [[-2.2606775760650635, 0.0, -1.893812775611877... | [[33.657691955566406, 0.0, 32.03106689453125, ... | 3c33bff2-f3f8-495e-97ff-635fdf97791c | 0.000240 | 0.181818 | ProbeA | 6.14 | 192.0 | ... | 0.90 | 3.0 | mua | 0.720588 | NaN | NaN | 0.012152 | 80.729996 | 0.118644 | NaN |
| 4 | [17.38472944654533, 17.43199606105022, 17.4949... | [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,... | [[-0.8938802480697632, 0.0, -0.425880044698715... | [[16.392057418823242, 0.0, 15.471063613891602,... | 8598dc2d-3be4-4704-a1c7-48e2b6a985bc | 0.000150 | 0.626911 | ProbeA | -20.09 | 150.0 | ... | 0.88 | 4.0 | sua | 1.000000 | NaN | 12.551991 | 0.114247 | 74.880000 | 0.021516 | 0.000043 |
5 rows × 52 columns
Units in this dataset have undergone additional postprocessing QC from Kilosort 2.5 and automated curation. Unlike other datasets, curated data can be accessed via the analysis attribute of the nwb file.
analysis_table = nwbfile_read.analysis['analysis_table'].to_dataframe()
analysis_table.head()
| ks_unit_id | probe | probe_type | Spontaneous_0_spikes | Spontaneous_1_spikes | Spontaneous_2_spikes | Spontaneous_3_spikes | Spontaneous_4_spikes | RFMapping_0_spikes | RFMapping_1_spikes | ... | optotagged | cell_type | spread | bAP_extent | bAP_attenuation | bAP_idx | burst_idx | num_bursts | burst_dur | burst_proportion | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | |||||||||||||||||||||
| 350 | 1 | A | Neuropixels Ultra (Switchable) | [41.11226992833221, 41.3126363738815, 41.31283... | [2846.700373779901, 2846.903873555326, 2847.07... | [5523.563186354844, 5523.772719456943, 5525.56... | NaN | NaN | [1254.011364748851, 1255.1815634574607, 1257.1... | [4058.995569266862, 4066.4692276858614, 4079.4... | ... | 0 | RS | 379.743122 | 294.0 | 0.948508 | 15.454996 | 0.000077 | 2 | 0.004500 | 0.000231 |
| 351 | 2 | A | Neuropixels Ultra (Switchable) | [43.51170061373816, 73.44483424725053, 83.9988... | [2929.772915437297, 2929.946315245939, 3028.47... | [5525.498517552413, 5530.011012572582, 5531.70... | NaN | NaN | [1303.9912762594438, 1416.535052060088, 1511.8... | [4080.6092454147683, 4235.196274817956, 4295.7... | ... | 0 | RS | 374.245220 | 276.0 | 0.946755 | 15.217587 | 0.000000 | 0 | NaN | 0.000000 |
| 352 | 3 | A | Neuropixels Ultra (Switchable) | [41.37910296719798, 59.87144922636121, 73.4770... | [2911.620335469846, 2954.582488058324, 2960.69... | [5531.838343889337, 5578.430625805066, 5623.63... | NaN | NaN | [1313.877898682248, 1451.1992804725305, 1459.4... | [4066.7330273947414, 4087.219038120433, 4117.8... | ... | 0 | RS | 503.960052 | 348.0 | 0.945747 | 18.880100 | 0.000000 | 0 | NaN | 0.000000 |
| 353 | 4 | A | Neuropixels Ultra (Switchable) | [41.006003378937564, 41.028736687183226, 41.04... | [2846.310140877215, 2846.3254741936266, 2846.3... | [5522.315921064615, 5522.396220975999, 5522.59... | NaN | NaN | [1253.6788651157858, 1253.7315650576281, 1253.... | [4058.8611027485877, 4058.8797360613576, 4058.... | ... | 0 | FSl | 336.366188 | 288.0 | 0.948941 | 14.712279 | 0.000980 | 157 | 0.006001 | 0.002977 |
| 354 | 5 | A | Neuropixels Ultra (Switchable) | [86.90411939405645, 147.6591856802338, 179.421... | [3348.0570871669183, 3410.4427849869217, 3650.... | [5647.04928341326, 5647.519949560517, 5686.992... | NaN | NaN | [1265.0223525975118, 1265.3398189138338, 1288.... | [4440.927181113891, 4503.954878225406, 5197.83... | ... | 0 | RS | 359.901768 | 300.0 | 0.949907 | 15.112158 | 0.000000 | 0 | NaN | 0.000000 |
5 rows × 44 columns
Analysis table properties include both extracted unit spike-time and waveform infomation (amplitude, duration, number or bursts, etc.) but also the timing of spikes during stimulus epochs (e.g. ‘Spontaneous_0_spikes’ are spikes that occurred during the first spontaneous activity epoch).
The analysis table and unit table data can be aligned by the unique ks_units_id column in both tables. For example, to get the spike times of an optotagged unit in the units table:
opto_unit = analysis_table[analysis_table['optotagged']==1].iloc[0]
probe = opto_unit['probe'] #get the probe the unit was recorded on as ks_unit_id is probe-specific
ks_id = opto_unit['ks_unit_id']
spike_times = units_table['spike_times'][(units_table['ks_unit_id']==ks_id)&(units_table['device_name']==f'Probe{probe}')]
spike_times
id
7 [35.05874327545814, 41.39350295130666, 82.9114...
Name: spike_times, dtype: object
Analysis table columns glossary#
Column name |
Definition |
|---|---|
ks_unit_id |
The cluster identifier given to a unit during spike sorting. Can be found in both the analysis and units tables. |
probe |
The label of the probe on which the unit was recorded |
probe_type |
the probe type (e.g. ‘Passive’ or ‘Switchable’) |
Spontaneous_i_spikes |
Spike times (in seconds) for the spontaneous activity epoch of a given index, i (e.g. 0, 1, etc). NaN if this epoch did not occur in the recording. Empty if no spikes occurred in this epoch. Spike times relative to recording start. |
RFMapping_i_spikes |
Spike times (in seconds) for the receptive field mapping epoch of a given index, i (e.g. 0, 1, etc). NaN if this epoch did not occur in the recording. Empty if no spikes occurred in this epoch. Spike times relative to recording start. |
mean_waveform |
|
Spontaneous_i_waveform |
The 384-channel average waveform (in microvolts) of spike that occurred in the spontaneous activity epoch of a given index, i (e.g. 0, 1, etc). NaN if this epoch did not occur in the recording. |
RFMapping_i_waveform |
The 384-channel average waveform (in \(\mu\)V) of spike that occurred in the receptive field mapping epoch of a given index, i (e.g. 0, 1, etc). NaN if this epoch did not occur in the recording. |
amplitude |
The spike amplitude (trough to peak, in \(\mu\)V) recording on the channel with the largest spike amplitude in the average spike waveform. |
duration |
The spike duration (trough to peak, in ms) of the average spike waveform. |
peak_trough_ratio |
The absolute value of the ratio of the amplitudes found at the spike trough and post-trough peak voltage in the average spike waveform. |
pre_peak_trough_ratio |
he absolute value of the ratio of the amplitudes found at the spike trough and pre-trough peak voltage in the average spike waveform. |
repolarization_slope |
The slope of the voltage from the trough to the peak. |
recovery_slope |
The slope of the voltage from the peak back to baseline (typically 0 \(\mu\)V). |
avg_ISI |
The average interspike interval (in seconds) taken across all spike, excluding those during the optotagging epochs. |
baseline_FR |
the average firing rate of spikes taken in the 200 ms window before each optotagging stimulus (used for optotagged neuron identification). |
evoked_FR |
the average firing rate of spikes taken in the optotagging stimulus window duration (used for optotagged neuron identification). |
footprint |
The average radius (in \(\mu\)m) of the spike waveform across the surface the probe before attenuating into noise. |
layer |
The cortical layer a given unit was found in. |
region |
The cortical area a given unit was found in. |
optotagged |
Whether a unit was found to reliably be excited by a photostimulus. 0 for not optotagged, 1 for optotagged. |
Cell type |
The putative cell type for a give unit. Can be “Sim1”, “Tlx3”, ‘RS’, ‘FSl’, or ‘FSs’. |
spread |
The vertical spread (in \(\mu\)m) of a spike waveform along the column of electrodes containing peak amplitude channel. |
bAP_extent |
The distance traveled (in \(\mu\)m) of a detected back-propagating action potential in the average spike waveform. |
bAP_attenuation |
The proportion of the maximum amplitude spike that a bAP attenuates by before falling below noise (~10 \(\mu\)V). |
bAP_idx |
The product of the bAP extent and one minus the bAP attenuation. |
burst_idx |
The ratio of the number of detected burst events to the total number of spikes. |
num_bursts |
The total number of detected burst events. |
burst_dur |
The average duration of a burst (in ms) |
burst_proportion |
The proportion of spikes allocated to burst events. |
Experimental epochs#
You may wish to know the time points at which different parts of the experimental session took place. For instance, you may wish to know when the pre- and post-injection spontaneous activity epochs took place, you can call the epoch table as:
# get the different epochs and their beginning and end times
epochs = nwbfile_read.stimulus['epochs'].to_dataframe()
epochs
| stim_name | start_time | stop_time | |
|---|---|---|---|
| id | |||
| 0 | Spontaneous_0 | 40.98221 | 1242.959627 |
| 1 | RFMapping_0 | 1253.51491 | 2455.941363 |
| 2 | OptoTagging_0 | 2467.50393 | 2706.501100 |
| 3 | Injection | 2706.51110 | 2846.239800 |
| 4 | Spontaneous_1 | 2846.24980 | 4048.293960 |
| 5 | RFMapping_1 | 4058.84910 | 5261.091884 |
| 6 | OptoTagging_1 | 5273.65616 | 5512.558350 |
| 7 | Spontaneous_2 | 5522.10880 | 6724.486726 |
| 8 | RFMapping_2 | 6734.49157 | 7936.617586 |
| 9 | OptoTagging_2 | 7948.99745 | 8187.649770 |
Stimulus data#
The visual stimulus used during these experiments were Gabor patches presented at various orientations and locations on the screen during receptive field mapping epochs. To find trial-specific information for visual stimuli:
# load the stimulus table
stimulus_table = nwbfile_read.stimulus['visualstim'].to_dataframe()
stimulus_table.head()
| start_time | stop_time | stim_name | orientation | posX | posY | |
|---|---|---|---|---|---|---|
| id | ||||||
| 0 | 1253.514910 | 1254.134077 | RFMapping_0 | 315.0 | 798.722753 | 146.240918 |
| 1 | 1254.034077 | 1254.651033 | RFMapping_0 | 270.0 | 159.744551 | -146.240918 |
| 2 | 1254.551033 | 1255.168247 | RFMapping_0 | 315.0 | -159.744551 | -146.240918 |
| 3 | 1255.068247 | 1255.685253 | RFMapping_0 | NaN | NaN | NaN |
| 4 | 1255.585253 | 1256.202437 | RFMapping_0 | NaN | NaN | NaN |
Optotagging laser stimuli parameters, timing, and additional data can be accessed by:
# load the photostim table
photostim_table = nwbfile_read.stimulus['photostim'].to_dataframe()
photostim_table.head()
| start_time | stop_time | power | stim_name | probe | wavelength | |
|---|---|---|---|---|---|---|
| id | ||||||
| 0 | 2467.50393 | 2467.51593 | 13.5 | OptoTagging_0 | D | 488 |
| 1 | 2468.63817 | 2468.65017 | 13.5 | OptoTagging_0 | B | 488 |
| 2 | 2469.93933 | 2470.14133 | 13.5 | OptoTagging_0 | F | 488 |
| 3 | 2471.20807 | 2471.22008 | 13.5 | OptoTagging_0 | F | 488 |
| 4 | 2472.44234 | 2472.64434 | 13.5 | OptoTagging_0 | A | 488 |