2

My day to day work flow is something like this:

  • acquire raw data (~50GB)
  • parse raw data timing-information and build raw data structure (struct / object) from timing-information (what event occurred when, in which order, in what file, what other events occurred at the same time, etc ...)
  • load only the necessary parts of raw data into struct / object as selected from previous timing information (basically this is a way to sub-select data)
  • for each raw data chunk, calculate / extract certain metrics like RMS of signal, events where data > threshold, d' / z-score, and save them with struct / object
  • given the the previously calculated metrics, load some raw-data of same time episodes from different data channel and compare certain things, etc ...
  • visualize results x, y, z

I have two ways of dealing with this kind of data / workflow:

  1. use struct()
  2. use objects

There are certain advantages / disadvantages to both cases:

  1. struct:

    • can add properties / fields on the fly
    • have to check for state of struct every single time that I pass a struct to a function
    • keep re-writing certain functions because every time that I change the struct slightly I a) tend to forget that a function already exists for it or b) I write a new version that handles a special case of the struct state.
  2. objects:

    • using 'get.property()' methods, I can check the state of a property before it get's accessed inside a function / method -> allows to do data consistency checks.
    • I always know which methods work with my object, since they are part of the object definition.
    • need to clear classes every time I add a new property or method - very annoying!

Now my question is: how do other people deal with this kind of situation? how do you organize your data? in structs? in objects? how do you handle state checks? is there a way to do 'stateless' programming in matlab?

memyself
  • 11,907
  • 14
  • 61
  • 102

1 Answers1

3

I like to use objects. You don't need to call clear classes on every change. It is enough to delete all instances of the "old" object.

Two very powerful additions I inherit often are handle and dynamicprops.

  1. Handle makes the object behave as handle. Very nice to come around matlabs copy-on-change behavior.
  2. Dynamic props - to do some meta programming.

About the consistency checks - why no do them when you use set.property?


Edit 1:

a simplified class that uses the database:

classdef measurement
   class
   id
properties (SetAccess = private)

end
methods
function obj = measurement(varargin)
  obj.id = varargin{1};
end

    function cs = get.class(obj)
       if isempty(obj.id)
                    cs = '';
                    return
       end
       mc = mydb.local; % use some tricks here to keep the connection open
         tmp = mym(mc,...
                    'SELECT class FROM measurements WHERE id = {Si}'...
                    ,obj.id);
         cs = tmp{1};
     end
end

Edit 2: Example for Event - Observer

classdef ObservableClass < handle

    properties 
        ListObservers=[]
        data
    end

    methods
        function obj = ObservableClass(varargin)
            obj.data = rand(100,2);
        end

        function addObserver(obj,observer)
            obj.ListObservers = [obj.ListObservers,observer];
        end

        function fireUpdate(obj)
            for i=1:numel(obj.ListObservers)
                obj.ListObservers(i).update();
            end
        end

        function set.data(obj,newData)
            obj.data = newData;
            obj.fireUpdate;
        end
    end
end

and a listener:

 classdef ObservingPlot
    properties
        fig
        observedClass
    end

    methods
        function obj = ObservingPlot(varargin)
            obj.observedClass = varargin{1};
            obj.createPlot;
            obj.observedClass.addObserver(obj);
        end

        function createPlot(obj)
            obj.fig=figure;
            plot(obj.observedClass.data);
        end

        function update(obj)
            gcf(obj.fig)
            clf
            plot(obj.observedClass.data);
        end
    end

end

The example:

a = ObservableClass()
b = ObservingPlot(a)

you can then observe when you do a: a.data=rand(100,3) - the plot will change immediatly.


Edit 3: a simple saving class

classdef SavingClass < handle

    properties 
        saveName
        data
    end

    methods
        function set.data(obj,input)
            if isempty(obj.saveName)
                obj.saveName = [tempname '.mat'];
            end
            save(obj.saveName,'input')
        end

        function out = get.data(obj)            
                out = [];
               if exist(obj.saveName,'file')                   
                   tmp = load(obj.saveName);
                   out = tmp.input;
               end
        end
    end

end

Example:

a = SavingClass;
b=rand(1000,1000);
a.data = b;

look at `whos':

Name         Size                Bytes  Class          Attributes

  a            1x1                    60  SavingClass              
  ans          1x5                    10  char                     
  b         1000x1000            8000000  double          

although you can do calculations like d = a.data-b - a takes just 60 bytes in memory - as opposed to the ~8 MB of b.


Edit 4: trick for often changing functions. When you put the logic in external commands matlab will not complain when you change the function definition there.

classdef MyOftenEditedClass < handle

    properties
        a
    end

    methods
        function set.a(obj,val)
            mySetFunctionA(obj,val)
        end

        function out=get.a(obj)
            out = myGetFunctionA(obj);
        end
    end

end
bdecaf
  • 4,652
  • 23
  • 44
  • do your objects reside in the base workspace? Since my objects are handled by a generic GUI, I need to keep them with the GUI (otherwise I need to always use `evalin` & `assignin`) – memyself Feb 05 '12 at 21:27
  • how big (memory wise) are your objects? mine grow up to 3GB, and re-instantiating them is therefore very annoying ... – memyself Feb 05 '12 at 21:29
  • The case with GUI I use the handle class - using this I can manipulate the objects in base workspace and in the figure the changes will be available. Together with listener-observer pattern very nice. – bdecaf Feb 05 '12 at 21:37
  • Objects can be as big for me. But then I try to split them up. Often using set.property to save to a file and get.property to load it. So they are not in workspace when not needed. More complex I put in a MySQL database instead. – bdecaf Feb 05 '12 at 21:40
  • would you mind sharing a short example class so I can see how you use listener-observer patterns, set.properties to save a file, etc? I'm also curious about your MySQL interaction :) – memyself Feb 05 '12 at 22:17
  • thanks for the code! but as I understand correctly, even if I use a handle class with dynamic properties, whenever I need to write a 'set/get.property' method, I will have to reload the object / class definition. Or do you know a way of circumventing this? – memyself Feb 06 '12 at 13:33
  • Well actually what happens is that Matlab complains. It will use the new definition once no more Instances of the old are around. But there is a nice trick for functions you need often. I'll add it to the list. Unfortunately there is no easy way if you change the fundamental model by adding/removing fields. – bdecaf Feb 06 '12 at 13:48
  • @bdecaf Since you linked to this from a newer question, I cannot resist. a) Your size-argument for the `SavingClass` is plain wrong: `whos` simply does not show a correct memory footprint for handle classes. `a` will of course need the same 8MB to store the data. b) Why implement an `Observer` yourself? MATLAB provides events and listeners you can use - no need to reinvent the wheel. – sebastian Nov 19 '13 at 15:56
  • Interesting comments. Maybe you can elaborate where my mistakes are. The assumption of the saving class would be to have an array of 100s of SavingClass objects so I won't need to keep the N*8MB in RAM till I need them. Did I overlook something? – bdecaf Nov 20 '13 at 11:21
  • To the observers I'm aware of linkdata - but I did not know there is a general purpose observer - can you tell me how it's called? – bdecaf Nov 20 '13 at 11:26