I have distributed my computing to many platforms so I cannot use fullpath but instead relative like $HOME.
Code
filename=strcat('$HOME/Images/',num2str(item);
save(strcat(filename,'.mat'),'masi');
saveas(her, strcat(filename,'.png'));
Output
Error using save
Cannot create '777.mat' because '$HOME/Images' does not exist.
Error in masiCool (line 98)
save(strcat(filename,'.mat'),'masi');
Backward flash \$HOME does not work neither.
How can you have $HOME in Matlab's save/saveas?
Environment variables (such as $HOME) are not automatically parsed by MATLAB. In general, if you need the value of an environment variable, you can use getenv.
homedir = getenv('HOME');
Alternately, on *nix, you can actually just use the tilde (~) to represent the user's home directory in a filepath.
folder = '~/Images';
However, I typically just rely upon the Java to get the user home directory for me since it will work properly on any platform.
homedir = char(java.lang.System.getProperty('user.home'));
Then, use fullfile to concatenate the path you want onto the user's home directory.
filename = fullfile(homedir, 'Images', sprintf('%d.mat', item))
NOTE: If you are wanting to do this on an HPC or some instance of MATLAB that is not using the JVM. The getenv option is best. On Windows, you would want the HOMEPATH variable rather than HOME.
Try full path instead of using $HOME. $HOME is a system command and it is not recognizable in Matlab.
Use \home\YOUR_USER_NAME instead of $HOME.
TIP: In case you have to use a system command inside Matlab, system() is a useful function.
Related
By way of preamble, consider this example from Unix. Suppose that /some/path/foo and /some/other/path/foo are both available executables. Also, suppose that both /some/path and /some/other/path are present in the $PATH environment variable, with /some/path appearing first. Then, if I run
% foo
the foo that gets run is /some/path/foo. That's what the $PATH variable is all about.
Nevertheless, I can always invoke the other foo by referring to it by its full path, like this:
% /some/other/path/foo
IOW, once I refer to the command by its full path, no name resolution needs to happen, so $PATH plays no role in deciding which foo gets run.
Importantly, this mechanism does not require modifiying the $PATH variable. One just sidesteps it.
With this example in mind, does MATLAB provide a way (other than changing the search path) to run a function foo from a file different from the first candidate file in the MATLAB search path?
See MATLAB function handles and feval.
I have created a few general function in MATLAB that I intend to use for a few separate projects. However I do not want to copy the function into each separate project function.
I have created a folder called Misc_Function when I have placed these general functions. I know I can reference this functions explicitly by using the path and function name when trying to call the functions.
I believe you can add a path (in my case 'H:\MyTeam\Matlab\Misc_Function') when MATLAB loads up is that correct and if so how do you do this?
Assuming the above can be done I'm interested to know how MATLAB finds the correct function. In my understanding (guess work) MATLAB has a list of paths that it check trying to find a function with the name specified - is that correct? If so what happens when there are functions with the same name?
MATLAB indeed has its own search path which is a collection of folders that MATLAB will search when you reference a function or class (and a few other things). To see the search path, type path at the MATLAB prompt. From the documentation:
The order of folders on the search path is important. When files with the same name appear in multiple folders on the search path, MATLAB uses the one found in the folder nearest to the top of the search path.
If you have a set of utility functions that you want to make available to your projects, add the folder to the top of the search path with the addpath function, like so
addpath('H:\MyTeam\Matlab\Misc_Function');
You have to do this everytime you start MATLAB. Alternatively, and more conveniently, save the current search path with the savepath command or add the above commands to your startup.m file.
You can check the actual paths where Matlab searches for functions using
path
You will notice, that the most top path (on start up) is a path in your home folder. For Linux this is e.g. /home/$USER/Documents/MATLAB. For Windows it is somewhere in the the c:\Users\%USER%\Documents\Matlab (I think). Placing a file startup.m in this folder allows to add additional paths using
addpath('H:\MyTeam\Matlab\Misc_Function');
or
addpath(genpath('H:\MyTeam\Matlab\Misc_Function'));
on start up of Matlab. The latter (genpath) allows to also add all subdirectories. Simply write a file startup.m and add one of above lines there.
I believe 'addpath' will add the folder to MATLAB path only for the current MATLAB session. To save the updated path for other sessions, you need to execute 'savepath' command.
As mentioned in the previous comments, adding the folder in startup.m is a good idea since it will be added to the path on MATLAB startup.
To answer your question about how MATLAB finds the correct function, MATLAB maintains a list of directories in its path in a file called pathdef.m. Any changes to the path will be written to this file (when you execute 'savepath'). The path variable is initialized with the contents of this file.
I wrote a MATLAB program with a GUI (to enter the measurement settings) and a measurement function which gets called when pressing "START" in the GUI.
In both I use separate files for sub functions to keep it easier to read and maintain.
The file structure looks something like this
C:/../folder/+measure/measure.m
C:/../folder/+measure/getData.m
C:/../folder/+measure/plot.m
C:/../folder/+measure/evalutate.m
C:/../folder/+measureGUI/getGuiData.m
C:/../folder/+measureGUI/calcLimits.m
C:/../folder/+measureGUI/saveGuiState.m
C:/../folder/+measureGUI/loadGuiState.m
C:/../folder/+measureGUI/background.png
C:/../folder/+measureGUI/guiState.mat
C:/../folder/measureGUI.fig
C:/../folder/measureGUI.m
This works, if I'm executing the measureGUI.m in "folder".
The current settings in the GUI are saved in the guiState.mat file when closing the GUI in saveGuiState.m
filename = '+autoProberGUI/guiState.mat';
save(filename, 'guiState');
And loaded (by loadGuiState.m) the next time the GUI gets opened.
Now I have to put the finished program on a network drive and add the folder to my matlab search path to call measureGUI.m.
The program works but it can't save or load the guiState.mat due to the relative path (I guess the path is relative to the folder I'm currently in, and not the folder the calling function is in).
I think I could include the subfolder to the search path or use an absolute path in filename. But both solutions seem to me to be not the proper way.
Is there a way to have relative paths to the file from where the function is located on the drive? Meaning relative to
I:/..NetworkDrive../folder/+measureGUI/saveGuiState.m
instead of relative from where I call measureGUI.m
(Sorry for the poor English, I hope it is not too confusing)
You can use pwd to get the full path to you current working directory.
Then you can concatenate with [pwd '/folder/+measureGUI/saveGuiState.m'].
To locate the function you can use which.
I have a situation in which a large amount of data output from Matlab programs needs to be stored in a specific location that can vary from machine to machine. What I'd like to have is a global variable that is set at startup for each machine. This variable could then be used by the various programs in order to determine the directory to store the output. Note the approach will need to be platform independent as there a potentially 3 operating systems that will run these scripts.
One approach I considered is using setenv:
setenv('DATDIR',fullfile(path,to,dir));
Then the script/function could query this variable using:
savedir = getenv('DATDIR');
In this case the variable is unaffected by clear inside the Matlab environment.
Another approach I thought to use is simply creating a function (like matlabroot), which is on the path and simply returns a string to which the data directory path is assigned.
function path = datroot()
path = fullfile(path,to,dir);
end
Finally, to my question: Is there another way to achieve the same result? If Matlab has it's own environment variables, I'd rather use those instead of functions or system-level variables. Is this possible?
Use the getpref/setpref/ispref/addpref/rmpref set of functions. According to the documentation:
Preference values are persistent and maintain their values between
MATLAB sessions. Where they are stored is system dependent.
This is like .ini or Java .properties files, but instead uses MAT-files to persist the values (which can be of any MATLAB type). On my Windows machine, the file used is stored as:
%APPDATA%\MathWorks\MATLAB\R2010b\matlabprefs.mat
I run MATLAB on both Linux and Windows XP. My files are synced among all of the computers I use, but because of the differences in directory structure between Linux and Windows I have to have separate import and export lines for the different operating systems. At the moment I just comment out the line for the wrong OS, but I am wondering if it is possible to write something like:
if OS == Windows
datafile = csvread('C:\Documents and Settings\Me\MyPath\inputfile.csv');
else
datafile = csvread('/home/Me/MyPath/inputfile.csv');
end
This is also a more general question that applies in cases where one wants to execute system commands from within MATLAB using system('command').
You can use ispc/isunix/ismac functions to determine the platform or even use the computer function for more information about the machine
if ispc
datafile = csvread('C:\Documents and Settings\Me\MyPath\inputfile.csv');
else
datafile = csvread('/home/Me/MyPath/inputfile.csv');
end
To follow up on Amro's answer, I was going to just make a comment but struggled with the formatting for the code.
I'd prefer to split the OS selection from the file read.
if ispc
strFile = 'C:\Documents and Settings\Me\MyPath\inputfile.csv';
else
strFile = '/home/Me/MyPath/inputfile.csv';
end
try
datafile = csvread(strFile);
catch
% setup any error handling
error(['Error reading file : ',strFile]);
end
That way if I need to change the way the file is read, perhaps with another function, it's only one line to change. Also it keeps the error handling simple and local, one error statement can handle either format.
Just to add a minor point to the existing good answers, I tend to use fileparts and fullfile when building paths that need to work on both UNIX and Windows variants, as those know how to deal with slashes correctly.
In addition to using the various techniques here for dealing with path and file separator differences, you should consider simply trying to avoid coding in absolute paths into your scripts. If you must use them, try to put them in as few files as possible. This will make your porting effort simplest.
Some ideas:
Set a fileRoot variable at some early entry point or config file. Use fullfile or any of the other techniques for constructing a full path.
Always use relative paths, relative to where the user is operating. This can make it easy for the user to put the input/output wherever is desired.
Parameterize the input and output paths at your function entries (e.g., via a system specific context object).
If the directory structures are within your home directory you could try building a single path that can be used on both platforms as follows (my Matlab is a bit rough so some of the syntax may not be 100%):
See here for how to get the home directory for the user
Create the path as follows (filesep is a function that returns the file separator for the platform you are running on)
filepath = [userdir filesep 'MyPath' filesep 'inputfile.csv']
Read the file
datafile = csvread(filepath)
Otherwise go with Amros answer. It is simpler.