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

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.

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));

How to save a .mat file using a name with a :

If I do x='bob:.mat' and then try to save it as a mat file like so:
number=10;
save(bob,'number');
I get an issue where it can't be saved, and I am assuming this is the case because: is a special character. I looked up online how to use it, and an example told me to put a ' mark before it, but that didn't work. Any help would be appreciated.
It should be: save('bob.mat', 'number');
Or
save bob number
save('bob', 'number'); also works.
save('bob:', 'number'); results an error (in Windows):
Error using save
Unable to open file "bob:" for output.
A file name with : is not allowed, because it's reserved for drive letters like C:.
A workaround is described here: How to get a file in Windows with a colon in the filename?
Following code actually does work:
save('bob꞉','number');

Add folder path based on run script 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

Running a Matlab p-file coded for Windows on a MacOS

I have several Windows sourced p-files internally coded with the '\' file separator that I want to run on Matlab under macOS.
I get errors caused by the '\' because macOS uses '/'.
eg The pfile tries to call a file named "model\xyz' which causes a warning:
"Name is nonexistent or not a directory: model\ "
1) Is there code that I might insert somewhere to recognise the 'model\' call from the pcode file and change it to 'model/' before it is used by MATLAB addpath?
2) Is there a generic fix I could apply to the addpath code?
3) Or better still is there a way to modify the Windows p-file without access to its source code so that it will run under macOS?
There are several things you can do (none of which are particularly easy; listed here in increasing order of how nasty I think they are):
Contact the author of the code and ask them to fix it.
Install an older MATLAB version (R2007b <= ver < R2015b, I think) which allowed debugging (stepping into) p-files within MATLAB, then, assuming that there is some line in the original source code that does
filepath = ['model' '\' 'xyz.m'];
step until you see filepath appear in the workspace (having the wrong path in it), then simply edit the value to the correct path, and hope for the best.
(Essentially the same idea as before, but on newer MATLAB versions, VERY DIFFICULT to pull off) Obtain an external debugger, attach to the MATLAB process, run the p-file and scan the memory for the contents of filepath. When you discover it, change the value to the correct path and detach/disable the debugger.
If this code relies on some external (and open source) function to get (or use) the path, you can modify its behavior to output the string you want. This requires some knowledge about the source code.
Find/make a tool for decoding p-files and fix the resulting source code yourself.
For completeness I describe how my problem was solved:
As suggested by Dev-iL I was eventually able to locate the author and he modified his code. This is the best solution but it took some time and is not always possible.
Based on: https://au.mathworks.com/matlabcentral/answers/117110-dealing-with-and-windows-vs-unix-for-path-definition I located a module (I've forgotten its name) within the Matlab package which handles file calls and intercepted all incoming file path names containing the '\' Windows separator, and replaced them with the always acceptable '/'. This quick and dirty fix worked until solution 1. was obtained.
Thanks to all who responded so quickly to this question.

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..