I want to read an image file in MATLAB and use the time it was created in the system to add a delay for my next command.
For ex if time_created is the system time the image file was created, I want my next command to execute after a delay of (time_now - time_created) + 3 sec. Is this possible?
You can use the information given by dir:
yourFileName = 'myFile.m'
allfiles = dir
filenames = {allfiles(:).name}
[~,idx] = ismember(yourFileName,filenames)
yourFileDate = allfiles(idx).date
which will return a date string:
yourFileDate = 06-Mar-2014 10:53:48
or alternatively:
yourFileDate = allfiles(idx).datenum
which will give you the output in datenum format. (You probably want to work with that)
you could then continue as follows:
timeNow = clock %//current system time as date vector
timeFileCreation = datevec(yourFileDate) %//file creation time as date vector
timeDiff = etime(timeNow,timeFileCreation)
returns the number of seconds between both time vectors.
Note that the matlab 'dir' command does not return the file creation time, but rather the last file modification time. In your use case, the creation time and the modification time are likely the same. But in other circumstances, the modification time may be different than the creation time (e.g. if a user edited a file after it was created). Different operating systems store different file times between the creation, last modification and last access times. Last modification time is the only one that is available in all operating systems that matlab runs on, so it is the only time supported by the matlab 'dir' command. Depending on with OS you're running on, you can access the other file times available on that OS, through (at least) use of the 'system' command and knowledge of the command line functions available in that OS.
With Python now really integrated into MATLAB, this works on both Windows and MacOS:
d1 =datetime(py.os.path.getctime('video_path'),'ConvertFrom','epochtime','TicksPerSecond',1,'Format','dd-MMM-yyyy HH:mm:ss.SSS');
Related
I'm running a short code to open one by one a list of files and saving back only one of the variables contained in the files. The process seems to me much slower than I expected and getting slower with time, I don't fully understand why and how I could make it run faster. I always struggle with optimization. I'd appreciate if you have suggestions.
The code is the following (the ... substitute the actual path just for example):
main_dir=dir(strcat('\\storage2-...\Raw\DAQ5\'));
filename={};
for m=7:size(main_dir,1)
m
second_dir=dir([main_dir(m).folder '\' main_dir(m).name '\*.mat']);
for mm=1:numel(second_dir)
filename{end+1}=[second_dir(mm).folder '\' second_dir(mm).name];
for mmm=1:numel(filename)
namefile=sprintf(second_dir(mm,1).name);
load(string(filename(1,mmm)));
save(['\\storage2-...\DAQ5\Ch1_',namefile(end-18:end-4),'.mat'], 'Ch_1_y')
end
end
end
The original file is about 17 MB and once the single variable is saved it is about 6 MB in size.
The Matlab load function takes an optional additional argument to specify just a selected variable to read from the input file.
s = load('path/to/file.mat', 'Ch_1_y');
That way you don't have to spend time loading in all the other variables from those input .mat files that you're just going to immediately throw away.
And using save to save MAT-files over SMB shares can be slow. You might want to call save to write it to a temporary local file first, and then copy the completed file to the final destination. Sounds like more I/O, but it can actually be a net win, depending on your particular system and network. Measure it both ways to see if it's a win in your particular situation.
I've got a problem changing my code result. The main problem is when I run the code, it works very well, and the final results are accurate. However, as you can see it's like a division of 2 big numbers. Please help me out how to change the formation of the results. I have to say that I've already used **format command ** and didn't get anything.
the result I want is something like :
sigma=156.45e+6;
Thanks.
The format command isn't what you need here I think.
If these values were generated using the symbolic toolbox, then they tend to remain as whole fractions, and in order to change this, you simply need to run the following code either in your script or in the command window:
sympref('FloatingPointOutput',true);
This will produce the values you are looking for.
Alternatively you can cast the values you have to a double using the following code:
ans = double(ans);
sigma1 = double(sigma1);
sigma2 = double(sigma2);
You must have set the command window format to long some time ago as this is not the usual behavior.
You can change this simply by typing to the command window.
The defaults are:
format shortEng % number representation
format compact % line spacing
BTW, you can get your current setting with this command
get(0,'Format')
However, changing the format only applied to your current session (until you close MATLAB). Therefore it is odd that you ask. If it persists to be changed, someone must have fiddled with the preference
The specified format applies only to the current MATLAB session. To maintain a format across sessions, choose a Numeric format or Numeric display option in the Command Window Preferences.
I'm using MATLAB and calling an .exe via the system command.
[status,cmdout] = system(command_s);
where command_s is a command string that is formatted earlier in my script to pass all the desired options to the .exe. The .exe would normally write to a .csv file via the > redirection operator in Windows/DOS. Instead, this output is going to cmdout where I use it later in the MATLAB script. It is working correctly and as expected. I'm doing it this way so that the process just uses memory and does not write a very large file to the disk, which would then have to be read from the disk and then deleted after I'm done with it. In the end, it saves a .mat file that's usually in hundreds of KB instead of 10s/100s of MBs as the .csv file would be (some unneeded data is thrown out in the end).
The issue I'm having is since I'm dealing with large files, the executable can take a significant amount of time. I typically have to wait about 2 minutes after executing this command. In the meantime, I have no feedback to know it is progressing and that my system hasn't froze. I know I could add the & symbol to the end of my string, command_s, and run MATLAB code while this is running in the background (or asynchronously as some would say), but that brings up an external window AND makes cmdout empty - so I cannot use the output - forcing me to sit there for 2 minutes wondering each time it executes.
Is there any way to run in the background AND get the stdout from the command?
Maybe you could try system(command_s,'-echo')?
I have a .csv file which is appended with 3 new values in the row below the previous set:
dlmwrite('MyFile.csv', [MyValue,MyValue2,MyValue3], '-append');
This happens every minute. It happens indefinitely because of a timer i.e it accumulates data over time:
How can I continually copy over the 60 most recent sets of values from the file and store them in a new csv file, say MyFile2.The row number of the .csv file is increasing by 1 with every minute. i.e 60 values stored in 60 minutes but I may have 100 values and want to extract the latest 60 for another file.
Image of the CSV file - 2nd column is time in HOURS:MINUTES without the : separator (ignore the lapse in time between rows 38 and 39 or any lapses elsewhere):
Note: MyValue is added to the file every minute because the script is run every 60 seconds from another script. I.e there is no internal timer in the main script:
Period = 60; % Update period in seconds
tim = timer('Period', Period, 'ExecutionMode', 'fixedRate',...
'TimerFcn', 'TESTINGFINAL');
start(tim)
stop(tim)
runtmp = fullfile('MyScriptLocation','MyScript');
run(runtmp);
If you want to do this continuously while running I'd suggest some sort of circular buffer arrangement so you always have the last 60 values in memory. This will be easier than trying to work out the current length of your continuously logging file. Basic idea (minus the actual timing code):
% initialising buffer
MyValue1 = zeros(60,1);
while true % for certain values of true
% these go once a minute
mv1 = myfunc1(inputs);
MyValue1 = [MyValue1(2:end); mv1];
dlmwrite('MyFile.csv', [mv1], '-append');
% this goes less frequently, I presume
filename = [datestr(now,30),'.csv']; % dynamic filename
dlmwrite(filename, MyValue1);
end
This way you have both your continuously logging file (updated every minute), and a series of smaller files containing what were the last 60 values at the time they were written (updated hourly, or on some other trigger, as required).
With your timer, one way of doing this would appear to be to keep a simple counter of how many times the acquisition script has run and then use the mod function to check for when this hits a multiple of 60.
This is not a full answer, but I do have an idea if I understand you correctly. This means you probably want to run Matlab 24/7? Or at least non-stop for a certain amount of time? If so, you could try out the command clock, it shows and stores the system time. In your case
time=clock;
where
time(4) holds the hour. So as soon as this parameter changes, you should open your .csv file and save the last 60 values.
However, doing it this way I think is highly energy-consuming. And sadly Matlab does not have a sleep command like for example Unix does, so maybe it would be interesting to look into running this program in another programming language?
Please provide me with comments and feedback since I see that this is not a complete answer (yet)!
I am using exist(x, 'file') to check for the existence of a file on my machine. The execution of this command takes FOREVER (over 10 seconds per call!).
My matlabpath is not too long (about 200 entries) and all folders on path are on my local drive (no network).
Why does exist takes forever?
Is there a way to make it run FASTER?
PS,
This call to exist is part of Matlab's execution of loadlibrary. So, if you are calling loadlibrary and you don't know why it takes forever - this question is also for you.
Here's one idea. You could put the directory containing those header files up at the front of the MATLAB path, so when exist() goes looking through the path, it finds them quickly and doesn't have to search through the rest of the entries. If it's spending its time stepping through your path, that may help.
Wow! That was a tough one. Bottom line: Delete %TEMP% files!
I had a few thousands files lying around in %TEMP%. It appears MATLAB really likes to go over and over the TEMP directory.
After clearing the TEMP folder, exist runs in no time!
(Thanks Andrew for the Process Monitor advice!)
exist is a built in Matlab function. It is designed to check existence of other types of objects (such as variables in Matlab) as well as files. Being a built in function, it's not a simple to see how it is coded. At least on Windows, when you call exist('filename','file') it seemingly only makes one API call to the operating system to check the file existence. So either the operating system is taking a long time, or there is some bloat in the exist function making it run slowly. See the solutions from the other posters for ideas on how to make the operating system return its result more quickly
People sometimes complain that running exist('filename','file') in a loop makes the loop very slow, this is due the call taking perhaps milliseconds and looping over a few thousand times. The solution here is to replace
if exist('filename','file')
% your code
with the line
if java.io.File('filename').exists
% your code
For 372 files
Matlab: Elapsed time is 40.207266 seconds. (get a cup of thee)
Java: Elapsed time is 0.122165 seconds. (eye blinking)