MATLAB fails to execute line with uigetfile-- why?

8 views (last 30 days)
Sarah
Sarah on 31 Jul 2014
Answered: Martijn on 23 Jan 2015
I call a function using uigetfile() from another function, but when it runs, MATLAB seems to ignore the line entirely. (The function runs just fine when called from the command line.)
The function is simply:
function [sl] = InputSeaLevel()
%InputSeaLevel prompts for the location of a file containing sea level data
[fname,pname]=uigetfile('*.mat','Select the file containing sea level data');
varname=load(strcat(pname,fname));
name=fieldnames(varname); sl=getfield(varname,name{1});
end
The script that calls InputSeaLevel() does so from within an if loop-- specifically, an if loop created to parse the output from a menu box, e.g.:
c=menu('Make a choice','Yes','No');
if c==1
sl=InputSeaLevel();
{more code}
else
{other code}
end
I successfully ran the function from the command line from within the following loop:
a=1;
if a==1
sl=InputSeaLevel();
end
and the function runs well when removed from the if loop, so I believe that the if loop itself (or perhaps the use of menu() is the problem. I do use eval in an earlier script:
eval([XYZ_var '= tempXYZ;';])
eval([StackName '= stackXYZ;';])
but I don't believe these lines are the cause of the problem, since the problem still occurs when these lines are commented out.
I've seen some discussion of similar problems with uigetfile() before (see here), but I haven't understood the proposed solutions-- presumably the dialog box opened by menu() (and closed when one of its option buttons is clicked) shouldn't be stuck waiting for a response. I don't follow the explanation for how to force any open (but somehow hidden) dialogs to stop waiting, and I don't understand how it could still be open to begin with.
I am running MATLAB R2013a from a Windows 7 machine.
Does anyone have an explanation for what is about this code that is preventing MATLAB from "seeing" uigetfile() when it executes my function? Does anyone know what I can do to either avoid or circumvent this (without simply excluding the function or removing it from the if statement)?
Thanks in advance!
  3 Comments
Sarah
Sarah on 1 Aug 2014
Geoff and dpb-- thanks for your responses. I have attached the code that's generating the error for me-- it's sort of an all-in-one script for automated data processing, so it calls several other scripts (ReadXYZ) and functions (InputSeaLevel, GridXYZ), also attached.
I ran the example code from the initial post in my command window and hit the same error-- a screen capture of the example code as run is attached so that you can see the exact error, which occurs not in the line containing uigetfile, but in the next line, which uses the output of uigetfile.)
The menu box does appear in the code when it is called, and it seems to work normally (i.e., it disappears when the Yes or No button is clicked and returns the proper value according to the button).
The problem does not happen when I run InputSeaLevel() itself (the function that calls uigetfile) from the command line, but it does happen when I call InputSeaLevel from the all-in-one script--specifically, from within the if loop after the menu() command. (It runs fine when called before menu()-- which very much implicates menu() as the cause of all this, even if it's not clear how or why.)
I have tried running the guts of InputSeaLevel() without the function wrapper (i.e., simply the text of lines 3 through 5) directly in ProcessXYZ, but it still generated the error. I've also tried converting ProcessXYZ to a no-input, no-output function with the same results.
The problem happens regardless of whether I'm running ProcessXYZ from the command window or through the GUI on the code editor, and really does seem to be that MATLAB simply ignores the line that calls uigetfile().
Thanks again for your help!

Sign in to comment.

Answers (2)

Geoff Hayes
Geoff Hayes on 1 Aug 2014
Edited: Geoff Hayes on 1 Aug 2014
Maria - I get that same error message
Warning: Input should be a string.
> In strcat at 83
In InputSeaLevel at 4
Warning: Input should be a string.
> In strcat at 91
In InputSeaLevel at 4
Error using load
File name is empty.
Error in InputSeaLevel (line 4)
varname=load(strcat(pname,fname));
if I run the code and choose not to select a file i.e. press the Cancel button. Is this what you are doing, or are you in fact selecting a file?
The InputSeaLevel code should be modified to handle the case of the user not selecting a file
function [sl] = InputSeaLevel()
[fname,pname]=uigetfile('*.mat','Select the file containing sea level data');
% if no file selected, then fname is a double - so check for char/string
if ischar(fname)
varname=load(strcat(pname,fname));
name=fieldnames(varname);
sl=getfield(varname,name{1});
else
% raise error indicating no file selected
error('InputSeaLevel - no file selected!');
end
-------------
As for running your script, if I create one or more dummy text files with 26 numeric elements in it (as per the specification) and run ProccessXYZ, I am prompted for a directory (for the XYZ data), I then see the menu (from which I select yes), and then I'm prompted with the file chooser, and the code runs to completion if I have chosen a file.
Have you thought about stepping through the code in the debugger? i.e. put a breakpoint in ProcessXYZ at line 10
if c1==1
and then re-run ProcessXYZ. What is the value of c1, at this point, when the user has selected Yes in the menu.
  4 Comments
Geoff Hayes
Geoff Hayes on 2 Aug 2014
Good luck, Sarah! One thing you may want to consider doing is following the suggestion from dpb and make your ReadXYZ and ProcessXYZ into functions (with the end as the last line for each). Just to see what happens.
One other positive benefit of making functions is that all variables are local to the function and so don't populate the base workspace. This removes the need for the clearvars or other statements. I realize that some of your variables from ReadXYZ need to be made available to ProcessXYZ, and they could be with just simple return to the function signature. For example, the first line of ReadXYZ becomes
function [stackXYZ,RunName,SaveDir] = ReadXYZ
and you can remove the clearvars at the end.
And the first couple of lines of ProcessXYZ becomes
function ProcessXYZ
close all
%%Loading and Gridding
%Loads the data and combines them into a single "stack" of output arrays
[stackXYZ,RunName,SaveDir] = ReadXYZ;
__
And the final thing I will say about the uigetfile problem and how when you commented out ReadXYZ it worked the first time but not the second. Could this have to do with some of the script variables (now in the base workspace) conflicting with some built-in function name? Anyway, if you have time, then please try the above.

Sign in to comment.


Martijn
Martijn on 23 Jan 2015
It looks like you are running into the bug which is described here:
https://www.mathworks.com/support/bugreports/895795
The menu function creates a figure which after you have made a choice is deleted. This then leads to a threading issue which can be resolved by calling drawnow between calling menu and uigetfile.

Products

Community Treasure Hunt

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

Start Hunting!