Changes

Jump to navigation Jump to search
16,166 bytes added ,  15:18, 24 September 2018
Created page with "__NOTOC__ = Dedicated ''get'' and ''put'' actions = There are cases in your experiment design where it would be handy to update information to the global variables in a user d..."
__NOTOC__
= Dedicated ''get'' and ''put'' actions =
There are cases in your experiment design where it would be handy to update information to the global variables in a user definable way, for instance to partially update or retrieve a variables structure field or to collect data in specific data structures. Such a feature can be implemented through dedicated ''get'' or ''put'' actions.

If you have plans to implement such custom-made functions, you should read following paragraph that explains how this can be done. Otherwise, jump directly to the next [[SmartGetPut#ExamplesGetPut|paragraph]] that demonstrates some examples that come standardly with BrainStream and demonstrate dedicated get/put actions to implement four data structures and direct update/retrieval from structure fields.

== Building custom-made dedicated get and put actions ==
Those functions should obey to a fixed format, where each format is different for ''get'', ''put'' and a new ''get+mod'' actions. Also, function names should always be prefixed with either of the following options: 'get_', 'pop_', 'put_', 'push_', 'load_' or 'save_' in order to be recognized by BrainStream as a dedicated get/put action. The functions should be copied to the BrainStream $BRAINSTREAM_FOLDER/core/getput/ folder.

'''get''':
<blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px">

general format implementation func:
</blockquote><pre> function ret = get_fun(var, varargin)
get_fun: the function name of your dedicated ''get'' action
var: the global variable
varargin: any additional user input arguments
ret: returned content derived from global variable </pre><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px"> specification in the table: </blockquote><pre> get_fun(field,varargin)</pre><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px"><blockquote>Notice the difference between function format and what is specified in your experiment definition table. In the table, the first argument <em>field </em>is the name of the ''event'' structure field that gets the content assigned. Also, the global variable ''var'' is automatically added as input argument by BrainStream, like this is also happening in the table for functions and the first ''event'' input argument.</blockquote></blockquote><pre> field: content is stored in this field of local event structure
varargin: any additional user input arguments </pre>

<blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px">

examples:
<pre>get_item (data structures: array, shiftreg) </pre><pre>load_var </pre></blockquote>

'''put''':
<blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px">

general format implementation func:
<pre>function var = put_fun(var, update, varargin)</pre></blockquote><pre> put_fun: the function name of your dedicated ''put'' action
var: the global variable
update: content to update the global variable
varargin: any additional user input arguments </pre> <blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px">specification table:</blockquote><pre> put_fun(content,varargin)
update: content to update the global variable, i.e., a constant, function or name of event structure field (prefix name with a dot)
varargin: any additional user input arguments </pre>

<blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px">

examples:
</blockquote><pre> put_item, push_item, put_new, put_clear (data structures: array, shiftreg, stack, queue) </pre><pre> save_var </pre>

'''get+mod''':
<blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px">

general format implementation func:
</blockquote> <pre> function [ret, var] = get_fun(var, varargin) </pre><pre> get_fun: the function name of your dedicated combined ''get+mod'' action </pre><pre> var: the global variable </pre><pre> varargin: any additional user input arguments </pre> <blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px">

specification table:
</blockquote><pre> getmod_fun(content,varargin) </pre><pre> content: constant, function or name of field for event structure </pre><pre> varargin: any additional user input arguments </pre>

<blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px">

examples:
</blockquote><pre> pop_item (data structures: stack, queue) </pre><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px">NOTE: this is a special newly introduced operation since it combines both a <em>get</em>- and a <em>mod</em>-operation. This combined action is necessary to implement data structures with ''pop'' behaviour, where a ''get'' operation not only retrieves some content from the data structure, but also modifies the content and thus implicitly also involves a ''mod'' operation to update the corresponding global variables content.</blockquote><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px"> </blockquote>

'''Important:''' Function names should always be prefixed with either of the following options: 'get_', 'pop_', 'put_', 'push_', 'load_' or 'save_' in order to be recognized by BrainStream as a dedicated get/put action. The functions should be copied to the BrainStream $BRAINSTREAM_FOLDER/core/getput/ folder.

<div id="ExamplesGetPut"></div>
<blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px"> </blockquote>

== Examples of custom-made get/put actions ==

From abovementioned smart get/put general function formats, users can derive their own custom made function to achieve dedicated get/put retrieval/updating functionality. BrainStream comes standardly with an implementation of the four data structures:

* queue
* stack
* array
* shiftreg (shift register)

These data structures are default available to the user and are modifiable via the functions:

* <span style="letter-spacing: 0px"> <tt>put_new:</tt> </span> <span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">initiate a new data structure (all four data structures)</span>
* <span style="letter-spacing: 0px"> <tt>put_clear:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">clear previously initiated data structure (all four data structures)</span>
* <span style="letter-spacing: 0px"> <tt>put_item:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">put new content to data structure (</span> ''array'' <span style="letter-spacing: 0px">)</span>
* <span style="letter-spacing: 0px"> <tt>push_item:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">push new content to data structure (</span> ''stack, shiftreg, queue'' <span style="letter-spacing: 0px">)</span>
* <span style="letter-spacing: 0px"> <tt>pop_item:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">pop item from data structure (</span> ''stack, queue'' <span style="letter-spacing: 0px">)</span>
* <span style="letter-spacing: 0px"> <tt>get_item:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">get item from data structure (</span> ''array, shiftreg'' <span style="letter-spacing: 0px">)</span>
* <span style="letter-spacing: 0px"> <tt>get_whole:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">get entire data returned (all four data structures)</span>

'''Note''': The format below is how users should specify it in their experiment definition tables.

<strong> put_new</strong>(type, dims, len, returnascell [, field]) for: array, shiftreg

<strong> put_new</strong>(type, dims, returnascell [, field]) for: queue, buffer, stack

* <span style="letter-spacing: 0px"> <tt>dims:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">dimensions of added content (empty if not known) &lt;numeric&gt;</span>
* <span style="letter-spacing: 0px"> <tt>len:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">length of array or shift register &lt;numeric&gt;</span>
* <span style="letter-spacing: 0px"> <tt>returnascell:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">set to zero if entire content can and should be returned as numeric matrix &lt;1,0&gt;</span>
* <span style="letter-spacing: 0px"> <tt>field:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span>assign update to structure field of global variable &lt;char&gt;

<strong> put_clear</strong>([field])

* <span style="letter-spacing: 0px"> <tt>field:</tt> </span>assign update to structure field of global variable &lt;char&gt;

<strong> put_item</strong>(update, idx [, field])

* <span style="letter-spacing: 0px"> <tt>update:</tt> </span><span style="letter-spacing: 0px"> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">the content to be updated (either constant value or a field of the event structure, literally specified and prefixed with a dot &lt;any type&gt;</span>
* <span style="letter-spacing: 0px"> <tt>idx:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">index position of entry to be updated &lt;number&gt;</span>
* <span style="letter-spacing: 0px"> <tt>field:</tt> </span><span style="letter-spacing: 0px"> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span>assign update to structure field of global variable &lt;char&gt;

<strong> push_item</strong>(update [, field])

* <span style="letter-spacing: 0px"> <tt>update:</tt> </span><span style="letter-spacing: 0px"> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">the content to be updated (either constant value or a field of the event structure, literally specified and prefixed with a dot &lt;any type&gt;</span>
* <span style="letter-spacing: 0px"> <tt>field:</tt> </span><span style="letter-spacing: 0px"> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span>assign update to structure field of global variable &lt;char&gt;

<strong> pop_item</strong>(.event_field [, field])

* <span style="letter-spacing: 0px"> <tt>.event_field:</tt> [[BrainStream|Brain Stream]] assigns returned result to event.event_field</span> &lt;char&gt;
* <span style="letter-spacing: 0px"> <tt>field:</tt> </span><span style="letter-spacing: 0px"> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">retrieved from global variables structure field &lt;char&gt;</span>

<strong> get_item</strong>(.event_field [,idx, field])

* <span style="letter-spacing: 0px"> <tt>.event_field:</tt> </span>BrainStream assigns returned result to event.event_field &lt;char&gt;
* <span style="letter-spacing: 0px"> <tt>idx:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">index position of entry to retrieve &lt;number&gt;</span>
* <span style="letter-spacing: 0px"> <tt>field:</tt> </span><span style="letter-spacing: 0px"> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">retrieved from global variables structure field &lt;char&gt;</span>

<strong> get_whole</strong>(.event_field [, field])

* <span style="letter-spacing: 0px"> <tt>.event_field:</tt> </span>BrainStream assigns returned result to event.event_field &lt;char&gt;
* <span style="letter-spacing: 0px"> <tt>field:</tt> </span><span style="letter-spacing: 0px"> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">retrieved from global variables structure field &lt;char&gt;</span>

Some other examples:

<strong> put_field</strong>(update, field)

* <span style="letter-spacing: 0px"> <tt>update:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">the content to be updated (either constant value or a field of the event structure, literally specified and prefixed with a dot &lt;any type&gt;</span>
* <span style="letter-spacing: 0px"> <tt>field:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">assign update to structure field of global variable &lt;char&gt;</span>

<strong> get_field</strong>(.event_field, field)

* <span style="letter-spacing: 0px"> <tt>.event_field:</tt> </span>BrainStream assigns returned result to event.event_field &lt;char&gt;
* <span style="letter-spacing: 0px"> <tt>field:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">retrieved from global variables structure field &lt;char&gt;</span>

<strong> save_var</strong>(update, name [, option]) % Note: it also incorporates a put action, i.e., it updates the global variable and saves it to a user-specified file.

* <span style="letter-spacing: 0px"> <tt>update:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span><span style="letter-spacing: 0px">the content to be updated (also updates global variable!) &lt;any type&gt;</span>
* <span style="letter-spacing: 0px"> <tt>name:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span>name of the file (Note: folder is determlined by blocksettings for [[OutFolder|Out Folder]]) &lt;char&gt;
* <span style="letter-spacing: 0px"><span style="letter-spacing: 0px"> <tt>option:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span>Matlab has different options on how to compress the variable before saving it. &lt;char&gt;</span>

<strong> load_var</strong>(.event_field, name)

* <span style="letter-spacing: 0px"> <tt>.event_field:</tt> </span>BrainStream assigns returned result to event.event_field &lt;char&gt;
* <span style="letter-spacing: 0px"> <tt>name:</tt> </span><span style="letter-spacing: 0px; white-space: pre" class="Apple-tab-span"> </span>name of the file to load from &lt;char&gt;

Todo: Add example table to demonstarte how this can be used in an experiment

== Examples of dedicated get and put actions ==

{| border="1"
|-
!colspan="5"| '''Example dedicated put: stack'''
|-
| <strong>marker <br /></strong> || <strong>time <br /></strong> || <strong>function <br /></strong> || <strong>trials <br /></strong> || <strong>sequence <br /></strong>
|-
| BS_INIT || EVENT || || [],put_new('stack') ||
|-
| trial || DATA || process_data || push_item(data) ||
|-
| BS_END || EVENT || || get_whole(.sequence) || save
|}

<br /> The BS_INIT event initialises a new stack ( <tt>put_new('stack')</tt>), configured to collect items in a cell-array (omitted input argument <tt>returnascell</tt> defaults to cell-type). For every incoming trial event, <tt>event.data</tt> is pushed ( <tt>push_item(.data)</tt>) to the stack (no pops so we are just collecting all data here). At the BS_END event the information on the stack is merged into a cell-array ( <tt>get_whole(.sequence)</tt>) as field of the event structure ( <tt>event.sequence</tt>), which is then saved to disk via the <tt>save</tt> keyword for the <tt>sequence</tt> variable.

Navigation menu