Problem with edfwrite regarding the number of the signals

Hi there,
I would like to open an EDF file in MATLAB, modify it and save it again. I expected that I could get header from edfinfo; however, it seems that I have to create header manually (only with edfheader). Am I right? But my question is about the edfwrite function. It tells me that:
Number of columns in the signal data must be equal to the number of signals.
But I have only one channel EEG and hdr.NumSignals=1. Here is the code (you can find EDF file here EDF file example):
clc;
clear all
close all
EEG_for_HFO=edfread('Rec-06.0001-GFP.edf');
header=edfinfo('Rec-06.0001-GFP.edf');
%header=get(header);
%% Inputs
EEG=EEG_for_HFO.EEG;
EEG=cell2mat(EEG);
SR=1000; % Sampling rate
% % Artifact Removal
% Threshold=1.5; % Threshold level for Artifact Removing in mili volt
% Window=10; % Length of step for Artifact Removing in mili second
% TimeDuration=100; % Time duration for Artifact Removing in mili second - Before and After
% % Highpass Filter
% FilterLevel=5; % Level of highpass filter
% Cutoff=2;
% %% Orders ------> 1 means On
% ArtifactRemoving=1;
% Filter=1;
% %% Plot
% figure;
% Time=1:length(EEG);
% plot(Time,EEG,'b');
% title('Raw signal')
% xlabel('Time(ms)');ylabel('EEG(mV)')
% %% Artifact Removal
% if (ArtifactRemoving==1)
% Start=100;
% End=Start+Window;
% for ii=1:(round(length(EEG)/Window)-Window)-1
% [Max(ii),max_indices(ii)]=max(abs(EEG(Start:End)));
% if Max(ii)>Threshold
% Before=max_indices(ii)-TimeDuration+Start;
% After=max_indices(ii)+TimeDuration-1+Start;
% EEG(Before:After)=0;
% end
%
% Start=Start+Window;
% End=End+Window;
% end
%
% hold on
% Time=1:length(EEG);
% plot(Time,EEG,'r')
% end
%
% %% Highpass Filter
% if (Filter==1)
%
% a=[];b=[];
% [b,a]=butter(FilterLevel,Cutoff/(SR/2),'high'); % Highpass filtering 2 Hz
% EEG=filtfilt(b,a,EEG);
% end
%% preparing cell
Start=1;
End=SR;
Step=SR;
EEGCell=[];
for ii=1:(length(EEG)/SR);
EEGCell{ii,1}=[EEG(Start:End)];
Start=End;
End=End+Step;
end
%% creating header
hdr=edfheader("EDF+");
hdr.Patient="Mice";
hdr.Recording="2021";
hdr.NumDataRecords=1440;
hdr.NumSignals=1;
hdr.SignalLabels="EEG";
hdr.PhysicalDimensions="mV";
hdr.PhysicalMin=-5;
hdr.PhysicalMax=5;
hdr.DigitalMin=-32256;
hdr.DigitalMax=32256;
%% exporting edf
% EEG_for_HFO.EEG=EEGCell;
% hdr.NumSignals=2;
% edfwrite('edited-Rec-06.0001-GFP.edf',hdr,EEG_for_HFO);
edfwrite('edited-Rec-06.0001-GFP.edf',hdr,EEGCell)

6 Comments

Is there a reason you do not use
EEGCell = mat2cell(EEG(:), SR*ones(numel(EEG)/SR), 1);
Dear Walter,
Thansk for your prompt (very prompt!) reply to my question, but I did not get your point. You mean I should add this argument before edfwrite, instead of my for loop? I can do it, but it won't solve the issue. What is wrong in the current code? Thanks
Your for loop to build EEgCell is okay, but you can code it more directly without a loop, using the mat2cell I showed.
Also, the code I showed acts slightly differently than your code under two circumstances:
  • the result of the EEG=cell2mat(EEG); turned out to be a row vector -- if so you would get the error you saw
  • the result of that statement turned out to be a 2D array -- if so then exact consequences would depend on whether it had more rows than columns or more columns than rows; if it had more columns then rows then you would get the error you saw
Thansk Walter for your effort and informative reply to my question. I did not use your method, seems easier and more directly; however, I faced the following error:
Input arguments, D1 through D2, should be vectors.
Do you think your recommended trick would solve my issue with edfwrite?
Thanks again
EEGCell = mat2cell(EEG(:), SR*ones(1,numel(EEG)/SR), 1);
Thanks for updating the code and your kind support; now, I don't face the Input arguments, D1 through D2, should be vectors. error anymore, but the Number of columns in the signal data must be equal to the number of signals is still there!
I mean, despite we have single column EEGCell and I I added hdr.NumSignals=1, I still face this error by running edfwrite:
Error using signal.internal.edf.write.validateSignalData (line 26)
Number of columns in the signal data must be equal to the number of signals.
Error in signal.internal.edf.write.getFileCreateOpts>checkSignals (line 223)
signal.internal.edf.write.validateSignalData(sigData, ...
Error in signal.internal.edf.write.getFileCreateOpts>createHdr (line 96)
[reqhdr, sigData] = checkSignals(reqhdr, sigData, tNumSignals);
Error in signal.internal.edf.write.getFileCreateOpts>createAndValidateHeader (line 47)
[hdr, sigData, tsal] = createHdr(thdr, sigData, tsal, hdrPropertiesList, ...
Error in signal.internal.edf.write.getFileCreateOpts (line 13)
[hdr, sigData, tsal] = createAndValidateHeader(hdr, sigData, tsal, ...
Error in edfwrite/createFile (line 1602)
signal.internal.edf.write.getFileCreateOpts(hdr, signalData, ...
Error in edfwrite (line 493)
[obj, fileInfo] = createFile(obj, filename, hdr,...

Sign in to comment.

 Accepted Answer

The number of entries in the cell array is expected to be the same as the number of signals (and each entry must be a vector)

3 Comments

Thanks Walter for your help. I still struggle with the code, but I think I would find the solution soon
I have the same problem, but I found the solution as below code:
clc, clear, close
hdr = edfheader("EDF");
hdr.Patient = "001 M 2020";
hdr.Recording = "This is the original header record";
hdr.StartTime = "00.00.01";
sig = randn(10,1); % one vector for 1 channel
hdr.NumDataRecords = 5; % 5 numbers of data recording
hdr.NumSignals = 1;
hdr.PhysicalMin = min(sig);
hdr.PhysicalMax = max(sig);
hdr.DataRecordDuration = seconds(10);
hdr.DigitalMin = -32767;
hdr.DigitalMax = 32767;
edfw = edfwrite("file.edf",hdr,sig,"InputSampleType","physical");
df = edfread('file.edf') % check edf
Thanks Phuc Nguyen for your comment.
I will test and see, whether it would solve the issue.

Sign in to comment.

More Answers (0)

Categories

Tags

Community Treasure Hunt

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

Start Hunting!