Commit a0260163 authored by Jay Dubb's avatar Jay Dubb
Browse files

v1.23.0

-- Step 1 in allowing acquired file data such as stimulus conditions to be modified through a separate save procedure. Added methods AcquiredDataModified and SaveAcquiredData to DataTreeClass.
parent ee4ec3f7
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ classdef FileLoadSaveClass < matlab.mixin.Copyable
        
        
        % ---------------------------------------------------------
        function Load(obj, filename, format, params)
        function Load(obj, filename, params, format)
            if ~exist('filename','var')
                filename = obj.filename;
            end
@@ -52,16 +52,16 @@ classdef FileLoadSaveClass < matlab.mixin.Copyable
        
        
        % ---------------------------------------------------------
        function Save(obj, filename, format, params)
        function Save(obj, filename, params, format)
            if ~exist('filename','var')
                filename = obj.filename;
            end            
            if ~exist('format','var')
                format = obj.fileformat;
            end
            if ~exist('params','var')
                params = [];
            end            
            if ~exist('format','var')
                format = obj.fileformat;
            end
                       
            switch(lower(format))
                case obj.supportedFomats.matlab
+138 −9
Original line number Diff line number Diff line
@@ -259,6 +259,7 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
        end
        
        
        
        % -------------------------------------------------------
        function objnew = CopyMutable(obj, options)
            if nargin==1
@@ -274,6 +275,8 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
            % Generate new instance of SnirfClass
            objnew = SnirfClass();
            
            objnew.filename = obj.filename;
            
            % Copy mutable properties to new object instance;
            objnew.stim = CopyHandles(obj.stim);
   
@@ -281,7 +284,6 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
                t = obj.GetTimeCombined();
                objnew.data = DataClass([],t,[]);
            end            
            
        end
        
        
@@ -369,8 +371,16 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
        
        
        % -------------------------------------------------------
        function err = LoadStim(obj, fileobj)
        function err = LoadStim(obj, fileobj, options)
            err = 0;
            if ~exist('options','var')
                options = '';
            end
            
            paramName = 'stim';
            if optionExists(options, 'original') || optionExists(options, 'orig')
                paramName = 'stim0';
            end
            
            % Since we want to load stims in sorted order (i.e., according to alphabetical order
            % of condition names), first load to temporary variable.
@@ -379,7 +389,7 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
                if ii > length(obj.stim)
                    obj.stim(ii) = StimClass;
                end
                if obj.stim(ii).LoadHdf5(fileobj, [obj.location, '/stim', num2str(ii)]) < 0
                if obj.stim(ii).LoadHdf5(fileobj, [obj.location, '/', paramName, num2str(ii)]) < 0
                    obj.stim(ii).delete();
                    obj.stim(ii) = [];
                    if ii==1
@@ -525,9 +535,18 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
        
        
        % -------------------------------------------------------
        function SaveStim(obj, fileobj)
        function SaveStim(obj, fileobj, options)
            if ~exist('options','var')
                options = '';
            end
            
            paramName = 'stim';
            if optionExists(options, 'original') || optionExists(options, 'orig')
                paramName = 'stim0';
            end            

            for ii=1:length(obj.stim)
                obj.stim(ii).SaveHdf5(fileobj, [obj.location, '/stim', num2str(ii)]);
                obj.stim(ii).SaveHdf5(fileobj, [obj.location, '/', paramName, num2str(ii)]);
            end
        end
        
@@ -582,8 +601,118 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
            
            % Save aux
            obj.SaveAux(fileobj);
        end
       
        
        
        % -------------------------------------------------------
        function [changes, stim0] = UpdateStim(obj, fileobj)
            flags = zeros(length(obj.stim), 1);
            
            % Load original unedited stim, rename it and save it if it
            % doesn't already exist
            snirf = SnirfClass();
            snirf.LoadStim(fileobj, 'orig');
            if snirf.stim.Error()<0  
                obj.stim.SaveStim('orig');
            end
            
            % Now load current stim from file and update it
            snirf.LoadStim(fileobj);
            stim0 = snirf.stim;
            
            % Update original stims from file with edited stims
            for ii = 1:length(obj.stim)
                for jj = 1:length(stim0)
                    if strcmp(obj.stim(ii).GetName(), stim0(jj).GetName())
                        if obj.stim(ii) ~= stim0(jj)
                            stim0(jj).Copy(obj.stim(ii));
                            stim0(jj).SaveHdf5(fileobj, [obj.location, '/stim', num2str(jj)]);
                        end
                        flags(ii) = 1;
                        break;
                    end
                end
                if ~flags(ii)
                    % We have new stimulus condition added
                    if ~obj.stim(ii).IsEmpty()
                        stim0(jj+1) = StimClass(obj.stim(ii));
                        stim0(jj+1).SaveHdf5(fileobj, [obj.location, '/stim', num2str(jj+1)]);
                    end
                end
            end            
            changes = sum(flags);
        end
        
        
        
        % -------------------------------------------------------
        function changes = StimChangesMade(obj)
            % Load original unedited stims from file
            snirf = SnirfClass();
            snirf.LoadStim(obj.filename);
            stim0 = snirf.stim;

            flags = zeros(length(obj.stim), 1);
                
            % Update original stims from file with edited stims
            for ii = 1:length(obj.stim)
                for jj = 1:length(stim0)
                    if strcmp(obj.stim(ii).GetName(), stim0(jj).GetName())
                        if obj.stim(ii) ~= stim0(jj)
                            flags(ii) = 1;
                        else
                            flags(ii) = -1;
                        end
                        break;
                    end
                end
                if flags(ii)==0
                    % We have new stimulus condition added
                    if ~obj.stim(ii).IsEmpty()
                        flags(ii) = 1;
                    end
                end
            end
            flags(flags ~= 1) = 0;
            changes = sum(flags)>0;
        end
        
        
        
        % -------------------------------------------------------
        function b = DataModified(obj)
            b = obj.StimChangesMade();
        end
        
        
        
        % -------------------------------------------------------
        function err = SaveMutable(obj, fileobj)
            if isempty(obj)
                return
            end
            % Arg 1
            if ~exist('fileobj','var') || ~exist(fileobj,'file')
                fileobj = '';
            end
            
            % Error checking            
            if ~isempty(fileobj) && ischar(fileobj)
                obj.filename = fileobj;
            elseif isempty(fileobj)
                fileobj = obj.filename;
            end 
            if isempty(fileobj)
               err = -1;
               return;
            end
                        
            % Update original stims and save back to file
            obj.UpdateStim(fileobj);
        end
       
        
        
        
        % -------------------------------------------------------
+3 −0
Original line number Diff line number Diff line
@@ -419,6 +419,9 @@ classdef StimClass < FileLoadSaveClass
            if isempty(obj.name)
                return;
            end
            if isempty(obj.data)
                return;
            end
            b = false;
        end
        
+21 −0
Original line number Diff line number Diff line
@@ -630,6 +630,27 @@ classdef GroupClass < TreeNodeClass
        
        
        
        % ----------------------------------------------------------------------------------
        function SaveAcquiredData(obj)            
            for ii = 1:length(obj.subjs)
                obj.subjs(ii).SaveAcquiredData();
            end
        end
        
        
        
        % ----------------------------------------------------------------------------------
        function b = AcquiredDataModified(obj)
            b = false;
            for ii = 1:length(obj.subjs)
                if obj.subjs(ii).AcquiredDataModified()
                    b = true;
                end
            end
        end
        
        
        
        % ----------------------------------------------------------------------------------
        function ExportHRF(obj, procElemSelect, iBlk)
            if ~exist('procElemSelect','var') || isempty(procElemSelect)
+48 −30
Original line number Diff line number Diff line
@@ -6,8 +6,7 @@ classdef ProcInputClass < handle
    properties
        tIncMan;                 % Manually include/excluded time points
        mlActMan;                % Manually include/excluded time points
        acquiredEditable;        % Copy of acquisition parameters that are editable 
                                 % through manual GUI operations. 
        acquired;                % Modifiable acquisition parameters initally copied from acquisition files
        stimValSettings;         % Derived stim values 
        misc;
    end
@@ -30,7 +29,7 @@ classdef ProcInputClass < handle
            if isempty(acquired)
                return;
            end
            obj.acquiredEditable = acquired.CopyMutable(copyOptions);
            obj.acquired = acquired.CopyMutable(copyOptions);
        end
        
                
@@ -56,7 +55,10 @@ classdef ProcInputClass < handle
                % CopyHandles instead of plain old assignment statement 
                eval( sprintf('obj.misc.%s = CopyHandles(obj2.misc.%s, obj.misc.%s);', fields{ii}, fields{ii}) );
            end
            obj.acquiredEditable = CopyHandles(obj2.acquiredEditable, obj.acquiredEditable);
            if isempty(obj.acquired)
                return;
            end
            obj.acquired.Copy(obj2.acquired);
        end
        
        
@@ -90,7 +92,7 @@ classdef ProcInputClass < handle
            elseif isproperty(obj.misc, varname)
                eval(sprintf('varval = obj.misc.%s;', varname));
            else
                varval = obj.acquiredEditable.GetVar(varname);
                varval = obj.acquired.GetVar(varname);
            end
            if ~isempty(varval) && exist('iBlk','var')
                if iscell(varval)
@@ -120,14 +122,27 @@ classdef ProcInputClass < handle
            nbytes(2) = sizeof(obj.mlActMan);
            nbytes(3) = sizeof(obj.misc);
            nbytes(4) = sizeof(obj.stimValSettings);
            if isempty(obj.acquiredEditable)
            if isempty(obj.acquired)
                nbytes(5) = 0;
            else
                nbytes(5) = obj.acquiredEditable.MemoryRequired();
                nbytes(5) = obj.acquired.MemoryRequired();
            end
            nbytes = sum(nbytes);
        end

        
        
        % ----------------------------------------------------------------------------------        
        function SaveAcquiredData(obj)
            obj.acquired.SaveMutable();
        end

        
        % ----------------------------------------------------------------------------------
        function b = AcquiredDataModified(obj)
            b = obj.acquired.DataModified();
        end
        
    end
        
    
@@ -188,7 +203,7 @@ classdef ProcInputClass < handle
            if nargin==1
                t = [];
            end
            s = obj.acquiredEditable.GetStims(t);
            s = obj.acquired.GetStims(t);
        end
        
        
@@ -200,7 +215,7 @@ classdef ProcInputClass < handle
            if isempty(condition)
                return;
            end
            obj.acquiredEditable.AddStims(tPts, condition);
            obj.acquired.AddStims(tPts, condition);
        end

        
@@ -212,7 +227,7 @@ classdef ProcInputClass < handle
            if ~exist('condition','var')
                condition = '';
            end
            obj.acquiredEditable.DeleteStims(tPts, condition);
            obj.acquired.DeleteStims(tPts, condition);
        end
        
        
@@ -224,7 +239,7 @@ classdef ProcInputClass < handle
            if ~exist('condition','var')
                condition = '';
            end
            obj.acquiredEditable.ToggleStims(tPts, condition);
            obj.acquired.ToggleStims(tPts, condition);
        end
        
        
@@ -236,7 +251,7 @@ classdef ProcInputClass < handle
            if ~exist('condition','var')
                condition = '';
            end
            obj.acquiredEditable.MoveStims(tPts, condition);
            obj.acquired.MoveStims(tPts, condition);
        end
        
        
@@ -250,7 +265,7 @@ classdef ProcInputClass < handle
    
        % ----------------------------------------------------------------------------------
        function SetStimTpts(obj, icond, tpts)
            obj.acquiredEditable.SetStimTpts(icond, tpts);
            obj.acquired.SetStimTpts(icond, tpts);
        end
        
    
@@ -259,13 +274,13 @@ classdef ProcInputClass < handle
            if ~exist('icond','var')
                icond=1;
            end
            tpts = obj.acquiredEditable.GetStimTpts(icond);
            tpts = obj.acquired.GetStimTpts(icond);
        end
        
        
        % ----------------------------------------------------------------------------------
        function SetStimDuration(obj, icond, duration)
            obj.acquiredEditable.SetStimDuration(icond, duration);
            obj.acquired.SetStimDuration(icond, duration);
        end
        
    
@@ -274,13 +289,13 @@ classdef ProcInputClass < handle
            if ~exist('icond','var')
                icond=1;
            end
            duration = obj.acquiredEditable.GetStimDuration(icond);
            duration = obj.acquired.GetStimDuration(icond);
        end
        
        
        % ----------------------------------------------------------------------------------
        function SetStimValues(obj, icond, vals)
            obj.acquiredEditable.SetStimValues(icond, vals);
            obj.acquired.SetStimValues(icond, vals);
        end
        
    
@@ -289,13 +304,13 @@ classdef ProcInputClass < handle
            if ~exist('icond','var')
                icond=1;
            end
            vals = obj.acquiredEditable.GetStimValues(icond);
            vals = obj.acquired.GetStimValues(icond);
        end
        
        
        % ----------------------------------------------------------------------------------
        function CondNames = GetConditions(obj)
            CondNames = obj.acquiredEditable.GetConditions();
            CondNames = obj.acquired.GetConditions();
        end
        
        
@@ -304,13 +319,13 @@ classdef ProcInputClass < handle
            if nargin==1
                return;
            end
            obj.acquiredEditable.SetConditions(CondNames);
            obj.acquired.SetConditions(CondNames);
        end
        
        
        % ----------------------------------------------------------------------------------
        function SetStims_MatInput(obj, s, t, CondNames)
            obj.acquiredEditable.SetStims_MatInput(s, t);
            obj.acquired.SetStims_MatInput(s, t);
        end
        
        
@@ -318,7 +333,7 @@ classdef ProcInputClass < handle
        function StimReject(obj, t, iBlk)
            tRange = [-2, 10];
            
            s = obj.acquiredEditable.GetStims(t);
            s = obj.acquired.GetStims(t);
            dt = (t(end)-t(1))/length(t);
            tRangeIdx = floor(tRange(1)/dt):ceil(tRange(2)/dt);
            smax = max(s,[],2);
@@ -329,7 +344,7 @@ classdef ProcInputClass < handle
                    s(lstS(iS),:) = -1*abs(s(lstS(iS),:));
                end
            end
            obj.acquiredEditable.SetStims_MatInput(s, t);
            obj.acquired.SetStims_MatInput(s, t);
        end
        
        
@@ -337,7 +352,7 @@ classdef ProcInputClass < handle
        function StimInclude(obj, t, iBlk)
            tRange = [-2, 10];
            
            s = obj.acquiredEditable.GetStims(t);
            s = obj.acquired.GetStims(t);
            dt = (t(end)-t(1))/length(t);
            tRangeIdx = floor(tRange(1)/dt):ceil(tRange(2)/dt);
            for iC = 1:size(s,2)
@@ -349,29 +364,32 @@ classdef ProcInputClass < handle
                    end
                end
            end
            obj.acquiredEditable.SetStims_MatInput(s, t);
            obj.acquired.SetStims_MatInput(s, t);
        end
        
        
        % ----------------------------------------------------------------------------------
        function RenameCondition(obj, oldname, newname)
            % Function to rename a condition. Important to remeber that changing the
            % Function to rename a condition. Important to note that changing the
            % condition involves 2 distinct well defined steps:
            %
            %   a) For the current element change the name of the specified (old)
            %      condition for ONLY for ALL the acquired data elements under the
            %      currElem, be it run, subj, or group . In this step we DO NOT TOUCH
            %      the condition names of the run, subject or group .
            %      condition ONLY for ALL the ACQUIRED data elements under the
            %      current element, be it run, subj, or group . In this step we DO NOT TOUCH
            %      the derived set of condition names of the run, subject or group .
            %   b) Rebuild condition names and tables of all the tree nodes group, subjects
            %      and runs same as if you were loading during Homer3 startup from the
            %      acquired data.
            %
            % This method only implements step a). 
            %
            if ~exist('oldname','var') || ~ischar(oldname)
                return;
            end
            if ~exist('newname','var')  || ~ischar(newname)
                return;
            end
            obj.acquiredEditable.RenameCondition(oldname, newname);
            obj.acquired.RenameCondition(oldname, newname);
        end
    end   
    
Loading