NexScript Language
We recommend to use Python when developing new scripts.
NeuroExplorer also has a less powerful (than Python) internal scripting language NexScript. NexScript syntax resembles the Matlab language.
Lines and Comments in NexScript
Each line of the script may contain only one statement, for example:
x = 0
If the statement is very long, you can use the line continuation symbol (backslash \
) to indicate
that the next line contains the continuation of the current line. For example, instead of:
Dialog(doc, "D:\Experiment101\data\mydata\*.nex5", "Filter", "string")
you can write:
Dialog(doc, "D:\Experiment101\data\mydata\*.plx",\
"Filter"", "string")
The percent symbol (%) marks the beginning of a comment in NexScript, for example:
% this is a comment line
x = 0 % this is also a comment
Variable Names
The variable name in NexScript should begin with a letter and contain only letters, digits and the underscore sign.
The following names are valid:
Neuron01 Bar_press Nr_1a SPK02b
These variable names cannot be used in NexScript:
2Neuron Bar-press
The variables from the opened data file can be accessed using the document reference with
the variable name specified in the square brackets.
For example, the spike train SPK01a
from the active document can be addressed as:
doc["SPK01a"]
where doc
is a reference to the document.
You can get this reference by calling GetActiveDocument()
or calling OpenDocument()
.
An alternative way to access file variable is by getting a reference to the variable:
SPK01a = GetVarByName(doc, "SPK01a")
Variable Types
NexScript supports numeric variables:
xmean = (xmax - xmin)/2.
and strings:
name = "SPK" + "01"
A variable can also be a reference to the existing variable in the file:
neuron1 = GetVar(doc, 1, "neuron")
or a reference to the opened document:
doc = GetActiveDocument()
A variable type can be changed if the right-hand side of the assignment has a different type. For example:
x = 0.005 % x now is a numeric variable
x = "SPK" % after this statement, x is a string
Global Variables
A variable can be declared global so that it can be accessed from several scripts:
Global name
Global
statements should be placed at the beginning of the script.
Assignments Involving File Variables
If the left-hand side of the assignment is not a file variable:
v = doc["Neuron01"]
the script variable v
will contain a reference (a shortcut) to the file variable Neuron01
and
Neuron01
spike times will not be copied to v
.
If the left-hand side of the assignment (doc["ContVarCopy"]
below) is a file variable:
doc["ContVarCopy"] = doc["ContChannel01"]
all the data of the file variable ContChannel01
will be copied to the new file variable ContVarCopy
.
For example, to create a new continuous variable containing rectified signal of continuous variable FP01
,
we can write the following code:
doc["FP01_Rectified"] = NewContVarWithFloats(doc, 10000)
for i=1 to GetContNumDataPoints(doc["FP01"])
t = doc["FP01"][i,1]
v = abs(doc["FP01"][i,2])
AddContValue(doc["FP01_Rectified"], t, v)
end
We can achieve the same result using variable references and copying data to a new variable (and the code below will run more than 7 times faster than the code above):
doc["FP01_Rectified"] = doc["FP01"]
rectified = doc["FP01_Rectified"]
ContVarStoreValuesAsFloats( rectified )
n = GetContNumDataPoints( rectified )
for i=1 to n
rectified[i,2] = abs( rectified[i,2] )
end
Access to the Data in File Variables
Timestamped Variables
You can access the timestamp value by specifying the timestamp index (1-based, i.e. the first timestamp has index 1) in square brackets:
doc = GetActiveDocument()
% first option: use doc["VarName"] notation
timestamp = doc["SPK01a"][3]
% second option: get variable by name and then use the variable directly
spikeTrain = doc["SPK01a"]
timestamp = spikeTrain[3]
You can assign a new value for any timestamp in the current file.
For example, to assign the value 0.5 (sec) to the third timestamp of the variable SPK01a
, you can use this script:
doc = GetActiveDocument()
doc["SPK01a"][3] = 0.5
You can also add timestamps to a variable using NexScript functions. See Modifying Variable Data Functions for details.
Interval Variables
IntVar[i,1]
gives you read/write access to the start of the i-th interval, IntVar[i,2]
gives you read/write access
to the end of the i-th interval.
For example, to assign the value 27.5 seconds to the end of the first interval of interval variable Frame
, you would use this script:
doc = GetActiveDocument()
doc["Frame"][1,2] = 27.5
You can also add intervals to an interval variable using NexScript functions. See Modifying Variable Data Functions for details.
Continuous Variables
ContVar[i,1]
gives you read-only access to the timestamp of the i-th data point.
ContVar[i,2]
gives you read-write access to the value of the i-th data point.
For example, the following script prints the timestamp and the value of the fifth data point in variable ContChannel01
:
Trace("ts = ", doc["ContChannel01"][5,1], "value =" ,doc["ContChannel01"][5,2])
The following script line assigns the value of 100 to the fifth data point:
doc["ContChannel01"][5,2] = 100.0
Note that when you assign a value to a continuous variable that was imported from a file created by a data acquisition system, the assigned value might be clipped.
Data acquisition systems usually store continuous values as 2-byte integers. NeuroExplorer also stores imported analog data as 2-byte integers with some scaling factors.
For example, if analog to digital converter has input range from -1000mV to +1000mV, then maximum 2-byte value 32767 corresponds to 1000mV and the scaling factor is 1000/32768. If we try to assign the value that is outside the original input range, the value has to be clipped so that it could be stored as a 2-byte integer. For example, if we try to assign 2000mV, the stored value will be 32767 or 1000mV.
To avoid data clipping, use ContVarStoreValuesAsFloats()
function to convert 2-byte integer storage
to 4-byte float storage that does not have clipping problems.
Marker Variables
MarkerVar[i,1]
gives you read-only access to the timestamp of the i-th marker.
MarkerVar[i,2]
gives you read-only access to the value of the first field of the i-th marker.
Note that marker field values are stored as strings, so you will need to use StrToNum()
function to convert these values to numbers.
For example, the following script prints the timestamp and the first field value of the fifth marker in variable Strobed
:
Trace("ts = ", doc["Strobed"][5,1], "marker value =" ,doc["Strobed"]5,2])
Expressions
Standard algebraic expressions are supported:
xmean = (xmax - xmin)/2.
Addition operation can also be applied to the strings:
name = "SPK" + "01"
Logical expressions may be used in if
and while
statements:
x = 2
if x >= 2
Trace("x is greater or equal to 2")
end
if x > 2
Trace("x > 2")
end
if x <= 2
Trace("x <= 2")
end
if x == 2
Trace("x equals 2")
end
if x <> 1
Trace("x is not equal to 1")
end
Logical expressions may be combined using logical AND (&
) or logical OR (|
) operators:
if (x >= 2) & (y <4)
Trace("x <=2 and y <4")
end
if (x >= 2) | (y <4)
Trace("x <=2 or y <4")
end
Flow Control in NexScript
Loops
NexScript supports two types of loops: for
loops and while
loops.
for
loop has the following syntax:
for variable = expression to expression
statements ...
end
Example:
for i = 1 to 10
SelectVar(doc, i, "neuron")
end
while
loop has the following syntax:
while logical_expression
statements ...
end
Example:
i = 1
while i < 10
SelectVar(doc, i, "neuron")
i = i + 1
end
break
break
statement causes an immediate exit from the loop.
The following loop
for i = 1 to 10
Trace(i)
if i == 5
break
end
end
will produce output: 1 2 3 4 5
continue
continue
statement returns to the loop’s beginning skipping the statements that follow it.
The following loop
for i = 1 to 5
if i == 3
continue
end
Trace(i)
end
will produce output: 1 2 4 5
return
return
statement causes an immediate exit from the script.
Conditional operators
Operator if
has the following syntax:
if logical_expression
statements ...
end
or
if logical_expression
statements ...
else
statements ...
end
Example
% select a variable if it has at lest one spike
% otherwise, deselect the variable
if GetVarCount(doc, i, "neuron") > 0
SelectVar(doc, i, "neuron")
else
DeselectVar(doc, i, "neuron")
end