def main(nwb, eyetracking_path): io = NWBHDF5IO(nwb, mode="a") nwbfile = io.read() left_et_data, right_et_data = read_eye_tracker_data(eyetracking_path) nwbfile.add_acquisition(left_et_data) nwbfile.add_acquisition(right_et_data) io.write(nwbfile) io.close()
def create_nwb(recording, save_path): """ Use metadata in BonsaiRecordingExtractor to create a NWB files Parameters ---------- recording: BonsaiRecordingExtractor save_path: str nwb_metadata: dict extra metadata info for constructing the nwb file (optional). """ assert HAVE_NWB, NwbRecordingExtractor.installation_mesg assert ( distutils.version.LooseVersion(pynwb.__version__) >= "1.3.3" ), "'write_recording' not supported for version < 1.3.3. Run pip install --upgrade pynwb" # if os.path.exists(save_path): # read_mode = "r+" # else: # read_mode = "w" # Update any previous metadata with user passed dictionary if recording.nwb_metadata is None: recording.nwb_metadata = dict() with NWBHDF5IO(save_path, mode="w") as io: # if read_mode == "r+": # nwbfile = io.read() # else: if "NWBFile" not in recording.nwb_metadata: recording.nwb_metadata["NWBFile"] = { "session_description": "no description", "identifier": str(uuid.uuid4()), "session_start_time": dp.parse(recording.session_start_time), } nwbfile = NWBFile(**recording.nwb_metadata["NWBFile"]) # Required # Add devices nwbfile = add_nwb_devices(recording=recording, nwbfile=nwbfile) # Add electrode groups nwbfile = add_nwb_electrode_groups(recording=recording, nwbfile=nwbfile) # Add electrodes nwbfile = add_nwb_electrodes(recording=recording, nwbfile=nwbfile) # Add electrical series nwbfile = add_nwb_electrical_series(recording=recording, nwbfile=nwbfile) # Add time series (if any) nwbfile = add_nwb_time_series(recording=recording, nwbfile=nwbfile) # Write to file io.write(nwbfile)
def write_recording(recording, save_path, acquisition_name='ElectricalSeries'): assert HAVE_NWB, "To use the Nwb extractors, install pynwb: \n\n pip install pynwb\n\n" M = recording.get_num_channels() nwbfile = NWBFile( session_description='', identifier='', session_start_time=datetime.now(), ) device = nwbfile.create_device(name='device_name') eg_name = 'electrode_group_name' eg_description = "electrode_group_description" eg_location = "electrode_group_location" electrode_group = nwbfile.create_electrode_group( name=eg_name, location=eg_location, device=device, description=eg_description ) for m in range(M): location = recording.get_channel_property(m, 'location') impedence = -1.0 while len(location) < 3: location = np.append(location, [0]) nwbfile.add_electrode( id=m, x=float(location[0]), y=float(location[1]), z=float(location[2]), imp=impedence, location='electrode_location', filtering='none', group=electrode_group, ) electrode_table_region = nwbfile.create_electrode_table_region( list(range(M)), 'electrode_table_region' ) rate = recording.get_sampling_frequency() ephys_data = recording.get_traces().T ephys_ts = ElectricalSeries( name=acquisition_name, data=ephys_data, electrodes=electrode_table_region, starting_time=recording.frame_to_time(0), rate=rate, resolution=1e-6, comments='Generated from SpikeInterface::NwbRecordingExtractor', description='acquisition_description' ) nwbfile.add_acquisition(ephys_ts) if os.path.exists(save_path): os.remove(save_path) with NWBHDF5IO(save_path, 'w') as io: io.write(nwbfile)
def get_data(data_sheet, imaging_folder, nwb_output_path): sbj_details = get_subject_sheet(data_sheet) all_imaging_times = pd.DataFrame() for sheet in sbj_details: subject_sheet = pd.read_excel(data_sheet, sheet_name=sheet, index_col=0) times, imaging_times_list = get_times_from_sheet(subject_sheet) data = pd.DataFrame(imaging_times_list) all_imaging_times = all_imaging_times.append(data) for i in sbj_details: subject_sheet = pd.read_excel(data_sheet, sheet_name=i, index_col=0) times, imaging_times_list = get_times_from_sheet(subject_sheet) if len(imaging_times_list) > 0: twop_folders = update_2p_spreadsheet(data_sheet, i, imaging_folder, imaging_times_list, all_imaging_times) tif_paths = [] for folder_time in twop_folders: for file in os.listdir( os.path.join(imaging_folder, folder_time)): if file.endswith('_XYT.tif'): tif_paths.append( os.path.join(imaging_folder, folder_time, folder_time + '_XYT.tif')) if len(tif_paths) > 0: mouse_id, exp_date, session_start, mouse_date_folder, output_filepath = \ mouse_folder_details(subject_sheet, data_sheet, imaging_times_list, nwb_output_path) source, session_description, identifier, session_start_time, lab, institution, experiment_description, \ virus = nwb_file_variables(imaging_folder,subject_sheet, mouse_id, exp_date, session_start) nwb_file = NWBFile( source=source, session_description=session_description, identifier=identifier, session_start_time=session_start_time, lab=lab, institution=institution, experiment_description=experiment_description, virus=virus) tifs = twop_ts(data_sheet, imaging_times_list, nwb_file, twop_folders, imaging_folder, exp_date, tif_paths) file = NWBHDF5IO(output_filepath, manager=get_manager(), mode='w') file.write(nwb_file) file.close()
def __init__(self, inFileOrFolder, outFile, outputFeedbackChannel, compression=True): """ Convert the given ABF file to NWB Keyword arguments: inFileOrFolder -- input file, or folder with multiple files, in ABF v2 format outFile -- target filepath (must not exist) outputFeedbackChannel -- Output ADC data from feedback channels as well (useful for debugging only) compression -- Toggle compression for HDF5 datasets """ inFiles = [] if os.path.isfile(inFileOrFolder): inFiles.append(inFileOrFolder) elif os.path.isdir(inFileOrFolder): inFiles = glob.glob(os.path.join(inFileOrFolder, "*.abf")) else: raise ValueError(f"{inFileOrFolder} is neither a folder nor a path.") self.outputFeedbackChannel = outputFeedbackChannel self.compression = compression self._settings = self._getJSONFiles(inFileOrFolder) self.abfs = [] pyabf.stimulus.Stimulus.protocolStorageDir = ABFConverter.protocolStorageDir for inFile in inFiles: abf = pyabf.ABF(inFile, loadData=False) self.abfs.append(abf) # ensure that the input file matches our expectations self._check(abf) self.refabf = self._getOldestABF() self._checkAll() self.totalSeriesCount = self._getMaxTimeSeriesCount() nwbFile = self._createFile() device = self._createDevice() nwbFile.add_device(device) electrodes = self._createElectrodes(device) nwbFile.add_ic_electrode(electrodes) for i in self._createStimulusSeries(electrodes): nwbFile.add_stimulus(i) for i in self._createAcquiredSeries(electrodes): nwbFile.add_acquisition(i) with NWBHDF5IO(outFile, "w") as io: io.write(nwbFile, cache_spec=True)
def write_recording(recording, save_path, metadata=None): ''' Parameters ---------- recording: RecordingExtractor save_path: str metadata: dict metadata info for constructing the nwb file (optional). ''' check_nwb_install() if os.path.exists(save_path): read_mode = 'r+' else: read_mode = 'w' # Update any previous metadata with user passed dictionary if metadata is None: metadata = dict() if hasattr(recording, 'nwb_metadata'): metadata = update_dict(recording.nwb_metadata, metadata) with NWBHDF5IO(save_path, mode=read_mode) as io: if read_mode == 'r+': nwbfile = io.read() else: if 'NWBFile' not in metadata: metadata['NWBFile'] = { 'session_description': 'no description', 'identifier': str(uuid.uuid4()), 'session_start_time': datetime.now() } nwbfile = NWBFile(**metadata['NWBFile']) # Add devices nwbfile = se.NwbRecordingExtractor.add_devices(recording=recording, nwbfile=nwbfile, metadata=metadata) # Add electrode groups nwbfile = se.NwbRecordingExtractor.add_electrode_groups( recording=recording, nwbfile=nwbfile, metadata=metadata) # Add electrodes nwbfile = se.NwbRecordingExtractor.add_electrodes( recording=recording, nwbfile=nwbfile, metadata=metadata) # Add electrical series nwbfile = se.NwbRecordingExtractor.add_electrical_series( recording=recording, nwbfile=nwbfile, metadata=metadata) # Add epochs nwbfile = se.NwbRecordingExtractor.add_epochs(recording=recording, nwbfile=nwbfile) # Write to file io.write(nwbfile)
def basic_tonotopy(nwbfile, outdir, identifier, ext): io = NWBHDF5IO(nwbfile, 'a') nwb = io.read() proc_dset = nwb.modules['Hilb_54bands'].data_interfaces['ECoG'] rate = proc_dset.rate stim_dur = 0.1 stim_dur_samp = int(stim_dur*rate) # Trials where pure tones were presented pure_tone_idxs = np.logical_or.reduce(( find_mask(nwb, [1, 0, 0, 0, 0]), find_mask(nwb, [0, 1, 0, 0, 0]), find_mask(nwb, [0, 0, 1, 0, 0]), find_mask(nwb, [0, 0, 0, 1, 0]), find_mask(nwb, [0, 0, 0, 0, 1]), )) # Start times of all trials where pure tones were presented pure_tone_times = nwb.trials['start_time'][pure_tone_idxs] # Start time, in samples, of all trials where pure tones were presented start_idxs = (pure_tone_times*rate).astype('int') # Frequency presented in each pure tone trial freqs = np.array(nwb.trials['freqs'][pure_tone_idxs]).astype('float') def get_best_freq(ch): bf, bf_peak_hg = -1, 0 for freq in np.unique(freqs): this_freq_trial_idxs = (freqs == freq) this_freq_start_idxs = start_idxs[this_freq_trial_idxs] this_freq_data = np.stack( proc_dset.data[i:i+stim_dur_samp, ch, 29:36] for i in this_freq_start_idxs ) this_freq_hg = np.average(this_freq_data, axis=-1) this_freq_hg_trial_avg = np.average(this_freq_hg, axis=0) this_freq_peak_hg_response = np.max(this_freq_hg_trial_avg) if this_freq_peak_hg_response > bf_peak_hg: bf, bf_peak_hg = freq, this_freq_peak_hg_response return bf # Frequency that elicits the biggest response on each electrode, in channel order best_freq_ch_order = np.array([get_best_freq(ch) for ch in range(128)]) # coordinates of ECoG electrodes x = nwb.electrodes['x'][:128] y = nwb.electrodes['y'][:128] grid_order = np.array(sorted(range(128), key=lambda i: (x[i], y[i]))) best_freq_grid_layout = np.reshape(best_freq_ch_order[grid_order], (8, 16)) plt.imshow(best_freq_grid_layout) plt.colorbar() plt.savefig(os.path.join(args.outdir, 'basic_tonotopy_{}.{}'.format(identifier, ext)))
def validate(self): filenames = [self.data_filename, self.link_filename] for fn in filenames: if os.path.exists(fn): with NWBHDF5IO(fn, mode='r') as io: errors = pynwb_validate(io) if errors: for err in errors: raise Exception(err)
def get(self, path): io = NWBHDF5IO(str(pathlib.Path(path)), mode='r') nwb = io.read() patch_clamp = [ obj for obj in nwb.objects.values() if obj.neurodata_type == 'PatchClampSeries' ][0] patch_clamp.io = io return patch_clamp
def run_conversion(self, metadata: dict, nwbfile_path: Optional[str] = None, save_to_file: bool = True, conversion_options: Optional[dict] = None, overwrite: bool = False, sorting: Optional[se.SortingExtractor] = None, recording_lfp: Optional[se.RecordingExtractor] = None, timestamps: OptionalArrayType = None): """ Build nwbfile object, auto-populate with minimal values if missing. Parameters ---------- metadata : dict nwbfile_path : Optional[str], optional save_to_file : bool, optional conversion_options : Optional[dict], optional overwrite : bool, optional sorting : SortingExtractor, optional A SortingExtractor object to write to the NWBFile. recording_lfp : RecordingExtractor, optional A RecordingExtractor object to write to the NWBFile. timestamps : ArrayType, optional Array of timestamps obtained from tsync file. """ nwbfile = super().run_conversion( metadata=metadata, save_to_file=False, conversion_options=conversion_options ) if sorting is not None: se.NwbSortingExtractor.write_sorting( sorting=sorting, nwbfile=nwbfile, timestamps=timestamps ) if recording_lfp is not None: se.NwbRecordingExtractor.write_recording( recording=recording_lfp, nwbfile=nwbfile, write_as_lfp=True ) if save_to_file: if nwbfile_path is None: raise TypeError("A path to the output file must be provided, but nwbfile_path got value None") if Path(nwbfile_path).is_file() and not overwrite: mode = "r+" else: mode = "w" with NWBHDF5IO(nwbfile_path, mode=mode) as io: if mode == "r+": nwbfile = io.read() io.write(nwbfile) print(f"NWB file saved at {nwbfile_path}!") else: return nwbfile
def save_param_file(nwb_filename, acq_label, detect='positive'): ''' saves a parameter file to the location of the nwb file to sort. currently hardcoded some default parameters, while reading in some from the file :return: ''' # TODO: Make this more mutable? if detect not in ['positive', 'negative']: raise ValueError('Detect must be "positive" or "negative"') # TODO: make SR calculation better io = NWBHDF5IO(nwb_filename, 'r') nwbfile = io.read() param_filename = os.path.splitext(nwb_filename)[0] + '.prm' prb_filename = os.path.join(os.path.split(nwb_filename)[0], 'se.prb') print('Probe filename is {}'.format(prb_filename)) if not os.path.isfile(prb_filename): FHC_SE_prb_file(prb_filename) print('Sample Rate conversion is kinda hacky\n') time_vec = nwbfile.acquisition[acq_label].timestamps.value sr = np.mean(np.diff(time_vec[:1000]))**-1 gain = nwbfile.acquisition[acq_label].conversion print('Writing parameter file to: {}'.format(param_filename)) fid = open(param_filename, 'w') experiment_name = os.path.splitext(os.path.split(nwb_filename)[1])[0] fid.write('experiment_name = r"{}"\n'.format(experiment_name)) fid.write('prb_file=r"{}"\n'.format(prb_filename)) fid.write( 'traces=dict(raw_data_files=["{}"],voltage_gain={},sample_rate={},n_channels=1,dtype="{}")\n' .format(experiment_name + '.dat', gain, sr, 'float32')) #spikedetekt params fid.write('spikedetekt={}\n') fid.write("spikedetekt['filter_low']={}\n".format(300.)) fid.write("spikedetekt['filter_high_factor']={}\n".format(0.95 * .5)) fid.write("spikedetekt['butter_order']={}\n".format(3)) fid.write("spikedetekt['chunk_size_seconds']={}\n".format(1)) fid.write("spikedetekt['chunk_overlap_seconds']={}\n".format(0.015)) fid.write("spikedetekt['n_excerpts']={}\n".format(50)) fid.write("spikedetekt['excerpt_size_seconds']={}\n".format(1)) fid.write("spikedetekt['threshold_strong_std_factor']={}\n".format(6.5)) fid.write("spikedetekt['threshold_weak_std_factor']={}\n".format(4.)) fid.write("spikedetekt['detect_spikes']='{}'\n".format(detect)) fid.write("spikedetekt['connected_component_join_size']={}\n".format(1)) fid.write("spikedetekt['extract_s_before']={}\n".format(15)) fid.write("spikedetekt['extract_s_after']={}\n".format(15)) fid.write("spikedetekt['n_features_per_channel']={}\n".format(5)) fid.write("spikedetekt['pca_n_waveforms_max']={}\n".format(10000)) # Klustakwik Params fid.write("klustakwik2 = {}\n") fid.write("klustakwik2['num_starting_clusters'] = {}\n".format(25)) fid.close()
def parse_contents(contents, filename): data = contents.encode("utf8").split(b";base64,")[1] if not os.path.exists(UPLOAD_DIRECTORY): os.mkdir(UPLOAD_DIRECTORY) with open(os.path.join(UPLOAD_DIRECTORY, filename), "wb") as fp: fp.write(base64.decodebytes(data)) nwb_io = NWBHDF5IO(os.path.join(UPLOAD_DIRECTORY, filename), 'r') nwbfile = nwb_io.read() return nwbfile
def read_block(self, lazy=False): assert os.path.exists(self.filename), "Cannot locate file: {}".format( self.filename) with NWBHDF5IO(self.filename, mode='r') as io: nwb = io.read() blk = Block()
def get_norm_spike_counts_spont(Sess, binsize=0.05): # binsize in sec: 0.05 s if sys.platform == 'win32': SaveDir = os.path.join(r'C:\Users\slashchevam\Desktop\NPx\Results', Sess) if sys.platform == 'linux': SaveDir = os.path.join('/mnt/gs/departmentN4/Marina/NPx/Results', Sess) os.chdir(SaveDir) f = NWBHDF5IO((Sess + '.nwb'), 'r') data_nwb = f.read() data_hdf = h5py.File((Sess + '_trials.hdf5'), 'r') spont_ind_trials = data_nwb.trials[:].index.values[ data_nwb.trials[:]['stimset'].values == ( 'spontaneous_brightness').encode('utf8')] units_v1_sorted = data_nwb.units[:].sort_values( by='depth')[data_nwb.units[:]['location'] == 'V1'] print("Found ", len(units_v1_sorted), 'units in V1') data_epochs = [] for ind in spont_ind_trials: # Calculate the duration of spont epoch to get the number of bins for spike counts dur = data_nwb.trials[:].loc[ind][ 'stop_time'] - data_nwb.trials[:].loc[ind]['start_time'] bins_n = int(dur / binsize) bins_vec = np.linspace(data_nwb.trials[:].loc[ind]['start_time'], data_nwb.trials[:].loc[ind]['stop_time'], num=bins_n) spike_traces = np.zeros((len(units_v1_sorted), bins_n - 1)) index = 0 for i in units_v1_sorted.index.values: #data_hdf.keys(): un = str(i) spikes_tmp = data_hdf[un]['spike_times'][data_hdf[un]['trial_num'] [:] == ind] counts, bin_edges = np.histogram(spikes_tmp, bins=bins_vec) spike_traces[index, :] = counts index = index + 1 # z-score the entire dataset with the same mean and std spike_traces_norm = st.zscore(spike_traces, axis=1) data_epochs.append(spike_traces_norm) print('Finished spontaneous epoch', ind) data_hdf.close() f.close() return data_epochs
def write_sorting(sorting, save_path, nwbfile_kwargs=None): """ Parameters ---------- sorting: SortingExtractor save_path: str nwbfile_kwargs: optional, dict with optional args of pynwb.NWBFile """ try: from pynwb import NWBHDF5IO from pynwb import NWBFile from pynwb.ecephys import ElectricalSeries except ModuleNotFoundError: raise ModuleNotFoundError( "To use the Nwb extractors, install pynwb: \n\n" "pip install pynwb\n\n") ids = sorting.get_unit_ids() fs = sorting.get_sampling_frequency() if os.path.exists(save_path): io = NWBHDF5IO(save_path, 'r+') nwbfile = io.read() else: io = NWBHDF5IO(save_path, mode='w') input_nwbfile_kwargs = { 'session_start_time': datetime.now(), 'identifier': '', 'session_description': '' } if nwbfile_kwargs is not None: input_nwbfile_kwargs.update(nwbfile_kwargs) nwbfile = NWBFile(**input_nwbfile_kwargs) # Stores spike times for each detected cell (unit) for id in ids: spkt = sorting.get_unit_spike_train(unit_id=id + 1) / fs nwbfile.add_unit(id=id, spike_times=spkt) # 'waveform_mean' and 'waveform_sd' are interesting args to include later io.write(nwbfile) io.close()
def test_ext_nrs(): nrs_survey_table.add_row(pain_intensity_rating=1.1, pain_relief_rating=5.5, relative_pain_intensity_rating=np.nan, pain_unpleasantness=np.nan, unix_timestamp=1588217283) nrs_survey_table.add_row(pain_intensity_rating=np.nan, pain_relief_rating=1, relative_pain_intensity_rating=6, pain_unpleasantness=2.7, unix_timestamp=1588217283) nrs_survey_table.add_row(pain_intensity_rating=5.3, pain_relief_rating=np.nan, relative_pain_intensity_rating=0.8, pain_unpleasantness=2.1, unix_timestamp=1588217283) nrs_survey_table.add_row(pain_intensity_rating=3.7, pain_relief_rating=np.nan, relative_pain_intensity_rating=6, pain_unpleasantness=np.nan, unix_timestamp=1588217283) nwbfile = NWBFile('description', 'id', datetime.now().astimezone()) nwbfile.create_processing_module(name='behavior', description='survey/behavioral data') nwbfile.processing['behavior'].add(nrs_survey_table) with NWBHDF5IO('test_nwb.nwb', 'w') as io: io.write(nwbfile) with NWBHDF5IO('test_nwb.nwb', 'r', load_namespaces=True) as io: nwbfile = io.read() read_table = nwbfile.processing['behavior'].data_interfaces[ 'nrs_survey_table'].to_dataframe() return np.testing.assert_array_equal(nrs_survey_table.to_dataframe(), read_table)
def test_write_dataset_custom_fillvalue(self): a = H5DataIO(np.arange(20).reshape(5, 4), fillvalue=-1) ts = TimeSeries('ts_name', a, 'A', timestamps=np.arange(5)) self.nwbfile.add_acquisition(ts) with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile, cache_spec=False) with File(self.path, 'r') as f: dset = f['/acquisition/ts_name/data'] self.assertTrue(np.all(dset[:] == a.data)) self.assertEqual(dset.fillvalue, -1)
def write(self, content): """Write nwb file handler with colected data into actual file""" logger.info('Writing down content to ' + self.output_file) with NWBHDF5IO(path=self.output_file, mode='w') as nwb_fileIO: nwb_fileIO.write(content) nwb_fileIO.close() logger.info(self.output_file + ' file has been created.') return self.output_file
def test_write_dataset_custom_chunks(self): a = H5DataIO(np.arange(30).reshape(5, 2, 3), chunks=(1, 1, 3)) ts = TimeSeries('ts_name', a, 'A', timestamps=np.arange(5)) self.nwbfile.add_acquisition(ts) with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile) infile = File(self.path, 'r') dset = infile['/acquisition/ts_name/data'] self.assertTrue(np.all(dset[:] == a.data)) self.assertEqual(dset.chunks, (1, 1, 3))
def plotWaveforms(nwbFilePath, channel): # Input Path Here #nwbBasePath = Path('V:/LabUsers/chandravadian/NWB Data/test/') #session = 'P9HMH_032306.nwb' #channel = [1:200] # ===================================================== # ===================================================== if not os.path.exists(nwbFilePath): print('This file does not exist: {}'.format(nwbFilePath)) sys.exit(-1) # Read NWB file io = NWBHDF5IO(nwbFilePath, mode='r') nwbfile = io.read() # get Waveform Means allwaveformLearn = np.asarray(nwbfile.units['waveform_mean_encoding'].data) allwaveformRecog = np.asarray( nwbfile.units['waveform_mean_recognition'].data) # Choose Which Channel Index to Plot waveformLearn = allwaveformLearn[channel, :] waveformRecog = allwaveformLearn[channel, :] # Plot #Plot Learning plt.subplot(1, 2, 1) plt.plot(range(len(waveformLearn)), waveformLearn, color='blue', marker='o', linestyle='dashed', linewidth=1, markersize=3) plt.title('Waveform Mean Learning, session: {}'.format(nwbfile.identifier)) plt.xlabel('time (in ms)') plt.ylabel('\u03BCV') #Plot Recog plt.subplot(1, 2, 2) plt.plot(range(len(waveformRecog)), waveformRecog, color='green', marker='o', linestyle='dashed', linewidth=1, markersize=3) plt.title('Waveform Mean Recognition, session: {}'.format( nwbfile.identifier)) plt.xlabel('time (in ms)') #plt.ylabel('\u03BCV') #Show Plot plt.show()
def write(self, content): '''Write collected NWB content into an actual file. ''' logger.info('Writing down content to ' + self.output_file) with NWBHDF5IO(path=self.output_file, mode='w') as nwb_fileIO: nwb_fileIO.write(content) nwb_fileIO.close() logger.info(self.output_file + ' file has been created.') return self.output_file
def test_write_probe_lfp_file_roundtrip(tmpdir_factory, roundtrip, lfp_data, probe_data, csd_data): expected_csd = xr.DataArray( name="CSD", data=csd_data["csd"], dims=["virtual_channel_index", "time"], coords={ "virtual_channel_index": np.arange(csd_data["csd"].shape[0]), "time": csd_data["relative_window"], "vertical_position": (("virtual_channel_index",), csd_data["csd_locations"][:, 1]), "horizontal_position": (("virtual_channel_index",), csd_data["csd_locations"][:, 0]), } ) expected_lfp = xr.DataArray( name="LFP", data=lfp_data["data"], dims=["time", "channel"], coords=[lfp_data["timestamps"], [2, 1]] ) tmpdir = Path(tmpdir_factory.mktemp("probe_lfp_nwb")) input_data_path = tmpdir / Path("lfp_data.dat") input_timestamps_path = tmpdir / Path("lfp_timestamps.npy") input_channels_path = tmpdir / Path("lfp_channels.npy") input_csd_path = tmpdir / Path("csd.h5") output_path = str(tmpdir / Path("lfp.nwb")) # pynwb.NWBHDF5IO chokes on Path test_lfp_paths = { "input_data_path": input_data_path, "input_timestamps_path": input_timestamps_path, "input_channels_path": input_channels_path, "output_path": output_path } probe_data.update({"lfp": test_lfp_paths}) probe_data.update({"csd_path": input_csd_path}) write_csd_to_h5(path=input_csd_path, **csd_data) np.save(input_timestamps_path, lfp_data["timestamps"], allow_pickle=False) np.save(input_channels_path, lfp_data["subsample_channels"], allow_pickle=False) with open(input_data_path, "wb") as input_data_file: input_data_file.write(lfp_data["data"].tobytes()) write_nwb.write_probe_lfp_file(4242, None, datetime.now(), logging.INFO, probe_data) obt = EcephysNwbSessionApi(path=None, probe_lfp_paths={12345: NWBHDF5IO(output_path, "r").read}) obtained_lfp = obt.get_lfp(12345) obtained_csd = obt.get_current_source_density(12345) xr.testing.assert_equal(obtained_lfp, expected_lfp) xr.testing.assert_equal(obtained_csd, expected_csd)
def setUp(self): numfiles = 3 self.test_temp_files = [tempfile.NamedTemporaryFile() for i in range(numfiles)] # On Windows h5py cannot truncate an open file in write mode. # The temp file will be closed before h5py truncates it # and will be removed during the tearDown step. for i in self.test_temp_files: i.close() self.io = [NWBHDF5IO(i.name) for i in self.test_temp_files] self.f = [i._file for i in self.io]
def test_different_channel_properties(self): for chan_id in self.RX2.get_channel_ids(): self.RX2.clear_channel_property(chan_id,'prop2') self.RX2.set_channel_property(chan_id,'prop_new',chan_id) write_recording(recording=self.RX, nwbfile=self.nwbfile1, metadata=self.metadata_list[0], es_key='es1') write_recording(recording=self.RX2, nwbfile=self.nwbfile1, metadata=self.metadata_list[1], es_key='es2') with NWBHDF5IO(str(self.path1), 'w') as io: io.write(self.nwbfile1) with NWBHDF5IO(str(self.path1), 'r') as io: nwb = io.read() for i, chan_id in enumerate(nwb.electrodes.id.data): if i<len(nwb.electrodes.id.data)/2: assert np.isnan(nwb.electrodes['prop_new'][i]) if i%2 == 0: assert nwb.electrodes['prop2'][i] == chan_id else: assert np.isnan(nwb.electrodes['prop2'][i]) else: assert np.isnan(nwb.electrodes['prop2'][i]) assert nwb.electrodes['prop_new'][i]==chan_id
def test_add_invalid_times(invalid_epochs, tmpdir_factory): nwbfile_name = str(tmpdir_factory.mktemp("test").join("test_invalid_times.nwb")) nwbfile = NWBFile( session_description="EcephysSession", identifier="{}".format(739448407), session_start_time=datetime.now() ) nwbfile = write_nwb.add_invalid_times(nwbfile, invalid_epochs) with NWBHDF5IO(nwbfile_name, mode="w") as io: io.write(nwbfile) nwbfile_in = NWBHDF5IO(nwbfile_name, mode="r").read() df = nwbfile.invalid_times.to_dataframe() df_in = nwbfile_in.invalid_times.to_dataframe() pd.testing.assert_frame_equal(df, df_in, check_like=True, check_dtype=False)
def test_write_dataset_custom_chunks(self): a = H5DataIO(np.arange(30).reshape(5, 2, 3), chunks=(1, 1, 3)) ts = TimeSeries(name='ts_name', data=a, unit='A', timestamps=np.arange(5.)) self.nwbfile.add_acquisition(ts) with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile, cache_spec=False) with File(self.path, 'r') as f: dset = f['/acquisition/ts_name/data'] self.assertTrue(np.all(dset[:] == a.data)) self.assertEqual(dset.chunks, (1, 1, 3))
def test_gzip_timestamps(self): ts = TimeSeries(name='ts_name', data=[1, 2, 3], unit='A', timestamps=H5DataIO(np.array([1., 2., 3.]), compression='gzip')) self.nwbfile.add_acquisition(ts) with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile, cache_spec=False) # confirm that the dataset was indeed compressed with File(self.path, 'r') as f: self.assertEqual(f['/acquisition/ts_name/timestamps'].compression, 'gzip')
def test_write_dataset_datachunkiterator(self): a = np.arange(30).reshape(5, 2, 3) aiter = iter(a) daiter = DataChunkIterator.from_iterable(aiter, buffer_size=2) ts = TimeSeries('ts_name', daiter, 'A', timestamps=np.arange(5)) self.nwbfile.add_acquisition(ts) with NWBHDF5IO(self.path, 'w') as io: io.write(self.nwbfile) infile = File(self.path, 'r') dset = infile['/acquisition/ts_name/data'] self.assertListEqual(dset[:].tolist(), a.tolist())
def preprocess_nwbfile(path, filename): path_to_file = os.path.join(path, filename) nwb_io = NWBHDF5IO(path_to_file, 'r') try: nwb_file = nwb_io.read() except: print("Error loading file " + filename) return experiment = ExperimentFactory.create_experiment(nwb_file.protocol, nwb_file) experiment.preprocess() experiment.save(nwb_file) export_filename = filename.replace('.nwb', '_new.nwb') new_path_to_file = os.path.join(path, export_filename) with NWBHDF5IO(new_path_to_file, mode='w') as export_io: export_io.export(src_io=nwb_io, nwbfile=nwb_file) nwb_io.close() os.remove(path_to_file) os.rename(new_path_to_file, path_to_file)
def test_append(self): proc_mod = self.nwbfile.create_processing_module(name='test_proc_mod', description='') proc_inter = LFP(name='LFP') proc_mod.add(proc_inter) device = self.nwbfile.create_device(name='test_device') e_group = self.nwbfile.create_electrode_group( name='test_electrode_group', description='', location='', device=device ) self.nwbfile.add_electrode(x=0.0, y=0.0, z=0.0, imp=np.nan, location='', filtering='', group=e_group) electrodes = self.nwbfile.create_electrode_table_region(region=[0], description='') e_series = ElectricalSeries( name='test_es', electrodes=electrodes, data=np.ones(shape=(100,)), rate=10000.0, ) proc_inter.add_electrical_series(e_series) with NWBHDF5IO(self.path, mode='w') as io: io.write(self.nwbfile, cache_spec=False) with NWBHDF5IO(self.path, mode='a') as io: nwb = io.read() link_electrodes = nwb.processing['test_proc_mod']['LFP'].electrical_series['test_es'].electrodes ts2 = ElectricalSeries(name='timeseries2', data=[4., 5., 6.], rate=1.0, electrodes=link_electrodes) nwb.add_acquisition(ts2) io.write(nwb) # also attempt to write same spec again self.assertIs(nwb.processing['test_proc_mod']['LFP'].electrical_series['test_es'].electrodes, nwb.acquisition['timeseries2'].electrodes) with NWBHDF5IO(self.path, mode='r') as io: nwb = io.read() np.testing.assert_equal(nwb.acquisition['timeseries2'].data[:], ts2.data) self.assertIs(nwb.processing['test_proc_mod']['LFP'].electrical_series['test_es'].electrodes, nwb.acquisition['timeseries2'].electrodes) errors = validate(io) for e in errors: print('ERROR', e)