edfwrite failure because of 8 byte limit

8 vues (au cours des 30 derniers jours)
Clay Smyth
Clay Smyth le 17 Août 2023
I am trying convert some data to an EDF with the following code (per this page edf_link):
fs = 250;
data = data_streams{i};
Undefined variable 'data_streams'.
out_dir = '[redacted]';
out_file = data_names{i};
out_file_full = fullfile(out_dir, strcat(out_file,'.edf'));
hdr = edfheader("EDF+");
hdr.NumDataRecords = 1;
hdr.NumSignals = 1;
hdr.SignalLabels = ["SubCTX"];
hdr.DataRecordDuration = seconds(length(data(:,1))/fs);
hdr.PhysicalDimensions = repelem("mV",1);
hdr.PhysicalMin = min(data);
hdr.PhysicalMax = max(data);
hdr.DigitalMin = -32768;
hdr.DigitalMax = 32767;
edfw = edfwrite(out_file_full,hdr,data);
But run into the following error:
_______
Error using signal.internal.edf.write.validateFieldBytes
Value of "DataRecordDuration" field must be less than or equal to 8 bytes. See edfheader documentation for more information.
Error in edfwrite/createFile (line 1685)
signal.internal.edf.write.validateFieldBytes(value, fieldIndex, ...
Error in edfwrite (line 499)
[obj, fileInfo] = createFile(obj, filename, hdr,...
Error in create_edfs_from_OFF_data (line 45)
edfw = edfwrite(out_file_full,hdr,data);
________
I do not know how to avoid this, because the output for
seconds()
is always 10 bytes.
Example:
tmp = seconds(1);
disp(whos('tmp').bytes)
Any guidance would be very welcomed! Thanks in advance.
  3 commentaires
Clay Smyth
Clay Smyth le 18 Août 2023
Thanks for the reply, here is the values of the variable:
Catherine
Catherine le 5 Nov 2023
Modifié(e) : Catherine le 5 Nov 2023
Hi, @Clay Smyth! I was struggling with this same issue and just found a workable solution — hopefully still useful for you :)
My theory is that it's not the size of the output of seconds() that matters, but rather the size of the object that you put into it. I tried seconds(1) and the script ran successfully despite seconds(1) being 10 bytes. However, when I tried it with the actual length of my data in milliseconds (which was a 10 byte double before I turned it into a duration) it failed. That being said, this theory didn't hold for when I converted my data length in milliseconds to seconds, which was also an 8 byte double, and set DataRecordDuration to that.
But anyhoo, this workaround is working with multiple files for me and can maybe work for you too:
%create duration (my data is in milliseconds)
data_duration = seconds(width(sig_data)/256);
%turns into a double
hours = hours(data_duration);
%round hours to 1 after decimal point, whos('hours_rounded') = 8 bytes
hours_rounded = round(hours,2);
%add to header as a duration
header.DataRecordDuration = hours(hours_rounded);

Connectez-vous pour commenter.

Réponses (1)

Christopher McCausland
Christopher McCausland le 5 Nov 2023
Modifié(e) : Christopher McCausland le 5 Nov 2023
Hi all,
I have had a look at the above, from the documentation in edfheader.DataRecordDuration the input should be [a] "Duration of each data record, returned as a duration scalar."
@Catherine's solotion does exactly that, takes a duration value and then returns it back as a double (i.e. a scalar).
@Walter Roberson, Is there anyway to get this flagged with the QA team to make the discription a little more indepth/ add an example? Scaler conversion is required several edfheader inputs and the scalar part is easy to miss!
A similar issue can be found here.
Christopher
  2 commentaires
Walter Roberson
Walter Roberson le 5 Nov 2023
The original poster had
hdr.DataRecordDuration = seconds(length(data(:,1))/fs);
data(:,1) is a vector, but length() of that is going to be a scalar; fs is a scalar so the result of the division will be a scalar. seconds() of a scalar will be a scalar duration.
hdr.DataRecordDuration = seconds(4.22)
which tells us that a duration is expected (or at least is one of the valid options.)
Christopher McCausland
Christopher McCausland le 5 Nov 2023
Hi Walter,
Just gave this a go in 2023b and the error message has been updated. It's now a lot more direct (which is far less confusing):
Error using edfwrite
Expected dataRecordDuration of header structure to be one of these types:
duration
Instead its type was double.
You are correct, as always @Walter Roberson, thank you for the clarity though!
@Clay Smyth I would also have a look at the orignal specification for .edf, if you want to know why it's limited to 8 bytes.Here is a link.
Christopher

Connectez-vous pour commenter.

Catégories

En savoir plus sur AI for Signals dans Help Center et File Exchange

Tags

Produits


Version

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by