Here's a sample MEDM display of some of the the aCalcout record fields.
See the EPICS Record Reference Manual for information on how to specify database links.
Field | Summary | Type | DCT | Initial | Access | Modify | Rec Proc Monitor |
---|---|---|---|---|---|---|---|
INPA | Input Link A | INLINK | Yes | 0 | No | No | N/A |
INPB | Input Link B | INLINK | Yes | 0 | No | No | N/A |
... | ... | ... | ... | ... | ... | ... | ... |
INPL | Input Link L | INLINK | Yes | 0 | No | No | N/A |
INAA | Input Link AA | INLINK | Yes | 0 | No | No | N/A |
INBB | Input Link BB | INLINK | Yes | 0 | No | No | N/A |
... | ... | ... | ... | ... | ... | ... | ... |
INFLL | Input Link LL | INLINK | Yes | 0 | No | No | N/A |
The CALC expression is actually converted to opcodes and stored in postfix
notation in the RPCL field. It is this postfix expression which is actually
evaluated. When the CALC field is changed at run-time, the record-support
routine special()
calls a function to check it, convert it
to postfix, and evaluate it.
The record also has a second set of calculation-related fields described in
Section 5, Output Parameters.
Field | Summary | Type | DCT | Initial | Access | Modify | Rec Proc Monitor | PP |
---|---|---|---|---|---|---|---|---|
CALC | Calculation | STRING[36] | Yes | 0 | Yes | Yes | Yes | No |
VAL | Value | DOUBLE | No | 0 | Yes | Yes | Yes | No |
RPCL | Postfix | NOACCESS | No | 0 | No | No | N/A | No |
AVAL | Array value | DOUBLE | No | 0 | Yes | Yes | Yes | No |
Expressions supported by the array calculation record can involve operands, algebraic operators and functions, trigonometric functions, relational operators, logical operators, array operators and functions, parentheses and commas, and the conditional '?:' operator. The expression can consist of any of these operators, as well as any of the values from the scalar and array input fields, which are the operands.
Unless otherwise stated, functions and operators behave as follows:
aa+bb =
aa[0]+bb[0], aa[1]+bb[1],...
)
A+BB
is the array
a*bb[0], a*bb[1], a*bb[3],...
?: ^ ** >> <<
, the scalar value used is the
value of the first array element. In the following expressions, the array
argument in color will be converted implicitly to scalar:
The number of elements of the array operands AA-LL is set at boot time by the field NELM. If an array value is received by the record with more or fewer elements, the array used by the aCalcout record will be truncated or padded at the end with zeros.
Field | Summary | Type | DCT | Initial | Access | Modify | Rec Proc Monitor | PP |
---|---|---|---|---|---|---|---|---|
A | Input Value A | DOUBLE | No | 0 | Yes | Yes/No* | Yes | Yes |
B | Input Value B | DOUBLE | No | 0 | Yes | Yes/No* | Yes | Yes |
... | ... | ... | ... | ... | ... | ... | ... | ... |
L | Input Value L | DOUBLE | No | 0 | Yes | Yes/No* | Yes | Yes |
AA | Input array AA | DOUBLE ARRAY | No | 0 | Yes | Yes/No* | Yes | Yes |
BB | Input array BB | DOUBLE ARRAY | No | 0 | Yes | Yes/No* | Yes | Yes |
... | ... | ... | ... | ... | ... | ... | ... | ... |
LL | Input array LL | DOUBLE ARRAY | No | 0 | Yes | Yes/No* | Yes | Yes |
* If a valid input link is associated with this field, then the record will not not permit it to be modified by a 'put' operation.
There are a few special operands not associated with input fields, but
defined by the record (more exactly, defined by the calc engine the record uses
to evaluate expressions). All but RNDM
and ARNDM
are
constants.
PI | 3.141592654 |
D2R | Degrees to radians (PI/180) |
R2D | Radians to degrees (1/D2R) |
S2R | Arc seconds to radians (D2R/3600) |
R2S | Radians to arc seconds (1/S2R) |
RNDM | Random number between 0 and 1. |
ARNDM | Array of random numbers between 0 and 1. |
IX | Array [0,1,2,...]. |
Op | Description | Example |
---|---|---|
ABS | Absolute value (one-argument function) | ABS(A)
|
SQRT | Square root (one-argument function) (SQR is deprecated) | SQRT(A)
|
MIN | Minimum (two-argument function) | MIN(A,B)
|
MAX | Maximum (two-argument function) | MAX(A,B)
|
CEIL | Ceiling (one-argument function) | CEIL(A)
|
FLOOR | Floor (one-argument function) | FLOOR(A)
|
INT | Nearest integer (one-argument function) | INT(A)
|
NINT | Nearest integer (one-argument function) | NINT(A)
|
LOG | Log base 10 (one-argument function) | LOG(A)
|
LN | Natural logarithm (one-argument function) | LN(A)
|
LOGE | Deprecated synonym for 'LN' | LOGE(A)
|
EXP | Exponential function (unary) | EXP(A)
|
^ | Exponential (binary) (Same as '**'.) | A^B
|
** | Exponential (binary) (Same as '^'.) | A**B
|
+ | Addition (binary) | A+B
|
- | Subtraction (binary) | A-B
|
* | Multiplication (binary) | A*B
|
/ | Division (binary) | A/B
|
% | Modulo (binary) | A%B
|
- | Negate (unary) | -A
|
NOT | Negate (unary) | NOT A
|
>& | Max (binary) | A>?B
|
<& | Min (binary) | A<?B
|
Op | Description | Example |
---|---|---|
SIN | Sine (one-argument function) | SIN(A)
|
SINH | Hyperbolic sine (one-argument function) | SINH(A)
|
ASIN | Arc sine (one-argument function) | ASIN(A)
|
COS | Cosine (one-argument function) | COS(A)
|
COSH | Hyperbolic cosine (one-argument function) | COSH(A)
|
ACOS | Arc cosine (one-argument function) | ACOS(A)
|
TAN | Tangent (one-argument function) | TAN(A)
|
TANH | Hyperbolic tangent (one-argument function) | TANH(A)
|
ATAN | Arc tangent (one-argument function) | ATAN(A)
|
ATAN2 | Alternate form of arctangent (two-argument function) | ATAN2(A,B)
|
Op | Description | Example |
---|---|---|
>= | Greater than or equal to | A>=B
|
> | Greater than | A>B
|
<= | Less than or equal to | A<=B
|
< | Less than | A<B
|
!= | Not equal to (same as '#') | A!=B
|
# | Not equal to (same as '!=') | A#B
|
== | Equal to (same as '=') | A==B
|
= | Equal to (same as '==') | A=B
|
Op | Description | Example |
---|---|---|
&& | Logical AND | A&&B
|
|| | Logical OR | A||B
|
! | Logical NOT | !A
|
Op | Description | Example |
---|---|---|
| | Bitwise OR | A|B
|
OR | Bitwise OR | A OR B
|
& | Bitwise AND | A&B
|
AND | Bitwise AND | A AND B
|
XOR | Bitwise Exclusive OR | A XOR B
|
~ | One's Complement | ~A
|
<< | Left shift | A<<B
|
>> | Right shift | A>>B
|
A AND B
could be shortened to A ANDB
,
because ANDB
will be parsed as AND B
. However,
A AND B
may not be shortened to AAND B
, because
AAND
would be parsed as AA ND
.
?:
") operator is supported. The format is:
<expression> ? <expression-true result> : <expression-false result>
Op | Description | Example |
---|---|---|
AMIN | Minimal element of array (one-argument function) | AMIN(AA) -> scalar
|
AMAX | Maximal element of array (one-argument function) | AMAX('a','b','c') -> 'c'
|
ARR | Convert argument to array (one-argument function) | ARR(1) -> 1, 1, 1,...
|
[ | Subarray | AA[1,3] -> aa(1),aa(2),aa(3)
|
{ | Subarray in place | AA[1,3] -> 0, aa(1),aa(2),aa(3), 0,...
|
>> | Array shift right. Move array elements by index. | AA>>2
|
<< | Array shift left. Move array elements by index. | AA<<2 (same as AA>>-2 )
|
AVG | Average of array values | AVG(AA)
|
STD | Standard deviation of array values | STD(AA)
|
Op | Description | Example |
---|---|---|
@ | Scalar array element. Regard the numeric fields A-L as an array whose
elements are numbered 0-11, and return the element whose number follows.
Thus, @0 is another way of saying A .
(unary operator)
| @A
|
@@ | Array array element. Regard the array fields AA-LL as an array of arrays whose
elements are numbered 0-11, and return the element whose number follows.
Thus, @@1 is another way of saying BB .
(unary operator)
| @@A
|
A + B + 10
A + B + 10
(A + B) < (C + D)
1
if (A+B) < (C+D)
0
if (A+B) >= (C+D)
(A+B)<(C+D)?E:F+L+10
E
if (A+B) < (C+D)
F+L+10
if (A+B) >= (C+D)
(A+B)<(C+D)?E
E
if (A+B) < (C+D)
(A+B) >= (C+D)
A&B
A
to integer
B
to integer
AND
of A
and B
Notation: I'll use (1,2,3)
to indicate an array. Note that
[1,2] is not an array, but the subrange operator with arguments 1 and 2.
The subrange operator must follow an array, like so: AA[2,5]
.
Similarly, {1,2} is not an array, but the subrange-in-place operator.
A + AA
(2,3,4)
.
A + DBL(AA)
2
. DBL returns the first array element.
AA+BB
(8,10,12)
. Element-by-element sum. Most operators
behave in this way.
AA[2,4]
(3,4,5)
. (The first element of an array is
numbered "0".)
AA[-3,-1]
(2,3,4)
. (The last element of an array is
numbered "-1".)
AA{2,4}
(0,0,3,4,5,0)
. (Similar to the [] operator,
but the selected subrange is left in place.)
@0
A
. ("@0
"
is just another name for A
.)
@@0
@(A+B)
Every Time | write output every time record is processed. |
On Change | write output every time VAL changes, i.e., every time the result of the expression changes. |
When Zero | when record is processed, write output if VAL is zero. |
When Non-zero | when record is processed, write output if VAL is non-zero. |
Transition to Zero | when record is processed, write output only if VAL is zero and last value was non-zero. |
Transition to Non-zero | when record is processed, write output only if VAL is non-zero and last value was zero. |
Never | Don't write output ever. |
The DOPT field determines what data is written to the output link when the output is executed. The field is a menu field with two options: Use CALC or Use OCAL. If Use CALC is specified, when the record writes its output it will write the result of the expression in the CALC field, that is, it will write the value of the VAL [AVAL] field to a double [array] destination. If Use OCAL is specified, the record will instead write the result of the expression in the OCAL field, which result is contained in the OVAL field (array result in the OAV field). The OCAL field is exactly analogous to the CALC field and has the same functionality: it can contain an expression which is evaluated at run-time. Thus, if necessary, the record can use the result of the CALC expression to determine if data should be written and can use the result of the OCAL expression as the data to write.
If the OEVT field specifies a non-zero integer and the condition in the OOPT field is met, the record will post a corresponding event. If the ODLY field is non-zero, the record pauses for the specified number of seconds before executing the OUT link or posting the output event. During this waiting period the record is "active" and will not be processed again until the wait is over. The field DLYA is equal to 1 during the delay period. The resolution of the delay entry is one clock tick, where the clock frequency is defined elsewhere (see epicsThreadSleepQuantum() in the EPICS Application Developer's Guide).
The IVOA field specifies what action to take with the OUT link if the aCalcout record enters an INVALID alarm status. The options are Continue normally, Don't drive outputs, and Set output to IVOV. If the IVOA field is Set output to IVOV, the data entered into the IVOV field is written to the OUT link if the record alarm severity is INVALID.
Field | Summary | Type | DCT | Initial | Access | Modify | Rec Proc Monitor | PP |
---|---|---|---|---|---|---|---|---|
OUT | Output Specification | OUTLINK | Yes | 0 | Yes | Yes | N/A | No |
OOPT | Output Execute Option | Menu | Yes | 0 | Yes | Yes | No | No |
DOPT | Output Data Option | Menu | Yes | 0 | Yes | Yes | No | No |
OCAL | Output Calculation | STRING[36] | Yes | Null | Yes | Yes | No | No |
OVAL | Output Value | DOUBLE | No | 0 | Yes | Yes | Yes | No |
OEVT | Event To Issue | SHORT | Yes | 0 | Yes | Yes | No | No |
ODLY | Output Execution Delay | FLOAT | Yes | 0 | Yes | Yes | No | No |
IVOV | Invalid Output Action | Menu | Yes | 0 | Yes | Yes | No | No |
IVOA | Invalid Output Value | DOUBLE | Yes | 0 | Yes | Yes | No | No |
OAV | Output array value | DOUBLE ARRAY | NO | 0 | Yes | Yes | Yes | No |
WAIT | Wait for completion? | Menu | Yes | "NoWait" | Yes | Yes | Yes | No |
The aCalcout record uses device support to write to the
OUT
link. Soft device supplied with the record is selected with
the .dbd specification
field(DTYP,"Soft Channel")This device support uses the record's
WAIT
field to determine
whether to wait for completion of processing initiated by the OUT
link before causing the record to execute its forward link. The mechanism by
which this waiting for completion is performed requires that the
OUT
link have the attribute CA
-- i.e., the link text
looks something like
xxx:record.field CA NMS
Currently, the record does not try to ensure that WAIT
and
OUT
are compatibly configured. If WAIT
== "Wait",
but the link looks like
xxx:record.field PP NMS
for example, then the record will not wait for completion before executing its forward link.
The EGU field contains a string of up to 16 characters which is supplied by the user and which describes the values being operated upon. The string is retrieved whenever the routine get_units is called. The EGU string is solely for an operator's sake and does not have to be used.
The HOPR and LOPR fields only refer to the limits of the VAL, HIHI, HIGH, LOW, and LOLO fields. PREC controls the precision of the VAL field.
The INAV-INLV and IAAV-ILLV fields indicate the status of the link to the PVs specified in the INPA-INPL and INAA-INLL fields, respectively. The fields can have three possible values:
Ext PV NC | the PV wasn't found on this IOC and a Channel Access link hasn't been established. |
Ext PV OK | the PV wasn't found on this IOC and a Channel Access link has been established. |
Local PV | the PV was found on this IOC. |
Constant | the corresponding link field is a constant. |
The OUTV field indicates the status of the OUT link. It has the same possible values as the INAV-INLV fields.
The CLCV and OLCV fields indicate the validity of the expression in the CALC and OCAL fields, respectively. If the expression is invalid, the field is set to one.
The DLYA field is set to one during the delay interval specified in ODLY.
See the EPICS Record Reference Manual, for more on the record name (NAME) and description (DESC) fields.
Field | Summary | Type | DCT | Initial | Access | Modify | Rec Proc Monitor | PP |
---|---|---|---|---|---|---|---|---|
EGU | Engineering Units | STRING [16] | Yes | Null | Yes | Yes | No | No |
PREC | Display Precision | SHORT | Yes | 0 | Yes | Yes | No | No |
HOPR | High Operating Range | FLOAT | Yes | 0 | Yes | Yes | No | No |
LOPR | Low Operating Range | FLOAT | Yes | 0 | Yes | Yes | No | No |
INAV | Link Status of INPA | Menu | No | 1 | Yes | No | No | No |
INBV | Link Status of INPB | Menu | No | 1 | Yes | No | No | No |
... | ... | ... | ... | ... | ... | ... | ... | ... |
INLV | Link Status of INPL | Menu | No | 1 | Yes | No | No | No |
OUTV | OUT PV Status | Menu | No | 0 | Yes | No | No | No |
CLCV | CALC Valid | LONG | No | 0 | Yes | Yes | No | No |
OCLV | OCAL Valid | LONG | No | 0 | Yes | Yes | No | No |
DLYA | Output Delay Active | USHORT | No | 0 | Yes | No | No | No |
NAME | Record Name | STRING [29] | Yes | 0 | Yes | No | No | No |
DESC | Description | STRING [29] | Yes | Null | Yes | Yes | No | No |
IAAV | Link Status of INAA | Menu | No | 1 | Yes | No | No | No |
IBBV | Link Status of INBB | Menu | No | 1 | Yes | No | No | No |
... | ... | ... | ... | ... | ... | ... | ... | ... |
ILLV | Link Status of INLL | Menu | No | 1 | Yes | No | No | No |
The following alarm parameters which are configured by the user define the limit alarms for the VAL field and the severity corresponding to those conditions.
The HYST field defines an alarm deadband for each limit. See the EPICS Record Reference Manual for a complete explanation of alarms and these fields.
Field | Summary | Type | DCT | Initial | Access | Modify | Rec Proc Monitor | PP |
---|---|---|---|---|---|---|---|---|
HIHI | Hihi Alarm Limit | FLOAT | Yes | 0 | Yes | Yes | No | Yes |
HIGH | High Alarm Limit | FLOAT | Yes | 0 | Yes | Yes | No | Yes |
LOW | Low Alarm Limit | FLOAT | Yes | 0 | Yes | Yes | No | Yes |
LOLO | Lolo Alarm Limit | FLOAT | Yes | 0 | Yes | Yes | No | Yes |
HHSV | Severity for a Hihi Alarm | Menu | Yes | 0 | Yes | Yes | No | Yes |
HSV | Severity for a High Alarm | Menu | Yes | 0 | Yes | Yes | No | Yes |
LSV | Severity for a Low Alarm | Menu | Yes | 0 | Yes | Yes | No | Yes |
LLSV | Severity for a Lolo Alarm | Menu | Yes | 0 | Yes | Yes | No | Yes |
HYST | Alarm Deadband | DOUBLE | Yes | 0 | Yes | Yes | No | No |
Field | Summary | Type | DCT | Initial | Access | Modify | Rec Proc Monitor | PP |
---|---|---|---|---|---|---|---|---|
ADEL | Archive Deadband | DOUBLE | Yes | 0 | Yes | Yes | No | No |
MDEL | Monitor, i.e. value change, Deadband | DOUBLE | Yes | 0 | Yes | Yes | No | No |
The LALM field is used to implement the hysteresis factor for the alarm limits.
The LA-LL fields are used to decide when to trigger monitors for the corresponding fields. For instance, if LA does not equal the value for A, monitors for A are triggered. The MLST and MLST fields are used in the same manner for the VAL field.
Field | Summary | Type | DCT | Initial | Access | Modify | Rec Proc Monitor | PP |
---|---|---|---|---|---|---|---|---|
LALM | Last Alarmed Value | DOUBLE | No | 0 | Yes | No | No | No |
ALST | Archive Last Value | DOUBLE | No | 0 | Yes | No | No | No |
MLST | Monitor Last Value | DOUBLE | No | 0 | Yes | No | No | No |
LA | Previous Input Value for A | DOUBLE | No | 0 | Yes | No | No | No |
LB | Previous Input Value for B | DOUBLE | No | 0 | Yes | No | No | No |
... | ... | ... | ... | ... | ... | ... | ... | ... |
LL | Previous Input Value for A | DOUBLE | No | 0 | Yes | No | No | No |
LAA | Previous Input Value for AA | DOUBLE ARRAY | No | 0 | Yes | No | No | No |
LBB | Previous Input Value for BB | DOUBLE ARRAY | No | 0 | Yes | No | No | No |
... | ... | ... | ... | ... | ... | ... | ... | ... |
LLL | Previous Input Value for LL | DOUBLE ARRAY | No | 0 | Yes | No | No | No |
A routine postfix is called to convert the infix expression in CALC and OCAL to reverse polish notation. The result is stored in RPCL and ORPC, respectively.
upper_alarm_limit = HIHI
upper_warning_limit = HIGH
lower_warning_limit = LOW
lower_alarm_limit = LOLO