Commit 694d1b6f authored by jayd1860's avatar jayd1860
Browse files

v1.20.4

-- Change current supported snirf version to 1.1. This is NOT OFFICIAL yet. This is what I'm advocating needs to happen because we are changing SNIRF format.
-- Add forward compatibility for snirf in ProbeClass. New snirf tentatively version 1.1, sourcePos2D and detectorPos2D have 2 columns but we convert to 3 columns to be compatible with Homer3 application
-- Change GroupClass version to 1.1 to account for the change in acquisition layer changes (Snirf format changed)
-- Update python application SnirfClass.py and add AuxClass
parent 043e67d6
Loading
Loading
Loading
Loading
+26 −9
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ classdef ProbeClass < FileLoadSaveClass
        wavelengthsEmission
        sourcePos2D
        detectorPos2D
        frequency
        frequencies
        timeDelay
        timeDelayWidth
        momentOrder
@@ -31,7 +31,7 @@ classdef ProbeClass < FileLoadSaveClass
                    obj.wavelengthsEmission  = [];
                    obj.sourcePos2D  = SD.SrcPos;
                    obj.detectorPos2D  = SD.DetPos;
                    obj.frequency  = 1;
                    obj.frequencies  = 1;
                    obj.timeDelay  = 0;
                    obj.timeDelayWidth  = 0;
                    obj.momentOrder = [];
@@ -52,7 +52,7 @@ classdef ProbeClass < FileLoadSaveClass
                obj.wavelengthsEmission  = [];
                obj.sourcePos2D  = [];
                obj.detectorPos2D  = [];
                obj.frequency  = 1;
                obj.frequencies  = 1;
                obj.timeDelay  = 0;
                obj.timeDelayWidth  = 0;
                obj.momentOrder = [];
@@ -65,6 +65,18 @@ classdef ProbeClass < FileLoadSaveClass

        
        
        % -------------------------------------------------------
        function ForwardCompatibility(obj)
            if size(obj.sourcePos2D,2)<3
                obj.sourcePos2D       = [obj.sourcePos2D, zeros(size(obj.sourcePos2D,1), 1)];
            end
            if size(obj.detectorPos2D,2)<3
                obj.detectorPos2D     = [obj.detectorPos2D, zeros(size(obj.detectorPos2D,1), 1)];
            end
        end

        
        
        % -------------------------------------------------------
        function err = LoadHdf5(obj, fileobj, location)
            err = 0;
@@ -101,13 +113,13 @@ classdef ProbeClass < FileLoadSaveClass
                obj.wavelengthsEmission       = HDF5_DatasetLoad(gid, 'wavelengthsEmission');
                obj.sourcePos2D                 = HDF5_DatasetLoad(gid, 'sourcePos2D', [], '2D');
                obj.detectorPos2D               = HDF5_DatasetLoad(gid, 'detectorPos2D', [], '2D');
                obj.frequency                 = HDF5_DatasetLoad(gid, 'frequency');
                obj.frequencies               = HDF5_DatasetLoad(gid, 'frequencies');
                obj.timeDelay                 = HDF5_DatasetLoad(gid, 'timeDelay');
                obj.timeDelayWidth            = HDF5_DatasetLoad(gid, 'timeDelayWidth');
                obj.momentOrder               = HDF5_DatasetLoad(gid, 'momentOrder');
                obj.correlationTimeDelay      = HDF5_DatasetLoad(gid, 'correlationTimeDelay');
                obj.correlationTimeDelayWidth = HDF5_DatasetLoad(gid, 'correlationTimeDelayWidth');
                obj.sourceLabels              = HDF5_DatasetLoad(gid, 'sourceLabels', obj.sourceLabels); %#ok<*PROPLC>
                obj.sourceLabels              = HDF5_DatasetLoad(gid, 'sourceLabels', obj.sourceLabels);
                obj.detectorLabels            = HDF5_DatasetLoad(gid, 'detectorLabels', obj.detectorLabels);
                                
                % Close group
@@ -116,6 +128,11 @@ classdef ProbeClass < FileLoadSaveClass
                err=-1;
                return;
            end
            
            % Call method to change future current and future versions of
            % SNIRF data to Homer3 compatible structure
            obj.ForwardCompatibility();
            
        end

        
@@ -139,9 +156,9 @@ classdef ProbeClass < FileLoadSaveClass
            end     
            hdf5write_safe(fileobj, [location, '/wavelengths'], obj.wavelengths);
            hdf5write_safe(fileobj, [location, '/wavelengthsEmission'], obj.wavelengthsEmission);
            hdf5write_safe(fileobj, [location, '/sourcePos2D'], obj.sourcePos2D, 'rw:2D');
            hdf5write_safe(fileobj, [location, '/detectorPos2D'], obj.detectorPos2D, 'rw:2D');
            hdf5write_safe(fileobj, [location, '/frequency'], obj.frequency);
            hdf5write_safe(fileobj, [location, '/sourcePos2D'], obj.sourcePos2D(:,1:2), 'rw:2D');
            hdf5write_safe(fileobj, [location, '/detectorPos2D'], obj.detectorPos2D(:,1:2), 'rw:2D');
            hdf5write_safe(fileobj, [location, '/frequencies'], obj.frequencies);
            hdf5write_safe(fileobj, [location, '/timeDelay'], obj.timeDelay);
            hdf5write_safe(fileobj, [location, '/timeDelayWidth'], obj.timeDelayWidth);
            hdf5write_safe(fileobj, [location, '/momentOrder'], obj.momentOrder);
@@ -187,7 +204,7 @@ classdef ProbeClass < FileLoadSaveClass
            if ~all(obj.detectorPos2D(:)==obj2.detectorPos2D(:))
                return;
            end
            if ~all(obj.frequency(:)==obj2.frequency(:))
            if ~all(obj.frequencies(:)==obj2.frequencies(:))
                return;
            end
            if ~all(obj.timeDelay(:)==obj2.timeDelay(:))
+11 −4
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
            %
             
            % Initialize properties from SNIRF spec 
            obj.formatVersion = '1.0';
            obj.formatVersion = '1.1';
            obj.metaDataTags   = MetaDataTagsClass().empty();
            obj.data           = DataClass().empty();
            obj.stim           = StimClass().empty();
@@ -344,7 +344,14 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
                [obj.gid, obj.fid] = HDF5_GroupOpen(fileobj, '/');
                
                %%%% Load formatVersion
                obj.formatVersion = HDF5_DatasetLoad(obj.gid, 'formatVersion');
                formatVersionFile = HDF5_DatasetLoad(obj.gid, 'formatVersion'); %#ok<*PROPLC>
                formatVersionFile = str2double(formatVersionFile);
                formatVersionCurr = str2double(obj.formatVersion); 
                if formatVersionFile < formatVersionCurr
                    fprintf('Warning: Current SNIRF version is %0.1f. Cannot load older version (%0.1f) file. Backward compatibility not yet implemented ...\n', formatVersionCurr, formatVersionFile)
                    err = -2;
                    return 
                end
            
                %%%% Load metaDataTags
                obj.LoadMetaDataTags(obj.fid);
@@ -432,7 +439,7 @@ classdef SnirfClass < AcqDataClass & FileLoadSaveClass
            
            % Save formatVersion
            if isempty(obj.formatVersion)
                obj.formatVersion = '1.10';
                obj.formatVersion = '1.1';
            end
            hdf5write_safe(fileobj, '/formatVersion', obj.formatVersion);
            
+56 −8
Original line number Diff line number Diff line
@@ -11,6 +11,19 @@ sys.path.append(rootpath)
from DataFiles.Hdf5.hdf5lib import h5getstr


# ---------------------------------------------------------------------------
def PrintArraySize(v, vname):
    if len(v.shape)==1:
        nrows = v.shape[0]
        ncols = 1
    elif len(v.shape)==2:
        nrows = v.shape[0]
        ncols = v.shape[1]
    sys.stdout.write('%s = [%d x %d]\n'% (vname, nrows, ncols))




############################################################
class ErrorClass:
    # -----------------------------------------------------------
@@ -55,9 +68,8 @@ class DataClass(ErrorClass):

    # -----------------------------------------------------------
    def Print(self):
        sys.stdout.write('  dataTimeSeries = [%d x %d]\n'% (self.dataTimeSeries.shape[0], self.dataTimeSeries.shape[1]))
        sys.stdout.write('  time = %d\n'% self.time.shape[0])

        PrintArraySize(self.dataTimeSeries, '  dataTimeSeries')
        PrintArraySize(self.time, '  time')


############################################################
@@ -70,14 +82,14 @@ class ProbeClass(ErrorClass):
        self.wavelengthsEmission  = fid.get(location + '/wavelengthsEmission')
        self.sourcePos2D  = np.array(fid.get(location + '/sourcePos2D'))
        self.detectorPos2D  = np.array(fid.get(location + '/detectorPos2D'))
        self.frequency  = np.array(fid.get(location + '/frequency'))
        self.frequencies  = np.array(fid.get(location + '/frequencies'))
        self.timeDelay  = 0
        self.timeDelayWidth  = 0
        self.momentOrder = []
        self.correlationTimeDelay = 0
        self.correlationTimeDelayWidth = 0
        self.sourceLabels = h5getstr(fid, location + '/sourceLabels')
        self.detectorLabels = h5getstr(fid, location + '/detectorLabels')
        self.sourceLabels = np.array(fid.get(location + '/sourceLabels'))
        self.detectorLabels = np.array(fid.get(location + '/detectorLabels'))

        ErrorClass.__init__(self)

@@ -92,7 +104,7 @@ class ProbeClass(ErrorClass):
        sys.stdout.write('  detectorPos2D:\n')
        for ii in range(0, self.detectorPos2D.shape[0]):
            sys.stdout.write('      %s\n'% self.detectorPos2D[ii])
        sys.stdout.write('  frequency = %s\n'% self.frequency)
        sys.stdout.write('  frequencies = %s\n'% self.frequencies)
        sys.stdout.write('  timeDelay = %s\n'% self.timeDelay)
        sys.stdout.write('  timeDelayWidth = %s\n'% self.timeDelayWidth)
        sys.stdout.write('  momentOrder = %s\n'% self.momentOrder)
@@ -130,6 +142,31 @@ class StimClass(ErrorClass):



###########################################################
class AuxClass(ErrorClass):

    # -----------------------------------------------------------
    def __init__(self, fid, location):
        self.name  = h5getstr(fid, location + '/name')
        self.time  = np.array(fid.get(location + '/time'))
        self.dataTimeSeries  = np.array(fid.get(location + '/dataTimeSeries'))
        ErrorClass.__init__(self)

    # -----------------------------------------------------------
    def Print(self):
        sys.stdout.write('  name: %s\n'% self.name)
        PrintArraySize(self.dataTimeSeries, '  dataTimeSeries')
        PrintArraySize(self.time, '  time')

    # -----------------------------------------------------------
    def IsEmpty(self):
        if ((self.time.all()==None) or (len(self.time)==0)) and \
            ((self.dataTimeSeries.all()==None) or (len(self.dataTimeSeries)==0)):
            return True
        return False



############################################################
class MetaDataTagsClass(ErrorClass):

@@ -189,6 +226,13 @@ class SnirfClass(ErrorClass):

        # aux
        self.aux = []
        ii = 1
        while 1:
            temp = AuxClass(fid, '/nirs/aux' + str(ii))
            if temp.GetError() < 0:
                break
            self.aux.append(temp)
            ii = ii+1

        fid.close()

@@ -212,6 +256,10 @@ class SnirfClass(ErrorClass):
        sys.stdout.write('probe:\n')
        self.probe.Print()

        for ii in range(0, len(self.aux)):
            sys.stdout.write('aux[%d]:\n'% ii)
            self.aux[ii].Print()


# -----------------------------------------------------------
if __name__ == "__main__":
@@ -223,7 +271,7 @@ if __name__ == "__main__":

    for ii in range(0, len(filenames)):
        sys.stdout.write('======================================================================\n')
        sys.stdout.write('Loading data from %s\n'% filenames[ii])
        sys.stdout.write('Loading data from %s\n\n'% filenames[ii])
        snirf = SnirfClass(filenames[ii])
        snirf.Print()
        sys.stdout.write('\n')
+5 −1
Original line number Diff line number Diff line
@@ -73,9 +73,13 @@ classdef GroupClass < TreeNodeClass
        
        % ----------------------------------------------------------------------------------
        function SetVersion(obj, vernum)
            % Version number should be incremented whenever properties are added, deleted or changed in 
            % GroupClass, SubjectClass, RunClass OR acquisition class, like AcqDataClass, SnirfClass and 
            % its sub-classes or NirsClass 
            
            if nargin==1
                obj.version{1} = '1';   % Major version #
                obj.version{2} = '0';   % Major sub-version #
                obj.version{2} = '1';   % Major sub-version #
                obj.version{3} = '0';   % Minor version #
                obj.version{4} = '0';   % Minor sub-version # or patch #: 'p1', 'p2', etc
            elseif iscell(vernum)
+1 −1
Original line number Diff line number Diff line
@@ -2,5 +2,5 @@ function vrnnum = getVernum()

vrnnum{1} = '1';   % Major version #
vrnnum{2} = '20';  % Major sub-version #
vrnnum{3} = '3';   % Minor version #
vrnnum{3} = '4';   % Minor version #
vrnnum{4} = '0';   % Minor sub-version # or patch #: 'p1', 'p2', etc