Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create class representation of Epoch #300

Open
ehennestad opened this issue Nov 22, 2024 · 3 comments
Open

Create class representation of Epoch #300

ehennestad opened this issue Nov 22, 2024 · 3 comments

Comments

@ehennestad
Copy link
Collaborator

Use ndi.epoch.epochset/buildepochtable as a starting point.

ehennestad added a commit that referenced this issue Nov 24, 2024
@ehennestad
Copy link
Collaborator Author

ehennestad commented Nov 24, 2024

Class could look like this:

classdef epoch < handle & matlab.mixin.SetGet
    % EPOCH Class to represent an epoch

    properties (SetAccess = private)
        % epoch_id - Unique identifier for the epoch
        epoch_id (1,1) string 
        
        % epoch_session_id - Identifier for the session containing this epoch
        epoch_session_id (1,1) string
    end

    properties
        % epochprobemap - Information about the contents of the epoch, usually 
        % of type ndi.epoch.epochprobemap or empty.
        epochprobemap (1,1) ndi.epoch.epochprobemap         
        
        % epoch_clock - 
        epoch_clock (1,:) ndi.time.clocktype = ndi.time.clocktype('no_time')
        
        % t_start - start time of time interval corresponding to each clockype
        t0_t1 (1,:) cell = {NaN, NAN} % or datetime?
        
        % underlying_epochs - epochsets?
        underlying_epochs      % Structure array of ndi.epoch.epochset objects comprising these epochs
    end

Are there any methods that would be useful?

Some thoughts:

  • Would it be useful to create a "ProbeEpoch" and an "ElementEpoch". They seem to be build in different ways? The "building" of an epoch could be the responsibility of the epoch class?

  • It could also hold a reference to time series objects and have utility methods like readEpochData

@stevewds
Copy link
Collaborator

Looking good..I think they should all have private SetAccess and we need a number field

@stevevanhooser
Copy link
Contributor

What do you think of this? I am new to using the get/set sorcery along with argument checking that you do so well. Is this the best way to do things?

I put it at +ndi/epoch.m instead of +ndi/epoch/epoch.m so its name can be ndi.epoch. Any preference? I have a slight preference for this but am open.

I made a new branch 301-add-epoch-class that builds on yours.

Matlab apparently doesn't let you recursively define properties (that is, I can't say that underlying_epochs must be an ndi.epoch, I get an error) but it lets you do this:

classdef epoch < handle & matlab.mixin.SetGet
    % EPOCH Class to represent an epoch, with the following properties:
    % 
    % 'epoch_number'            | The number of the epoch. The number may change as epochs are added and subtracted.
    % 'epoch_id'                | The epoch ID code (will never change once established, though it may be deleted.)
    %                           |   This epoch ID uniquely specifies the epoch.
    % 'epoch_session_id'           | The session ID that contains this epoch
    % 'epochprobemap'           | Any contents information for each epoch, usually of type ndi.epoch.epochprobemap or empty.
    % 'epoch_clock'             | A cell array of ndi.time.clocktype objects that describe the type of clocks available
    % 't0_t1'                   | A cell array of ordered pairs [t0 t1] that indicates the start and stop of the epoch for each
    %                           |   respective epoch_clock{}. The time units of t0_t1{i} match epoch_clock{i}.
    % 'object'                  | The ndi.epochset object that has the epoch
    % 'underlying_epochs'       | An array of the ndi.epoch objects that comprise this epochs.

			% note: will need to change underlying_epochs.underlying to underlying_epochs.object in all code

    properties (SetAccess = private)
        epoch_number (1,1) double {mustBeInteger(epoch_number)} = 0;
        epoch_id (1,1) string = "" % Unique identifier for the epoch; could be any string 
        epoch_session_id (1,1) string {did.ido.isvalid(epoch_session_id)} = ndi.ido.unique_id % Identifier for the session containing this epoch
        epochprobemap (1,1) {mustBeA(epochprobemap,'ndi.epoch.epochprobemap')} =  ndi.epoch.epochprobemap
        epoch_clock cell = {} % A cell array of ndi.time.clocktype objects that describe the types of clocks available
        t0_t1 cell = {} % A cell array of ordered pairs [t0 t1] that indicates the start and stop time of the epoch in each clock
        object (1,1) {mustBeA(object,'ndi.ido')} = ndi.ido
        underlying_epochs {} = [] % An array of the ndi.epoch objects that underlie/comprise this epoch
    end

    methods
         function obj = epoch(varargin)
             % EPOCH - create an ndi.epoch object
             % 
             % OBJ = EPOCH(...)
             %
             % Create an ndi.epoch() object. The properties must be passed as name/value pairs.
             % 
             % 'epoch_number'            | The number of the epoch. The number may change as epochs are added and subtracted.
             % 'epoch_id'                | The epoch ID code (will never change once established, though it may be deleted.)
             %                           |   This epoch ID uniquely specifies the epoch.
             % 'epoch_session_id'        | The session ID that contains this epoch
             % 'epochprobemap'           | Any contents information for each epoch, usually of type ndi.epoch.epochprobemap or empty.
             % 'epoch_clock'             | A cell array of ndi.time.clocktype objects that describe the type of clocks available
             % 't0_t1'                   | A cell array of ordered pairs [t0 t1] that indicates the start and stop of the epoch
             %                           |   for each respective epoch_clock{}. The time units of t0_t1{i} match epoch_clock{i}.
             % 'object'                  | The ndi.epochset object that has the epoch
             % 'underlying_epochs'       | An array of the ndi.epoch objects that comprise this epochs.
                  try
                      for i=1:2:numel(varargin),
                          obj.set(varargin{i},varargin{i+1});
                      end
                  catch
                      error(['Error in creating ndi.epoch object: ' lasterr ]);
                  end

          end % epoch
    end % methods

    methods(Static) 
        function mustBeEpochOrEmpty(value)
            % mustBeEpochOrEmpty - validate that a value is either an ndi.epoch or is empty
            %
            % Syntax:
            %   ndi.epoch.mustBeEpochOrEmpty(value)
            % Inputs: <value>, an input
                assert( isa(value,'ndi.epoch') | isempty(value), 'Value must be an ndi.epoch or be empty.');
        end
    end % Static Methods
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants