Diff of /functions/@mmo/mmo.m [000000] .. [422372]

Switch to side-by-side view

--- a
+++ b/functions/@mmo/mmo.m
@@ -0,0 +1,165 @@
+% MMO - create a memory-mapped data class
+%
+% Usage:
+%   >> data_class = mmo(data);
+%
+% Inputs:
+%   data         - input data or data file
+%
+% Outputs:
+%   data_class    - output dataset class
+%
+% Author: Arnaud Delorme, SCCN, INC, UCSD, Nov. 2012-
+
+% Copyright (C) 2008 Arnaud Delorme, SCCN, INC, UCSD
+%
+% This file is part of EEGLAB, see http://www.eeglab.org
+% for the documentation and details.
+%
+% Redistribution and use in source and binary forms, with or without
+% modification, are permitted provided that the following conditions are met:
+%
+% 1. Redistributions of source code must retain the above copyright notice,
+% this list of conditions and the following disclaimer.
+%
+% 2. Redistributions in binary form must reproduce the above copyright notice,
+% this list of conditions and the following disclaimer in the documentation
+% and/or other materials provided with the distribution.
+%
+% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+% THE POSSIBILITY OF SUCH DAMAGE.
+
+classdef mmo
+    properties
+        dataFile   = [];
+        dimensions = [];
+        writable   = true;  % duplicate of the writable field of memmapfile
+        workspace  = [];
+        type       = 'mmo';
+        transposed = false;
+        debug      = false;
+    end
+        
+    methods
+        function dataout = mmo(dataFileIn, datadims, writableVal, transposedVal, debugVal)
+            if nargin < 3
+                writableVal = true;
+            end
+            if nargin < 4
+                transposedVal = false;
+            end
+            if nargin < 5
+                debugVal = false;
+            end
+            
+            % check that the file is not empty
+            % --------------------------------
+            if ~isempty(dataFileIn)
+                if ~ischar(dataFileIn)
+                    error('First input must be a file name');
+                end
+
+                dirContent = dir(dataFileIn);
+                if isempty(dirContent)
+                    error([ 'Data file ''' dataFileIn '''not found' ]);
+                elseif dirContent(1).bytes == 0
+                    error([ 'Empty data file ''' dataFileIn '''' ]);
+                end
+            else
+                dataFileIn = mmo.getnewfilename;
+                fid = fopen(dataFileIn, 'w');
+                if fid == -1, error('Cannot open new file'); end
+                if length(datadims) == 1, datadims(2) = 1; end
+                tmpdata = zeros(1, prod(datadims(2:end)), 'single');
+                for index = 1:datadims(1)
+                    fwrite(fid, tmpdata, 'float');
+                end
+                fclose(fid);
+            end
+                
+            % test memory map but discards it
+            % -------------------------------
+            test = memmapfile(dataFileIn, 'writable', writableVal, 'format', { 'single' datadims 'x' });
+            clear test;
+            
+            % set fields
+            % ----------
+            while datadims(end) == 1 && length(datadims) > 1
+                datadims(end) = [];
+            end
+            if transposedVal
+                if length(datadims) == 1, datadims = [1 datadims];
+                else                      datadims = [datadims(2:end) datadims(1)];
+                end
+            end
+            
+            dataout.dataFile   = dataFileIn;
+            dataout.dimensions = datadims;
+            dataout.writable   = writableVal;
+            dataout.transposed = transposedVal;
+            
+            % set workspace
+            % -------------
+            dataout = updateWorkspace(dataout);
+%             stack = dbstack;
+%             stack(1) = [];
+%             stack = rmfield(stack, 'line');
+%             dataout.workspace = stack;
+            dataout.debug     = debugVal;
+        end
+        
+        % this function updates the function workspace
+        % --------------------------------------------
+        function obj = updateWorkspace(obj);
+            stack = dbstack;
+            stack(1:2) = [];
+            stack      = rmfield(stack, 'line');
+            obj.workspace = stack;
+        end
+        
+        % function to check copies (only used for testing,
+        % implemented in subasign as well)
+        % --------------------------------
+        function ncopies = checkcopies(obj);
+            ncopies = checkworkspace(obj);
+            if ncopies < 2
+                s = evalin('caller', 'whos');
+                for index = 1:length(s)
+                    if strcmpi(s(index).class, 'struct') || strcmpi(s(index).class, 'cell')
+                        tmpVar = evalin('caller', s(index).name);
+                        ncopies = ncopies + checkcopies_local(obj, tmpVar);
+                    elseif strcmpi(s(index).class, 'mmo')
+                        if s(index).persistent || s(index).global
+                            disp('Warning: mmo objects should not be made persistent or global. Behavior is unpredictable.');
+                        end
+                        tmpVar = evalin('caller', s(index).name);
+                        if isequal(tmpVar, obj), ncopies = ncopies + 1; end
+                        if ncopies > 1, break; end
+                    end
+                end
+            end
+        end
+        
+        % numerical implementations of basic functions
+        % --------------------------------------------
+        function obj2 = log(obj1); obj2 = unitaryopp(@log, obj1); end
+        function val  = mean(obj,dim); if nargin <1, dim=1; end; val = sum(obj,dim)/size(obj,dim); end
+        function val  = std(varargin); val = sqrt(var(varargin{:})); end
+        function obj3 = minus(obj1, obj2); obj3 = binaryopp(@minus, obj1, obj2); end
+        function obj3 = plus(obj1, obj2); obj3 = binaryopp(@plus, obj1, obj2); end
+        function obj3 = time(obj1, obj2); obj3 = binaryopp(@time, obj1, obj2); end
+    end
+    
+    methods (Static)
+        function str  = getnewfilename; str = fullfile(gettempfolder(true), sprintf('memapdata_%.9d%.9d.fdt', round(rand(1)*10^9), round(rand(1)*10^9))); end
+    end
+end