Renaming files in mass in MATLAB - matlab

When collecting data, I've currently named my files in the following format:
1_10.mat
Where the number before the underscore is a continent:
1- Africa
2- South America
3- Central America
The second number is the day in that continent the measurement was made on. What I'd like to do is to add the country the measurements were made in onto the end of the filename as well. For example:
1_1 --> 1_10 I want to rename each one to 1_1_Zaire --> 1_10_Zaire
1_11 --> 1_14, I want to rename each one to 1_11_Kenya --> 1_11_Kenya
How could I do this while keeping all the .mat files in the same folder? I'd prefer to use MATLAB for the renaming if possible.
I understand the algorithm will be something like the following:
name a directory with all the .mat files
make a for loop from bound 1 to bound x
concatenate the phrase I want
The only problem is, I don't know how to get the length of the loop, and I don't understand how MATLAB reads files in a directory.
This is what I've tried.
directory = 'C:\place';
for 1 : 9
curName = directory.name;
s = '_Africa';
laterName = (strcat(directory,s)).name;
end

Something like this should get you started:
directory = 'C:\place\';
% Filter the list of files using * as a wildcard.
file = strcat(directory, '*.mat');
% Get a list of files and concatenate them with the directory name.
results = dir(file);
file_name = strcat(directory, '\', num2cell(char(results.name), 2)')';
% The total number of files
nfile = length(file_name)
% Loop through each file.
for i = 1: nfile
curName = file_name{i}
d = textscan(curName, '%3s%f%1s%f');
if (d{2} == 1)
if (1 <= d{4} && d{4} <= 10)
laterName = sprintf('.\\%i_%i_Zaire.mat', d{2}, d{4})
elseif (11 <= d{4} && d{4} <= 14)
laterName = sprintf('.\\%i_%i_Kenya.mat', d{2}, d{4})
end
else
% ...
end
end

Related

find correlation images in folders and print result in excel using matlab

I tried to compare my template image ( image2 ) with image folders names as test* ( test1 , test 2 .... test n) to find correlation between my template image with images from that folder , then print result in that folder then go to next folder test2 .. till test n , thats mean the result of find correlation with each image in folder test1 its print as excel file named ( any name ) store in folder test1 and the content of that excel file as follow :
first row contain the names of images in folder test1 ,
second row contain the correlation result if 0 or 1 after that its jump to next folder test2 ...test3.... etc
the following code i tried long time
xls_sheet = 'Sheet1';
column_range = 'B'; % Initialisation of the column range
srcFolders = dir('D:\test*');
xls_filename = 'result.xls';
for folder = 1:length(srcFolders)
path = strcat('D:\',srcFolders(folder).name);
xlswrite('D:\srcFiles(i)\xls_filename',{srcFolders(folder).name},xls_sheet,folder_range); %Writing the name of the folder in the first row
sear = strcat(path, '\*.bmp');
srcFiles = dir(sear);
row_range = '2';
srcFolders = dir('D:\');
for folder = 1:length(srcFolders)
srcFolders(folder).fullname = strcat('image:\',srcFolders(folder).name);
end
xlswrite('D:\xlsFile', {srcFolders(:).fullname}, 'Sheet1','A2');
for i = 1 : length(srcFiles)
filename = strcat(path,'\',srcFiles(i).name);
Image1= imread(filename);
Image2 = imread('D:\act','jpeg');
x = corr2(Image1,Image2);
file_range = strcat(column_range, row_range);
if (x = 0)
xlswrite(xls_filename, {'0'}, xls_sheet, file_range ); %Writing '0' in the second row
else
xlswrite(xls_filename, {'1'}, xls_sheet, file_range ); %Writing '1' in the second row
end
end
row_range = char(row_range + 1); %Moving to the next row
column_range = char(column_range + 1); %Moving to the next column
end
i print names of files in first row , and
my questions how :
1- we can print excel file in each test* folders .
2- how can i repeat this process for all test* folders .
in the result i hope to get excel file in each and every folder in test1 , test 2 ... that contain 1 for corr=1 and 0 for others for all images in that folder.

Matlab; how to extract information from a header's file (text file)

I have many text files that have 35 lines of header followed by a large matrix with data of an image (that info can be ignored and do not need to read it at the moment). I want to be able to read the header lines and extract information contained on those lines. For instance the first few lines of the header are..
File Version Number: 1.0
Date: 06/05/2015
Time: 10:33:44 AM
===========================================================
Beam Voltage (-kV) = 13.000
Filament (W) = 4.052
Cond. (-kV) = 8.885
CenterX1 (V) = 10.7
CenterY1 (V) = -45.9
Objective (%) = 71.40
OctupoleX = -0.4653
OctupoleY = -0.1914
Angle (deg) = 0.00
.
I would like to be able to open this text file and read the vulue of the day and time the file was created, filament power, the condenser voltage, the angle, etc.. and save these in variables or send them to a text box on a GUI program.
I have tried several things but since the values I want to extract some times are after a '=' or after a ':' or simply after a '' then I do not know how to approach this. Perhaps reading each line and look for a match of a word?
Any help would be much appreciated.
Thanks,
Alex
This is not particularly difficult, and one of the ways to do it would be to parse line-by-line as you suggested. Something like this:
MAX_LINES_TO_READ = 35;
fid = fopen('input.txt');
lineCount = 0;
dateString = '';
beamVoltage = 0;
while ~eof(fid)
line = fgetl(fid);
lineCount = lineCount + 1;
%//check conditions for skipping loop body
if isempty(line)
continue
elseif lineCount > MAX_LINES_TO_READ
break
end
%//find headers you are interested in
if strfind(line, 'Date')
%//find the first location of the header separator
idx = find(line, ':', 1);
%//extract substring starting from 1 char after separator
%//note: the trim is to get rid of leading/trailing whitespace
dateString = strtrim(line(idx + 1 : end));
elseif strfind(line, 'Beam Voltage')
idx = find(line, '=', 1);
beamVoltage = str2double(line(idx + 1 : end));
end
end
fclose(fid);

dynamically create for loops matlab

I am given a structure with variable names L1dirs, L2dirs...etc all the way up to however many levels the user wants. Each Lxdirs contains a cell array of the names of the directories to be created.
The end result should be the creation of a nested set of directories where each level 1 directory contains all level 2 directories and all level 2 directories contain all level 3 directories, etc. How can I dynamically create this hierarchy?
From the code below, I have already found out through try-catch statements how many levels the user specified.
Now given that we know how many levels the user specified, how can we generate a list of all the unique filepath combinations? The end result should be a column cell array of m paths where mis the number of L1 directories times the number of L2 directories times.....times the number of Lx directories.
Can MATLAB do this? I attempted to use eval() by creating a dynamically created string macro, but eval doesn't like the use of the end statement when trying to dynamically nest for loops. Is there another way?
Here is a sample piece of code of what I have so far:
Main Code
userinputs.L1dirs = {'Level 1 Dir 1';
'Level 1 Dir 2';
'Level 1 Dir 3'};
userinputs.L2dirs = {'Level 2 Dir 1';
'Level 2 Dir 2';
'Level 2 Dir 3'};
userinputs.L3dirs = {'Level 3 Dir 1';
'Level 3 Dir 2';
'level 3 Dir 3'};
userinputs.top_level_dir = strcat(pwd,'\Results\');
pathlist1 = check_results_dirs(userinputs)
userinputs.L4dirs = {'Level 4 Dir 1';
'Level 4 Dir 2'};
userinputs.top_level_dir = strcat(pwd,'\Results 2\');
pathlist2 = check_results_dirs(userinputs)
Support Function
function pathlist = check_results_dirs(inputdata)
%{
This function checks if the file directory exists in the top level
directory as specified by the inputs structure. If the directory already
exists, then it checks whether these files are to be overwritten or not.
This function dynamically checks how many levels of directories the user
specified.
Inputs
inputdata - structure containing the following variable names
inputdata.LXdirs - X is an integer value. Variable(s) contain cell
arrays of directory names
inputdata.top_level_dir - top level destination directory to
create this file structure. If this folder does not exist, it will be
created.
%}
%check if top level directory exists
if ~exist(inputdata.top_level_dir,'file')
mkdir(inputdata.top_level_dir);
end
%determine how many directory levels there are as determined by the user
numDirLevels = 1;
numDirsPerLevel = [];
moreDirsFlag = 1;
while moreDirsFlag
try
eval(sprintf('temp = inputdata.L%idirs;',numDirLevels));
numDirsPerLevel = [numDirsPerLevel; length(temp)];
numDirLevels = numDirLevels + 1;
catch err
if strcmp(err.identifier,'MATLAB:nonExistentField')
%no more directory levels
numDirLevels = numDirLevels - 1;
moreDirsFlag = 0;
else
rethrow(err);
end
end
end
numUniqueDirs = prod(numDirsPerLevel);
%Generate Path list
beginstr = '';
midstr = 'pathlist{numUniqueDirs} = strcat(';
endstr = '';
for ii = 1:numDirsPerLevel
beginstr = strcat(beginstr,sprintf('for x%i=1:numDirsPerLevel(%i) ',ii,ii));
midstr = strcat(midstr,sprintf('inputdata.L%idirs(x%i),''\\'',',ii,ii));
endstr = strcat(' end ',endstr);
end
midstr = strcat(midstr,''''');');
evalstr = ' numUniqueDirs = numUniqueDirs+1;'
midstr = strcat(midstr,evalstr);
evalstr = 'numUniqueDirs = 1; '
beginstr = strcat(evalstr,beginstr);
eval(strcat(beginstr,midstr,endstr)); %error is thrown here due to an illegal
%use of 'end'. Can I not
%use for loops using eval?
%debug statements
disp(beginstr)
disp(midstr)
disp(endstr)
end
Note how in the main code the function is called twice. Once calls it to make three levels of directories another call is to make four levels of directories. The output pathlist should contain numL1dirs times numL2dirs times .... times numLxdirs so for the first example it should create 27 distinct directories such that each level 1 dir contains all three level 2 dirs and each level 2 dir contains all three level 3 dirs. For the second example, pathlist should contain 54 unique directory paths.
Well the reason why you struggled so much is probably your attachment to eval. You need to really limit the use of that to a strict minimum ... ideally never. I can see why you thought you had to resort to it (your dynamic field/variable names) but fortunately Matlab gave us a few tools to overcome that.
You should have a good look at the Dynamic field names functionalities from Matlab. This will probably be of great use given your style of programming, and use it as much as you can to avoid any use of the evil eval.
Once you use this. Do a recursive call to generate a list of strings representing all the paths of the folders to generate, then mkdir them and you're done.
function pathList = Generate_PathList(userinputs)
%% // check if top level directory exists
if ~exist(userinputs.top_level_dir,'dir')
mkdir(userinputs.top_level_dir);
end
%% // determine how many directory levels there are
fnames = fieldnames(userinputs) ;
maxDirLevel = 1 ;
for iField = 1:numel(fnames)
lvlDir = sscanf(fnames{iField},'L%idirs') ;
if lvlDir > maxDirLevel
maxDirLevel = lvlDir ;
end
end
%% // Generate string list
pathList = { userinputs.top_level_dir } ;
for iLvl = 1:maxDirLevel % // loop on all directory level
dirLevelName = ['L' num2str(iLvl) 'dirs'] ;
pathList = addPathToList( pathList , userinputs.(dirLevelName) ) ;
end
%% // Generate the directories
for iDir = 1:numel(pathList)
mkdir( pathList{iDir} ) ;
end
%% // Helper function called recursively
function pathListOut = addPathToList( pathList , dirNames )
nTop = numel(pathList) ;
nLow = numel(dirNames) ;
pathListOut = cell( nTop*nLow , 1 ) ;
iPath = 0 ;
for iTopDir = 1:nTop
for iLowDir = 1:nLow
iPath = iPath + 1 ;
pathListOut{iPath} = [pathList{iTopDir} '\' dirNames{iLowDir}] ;
end
end
You can call this function the same way you used to call your initial function:
userinputs.top_level_dir = strcat(pwd,'\Results');
pathList = Generate_PathList(userinputs)
userinputs.L4dirs = {'Level 4 Dir 1';
'Level 4 Dir 2'};
userinputs.top_level_dir = strcat(pwd,'\Results 2');
pathList = Generate_PathList(userinputs)
Will create your 27 and respectively 54 unique folders.
Just note that I removed the last '\' in your top level folder definition (to be consistent with the folder path generation used later on ...)

Read with order files in subfolders in matlab

I've got a folder which contains subfolders with text files. I want to read those file with the same order as they are in the subfolders. I've got a problem with that. I use the following matlab code:
outNames = {};
k=1;
feature = zeros(619,85);
fileN = cell(619,1);
for i=1:length(nameFolds)
dirList = dir(strcat(path, num2str(cell2mat(nameFolds(i,1)))));
names = {dirList.name};
outNames = {};
for j=1:numel(names)
name = names{j};
if ~isequal(name,'.') && ~isequal(name,'..')
[~,name] = fileparts(names{j});
outNames{end+1} = name;
fileName = strcat(path, num2str(cell2mat(nameFolds(i,1))), '\', name, '.descr' );
feature(k,:) = textread(fileName);
fileN{k} = [fileName num2str(k)];
k= k+1;
end
end
end
In one subfolder I've got the above text file names:
AnimalPrint_tiger_test_01.descr
AnimalPrint_tiger_test_02.descr
AnimalPrint_tiger_test_03.descr
AnimalPrint_tiger_test_04.descr
AnimalPrint_tiger_test_05.descr
AnimalPrint_tiger_test_06.descr
AnimalPrint_tiger_test_07.descr
AnimalPrint_tiger_test_08.descr
AnimalPrint_tiger_test_09.descr
AnimalPrint_tiger_test_10.descr
AnimalPrint_tiger_test_11.descr
AnimalPrint_tiger_test_12.descr
AnimalPrint_tiger_test_13.descr
AnimalPrint_tiger_test_14.descr
AnimalPrint_tiger_test_15.descr
AnimalPrint_zebra_test_1.descr
AnimalPrint_zebra_test_2.descr
AnimalPrint_zebra_test_3.descr
AnimalPrint_zebra_test_4.descr
AnimalPrint_zebra_test_5.descr
AnimalPrint_zebra_test_12.descr
But it seems that it reads first the AnimalPrint_zebra_test_12.descr and after the AnimalPrint_zebra_test_1.descr and the rest. Any idea why this happens?
dir sorts the files according to their names, for instance
test_1
test_12 % 1 followed by 2
test_2
test_3
You may want to build your own order with ['test_' num2str(variable) '.descr'] that concatenates test_ with an incrementing variable.

MATLAB: Get the last modification time of a file

I am looking for MATLAB code that does some routine (updates a file.m), if file.csv is edited more recently than file.m.
Something that should look like:
% Write time extraction
tempC = GetFileTime('file.csv', [], 'Write');
tempdateC = tempC.date
tempM = GetFileTime('file.m', [], 'Write');
tempdateM = tempM.date
% Write time comparison
if numel(dir('file.m')) == 0 || tempdateC >= tempdateM
matDef = regexprep(fileread('file.csv'), '(\r\n|\r|\n)', ';\n');
f = fopen('file.m', 'w');
fwrite(f, ['Variable = [' matDef(1:end) '];']);
fclose(f);
end
The lines for timestamp extraction seem to be incorrect MATLAB code. The rest works (Evaluate variables in external file strings).
You can extract the modification time of a file using MATLAB's dir command. Something like:
function modTime = GetFileTime(fileName)
listing = dir(fileName);
% check we got a single entry corresponding to the file
assert(numel(listing) == 1, 'No such file: %s', fileName);
modTime = listing.datenum;
end
Note that the output is in MATLAB's datenum serial date format.