Add folder path based on run script matlab - matlab

Don't know why this isn't working anymore. Very simple. I have a script with a folder in the same path. The folder contains a series of m files for the script to work.
Originally I simply would use
addpath('.../utilities/);
when the script was first run. but recently I started receiving this error
Warning: Name is nonexistent or not a directory: ...\utilities
In path (line 109)
In addpath (line 88)
In Myrunningcode (line 101)
and I don't know why.
I fixed the problem by running the following code
p = mfilename('fullpath');
[filepath,~,~] = fileparts(p);
addpath([filepath,'/utilities/']);
At least I would like to know why this error occurred.
Here is my directory setup. I use windows 10 and matlab 2016a.

The issue is likely that your current directory (pwd) is not the same as the file location. The relative directory isn't relative to the current script, it's relative to pwd, hence why the mfilename workaround fixes your issue.
The first solution is your own, but you can do it in one line:
addpath( fullfile( fileparts( mfilename('fullpath') ), 'utilities' ) );
Then the quickest way to check if your files are already on the path is using which:
% Assuming that myFile.m is within the utilities folder, and not shadowed elsewhere.
% If utilities is on the path, which('myFile') will not be empty.
if isempty( which( 'myFile' ) )
addpath( fullfile( fileparts( mfilename('fullpath') ), 'utilities' ) );
end
Alternatively, you could pair the above check with a persistent flag variable, so you don't have to repeat the check if you re-enter the function.
Note that addpath isn't particularly slow, it's genpath you want to avoid if you were to add a load of subdirectories too.
Aside: It's good to use fullfile instead of manually concatenating with (OS dependent) file separators. Less room for error (e.g. double slashes) even if you're always using the same OS.

The correct way to include a relative folder is:
addpath('./utilities/');
with a single dot.
This has worked (and works) since the existence of relative folders, AFAIK, so you should be able to use it without fear of deprecation

Related

Error using "save" to save in a directory

I would like to save a workspace in another directory and I have written the following in Matlab for it:
fileName = [datestr(now, 'dd-mmm-yyyy_HHMMSS') '_test'];
save('C:\Users\User\project',fileName)
It gives me the error: Error using save: '05-Nov-2019_083736_test' is not a valid variable name.
But if I run without giving an address of the directory it workes perfectly.
Why does it happen?
You can either use il_raffa's suggestion from the comments (with a small correction):
save(['C:\Users\User\project\' fileName])
% ^ add a folder separator here
or use the fullfile function, to avoid errors due to forgotten folder separators:
save(fullfile('C:\Users\User\project', fileName));
This works also for subfolders and filenames, e.g.
save(fullfile('C:\Users\User\project', 'matfiles', fileName));

Matlab: access files relative to working directory

I've noticed that most Matlab functions that acess files, e.g. load() resolve relative paths by finding some directory on the current path that contains files or directories matching these paths. E.g. calling load('foo/bar.m') will load /home/someuser/dir1/foo/bar.m over /home/someuser/dir2/foo/bar if the current working directory is /home/someuser/dir2 but /home/someuser/dir1 is on the search path.
I find this to be highly irritating and error-prone, how can I access files relative to the current working directory instead?
As you know, Matlab can resolve both relative and absolute paths. But my suggestions to handle your issue with less headaches:
At each (relevant/main) script ensure that your workspace is the scripts location with:
PATH.SCRIPT = fileparts(mfilename('fullpath'))
cd(PATH.SCRIPT)
Then, always call functions with absolute paths using:
load([PATH.SCRIPT, filesep, 'filename'])
or
load([PATH.SCRIPT, filesep, '..' , filesep, 'file_at_upper_dir_name'])
or
load([PATH.SCRIPT, filesep, 'subfolder' , filesep, 'file_at_lower_dir_name'])
If possible, try not messing too much with Matlab's default path, and at initialization of your workspace call restoredefaultpath. This reduces chances that there is a spurious folder in your path where name collisions can happen.
As others have mentioned, ./ or ['.', filesep] also provides with with the current folder.
As #CrisLuengo mentions, instead of filesep one might prefer to compose paths with fullfile, for instance: load(fullfile(PATH.SCRIPT, '..', 'file_at_upper_dir_name'))

Failure to read jpeg files in Matlab

I'm trying to open images with imread but it keEps telling me that the files do not exist.
Here's the message from the command window
Error using imread>get_full_filename (line 516)
File "Pic1.jpg" does not exist.
Error in imread (line 340)
fullname = get_full_filename(filename);
Error in ImageDetection (line 2)
img1 = imread('Pic1.jpg');
And here are the sections of code that it's referencing from the function itself
if (fid == -1)
if ~isempty(dir(filename))
% String 'Too many open files' is from strerror.
% So, no need for a message catalog.
if contains(errmsg, 'Too many open files')
error(message('MATLAB:imagesci:imread:tooManyOpenFiles', filename));
else
error(message('MATLAB:imagesci:imread:fileReadPermission', filename));
end
else
error(message('MATLAB:imagesci:imread:fileDoesNotExist', filename));<--LINE 516
end
if isempty(fmt_s)
% The format was not specified explicitly.
% Get the absolute path of the file
fullname = get_full_filename(filename); <--LINE 340
Image isn't in Current Directory (Or Path)
If your image is in your working directory, you can call it by its name ("Pic1.jpg"). However, MATLAB doesn't search all folders on your computer. If, for example, if your program is running in C:\Users\user\Documents\MATLAB, and the image is in C:\Users\user\Pictures, you could reference the picture using:
Absolute paths ("C:\Users\user\Pictures\Pic1.jpg")
Relative paths ("..\..\Pictures\Pic1.jpg")
Usually, if the pictures only exist because of your program, it'd be somewhere in the same directory, so you wouldn't need to use ".." to move up any directories.
If you want the user to be able to select a picture each time the program is run, I'd recommend looking into uigetfile. If you want to know more about where MATLAB searches for files, see this article.
Secondly, you may want to check your file name. While it seems obvious, a simple misspelling can be hard to notice at times, for example "Pic1.jpg" vs "Pic1,jpg" vs "Pic1.jpeg"
Just above the line of your code where the error occurs, write a new line:
dir
To output in the prompt the files of the current folder, and check that the name of your file exactly appears there. Could you copy us that output?

Matlab doesn't read files with tilde (~) instead of full home path

I've noticed a strange behavior of Matlab when accessing files. Say I have a path to a file like this:
path = '~/data/file'
If I run exist(path), the result is 2, i.e. the file exists. If I run
textread(path, '%s')
then I get an error message
Error using dataread
File not found or permission denied.
However, if I expand the tilde and run textread, it works fine:
path2 = '/home/username/data/file'
textread(path2, '%s')
Can you explain this behavior?
Yes, exist understands relative paths (as identified by the tilde), whereas textread does not.
Note that textscan is now the preferred way of reading data from a file - this accepts file identifiers so will work with relative paths.
If this is not an option, a good GetFullPath function can be found here.

octave load function

i'm trying to load a mat file from a subdirectory using the following code:
% filename_str is read from a text file
directoryname_str = "./data";
f = fullfile(directoryname_str, filename_str);
load(f);
when i run this sequence, load says it can't find the file...but when i copy or type the relative path and the file name by hand into an active octave session, everything works like a champ with no errors.
i assume this has something to do with how octave searches for mat files? if so, what's the correct environment variable or function call i need to make in order for this code to work?
thanks!
Are you sure that what you put into the variable f is the same as what you input manually in octave?
Are you also in the same directory? Because you're specifying relative paths, this should be the case.. you can get the current directory octave is in with pwd
And last of all, you can double check file existence in octave itself using exist
exist(f,'file')
If this returns false, there's definitely something wrong with your current directory, are something's very weird going on..