Skip to content

Commit 448762b

Browse files
authored
Merge v1.72.0: Fix for ar_glm_final.m stepwise error in GLM and fix for export of proc stream mlActMan (#162)
Merge v1.72.0: Fix for ar_glm_final.m stepwise error in GLM and fix for export of proc stream mlActMan
1 parent 40bb3ca commit 448762b

File tree

17 files changed

+253
-43
lines changed

17 files changed

+253
-43
lines changed

DataTree/AcquiredData/Nirs/NirsClass.m

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ function SaveMat(obj, fname, options)
388388
return;
389389
end
390390
else
391-
if eval( sprintf('~all( (obj.SD.%s(:) - obj2.SD.%s(:)) < EPS )', field, field) )
391+
if eval( sprintf('~all( abs(obj.SD.%s(:) - obj2.SD.%s(:)) < EPS )', field, field) )
392392
return;
393393
end
394394
end
@@ -1033,6 +1033,7 @@ function RenameCondition(obj, oldname, newname)
10331033
end
10341034

10351035

1036+
10361037
% ----------------------------------------------------------------------------------
10371038
function SD = InitProbe(obj)
10381039
SD = struct(...
@@ -1049,7 +1050,6 @@ function RenameCondition(obj, oldname, newname)
10491050
'SrcGrommetRot',[], ...
10501051
'DetGrommetRot',[], ...
10511052
'DummyGrommetRot',[], ...
1052-
'nDummys',0, ...
10531053
'Landmarks',obj.InitLandmarks(), ...
10541054
'Landmarks2D',obj.InitLandmarks(), ...
10551055
'Landmarks3D',obj.InitLandmarks(), ...
@@ -1069,6 +1069,59 @@ function RenameCondition(obj, oldname, newname)
10691069

10701070

10711071

1072+
% ----------------------------------------------------------------------------------
1073+
function SetProbeSpatialUnit(obj, spatialUnitNew)
1074+
scaling = 1;
1075+
if strcmpi(spatialUnitNew,'mm')
1076+
if strcmpi(obj.SD.SpatialUnit,'cm')
1077+
scaling = 10;
1078+
end
1079+
elseif strcmpi(spatialUnitNew,'cm')
1080+
if strcmpi(obj.SD.SpatialUnit,'mm')
1081+
scaling = 1/10;
1082+
end
1083+
else
1084+
spatialUnitNew = '';
1085+
end
1086+
obj.SD.SpatialUnit = spatialUnitNew;
1087+
obj.SD.SrcPos = obj.SD.SrcPos * scaling;
1088+
obj.SD.DetPos = obj.SD.DetPos * scaling;
1089+
obj.SD.DummyPos = obj.SD.DummyPos * scaling;
1090+
if size(obj.SD.SpringList,2)==3
1091+
lst = find(obj.SD.SpringList(:,3)~=-1);
1092+
obj.SD.SpringList(lst,3) = obj.SD.SpringList(lst,3) * scaling;
1093+
end
1094+
obj.SD.Landmarks.pos = obj.SD.Landmarks.pos * scaling;
1095+
obj.SD.Landmarks3D.pos = obj.SD.Landmarks3D.pos * scaling;
1096+
obj.SD.Landmarks2D.pos = obj.SD.Landmarks2D.pos * scaling;
1097+
end
1098+
1099+
1100+
1101+
% ----------------------------------------------------------------------------------
1102+
function FixProbeSpatialUnit(obj)
1103+
if isempty(obj.SD.SpatialUnit)
1104+
q = MenuBox('Spatial units not provided in probe data. Please specify spatial units of the optode coordinates?', ...
1105+
{'mm','cm',sprintf('do not know')});
1106+
if q==1
1107+
obj.SD.SpatialUnit = 'mm';
1108+
elseif q==2
1109+
obj.SD.SpatialUnit = 'cm';
1110+
elseif q==3
1111+
obj.SD.SpatialUnit = '';
1112+
end
1113+
end
1114+
if ~strcmpi(obj.SD.SpatialUnit,'mm')
1115+
q = MenuBox(sprintf('This probe uses ''%s'' units for probe coordinates. We recommend converting to ''mm'' units, to be consistent with Homer. Do you want to convert probe coordinates from %s to mm?', ...
1116+
obj.SD.SpatialUnit), {'YES','NO'}, 'upperleft');
1117+
if q==1
1118+
obj.SetProbeSpatialUnit('mm')
1119+
end
1120+
end
1121+
end
1122+
1123+
1124+
10721125
% ----------------------------------------------------------------------------------
10731126
function b = IsProbeValid(obj)
10741127
b = false;
@@ -1113,11 +1166,70 @@ function CopyProbe(obj, SD)
11131166
fields = propnames(obj.SD);
11141167
for ii = 1:length(fields)
11151168
if eval( sprintf('isfield(SD, ''%s'')', fields{ii}) )
1169+
if eval( sprintf('strcmp(class(obj.SD.%s), class(SD.%s))', fields{ii}, fields{ii}) )
11161170
eval( sprintf('obj.SD.%s = SD.%s;', fields{ii}, fields{ii}) );
1171+
elseif eval( sprintf('isnumeric(obj.SD.%s) && iscell(SD.%s)', fields{ii}, fields{ii}) )
1172+
if eval( sprintf('~isempty(SD.%s)', fields{ii}) )
1173+
eval( sprintf('obj.SD.%s = cell2array(SD.%s);', fields{ii}, fields{ii}) );
11171174
end
1175+
elseif eval( sprintf('isscalar(obj.SD.%s) && isscalar(SD.%s)', fields{ii}, fields{ii}) )
1176+
eval( sprintf('obj.SD.%s = SD.%s;', fields{ii}, fields{ii}) );
1177+
end
1178+
end
1179+
end
1180+
1181+
% Fill in any fields that don't conform to standard SD data structure
1182+
1183+
% SrcGrommetType
1184+
d1 = size(obj.SD.SrcPos,1) - length(obj.SD.SrcGrommetType);
1185+
if d1 > 0
1186+
obj.SD.SrcGrommetType(end+1:end+d1) = repmat({'none'}, d1, 1);
11181187
end
1188+
1189+
% SrcGrommetRot
1190+
d2 = size(obj.SD.SrcPos,1) - length(obj.SD.SrcGrommetRot);
1191+
if d2 > 0
1192+
obj.SD.SrcGrommetRot(end+1:end+d2) = zeros(d2,1);
1193+
end
1194+
1195+
% DetGrommetType
1196+
d1 = size(obj.SD.DetPos,1) - length(obj.SD.DetGrommetType);
1197+
if d1 > 0
1198+
obj.SD.DetGrommetType(end+1:end+d1) = repmat({'none'}, d1, 1);
1199+
end
1200+
1201+
% DetGrommetRot
1202+
d2 = size(obj.SD.DetPos,1) - length(obj.SD.DetGrommetRot);
1203+
if d2 > 0
1204+
obj.SD.DetGrommetRot(end+1:end+d2) = zeros(d2,1);
1205+
end
1206+
1207+
% DummyGrommetType
1208+
d1 = size(obj.SD.DummyPos,1) - length(obj.SD.DummyGrommetType);
1209+
if d1 > 0
1210+
obj.SD.DummyGrommetType(end+1:end+d1) = repmat({'none'}, d1, 1);
1211+
end
1212+
1213+
% DummyGrommetRot
1214+
d2 = size(obj.SD.DummyPos,1) - length(obj.SD.DummyGrommetRot);
1215+
if d2 > 0
1216+
obj.SD.DummyGrommetRot(end+1:end+d2) = zeros(d2,1);
1217+
end
1218+
1219+
% MesListAct
1220+
if size(obj.SD.MeasListAct,1) < size(obj.SD.MeasList,1)
1221+
d = size(obj.SD.MeasListAct,1) - size(obj.SD.MeasList,1);
1222+
if d < 0
1223+
obj.SD.MeasListAct(end+1:end+abs(d)) = ones(abs(d),1);
1224+
elseif d>1
1225+
obj.SD.MeasListAct(end-d:end) = [];
1226+
end
11191227
end
11201228

1229+
end
1230+
1231+
1232+
11211233

11221234
% -------------------------------------------------------
11231235
function CopyStim(obj, obj2)
@@ -1127,7 +1239,7 @@ function CopyStim(obj, obj2)
11271239

11281240

11291241
% ----------------------------------------------------------------------------------
1130-
function b = CopyStruct(obj, s)
1242+
function CopyStruct(obj, s)
11311243
fields = propnames(obj);
11321244
for ii = 1:length(fields)
11331245
if eval( sprintf('isfield(s, ''%s'')', fields{ii}) )

DataTree/AcquiredData/Snirf/DataClass.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,9 @@ function SaveHdf5(obj, fileobj, location)
771771
ml = obj.measurementList;
772772
ml(order) = ml;
773773
end
774+
if contains(options, 'reshape')
775+
ml = measurementListSDpairs;
776+
end
774777

775778
obj.SimulateErrors(d);
776779
end

DataTree/AcquiredData/Snirf/MetaDataTagsClass.m

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
obj.tags.LengthUnit = 'mm';
1717
obj.tags.TimeUnit = 'unknown';
1818
obj.tags.FrequencyUnit = 'unknown';
19-
obj.tags.AppName = 'snirf-homer3';
20-
19+
obj.tags.AppName = 'homer3-DataTree';
20+
2121
if nargin==1 && ~isempty(varargin{1})
2222
obj.SetFilename(varargin{1});
2323
obj.Load();
@@ -83,7 +83,7 @@
8383

8484
end
8585
obj.SetError(err);
86-
86+
8787
end
8888

8989

@@ -105,8 +105,8 @@ function SaveHdf5(obj, fileobj, location) %#ok<*INUSD>
105105
fid = H5F.create(fileobj, 'H5F_ACC_TRUNC', 'H5P_DEFAULT', 'H5P_DEFAULT');
106106
H5F.close(fid);
107107
end
108-
props = propnames(obj.tags);
109-
for ii=1:length(props)
108+
props = propnames(obj.tags);
109+
for ii = 1:length(props)
110110
eval(sprintf('hdf5write_safe(fileobj, [location, ''/%s''], obj.tags.%s);', props{ii}, props{ii}));
111111
end
112112
end

DataTree/AcquiredData/Snirf/ProbeClass.m

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
landmarkLabels
2121
end
2222

23+
properties (Access = private)
24+
scaling
25+
end
26+
2327

2428

2529
methods
@@ -28,11 +32,13 @@
2832
function obj = ProbeClass(varargin)
2933
% Set class properties not part of the SNIRF format
3034
obj.SetFileFormat('hdf5');
35+
obj.scaling = 1;
3136

3237
% Set SNIRF fomat properties
3338
if nargin>0
3439
if isstruct(varargin{1})
35-
SD = varargin{1};
40+
n = NirsClass(varargin{1});
41+
SD = n.SD;
3642
obj.wavelengths = SD.Lambda;
3743
obj.wavelengthsEmission = [];
3844
if isfield(SD,'SrcPos2D') & ~isempty(SD.SrcPos2D)
@@ -250,18 +256,16 @@ function Project_3D_to_2D(obj)
250256
end
251257

252258
% Arg3
253-
scaling = 1;
254259
if exist('LengthUnit','var')
255-
if strcmpi(LengthUnit,'m')
256-
scaling = 1000;
257-
elseif strcmpi(LengthUnit,'cm')
258-
scaling = 10;
260+
% Figure out the scaling factor to multiple by to get the coorinates to be in mm units
261+
if strcmpi(LengthUnit,'m') % meter units
262+
obj.scaling = 100;
263+
elseif strcmpi(LengthUnit,'cm') % centimeter units
264+
obj.scaling = 10;
259265
end
260266
end
261267

262268

263-
264-
265269
% Error checking
266270
if ~isempty(fileobj) && ischar(fileobj)
267271
obj.SetFilename(fileobj);
@@ -280,12 +284,12 @@ function Project_3D_to_2D(obj)
280284
% Load datasets
281285
obj.wavelengths = HDF5_DatasetLoad(gid, 'wavelengths');
282286
obj.wavelengthsEmission = HDF5_DatasetLoad(gid, 'wavelengthsEmission');
283-
obj.sourcePos2D = HDF5_DatasetLoad(gid, 'sourcePos2D', [], '2D')*scaling;
284-
obj.detectorPos2D = HDF5_DatasetLoad(gid, 'detectorPos2D', [], '2D')*scaling;
285-
obj.landmarkPos2D = HDF5_DatasetLoad(gid, 'landmarkPos2D', [], '2D')*scaling;
286-
obj.sourcePos3D = HDF5_DatasetLoad(gid, 'sourcePos3D', [], '3D')*scaling;
287-
obj.detectorPos3D = HDF5_DatasetLoad(gid, 'detectorPos3D', [], '3D')*scaling;
288-
obj.landmarkPos3D = HDF5_DatasetLoad(gid, 'landmarkPos3D', [], '2D')*scaling;
287+
obj.sourcePos2D = HDF5_DatasetLoad(gid, 'sourcePos2D', [], '2D') * obj.scaling;
288+
obj.detectorPos2D = HDF5_DatasetLoad(gid, 'detectorPos2D', [], '2D') * obj.scaling;
289+
obj.landmarkPos2D = HDF5_DatasetLoad(gid, 'landmarkPos2D', [], '2D') * obj.scaling;
290+
obj.sourcePos3D = HDF5_DatasetLoad(gid, 'sourcePos3D', [], '3D') * obj.scaling;
291+
obj.detectorPos3D = HDF5_DatasetLoad(gid, 'detectorPos3D', [], '3D') * obj.scaling;
292+
obj.landmarkPos3D = HDF5_DatasetLoad(gid, 'landmarkPos3D', [], '2D') * obj.scaling;
289293
obj.frequencies = HDF5_DatasetLoad(gid, 'frequencies');
290294
obj.timeDelays = HDF5_DatasetLoad(gid, 'timeDelays');
291295
obj.timeDelayWidths = HDF5_DatasetLoad(gid, 'timeDelayWidths');
@@ -350,6 +354,16 @@ function SaveHdf5(obj, fileobj, location)
350354
H5F.close(fid);
351355
end
352356

357+
% Multiple all coordinates by reciprocal of scaling factor when saving to get the
358+
% coordinates back to original.
359+
obj.sourcePos2D = obj.sourcePos2D / obj.scaling;
360+
obj.detectorPos2D = obj.detectorPos2D / obj.scaling;
361+
obj.landmarkPos2D = obj.landmarkPos2D / obj.scaling;
362+
obj.sourcePos3D = obj.sourcePos3D / obj.scaling;
363+
obj.detectorPos3D = obj.detectorPos3D / obj.scaling;
364+
obj.landmarkPos3D = obj.landmarkPos3D / obj.scaling;
365+
366+
% Now save
353367
hdf5write_safe(fileobj, [location, '/wavelengths'], obj.wavelengths, 'array');
354368
hdf5write_safe(fileobj, [location, '/wavelengthsEmission'], obj.wavelengthsEmission, 'array');
355369
hdf5write_safe(fileobj, [location, '/sourcePos2D'], obj.sourcePos2D, 'array');

DataTree/AcquiredData/Snirf/SnirfClass.m

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,6 @@ function SortStims(obj)
516516
LengthUnit = obj.metaDataTags.Get('LengthUnit');
517517
obj.probe = ProbeClass();
518518
err = obj.probe.LoadHdf5(fileobj, [obj.location, '/probe'], LengthUnit);
519-
obj.metaDataTags.Set('LengthUnit','mm');
520519

521520
% This is a required field. If it's empty means the whole snirf object is bad
522521
if isempty(obj.probe)

DataTree/GroupClass.m

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171

7272
% ----------------------------------------------------------------------------------
7373
function InitVersion(obj)
74-
obj.SetVersion();
74+
obj.SetVersion(getVernum('DataTree'));
7575
obj.InitVersionStrFull();
7676
end
7777

@@ -848,15 +848,6 @@ function SaveAcquiredData(obj)
848848
% ----------------------------------------------------------------------------------
849849
function probe = GetProbe(obj)
850850
probe = obj.subjs(1).GetProbe();
851-
% for subj = obj.subjs
852-
% for sess = subj.sess
853-
% for run = sess.runs
854-
% if ~(probe == run.GetProbe())
855-
% warning(['Probe ', run.name, ' differs from ', obj.subjs(1).sess(1).runs(1).name])
856-
% end
857-
% end
858-
% end
859-
% end
860851
end
861852

862853

@@ -1133,7 +1124,11 @@ function BackwardCompatability(obj)
11331124
if ~ispathvalid([obj.path, obj.outputDirname])
11341125
mkdir([obj.path, obj.outputDirname]);
11351126
end
1136-
movefile(oldDerivedPath, [obj.path, obj.outputDirname])
1127+
1128+
try
1129+
movefile(oldDerivedPath, [obj.path, obj.outputDirname])
1130+
catch
1131+
end
11371132

11381133
if ispathvalid([obj.path, obj.outputDirname, obj.outputFilename])
11391134
if ~strcmp(obj.outputFilename, 'groupResults.mat')

DataTree/ProcStream/ProcStreamClass.m

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,10 +376,16 @@ function SaveInitOutput(obj, pathname, filename)
376376
% ----------------------------------------------------------------------------------
377377
function mlActMan = CompressMlActMan(obj)
378378
mlActMan = [];
379-
if isempty(obj.input.mlActMan)
379+
380+
% We don't need to compress mlAct man because it is usually not that big
381+
% But even did then we have to modify compressLogicalArray to handle 2d arrays
382+
% instead of just vectors.
383+
% mlActMan = compressLogicalArray(obj.input.mlActMan{1});
384+
temp = obj.GetVar('mlActMan');
385+
if isempty(temp)
380386
return
381387
end
382-
mlActMan = compressLogicalArray(obj.input.mlActMan{1});
388+
mlActMan = temp{1};
383389
end
384390

385391

DataTree/RunClass.m

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,28 @@ function InitMlVis(obj, iBlk)
520520

521521

522522

523+
% ----------------------------------------------------------------------------------
524+
function mlAct = GetActiveChannels(obj)
525+
% Load to memory if needed
526+
err = -1;
527+
if obj.procStream.output.IsEmpty()
528+
obj.Load();
529+
err = 0;
530+
end
531+
532+
mlAct = obj.GetVar('mlActAuto');
533+
if ~isempty(mlAct)
534+
mlAct = mlAct{1};
535+
end
536+
537+
% Free memory
538+
if err==0
539+
obj.FreeMemory();
540+
end
541+
end
542+
543+
544+
523545
% ----------------------------------------------------------------------------------
524546
function SetStims_MatInput(obj, s, t, CondNames)
525547
obj.procStream.SetStims_MatInput(s, t, CondNames);

0 commit comments

Comments
 (0)