Skip to content

Commit 67b7c9f

Browse files
jayd1860mayucelJay Dubb
authored
v1.70.0 -- Fix hmrR_PCAFilter mlAct channel order issue; Provide DataTree examples; Fix DataTree standalone issues. (#153)
* Update on AR-GLM code (#148) * v1.59.0 -- Fix retrieving inactive channels in hmrR_PCAFilter.m using the new mlAct supporting user functions. -- Update design doc to document new loading and exporting of stim from and to BIDS events TSV files. * Make standalone DataTree work by supplying missing cell2str.m function to shared library * v1.60.0 -- Include startup functions in setpaths to be able initialize search paths for DataTree. -- Add examples folder with runProcessingStream.m on how to download and run processing stream in DataTree standalone. * v1.61.0 -- Add initialization script to run after downloading DataTree which downloads dependencies Utils and FuncRegistry and runs setpaths for ease of standalone operation -- Add submodules .gitmodules file to DataTree library to stream line process of downloading dependencies when running DataTree standalone -- Provide plotting method for TreeNodeClass elements to run from command line -- Fix typos in .gitmodules and add FuncRegistry as a third submodule/library that Homer3 uses -- Provide LoadRunPlotExamples.m example of how to use DataTree from scratch. -- Add missing description of input argument mlAct in hmrR_PCAFilter.m * v1.61.1 -- Fix typo in DataTree/.gitmodules FuncRegistry entry. This was fixed in the parent (Homer3) .gitmodules but not DataTree. -- In syncSubmodules.m add .gitmodules to the list of file types to search for when syncing parent and submodules * v1.62.0 -- Sync with changes in DataTree and Utils shared libraries: DataTree: 1. Rename LoadRunPlotExamples to LoadRunPlotExample1.m and LoadRunPlotExample2.m - LoadRunPlotExample1 uses TreeNodeClass methods to get access to data and time and plot them, while LoadRunPlotExample2.m does the same thing BUT accesses snirf objects directly without any methods and then plots them directly in the script to show user how snirf objects work. Add example data that goes with it Example4_twNI. 2. Add another example EditStimExample.m which shows how to export and edit stim and conditions. Add example data that goes with it SubjDataSample. 3. Fix bugs in StimClass methods for editing stims (adding, deleting, and changing condition of) based on an inclusive time points vector. 4. Fix run/plot examples and remove the download and initialization parts as that is unnecessary and does not quite makes sense since you have to first download the repo before accessing the LoadRunPlotExamples.m script. This part can simply be described in the comments. 5. Simplify initialization by moving downloading of submodules to setpaths and get rid of initialize.m Utils: 1. Add capability to readTsv.m to be able to load TSV file that is separated by spaces instead of tabs if it is can be clearly determined that spaces are separators (instead of say names of conditions). If spaces are detected then the file is written to correctly contain tab separators as is appropriate for the .tsv format. 2. Add namespace DataTreeClass to setGuiFonts.m so that fonts can be set in a figure when DataTree standalone is running 3. Return figure handle of MenuBox.m so that it can be repositioned after calling it * 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. * Remove obsolete example - merge with bunpc missed this for some reason * v1.67.0 -- Sync with shared libraries Add version number files to libaries. Add common functions getVernum.m and parseGitSubmodulesFile.m which can exist as generic non startup Utils functions Add logging to setpaths to setpaths.log (instead of the previous SystemInfo.log) so its clear where the log file came from. Remove extra log files created unintentionally in DataTree like History.log Return missing support functions to downloadDependencies.m -- Add .csd files to list of files in syncSubmodules.m to sync with shared libraries * v1.68.0 -- Sync with DataTree v1.1.0 shared library : Add error checking to TreeNodeClass.Plot() method when there no data. Clean up zombie figure handles from TreeNodeClass.Plot() method so that handles don't accumulate indefinitely in obj.hFig as more plots are displayed. Return single number indices of plotted channels in TreeNodeClass.Plot() Minor change to LoadRunPlotExample1.m to name the function same as file * v1.69.0 -- Fix another exception in setpaths when removing path with setpaths(0), because Logger and printStack is no longer in path but is not empty. -- Update NirsClass.m to be able to at least load .nirs data setpaths.m -- Update archived user functions for .nirs dataset (hmrE_RunAvg_Nirs, hmrS_SessAvg, etc) for the new BIDS data structure (which has sessions) -- Simplify and clean up initial saving of group structure file groupResults.mat also saving the function call chain which did not get saved initially at time of Homer3 launch. Added initsaveflag to GroupClass and moved call to Save out of Load method and into the calling method DataTreeClass.LoadGroup() after proc stream initialization/copying has been completed and after SetConditions has been called. * -- Minor fix to setpaths logging plus added time stamp when setpaths completed. Sync with same fix in DataTree setpaths. * v1.70.0 -- Sync with shared libraries and AtlasViewer v1.24.0: Replace calls to matlab's built-in function menu() with Utils MenuBox() to fix strange issue with direct use of menu where it generates this error in R2017b and R2020b (and maybe other matlab versions): Error using matlab.ui.Figure/set Error setting property 'Position' of class 'Figure': Width and height must be greater than or equal to 0 Error in menu>local_GUImenu (line 239) set( menuFig, 'Position', [winLeftGap bottom winWide winHigh] ); Error in menu (line 51) k = local_GUImenu( xHeader, ArgsIn ); --------- Co-authored-by: Meryem Ayşe Yücel <[email protected]> Co-authored-by: Jay Dubb <[email protected]>
1 parent c187f58 commit 67b7c9f

Some content is hidden

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

60 files changed

+3389
-545
lines changed

.gitmodules

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
[submodule "Utils/Shared"]
22
path = Utils/Shared
33
url = https://github.com/BUNPC/Utils
4-
[submodule "Group/DataTree"]
4+
[submodule "DataTree"]
55
path = DataTree
66
url = https://github.com/BUNPC/DataTree
7+
[submodule "FuncRegistry"]
8+
path = FuncRegistry
9+
url = https://github.com/BUNPC/FuncRegistry

DataTree/.gitmodules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[submodule "Utils"]
2+
path = Utils
3+
url = https://github.com/BUNPC/Utils
4+
[submodule "FuncRegistry"]
5+
path = FuncRegistry
6+
url = https://github.com/BUNPC/FuncRegistry

DataTree/AcquiredData/AcqDataClass.m

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -213,39 +213,6 @@ function FreeMemory(obj, filename)
213213

214214

215215

216-
% ---------------------------------------------------------
217-
function bbox = GetSdgBbox(obj)
218-
bbox = [];
219-
220-
optpos = [obj.GetSrcPos('2D'); obj.GetDetPos('2D')];
221-
if isempty(optpos)
222-
return
223-
end
224-
225-
xmax = max(optpos(:,1));
226-
ymax = max(optpos(:,2));
227-
228-
xmin = min(optpos(:,1));
229-
ymin = min(optpos(:,2));
230-
231-
width = xmax-xmin;
232-
height = ymax-ymin;
233-
234-
if width==0
235-
width = 1;
236-
end
237-
if height==0
238-
height = 1;
239-
end
240-
241-
px = width * 0.05;
242-
py = height * 0.05;
243-
244-
bbox = [xmin-px, xmax+px, ymin-py, ymax+py];
245-
end
246-
247-
248-
249216
% ----------------------------------------------------------------------------------
250217
function varval = GetVar(obj, varname)
251218
if ismethod(obj,['Get_', varname])

DataTree/AcquiredData/DataFiles/FindFiles.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@
9393
case {'nirs','.nirs'}
9494
files = DataFilesClass(dirnameGroup, 'nirs');
9595
otherwise
96-
q = menu(sprintf('Homer3 only supports file formats: {%s}. Please choose one.', cell2str(supportedFormats(:,1))), ...
97-
'OK','CANCEL');
96+
q = MenuBox(sprintf('Homer3 only supports file formats: {%s}. Please choose one.', cell2str(supportedFormats(:,1))), ...
97+
{'OK','CANCEL'});
9898
if q==2
9999
return;
100100
else

DataTree/AcquiredData/Nirs/NirsClass.m

Lines changed: 109 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ function SortData(obj)
185185

186186
% Optional fields
187187
err = obj.LoadAux(fdata, err);
188-
err = obj.LoadStims(fdata, err);
188+
err = obj.LoadStim(fdata, err);
189189

190190
catch
191191

@@ -261,7 +261,7 @@ function SortData(obj)
261261

262262

263263
% ---------------------------------------------------------
264-
function err = LoadStims(obj, fdata, err)
264+
function err = LoadStim(obj, fdata, err)
265265
if ischar(fdata)
266266
fname = fdata;
267267

@@ -399,6 +399,20 @@ function SaveMat(obj, fname, options)
399399

400400

401401

402+
% --------------------------------------------------------------------
403+
function b = EqualStim(obj, obj2)
404+
b = false;
405+
if length(obj.s) ~= length(obj2.s)
406+
return;
407+
end
408+
if ~all(obj.s(:) == obj2.s(:))
409+
return;
410+
end
411+
b = true;
412+
end
413+
414+
415+
402416
% -------------------------------------------------------
403417
function B = eq(obj, obj2)
404418
B = false;
@@ -466,7 +480,7 @@ function SaveMat(obj, fname, options)
466480
% If we're working off the snirf file instead of loading everything into memory
467481
% then we have to load stim here from file before accessing it.
468482
if strcmpi(obj.GetDataStorageScheme(), 'files')
469-
obj.LoadStims(obj.GetFilename(), 0);
483+
obj.LoadStim(obj.GetFilename(), 0);
470484
end
471485

472486
% Generate new instance of NirsClass
@@ -562,23 +576,41 @@ function SetDataTimeSeries(obj, val)
562576
obj.d = val;
563577
end
564578

579+
565580
% ---------------------------------------------------------
566-
function val = GetDataTimeSeries(obj, ~, iBlk)
567-
val = [];
568-
if ~exist('iBlk','var') || isempty(iBlk)
569-
iBlk=1;
581+
function [d, t, ml] = GetDataTimeSeries(obj, options, ~)
582+
d = obj.d;
583+
t = obj.t;
584+
ml = obj.GetMeasurementList(options);
585+
end
586+
587+
588+
% ---------------------------------------------------------
589+
function ml = GetMeasurementList(obj, matrixMode, ~)
590+
if ~exist('matrixMode','var')
591+
matrixMode = '';
592+
end
593+
if strcmpi(matrixMode, 'matrix')
594+
ml = obj.SD.MeasList;
595+
else
596+
ml = MeasListClass();
597+
for ii = 1:size(obj.SD.MeasList,1)
598+
ml(ii).sourceIndex = obj.SD.MeasList(ii,1);
599+
ml(ii).detectorIndex = obj.SD.MeasList(ii,2);
600+
ml(ii).dataTypeIndex = 0;
601+
ml(ii).wavelengthIndex = obj.SD.MeasList(ii,4);
570602
end
571-
if iBlk>1
572-
return
573603
end
574-
val = obj.d;
575604
end
576605

606+
607+
577608
% ---------------------------------------------------------
578609
function SetTime(obj, val)
579610
obj.t = val;
580611
end
581612

613+
582614
% ---------------------------------------------------------
583615
function val = GetTime(obj, iBlk)
584616
val = [];
@@ -588,26 +620,31 @@ function SetTime(obj, val)
588620
val = obj.t;
589621
end
590622

623+
591624
% ---------------------------------------------------------
592625
function val = GetSD(obj)
593626
val = obj.SD;
594627
end
595628

629+
596630
% ---------------------------------------------------------
597631
function SetS(obj, val)
598632
obj.s = val;
599633
end
600634

635+
601636
% ---------------------------------------------------------
602637
function val = GetS(obj)
603638
val = obj.s;
604639
end
605640

641+
606642
% ---------------------------------------------------------
607643
function SetAux(obj, val)
608644
obj.aux = val;
609645
end
610646

647+
611648
% ---------------------------------------------------------
612649
function val = GetAux(obj, options)
613650
if ~exist('options','var')
@@ -627,17 +664,50 @@ function SetAux(obj, val)
627664
end
628665

629666

630-
631667
% ---------------------------------------------------------
632668
function SetCondNames(obj, val)
633669
obj.CondNames = val;
634670
end
635671

672+
636673
% ---------------------------------------------------------
637674
function val = GetCondNames(obj)
638675
val = obj.CondNames;
639676
end
640677

678+
679+
% ---------------------------------------------------------
680+
function bbox = GetSdgBbox(obj)
681+
bbox = [];
682+
683+
optpos = [obj.SD.SrcPos; obj.SD.DetPos];
684+
% optpos = [obj.SD.SrcPos; obj.SD.DetPos; obj.SD.DummyPos];
685+
if isempty(optpos)
686+
return
687+
end
688+
689+
xmax = max(optpos(:,1));
690+
ymax = max(optpos(:,2));
691+
692+
xmin = min(optpos(:,1));
693+
ymin = min(optpos(:,2));
694+
695+
width = xmax-xmin;
696+
height = ymax-ymin;
697+
698+
if width==0
699+
width = 1;
700+
end
701+
if height==0
702+
height = 1;
703+
end
704+
705+
px = width * 0.05;
706+
py = height * 0.05;
707+
708+
bbox = [xmin-px, xmax+px, ymin-py, ymax+py];
709+
end
710+
641711
end
642712

643713

@@ -669,17 +739,6 @@ function SetCondNames(obj, val)
669739
end
670740

671741

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-
683742
% ---------------------------------------------------------
684743
function wls = GetWls(obj)
685744
wls = obj.SD.Lambda;
@@ -917,6 +976,7 @@ function SetStimDuration(~, ~, ~)
917976
return;
918977
end
919978

979+
920980
% ----------------------------------------------------------------------------------
921981
function duration = GetStimDuration(~, ~)
922982
duration = [];
@@ -929,6 +989,7 @@ function SetStimAmplitudes(~, ~, ~)
929989
end
930990

931991

992+
932993
% ----------------------------------------------------------------------------------
933994
function vals = GetStimAmplitudes(obj, icond)
934995
vals = [];
@@ -951,6 +1012,8 @@ function RenameCondition(obj, oldname, newname)
9511012
obj.SortStims();
9521013
end
9531014

1015+
1016+
9541017
% ----------------------------------------------------------------------------------
9551018
function nbytes = MemoryRequired(obj)
9561019
nbytes = 0;
@@ -1056,6 +1119,13 @@ function CopyProbe(obj, SD)
10561119
end
10571120

10581121

1122+
% -------------------------------------------------------
1123+
function CopyStim(obj, obj2)
1124+
obj.s = obj2.s;
1125+
obj.CondNames = obj2.CondNames;
1126+
end
1127+
1128+
10591129
% ----------------------------------------------------------------------------------
10601130
function b = CopyStruct(obj, s)
10611131
fields = propnames(obj);
@@ -1200,6 +1270,23 @@ function ErrorCheck(obj)
12001270
end
12011271

12021272

1273+
% -------------------------------------------------------
1274+
function changes = StimChangesMade(obj)
1275+
% Load stims from file
1276+
nirs = NirsClass();
1277+
nirs.SetFilename(obj.GetFilename())
1278+
nirs.LoadStim(obj.GetFilename());
1279+
changes = ~obj.EqualStim(nirs);
1280+
end
1281+
1282+
1283+
1284+
% -------------------------------------------------------
1285+
function b = DataModified(obj)
1286+
b = obj.StimChangesMade();
1287+
end
1288+
1289+
12031290
end
12041291

12051292
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

DataTree/AcquiredData/Snirf/DataClass.m

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,10 @@ function SaveHdf5(obj, fileobj, location)
494494
% will follow this order in linear form. That is, the order of ml will index the columns
495495
% of d squeezed into 2 dimensions d(:,:)
496496
%
497-
% 'matrix' - dataTimeSeries will not be modified but ml will be returned as a 2D matrix instead of a
498-
% MeasListClass structure. It's rows will have the same order as the structure elements.
497+
% 'matrix' - This options refers to the measurement list type: if 'matrix' keyword is in the options
498+
% then ml will be returned as a 2D matrix instead of a MeasListClass object (that is the
499+
% object representing the measurementList SNIRF field). The rows of the 2d array will have
500+
% the same order as the original MeasListClass object elements.
499501
%
500502
% 'datatype' - used in combination with reshape. dataTimeSeries will be reshaped as above but the
501503
% slowest dimensions to change will be reversed from left-to-right, that is,
@@ -510,7 +512,7 @@ function SaveHdf5(obj, fileobj, location)
510512
% %%%% 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.
511513
%
512514
%
513-
% % Example 1: Return OD dataTimeSeries, time and measurementList unchanged.
515+
% % Example 1: Return OD dataTimeSeries, time and measurementList (ml) unchanged, that is, as a MeasListClass object instead of Nx4 2D array.
514516
% [d, t, ml, order] = dod.GetDataTimeSeries();
515517
%
516518
%

DataTree/AcquiredData/Snirf/ProbeClass.m

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,40 @@ function SaveHdf5(obj, fileobj, location)
523523
b = true;
524524
end
525525

526+
527+
528+
% ---------------------------------------------------------
529+
function bbox = GetSdgBbox(obj)
530+
bbox = [];
531+
532+
optpos = [obj.GetSrcPos('2D'); obj.GetDetPos('2D')];
533+
if isempty(optpos)
534+
return
535+
end
536+
537+
xmax = max(optpos(:,1));
538+
ymax = max(optpos(:,2));
539+
540+
xmin = min(optpos(:,1));
541+
ymin = min(optpos(:,2));
542+
543+
width = xmax-xmin;
544+
height = ymax-ymin;
545+
546+
if width==0
547+
width = 1;
548+
end
549+
if height==0
550+
height = 1;
551+
end
552+
553+
px = width * 0.05;
554+
py = height * 0.05;
555+
556+
bbox = [xmin-px, xmax+px, ymin-py, ymax+py];
557+
end
558+
559+
526560
end
527561

528562
end

0 commit comments

Comments
 (0)