Commit a82e33e3 authored by Jay Dubb's avatar Jay Dubb
Browse files

v.1.23.1

-- Step 2 in allowing acquired file data such as stimulus conditions to be modified through a separate save procedure. Finished implementing this feature.
-- Add HDF5_DatasetWrite which allows overwriting of chunked datasets. This is what allows tims to be updated in a SNIF file after file creation.
-- Consolidate StimEditGUI file into one file (StimEditGUI.m).
-- Add small button to upper right corner of MainGUI.fig to easily shrink or expand GUI to fixed standard sizes, without having to resize by dragging mouse.
parent a0260163
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -23,4 +23,8 @@ on
% Data Storage Scheme
file

% Auto Save Acquisition Files
Yes


% END
+101 −0
Original line number Diff line number Diff line
function err = HDF5_DatasetWrite(fname, location, data)

if exist(fname,'file')
    fid = H5F.open(fname, 'H5F_ACC_RDWR', 'H5P_DEFAULT');
else
    fid = H5F.create(fname, 'H5F_ACC_TRUNC', 'H5P_DEFAULT', 'H5P_DEFAULT');
end
if fid<0
    err = -1;
    return;
end

% Create group where dataset is located
group = filesepStandard(fileparts(location), 'nameonly');
gid = CreateGroup(fid, group);
if gid < 0
    err = -1;
    return;
end

% Update dataset
err = WriteDataset(fid, location, data);




% ----------------------------------------------------------------
function gid = CreateGroup(fid, group)
if group == '/'
    gid = H5G.open(fid, '/');
    return;
end

try
    gid = H5G.open(fid, group);
catch
    [rootgroup, group] = filesepStandard(fileparts(group));
    gid = CreateGroup(fid, rootgroup);
    gid = H5G.create(gid, group, 'H5P_DEFAULT','H5P_DEFAULT','H5P_DEFAULT');
end



% --------------------------------------------------------------
function err = WriteDataset(fid, location, data)

err = 0;

% data = HDF5_Transpose(data);
dims = size(data);
h5_dims = fliplr(dims);
unlimited = H5ML.get_constant_value('H5S_UNLIMITED');
h5_maxdims = [unlimited, unlimited];

if isnumeric(data)
    type_id = H5T.copy('H5T_NATIVE_DOUBLE');
elseif ischar(data)
    type_id = H5T.copy('H5T_C_S1'); 
else
    err = -1;
    return;
end

space_id = H5S.create_simple(2, h5_dims, h5_maxdims);
proplist_id = H5P.create('H5P_DATASET_CREATE');

% Open or create dataset
try
    dset_id = H5D.open(fid, location);
    H5D.set_extent(dset_id, h5_dims);
catch
    H5P.set_chunk(proplist_id, h5_dims);
    dset_id = H5D.create(fid, location, type_id, space_id, proplist_id);
end
file_space_id = H5D.get_space(dset_id);

% Write dataset
% H5D.write(dset_id, type_id, space_id, file_space_id, proplist_id, data);
H5D.write(dset_id, type_id, space_id, file_space_id, 'H5P_DEFAULT', data);

% Close space, type, dataset and file
H5S.close(space_id);
H5T.close(type_id);
H5D.close(dset_id);
H5F.close(fid);



% ----------------------------------------------------------------
function [dset_id, type_id, space_id, proplist_id] = CreateDataset(fid, location, h5_dims)

h5_maxdims = h5_dims;

type_id = H5T.copy('H5T_NATIVE_DOUBLE');
space_id = H5S.create_simple(2, h5_dims, h5_maxdims);
proplist_id = H5P.create('H5P_DATASET_CREATE');
H5P.set_chunk(proplist_id, [h5_dims(1), h5_dims(2)]);

dset_id = H5D.create(fid, location, type_id, space_id, proplist_id);

+1 −1
Original line number Diff line number Diff line
function HDF5_WriteStrings(fname, location, data)
function HDF5_DatasetWriteStrings(fname, location, data)

if ~exist(fname, 'file')
    fid = H5F.create(fname, 'H5F_ACC_TRUNC', 'H5P_DEFAULT', 'H5P_DEFAULT');
+2 −13
Original line number Diff line number Diff line
@@ -9,23 +9,12 @@ if ~exist('options','var')
end

if iscell(val)
    HDF5_WriteStrings(fname, name, val)
    HDF5_DatasetWriteStrings(fname, name, val)
else
    val = HDF5_Transpose(val, options);
    try
        if ~isempty(findstr('rw', options))
            try
                % For datasets that are writeable AFTER they are created
                % there's we need to have a separte create step where we can provide the
                % dimensions and chunk size. Since there's no way to test to see if dataset
                % already exists, we use try/catch by attempting to create the data set
                % and no harm done if it exists and we catch the exception.
                dims = size(val);
                h5create(fname, name, [dims(1), Inf], 'ChunkSize',[dims(1), 64]);
            catch
                % Dataset already exists. move on...
            end
            h5write(fname, name, val, [1,1], dims);
            HDF5_DatasetWrite(fname, name, val);
        else
            hdf5write(fname, name, val, 'WriteMode','append');
        end
+163 −154
Original line number Diff line number Diff line
@@ -9,12 +9,13 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
        aux
    end
    
    properties (Access = private)
    properties (Access = public)
        fid
        gid
        location
        nirsdatanum
        nirs_tb;
        stim0
    end
    
    methods
@@ -240,6 +241,8 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
            obj.stim           = StimClass().empty();
            obj.probe          = ProbeClass().empty();
            obj.aux            = AuxClass().empty();
            
            obj.stim0          = StimClass().empty();
        end
        
        
@@ -256,6 +259,11 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
            obj.stim          = CopyHandles(obj2.stim);
            obj.probe         = CopyHandles(obj2.probe);
            obj.aux           = CopyHandles(obj2.aux);
            
            try
                obj.stim0     = CopyHandles(obj2.stim0);
            catch
            end
        end
        
        
@@ -371,25 +379,15 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
        
        
        % -------------------------------------------------------
        function err = LoadStim(obj, fileobj, options)
        function err = LoadStim(obj, fileobj)
            err = 0;
            if ~exist('options','var')
                options = '';
            end
            
            paramName = 'stim';
            if optionExists(options, 'original') || optionExists(options, 'orig')
                paramName = 'stim0';
            end
            
            % Since we want to load stims in sorted order (i.e., according to alphabetical order
            % of condition names), first load to temporary variable.
            ii=1;
            while 1
                if ii > length(obj.stim)
                    obj.stim(ii) = StimClass;
                end
                if obj.stim(ii).LoadHdf5(fileobj, [obj.location, '/', paramName, num2str(ii)]) < 0
                if obj.stim(ii).LoadHdf5(fileobj, [obj.location, '/stim', num2str(ii)]) < 0
                    obj.stim(ii).delete();
                    obj.stim(ii) = [];
                    if ii==1
@@ -400,6 +398,21 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
                ii=ii+1;
            end
            obj.SortStims();
            
            % Load original, unedited stims, if they exist
            ii=1;
            while 1
                if ii > length(obj.stim0)
                    obj.stim0(ii) = StimClass;
                end
                if obj.stim0(ii).LoadHdf5(fileobj, [obj.location, '/stim0', num2str(ii)]) < 0
                    obj.stim0(ii).delete();
                    obj.stim0(ii) = [];
                    break;
                end
                ii=ii+1;
            end
            
        end
        
        
@@ -435,7 +448,7 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
        
        
        % -------------------------------------------------------
        function err = LoadHdf5(obj, fileobj, params)
        function err = LoadHdf5(obj, fileobj, ~)
            err = 0;
            
            % Arg 1
@@ -535,18 +548,15 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
        
        
        % -------------------------------------------------------
        function SaveStim(obj, fileobj, options)
            if ~exist('options','var')
                options = '';
        function SaveStim(obj, fileobj)
            for ii=1:length(obj.stim)
                obj.stim(ii).SaveHdf5(fileobj, [obj.location, '/stim', num2str(ii)]);
            end
            
            paramName = 'stim';
            if optionExists(options, 'original') || optionExists(options, 'orig')
                paramName = 'stim0';
            if isempty(obj.stim0)
                obj.stim0 = obj.stim.copy();
                for ii=1:length(obj.stim0)
                    obj.stim0(ii).SaveHdf5(fileobj, [obj.location, '/stim0', num2str(ii)]);
                end

            for ii=1:length(obj.stim)
                obj.stim(ii).SaveHdf5(fileobj, [obj.location, '/', paramName, num2str(ii)]);
            end
        end
        
@@ -606,28 +616,19 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
        
        
        % -------------------------------------------------------
        function [changes, stim0] = UpdateStim(obj, fileobj)
        function [stimFromFile, changes] = UpdateStim(obj, fileobj)
            flags = zeros(length(obj.stim), 1);
            
            % Load original unedited stim, rename it and save it if it
            % doesn't already exist
            snirf = SnirfClass();
            snirf.LoadStim(fileobj, 'orig');
            if snirf.stim.Error()<0  
                obj.stim.SaveStim('orig');
            end
            
            % Now load current stim from file and update it
            snirf.LoadStim(fileobj);
            stim0 = snirf.stim;
            % Load stim from file and update it
            snirfFile = SnirfClass();
            snirfFile.LoadStim(fileobj);
            
            % Update original stims from file with edited stims
            % Update stims from file with edited stims
            for ii = 1:length(obj.stim)
                for jj = 1:length(stim0)
                    if strcmp(obj.stim(ii).GetName(), stim0(jj).GetName())
                        if obj.stim(ii) ~= stim0(jj)
                            stim0(jj).Copy(obj.stim(ii));
                            stim0(jj).SaveHdf5(fileobj, [obj.location, '/stim', num2str(jj)]);
                for jj = 1:length(snirfFile.stim)
                    if strcmp(obj.stim(ii).GetName(), snirfFile.stim(jj).GetName())
                        if obj.stim(ii) ~= snirfFile.stim(jj)
                            snirfFile.stim(jj).Copy(obj.stim(ii));
                        end
                        flags(ii) = 1;
                        break;
@@ -636,30 +637,36 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
                if ~flags(ii)
                    % We have new stimulus condition added
                    if ~obj.stim(ii).IsEmpty()
                        stim0(jj+1) = StimClass(obj.stim(ii));
                        stim0(jj+1).SaveHdf5(fileobj, [obj.location, '/stim', num2str(jj+1)]);
                        snirfFile.stim(jj+1) = StimClass(obj.stim(ii));
                    end
                end
            end
            
            % If stims were edited then update snirf file with new stims
            changes = sum(flags);
            if changes
                snirfFile.SaveStim(fileobj);
            end
            stimFromFile = snirfFile.stim;
        end
        
        
        
        % -------------------------------------------------------
        function changes = StimChangesMade(obj)
            % Load original unedited stims from file
            snirf = SnirfClass();
            snirf.LoadStim(obj.filename);
            stim0 = snirf.stim;
            
            flags = zeros(length(obj.stim), 1);
            
            % Update original stims from file with edited stims
            % Load stims from file
            snirf = SnirfClass();
            snirf.LoadStim(obj.filename);
            stimFromFile = snirf.stim;
            
            % Update stims from file with edited stims
            for ii = 1:length(obj.stim)
                for jj = 1:length(stim0)
                    if strcmp(obj.stim(ii).GetName(), stim0(jj).GetName())
                        if obj.stim(ii) ~= stim0(jj)
                for jj = 1:length(stimFromFile)
                    if strcmp(obj.stim(ii).GetName(), stimFromFile(jj).GetName())
                        if obj.stim(ii) ~= stimFromFile(jj)
                            flags(ii) = 1;
                        else
                            flags(ii) = -1;
@@ -692,6 +699,7 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
            if isempty(obj)
                return
            end
            
            % Arg 1
            if ~exist('fileobj','var') || ~exist(fileobj,'file')
                fileobj = '';
@@ -1287,6 +1295,7 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
        end
        
        
        
        % ----------------------------------------------------------------------------------
        function vals = GetStimValues(obj, icond)
            if icond>length(obj.stim)
Loading