get 'Documents' path in Matlab - matlab

I understand you can probably use the following code to get the job done in most cases:
mydocpath = fullfile(getenv('USERPROFILE'), 'Documents');
However, if the user has moved 'Doucments' folder to a different location, for example: E:\Documents, the above code won't work, since getenv('USERPROFILE') always returns C:\Users\MY_USER_NAME.
In C#, one can use Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), which always returns the correct path regardless where 'Documents' is. Is there anything similar in Matlab?
My current solution is rather clumsy and probably unsafe:
% search in the MATLAB path lists
% this method assumes that there is always a path containing \Documents\MATLAB registered already
searchPtn = '\Documents\MATLAB';
pathList = strsplit(path,';');
strIdx = strfind(pathList, searchPtn);
candidateIdx = strIdx{find(cellfun(#isempty,strIdx)==0, 1)}(1);
myDocPath = pathList{candidateIdx}(1 : strIdx{candidateIdx}+ numel(searchPtn));

Based on #excaza 's suggestion, I came up with a solution using dos and the cmd command found here to query the registry.
% query the registry
[~,res]=dos('reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Personal');
% parse result
res = strsplit(res, ' ');
myDocPath = strtrim(res{numel(res)});
Edit:
If the document folder in customer's PC has not been relocated or moved to one of the environment path such as %SYSTEMROOT%, the above method would return
%SOME_ENVIRONMENT_PATH%/Documents(Or a custom folder name)
The above path will not work in Matlab's functions such as mkdir or exist, which will take %SOME_ENVIRONMENT_PATH% as a folder name. Therefore we need to check for the existence of environment path in the return value and get the correct path:
[startidx, endidx] = regexp(myDocPath,'%[A-Z]+%');
if ~isempty(startidx)
myDocPath = fullfile(getenv(myDocPath(startidx(1)+1:endidx(1)-1)), myDocPath(endidx(1)+1:end));
end
Full code:
% query the registry
[~,res]=dos('reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v Personal');
% parse result
res = strsplit(res, ' ');
% get path
myDocPath = strtrim(res{numel(res)});
% if it returns %AAAAA%/xxxx, meaning the Documents folder is
% in some environment path.
[startidx, endidx] = regexp(myDocPath,'%[A-Z]+%');
if ~isempty(startidx)
myDocPath = fullfile(getenv(myDocPath(startidx(1)+1:endidx(1)-1)), myDocPath(endidx(1)+1:end));
end

Related

Matlab move multiple files in a directory

Using Matlab, I want to move the images present in the same directory in two new directories according to their name.
In the directory there are two set of image' name: 'neg-0.pgm', 'neg-1.pgm', 'neg-2.pgm', ... and 'pos-0.pgm', 'pos-1.pgm', 'pos-2.pgm', ...
I tried different functions to change the image directory but I wasn't able to make the operation successfully.
My code is:
if not(exist('./CarDataset/TrainImages/PosImages', 'dir'))
mkdir ./CarDataset/TrainImages PosImages
end
if not(exist('./CarDataset/TrainImages/NegImages', 'dir'))
mkdir ./CarDataset/TrainImages NegImages
end
trainIm = dir('./CarDataset/TrainImages/*.pgm');
for i = 1:size(trainIm, 1)
if(strcmp(trainIm(i).name, 'neg*.pgm'))
save(fullfile('./CarDataset/TrainImages/NegImages', ['neg-' num2str(i) '.pgm']))
end
end
I don't get any error but the new directories are still empty.
I believe there are two issues going on:
1 - using strcmp in the if statement with a wildcard (*) may not work properly
2 - use movefile instead of save.
https://www.mathworks.com/help/matlab/ref/movefile.html
See below code (use after you have made the new directories):
origDir = './CarDataset/TrainImages/';
trainIm = dir([origDir '*.pgm']);
for i = 1:size(trainIm, 1)
origFile = trainIm(i).name;
if contains(trainIm(i).name, 'neg'))
newDir = './CarDataset/TrainImages/NegImages/';
else
newDir = './CarDataset/TrainImages/PosImages/';
end
movefile([origDir trainIm(i).name], newDir);
end

Extract information from path name

I want to make a script in MATLAB that saves my output data with a certain name. All information for this name is in the path from the input data, like it is shown here:
path = 'C:\projektions100\algorithm1\method_A\data1';
projection =
algorithm =
method =
data =
The script then should extract the text in the path with the keyword (f.e. method) from the adjacent backslashes so the script is more flexible in case I made a spelling mistake with some folder names.
This is what I found to extract a text between a start and a end point but I cannot simply use the backslashes since there are a few of them in the path.
How should I proceed?
You can simply use a regexp with named tokens:
>> path = 'C:\projektions100\algorithm1\method_A\data1';
>> all=regexp(path,'[^\\]+\\proje[ck]tion(?<projection>[^\\]+)\\algorithm(?<algorithm>[^\\]+)\\method(?<method>[^\\]+)\\data(?<data>.+$)','names')
all =
struct with fields:
projection: 's100'
algorithm: '1'
method: '_A'
data: '1'
The problem is on how to find the end of your keywords. Here is a bit code, which loops through the keywords and looks for them in the path (stored in p2fldr, because the variable path returns the working path in MATLAB and you overshadow it if you define it).
p2fldr = 'C:\projektions100\algorithm1\method_A\data1';
% keywords
kyWrd = {'projection','algorithm','method','data'};
Tag = cell(size(kyWrd));
for i = 1:length(kyWrd)
% get keyword
ky = kyWrd{i};
% look for it in the path
idx = strfind(p2fldr,ky);
if ~isempty(idx)
% remaining path
idx_offset = idx+strlength(ky);
prm = p2fldr(idx_offset:end);
% look for file separator '\'
idx_tmp = strfind(prm,filesep);
% if you don't find one, it is pabably the last entry, so take the
% length
if isempty(idx_tmp)
idx_tmp = length(prm)+1;
end
% this is the index where it ends
idx2 = idx_tmp(1)-1;
% assign to tag-cell
Tag{i} = prm(1:idx2);
end
end
You can build a shortcut if you know that they are always in the last 4 entries of your path, so you can use strsplit right away and index the last returned cells
str_splt = strsplit(p2fldr,filesep);
Tag = cell(size(kyWrd));
for i = 1:length(kyWrd)
% index cells
str = str_splt{end-length(kyWrd)+i};
% get keyword
ky = kyWrd{i};
Tag{i} = str(length(ky)+1:end);
end
Note that this does not care if it matches your keywords (e.g. your path says 'projektions' but I defined the keyword to be 'projection')

searching matlab search path with strcmp

I have written the code below. Basically it is checking if some path is already in the matlab search path or not. If it is not found then it adds the path.
The problem is the strcmp always returns a vector of zeros despite the path actually already existing in currPath. I actually copied a path from currPath to check I was getting the correct values. Not sure why this is?
% get current path
currPath = strsplit(path, ';')';
currPath = upper(currPath);
% check if required paths exist - if not add them
pathsToCheck = ['C:\SOMEFOLDER\MADEUP'];
pathsToCheck = upper(pathsToCheck);
for n = 1 : length(pathsToCheck(:, 1))
index = strcmp(currPath, pathsToCheck(n, 1));
if sum(index) > 0
addpath(pathsToCheck{t, 1}, '-end'); % add path to the end
end
end
% save changes
savepath;
The issue is that you have defined pathsToCheck as a character array and not a cell array (which I think is what you intended the way that you are looping through it).
Rather than using a for loop, you could use ismember to check which members of a cell array of strings exist in another cell array of strings.
% Note the use of pathsep to make this work across multiple operating systems
currentPath = strsplit(path, pathsep);
pathsToCheck = {'C:\SOMEFOLDER\MADEUP'};
exists = ismember(pathsToCheck, currentPath);
% If you want to ignore case: ismember(upper(pathsToCheck), upper(currentPath))
% Add the ones that didn't exist
addpath(pathsToCheck{~exists}, '-end');

Import variables from file

Hi so I have a file called config.m that contains a list of variables along with some comments. I wanted to basically load that script up through another matlab script so that the variables would be recognized and used and could also be changed easily. Here is what my file with the variables looks like.
%~~~~~~~~~~~~~~~~~
%~~~[General]~~~~~
%~~~~~~~~~~~~~~~~~
%path to samtools executable
samtools_path = '/home/pubseq/BioSw/samtools/0.1.8/samtools';
%output_path should be to existing directory, script will then create tumour
%and normal folders and link the bam files inside respectively
output_path = '/projects/dmacmillanprj/testbams';
prefix = %prefix for output files
source_file = % from get_random_lines.pl, what is this?
% The window size
winSize = '200';
% Between 0 and 1, i.e. 0.7 for 70% tumour content
tumour_content = '1';
% Should be between 0 and 0.0001
gc_window = 0.005;
% Path to tumour bam file
sample_bam = '/projects/analysis/analysis5/HS2310/620GBAAXX_4/bwa/620GBAAXX_4_dupsFlagged.bam';
% Path to normal bam file
control_bam = '/projects/analysis/analysis5/HS2381/620GBAAXX_6/bwa/620GBAAXX_6_dupsFlagged.bam';
I have tried this:
load('configfile.m')
??? Error using ==> load
Number of columns on line 2 of ASCII file /home/you/CNV/branches/config_file/CopyNumber/configfile.m
must be the same as previous lines.
Just run the script config.m inside another script as
config
Remember config.m file should be in the working directory or in MATLAB path.
However I would recommend you to create a function from this script and return a structure with all the parameters as fields. Then you will be more flexible in your main script since you can assign any name to this structure.
function param = config()
param.samtools_path = '/home/pubseq/BioSw/samtools/0.1.8/samtools';
param.output_path = '/projects/dmacmillanprj/testbams';
% ... define other parameteres
In the main script:
P = config;
st_dir = P.samtools_path;
% ...etc...
Alternatively, you could define a class with constant properties in your config.m file:
classdef config
properties (Constant)
samtools_path = '/home/pubseq/BioSw/samtools/0.1.8/samtools';
output_path = '/projects/dmacmillanprj/testbams';
end
end
Thereby, you can access the class properties in another script:
config.samtools_path
config.output_path
To round it up, you could place your config.m file into a package (+ folder) and import it explicitly in your script. Assuming your package would be called "foo" and the "+foo" folder on your Matlab path, your script would look as follows:
import foo.config
foo.config.samtools_path
foo.config.output_path
load() is not suitable for files that contain text (even in the form of matlab comments.)
You should use textscan() or dlmread(), specifying to them that you want to skip two header lines or that you want to treat '%' as indicating a comment.

Matlab, Advanced loop in folders and applying a function

i wrote a code that analyze a video file and then plot data on a graph then
save this graph into
excel and jpg.
but my problem is that i have more than 200 video to analyze in around 20 folder,
so i need to automate this code to loop inside folders and analyze each *.avi file inside and
.. So any ideas or suggestions
Really appreciate your help
I need to know how to loop folders and get files inside and the apply a function to these files in that folder
Please note that my function that i also want to save graph result to img, should i then include full path while saving ? and how can i do it ?
The dir and fullfile commands are what you need. Depending on your directory structure, something like this:
video_dir = 'videos';
% I'm not sure if there's a way to directly get a list of directories, but
% this will work
video_dir_children = dir(video_dir);
video_subdirs = [];
for ix = 1 : length(video_dir_children),
% note we're careful to kick out '.' and '..'
% (and any other directory starting with a '.')
if(video_dir_children(ix).isdir && video_dir_children(ix).name(1) ~= '.')
video_subdirs = [video_subdirs; video_dir_children(ix)];
end
end
for ix = 1 : length(video_subdirs),
this_dir = fullfile(video_dir, video_subdirs(ix).name);
avi_files_in_this_dir = dir(fullfile(this_dir, '*.avi'));
for jx = 1 : avi_files_in_this_dir,
doVideoProcessing(fullfile(this_dir, avi_files_in_this_dir(jx).name));
end
end