MATLAB: Running a .bat in parallel: multiple working directories possible? - matlab

I am running a .bat file using the command system (or dos) in a parfor loop in Matlab 2013a. Is there a way to change in which directory the command gets executed? So far it seems that it is always the current (working) directory. Another option would be to change the working directory inside the parfor loop, but that would mean having multiple working directories at the same time, which doesn't seem to be possible. The reason I do this is that I have one Simpack model and want to run several different simulations at the same time. In serial for-loop I can do this by copying the simulation specification to the Simpack folder one-at-a-time, but in parallel this must be changed.
parfor i=1:2
...
cd(path_model_main_temp_i);
system('C:\SIMPACK\SIMPACKv8.9\s_8904\simpack\com\spck.bat simpack integ modelname');
copyfile(path_results_temp_i, path_results{i});
end
This snippet doesn't work, but is it the right direction?
EDIT: It turns out there was a different problem with my code. It is possible to have a cd command inside a parfor loop.

Try changing directory within the process created by the system() command - which is fine as it is a new, and distinct process, it can have its own directory.
Something like this:
system('cd somewhere & C:\SIMPACK...');

I think you're on the right track here. One thing you could do use getCurrentTask to work out where to put that directory. For example, something like this:
parfor idx = 1:2
t = getCurrentTask();
if isempty(t)
% running on the client - use tempdir
d = tempdir();
else
% on a worker - make a subdirectory using task ID
d = fullfile(tempdir(), num2str(t.ID));
mkdir(d);
end
cd(d);
pwd
% do stuff
end

Related

General file pathing in MATLAB

I'm looking for a command to get a general file path in MATLAB. I'm looking to be able to run my code across multiple computers.
Example
fullfile('','C:','users','XXXXXX','Desktop','Matlab Data')
Is it possible to get this fullfile location off of where the MATLAB code is stored so that it can be used later in the code for file execution, regardless of what computer it's executing it?
From within a function called foo:
function x = foo( )
x=fullfile(fileparts(mfilename('fullpath')),'lorem','ipsum');
% fun stuff
end
This should work regardless of your current working directory.

Find location of current script (mlx-file) in MATLAB

I'm working on my MATLAB code in a number of different locations, and it would be really helpful if I could make the code aware of its location on the computer. Till now I worked with .m-files. For .m-files I found the following solutions:
%example 1
cd(fileparts(mfilename('fullpath')))
or
%example 2
tmp = matlab.desktop.editor.getActive;
cd(fileparts(tmp.Filename));
or
%example 3
S = dbstack('-completenames');
S(1).file
or
%example 4
which(mfilename)
But with MATLAB 2016a there comes a new feature called live script. And with that those solutions are not working anymore.
%For example I would like to do something like this
cd(MLX_FILELOCATION);
%or
which(mlxfilename)
(Edit III: Problem: I am not able to get the path/filelocation or name of the current opened/executed MATLAB-file. With *.m-files this is possible with the examples above. With *.mlx-files it is not possible anymore. And I prefere to use *.mlx-files instead of *.m-files.)
Outputs of the examples above executed in a *.mlx-file:
%example1: mfilename returns the path to the 'MatlabEvaluationHelper' in the 'AppData\Local\Temp'-folder
%example2: output is an empty array
%example3: same output as example1
%example4: same output as example1, because mfilename returns "MatlabEvaluationHelper"
Edit I:
My first goal is that I would like to change the "current folder" (-> "cd") to the path of the running script.
Why: In the same folder with the mlx-file I have for example .csv-files with data. And for example by tomorrow I have new folder. I copy the mlx_file and now I want to make sure that I don't use the csv-files from yesterday (because the current folder from yesterday is shown in the file browser of MATLAB) -> so I would like to change the "current folder" automatically with just copying the mlx-file into a new folder.
If there is a better practise for that, please let me know.
Thanks for helping
Edit II:
Example for a used workflow:
I programmed a MATLAB script. Saved it in folder "Dataset_ONE". Furthermure I copy "Dataset_ONE.csv"-file into the same folder. E.g. I now create a plot and save it as the "*.png" in folder "Dataset_ONE".
The day after I might have a second (a new and with that different) dataset "Datasset_TWO". I create a new folder "Dataset_TWO". Copy the MATLAB-files to the new folder. Open the MATLAB file there. Then, because of the default settings, MATLAB has changed the "Current Folder" to the new folder where I opened MATLAB.
But if I now open the MATLAB script in the first folder again (at the same time with the other dataset MATLAB script) I have to be careful about the current folder.
In this case it might be useful to have the described solution.
If what you want is some sort of way of preventing you running the wrong script on the wrong data without realising, then you could add a safety instruction at the top of each script, throwing an error if your current directory is not the same as the location of the script you're running. e.g.
>> assert (strcmp (pwd, '/absolute/path/to/my/script'));
As for loading the right data / saving to the right location, just load and save using absolute paths and there should be no confusion.

saving data from workspace to different dirrectory in matlab

I have a loop which my main script run through that. I wounder to save some of my variables in different directory every time that my loop is running. I have used following script but its not working:
for i=1:size(whisk, 1);
my codes is here and it creates variables in my workspace like [format, measurements].
the rest is what I wote to save this variables:
mkdir('C:\videos\results\', num2str(i));
dumvar=0; % As matlab has problem with data>2GB, then I use this 2 line code for saving
save('measurenments','dumvar','-v7.3');
save(fullfile('C:\videos\results\', num2str(i),'measurenments'));
clear all;
close all;
end
but Unfortunately its not work!!!!!!!!!!!
Any help would be appreciated.
Sam
Except that measurenments is wrongly spelled (correct spelling is measurements), there is not so strange that it does not work. The first call to save, saves the variable dumvar in the current folder, with the format v7.3. The second call to save, saves the whole workspace as a file fullfile('C:\videos\results\', num2str(i),'measurenments'). Try this,
save(fullfile('C:\videos\results\', num2str(i),'measurenments'),'dumvar','-v7.3');
However it seems as the folder fullfile('C:\videos\results\', num2str(i),'measurenments') does not exist since you only create the folder mkdir('C:\videos\results\', num2str(i))
. Then matlab cannot save anything there. Try either to save as fullfile('C:\videos\results\', [num2str(i),'measurenments']) or create the directory mkdir('C:\videos\results\', [num2str(i),'\','measurenments']);
`

Can I change the script from one Matlab session while the other one is running that script?

I have two Matlab sessions runs parallel.
To be handy, I just change the parameters that are hard-coded into the scripts for each run.
So my question is, can I change the script when the first Matlab session is running that script? After I changed and saved that very script, will the first Matlab session run according to the original version of the script?
I have multiple scripts that call each other. Will it be more complicated in this situation?
If the answer is YES, it will appear to me that for each run, Matlab will make a ad-hoc copy of all the scripts and run that copy regardless of the hard-disk changes.
MATLAB's first step after you press "run" is to parse all the script/function's M-code and all of its dependencies into something akin to "byte code". That means that whatever MATLAB is running, is entirely in memory and thus not coupled anymore to what's in the M-file(s).
Therefore, you may indeed use another MATLAB session to change parameters in an M-file, save it, and run it in the new session, without affecting what the outcomes of the first session are.
Be sure to save or print the values of those variables though; working this way is a sure way to forget what values of those parameters belong to which session again :)
Note that this is NOT true for:
data files, or other files explicitly read during runtime
MEX files
A better workflow would be to convert those scripts into modular functions that receive configurable parameters as input, as opposed to hardcoding the values in the code.
That way you call the same function in each MATLAB session without making any changes to the M-files, only each session passes different input arguments as needed.
To learn more about how MATLAB detects changes in M-files, run the following:
>> help changeNotification
>> help changeNotificationAdvanced
You also might also wanna read about the following functions: rehash and clear functions
EDIT:
One way to find out which scripts/functions are currently "loaded in memory" is to use inmem. Say for example we have the following script saved in a file available on the path (the same works for functions):
testScript.m
x = 10;
disp(x)
Now starting with a clean session, the script is initially not loaded. After calling the script, the file is loaded and remains in memory:
% initially not loaded
>> ismember('testScript', inmem())
ans =
0
% execute script
>> testScript
10
% file is cached in memory
>> ismember('testScript', inmem())
ans =
1
Immediately continuing with the same session, make an edit to the file (for example change x to 99). By checking the list of loaded functions/scripts again, you will see that MATLAB has already detected the change, and invalidated the cached version by removing it from memory:
>> % .. make changes to testScript.m file
% file is automatically unloaded
>> ismember('testScript', inmem())
ans =
0
% execute the new script
>> testScript
99
% the result is cached once more
>> ismember('testScript', inmem())
ans =
1
I tested the above on my Windows machine, but I can't guarantee this behavior is cross-platform, you'll have to test it on Mac/Linux and see if works the same...
The script can definately be altered without influencing an ongoing run. However, if your flow gets more complicated it can be problematic to depend on what will happen:
Here are some flows you will not likely want:
main1 calls sub
sub is edited
main2 calls sub
main1 continues to run and calls sub for a second time
In the above case I would expect the second run of main1 to be calling the altered version of sub, but I would not depend on it.
main1 calls sub
sub is edited
sub called by main1 hits a breakpoint
I am not even sure what will happen, but I believe that you will stop on the original line, but will see the edited code. So the line you find may not even be the line with the breakpoint anymore.
So to conclude: Don't alter your script frequently to change the output, rather give it inputs that will determine the output.

Matlab - Can't call function because it says I'm trying to execute a script

In Matlab I defined a function called iReadImage it looks like:
function [outimag] = iReadImage(imaurl)
{code}
I used it for hours and everything seemed to work fine but then I changed one line and all of a sudden it didn't work anymore, even after I deleted that line nothing worked. It always tells me:
Attempt to execute SCRIPT iReadImage as a function:
/home/.../iReadImage.m
When I look at the file it says that it is 0kB....No idea why, I tried kind of everything, copied the function to a new function, rebooted my computer even tried it on other PCs. Two or three times it seemed to work again but never for long until I got the same error message.
Matlab is very particular about how its functions can be constructed. The file functionname.m should start with the first line function [output] = functionname(input). Otherwise, it will assume that it is dealing with a script and not a function. Additionally, if your file is a function, you can declare within it, like:
function y = f(x)
y = g(x) + 2;
function z = g(x)
z = x.^2;
end
end
However, if your file is a script, Matlab does not allow such function declarations. One way to test this would be to trivially turn your existing script into a function (by wrapping it with a function with null input and output), and see if he same error occurs.
The problem is probably that you've changed your working directory (using e.g. cd). You can only run functions that are in the current working directory, or in directories listed in path.
To confirm, type which iReadImage.
My guess is that you have multiple iReadImage files in the directories where matlab searches for scripts and functions. If so it's likley that Matlab have found the wrong one (perhaps one with an error in it?) and tries to execute it.
Make sure you only have one copy of the file (check which directories Matlab searches in with path).
To find out from which directory Matlab will execute your function write which <filename>, that is, in your case which iReadImage and make sure the correct file is used.
You can also use which iReadImage -all to find all iReadImage files.