NeurodataWithoutBorders / matnwb

A Matlab interface for reading and writing NWB files
BSD 2-Clause "Simplified" License
50 stars 32 forks source link

[Bug]: Accessing and replacing raw data in a .NWB file with Matlab #480

Open raphaelguex opened 1 year ago

raphaelguex commented 1 year ago

What happened?

I am trying to access the raw data and to replace them in matlab of some iEEG file coded in NWB.

For some other files, the code like: "trials_good = nwb.intervals_trials.vectordata.get('good').data.load;" is working.

but not for timeseriesB = nwb.acquisition.multielectrode_recording.vectordata.get('data').data.load; which gives me as an error: "Unrecognized method, property, or field 'multielectrode_recording' for class 'types.untyped.Set'."

nor simply with "timeseriesB = nwb.acquisition_multielectrode_recording.data;"; which gives me the error: "Unrecognized method, property, or field 'acquisition_multielectrode_recording' for class 'NwbFile'."

"In classic matlab" it would be easy to recover these part of the data and replace them but here I am stucked, any idea ? many thanks !

--> I also attach a screenshot of how are stored the data in this file, it may help perhaps to understand this issue ?

NWB_Prob_AccessRawData

Steps to Reproduce

I a simply trying to updload and replace some raw data in NWB.

Error Message

but not for timeseriesB = nwb.acquisition.multielectrode_recording.vectordata.get('data').data.load;
which gives me as an error: "Unrecognized method, property, or field 'multielectrode_recording' for class 'types.untyped.Set'."

 nor simply with "timeseriesB = nwb.acquisition_multielectrode_recording.data;"; which gives me the error: "Unrecognized method, property, or field 'acquisition_multielectrode_recording' for class 'NwbFile'."

Operating System

Windows

Matlab Version

2021b

Code of Conduct

lawrence-mbf commented 1 year ago

Hi @raphaelguex,

Instead of

timeseriesB = nwb.acquisition.multielectrode_recording.vectordata.get('data').data.load();

try

timeseriesB = nwb.acquisition.get('multielectrode_recording').vectordata.get('data').data.load();
raphaelguex commented 1 year ago

using this code, i get the following error:

Unrecognized method, property, or field 'vectordata' for class 'types.core.ElectricalSeries'.

any idea ? i tried without the () at the end, unsuccessfully; many thanks agin

raphaelguex commented 1 year ago

And, perhaps also, would you have please a line of code to replace the data into this same vector ? thanks

lawrence-mbf commented 1 year ago

using this code, i get the following error:

Unrecognized method, property, or field 'vectordata' for class 'types.core.ElectricalSeries'.

Try

timeseriesB = nwb.acquisition.get('multielectrode_recording').data.load();

And, perhaps also, would you have please a line of code to replace the data into this same vector ? thanks

You should be able to simply replace the data with your own matrix. I think the only issue would be that your types and your matrix dimensions have to be the same or exporting will throw an error. The following should work but I would advise exporting to a different file.

Recording = nwb.acquisition.get('multielectrode_recording');
DataStub = Recording.data;
Recording.data = rand(DataStub.dims); % assuming this data is in doubles.
nwbExport(nwb, 'otherTest.nwb'); % actually writes to file. If you need to amend a file, then call this with the same file name.
raphaelguex commented 1 year ago

timeseriesB = nwb.acquisition.get('multielectrode_recording').data.load(); ->Works fine, many thanks!

Ok, many thanks also for your second response, I will try it tomorrow. thanks again!

raphaelguex commented 1 year ago

Thanks again for your help @lawrence-mbf , I tried this code and needed to adapt it a bit to get the correct dimensions: " Recording = nwb.acquisition.get('multielectrode_recording'); DataStub = Recording.data; % Recording.data = rand(DataStub.dims); % assuming this data is in doubles. Recording.data = rand(size(DataStub,1),size(DataStub,2)); % assuming this data is in doubles. nwbExport(nwb, 'otherTest.nwb'); % actually writes to file. If you need to amend a file, then call this with the same file name. " And I got the following error message: " Error using hdf5lib2 The HDF5 library encountered an error and produced the following stack trace information " I guess that I should simply CD to another folder in order to save the new file. However, I was more trying to get the data under a new name to have the new data into the workspace. A work around I have been trying is to simply have the time stamp of each trials. Which I found using HDF in the file like: "intervals.trials.start_time", please see pic attached. However, I could not recover these information with Matlab (the time stamp of each start trial, as loggued in the file while accessing with HDF). One reason I believe is that the name "start_time" is used differentially in HDF than in NWBmatlab, as far as I can see, which is strange to me as i can gather other info from the file but not this one. --> would you have therefore perhaps a simple code to access the time stamp of each trial as logged in the HDF file in the screenshot attached ? (which shall correspond to the trigger of each trial start)

NWB_FindTimeStampEachTrial_InMatlab

thanks again for your help!

lawrence-mbf commented 1 year ago

I'm not entirely sure I understand how you want your data. Retrieving start_time from trials should be as simple as using

start_times = nwb.intervals_trials.start_time.data.load();

If I'm off the mark here, please let me know.

Alternatively, the root NwbFile object has a function called resolve which takes in a HDF5 path and returns its equivalent object if it exists. Perhaps that will also help converting between the HDF5 pathing and the NwbFile data structure. An equivalent example to the one above:

start_times = nwb.resolve('/intervals/trials/start_time').data.load();