Commit bb59bc7e authored by jayd1860's avatar jayd1860
Browse files

v1.51.0

-- Fix channel order issues excluded time by channel in hmrR_MotionCorrectSplineSG. Change GetDataTimeSeries to return measurement list associated with the data time series as well as adding other options to control channel order.
-- Fix matlab exception bug in plot probe when clicking non-run, non-hrf data in MainGUI. Fix in plotProbeAndSetProperties.m, updateData() function which was cleaned up in addition to fixing problem.
-- Fix incomplete isequal method in ProcStreamClass comparing 2 objects. This caused active ProcStreamOptionsGUI not to update correctly when removing function from function call chain in ProcStreamEditGUI.
-- Fix issue in SubjClass when processing multiple sessions incorrectly adding trials from all the sessions.
parent 402d7875
Loading
Loading
Loading
Loading
+259 −89
Original line number Diff line number Diff line
@@ -464,64 +464,142 @@ classdef DataClass < FileLoadSaveClass
        
        
        % ---------------------------------------------------------
        function [d, order] = GetDataTimeSeries(obj, options)
        function [d, t, ml, order] = GetDataTimeSeries(obj, options)
            %
            % SYNTAX:
            %       d = GetDataTimeSeries(obj)
            %       [d, t] = GetDataTimeSeries(obj)
            %       [d, t, ml] = GetDataTimeSeries(obj)
            %       [d, t, ml, order] = GetDataTimeSeries(obj)
            %       d = GetDataTimeSeries(obj, options)
            %       [d, t] = GetDataTimeSeries(obj, options)
            %       [d, t, ml] = GetDataTimeSeries(obj, options)
            %       [d, t, ml, order] = GetDataTimeSeries(obj, options)
            %
            % DESCRIPTION:
            %       If no argument is supplied, or if option='', then dataTimeSeries and accompanying 
            %       measurementList is returned as is, as it exists in the SNIRF object. 
            %
            %       If option is supplied then we have the following option values possible values which can be 
            %       mixed and matched. The options are combined in one string argument with colon ':'. 
            %       
            %           'reshape'  - dataTimeSeries will be sorted, reshaped and reordered with the following dimensions:  
            %               
            %                        [ dataTimePoints,  sdPairIndex,  dataType, condition ]
            %                   
            %                        and all dimensions sorted in ascending order. The slowest dimensions to change will be 
            %                        from right-to-left. That is, sdPairIndex, dataType, condition. The rows of measurement list, ml, 
            %                        will follow this order in linear form. That is, the order of ml will index the columns 
            %                        of d squeezed into 2 dimensions d(:,:)
            %       
            %           'matrix'   - dataTimeSeries will not be modified but ml will be returned as a 2D matrix instead of a 
            %                        MeasListClass structure. It's rows will have the same order as the structure elements. 
            %       
            %           'datatype' - used in combination with reshape. dataTimeSeries will be reshaped as above but the 
            %                        slowest dimensions to change will be reversed from left-to-right, that is, 
            %                        condition, dataType, sdPair:  
            %  
            %           'linear'   - Reordering as shown above with reshape and datatype, but d will be squeezed into 2D 
            %                        array
            % 
            %  EXAMPLES:
            %       
            %       %%%% dod is a DataClass object containing optical density data, with 4 sources, 8 detectors, 9 sd pairs, and 2 wavelengths.
            %       %%%% dc is a DataClass object containing concentration data, with 4 sources, 8 detectors, 9 sd pairs, and 3 Hb data types:  hbo, hbr, and hbt. 
            %
            %
            %       % Example 1:  Return OD dataTimeSeries, time and  measurementList unchanged.
            %       [d, t, ml, order] = dod.GetDataTimeSeries();
            %
            %
            %       % Example 2:  Return OD dataTimeSeries, and time unchanged and measurementList (ml) as a 2D matrix. Channel order is unchanged.
            %       [d, t, ml, order] = dod.GetDataTimeSeries('matrix');
            %
            %
            %       % Example 3:  Return concentration dataTimeSeries as a 3D array (d), and measurementList (ml) as a 2D array. Channel order is sorted, 
            %                     with slowest dimension to change being Hb type. 
            %       [d, t, ml, order] = dc.GetDataTimeSeries('matrix:reshape');
            %
            %
            %       % Example 4:  Return concentration dataTimeSeries as a 3D array (d), and measurementList (ml) as a 2D array. Channel order is sorted, 
            %                     with slowest dimension to change being sdPair. 
            %       [d, t, ml, order] = dc.GetDataTimeSeries('matrix:reshape:datatype');
            %
            %
            %       % Example 5:  Return concentration dataTimeSeries as a 2D array (d), and measurementList (ml) as a 2D array. Channel order is sorted, 
            %                     with slowest dimension to change being sdPair (ie. same channel as Example 4). 
            %       [d, t, ml, order] = dc.GetDataTimeSeries('matrix:reshape:datatype:linear');
            %
            %
            %
            d = [];
            t = [];
            ml = [];
            order = [];
            
            if ~exist('options','var') || isempty(options)
                options = '';
            end
            if isempty(obj.dataTimeSeries)
            if isempty(obj)
                return;
            end            
            if ~strcmp(options, 'reshape')
                d = obj.dataTimeSeries;
                return
            if isempty(obj.dataTimeSeries)
                return;
            end
            
            dataTypeLabels = {};
            srcs = zeros(0,1);
            dets = zeros(0,1);
            conditions = [];
            wavelengths = [];
            hh=1; jj=1; kk=1; ll=1; mm=1;
            for ii = 1:length(obj.measurementList)
                if ~ismember(obj.measurementList(ii).dataTypeLabel, dataTypeLabels) && ~isempty(obj.measurementList(ii).dataTypeLabel)
                    dataTypeLabels{hh} = obj.measurementList(ii).dataTypeLabel; %#ok<*AGROW>
                    hh=hh+1;
            reshapeOption = '';
            if contains(options, 'reshape')
                reshapeOption = 'reshape';
            end
                if isempty(find(srcs == obj.measurementList(ii).GetSourceIndex()))
                    srcs(jj) = obj.measurementList(ii).GetSourceIndex();
                    jj=jj+1;
            dimSlow = 'sdpair';
            if contains(lower(options), 'condition')
                dimSlow = 'condition';
            elseif contains(lower(options), 'datatype')
                dimSlow = 'datatype';
            elseif contains(lower(options), 'wavelength')
                dimSlow = 'datatype';
            elseif contains(lower(options), 'hbtype')
                dimSlow = 'datatype';
            end
                if isempty(find(dets == obj.measurementList(ii).GetDetectorIndex())) %#ok<*EFIND>
                    dets(kk) = obj.measurementList(ii).GetDetectorIndex();
                    kk=kk+1;
                end
                if ~ismember(obj.measurementList(ii).GetCondition(), conditions) && obj.measurementList(ii).GetCondition() > 0
                    conditions(ll) = obj.measurementList(ii).GetCondition();
                    ll=ll+1;
                end
                if ~ismember(obj.measurementList(ii).GetWavelengthIndex(), wavelengths) && obj.measurementList(ii).GetWavelengthIndex()>0
                    wavelengths(mm) = obj.measurementList(ii).GetWavelengthIndex();
                    mm=mm+1;
            matrixOption = '';
            if contains(options, 'matrix')
                matrixOption = 'matrix';
            end
            
            t = obj.time;
            if ~strcmp(reshapeOption, 'reshape')
                d = obj.dataTimeSeries;
                ml = obj.GetMeasurementList(matrixOption);
                order = 1:size(d,2);
                return
            end            
            
            % Sort all the dimension data
            srcs            = sort(srcs);
            dets            = sort(dets);
            wavelengths     = sort(wavelengths);
            hbTypes         = sort(dataTypeLabels);            
            conditions      = sort(conditions);
            measurementListFull = obj.GetMeasurementList('matrix');
            measurementListSDpairs = obj.GetMeasListSrcDetPairs('reshape');
            
            % Sort all the dimension data
            srcs       = sort(unique(measurementListFull(:,1)));
            dets       = sort(unique(measurementListFull(:,2)));
            conditions = sort(unique(measurementListFull(:,3)));
            dataTypes  = sort(unique(measurementListFull(:,4)));

            if obj.measurementList(1).wavelengthIndex > 0
                wavelengths     = dataTypes;
                hbTypes         = [];
            else
                wavelengths     = [];
                hbTypes         = dataTypes;
            end
            if conditions == 0
                conditions = [];
            end
            nWavelengths    = length(wavelengths);
            nDataTypeLabels = length(hbTypes);
            nCond           = length(conditions);
            
            measurementListFull = obj.GetMeasurementList('matrix');
            measurementListSDpairs = obj.GetMeasListSrcDetPairs('reshape');
            
            kk = 1;            
            if strcmp(dimSlow, 'sdpair')
                
                if nWavelengths > 0 && nCond == 0
                    
                    for iS = 1:length(srcs)
@@ -599,6 +677,98 @@ classdef DataClass < FileLoadSaveClass
                    end
                end
                
            elseif strcmp(dimSlow, 'condition') || strcmp(dimSlow, 'datatype')
                
                if nWavelengths > 0 && nCond == 0
                    
                    for iWl = 1:nWavelengths
                        for iS = 1:length(srcs)
                            for iD = 1:length(dets)
                                
                                k = find(measurementListFull(:,1)==srcs(iS) & measurementListFull(:,2)==dets(iD) & measurementListFull(:,4)==wavelengths(iWl));
                                if ~isempty(k)
                                    iSDPair = find(measurementListSDpairs(:,1)==srcs(iS) & measurementListSDpairs(:,2)==dets(iD));
                                    d(:, iWl, iSDPair) = obj.dataTimeSeries(:,k); %#ok<*FNDSB>
                                    order(kk) = k;
                                    kk = kk+1;
                                end
                                
                            end
                        end
                    end
                    
                elseif nWavelengths > 0 && nCond > 0
                    
                    for iCond = 1:nCond
                        for iWl = 1:nWavelengths
                            for iS = 1:length(srcs)
                                for iD = 1:length(dets)
                                    
                                    k = find(measurementListFull(:,1)==srcs(iS) & measurementListFull(:,2)==dets(iD) & measurementListFull(:,3)==iCond &  measurementListFull(:,4)==wavelengths(iWl));
                                    if ~isempty(k)
                                        iSDPair = find(measurementListSDpairs(:,1)==srcs(iS) & measurementListSDpairs(:,2)==dets(iD));
                                        d(:, iWl, iSDPair, iCond) = obj.dataTimeSeries(:,k);
                                        order(kk) = k;
                                        kk = kk+1;
                                    end
                                    
                                end
                            end
                        end
                    end
                    
                elseif nDataTypeLabels > 0 && nCond == 0
                    
                    for iHbType = 1:length(hbTypes)
                        for iS = 1:length(srcs)
                            for iD = 1:length(dets)
                                
                                k = find(measurementListFull(:,1)==srcs(iS) & measurementListFull(:,2)==dets(iD) & measurementListFull(:,4)==iHbType);
                                if ~isempty(k)
                                    iSDPair = find(measurementListSDpairs(:,1)==srcs(iS) & measurementListSDpairs(:,2)==dets(iD));
                                    d(:, iHbType, iSDPair) = obj.dataTimeSeries(:,k);
                                    order(kk) = k;
                                    kk = kk+1;
                                end
                                
                            end
                        end
                    end
                    
                elseif nDataTypeLabels > 0 && nCond > 0
                    
                    for iCond = 1:nCond
                        for iHbType = 1:length(hbTypes)
                            for iS = 1:length(srcs)
                                for iD = 1:length(dets)
                                    
                                    k = find(measurementListFull(:,1)==srcs(iS) & measurementListFull(:,2)==dets(iD) & measurementListFull(:,3)==iCond &  measurementListFull(:,4)==iHbType);
                                    if ~isempty(k)
                                        iSDPair = find(measurementListSDpairs(:,1)==srcs(iS) & measurementListSDpairs(:,2)==dets(iD));
                                        d(:, iHbType, iSDPair, iCond) = obj.dataTimeSeries(:,k);
                                        order(kk) = k;
                                        kk = kk+1;
                                    end
                                    
                                end
                            end
                        end
                    end
                end
                
            end
            
            ml = measurementListFull(order,:);
            
            if contains(options, 'linear') 
                d = d(:,:);
            end
            if ~contains(options, 'matrix')
                ml = obj.measurementList;
                ml(order) = ml;
            end

            
            d = simulateDataError(d);
        end
        
+5 −3
Original line number Diff line number Diff line
@@ -1011,8 +1011,10 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
        
        
        % ---------------------------------------------------------
        function datamat = GetDataTimeSeries(obj, options, iBlk)
            datamat = [];
        function [d, t, ml] = GetDataTimeSeries(obj, options, iBlk)
            d = [];
            t = [];
            ml = [];
            if ~exist('options','var')
                options = '';
            end
@@ -1022,7 +1024,7 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
            if iBlk>length(obj.data)
                return;
            end
            datamat = obj.data(iBlk).GetDataTimeSeries(options);
            [d, t, ml] = obj.data(iBlk).GetDataTimeSeries(options);
        end
        
        
+14 −2
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ classdef ProcStreamClass < handle
        function B = isequal(obj, obj2)
            B = false;
            if isa(obj2, 'ProcStreamClass')
                % Compare in both direction obj -> obj2  AND  obj2 -> obj
                for ii = 1:length(obj.fcalls)
                    if ii>length(obj2.fcalls)
                        return
@@ -128,6 +129,14 @@ classdef ProcStreamClass < handle
                        return;
                    end
                end
                for ii = 1:length(obj2.fcalls)
                    if ii>length(obj.fcalls)
                        return
                    end
                    if obj.fcalls(ii) ~= obj2.fcalls(ii)
                        return;
                    end
                end
            elseif isstruct(obj2)
                if ~isproperty(obj2, 'procFunc')
                    return;
@@ -153,6 +162,8 @@ classdef ProcStreamClass < handle
                if length(obj.fcalls) ~= length(obj2.procFunc.funcName)
                    return;
                end
                
                % Compare in both direction obj -> obj2  AND  obj2 -> obj
                for ii = 1:length(obj.fcalls)
                    obj3.funcName        = obj2.procFunc.funcName{ii};
                    obj3.funcNameUI      = obj2.procFunc.funcNameUI{ii};
@@ -492,6 +503,7 @@ classdef ProcStreamClass < handle
        end
        
        
        
        % ----------------------------------------------------------------------------------
        function sargin = ParseInputParams(obj, iFcall)
            sargin = '';
+5 −5
Original line number Diff line number Diff line
@@ -399,16 +399,16 @@ classdef RunClass < TreeNodeClass

        
        % ----------------------------------------------------------------------------------
        function d = GetRawData(obj, iBlk)
        function [d, t, ml] = GetRawData(obj, iBlk)
            if nargin<2
                iBlk = 1;
            end
            d = obj.acquired.GetDataTimeSeries('', iBlk);
            [d, t, ml] = obj.acquired.GetDataTimeSeries('', iBlk);
        end
        
        
        % ----------------------------------------------------------------------------------
        function d = GetDataTimeSeries(obj, options, iBlk)
        function [d, t, ml] = GetDataTimeSeries(obj, options, iBlk)
            if ~exist('options','var')
                options = '';
            end
@@ -416,9 +416,9 @@ classdef RunClass < TreeNodeClass
                iBlk = 1;
            end
            if isempty(options) || strcmp(options, 'reshape')
                d = obj.acquired.GetDataTimeSeries(options, iBlk);
                [d, t, ml] = obj.acquired.GetDataTimeSeries(options, iBlk);
            else
                d = obj.GetDataTimeSeries@TreeNodeClass(options, iBlk);
                [d, t, ml] = obj.GetDataTimeSeries@TreeNodeClass(options, iBlk);
            end
        end
        
+4 −1
Original line number Diff line number Diff line
@@ -305,7 +305,10 @@ classdef SubjClass < TreeNodeClass
                if isempty(obj.inputVars.nTrialsSess)
                    obj.inputVars.nTrialsSess                      = obj.sess(iSess).procStream.output.GetVar('nTrials');
                else
                    obj.inputVars.nTrialsSess                      = obj.inputVars.nTrialsSess + obj.sess(iSess).procStream.output.GetVar('nTrials');
                    nTrialsSess                                    = obj.sess(iSess).procStream.output.GetVar('nTrials');
                    for iBlk = 1:length(obj.inputVars.nTrialsSess)
                        obj.inputVars.nTrialsSess{iBlk}            = obj.inputVars.nTrialsSess{iBlk} + nTrialsSess{iBlk};
                    end
                end
                if ~isempty(obj.sess(iSess).procStream.output.GetVar('misc'))
                    if isfield(obj.sess(iSess).procStream.output.misc, 'stim') == 1
Loading