Commit 344f659e authored by Jay Dubb's avatar Jay Dubb
Browse files

v1.21.7

-- Step 5 of changing the way Homer3 stores the group data in memory, how it saves processed data and loads processed and acquired data. Implemented loading and freeing of acquired data.

-- Removed old code to quickly calculate memory required and check for enough disk space. The rationale for getting rid of this code is that I'm not sure this is a big problem people are encountering and woth complicating already intricate code which we want to keep as simple as possible. The distributed storage scheme should take care of the issue of limited max size of a single file (groupResults.mat). If running out of disk space proves a widespread issue we can re-introduce that code.

-- Returned original slow-running implementation of MemoryRequired for diagnostic purposes but not meant to be run during a user session of Homer3.

-- Change MainGUI.GetWl.m to get selected wavelength ONLY from GUI
parent 8adef79b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -21,6 +21,6 @@ On
on

% Data Storage Scheme
memory
disk

% END
+14 −5
Original line number Diff line number Diff line
@@ -69,6 +69,18 @@ classdef AcqDataClass < matlab.mixin.Copyable
    
    methods
        
        % -------------------------------------------------------
        function b = Error(obj)
            if obj.err<0
                b = true;
            elseif obj.err==0
                b = false;
            else
                b = true;
            end
        end
        
        
        % -------------------------------------------------------
        function FreeMemory(obj, filename)
            if ~exist('filename','var')
@@ -77,10 +89,7 @@ classdef AcqDataClass < matlab.mixin.Copyable
            if isempty(filename)
                return;
            end            
            
            % TBD: Tight now we only save processed output and free memory 
            % associated with it. Need to do the same for acquired data
            % obj.Initialize();  
            obj.Initialize();
        end
        
        
+8 −1
Original line number Diff line number Diff line
@@ -104,11 +104,18 @@ classdef NirsClass < AcqDataClass & FileLoadSaveClass
            else
                fname = obj.filename;
            end
            if isempty(fname)
            if exist(fname, 'file') ~= 2
               err=-1;
               return;
            end
            
            % Don't reload if not empty
            if ~obj.IsEmpty()
               return;
            end
            
            
                        
            warning('off', 'MATLAB:load:variableNotFound');
            fdata = load(fname,'-mat', 'SD','t','d','s','aux','CondNames');
            if isproperty(fdata,'d')
+6 −1
Original line number Diff line number Diff line
@@ -383,6 +383,11 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
               return;
            end
            
            % Don't reload if not empty
            if ~obj.IsEmpty()
               return;
            end
            
            
            %%%%%%%%%%%% Ready to load from file
            
+12 −63
Original line number Diff line number Diff line
@@ -305,7 +305,7 @@ classdef DataTreeClass < handle
                % (We do not reset current subject or group because they can contain multiple 
                % nodes and they cannot be empty once they've been initialized once whereas run 
                % can be if it fails to load a data file. 
                if ~runCurr.IsEmpty()
                if ~runCurr.Error()
                    obj.Add(groupCurr, subjCurr, runCurr);
                    runCurr = RunClass().empty();
                end
@@ -426,73 +426,22 @@ classdef DataTreeClass < handle


        % ----------------------------------------------------------------------------------
        function nbytes = MemoryRequired(obj, option)
            if ~exist('option','var')
                option = 'memory';
            end
        function nbytes = MemoryRequired(obj)
            nbytes = 0;
            if isempty(obj)
                return;
            end                        
            
            nbytes = [0,0,0];
            kg = find(obj.groups.GroupsProcFlags==1);
            ks = find(obj.groups.SubjsProcFlags==1);
            kr = find(obj.groups.RunsProcFlags==1);
            
            % We assume for practcal purposes that unprocessed nodes take up zero bytes 
            if ~isempty(kg)
                nbytes(1) = length(kg) * obj.groups(kg(1)).MemoryRequired();
            end
            if ~isempty(ks)
                [iG,iS] = ind2sub(size(obj.groups.SubjsProcFlags), ks);
                nbytes(2) = length(ks) * obj.groups(iG(1)).subjs(iS(1)).MemoryRequired();
            for ii = 1:length(obj.groups)
                nbytes = nbytes + obj.groups(ii).MemoryRequired();
            end
            if ~isempty(kr)
                [iG,iS,iR] = ind2sub(size(obj.groups.RunsProcFlags), kr);
                nbytes(3) = length(kr) * obj.groups(iG(1)).subjs(iS(1)).runs(iR(1)).MemoryRequired(option);
        end
        
            % Add up the bytes. 
            nbytes = sum(nbytes);
        end
        
        
        % ----------------------------------------------------------------------------------
        function diskspaceToSpare = CheckAvailableDiskSpace(obj, hwait)
            if ishandle(hwait)
                obj.logger.Write(sprintf('Estimating disk space required to save processing results ...\n'), obj.logger.ProgressBar(), hwait);
            end
            
            % Calculate the amount of disk space already used by groupResults. Add that to free disk space because
            % groupResults will be overwritten 
            freeDiskSpace = 0;
            for ii = 1:length(obj.groups)
                freeDiskSpace = freeDiskSpace + GetFileSize([obj.groups(ii).pathOutput, 'groupResults.mat']);
            end
            
            memRequired = obj.MemoryRequired('disk');
            freeDiskSpace = getFreeDiskSpace() + freeDiskSpace;
            
            diskspaceToSpare = (freeDiskSpace - memRequired);   % Disk space to spare in megabytes
            diskspacePercentRemaining = 100 * diskspaceToSpare/memRequired;
            msg = {};
            obj.logger.Write(sprintf('CheckAvailableDiskSpace:    disk space available = %0.1f MB,    required disk space estimate = %0.1f MB\n', freeDiskSpace/1e6, memRequired/1e6));
            if diskspaceToSpare < 0
                msg{1} = sprintf('ERROR: Cannot save processing results requiring ~%0.1f MB of disk space on current drive with only %0.1f MB of free space available.\n', ...
                                  memRequired/1e6, freeDiskSpace/1e6);
                obj.warningflag = 0;
            elseif diskspacePercentRemaining < 200                
                msg{1} = sprintf('WARNING: Available disk space on the current drive is low (%0.1f MB). This may cause problems saving processing results in the future.', ...
                                  freeDiskSpace/1e6);
                msg{2} = sprintf('Consider moving your data set to a drive with more free space\n');
            end            
            if ~isempty(msg)
                if ~obj.warningflag
                    MessageBox([msg{:}]);
                    obj.warningflag = 1;
                end
                obj.logger.Write([msg{:}]);
            end            
            diskspaceToSpare = getFreeDiskSpace();   % Disk space to spare in megabytes
            %diskspaceToSpare = (getFreeDiskSpace() - obj.MemoryRequired());   % Disk space to spare in megabytes
        end

        
@@ -506,7 +455,7 @@ classdef DataTreeClass < handle
            % Check that there is anough disk space. NOTE: for now we
            % assume that all groups are on the same drive. This should be 
            % changed but for now we simplify. 
            if obj.CheckAvailableDiskSpace(hwait) < 0
            if obj.CheckAvailableDiskSpace(hwait) <= 0
                return;
            end
            
Loading