MATLAB: How to fix this uigetfile multiselect error

uigetfile multiselect

I have developed a script to process raw data from wind turbine noise. I am attempting to adapt it to automatically process a number of files as opposed to running the script for each file individually. The script is shown below:
function ruk_am_v1_OPTI
%%Initiatilise Variables and Setup Environment
% RenewableUK AM Assessment Program - V1 December 2013
% ########################################
% Clear all variables and workspace data from system memory
clear all;
% Clear command window
clc;
% Clear all old figures
close all;
% Configure run and initialise all variables
repository = 'C:\';
blockTime = 10; % Main analysis interval (here 10 sec)
sampPerSec = 10; % Number of Leq periods per second (here 10 Hz, or 100 msec)
maxBlocks = 1440; % Maxiumum number of blocks program can process at once (4 hours)
%%Ask user to specify blade passing frequency
bladePassingFrequency = 1.25;
%%Select data file using UI control
[filename,pathname] = uigetfile('*.txt','Select the TXT file to process',repository,'Multiselect','on');
if isequal(filename, 0)
disp('User selected Cancel')
return;
end
for n = 1:length(filename)
% Create name for output file and open for output
filename = lower([pathname,filename(n)]);
filenameOut= strrep(filename(n), 'txt', 'out');
filenameOut= char(filenameOut);
fid = fopen(filenameOut, 'w');
%%Read input data
blockLength = blockTime * sampPerSec;
% Open input TXT file and read first line, which contains number of items
filename=char(filename);
fidtxt = fopen(filename(n), 'r');
dummy = fgetl(fidtxt);
totalSamples = str2double(dummy);
LeqWholePeriod = zeros(1,totalSamples);
end
% Create progress bar for reading input data
h = waitbar(0,'Reading LAeq,100msec levels from TXT file...');
for i = 1:totalSamples
dummy = fgetl(fidtxt);
LeqWholePeriod(1,i) = str2double(dummy);
waitbar(i/totalSamples);
end
close(h);
% Close input TXT data file
fclose(fidtxt);
% Determine how many 10 sec periods the input TXT file contains
numBlocks = max(1,floor(totalSamples / blockLength));
% Check that this is not more than maxBlocks, which is the maximum
if numBlocks > maxBlocks
msgBox('Cannot process more than ''maxblocks'' blocks','Program Termination Warning','warn');
return;
end
%%Put information on screen and in 'Out' file
for fileHandle = [1,fid]
fprintf(fileHandle,'Input file name %s\r\n',filename);
fprintf(fileHandle,'Output file name %s\r\n',filenameOut);
fprintf(fileHandle,'Number of samples in file %9i\r\n',totalSamples);
fprintf(fileHandle,'No of samples per sec. %9i\r\n',sampPerSec);
fprintf(fileHandle,'Duration of file %9.2f s\r\n',totalSamples/sampPerSec);
fprintf(fileHandle,'Length of data blocks %9i s\r\n',blockTime);
fprintf(fileHandle,'No of data blocks %9i\r\n',numBlocks);
% Detrend using 5th order polynomial
fprintf(fileHandle,'Detrending Method. Polynomial(');
fprintf(fileHandle,'Order 5)\r\n');
fprintf(fileHandle,'Blade passing frequency %9.2f Hz (User chosen)\r\n',bladePassingFrequency);
end
% Print file headers for output 'Out' file
fprintf(fid,'\r\n');
fprintf(fid,' Block No.| Spec Line| Frequency/Hz| Raw Spec Level/dB| Int Spec Level/dB\r\n');
%%Now loop over the whole input file in 'blockTime' second blocks
n2 = 0;
hold off
% Start processing each block in turn
for iblock = 1:numBlocks
% Block counter
disp(['Processing Block Number ',num2str(iblock),' of ',num2str(numBlocks)]);
t = 0:1/sampPerSec:blockTime-(1/sampPerSec);
n1 = 1 + n2;
n2 = min(blockLength,totalSamples) + n2;
Leq = LeqWholePeriod(1,n1:n2);
nsamp = length(Leq);
time = nsamp / sampPerSec;
if blockLength ~= nsamp(1,1)
msgbox('blockLength differs from nsamp!','Program Termination Warning','error');
end
if blockTime ~= time(1,1)
msgbox('blockTime differs from time!','Program Termination Warning','error');
end
%%Check for bad data
% Calculate Leq for 'blockTime' seconds
LeqTotal = 10*log10(1/sampPerSec*(sum(10.^(Leq/10)))/blockTime);
% Test whether max value of Leq is > 10 dB more than mean
% (implies non-stationarity rather than error) or data which
% has spikes, i.e. overal level >= 60 dB(A)
if max(Leq) - mean(Leq) > 10
iBad = 1; % set to bad data

elseif LeqTotal > 60
iBad = 1; % set to bad data
else
iBad = 0;
end
If block data NOT bad then proceed, otherwise discard it
if iBad == 0
%%Detrend and plot the Leq Data
p = polyfit(t,Leq,5);
deT = polyval(p,t);
Leq = Leq - deT; % detrend data
%%Now perform the spectral analysis of the detrended data
% Create spectrum object and call its PSD method.
h = spectrum.periodogram('Rectangular');
hopts = psdopts(h,Leq);
set(hopts,'Fs',sampPerSec,'SpectrumType','onesided');
amspec = psd(h,Leq,hopts);
% Extract results from object
Fw = amspec.Frequencies;
Pw = amspec.Data;
FreqRes = Fw(2) - Fw(1);
maxFreq = sampPerSec/2;
Pw_max = 10.0;
Pw_min = 0;
% Convert spectrum results to dB levels
ampMod = 2*sqrt(2*FreqRes*Pw);
%%Integrate the spectrum to determine the 'true' level
% Integrate the PSD to determine the energy in a critical band. The
% critical band is defined as the +/-10% of the BPF
critBand = 2 * 0.1 * bladePassingFrequency;
% determine the number of frequency intervals this includes.
windowSize = floor(critBand /FreqRes) + 1;
if mod(windowSize,2) == 0
halfWindow = windowSize/2;
else
halfWindow = (windowSize - 1)/2;
end
intAmpMod = zeros(1,length(Fw));
% Calculate rolling sum over entire spectrum
for j = 1:length(Fw)
if j <= halfWindow
% Portion of spectrum < halfWindow from beginning
intAmpMod(j) = sum(Pw(1:j + halfWindow));
elseif j >= length(Fw)- halfWindow + 1
% Portion of spectrum < halfWindow from end
intAmpMod(j) = sum(Pw(j - halfWindow:length(Fw)));
else
% rest of spectrum
intAmpMod(j) = sum(Pw(j - halfWindow:j + halfWindow));
end
end
% Convert to dB units, as before
intAmpMod = 2 * sqrt(2 * FreqRes * intAmpMod);
% Print out results to text file
for j = 1:length(Fw)
fprintf(fid,'%12i|%12i|%18.6f|%18.3f|%18.3f\r\n',iblock,j,Fw(j),ampMod(j),intAmpMod(j));
end
else %iBad ~= 0
fprintf(fid,'%12i| Bad data - affected by ',iblock);
fprintf(fid,'high energy peaks - not analysed\r\n');
end
end
%%Close all files and exit
% Turn warnings back on
warning('on','all');
% Close 'Out' text file
fprintf(fid,'\r\nRun Date: %s',datestr(now));
fclose(fid);
% Alert user that data processing is complete
msgbox('Data processing complete!','Warning Message!','warn');
The error I am receiving is as follows:
Error using fgets
Invalid file identifier. Use fopen to generate a valid file identifier.
Error in fgetl (line 33)
[tline,lt] = fgets(fid);
Error in ruk_am_v1_OPTI (line 52)
dummy = fgetl(fidtxt);
Does anyone know how to correct this?
Thanks.

Best Answer

Don't know if this is the cause of your problem, but I can say that uigetfile in 'MultiSelect' mode has the bothersome behavior where it returns a variable of a different class depending on whether the user picks one or more than one file. Very frustrating! In the first instance your variable 'filename' will be a char, so
fopen(filename{n}, 'r');
will fail, saying 'Cell contents reference from a non-cell array object.' Which is true, because it's not a cell array! Similarly if you use brackets:
fopen(filename(n), 'r');
will fail, but this time it's because you have specified the filename as the first letter in the name of the file. The first method works if the user has picked more than one file... so I would advise you to first check the number of files selected as follows:
n_files = numel(cellstr(filename));
because this will accurately report the number of files selected, instead of reporting the number of files as being the number of characters in the name of the one file you picked, then loop through n_files using an if statement for the special case of one file selected:
for file = 1:n_files,
if n_files==1,
filenameOut = filename;
else filenameOut = filename{file};
end
load(filenameOut)
%load your shiny new data and do something here
end
Does this make any sense?