Skip to content

Commit 52ec620

Browse files
authored
Redo retrieval of measurement list, dataTimeSeries and mlAct to fix major issues with incorrect sorting of data. (#141) (#143)
* v1.39.0 -- Fix matlab generated error displaying measurement list visible channels. Take MeasListVis field out of processing stream input (ProcInputClass) since it does not actually contribute to proc stream processing and move it to TreeNodeClass field chVis. * v1.40.0 -- Fix major issue with incorrect sorting of data and measurement list. -- Change unit tests to include wavelength when scrambling channel order. Also make scrambling for unit tests an option * v1.40.1 -- Add back display of standard error bars, and x and y-axis labels to MainGUI data display. -- Fix current element condition name display being cut off in PlotProbeGUI.m * -- Fix bug in shared lib synching code which incorrectly ignores differences in files with .cfg extensions thus ignoring differences in AppSettings.cfg * v1.41.0 -- Add ability to plot selected measurements in exported HRF file from ExportDataGUI -- In ConfigFileClass exclude AppSettings.cfg in submodules folder under Homer3 root folder * v1.42.0 -- Fix issue with probe.snirf or any other snirf files with no data or intentionally corrupt data being accepted as valid. -- Fix Nirs2Snirf not working for some some .nirs datasets which do not have CondNames. Add default CondNames to NirsClass.ErrorCheck() -- Fix display of mlAct in MainGUI broken after the measurement list order issue. -- For diagnostic purposes save error code in err field of all the SnirfClass sub-classes -- Add back to MainGUI making channels invisible by mouse right-clicking on them. * v1.42.1 -- Fix bug removing channels from display by mouse right-clicking in MainGUI axesSDG. Fixed incorrect distance criteria for source and detector from end points on clicked line. * v1.42.2 -- Fix error when loading snirf with corrupt stim data. Added error checking to flag bad stim data. Then add file with bad stim data and discard bad stims while displaying warning. -- Improve warning reporting for files that were allowed to load but with warnings. -- Fix matlab error in backward compatability code when derived output folder is same as root group folder * -- Log the current processing stream function call chain every time RUN button is clicked in MainGUI to generate derived data. -- Minor code formatting in SubjClass.m * v1.42.4 -- Fix bugs found by Meryem in fNIRS 2018 course SS_DEMO_1, Finger_Tapping_*.snirf. Errors when running processing stream in 1. hmrR_MotionArtifact fixed by getting rid of 'reshape' option to DataTimeSeries() 2. hmrR_OD2Conc.m fixed by getting rid of 'reshape' option to DataTimeSeries() 3. hmrR_GLM.m fixed in DataClass.m by NOT assuming source and detector indices do not skip numbers -- Just like for hmrR_MotionArtifact.m no need to reshape for hmrR_MotionArtifactByChannel.m since the -- Better error/warning logging in DataFilesClass.m and FileLoadSaveClass.m * v1.43.0 -- Set inactive channel data to NaN. That way they don't show up in MainGUI display. Implement this in DataClass: inactive channel is a channel for which all data is exactly zero (not approximately zero). -- Fix an issue in ProbeClass which incorrectly upload sourcePos3D or detectorPos3D as a column vector IF AND ONLY IF it is the ONLY optode in the probe. This leads to incorrect result in at least one user function processing hmrR_OD2Conc in which the calculation of rho is sensitive to row vs column vector. -- Fix several issues in incorrect unit tests results for Example9_SessRuns because of file naming in Simple_Probe_run* which contains '_' between Simple and Probe which are interpreted as a subject and session name. This is not how the original .nirs benchmark was processed based on the Simple_Probe*_. In order to match the original subject/session breakdown need to get rid of '_'. -- Fix another unit test bug which has to load saved derived data in compareDcAvg.m before comparing to benchmark. -- Fix another unit test bug in unitTest_BandpassFilt_LPF.m lpf wasn't being changed no matter what the value was because hmrR_BandpassFilter() changed to hmrR_BandpassFilter_old() -- Add to unit tests simulation of occasional random errors (simulateDataError.m and generateErrorOddsConstant.m) to do a check of whether the unit test is really checking data against the benchmark correctly. * -- Fix bug in SnirfClass .snirf file fomat conversion to NirsClas .nirs. -- Set default simulation of errors to none in UnitTests_Init.m -- Add namespace DataTreeClass to shared library Utils function points_on_line.m * v1.44.0 -- Fix ordering issue with active/inactive (mlAct) channels in user functions and MainGUI display. Use sources, detectors, wavelength matrix rather than a logical vector. -- When manually pruning channel only prune at the current wavelength. -- Implement missing application of active/inactive (mlAct) channels at the higher averaging user functions: hmrE_RunAvg.m, hmrG_SubjAvg.m, hmrS_SessAvg.m -- Fix incorrect nTrials calculation at the group level -- Fix PlotProbeGUI/plotProbe.m display issue as a result of fixing the MeasList ordering issue. * v1.45.0 -- Fix bug in channel exclusion in hmrR_PruneChannels.m -- Fix display of manually pruned channels in DisplayAxesSDG.m * v1.46.0 -- Fix plotProbe.m by rewriting the plotting to be based on SNIRF style 2D measurement list rather than .nirs era wavelength based measurement. * v1.47.0 -- Fix mlAct in hmrR_tCCA.m -- In PlotProbeGUI get condition dynamically from parent gui, that is MainGUI -- In PlotProbeGUI.m add back ability to display OD HRF and also any data type that is currently selected in MainGUI * v1.48.0 -- Fix very slow processing at the group, subject and session levels and slow display. All were caused by the same issue: very inefficient DataClass.GetDataTimeSeries('reshape') method. Changed it's code to be much more efficient. -- Fix typo in plotProbeAndSetProperties.m causing matlab-generated error -- Minor improvement to display of location of current processing in MainGUI listboxGroupTree when calculating provcessing stream * v1.48.1 -- Fix typo in hmrR_MotionCorrectWavelet.m causing matlab-generated exception -- More fixes in user functions hmrR_MotionArtifactByChannel.m and hmrR_MotionCorrectCbsi.m of inactive channels mlAct -- Added another performance enhancer in DataClass.GetDataTimeSeries() to speed up retrieval of measurement list and thus data time series. Added cache for measurement list matrix to avoid recalculating it. * v1.48.2 -- Capture and log to log file the function call stack when exception error occurs while running processing stream. * v1.48.3 -- Fix some child gui repositioning issues when MainGUI is upodated especially ProcStreamOptionsGUI -- Don't redisplay ProcStreamOptionsGUI if function call list is exactly same as last time. * v1.48.4 -- Fix time exclusion and motion correction by channel having incorrect channel order. Modify tIncCh to include measurement list info about sources, detectors and data type. -- Fix display of time exclusion and motion correction by channel showing incorrect channels. Clean up and rewrite DisplayExcludedTime() function. -- Improve speed of display function GetMeasurementList to use ml matrices instead of structures. Change definitions of GetMeasurementList() functions to be uniform and compatible with each other up and down the call stack, as well as having separate arguments for matrixOption ('matrix') and dataType ('dod', 'dc', dcAvg', etc). -- Minor graphics adjustment to MainGUI datatype listboxes for wavelength and HbType to be exactly overlapping * v1.50.0 -- Fix another channel order bug in DataClass.GetDataTimeSeries. order need to match linear order when squeezing dimensions > 1 into 1D. This caused incorrect results to be displayed for concentration HbT after running hmrR_MotionCorrectCbsi -- Fix minor display issue in MainGUI.m icorrectly enabling OD and concentration radio buttons even though no results exists. -- Add diagnostic/debug functions to unit test to generate simulated data time series whose data identifies the channel it originated in. * 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. * v1.51.1 -- Fix matlab exception in hmrR_MotionCorrectCbsi.m because call to GetDataTimeSeries method was not updated to match new function definition. -- MainGUI and PlotProbeGUI/plotProbe.m display improvements: thinner data plot lines, exclude time patches incorrectly changing y lim. * v1.51.2 -- Fix matlab exception in hmrR_MotionCorrectSplineSG because of typo missing 'matrix' argument in GetMeasurementList(). hmrR_MotionCorrectSplineSG expects measurement list in matrix form rather than structure. * Diagnostic code which does not effect main Homer3 operation (so version number stays the same): -- Change generateSimData.m to include all data files in a group. This function replaces the files real data with fake data that has the channel ID (source idx, detector index, data type idx, condition idx) embedded in the data itself for diagnosing/uncovering channel order issues. -- Add more sim data user functions
1 parent 19566ba commit 52ec620

File tree

122 files changed

+3865
-1506
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+3865
-1506
lines changed

DataTree/AcquiredData/DataFiles/DataFilesClass.m

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
methods
2121

2222
% ----------------------------------------------------
23-
function obj = DataFilesClass(varargin)
23+
function obj = DataFilesClass(varargin)
2424
obj.files = FileClass.empty();
2525
obj.filesErr = FileClass.empty();
2626
obj.filetype = '';
@@ -472,25 +472,34 @@ function ErrorCheck(obj)
472472
if obj.files(ii).isdir
473473
continue;
474474
end
475-
filename = [obj.files(ii).rootdir, obj.files(ii).name];
475+
filename = [obj.rootdir, obj.files(ii).name];
476476
eval( sprintf('o = %s(filename);', constructor) );
477477
if o.GetError() < 0
478-
obj.logger.Write('DataFilesClass.ErrorCheck: FAILED error check - %s will not be added to data set\n', filename);
478+
obj.logger.Write('DataFilesClass.ErrorCheck - ERROR: In file "%s" %s. File will not be added to data set\n', obj.files(ii).name, o.GetErrorMsg());
479479
errorIdxs = [errorIdxs, ii]; %#ok<AGROW>
480-
elseif contains(o.GetErrorMsg(), 'WARNING: ''data'' corrupt and unusable')
481-
obj.logger.Write('DataFilesClass.ErrorCheck: WARNING data is unusable - %s will not be added to data set\n', filename);
480+
elseif contains(o.GetErrorMsg(), '''data'' field corrupt and unusable')
481+
obj.logger.Write('DataFilesClass.ErrorCheck - WARNING: In file "%s" %s. File will not be added to data set\n', obj.files(ii).name, o.GetErrorMsg());
482482
errorIdxs = [errorIdxs, ii]; %#ok<AGROW>
483+
elseif contains(o.GetErrorMsg(), '''data'' field is invalid')
484+
obj.logger.Write('DataFilesClass.ErrorCheck - WARNING: In file "%s" %s. File will not be added to data set\n', obj.files(ii).name, o.GetErrorMsg());
485+
errorIdxs = [errorIdxs, ii]; %#ok<AGROW>
486+
elseif ~isempty(o.GetErrorMsg())
487+
obj.logger.Write('DataFilesClass.ErrorCheck - WARNING: In file "%s" %s. File will be added anyway.\n', obj.files(ii).name, o.GetErrorMsg());
488+
dataflag = true;
483489
else
484490
dataflag = true;
485491
end
492+
if ~isempty(o.GetErrorMsg())
493+
obj.files(ii).SetError(o.GetErrorMsg());
494+
end
486495
hwait = waitbar_improved(ii/length(obj.files), hwait, msg);
487496
end
497+
488498
if dataflag==false
489499
obj.files = FileClass.empty();
490500
else
491501
for jj = 1:length(errorIdxs)
492502
obj.filesErr(end+1) = obj.files(errorIdxs(jj)).copy;
493-
obj.filesErr(end).SetError('Invalid Data Format');
494503
end
495504
obj.files(errorIdxs) = [];
496505
obj.nfiles = obj.nfiles - length(errorIdxs);

DataTree/AcquiredData/DataFiles/DeleteDataFiles.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ function DeleteDataFiles(varargin)
7070
% Get final list of data files
7171
datafiles = mydir(dirname);
7272
if iscell(datafiles0)
73-
for ii=1:length(datafiles0)
73+
for ii = 1:length(datafiles0)
7474
datafiles(ii) = mydir([dirname, datafiles0{ii}]);
7575
end
7676
elseif ischar(datafiles0)
@@ -81,7 +81,7 @@ function DeleteDataFiles(varargin)
8181

8282

8383
% Delete data files
84-
for ii=1:length(datafiles)
84+
for ii = 1:length(datafiles)
8585
if datafiles(ii).isdir
8686
continue;
8787
end

DataTree/AcquiredData/DataFiles/FileClass.m

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
rootdir
2020
err
2121
logger
22-
errmsgs
22+
errmsg
2323
end
2424

2525
methods
@@ -38,9 +38,9 @@
3838
obj.filename = '';
3939
obj.map2group = struct('iGroup',0, 'iSubj',0, 'iSess',0, 'iRun',0);
4040
obj.rootdir = '';
41-
obj.err = -1; % Assume file is not loadable
41+
obj.errmsg = ''; % Assume file is not loadable
4242
obj.logger = InitLogger(logger);
43-
obj.errmsgs = {'Invalid Data Format','Invalid File Name'};
43+
obj.errmsg = '';
4444

4545

4646
if nargin==0
@@ -538,22 +538,19 @@ function NameConflictFixed(obj)
538538

539539
% -----------------------------------------------------
540540
function err = GetError(obj)
541-
err = obj.err;
541+
err = ~isempty(obj.errmsg);
542542
end
543543

544544

545545
% -----------------------------------------------------
546-
function err = SetError(obj, err)
547-
if ischar(err)
548-
err = find(strcmp(obj.errmsgs, err));
549-
end
550-
obj.err = err;
546+
function SetError(obj, errmsg)
547+
obj.errmsg = errmsg;
551548
end
552549

553550

554551
% -----------------------------------------------------
555552
function msg = GetErrorMsg(obj)
556-
msg = obj.errmsgs{abs(obj.err)};
553+
msg = obj.errmsg;
557554
end
558555

559556
end

DataTree/AcquiredData/DataFiles/FileLoadSaveClass.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ function SetError(obj, err)
142142

143143
% -------------------------------------------------------
144144
function err = GetError(obj)
145+
err = [];
146+
if isempty(obj)
147+
return
148+
end
145149
err = obj.err;
146150
end
147151

DataTree/AcquiredData/DataFiles/Hdf5/HDF5_Transpose.m

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
% HDF5 stores them in row-major order. We want to transpose the data to agree
99
% with the file format's storage order.
1010
if (~isrow(val) && ~iscolumn(val)) || ... % Matrices
11-
~isempty(findstr('multidim', options)) || ... % Force multi-dimensional even if vector
12-
~isempty(findstr('2D', options)) % Force 2D even if vector
11+
~isempty(findstr('multidim', options)) || ... % Force multi-dimensional even if vector
12+
~isempty(findstr('2D', options)) || ... % Force 2D even if vector
13+
~isempty(findstr('3D', options)) % Force 3D even if vector
1314

1415
val = permute(val, ndims(val):-1:1);
1516

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
function Snirf2Nirs(rootdir, options)
2+
if ~exist('rootdir','var')
3+
rootdir = pwd;
4+
end
5+
if ~exist('options','var')
6+
options = 'sort';
7+
end
8+
rootdir = filesepStandard(rootdir);
9+
files = DataFilesClass(rootdir, 'snirf');
10+
files = files.files;
11+
for ii = 1:length(files)
12+
if files(ii).IsDir()
13+
continue
14+
end
15+
fname = filesepStandard([files(ii).rootdir, files(ii).name]);
16+
s = SnirfClass(fname);
17+
n = NirsClass(s);
18+
if optionExists(options, 'sort')
19+
n.SortData();
20+
end
21+
[pname, fname] = fileparts(fname);
22+
fnameNew = [filesepStandard(pname), fname, '.nirs'];
23+
fprintf('Converting %s to %s\n', fname, fnameNew)
24+
n.Save(fnameNew);
25+
end
26+
27+

DataTree/AcquiredData/Nirs/NirsClass.m

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,15 @@ function SortStims(obj)
132132
end
133133

134134

135+
% ---------------------------------------------------------
136+
function SortData(obj)
137+
[obj.SD.MeasList, order] = sortrows(obj.SD.MeasList);
138+
obj.d = obj.d(:,order);
139+
[obj.SD.MeasList, order] = sortrows(obj.SD.MeasList,4);
140+
obj.d = obj.d(:,order);
141+
end
142+
143+
135144
% ---------------------------------------------------------
136145
function err = LoadMat(obj, fname, ~)
137146
err = 0;
@@ -468,10 +477,9 @@ function SaveMat(obj, fname, options)
468477

469478
% Always sort stimulus conditions and associated stims
470479
% to have a predictable order for display
471-
objnew.s = obj.s;
472-
obj.SortStims();
473-
480+
objnew.s = obj.s;
474481
objnew.CondNames = obj.CondNames;
482+
objnew.SortStims();
475483
end
476484

477485

@@ -650,25 +658,36 @@ function SetCondNames(obj, val)
650658

651659

652660
% ---------------------------------------------------------
653-
function SD = GetSDG(obj, option)
661+
function SD = GetSDG(obj, ~)
654662
SD = obj.SD;
655663
end
656664

657665

658666
% ---------------------------------------------------------
659-
function ml = GetMeasList(obj, iBlk)
667+
function ml = GetMeasList(obj, ~)
660668
ml = obj.SD.MeasList;
661669
end
662670

663671

672+
% ---------------------------------------------------------
673+
function ml = GetMeasurementList(obj, ~, ~)
674+
ml = MeasListClass();
675+
for ii = 1:size(obj.SD.MeasList,1)
676+
ml(ii).sourceIndex = obj.SD.MeasList(ii,1);
677+
ml(ii).detectorIndex = obj.SD.MeasList(ii,2);
678+
ml(ii).wavelengthIndex = obj.SD.MeasList(ii,4);
679+
end
680+
end
681+
682+
664683
% ---------------------------------------------------------
665684
function wls = GetWls(obj)
666685
wls = obj.SD.Lambda;
667686
end
668687

669688

670689
% ---------------------------------------------------------
671-
function SetStims_MatInput(obj,s,t,CondNames)
690+
function SetStims_MatInput(obj, s, ~, ~)
672691
obj.s = s;
673692
end
674693

@@ -703,13 +722,13 @@ function SetConditions(obj, CondNames)
703722

704723

705724
% ---------------------------------------------------------
706-
function srcpos = GetSrcPos(obj,option)
725+
function srcpos = GetSrcPos(obj, ~)
707726
srcpos = obj.SD.SrcPos;
708727
end
709728

710729

711730
% ---------------------------------------------------------
712-
function detpos = GetDetPos(obj,option)
731+
function detpos = GetDetPos(obj, ~)
713732
detpos = obj.SD.DetPos;
714733
end
715734

@@ -728,13 +747,13 @@ function SetConditions(obj, CondNames)
728747

729748

730749
% ----------------------------------------------------------------------------------
731-
function n = GetDataBlocksNum(obj)
750+
function n = GetDataBlocksNum(~)
732751
n = 1;
733752
end
734753

735754

736755
% ----------------------------------------------------------------------------------
737-
function [iDataBlks, ich] = GetDataBlocksIdxs(obj, ich)
756+
function [iDataBlks, ich] = GetDataBlocksIdxs(~, ich)
738757
iDataBlks = 1;
739758
ich={ich};
740759
end
@@ -882,30 +901,30 @@ function MoveStims(obj, tPts, condition)
882901

883902

884903
% ----------------------------------------------------------------------------------
885-
function SetStimTpts(obj, icond, tpts)
904+
function SetStimTpts(~, ~, ~)
886905
return;
887906
end
888907

889908

890909
% ----------------------------------------------------------------------------------
891-
function tpts = GetStimTpts(obj, icond)
910+
function tpts = GetStimTpts(~, ~)
892911
tpts = [];
893912
end
894913

895914

896915
% ----------------------------------------------------------------------------------
897-
function SetStimDuration(obj, icond, duration)
916+
function SetStimDuration(~, ~, ~)
898917
return;
899918
end
900919

901920
% ----------------------------------------------------------------------------------
902-
function duration = GetStimDuration(obj, icond)
921+
function duration = GetStimDuration(~, ~)
903922
duration = [];
904923
end
905924

906925

907926
% ----------------------------------------------------------------------------------
908-
function SetStimAmplitudes(obj, icond, vals)
927+
function SetStimAmplitudes(~, ~, ~)
909928
return;
910929
end
911930

@@ -1027,7 +1046,7 @@ function RenameCondition(obj, oldname, newname)
10271046

10281047

10291048
% ----------------------------------------------------------------------------------
1030-
function b = CopyProbe(obj, SD)
1049+
function CopyProbe(obj, SD)
10311050
fields = propnames(obj.SD);
10321051
for ii = 1:length(fields)
10331052
if eval( sprintf('isfield(SD, ''%s'')', fields{ii}) )
@@ -1082,15 +1101,19 @@ function ConvertSnirfData(obj, snirf)
10821101
function ConvertSnirfStim(obj, snirf)
10831102
obj.s = zeros(length(obj.t), length(snirf.stim));
10841103
for ii = 1:length(snirf.stim)
1085-
k = round(nearest_point(obj.t, snirf.stim(ii).data(:,1)));
1086-
for jj = 1:length(k)
1087-
if k(jj) == 0
1088-
k(jj) = 1;
1104+
if isempty(snirf.stim(ii).data)
1105+
ik = [];
1106+
else
1107+
[~,ik] = nearest_point(obj.t, snirf.stim(ii).data(:,1));
1108+
end
1109+
for jj = 1:length(ik)
1110+
if ik(jj) == 0
1111+
ik(jj) = 1;
10891112
end
1090-
if k(jj) > length(obj.t)
1091-
k(jj) = length(obj.t);
1113+
if ik(jj) > length(obj.t)
1114+
ik(jj) = length(obj.t);
10921115
end
1093-
obj.s(k(jj),ii) = 1;
1116+
obj.s(ik(jj),ii) = 1;
10941117
end
10951118
obj.CondNames{ii} = snirf.stim(ii).name;
10961119
end
@@ -1127,36 +1150,38 @@ function ErrorCheck(obj)
11271150
obj.SD.SrcGrommetType{ii} = 'none';
11281151
end
11291152
end
1130-
11311153
if isempty(obj.SD.DetGrommetType)
11321154
for ii = 1:size(obj.SD.DetPos,1)
11331155
obj.SD.DetGrommetType{ii} = 'none';
11341156
end
11351157
end
1136-
11371158
if isempty(obj.SD.DummyGrommetType)
11381159
for ii = 1:size(obj.SD.DummyPos,1)
11391160
obj.SD.DummyGrommetType{ii} = 'none';
11401161
end
11411162
end
1142-
11431163
if isempty(obj.SD.SrcGrommetRot)
11441164
for ii = 1:size(obj.SD.SrcPos,1)
11451165
obj.SD.SrcGrommetRot(ii) = 0;
11461166
end
11471167
end
1148-
11491168
if isempty(obj.SD.DetGrommetRot)
11501169
for ii = 1:size(obj.SD.DetPos,1)
11511170
obj.SD.DetGrommetRot(ii) = 0;
11521171
end
11531172
end
1154-
11551173
if isempty(obj.SD.DummyGrommetRot)
11561174
for ii = 1:size(obj.SD.DummyPos,1)
11571175
obj.SD.DummyGrommetRot(ii) = 0;
11581176
end
11591177
end
1178+
if isempty(obj.CondNames)
1179+
for ii = 1:size(obj.s,2)
1180+
if length(obj.s(:,ii)) == length(obj.t)
1181+
obj.CondNames{ii} = num2str(ii);
1182+
end
1183+
end
1184+
end
11601185

11611186
end
11621187

DataTree/AcquiredData/Snirf/AuxClass.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@
110110
end
111111

112112
end
113+
114+
obj.SetError(err);
113115
end
114116

115117

0 commit comments

Comments
 (0)