Aligning events to continous data (kwik format)

460 views
Skip to first unread message

Edgar Bermudez

unread,
Jun 12, 2016, 3:23:19 PM6/12/16
to Open Ephys
Hi all,

I am having problems aligning events to my continuous data. I was wondering if somebody could spot the problem:

I load the continuous data (kwd) in matlab (similarly to the analysis-tools/Kwik.py):

filename = file.kwd
data = double(h5read(filename,'/recordings/0/data'));

sample_rate = double((h5readatt(filename,'/recordings/0/','sample_rate')));% in sec
start_time = double(h5readatt(filename,'/recordings/0/','start_time'));%in sec
bit_depth = h5readatt(filename,'/recordings/0/','bit_depth');
channel_bit_volts = double(h5readatt(filename,'/recordings/0/application_data','channel_bit_volts'));

%assume constant sampling rate (THIS IS WHERE I SHIFT THE CONTINUOUS DATA BY THE START TIME)
ts = ((1:length(data))+ start_time)sample_rate;

Then, I load the events like this:

filename = file.kwe
% ttl events for all channels
ttl_chan = h5read(filename, '/event_types/TTL/events/user_data/event_channels');
% ttl event sample times
ttl_times = double(h5read(filename, '/event_types/TTL/events/time_samples'));
% corresponding recording of the events
ttl_rec = h5read(filename, '/event_types/TTL/events/recording');
% event ID number for each sampled event (ON == 1, OFF = 0)
ttl_eventID = h5read(filename, '/event_types/TTL/events/user_data/eventID');
% recording node number
ttl_nodeID = h5read(filename, '/event_types/TTL/events/user_data/nodeID');
       
%attributes
sample_rate = double(h5readatt(filename,'/recordings/0/','sample_rate'));
ttl_start_time = double(h5readatt(filename,'/recordings/0/','start_time'));

% to align to continuous data, I simply divide the events times by the sampling rate assuming that the ttl times are relative to the start_time
ts_eve = ttl_times/sample_rate
       
However, if I do this, the events do not seem to align properly. What is the difference between the start time in kwd (/recordings/0/) and in kwe (/recordings/0/)?

Many thanks again for your help,

Edgar




Aarón Cuevas

unread,
Jun 13, 2016, 1:05:20 PM6/13/16
to Open Ephys
Hello Edgar,

The difference between start_time in different files is related to the fact that we can record from different processors, each saved in its own kwd file, which can, in turn, have channels from different sources, each with its own timestamp. So basically for the kwd files the start_time corresponds to the start timestamp for the first channel in that file, while for the kwe corresponds to the one on the "first" kwd. On most normal situations, though, those values should be the same, and equal for all channels. For more complicated multiple-source setups, in the message events (in the kwe) there are special system messages which indicate the record starting timestamp for each source processor present. Again, in most normal situations there is only one source so the value on these messages is the same as start_time and the same for all channels. (Or, said shortly: we allow for many weird configurations the kwik standard was not intended for)

Regarding your code, the most obvious flaw is the ts vector generation, as the start timestamp counts as 0, not 1. Thus the line should be something like ts = (0:(length(data)-1)+start_time)/sample_rate;

Newer versions of the GUI, however, included a timestamp vector for each source processor, indicating the timestamps for each 1024 samples (useful in case there were a data skip for any reason),

Hope this helps.

Best,
Aarón.

Edgar Bermudez

unread,
Jun 13, 2016, 5:04:19 PM6/13/16
to Open Ephys
Hello Aarón,

Thank you for the explanation. I now realized that the reason why my events do not align with the continuous data seems to be because their start times are different. In recordings I have done previously where start time in the kwe and kwd files is the same, the events align properly.

I am wondering how to solve it and why there are cases when the start times are different? I checked the configuration files of several recordings and it seems that when the start times are different, I was saving the channel data in the FPGA module and in the channel map module. I guess the work load was too much?

For the correct alignment of the events and continuous data when the start times are different in the kwe and kwd files, is it only needed to shift the times (time stamps) by the difference between the two start times?

Thanks again,

Edgar

Edgar Bermudez

unread,
Jun 13, 2016, 6:37:26 PM6/13/16
to Open Ephys
Just to clarify, I attach the graph of the recording where the start times of the kwd and kwe files are different.

The one from the kwe (/recordings/0/) is 387401700 and the one from the kwd (/recordings/0/) is 387402300, so there is a 600 seconds difference.

I tried to align them using the two start times or their difference but no luck. I guess I am not understanding how the start times for the kwe and kwd files work...

Any ideas?
OE_graph.png

Aarón Cuevas

unread,
Jun 13, 2016, 11:58:30 PM6/13/16
to Open Ephys
Ok, in your case, with only one source, all start times should be the same. The fact that it isn't is a bug. Which version of the GUI are you using? the latest build incorporates some patches that fix some issues we had with start times, please check if the start times are consistent with the newer version or if the bug still persists.

For your already recorded data, in the kwe open /event_types/Messages/events/user_Data/Text there, for each recording, you should find a line like "Processor: <proc_number> start time: <start_time>@<sample_rate>Hz" the start time there is the one you should use for your data.

For alignment, the start_time represent the first sample in the continuous data, and then it's just a matter of adding (like you did with the length vectors). For events, the timestamp provided is raw, so you should not need to add anything to it, as long as the data timestamps are properly created from a valid start time.

Hope this helps.

Best,
Aarón.

Edgar Bermudez

unread,
Jun 14, 2016, 12:15:20 PM6/14/16
to Open Ephys
The version of the GUI is 0.4.0 which I downloaded at the beginning of May.

For the alignment, if I use the start time in the kwe open /event_types/Messages/events/user_Data/Text:

Software time: 30266130153@2343751Hz
Processor: 108 start time: 387403500@30000Hz

to shift the continuous data (in the kwd) like:

ts = ((0:length(data)-1)+ start_time)/sample_rate;

The data is not aligned still. Do I need to do something to the time stamps of the events in the kwe file?

I noticed that in my other recordings where I was only recording the channels in the FPGA module (not in the channel map module as well), the time start in the /event_types/Messages/events/
user_Data/Text is also different from the start time in the kwd file (/recordings/0/). Is this a bug?

Many thanks for your help again,

Edgar

Edgar Bermudez

unread,
Jun 20, 2016, 2:38:13 PM6/20/16
to Open Ephys
Hi Aarón,

I was wondering if you could suggest what would be the best way of trouble shooting this bug. Could this happen because the work load is too high?

Cheers,

Edgar

Edgar Bermudez

unread,
Jul 8, 2016, 2:27:20 PM7/8/16
to Open Ephys
I am trying again the kwik format. I am checking the recorded data.

In experiment1.kwe: event_types/Messages/events/user_data/Text:
Processor: 108 start time: 387403500@30000Hz

In experiment1_108.raw.kwd: recordings/0/:
start_time = 387402300

Does this mean the data can not be aligned to the events?

Cheers,

Edgar

Edgar Bermudez

unread,
Jul 11, 2016, 12:23:08 PM7/11/16
to Open Ephys
hi,

I just compiled the GUI plugin version. I will try to see if in this version I find the same bug (different start_time in the event and FPGA processors) as in the pre-compiled GUI version.

Cheers

Josh Siegle

unread,
Jul 11, 2016, 10:20:51 PM7/11/16
to Open Ephys
Hi Edgar,

You should use the start time from the events (.kwe) file as the true start time. Looking at the code, the start time in the KWD file is the timestamp when the file is opened, not the timestamp of the first data buffer that’s written. We will fix this so there’s no longer an apparent conflict.

Josh

-- 
You received this message because you are subscribed to the Google Groups "Open Ephys" group.
To unsubscribe from this group and stop receiving emails from it, send an email to open-ephys+...@googlegroups.com.
To post to this group, send email to open-...@googlegroups.com.
Visit this group at https://groups.google.com/group/open-ephys.
To view this discussion on the web visit https://groups.google.com/d/msgid/open-ephys/223bf5aa-57a4-48db-a425-879426e27be8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Aarón Cuevas

unread,
Jul 12, 2016, 8:44:36 AM7/12/16
to Open Ephys
In theory, at least in the development branch, the timestamp in the kwd should be the same as in the kwe now, but there might still be some corner cases when it still fails. I'll try to check that again.
To unsubscribe from this group and stop receiving emails from it, send an email to open-ephys+unsubscribe@googlegroups.com.

Edgar Bermudez

unread,
Jul 15, 2016, 12:24:33 AM7/15/16
to Open Ephys
Hi Aaron, Josh,

Thanks for the messages. I tested the plugin GUI implementation (my previous recording were done with the pre-compiled version 0.4.0), I downloaded the latest version, compiled it and the same happens. The kwe and kwd files have different start_times so the data don't align. However, in previous recordings, I have had cases where the these start_times were the same. Even if I use the start_time in /event_types/Messages/user_data/Text from the kwe file, the continuous and events don't align properly.

I was wondering if you could clarify what is the difference between

start_time = double(h5readatt(continuous.kwd,'/recordings/0/','start_time'))%in sec

start_time = double(h5readatt(events.kwe,'/recordings/0/','start_time')) %usec

and the one in

text = h5read(events.kwe, '/event_types/Messages/events/user_data/Text');

According to Josh: "the start time in the KWD file is the timestamp when the file is opened, not the timestamp of the first data buffer that’s written".

Could these be different if there were TTL pulses before I pressed the record button (only with the acquisition (play) button pressed)?

Many thanks again,

Edgar



Many thanks,
Edgar
To unsubscribe from this group and stop receiving emails from it, send an email to open-ephys+...@googlegroups.com.

Josh Siegle

unread,
Jul 15, 2016, 2:47:06 PM7/15/16
to Open Ephys
Hi Edgar,

To do the proper alignment, you should be adding the .kwe timestamp:

h5read(events.kwe, '/event_types/Messages/events/time_samples/‘)

to the timestamps for the .kwd file (assuming they start at 0).

Have you done a recording where you put the same 0-5 V signal on one of the digital input channels and one of the analog input channels? Then you can verify how much the alignment is off (if at all).

Josh


Jan Zimmermann

unread,
Jul 16, 2016, 1:22:55 AM7/16/16
to Open Ephys
I have had this issue before as well and could not explain the discrepancy in the continuous vs kwe file.

Upon inspection however, my recordings went fine with using the start time from the kwe file. Perfect alignment!

I dug through some old files and the difference between the start_times is always somewhere on the order of 10-30 ms.
When I use the kwe starttime however I get perfect alignment every time!

Edgar Bermudez

unread,
Jul 18, 2016, 3:01:36 PM7/18/16
to Open Ephys
Hi,

Thanks for the suggestions. I guess there is something wrong the way the events are handled or saved in the kwik version.

For example, one of the signals that I am recording is a 150Hz 5V pulse signal in the digital input from the IO board. I am sampling at 30000 Hz.

If I plot the LFP and the events and aligned using the start_time from

h5read(events.kwe, '/event_types/Messages/events/time_samples/‘), to the timestamps for the .kwd file (assuming they start at 0), they don't seem to end at the same time (see attached plot).

I will record TTL pulses both in the continuous channels and the digital input and see if this misalignment is consistent.

This is the code to generate the attached plot:

%The events are read:
ttl_time = double(h5read([fdir fname_eve], '/event_types/TTL/events/time_samples'));
ttl_chan = h5read([fdir fname_eve], '/event_types/TTL/events/user_data/event_channels');

%Then scaled to seconds:
ttl_times = ttl_time/sample_rate;

% continuous data are read
data =  (h5read([fdir fname_con],'/recordings/0/data'));

The time stamps are calculated:
%assume constant sampling rate
ts = ((0:size(data,2)-1)+ start_time)/sample_rate;

Then plotting events and continuous data together:
plot(ts, data(num_channel, :)*channel_bit_volts(1)); hold on;

% select the pulses to a particular channel (@150Hz)
ttl_pulses = find(ttl_chan == 4 & ttl_state == 1);
% plot events
plot(ttl_times(ttl_pulses), ttl_chan(ttl_pulses),'.');

Any ideas why the events end at a different time compared to the continuous signal (see the end of the LFP compared to the end of events, yellow dots)?

Cheers,
LFP_cam_clk_12Jul2016.jpg

Josh Siegle

unread,
Jul 19, 2016, 5:39:54 PM7/19/16
to Open Ephys
It is possible that the events file could contain events that end after the last continuous sample, but I would expect this difference to be on the order of milliseconds, rather than many seconds as shown in your figure.

Does 1/mean(diff(ttl_times)) = 150, as you’d expect?

Please let us know the results of sending the TTL pulses to a continuous channel, hopefully that will shed some light on what’s going on.


For more options, visit https://groups.google.com/d/optout.
<LFP_cam_clk_12Jul2016.jpg>

Jan Zimmermann

unread,
Jul 22, 2016, 10:57:46 AM7/22/16
to Open Ephys
Could you also try the following:

start_time = h5read('*.kwe','/event_types/Messages/events/user_data/Text'); and use this time as your start time. 

event_times = (double(event_times)-start_time) / 30 / 1000; % in seconds

Please let me know if this works :)

Boleslaw Osinski

unread,
Jul 23, 2016, 1:00:11 PM7/23/16
to Open Ephys

Hello,


I have a very similar problem except that I am trying to align spike times (saved in kwx files) and continuous data (saved in raw.kwd files). If I understand correctly, the spikes are saved as sample times. The last spike sample time is 1908502, but the continuous data in the kwd file is only 1819500 samples long, so I am assuming that the spike sample times need to be shifted relative to some non-zero start time. I can find the start time in the kwd file, but not in the kwx file!


I loaded the spike times of channel 0 into MATLAB as 


fname = 'experiment1.kwx';

dataset_name = '/channel_groups/0/time_samples';

SPKS = h5read(fname, dataset_name);


And I explored the kwx data structure by manually looking through the info structure obtained by


info = hdf5info(fname);


I expected to find it in one of the “Attributes” groups, but nearly all of them were empty. Are there just no start times in kwx files because they are recorded relative to the record button press? Was this one of the issues in older GUI versions (I can't check the GUI version now because I am away from the computer where it is installed)? Or am I just looking in the wrong place?


Many thanks you for your help,


Bo


Jan Zimmermann

unread,
Jul 25, 2016, 8:32:24 AM7/25/16
to Open Ephys
@Bo,

just read in the start_time and substract it from the timestamps of your spikes.

start_time = h5read('*.kwe','/event_types/Messages/events/user_data/Text');

All the best

Jan

Boleslaw Osinski

unread,
Jul 26, 2016, 4:41:40 AM7/26/16
to Open Ephys
Thank you Jan! I didn't realize that the start time in the kwe file also applies to the spikes in the kwx file.

Bo

Boleslaw Osinski

unread,
Jul 26, 2016, 8:40:32 AM7/26/16
to Open Ephys
I have 3 quick followup questions:

Reading the data from '/event_types/Messages/events/user_data/Text' produces a 2x1 cell. The 2nd element contains the following data (including the strange characters):

Processor: 100 start time: 90300@30000Hz      ¨  ‘E"4„ €â (   
    ÑX    ñ  ÿ    ò       á ÿ    â     E"4„€ €æ €€š€Ë€ä€æ€ò€ô€Ö€«€j€ €    ñ  ÿ    ò       á ÿ    â ™E"4„  €ê a #M   (     ì à    ñ  ÿ    ò       á ÿ   eE"4„  €î ¾€

Q1:
I am assuming that the start time I am to use for the spikes is 90300. Is this correct?

Q2:
There is also a start time in the kwe file at '/recordings/0/start_time' with a value of 88800 (different from the 1st start time). What does this start time refer to? Is it for the continuous data or for some external TTL triggers (which I am not using in this particular experiment)?

Q3:
I am new to the hdf5 file format so I imagine this is all explained somewhere. Where can I learn more about the organization of these files?


Thank you,

Bo

Jan Zimmermann

unread,
Jul 26, 2016, 10:15:57 AM7/26/16
to Open Ephys
Hi Bo,

my general advice at this moment is to stay away from kwik and go for the open ephys format. Kwik was a great idea but has so many issues. The open ephys format seems better supported, is more stable and is more immune to data corruption.

All the best

Jan

Aarón Cuevas

unread,
Jul 26, 2016, 12:41:43 PM7/26/16
to Open Ephys
Hi Boleslaw,

Answering your questions:
Q1: Yes, the time in the text event is the one you should use as start for all the data (continuous, spikes and events). I do not know why matlab is loading those random data after the text, though.
Q2: start_time should be equal to the one in the text field. It isn't due to a bug which I thought was already fixed, but seems to be coming back. When in doubt, always use the one in the event file.
Q3: hdf5 a container instead of a format itself. The hdf5 structure we're using follows the kwik format described in https://github.com/klusta-team/kwiklib/wiki/Kwik-format with some changes, explained in the wiki https://open-ephys.atlassian.net/wiki/display/OEW/KWIK+format

Regarding this and Jan's advice, the truth is that the original KWIK format specs do not support many features needed for its use on our GUI, so we had to somewhat add them on top of the original format, which is the source of many of the issues. We are now developing a new hdf5-based file format following the Neurodata Without Borders specification which supports all these features natively, so it should be better fitted for acquiring with our software.

Best,
Aarón.
Reply all
Reply to author
Forward
0 new messages