1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261 | //=====================================================================================================================
//
// cxtrialcodes_mex.h : Format of trial codes defining the execution of a trial in MAESTRODRIVER
//
// AUTHOR: saruffner, sglisberger, et al.
//
// DESCRIPTION:
// This is a modified version of the CNTRLX/CXDRIVER source code header file CXTRIALCODES.H. It is required to build
// the MATLAB MEX function readcxdata(), which is used to read CNTRLX data files into the MATLAB environment. MATLAB's
// MEX tool uses the GNU CC compiler; while GCC can handle C++ source code files, MEX handles only C files.
//
// It is the "const <type> IDENTIFIER = <value>" syntax that caused problems with the MEX build. While such a constant
// definition is acceptable when <value> is a constant, it introduces several problems down the line:
// 1) The compiler cannot handle "const <type> IDENTIFIER = <constant identifier>" when <constant identifier> was
// defined using the above syntax. Here we must replace <constant identifer> with a constant literal or a
// #define'd constant name.
// 2) Any constant defined using the above syntax CANNOT be used to indicate the dimensions of an array declared
// outside a function. Nor can they be used in "case <constant>" expressions within a "switch" clause. We must
// define these constants using the #define construct.
//
// Thus, I've replaced all "const <type> IDENTIFIER = <value>" constructs with "#define IDENTIFIER <value>" throughout
// this file.
//
// See also: CXTRIALCODES.H in CXDRIVER development folder.
//
//
// REVISION HISTORY:
// 28mar2003-- Modified from the original CXTRIALCODES.H dtd 25mar2003. Keep in synch w/ future changes!
// 03nov2004-- Modified IAW same-dtd changes in CXTRIALCODES.H. Changes do not impact READCXDATA or EDITCXDATTA.
// 26jan2005-- Modified IAW changed in CXTRIALCODES.H dtd 25jan2005. Changes DO impact trial code processing in
// READCXDATA. EDITCXDATA unaffected.
// 29jul2005-- Modified IAW changes in CXTRIALCODES.H dtd 29jul2005, re: content of TARGET_PERTURB code group. Changes
// will now permit reproduction of target trajectories perturbed by noise. As of Maestro v1.3.2.
// 03jan2006-- Modified IAW changes in CXTRIALCODES.H dtd 06dec2005, re: new trial code group RPDWINDOW and new special
// op code SPECIAL_RPDISTRO, in support of response distribution-based reward/penalty protocol. As of
// Maestro v1.4.0.
// 18mar2006-- Modified IAW changes in CXTRIALCODES.H dtd 13mar2006, re: TARGET_HOPEN. Comments only.
// 18apr2006-- Modified IAW changes in CXTRIALCODES.H dtd 10apr2006, re: new trial code TARGET_VSTAB.
// 27feb2007-- Modified IAW changes in CXTRIALCODES.H dtd 04jan2007, re: new special op codes SPECIAL_CHOOSEFIX*.
// 27feb2007-- Modified IAW changes in CXTRIALCODES.h dtd 27feb2007, re: INSIDE_***ACC trial codes.
// 16may2007-- Modified IAW changes in CXTRIALCODES.h dtd 25apr2007, re: new usage for SPECIALOP codes pertaining to
// the SPECIAL_RPDISTRO optype.
// 06sep2013-- Modified IAW changes in CXTRIALCODES.h dtd 01feb2011 and 05sep2013, re: special op code SPECIAL_SEARCH,
// and new constant MAXTRIALDUR.
// 01oct2018-- Modified IAW changes in CXTRIALCODES.h dtd 24sep2018 -- comments re: usage of PULSE_ON code to trigger
// RMVideo "vertical sync" flash at the start of a trial segment
// 13may2019-- Modified IAW change in CXTRIALCODES.h dtd 30apr2019 -- need to enclose definition of VSTAB_MASK in
// parentheses!
//=====================================================================================================================
#if !defined(CXTRIALCODES_MEX_H__INCLUDED_)
#define CXTRIALCODES_MEX_H__INCLUDED_
typedef struct tagTrialCode // one trial code block contains:
{
short code; // [block 0] the trial code; [other blocks] usage varies.
short time; // [block 0] trial time; [other blocks] usage varies.
} TRIALCODE, *PTRIALCODE;
// scale factors used in trial-code processing to encode floating-point values as short integers:
#define d_TC_STDSCALE 10.0
#define d_TC_SLOSCALE1 500.0
#define d_TC_SLOSCALE2 100.0
// trial duration must be less than max value of a short integer b/c trial codes store elapsed time with short ints!
#define MAXTRIALDUR 32760
// Existing MAESTRO trial codes and their format. LEGEND:
// purpose of trial code (N = #blocks)
// code1 = <description> --> contents of additional code blocks <1..N-1> described
// time1 = <description>
// ...
//
// Note that "target#" refers to the ordinal pos of the target's definition in the "trial target map" in IPC memory!
// That map, in turn, points to the target's actual definition in the "loaded target list", which also resides in IPC.
//
#define TARGET_ON 1 // turn specified target on (N=2); code1 = target#; time1 = notUsed
#define TARGET_OFF 2 // turn specified target off (N=2); code1 = target#; time1 = notUsed
#define TARGET_HVEL 3 // change target's horiz velocity (N=2)
// code1 = target#; time1 = (new velocity in deg/sec) * 10
#define TARGET_VVEL 4 // change target's verti velocity (N=2)
// code1 = target#; time1 = (new velocity in deg/sec) * 10
#define TARGET_HPOSREL 5 // add specified delta to target's horiz pos (N=2)
// code1 = target#; time1 = (pos change in deg) * 100
#define TARGET_VPOSREL 6 // add specified delta to target's verti pos (N=2)
// code1 = target#; time1 = (pos change in deg) * 100
#define TARGET_HPOSABS 7 // change target's horiz coord to specified value (N=2)
// code1 = target#; time1 = (new absolute coord in deg) * 100
#define TARGET_VPOSABS 8 // change target's verti coord to specified value (N=2)
// code1 = target#; time1 = (new absolute coord in deg) * 100
#define ADCON 10 // start saving ADC channel data & recording timer events (N=1)
#define ADCOFF 11 // stop saving ADC channel data & recording timer events (N=1) NO LONGER USED
#define FIXEYE1 12 // change fixation tgt#1 (N=2)
// code1 = target# of selected fixation tgt
// time1 = nonzero value enables periodic rewards during the segment!
#define FIXEYE2 13 // change fixation tgt#2 (N=2)
// code1 = target# of selected fixation tgt; time1 = notUsed
#define FIXACCURACY 14 // change behavioral fixation accuracy (N=2)
// code1 = (new H fixation accuracy in deg) * 100;
// time1 = (new V fixation accuracy in deg) * 100;
#define PULSE_ON 16 // turn on specified pulse for one scan period, and/or RMVideo sync flash (N=2)
// code1 = VSYNCPULSE (NO LONGER USED), or which timer digital output line
// should be pulsed (1 to 11)
// time1 = if nonzero, trigger RMVideo vertical sync spot flash
#define VSYNCPULSE 32 //
#define TARGET_HACC 18 // change target's horiz acceleration (N=2)
// code1 = target#; time1 = new acceleration in deg/sec^2
#define TARGET_VACC 19 // change target's verti acceleration (N=2)
// code1 = target#; time1 = new acceleration in deg/sec^2
#define TARGET_PERTURB 20 // apply velocity/directional perturbation waveform to a trial target (N=5).
// code1 = target#; time1 = (affected traj cmpt << 4) | pert type
// code2 = pert amplitude * 10 ; time2 = duration in ms
// The "affected traj cmpt" is one of the PERT_ON_* constants in CXOBJ_IFC.H, while "pert type" is one of the PERT_IS*
// constants. Note that the perturbation's duration can be longer than the segment in which it starts! The remaining
// (code,time) pairs in this code group are the defining parameters for the perturbation, as listed below.
//
// PERT_ISSINE: code3 = period in ms; time3 = phase in deg/100. code4,time4 = not used.
// PERT_ISTRAIN: code3 = pulse dur in ms; time3 = ramp dur in ms; code4 = pulse interval in ms; time4 = not used.
// PERT_ISNOISE: code3 = update interval in ms; time3 = mean * 1000 (range [-1000..1000]); code4 = HIWORD(seed);
// time4 = LOWORD(seed).
// PERT_ISGAUSS: same as for PERT_ISNOISE.
//
#define TARGET_HOPEN 21 // start velocity stabilization on fix tgt #1 at specified time (N=2)
// code1 = # of contiguous segments over which vel stab is in effect
// time1, bit0 = 0 for "OPEN" mode, 1 for "OPN2" mode (same as "OPEN", except
// tgt does not "snap" to eye at start of open-loop seg).
// time1, bit2..1 = 01b to stabilize H cmpt only, 10b to stabilize V cmpt
// only; otherwise, both cmpts are stabilized
// NOTE: Prior to 13mar06, code1 held tgt ID, but that usage has been obsolete
// since Maestro first came out b/c v. stab. restricted to fix tgt #1.
// OBSOLETE AS OF MAESTRO V2.0.0. REPLACED by TARGET_VSTAB
#define OPENMODE_MASK (1<<0)
#define OPENMODE_SNAP 0
#define OPENMODE_NOSNAP 1
#define OPENENA_MASK (0x03<<1)
#define OPENENA_HONLY 2
#define OPENENA_VONLY 4
#define TARGET_HSLOVEL 27 // analogous to TARGET_HVEL, but time1 = (new velocity in deg/sec) * 500
#define TARGET_VSLOVEL 28 // analogous to TARGET_VVEL, but time1 = (new velocity in deg/sec) * 500
#define TARGET_HSLOACC 29 // analogous to TARGET_HACC, but time1 = (new accel in deg/sec^2) * 100
#define TARGET_VSLOACC 30 // analogous to TARGET_VACC, but time1 = (new accel in deg/sec^2) * 100
#define DELTAT 36 // change XY scope update interval (N=2)
// code1 = new update interval (ms); time1 = notUsed
#define XYTARGETUSED 38 // specifies that a given target # will appear on XY scope (N=2)
// code1 = target#;
// time1 = 0 or #interleaved XY tgts in trial if tgt is to be interleaved
#define INSIDE_HVEL 39 // change target horizontal pattern vel (N=2)
// code1 = target#; time1 = (new pattern velocity in deg/sec) * 10
#define INSIDE_VVEL 40 // analogous to INSIDE_HVEL
#define INSIDE_HSLOVEL 41 // analogous to INSIDE_HVEL, but time1 = (new velocity in deg/sec) * 500
#define INSIDE_VSLOVEL 42 // analogous to INSIDE_HSLOVEL
// [Effective Maestro v2.1.0, mar 2007:]
#define INSIDE_HACC 45 // change target horizontal pattern acceleration (N=2)
// code1 = target#; time1 = new pattern acceleration in deg/sec^2
#define INSIDE_VACC 46 // analogous to INSIDE_HACC
#define INSIDE_HSLOACC 47 // analogous to INSIDE_HACC, but time1 = (new pat acc in deg/sec^2) * 100
#define INSIDE_VSLOACC 48 // analogous to INSIDE_HSLOACC
// [25apr2007] Effective Maestro v2.1.1, the SPECIAL_RPDISTRO feature supports four alternative behavioral
// response types (TH_RPD_*** in cxobj_ifc.h). To communicate the response type to MaestroDRIVER, the response
// type ID [0..3] is left-shifted 8 bits and bitwise-OR'd into 'code1'.
#define SPECIALOP 60 // perform special, saccade-triggered op during segment (N=2)
// code1 = optype, IF optype != SPECIAL_RPDISTRO (see below); ELSE
// = SPECIAL_RPDISTRO | (rpdRespType << 8), where rpdRespType
// is the type of behavioral response to measure
// time1 = saccade threshold velocity in deg/sec
#define SPECIAL_SKIP 1 // optype = "skip on saccade"
#define SPECIAL_FIX 2 // optype = "select by fixation"
#define SPECIAL_FIX2 3 // optype = "select by fixation, version 2"
#define SPECIAL_SWITCHFIX 4 // optype = "switch fix"
#define SPECIAL_RPDISTRO 5 // [05dec2005] optype = "R/P Distro"
#define SPECIAL_CHOOSEFIX1 6 // [04jan2007] optype = "choose fixation tgt #1"
#define SPECIAL_CHOOSEFIX2 7 // [04jan2007] optype = "choose fixation tgt #2"
#define SPECIAL_SEARCH 8 // [01feb2011] optype = "search task"
#define REWARDLEN 61 // reward pulse lengths; always sent at time0 = 0 (N=2)
// code1 = pulse length in msec; if SPECIAL_FIX trial, this pulse length
// applies when the subject "selects" the first fixation target. for
// all other trials, this sets the reward pulse length if fixation is
// maintained over the entire trial.
// time1 = 2nd pulse length in msec; applies to SPECIAL_FIX trial only --
// reward pulse of this length is given when the subject "selects"
// second fixation target. for all other trials, this is ignored.
#define PSGM_TC 62 // defining params for SGM electrical pulse stimulus seq (N=6)
// code1 = op mode; time1 = external trig (1) or s/w start (0).
// code2 = pulse 1 amplitude; time2 = pulse 2 amplitude.
// code3 = pulse 1 width; time3 = pulse 2 width.
// code4 = interpulse interval; time4 = intertrain interval.
// code5 = #pulses per train; time5 = #trains per sequence.
// NOTE: all params are sent regardless of mode, even though not all apply to
// all modes. params sent in non-encoded format (see SGMPARMS in cxobj_ifc.h)
#define CHECKRESPON 63 // begin checking subject's response (N=2) [staircase sequences only]
// code1 = ADC channel # to monitor for correct response
// time1 = ADC channel # to monitor for incorrect response
#define CHECKRESPOFF 64 // stop checking subject's response (N=1) [staircase sequences only]
#define FAILSAFE 65 // set "failsafe" time (N=1). if trial stops before this time, the collected
// data from the trial is discarded.
#define MIDTRIALREW 66 // [25jan2005] mid-trial reward parameters; always sent at time0 = 0 (N=2)
// code1: If <=0, use "atSegEnd" mode; rewards delivered at end of enabled
// segments. Else use "periodic" mode, in which case code1 is the
// reward interval in ms.
// time1: Midtrial reward pulse length in ms.
// This trial code is always sent after the SPECIALOP code for a trial that uses the "R/P Distro" operation and has at
// least one defined behavioral response window. It sets the bounds for up to two such windows, where the behavioral
// response is eye velocity magnitude in deg/sec, averaged over the course of the "special segment". The reward(s)
// delivered to the subject depend on the definition of these "reward windows". If none are defined, the subject only
// gets the regular end-of-trial reward, using reward pulse #1 as usual. If one or both windows are defined AND the
// measured response falls within one such window, then the subject has "passed the test" and gets two rewards:
// reward pulse #2 is delivered immediately after the special segment [NOT the same as the "atSegEnd" midtrial reward.
// Users are advised not to enable the "atSegEnd" midtrial reward for the "R/P Distro" special segment] and reward
// pulse #1 is delivered as the end-of-trial reward. If the measured response falls outside the defined reward
// window(s), the subject has "failed the test" and gets only reward pulse #2 as an end-of-trial reward. Of course,
// to properly motivate the subject, reward pulse #2 should be shorter than reward pulse #1.
//
// NOTE: If neither reward window is defined on the "R/P Distro" trial, then this trial code is NOT sent!
//
#define RPDWINDOW 67 // [05dec2005] reward window(s) for an "R/P Distro" operation (N=3)
// code1, time1: [min,max] for reward window #1, in deg/s * 10.
// code2, time2: [min,max] for reward window #2, in deg/s * 10.
// If a window is not defined, min==max==0.
#define TARGET_VSTAB 68 // alter velocity stabilization of specified tgt at specified time (N=2).
// code1 = target#
// time1 = velocity stabilization flag bits
// AS OF MAESTRO V2.0.0. REPLACES TARGET_HOPEN code. The code is sent whenever
// v-stab's effect on a target's trajectory changes.
// Velocity stabilization flag bits for TARGET_VSTAB:
#define VSTAB_ON (1<<0) // turn stabilization of target ON (set) or off (unset)
#define VSTAB_SNAP (1<<1) // if set AND stabilization is turning ON (ie, it was off during previous
// segment), then tgt is snapped to current eye pos.
#define VSTAB_H (1<<2) // enable (set) or disable (unset) stabilization of H component of motion
#define VSTAB_V (1<<3) // enable (set) or disable (unset) stabilization of V component of motion
#define VSTAB_MASK (VSTAB_ON|VSTAB_SNAP|VSTAB_H|VSTAB_V)
#define RANDOM_SEED 97 // specify seed for XY scope random # generator (N=2)
// code1 = HIWORD(randSeedLong); time1 = LOWORD(randSeedLong)
// 13jan2003: OBSOLETE!
#define STARTTRIAL 98 // first trial code (N=1)
#define ENDTRIAL 99 // specifies time at which trial stops (N=1)
#endif // !defined(CXTRIALCODES_MEX_H__INCLUDED_)
|