def __get_single_fl_task(self, task_name, task_description, camera_id, task_epochs, task_environment): task_name_data = VectorData(name='task_name', description='the name of the task', data=[task_name]) task_description_data = VectorData( name='task_description', description='a description of the task', data=[task_description]) camera_id_data = VectorData( name='camera_id', description='the ID number of the camera used for video', data=[camera_id]) task_epochs_data = VectorData( name='task_epochs', description= 'the temporal epochs where the animal was exposed to this task', data=[task_epochs]) environment_data = VectorData( name='task_environment', description= 'the environment in which the animal performed the task', data=[task_environment]) task = TaskBuilder.build(name='task_' + str(self.task_counter), description='', task_name=task_name_data, task_description=task_description_data, camera_id=camera_id_data, task_epochs=task_epochs_data, task_environment=environment_data) self.task_counter += 1 return task
def test_DynamicTableRegion_shape_validation(self): # Create a test DynamicTable dt_spec = [ { 'name': 'foo', 'description': 'foo column' }, { 'name': 'bar', 'description': 'bar column' }, { 'name': 'baz', 'description': 'baz column' }, ] dt_data = [[1, 2, 3, 4, 5], [10.0, 20.0, 30.0, 40.0, 50.0], ['cat', 'dog', 'bird', 'fish', 'lizard']] columns = [ VectorData(name=s['name'], description=s['description'], data=d) for s, d in zip(dt_spec, dt_data) ] dt = DynamicTable("with_columns_and_data", "a test table", columns=columns) # Create test DynamicTableRegion dtr = DynamicTableRegion('dtr', [1, 2, 2], 'desc', table=dt) # Confirm that the shapes match res = assertEqualShape(dtr, np.arange(9).reshape(3, 3)) self.assertTrue(res.result)
def test_task_creator_create_task_and_write_to_nwb_successfully(self): nwb_content = NWBFile(session_description='demonstrate external files', identifier='NWBE1', session_start_time=datetime(2017, 4, 3, 11, tzinfo=tzlocal()), file_create_date=datetime(2017, 4, 15, 12, tzinfo=tzlocal())) processing_module = ProcessingModule('pm', 'none') mock_fl_task_0 = Mock(spec=FlTask) mock_fl_task_0.name = 'task_0' mock_fl_task_0.description = '' mock_fl_task_0.columns = [ VectorData(name='task_name', description='', data=['Sleep']), VectorData(name='task_description', description='', data=['The animal sleeps in a small empty box.']), VectorData(name='camera_id', description='', data=[[0]]), VectorData(name='task_epochs', description='', data=[[1, 3, 5]]), ] mock_fl_task_1 = Mock(spec=FlTask) mock_fl_task_1.name = 'task_1' mock_fl_task_1.description = '' mock_fl_task_1.columns = [ VectorData(name='task_name', description='', data=['Stem+Leaf']), VectorData(name='task_description', description='', data=['Spatial Bandit']), VectorData(name='camera_id', description='', data=[[1, 2]]), VectorData(name='task_epochs', description='', data=[[2, 4]]), ] task_0 = TaskCreator.create(mock_fl_task_0) task_1 = TaskCreator.create(mock_fl_task_1) processing_module.add(task_0) processing_module.add(task_1) nwb_content.add_processing_module(processing_module) with NWBHDF5IO(path='task.nwb', mode='w') as nwb_file_io: nwb_file_io.write(nwb_content) nwb_file_io.close() with NWBHDF5IO(path='task.nwb', mode='r') as nwb_file_io: nwb_content = nwb_file_io.read() self.assertContainerEqual( nwb_content.processing['pm'].data_interfaces['task_0'], task_0) self.assertContainerEqual( nwb_content.processing['pm'].data_interfaces['task_1'], task_1) os.remove('task.nwb')
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]) vd1 = VectorData('Data1', 'vector data for creating a DynamicTable', data=data1) vd2 = VectorData('Data2', 'vector data for creating a DynamicTable', data=data2) vd = [vd1, vd2] dynamic_table = DynamicTable(name='test table', description='This is a test table', columns=vd, colnames=['Data1', 'Data2']) assert dicts_exact_equal(infer_categorical_columns(dynamic_table), { 'Data1': np.array([1, 2, 3]), 'Data2': np.array([2, 3, 4]) })
def test_surgery(): nwbfile = NWBFile('session description', 'session id', datetime.now(tzlocal()), experimenter='experimenter name', lab='lab name', institution='institution name', experiment_description=('experiment description'), session_id='sessionid') surgery_tempo = Surgery( surgery_date='0000-0-0', implantation_device='my_implantationdevice', ophys_implant_name='myophysimplantname', virus_injection_id='virusID', virus_injection_opsin_l_r='R', virus_injection_coordinates='[1.0, 2.0, 3.0]', ophys_injection_date='000-00-00', ophys_injection_flr_protein_data=DynamicTable( name='name', description='ophys_data', columns=[ VectorData(name='protein_name', description='protein_name_column', data=['protein1', 'protein2']), Measurement(name='protein_concentration', description='protein_conc_column', data=[2e12, 5e12], unit='ml') ])) mouse_data_tempo = SubjectComplete(name='mouse_metadata', surgery_data=surgery_tempo, sacrificial_date='0000-00-00', strain='myanimalstrain') nwbfile.subject = mouse_data_tempo # testing nwbfile addition: assert_array_equal( nwbfile.subject.surgery_data.ophys_injection_flr_protein_data. columns[1].data, [2e12, 5e12]) assert_array_equal( nwbfile.subject.surgery_data.virus_injection_coordinates, [1.0, 2.0, 3.0]) with NWBHDF5IO('test_device_surgery.nwb', 'w') as io: io.write(nwbfile) del nwbfile with NWBHDF5IO('test_device_surgery.nwb', 'r', load_namespaces=True) as io: nwb = io.read() assert_array_equal( nwb.subject.surgery_data.ophys_injection_flr_protein_data. columns[1].data, [2e12, 5e12]) assert_array_equal( nwb.subject.surgery_data.virus_injection_coordinates, [1.0, 2.0, 3.0])
def create_ragged_array(name, values): """ :param values: list of lists :return: """ vector_data = VectorData( name, 'indicates which compartments the data refers to', [item for sublist in values for item in sublist]) vector_index = VectorIndex(name + '_index', np.cumsum([len(x) for x in values]), target=vector_data) return vector_data, vector_index
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 write_segmentation( segext_obj: SegmentationExtractor, save_path: PathType = None, plane_num=0, metadata: dict = None, overwrite: bool = True, buffer_size: int = 10, nwbfile=None, ): assert ( save_path is None or nwbfile is None ), "Either pass a save_path location, or nwbfile object, but not both!" # parse metadata correctly: if isinstance(segext_obj, MultiSegmentationExtractor): segext_objs = segext_obj.segmentations if metadata is not None: assert isinstance(metadata, list), ( "For MultiSegmentationExtractor enter 'metadata' as a list of " "SegmentationExtractor metadata") assert len(metadata) == len(segext_objs), ( "The 'metadata' argument should be a list with the same " "number of elements as the segmentations in the " "MultiSegmentationExtractor") else: segext_objs = [segext_obj] if metadata is not None and not isinstance(metadata, list): metadata = [metadata] metadata_base_list = [ NwbSegmentationExtractor.get_nwb_metadata(sgobj) for sgobj in segext_objs ] print(f"writing nwb for {segext_obj.extractor_name}\n") # updating base metadata with new: for num, data in enumerate(metadata_base_list): metadata_input = metadata[num] if metadata else {} metadata_base_list[num] = dict_recursive_update( metadata_base_list[num], metadata_input) metadata_base_common = metadata_base_list[0] # build/retrieve nwbfile: if nwbfile is not None: assert isinstance( nwbfile, NWBFile), "'nwbfile' should be of type pynwb.NWBFile" write = False else: write = True save_path = Path(save_path) assert save_path.suffix == ".nwb" if save_path.is_file() and not overwrite: nwbfile_exist = True file_mode = "r+" else: if save_path.is_file(): os.remove(save_path) if not save_path.parent.is_dir(): save_path.parent.mkdir(parents=True) nwbfile_exist = False file_mode = "w" io = NWBHDF5IO(str(save_path), file_mode) if nwbfile_exist: nwbfile = io.read() else: nwbfile = NWBFile(**metadata_base_common["NWBFile"]) # Subject: if metadata_base_common.get("Subject") and nwbfile.subject is None: nwbfile.subject = Subject(**metadata_base_common["Subject"]) # Processing Module: if "ophys" not in nwbfile.processing: ophys = nwbfile.create_processing_module( "ophys", "contains optical physiology processed data") else: ophys = nwbfile.get_processing_module("ophys") for plane_no_loop, (segext_obj, metadata) in enumerate( zip(segext_objs, metadata_base_list)): # Device: if metadata["Ophys"]["Device"][0]["name"] not in nwbfile.devices: nwbfile.create_device(**metadata["Ophys"]["Device"][0]) # ImageSegmentation: image_segmentation_name = ( "ImageSegmentation" if plane_no_loop == 0 else f"ImageSegmentation_Plane{plane_no_loop}") if image_segmentation_name not in ophys.data_interfaces: image_segmentation = ImageSegmentation( name=image_segmentation_name) ophys.add(image_segmentation) else: image_segmentation = ophys.data_interfaces.get( image_segmentation_name) # OpticalChannel: optical_channels = [ OpticalChannel(**i) for i in metadata["Ophys"]["ImagingPlane"] [0]["optical_channel"] ] # ImagingPlane: image_plane_name = ("ImagingPlane" if plane_no_loop == 0 else f"ImagePlane_{plane_no_loop}") if image_plane_name not in nwbfile.imaging_planes.keys(): input_kwargs = dict( name=image_plane_name, device=nwbfile.get_device( metadata_base_common["Ophys"]["Device"][0]["name"]), ) metadata["Ophys"]["ImagingPlane"][0][ "optical_channel"] = optical_channels input_kwargs.update(**metadata["Ophys"]["ImagingPlane"][0]) if "imaging_rate" in input_kwargs: input_kwargs["imaging_rate"] = float( input_kwargs["imaging_rate"]) imaging_plane = nwbfile.create_imaging_plane(**input_kwargs) else: imaging_plane = nwbfile.imaging_planes[image_plane_name] # PlaneSegmentation: input_kwargs = dict( description="output from segmenting imaging plane", imaging_plane=imaging_plane, ) ps_metadata = metadata["Ophys"]["ImageSegmentation"][ "plane_segmentations"][0] if ps_metadata[ "name"] not in image_segmentation.plane_segmentations: ps_exist = False else: ps = image_segmentation.get_plane_segmentation( ps_metadata["name"]) ps_exist = True roi_ids = segext_obj.get_roi_ids() accepted_list = segext_obj.get_accepted_list() accepted_list = [] if accepted_list is None else accepted_list rejected_list = segext_obj.get_rejected_list() rejected_list = [] if rejected_list is None else rejected_list accepted_ids = [1 if k in accepted_list else 0 for k in roi_ids] rejected_ids = [1 if k in rejected_list else 0 for k in roi_ids] roi_locations = np.array(segext_obj.get_roi_locations()).T def image_mask_iterator(): for id in segext_obj.get_roi_ids(): img_msks = segext_obj.get_roi_image_masks( roi_ids=[id]).T.squeeze() yield img_msks if not ps_exist: input_kwargs.update( **ps_metadata, columns=[ VectorData( data=H5DataIO( DataChunkIterator(image_mask_iterator(), buffer_size=buffer_size), compression=True, compression_opts=9, ), name="image_mask", description="image masks", ), VectorData( data=roi_locations, name="RoiCentroid", description= "x,y location of centroid of the roi in image_mask", ), VectorData( data=accepted_ids, name="Accepted", description= "1 if ROi was accepted or 0 if rejected as a cell during segmentation operation", ), VectorData( data=rejected_ids, name="Rejected", description= "1 if ROi was rejected or 0 if accepted as a cell during segmentation operation", ), ], id=roi_ids, ) ps = image_segmentation.create_plane_segmentation( **input_kwargs) # Fluorescence Traces: if "Flourescence" not in ophys.data_interfaces: fluorescence = Fluorescence() ophys.add(fluorescence) else: fluorescence = ophys.data_interfaces["Fluorescence"] roi_response_dict = segext_obj.get_traces_dict() roi_table_region = ps.create_roi_table_region( description=f"region for Imaging plane{plane_no_loop}", region=list(range(segext_obj.get_num_rois())), ) rate = (np.float("NaN") if segext_obj.get_sampling_frequency() is None else segext_obj.get_sampling_frequency()) for i, j in roi_response_dict.items(): data = getattr(segext_obj, f"_roi_response_{i}") if data is not None: data = np.asarray(data) trace_name = "RoiResponseSeries" if i == "raw" else i.capitalize( ) trace_name = (trace_name if plane_no_loop == 0 else trace_name + f"_Plane{plane_no_loop}") input_kwargs = dict( name=trace_name, data=data.T, rois=roi_table_region, rate=rate, unit="n.a.", ) if trace_name not in fluorescence.roi_response_series: fluorescence.create_roi_response_series(**input_kwargs) # create Two Photon Series: if "TwoPhotonSeries" not in nwbfile.acquisition: warn( "could not find TwoPhotonSeries, using ImagingExtractor to create an nwbfile" ) # adding images: images_dict = segext_obj.get_images_dict() if any([image is not None for image in images_dict.values()]): images_name = ("SegmentationImages" if plane_no_loop == 0 else f"SegmentationImages_Plane{plane_no_loop}") if images_name not in ophys.data_interfaces: images = Images(images_name) for img_name, img_no in images_dict.items(): if img_no is not None: images.add_image( GrayscaleImage(name=img_name, data=img_no.T)) ophys.add(images) # saving NWB file: if write: io.write(nwbfile) io.close() # test read with NWBHDF5IO(str(save_path), "r") as io: io.read()
def copy_obj(obj_old, nwb_old, nwb_new): """ Creates a copy of obj_old. """ # ElectricalSeries -------------------------------------------------------- if type(obj_old) is ElectricalSeries: nChannels = obj_old.electrodes.table['x'].data.shape[0] elecs_region = nwb_new.electrodes.create_region( name='electrodes', region=np.arange(nChannels).tolist(), description='' ) return ElectricalSeries( name=obj_old.name, data=obj_old.data[:], electrodes=elecs_region, rate=obj_old.rate, description=obj_old.description ) # DynamicTable ------------------------------------------------------------ if type(obj_old) is DynamicTable: return DynamicTable( name=obj_old.name, description=obj_old.description, colnames=obj_old.colnames, columns=obj_old.columns, ) # LFP --------------------------------------------------------------------- if type(obj_old) is LFP: obj = LFP(name=obj_old.name) assert len(obj_old.electrical_series) == 1, ( 'Expected precisely one electrical series, got %i!' % len(obj_old.electrical_series)) els = list(obj_old.electrical_series.values())[0] nChannels = els.data.shape[1] #### # first check for a table among the new file's data_interfaces if els.electrodes.table.name in nwb_new.processing[ 'ecephys'].data_interfaces: LFP_dynamic_table = nwb_new.processing['ecephys'].data_interfaces[ els.electrodes.table.name] else: # othewise use the electrodes as the table LFP_dynamic_table = nwb_new.electrodes #### elecs_region = LFP_dynamic_table.create_region( name='electrodes', region=[i for i in range(nChannels)], description=els.electrodes.description ) obj_ts = obj.create_electrical_series( name=els.name, comments=els.comments, conversion=els.conversion, data=els.data[:], description=els.description, electrodes=elecs_region, rate=els.rate, resolution=els.resolution, starting_time=els.starting_time ) return obj # TimeSeries -------------------------------------------------------------- if type(obj_old) is TimeSeries: return TimeSeries( name=obj_old.name, description=obj_old.description, data=obj_old.data[:], rate=obj_old.rate, resolution=obj_old.resolution, conversion=obj_old.conversion, starting_time=obj_old.starting_time, unit=obj_old.unit ) # DecompositionSeries ----------------------------------------------------- if type(obj_old) is DecompositionSeries: list_columns = [] for item in obj_old.bands.columns: bp = VectorData( name=item.name, description=item.description, data=item.data[:] ) list_columns.append(bp) bandsTable = DynamicTable( name=obj_old.bands.name, description=obj_old.bands.description, columns=list_columns, colnames=obj_old.bands.colnames ) return DecompositionSeries( name=obj_old.name, data=obj_old.data[:], description=obj_old.description, metric=obj_old.metric, unit=obj_old.unit, rate=obj_old.rate, # source_timeseries=lfp, bands=bandsTable, ) # Spectrum ---------------------------------------------------------------- if type(obj_old) is Spectrum: file_elecs = nwb_new.electrodes nChannels = len(file_elecs['x'].data[:]) elecs_region = file_elecs.create_region( name='electrodes', region=np.arange(nChannels).tolist(), description='' ) return Spectrum( name=obj_old.name, frequencies=obj_old.frequencies[:], power=obj_old.power, electrodes=elecs_region )
def spectral_decomposition(block_path, bands_vals): """ Takes preprocessed LFP data and does the standard Hilbert transform on different bands. Takes about 20 minutes to run on 1 10-min block. Parameters ---------- block_path : str subject file path bands_vals : [2,nBands] numpy array with Gaussian filter parameters, where: bands_vals[0,:] = filter centers [Hz] bands_vals[1,:] = filter sigmas [Hz] Returns ------- Saves spectral power (DecompositionSeries) in the current NWB file. Only if container for this data do not exist in the file. """ # Get filter parameters band_param_0 = bands_vals[0, :] band_param_1 = bands_vals[1, :] with NWBHDF5IO(block_path, 'r+', load_namespaces=True) as io: nwb = io.read() lfp = nwb.processing['ecephys'].data_interfaces[ 'LFP'].electrical_series['preprocessed'] rate = lfp.rate nBands = len(band_param_0) nSamples = lfp.data.shape[0] nChannels = lfp.data.shape[1] Xp = np.zeros( (nBands, nChannels, nSamples)) #power (nBands,nChannels,nSamples) # Apply Hilbert transform --------------------------------------------- print('Running Spectral Decomposition...') start = time.time() for ch in np.arange(nChannels): Xch = lfp.data[:, ch] * 1e6 # 1e6 scaling helps with numerical accuracy Xch = Xch.reshape(1, -1) Xch = Xch.astype('float32') # signal (nChannels,nSamples) X_fft_h = None for ii, (bp0, bp1) in enumerate(zip(band_param_0, band_param_1)): kernel = gaussian(Xch, rate, bp0, bp1) X_analytic, X_fft_h = hilbert_transform(Xch, rate, kernel, phase=None, X_fft_h=X_fft_h) Xp[ii, ch, :] = abs(X_analytic).astype('float32') print('Spectral Decomposition finished in {} seconds'.format( time.time() - start)) # data: (ndarray) dims: num_times * num_channels * num_bands Xp = np.swapaxes(Xp, 0, 2) # Spectral band power # bands: (DynamicTable) frequency bands that signal was decomposed into band_param_0V = VectorData( name='filter_param_0', description='frequencies for bandpass filters', data=band_param_0) band_param_1V = VectorData( name='filter_param_1', description='frequencies for bandpass filters', data=band_param_1) bandsTable = DynamicTable( name='bands', description='Series of filters used for Hilbert transform.', columns=[band_param_0V, band_param_1V], colnames=['filter_param_0', 'filter_param_1']) decs = DecompositionSeries( name='DecompositionSeries', data=Xp, description='Analytic amplitude estimated with Hilbert transform.', metric='amplitude', unit='V', bands=bandsTable, rate=rate, source_timeseries=lfp) # Storage of spectral decomposition on NWB file ------------------------ ecephys_module = nwb.processing['ecephys'] ecephys_module.add_data_interface(decs) io.write(nwb) print('Spectral decomposition saved in ' + block_path)
def get_bipolar_referenced_electrodes(X, electrodes, rate, grid_size=None, grid_step=1): ''' Bipolar referencing of electrodes according to the scheme of Dr. John Burke Each electrode (with obvious exceptions at the edges) yields two bipolar- referenced channels, one for the "right" and one for the "below" neighbors. These are returned as an ElectricalSeries. Input arguments: -------- X: numpy array containing (raw) electrode traces (Nelectrodes x T) electrodes: DynamicTableRegion containing the metadata for the electrodes whose traces are in X rate: sampling rate of X; for storage in ElectricalSeries grid_size: numpy array with the two dimensions of the grid (2, ) Returns: -------- bipolarElectrodes: ElectricalSeries containing the bipolar-referenced (pseudo) electrodes and associated metadata. (NB that a, e.g., 16x16 grid yields 960 of these pseudo-electrodes.) ''' # set mutable default argument(s) if grid_size is None: grid_size = np.array([16, 16]) # malloc elec_layout = np.arange(np.prod(grid_size) - 1, -1, -1).reshape(grid_size).T elec_layout = elec_layout[::grid_step, ::grid_step] grid_size = elec_layout.T.shape # in case grid_step > 1 Nchannels = 2 * np.prod(grid_size) - np.sum(grid_size) XX = np.zeros((Nchannels, X.shape[1])) # create a new dynamic table to hold the metadata column_names = ['x', 'y', 'z', 'imp', 'location', 'label', 'bad'] columns = [ VectorData(name=name, description=electrodes.table[name].description) for name in column_names ] bipolarTable = DynamicTable( name='bipolar-referenced metadata', description=('pseudo-channels derived via John Burke style' ' bipolar referencing'), colnames=column_names, columns=columns, ) # compute bipolar-ref'd channel and add a new row of metadata to table def add_new_channel(iChannel, iElectrode, jElectrode): jElectrode = int(jElectrode) # "bipolar referencing": the difference of neighboring electrodes XX[iChannel, :] = X[iElectrode, :] - X[jElectrode, :] # add a row to the table for this new pseudo-electrode bipolarTable.add_row({ 'location': '_'.join({ electrodes.table['location'][iElectrode], electrodes.table['location'][jElectrode] }), 'label': '-'.join([ electrodes.table['label'][iElectrode], electrodes.table['label'][jElectrode] ]), 'bad': (electrodes.table['bad'][iElectrode] or electrodes.table['bad'][jElectrode]), **{ name: electrodes.table[name][iElectrode] for name in ['x', 'y', 'z', 'imp'] }, }) return iChannel + 1 iChannel = 0 # loop across columns and rows (remembering that grid is transposed) for i in range(grid_size[1]): for j in range(grid_size[0]): if j < grid_size[0] - 1: iChannel = add_new_channel(iChannel, elec_layout[i, j], elec_layout[i, j + 1]) if i < grid_size[1] - 1: iChannel = add_new_channel(iChannel, elec_layout[i, j], elec_layout[i + 1, j]) # create one big region for the entire table bipolarTableRegion = bipolarTable.create_region( 'electrodes', [i for i in range(Nchannels)], 'all bipolar electrodes') return XX, bipolarTable, bipolarTableRegion
def test_device(): nwbfile = NWBFile('session description', 'session id', datetime.now(tzlocal()), experimenter='experimenter name', lab='lab name', institution='institution name', experiment_description=('experiment description'), session_id='sessionid') laserline_device = LaserLine(name='mylaserline1', reference='test_ref_laserline', analog_modulation_frequency=Measurement( name='None', description='None', unit='Hz', data=[100]), power=Measurement(name='None', description='None', unit='uW', data=[100])) laserline_devices_ = LaserLineDevices() laserline_devices_.add_laserline(laserline_device) laserline_devices_.create_laserline( name='mylaserline2', reference='test_ref_laserline', analog_modulation_frequency=Measurement(name='None', description='None', unit='Hz', data=[100]), power=Measurement(name='None', description='None', unit='uW', data=[100])) photodetector_device = PhotoDetector(name='myphotodetector1', reference='test_ref_photodetector', gain=Measurement(name='None', description='None', unit='Hz', data=[1]), bandwidth=Measurement( name='None', description='None', unit='uW', data=[50])) photodetector_devices_ = PhotoDetectorDevices() photodetector_devices_.add_photodetector(photodetector_device) lockinamp_device = LockInAmplifier(name='mylockinamp', demodulation_filter_order=10.0, reference='test_ref', demod_bandwidth=Measurement( name='None', description='None', unit='Hz', data=[150]), columns=[ VectorData(name='channel_name', description='None', data=['name1', 'name2']), Measurement(name='offset', description='None', unit='mV', data=[140, 260]), VectorData(name='gain', description='None', data=[250, 250]) ]) lockinamp_devices_ = LockInAmplifierDevices() lockinamp_devices_.add_lockinamp(lockinamp_device) nwbfile.add_device( TEMPO(name='tempo_test', laserline_devices=laserline_devices_, photodetector_devices=photodetector_devices_, lockinamp_devices=lockinamp_devices_)) # testing laserline_device assert_array_equal( np.array(nwbfile.devices['tempo_test'].laserline_devices.children[0]. analog_modulation_frequency.data), np.array([100])) # testing photodetector_device assert_array_equal( np.array(nwbfile.devices['tempo_test'].photodetector_devices. children[0].bandwidth.data), np.array([50])) # testing lockinamp_device assert_array_equal( np.array(nwbfile.devices['tempo_test'].lockinamp_devices.children[0]. columns[1].data), np.array([140, 260])) with NWBHDF5IO('test_ndx-tempo.nwb', 'w') as io: io.write(nwbfile) del nwbfile with NWBHDF5IO('test_ndx-tempo.nwb', 'r', load_namespaces=True) as io: nwb = io.read() # testing laserline_device assert_array_equal( np.array(nwb.devices['tempo_test'].laserline_devices.children[0]. analog_modulation_frequency.data), np.array([100])) # testing photodetector_device assert_array_equal( np.array(nwb.devices['tempo_test'].photodetector_devices. children[0].bandwidth.data), np.array([50])) # testing lockinamp_device assert_array_equal( np.array(nwb.devices['tempo_test'].lockinamp_device.children[0]. columns[1].data), np.array([140, 260]))
def copy_obj(obj_old, nwb_old, nwb_new): """ Creates a copy of obj_old. """ # ElectricalSeries -------------------------------------------------------- if type(obj_old) is ElectricalSeries: # If reference electrodes table is bipolar scheme if isinstance(obj_old.electrodes.table, BipolarSchemeTable): bst_old = obj_old.electrodes.table bst_old_df = bst_old.to_dataframe() bst_new = nwb_new.lab_meta_data['ecephys_ext'].bipolar_scheme_table for id, row in bst_old_df.iterrows(): index_anodes = row['anodes'].index.tolist() index_cathodes = row['cathodes'].index.tolist() bst_new.add_row(anodes=index_anodes, cathodes=index_cathodes) bst_new.anodes.table = nwb_new.electrodes bst_new.cathodes.table = nwb_new.electrodes # if there are custom columns new_cols = list(bst_old_df.columns) default_cols = ['anodes', 'cathodes'] [new_cols.remove(col) for col in default_cols] for col in new_cols: col_data = list(bst_old[col].data[:]) bst_new.add_column(name=str(col), description=str(bst_old[col].description), data=col_data) elecs_region = DynamicTableRegion(name='electrodes', data=bst_old_df.index.tolist(), description='desc', table=bst_new) else: region = np.array(obj_old.electrodes.table.id[:])[ obj_old.electrodes.data[:]].tolist() elecs_region = nwb_new.create_electrode_table_region( name='electrodes', region=region, description='') els = ElectricalSeries(name=obj_old.name, data=obj_old.data[:], electrodes=elecs_region, rate=obj_old.rate, description=obj_old.description) return els # DynamicTable ------------------------------------------------------------ if type(obj_old) is DynamicTable: return DynamicTable( name=obj_old.name, description=obj_old.description, colnames=obj_old.colnames, columns=obj_old.columns, ) # LFP --------------------------------------------------------------------- if type(obj_old) is LFP: obj = LFP(name=obj_old.name) assert len(obj_old.electrical_series) == 1, ( 'Expected precisely one electrical series, got %i!' % len(obj_old.electrical_series)) els = list(obj_old.electrical_series.values())[0] #### # first check for a table among the new file's data_interfaces if els.electrodes.table.name in nwb_new.processing[ 'ecephys'].data_interfaces: LFP_dynamic_table = nwb_new.processing['ecephys'].data_interfaces[ els.electrodes.table.name] else: # othewise use the electrodes as the table LFP_dynamic_table = nwb_new.electrodes #### region = np.array( els.electrodes.table.id[:])[els.electrodes.data[:]].tolist() elecs_region = LFP_dynamic_table.create_region( name='electrodes', region=region, description=els.electrodes.description) obj.create_electrical_series(name=els.name, comments=els.comments, conversion=els.conversion, data=els.data[:], description=els.description, electrodes=elecs_region, rate=els.rate, resolution=els.resolution, starting_time=els.starting_time) return obj # TimeSeries -------------------------------------------------------------- if type(obj_old) is TimeSeries: return TimeSeries(name=obj_old.name, description=obj_old.description, data=obj_old.data[:], rate=obj_old.rate, resolution=obj_old.resolution, conversion=obj_old.conversion, starting_time=obj_old.starting_time, unit=obj_old.unit) # DecompositionSeries ----------------------------------------------------- if type(obj_old) is DecompositionSeries: list_columns = [] for item in obj_old.bands.columns: bp = VectorData(name=item.name, description=item.description, data=item.data[:]) list_columns.append(bp) bandsTable = DynamicTable(name=obj_old.bands.name, description=obj_old.bands.description, columns=list_columns, colnames=obj_old.bands.colnames) return DecompositionSeries( name=obj_old.name, data=obj_old.data[:], description=obj_old.description, metric=obj_old.metric, unit=obj_old.unit, rate=obj_old.rate, # source_timeseries=lfp, bands=bandsTable, ) # Spectrum ---------------------------------------------------------------- if type(obj_old) is Spectrum: file_elecs = nwb_new.electrodes nChannels = len(file_elecs['x'].data[:]) elecs_region = file_elecs.create_region( name='electrodes', region=np.arange(nChannels).tolist(), description='') return Spectrum(name=obj_old.name, frequencies=obj_old.frequencies[:], power=obj_old.power, electrodes=elecs_region) # Survey tables ------------------------------------------------------------ if obj_old.neurodata_type == 'SurveyTable': if obj_old.name == 'nrs_survey_table': n_rows = len(obj_old['nrs_pain_intensity_rating'].data) for i in range(n_rows): nrs_survey_table.add_row( **{c: obj_old[c][i] for c in obj_old.colnames}) return nrs_survey_table elif obj_old.name == 'vas_survey_table': n_rows = len(obj_old['vas_pain_intensity_rating'].data) for i in range(n_rows): vas_survey_table.add_row( **{c: obj_old[c][i] for c in obj_old.colnames}) return vas_survey_table elif obj_old.name == 'mpq_survey_table': n_rows = len(obj_old['throbbing'].data) for i in range(n_rows): mpq_survey_table.add_row( **{c: obj_old[c][i] for c in obj_old.colnames}) return mpq_survey_table
def with_table_columns(self): cols = [VectorData(**d) for d in self.spec] table = DynamicTable("with_table_columns", 'a test table', columns=cols) return table