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

Change TreeNodeClass.Plot method accept source/detector/datatype instead of...

Change TreeNodeClass.Plot method accept source/detector/datatype instead of single number index  (#151)

v1.64.0

-- Fix DataTree/setpaths not deleting other DataTree repos from path.
-- Change TreeNodeClass.Plot method accept source/detector/datatype instead of single number index vector, and handle multiple plot figures.
-- Reorganize and add documentation for TreeNodeClass plotting methods under separate methods section.
-- Redo LoadRunPlotExample (rename from LoadRunPlotExample1.m and delete LoadRunPlotExample2.m)  to display multiple plot figures.
parent f487f7cc
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -494,8 +494,10 @@ classdef DataClass < FileLoadSaveClass
            %                        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. 
            %           'matrix'   - This options refers to the measurement list type: if 'matrix' keyword is in the options 
            %                        then ml will be returned as a 2D matrix instead of a MeasListClass object (that is the 
            %                        object representing the measurementList SNIRF field). The rows of the 2d array will have 
            %                        the same order as the original MeasListClass object 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, 
@@ -510,7 +512,7 @@ classdef DataClass < FileLoadSaveClass
            %       %%%% 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.
            %       % Example 1:  Return OD dataTimeSeries, time and  measurementList (ml) unchanged, that is, as a MeasListClass object instead of Nx4 2D array.
            %       [d, t, ml, order] = dod.GetDataTimeSeries();
            %
            %
+13 −2
Original line number Diff line number Diff line
@@ -507,6 +507,11 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
        
        % -------------------------------------------------------
        function err = LoadProbe(obj, fileobj, ~)
            % metaDataTags is a prerequisite for load probe, so check to make sure its already been loaded
            if isempty(obj.metaDataTags)
                obj.LoadMetaDataTags(fileobj);
            end
                
            % get lenth unit through class method
            LengthUnit = obj.metaDataTags.Get('LengthUnit');
            obj.probe = ProbeClass();
@@ -1070,11 +1075,17 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
            if ~exist('iBlk','var') || isempty(iBlk)
                iBlk = 1;
            end
            freememory = false;
            if isempty(obj.data)
                obj.LoadData(obj.GetFilename());
                freememory = true;
            end
            if iBlk>length(obj.data)
                return;
            end
            for ii = 1:length(iBlk)
                ml = [ml; obj.data(ii).GetMeasurementList(matrixMode)];
            ml = obj.data(iBlk).GetMeasurementList(matrixMode);
            if freememory 
                obj.FreeMemory(obj.GetFilename());
            end
        end
        
+28 −4
Original line number Diff line number Diff line
@@ -69,21 +69,25 @@ logger = Logger('DataTreeClass');
cfg = ConfigFileClass();

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 1. Plot raw data for current element for channels 1 and 2
% 1. Plot raw data for current element for channel 2
% 2. Export stim for the current element
% 3. Edit stim in the events TSV file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
obj = dataTree.currElem;
obj.Load();
obj.Plot('raw',[1,2]);
h = obj.Plot('raw', [1,2,0,1]);
repositionFigures(h);         % Local function to reposition figures so they can be all be seen on screen at once

obj.ExportStim();

pause(2);

EditEventsTsvFile_InMatlabEditor(obj, dataSetDir);

obj.ReloadStim();
obj.Plot('raw',[1,2]);
obj.ClosePlots();
dataTree.ReloadStim();
h = obj.Plot('raw', [1,2,0,1]);
repositionFigures(h);         % Local function to reposition figures so they can be all be seen on screen at once


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -118,3 +122,23 @@ editorTab.makeActive;
MenuBox('Please edit TSV stim file and save it, then click the ''OK'' button.');




% -------------------------------------------------------------------
function repositionFigures(h,i)
if ~exist('i','var')
    i = 1;
end
k = find(h(1,:)==-1)-1;
set(h(1,k), 'units','normalized')
set(h(2,k), 'units','normalized')
p1 = get(h(1,k), 'position');
p2 = get(h(2,k), 'position');
set(h(1,k), 'position',[p1(1)-(p1(1)/2),  1.0-(p1(4)+i/10),  p1(3),  p1(4)])
set(h(2,k), 'position',[p2(1)+(p2(1)/2),  1.0-(p2(4)+i/10),  p2(3),  p2(4)])





+168 −0
Original line number Diff line number Diff line
function LoadRunPlotExample1(dataSetDir)
function LoadRunPlotExample(dataSetDir)

%
%   Syntax:
%       LoadRunPlotExample1(dataSetDir)
%       LoadRunPlotExample(dataSetDir)
%
%   Description:
%       This script does the following:
@@ -22,7 +22,7 @@ function LoadRunPlotExample1(dataSetDir)
%
%   Examples:
%       cd <local_path>/DataTree
%       LoadRunPlotExample1('./Examples/Example4_twNI')
%       LoadRunPlotExample('./Examples/Example4_twNI')
%


@@ -31,7 +31,7 @@ function LoadRunPlotExample1(dataSetDir)
% Parse arguments
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ~exist('dataSetDir','var')
    f = which('LoadRunPlotExample1');
    f = which('LoadRunPlotExample');
    dataSetDir = [fileparts(f), '/Example4_twNI']; 
end

@@ -67,44 +67,77 @@ logger = Logger('DataTreeClass');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plot raw data for current element for channels 6 nd 7
% Plot raw data for current element, for  1st wavelength of 3 source/detector pairs , [2,3], [3,5] and [4,6]:
% (NOTE: for non-HRF, raw, and OD, condition is 0 and datatype refers to wavelength)
%        for non-HRF, concentration, condition is 0 and datatype refers to Hb type)
%
%    ch A:      source idx = 2, detector idx = 3,  condition idx = 0,   datatype idx = 1
%    ch B:      source idx = 3, detector idx = 5,  condition idx = 0,   datatype idx = 1 
%    ch C:      source idx = 4, detector idx = 6,  condition idx = 0,   datatype idx = 1
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
obj = dataTree.currElem;
obj.Load();
obj.Plot('raw',[6,7]);
h = obj.Plot('raw',[2,3,0,1; 3,5,0,1; 4,6,0,1]);
repositionFigures(h,1);         % Local function to reposition figures so they can be all be seen on screen at once
pause(2);



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plot raw data for 3rd run of the 1st session, 3rd subject,  
% and 1st group for channels 6 nd 7
% and 1st group for 2nd wavelength of 3 source/detector pairs, [2,3], [3,5] and [4,6]:
% (NOTE: for non-HRF, raw, and OD, condition is 0 and datatype refers to wavelength)
%        for non-HRF, concentration, condition is 0 and datatype refers to Hb type)
%
%    ch A:      source idx = 2, detector idx = 3,  condition idx = 0,   datatype idx = 2
%    ch B:      source idx = 3, detector idx = 5,  condition idx = 0,   datatype idx = 2 
%    ch C:      source idx = 4, detector idx = 6,  condition idx = 0,   datatype idx = 2
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
obj = dataTree.groups(1).subjs(2).sess(1).runs(3);
obj.Load();
obj.Plot('raw',[6,7]);
h = obj.Plot('raw',[2,3,0,2; 3,5,0,2; 4,6,0,2]);
repositionFigures(h,2);          % Local function to reposition figures so they can be all be seen on screen at once
pause(2);



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Run processing stream for current element and plot 
% concentration HRF for channels 2,3 and 4
% Run processing stream for current element and plot concentration HRF for HbR of condition 1, 
% for 3 channels with source/detector pairs, [2,3], [3,5] and [4,6]:
%
% (NOTE: for HRF data OD, condition is > 0 and datatype refers to wavelength)
%        for HRF data concentration, condition is > 0 and datatype refers to Hb type)
%
%    ch A:      source idx = 2, detector idx = 3,  condition idx = 1,   datatype idx = 2 
%    ch B:      source idx = 3, detector idx = 5,  condition idx = 1,   datatype idx = 2 
%    ch C:      source idx = 4, detector idx = 6,  condition idx = 1,   datatype idx = 2 
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
obj = dataTree.currElem;
obj.Calc();
obj.Plot('conc hrf',[2,3,4]);
h = obj.Plot('conc hrf',[2,3,1,2; 3,5,1,2; 4,6,1,2]);
repositionFigures(h,3);         % Local function to reposition figures so they can be all be seen on screen at once
pause(2);



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Run processing stream for the first group and plot it's
% concentration HRF for channels 2,3 and 4
% Run processing stream for group 1 and plot concentration HRF for HbT of condition 2, 
% for 2 channels with source/detector pairs, [3,6] and [4,8]:
%
% (NOTE: for HRF data OD, condition is > 0 and datatype refers to wavelength)
%        for HRF data concentration, condition is > 0 and datatype refers to Hb type)
%
%    ch A:      source idx = 3, detector idx = 6,  condition idx = 2,   datatype idx = 3 
%    ch B:      source idx = 4, detector idx = 8,  condition idx = 2,   datatype idx = 3 
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
obj = dataTree.groups(1);
obj.Calc();
obj.Plot('conc hrf', [2,3,4]);
h = obj.Plot('conc hrf',[3,6,2,3; 4,8,2,3]);
repositionFigures(h,4);         % Local function to reposition figures so they can be all be seen on screen at once
pause(2);



@@ -112,4 +145,24 @@ obj.Plot('conc hrf', [2,3,4]);
% Close open log files
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
obj.logger.Close();
MenuBox('When done, click okay button to close all plots','OK');
obj.ClosePlots('all')




% -------------------------------------------------------------------
function repositionFigures(h,i)
k = find(h(1,:)==-1)-1;
set(h(1,k), 'units','normalized')
set(h(2,k), 'units','normalized')
p1 = get(h(1,k), 'position');
p2 = get(h(2,k), 'position');
set(h(1,k), 'position',[p1(1)-(p1(1)/2),  1.0-(p1(4)+i/10),  p1(3),  p1(4)])
set(h(2,k), 'position',[p2(1)+(p2(1)/2),  1.0-(p2(4)+i/10),  p2(3),  p2(4)])





+0 −178
Original line number Diff line number Diff line
function LoadRunPlotExample2(dataSetDir)

%
%   Syntax:
%       LoadRunPlotExample2(dataSetDir)
%
%   Description:
%       LoadRunPlotExample2 does the exast same thing as it accesses snirf objects directly without any methods 
%       and then plots them directly in the script to show user how snirf objects work. This script does the following:
%
%       1. If starting from scratch, first download the DataTree repo from
%          github
%
%           a) git clone  -b <branch_name>   https://github.com/<username>/DataTree  <local_path>/DataTree  
%           b) cd <local_path>/DataTree
%           c) setpaths
%
%       2. Change folder to dataSetDir
%       3. Load data set
%       4. Plot raw data for various dataTree elements
%       5. Run processing stream
%       6. Plot HRF for various dataTree elements
%
%   Examples:
%       cd <local_path>/DataTree
%       LoadRunPlotExample2('./Examples/Eaxmple4_twNI')
%



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Parse arguments
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ~exist('dataSetDir','var')
    f = which('LoadRunPlotExample2');
    dataSetDir = [fileparts(f), '/Example4_twNI']; 
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% a) Change current folder to a data set folder, 
% b) Load dataset
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if ~exist(dataSetDir,'dir')
    mkdir(dataSetDir);
end
cd(dataSetDir)
if exist([dataSetDir, '/derivatives']','dir')
    rmdir([dataSetDir, '/derivatives'], 's')
end
dataTree = DataTreeClass();
if dataTree.IsEmpty()
    MenuBox('No data set was loaded',{'OK'});
    return
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This step is NOT essential, but is a good idea in order to
% set up logging. Since we are running data tree standalone 
% initilize logger here which would have been done by parent 
% gui like Homer3 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
global logger
logger = Logger('DataTreeClass');


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plot raw data for current element for channels 6 nd 7
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
obj = dataTree.currElem;
obj.Load();
t = obj.acquired.data(1).time;
d = obj.acquired.data(1).dataTimeSeries;
id = [obj.iGroup, obj.iSubj, obj.iSess, obj.iRun];
stim = [];
if ~isempty(obj.procStream.input.acquired)
    stim = obj.procStream.input.acquired.stim;
end
hfig = Plot(t, d, stim, [6,7], obj.GetName(), 'raw', id);
pause(2);



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plot raw data for 3rd run of the 1st session, 3rd subject,  
% and 1st group for channels 6 nd 7
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
obj = dataTree.groups(1).subjs(2).sess(1).runs(3);
obj.Load();
t = obj.acquired.data(1).time;
d = obj.acquired.data(1).dataTimeSeries;
stim = [];
if ~isempty(obj.procStream.input.acquired)
    stim = obj.procStream.input.acquired.stim;
end
hfig = Plot(t, d, stim, [6,7], id, obj.GetName(), 'raw', hfig);
pause(2);



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Run processing stream for current element and plot 
% concentration HRF for channels 2,3 and 4
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
obj = dataTree.currElem;
obj.Calc();
t = obj.procStream.output.dcAvg.time;
d = obj.procStream.output.dcAvg.dataTimeSeries;
stim = [];
id = [obj.iGroup, obj.iSubj, obj.iSess, obj.iRun];
hfig = Plot(t, d, stim, [2,3,4], id, obj.GetName(), 'conc hrf', hfig);
pause(2);



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Run processing stream for the first group and plot it's
% concentration HRF for channels 2,3 and 4
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
obj = dataTree.groups(1);
obj.Calc();
t = obj.procStream.output.dcAvg.time;
d = obj.procStream.output.dcAvg.dataTimeSeries;
stim = [];
id = [obj.iGroup, obj.iSubj, obj.iSess, obj.iRun];
Plot(t, d, stim, [2,3,4], id, obj.GetName(), 'conc hrf', hfig);



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Close open log file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
obj.logger.Close();




% ------------------------------------------------------------------------------------
function hfig = Plot(t, d, stim, iChs, id, name, datatype, hfig)
if ~exist('hfig','var')
    hfig = [];
end
if ishandles(hfig)
    close(hfig);
end
hfig = figure;
figname = sprintf('PROCESSING ELEMENT: "%s" (ID = [%s]) ;   DATATYPE: "%s";   CHANNELS: [ %s ]', name, ...
    num2str(id), datatype, num2str(iChs));
namesize = uint32(length(figname)/2);
set(hfig, 'units','characters');
p1 = get(hfig, 'position');
set(hfig, 'name',figname, 'menubar','none', 'NumberTitle','off', 'position',[p1(1)/2, p1(2), p1(3)+namesize, p1(4)]);

% Plot data
plot(t, d(:, iChs));
hAxes = gca;
set(hAxes, 'xlim', [t(1), t(end)]);

% Plot stims
hold on
if ~isempty(stim)
    ylim = get(hAxes, 'ylim');
    d = (1e-4)*(ylim(2)-ylim(1));
    yrange = [ylim(1)+d, ylim(2)-d];
    CondColTbl = distinguishable_colors(10);
    for jj = 1:length(stim)
        for ii = 1:size(stim(jj).data,1)
            plot(hAxes, stim(jj).data(ii,1)*[1,1], yrange, 'color',CondColTbl(jj,:));
        end
    end
end
hold off




Loading