Unverified Commit f2addb82 authored by jayd1860's avatar jayd1860 Committed by GitHub
Browse files

Merge pull request #116 from BUNPC/development

Merge BIDS support and tools for shared library maintenance that avoids git submodules
parents c83f79ed 2ecfb701
Loading
Loading
Loading
Loading

.gitmodules

0 → 100644
+6 −0
Original line number Original line Diff line number Diff line
[submodule "Utils/Shared"]
	path = Utils/Shared
	url = https://github.com/BUNPC/Utils
[submodule "Group/DataTree"]
	path = DataTree
	url = https://github.com/BUNPC/DataTree

DataTree/.numberfiles

deleted100644 → 0
+0 −1
Original line number Original line Diff line number Diff line
67
 No newline at end of file
+210 −71
Original line number Original line Diff line number Diff line
@@ -2,24 +2,31 @@ classdef DataFilesClass < handle
    
    
    properties
    properties
        files;
        files;
        type;
        filetype;
        dirFormats;
        err;
        err;
        errmsg;
        errmsg;
        pathnm;
        rootdir;
        config;
        config;
        nfiles;
        nfiles;
        logger
        logger
    end
    end
    
    
    properties (Access = private)
        lookupTable
    end
    
    methods
    methods
        
        
        % ----------------------------------------------------
        % ----------------------------------------------------
        function obj = DataFilesClass(varargin)            
        function obj = DataFilesClass(varargin)            
            obj.type = '';
            obj.files = FileClass.empty();
            obj.pathnm = pwd;
            obj.filetype = '';
            obj.rootdir = pwd;
            obj.nfiles = 0;
            obj.nfiles = 0;
            obj.err = -1;
            obj.err = -1;
            obj.errmsg = {};
            obj.errmsg = {};
            obj.dirFormats = struct('type',0, 'choices',{{}});


            global logger
            global logger
            global cfg
            global cfg
@@ -28,6 +35,7 @@ classdef DataFilesClass < handle
            cfg    = InitConfig(cfg);
            cfg    = InitConfig(cfg);
            
            
            obj.logger = logger;
            obj.logger = logger;
            obj.lookupTable = [];
            
            
            skipconfigfile = false;
            skipconfigfile = false;
            askToFixNameConflicts = [];
            askToFixNameConflicts = [];
@@ -36,32 +44,32 @@ classdef DataFilesClass < handle
                return
                return
            end            
            end            
            if nargin==1
            if nargin==1
                obj.pathnm = varargin{1};
                obj.rootdir = varargin{1};
            end            
            end            
            if nargin==2
            if nargin==2
                obj.pathnm = varargin{1};
                obj.rootdir = varargin{1};
                obj.type = varargin{2};
                obj.filetype = varargin{2};
            end
            end
            if nargin==3
            if nargin==3
                obj.pathnm = varargin{1};
                obj.rootdir = varargin{1};
                obj.type = varargin{2};
                obj.filetype = varargin{2};
                if strcmp(varargin{3}, 'standalone')
                if strcmp(varargin{3}, 'standalone')
                    skipconfigfile = true;
                    skipconfigfile = true;
                end
                end
            end            
            end            
            if nargin==4
            if nargin==4
                obj.pathnm = varargin{1};
                obj.rootdir = varargin{1};
                obj.type = varargin{2};
                obj.filetype = varargin{2};
                if strcmp(varargin{3}, 'standalone')
                if strcmp(varargin{3}, 'standalone')
                    skipconfigfile = true;
                    skipconfigfile = true;
                end
                end
                askToFixNameConflicts = varargin{4};
                askToFixNameConflicts = varargin{4};
            end
            end
                        
                        
            if obj.type(1)=='.'
            if obj.filetype(1) == '.'
                obj.type(1)='';
                obj.filetype(1) = '';
            end
            end
            obj.pathnm = filesepStandard(obj.pathnm,'full');
            obj.rootdir = filesepStandard(obj.rootdir,'full');           
            
            
            % Configuration parameters
            % Configuration parameters
            obj.config = struct('RegressionTestActive','','AskToFixNameConflicts',1);
            obj.config = struct('RegressionTestActive','','AskToFixNameConflicts',1);
@@ -91,82 +99,156 @@ classdef DataFilesClass < handle
            end
            end
            
            
            obj.err = 0;
            obj.err = 0;
            obj.files = mydir(obj.pathnm);
            
            GetDataSet(obj);
            obj.InitFolderFromats();
            obj.GetDataSet();
        end
        end
        
        
        
        
        
        % -----------------------------------------------------------------------------------
        % -----------------------------------------------------------------------------------
        function GetDataSet(obj)
        function GetDataSet(obj)
            if exist(obj.pathnm, 'dir')~=7
            if exist(obj.rootdir, 'dir')~=7
                error('Invalid subject folder: ''%s''', obj.pathnm);
                error('Invalid subject folder: ''%s''', obj.rootdir);
            end
            
            for ii = 1:length(obj.dirFormats.choices)
                obj.InitLookupTable();
                obj.FindDataSet(ii);
                
                obj.ErrorCheck();
                if ~isempty(obj.files)
                    break
                end
            end
            end
            obj.findDataSet(obj.type);
            
            
            % Remove any files that cannot pass the basic test of loading
            % Remove any files that cannot pass the basic test of loading
            % its data
            % its data
            obj.ErrorCheck(obj.type);
            obj.ErrorCheckName();
            obj.ErrorCheckName();
        end
        end


        
        
        
        % -----------------------------------------------------------------------------------
        function InitFolderFromats(obj)
            obj.dirFormats.choices = {
                
                %%%% 1. Flat #1
                {
                ['*_run*.', obj.filetype];
                }

                %%%% 2. Flat #2
                {
                ['*.', obj.filetype];
                }
                
                %%%% 3. Subjects 
                {
                '*';
                ['*.', obj.filetype];
                }

                %%%% 4. BIDS #1,    sub-<label>[_ses-<label>][_task-<label>][_run-<index>]_nirs.snirf
                {                
                'sub-*';
                'ses-*';
                ['nirs/sub-*_run-*_nirs.', obj.filetype];
                }
                                
                %%%% 5. BIDS #2 
                {
                'sub-*';
                ['nirs/sub-*_run-*_nirs.', obj.filetype];
                }
                
                %%%% 6. BIDS-like folder structure without file naming restrictions
                {
                'sub-*';
                'ses-*';
                ['nirs/*.', obj.filetype];
                }
                                
                };
        end
        

            
        
        % ----------------------------------------------------
        % ----------------------------------------------------
        function findDataSet(obj, type)
        function FindDataSet(obj, iFormat, iPattern, parentdir)
            obj.files = mydir([obj.pathnm, '/*.', type]);
            if ~exist('iFormat','var')
                iFormat = 1;
            end
            if ~exist('iPattern','var')
                iPattern = 1;
            end            
            if ~exist('parentdir','var')
                parentdir = obj.rootdir;
            end
            
            
            % Remove any files that cannot pass the basic test of loading
            if iFormat > length(obj.dirFormats.choices)
            % its data
                return
            obj.ErrorCheck(type);
            end
            if iPattern > length(obj.dirFormats.choices{iFormat})
                return
            end
            parentdir = filesepStandard(parentdir);
            pattern = obj.dirFormats.choices{iFormat}{iPattern};
            
            
            if isempty( obj.files )                
            dirs = mydir([parentdir, pattern]);
                % If there are no data files in current dir, don't give up yet - check
            
                % the subdirs for data files.
            dirnamePrev = '';
                dirs = mydir(obj.pathnm);
            for ii = 1:length(dirs)
            for ii = 1:length(dirs)
                    if dirs(ii).isdir && ...
                if dirs(ii).IsFile()
                            ~strcmp(dirs(ii).name,'.') && ...
                    if strcmp(pattern, '*')
                            ~strcmp(dirs(ii).name,'..') && ...
                        continue
                            ~strcmp(dirs(ii).name,'hide')
                    end
                        dirs(ii).idx = length(obj.files)+1;
                    if includes(dirs(ii).name, obj.filetype)
                        foos = mydir([obj.pathnm, dirs(ii).name, '/*.', type]);
                        if ~strcmp(dirs(ii).name, dirnamePrev)
                        nfoos = length(foos);
                            obj.AddParentDirs(dirs(ii));
                        if nfoos>0
                            for jj = 1:nfoos
                                foos(jj).subjdir      = dirs(ii).name;
                                foos(jj).subjdiridx   = dirs(ii).idx;
                                foos(jj).idx          = dirs(ii).idx+jj;
                                foos(jj).filename     = foos(jj).name;
                                foos(jj).name         = [dirs(ii).name, '/', foos(jj).name];
                                foos(jj).map2group    = struct('iGroup',0, 'iSubj',0, 'iRun',0);
                                foos(jj).pathfull     = dirs(ii).pathfull;
                                if ~foos(jj).isdir
                                    obj.nfiles = obj.nfiles+1;
                        end
                        end
                        obj.AddFile(dirs(ii));
                    end
                    end
                    
                    
                            % Add file from current subdir to files struct
                    if obj.dirFormats.type == 0 
                            if isempty(obj.files)
                        obj.dirFormats.type = iFormat;
                                obj.files = dirs(ii);
                            else
                                obj.files(end+1) = dirs(ii);
                    end
                    end
                            obj.files(end+1:end+nfoos) = foos;                                                        
                elseif dirs(ii).IsDir()
                    obj.FindDataSet(iFormat, iPattern+1, [parentdir, dirs(ii).filename])
                end
                end
                dirnamePrev = dirs(ii).name;
            end
            end
        end
        end
            else
        
                for ii = 1:length(obj.files)

                    obj.files(ii).pathfull = obj.pathnm;
        
        % ----------------------------------------------------
        function AddParentDirs(obj, dir)
            pathrel = getPathRelative([dir.rootdir, dir.name], obj.rootdir);
            subdirs = str2cell_fast(pathrel, {'/','\'});
            notUnique = false;
            N = length(subdirs);
            for ii = 1:N-1
                if strcmp(subdirs{ii}, 'nirs')
                    continue;
                end
                end
                obj.nfiles = obj.nfiles+length(obj.files);
                pathrel2 = buildpathfrompathparts(subdirs(1:ii));
                if obj.SearchLookupTable(pathrel2)
                    continue;
                end
                obj.files(end+1) = FileClass(pathrel2);
                obj.AddLookupTable(obj.files(end).name)
            end
            end
        end
        end
        
        
        
        
        
        
        % ----------------------------------------------------
        % ----------------------------------------------------
        function getDataFile(obj, filename)
        function AddFile(obj, file)
            obj.files = mydir(filename);
            obj.files(end+1) = file;
            obj.nfiles = obj.nfiles+1;
            obj.AddLookupTable(obj.files(end).filename)
        end
        end
        
        
        
        
@@ -220,7 +302,7 @@ classdef DataFilesClass < handle
        % -----------------------------------------------------
        % -----------------------------------------------------
        function errmsg = GetErrorMsg(obj, ii)
        function errmsg = GetErrorMsg(obj, ii)
            p1      = fileparts(obj.files(ii).GetName());
            p1      = fileparts(obj.files(ii).GetName());
            [p2,f2] = fileparts(filesepStandard(obj.files(ii).pathfull,'nameonly:file'));
            [p2,f2] = fileparts(filesepStandard(obj.files(ii).rootdir,'nameonly:file'));
            [~,f3]  = fileparts(p2);
            [~,f3]  = fileparts(p2);
            if isfile_private(obj.files(ii).GetName())
            if isfile_private(obj.files(ii).GetName())
                filetype = 'file';
                filetype = 'file';
@@ -301,7 +383,7 @@ classdef DataFilesClass < handle
        
        
        
        
        % ----------------------------------------------------------
        % ----------------------------------------------------------
        function ErrorCheck(obj, type)
        function ErrorCheck(obj)
            errorIdxs = [];
            errorIdxs = [];


            if isempty(obj.files)
            if isempty(obj.files)
@@ -309,7 +391,7 @@ classdef DataFilesClass < handle
            end
            end
                       
                       
            % Assume constructor name follows from name of data format type
            % Assume constructor name follows from name of data format type
            constructor = sprintf('%sClass', [upper(type(1)), type(2:end)]);
            constructor = sprintf('%sClass', [upper(obj.filetype(1)), obj.filetype(2:end)]);
            
            
            % Make sure function by that name exists; otherwise no way to
            % Make sure function by that name exists; otherwise no way to
            % use it to check loadability
            % use it to check loadability
@@ -317,13 +399,13 @@ classdef DataFilesClass < handle
                return;
                return;
            end
            end
            
            
            % Try to create object of data type and load data into it
            % Try to create object of data filetype and load data into it
            dataflag = false;
            dataflag = false;
            for ii = 1:length(obj.files)
            for ii = 1:length(obj.files)
                if obj.files(ii).isdir
                if obj.files(ii).isdir
                    continue;
                    continue;
                end
                end
                filename = [obj.files(ii).pathfull, obj.files(ii).name];
                filename = [obj.files(ii).rootdir, obj.files(ii).name];
                eval( sprintf('o = %s(filename);', constructor) );
                eval( sprintf('o = %s(filename);', constructor) );
                if o.GetError()<0
                if o.GetError()<0
                    obj.logger.Write('FAILED error check:   %s will not be added to data set\n', filename);
                    obj.logger.Write('FAILED error check:   %s will not be added to data set\n', filename);
@@ -349,5 +431,62 @@ classdef DataFilesClass < handle
            err = obj.err;
            err = obj.err;
        end
        end
                
                
        % ----------------------------------------------------------
        function PrintFolderStructure(obj, options)
            if ~exist('options','var')
                options = '';
            end
            stepsize = 3;
            obj.logger.Write('\n');
            obj.logger.Write('DataTreeClass - Data Set Folder Structure:\n');
            for ii = 1:length(obj.files)
                k = length(find(obj.files(ii).name=='/'));   
                if ii<10, j=3; elseif ii>9 && ii<100, j=2; else j=3; end
                if optionExists(options, 'flat')
                    obj.logger.Write(sprintf('%d.%s%s\n', ii, blanks(j), obj.files(ii).name));
                else
                    if ii<10, j=3; elseif ii>9 && ii<100, j=2; else j=3; end
                    if optionExists(options, 'numbered')
                        n = k*stepsize+stepsize+j;
                        obj.logger.Write(sprintf('%d.%s%s\n', ii, blanks(n), obj.files(ii).filename));
                    else
                        n = k*stepsize+stepsize;
                        obj.logger.Write(sprintf('%s%s\n', blanks(n), obj.files(ii).filename));
                    end
                end
            end
            obj.logger.Write('\n');
        end
        
    end
        
    
    
    methods (Access = private)

        % ----------------------------------------------------------
        function InitLookupTable(obj)
            width = 4;
            if isempty(obj.lookupTable)
                obj.lookupTable = int32(zeros((10^width)-1, 1));
            else
                obj.lookupTable(:) = 0;                
            end
        end

        
        % ----------------------------------------------------------
        function AddLookupTable(obj, str)
            n = round(log10(length(obj.lookupTable)));
            obj.lookupTable(string2hash(str, n)) = 1;
        end

        
        % ----------------------------------------------------------
        function b = SearchLookupTable(obj, str)
            n = round(log10(length(obj.lookupTable)));
            b = obj.lookupTable(string2hash(str, n));
        end
        
    end
    end
end
end
+6 −6
Original line number Original line Diff line number Diff line
@@ -86,15 +86,15 @@ for ii=1:length(datafiles)
        continue;
        continue;
    end
    end
    if strcmp(options, 'delete')
    if strcmp(options, 'delete')
        fprintf('Deleting %s\n', [datafiles(ii).pathfull, '/', datafiles(ii).name]);
        fprintf('Deleting %s\n', [datafiles(ii).rootdir, '/', datafiles(ii).name]);
        delete([datafiles(ii).pathfull, '/', datafiles(ii).name]);
        delete([datafiles(ii).rootdir, '/', datafiles(ii).name]);
    elseif strcmp(options, 'move')
    elseif strcmp(options, 'move')
        fprintf('Moving %s to %s\n', [datafiles(ii).pathfull, '/', datafiles(ii).name], [datafiles(ii).pathfull, '/', datafiles(ii).name, '.old']);
        fprintf('Moving %s to %s\n', [datafiles(ii).rootdir, '/', datafiles(ii).name], [datafiles(ii).rootdir, '/', datafiles(ii).name, '.old']);
        movefile([datafiles(ii).pathfull, '/', datafiles(ii).name], [datafiles(ii).pathfull, '/', datafiles(ii).name, '.old']);
        movefile([datafiles(ii).rootdir, '/', datafiles(ii).name], [datafiles(ii).rootdir, '/', datafiles(ii).name, '.old']);
    elseif strcmp(options, 'restore')
    elseif strcmp(options, 'restore')
        [pname, fname] = fileparts(datafiles(ii).name);
        [pname, fname] = fileparts(datafiles(ii).name);
        fprintf('Restoring %s to %s\n', [datafiles(ii).pathfull, '/', datafiles(ii).name], [datafiles(ii).pathfull, '/', pname, '/', fname]);
        fprintf('Restoring %s to %s\n', [datafiles(ii).rootdir, '/', datafiles(ii).name], [datafiles(ii).rootdir, '/', pname, '/', fname]);
        movefile([datafiles(ii).pathfull, '/', datafiles(ii).name], [datafiles(ii).pathfull, '/', pname, '/', fname]);
        movefile([datafiles(ii).rootdir, '/', datafiles(ii).name], [datafiles(ii).rootdir, '/', pname, '/', fname]);
    end
    end
    pause(0.25);
    pause(0.25);
end
end
+286 −69

File changed.

Preview size limit exceeded, changes collapsed.

Loading