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

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.

Related

Siemens S5 to S7 XR.INI file

I'm trying to convert a program from S5 to S7. I've taken a look into the tutorials and documents that are available. But I cant seem to find any information about this problem:
The program is pretty complicated and I should need the XR.INI file to convert it with the S5 Converter program that came with Simatic S7. When I open the folder with the project I see all the files I need and that are described in the tutorial made by Siemens.
.ST.S5D
.XR.INI
.Z0.SEQ
I start the converter and open .ST.S5D. When I did this I get the error there is no .XR.INI file. But I can see it in the folder. Its called CERMST.INI. So I guess the name isnt correct?
In PG2000 I remade the XRF with CTRL Q but nothing changed. I also tried to rename the file to CERM.XR.INI because I saw somewhere these files can only be 6 characters long (not sure if this is true).
I tried first without the XRF. There were some errors because of the ASM command. In the tutorial I saw the converter cant handle these so I removed these functions from the program to rewrite manually later on. After this I had an error because I had no XRF. Error was:
Error No PLC type description found for called or addressed block
So I really need the .XR.INI file but the program can't find it, but its clearly in the folder. How can I fix this? How can I make a new .INI file?
Link to tutorial: http://www.sankotek.com/TR/Dokumanlar/STEP%207%20-%20From%20S5%20to%20S7.pdf
Thanks in advance!
Siemens S5 file extensions used also last two letters before file extension to mark file type, like xxxxxxXX.XXX where x is file name and X is file type for S5, without second dot in the middle like you have. File name length limit exists, I think it comes from DOS or some older operating system file length limit.
If you don't have XRF file then if i remember correctly compiler does not have compile order. Some blocks have not been compiled but are referenced in caller block that the compiler tries to compile. Compiler does not find called block in compiled blocks folder and wham... fatal error. When i had such troubles i compiled called blocks independenly before calling blocks. So you can do without XRF file. But try to include Z0.SEQ, that file has assignment list so you get nice variable names instead of just variable address numbers.
Also, stackoverflow is not the correct place to ask questions about Siemens S5-S7 conversion. You should post your questions in http://www.plctalk.net, they have guys there who used to program S5 plc-s.

MATLAB doesn't find files I downloaded while the script is running

My problem is as described. My script downloads files through an external call to cmd (using the system function and then .NET to make keypresses). The issue is that when it tries to fopen these files I downloaded (filenames from a text file I write as I download), it doesn't find them, causing an error. When I run the script again after seeing it fail, it works but only up to the point where it's trying to download/call new files again, where it runs into the same problem.
Are new files downloaded during when a script is running somehow not visible to the search path? Because the folder is most definitely in my search path (seeing as it works outside of during-script downloads). It's not that it isn't getting the files fast enough either, cause they appear in my folder almost instantly, and I've tried a delay to allow for it to recognize it, but that didn't work either.
I'm not sure if it's important to note that the script calls an external function which tries to read the files from the .txt list I create in the main script.
Any ideas?
The script to download the files looks like so:
NET.addAssembly('System.Windows.Forms');
sendkey = #(strkey) System.Windows.Forms.SendKeys.SendWait(strkey);
system('start cygwinbatch.bat')
pause(.1)
sendkey(callStr1)
sendkey('{ENTER}')
pause(.1)
sendkey(callStr2)
sendkey('{ENTER}')
pause(.1)
sendkey('exit')
pause(2)
sendkey('{ENTER}')
But that is not the main reason I am asking: I am confident that the downloads are occurring when the script calls them, because I see them appearing in my folder as it called. I am more confused as to why MATLAB doesn't seem to know they are there while the script is running, and I have to stop it and run it again for it to recognize the ones I've downloaded already.
Thank you,
Aaron
The answer here is probably to run the 'rehash' function. Matlab does not look for new files while executing an operation, and in some environments misses new files even during interactive activity.
Running the rehash function forces Matlab to search through its full path and determine if there are any new files.
I've never tried to run rehash in the middle of an operation though. ...
My guess is that the MATLAB interpreter is trying to look ahead and is throwing errors based on a snapshot of what the filesystem looked like before the files were downloaded. Do you get different behavior if you run it one line at a time using F9? If that's the case then you may be able to prevent the interpreter from looking ahead by using eval().

Matlab and addpath

I have recently been working with Matlab. My question stems from my usage over a few months and is something that I can't seem to solve. I have an external SVM toolbox (OSU-SVM) that I would like to interface to with my project. I am able to get the entire system to work when I add the path of the toolbox manually (Right click -> Add to Path -> Selected Folders and Subfolders). What I would like to do is add the folder in a script. I've tried the "addpath" command but for some reason I can't get it to find the library relative to the m-file (script) that I run the command from. The following is an example of the code:
% Add OSU SVM system
addpath(genpath('./osu-svm/'));
The reason the I'd like to add the path using a relative folder to the M-file is that the code needs to run in a different environment that will not have the toolbox install. The code is also going to be executed in a different OS to the one I am developing on. That is, I am running a Windows Matlab to develop the code and need to run the finished system on a Linux machine. The process of running my files needs to be as painless as possible and shouldn't require much input from the user. That is why I'm specifically trying to avoid manual addition of the path.
On a side note a similar problem occurs when I wish to use "uigetfile" using a relative path. I believe there is something I am missing that will help me solve both of these simultaneously. Any help would be greatly appreciated.
Instead of './osu-svm/' alone use
fullfile('.','osu-svm')
The reason it does not work for you on windows is that you are using forward slash file separators. Full file will make a file string containing the correct file separator for each OS.
The genpath example in the matlab documentation also uses fullfile
http://www.mathworks.co.uk/help/techdoc/ref/genpath.html
Furthermore, the '.' is kinda unnecessary as it just means "relative to the current directory" and can be left out of the command. Perhaps you meant one directory up?
'..'
???

How to make matlab see functions defined in .m files?

I'm a total newbie to MATLAB but I have to write some code in it. I've had problems with making MATLAB see functions I've defined in external .m files. This is what I've done: I've created a file named, say, foo.m in my home dir with the following contents:
function [y] = foo(x)
% description
y = x + 1
When I run matlab (my home dir is matlab's workdir) it does not see foo function - it replies with standard ??? Undefined function or variable 'foo' message. BUT help foo or which foo return correct data printing help text and pointing on foo.m file respectively.
I must be missing something but I have no idea what it is. This is getting very annoying.
Oh, after several trial and error attempts I've managed to call that function. Unfortunately I can't remember the sequence of steps I've performed. Moreover after restarting matlab it returns to its usual 'Undefined function or variable' response.
I have 7.11.0.584 matlab running on linux.
MATLAB needs to be told which directories to search over to access those m-files. Clearly it cannot be left to search over your entire disk drives. The MATLAB search path is a list of directories that will be searched in specific order to find your functions.
help addpath
help pathtool
You should never put those files anywhere in the official MATLAB toolbox directories. Choose an entirely separate directory.
Finally, be careful not to name your own functions to match the names of existing MATLAB functions. Otherwise, your very next question here will be why your code does not work properly. This is a common cause of strange and confusing bugs.
It seems you're having some trouble with addpath. Try opening the file in the matlab editor and adding a break point in the file. If the file is not on Matlab's path, matlab should ask if you want to change directory or add the file to the path, choose add to the path.
If this doesn't work, try changing the current working directory (displayed in the main window) to the same location as the m file and calling the function. If this doesn't work you're either getting the name wrong ar there's possibly something wrong with your installation.
Occasionally matlab has problems if it does not have write permission to the directory the file's in, so check that too, i.e. make sure admin rights aren't required for the directory or m file.
Oh, and try:
clear functions
to reload all functions into memory.
The function needs to be in MATLAB's path. Use pathtool to tell MATLAB where to find your function. Note that if you name a function the same name as an existing function, MATLAB will use whichever function it finds first according to the order that the paths are listed as you see them in pathtool.
Although coming late but I hope it will help someone.
If in the folder where the function you are calling is residing, there is any other function with the same name as one of the functions from MATLAB toolboxes, then Matlab will not recognize its license and therefore will disable the whole folder from execution, no matter it is properly added to the path. The help will display though.
In order to check it, type:
which name_of_func.m
and you will get the path with "%Has no license available" message.
If it is your own function, you should not get this message but only the path.
Therefore, find the function in this folder which has the same name as a MATLAB toolbox functions, and rename it. I will solve the problem :).
Best Regards
Wajahat

Is it possible for a MATLAB script to behave differently depending on the OS it is being executed on?

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.