====== Calculate Functors — Complete Operator Documentation ======
----
====== Overview ======
Dinamica EGO provides a family of five **calculator functors** that evaluate an algebraic or logical expression and return a result of a specific type. All five share the same underlying **Image Expression Language**, but they differ in what they output, how many expressions they accept, and which language features are available in each context.
^ Functor ^ EGO Script Shorthand ^ Output Type ^ Evaluation context ^
| [[Calculate Map]] | ''#'' | Raster map (continuous) | Once per cell across a spatial grid |
| [[Calculate Categorical Map]] | ''##'' | Raster map (categorical) | Once per cell across a spatial grid |
| [[Calculate Value]] | ''$'' | Single scalar value | Once, with no spatial or row context |
| [[Calculate Lookup Table Values]] | ''%'' | Lookup table (values computed) | Once per row of a base lookup table |
| [[Calculate Lookup Table Keys And Values]] | %% | Lookup table (keys and values computed) | Once per row — two separate expressions |
The shorthand symbols are also referred to as **abbreviated syntax** — both terms mean the same thing and are used interchangeably in this documentation and in the Dinamica EGO GUI options.
The expression language, including all arithmetic, logical, conditional, spatial, and stochastic operators, is described in full in [[#the_expression_language|The Expression Language]] section. Per-functor restrictions and the availability of each operator category are noted both in each functor's own section and in the relevant expression-language subsections. For a complete description of the EGO Script syntax used to call these functors — including the shorthand symbols, hook blocks, and conversion between forms — see [[ego_script#calculator_functor_shorthand|Calculator functor shorthand]] in the EGO Script documentation.
----
====== Functor Reference ======
===== CalculateMap (''#'') =====
[[Calculate Map]] computes a new **continuous raster map** cell by cell using an algebraic or logical expression. The expression is evaluated independently for every cell in the output map. The result is always computed as a real (floating-point) value and then converted to the output map's chosen cell type.
When an expression references more than one connected map, all of them are evaluated at the same current cell. The connected maps do not need matching extent, resolution, or pixel dimensions beforehand — Dinamica EGO reconciles this automatically at runtime through image virtualization — but they do need to share the same projection. See [[#4_image_operators_and_functions|Co-located evaluation]] in section 4 for details.
==== Inputs and Parameters ====
^ Name ^ Type ^ Required ^ Default ^ Description ^
| Expression | Image Expression Type | **Yes** | — | The algebraic or logical formula used to compute each output cell. |
| Cell Type | Cell Type Type | No | Signed 32-bit Integer | Data type for each output cell (e.g., byte, int16, float32). |
| Null Value | Null Value Type | No | Based on Cell Type | Sentinel value representing "no data" in the output. |
| Result Is Sparse | Boolean Value Type | No | False | If ''True'', only non-null cells are stored — saves memory but slows random access. |
| Result Format | Map Type | No | None | Optional reference map whose spatial format (extent, resolution, projection) is applied to the output. Category information in the reference map is ignored. |
==== Output ====
^ Name ^ Type ^ Description ^
| Result | Map Type | The computed output map. |
==== Available expression features ====
All expression language features are available: image operators (''iX'', ''iX[line,col]''), the ''line'' and ''column'' spatial keywords, lookup table operators ([[#5_lookup_table_operators|section 5]]), multi-column table operators ([[#6_multi-column_table_operators|section 6]]), neighbourhood functions (''nbMin'', ''nbMax'', ''nbAverage'', etc. — [[#7_image_neighborhood_functions|section 7]]), neighbourhood indexing (''nbMinRef'', ''nbMaxRef'' — [[#8_image_neighborhood_indexing_functions|section 8]]), and the convolution operator (''nbConvol'' — [[#9_convolution_operator|section 9]]).
----
===== CalculateCategoricalMap (''##'') =====
Computes a new **categorical raster map** using an expression. Functionally identical to [[Calculate Map]] — the same inputs, parameters, and expression language apply — but the output is typed as a **categorical map**, which preserves category semantics for downstream functors that distinguish categorical maps from continuous maps (e.g., [[Calc Areas]], [[For Each Category]]).
Use [[Calculate Categorical Map]] when the expression produces integer class codes rather than measured or continuous values. A common pattern is reclassifying a continuous map into discrete categories based on thresholds.
==== Inputs and Parameters ====
^ Name ^ Type ^ Required ^ Default ^ Description ^
| Expression | Image Expression Type | **Yes** | — | The formula used to compute each output cell's category code. |
| Cell Type | Cell Type Type | No | Signed 32-bit Integer | Data type for each output cell. |
| Null Value | Null Value Type | No | Based on Cell Type | Sentinel value representing "no data" in the output. |
| Result Is Sparse | Boolean Value Type | No | False | If ''True'', only non-null cells are stored. |
| Result Format | Map Type | No | None | Optional reference map whose spatial format is applied to the output. |
==== Output ====
^ Name ^ Type ^ Description ^
| Result | Categorical Map Type | The computed categorical output map. |
==== Available expression features ====
Identical to [[Calculate Map]]: all operators, spatial keywords, neighbourhood functions, indexing functions, and convolution are available.
----
===== CalculateValue (''$'') =====
Evaluates an expression **once** and returns a single **scalar value**. Because there is no current cell, row, or spatial grid, all image-based and neighbourhood operators are unavailable.
[[Calculate Value]] is used to compute a single parameter — such as a global threshold, a weighted sum of scalar inputs, or a value derived from a table — that can then be passed as input to other functors.
==== Inputs and Parameters ====
^ Name ^ Type ^ Required ^ Default ^ Description ^
| Expression | Image Expression Type | **Yes** | — | An expression that evaluates to a single numeric result. |
==== Output ====
^ Name ^ Type ^ Description ^
| Result | Value Type | The computed scalar value. |
==== Available expression features ====
**Available:** all arithmetic and logical operators (sections [[#1_general_operators|1]] and [[#2_general_functions|2]]), scalar value references (''vX''), and lookup table queries (''tX[...]'') in all single-key and multi-column forms ([[#5_lookup_table_operators|section 5]], [[#6_multi-column_table_operators|section 6]]).
**Not available:** image operators (''iX'', ''iX[line,col]''), the ''line'' and ''column'' spatial keywords, neighbourhood functions, neighbourhood indexing functions, and the convolution operator. These all require a cell or row context that does not exist in [[Calculate Value]].
----
===== CalculateLookupTableValues (''%'') =====
[[Calculate Lookup Table Values]] evaluates an expression **once per row** of a base lookup table and writes the computed result as the **value** for that row in the output lookup table. The **keys** of the output table are inherited from the base table and are not recomputed.
When the base lookup table argument is ''.none'', the row set is not a union of all connected tables. Instead it comes from a single connected lookup table: in the verbose form, this is the lookup table connected via the ''NumberTable'' port with the lowest index (e.g. ''t1'' rather than ''t2''); in the shorthand form, it is the first lookup table referenced by name in the expression.
==== Inputs and Parameters ====
^ Name ^ Type ^ Required ^ Default ^ Description ^
| Expression | Image Expression Type | **Yes** | — | Formula evaluated for each row. The result becomes the value for that row's key in the output table. |
| Key Column Name | String | **Yes** | — | Name of the key column in the output lookup table. |
| Value Column Name | String | **Yes** | — | Name of the value column in the output lookup table. |
| Base Lookup Table | Lookup Table Type | No | ''.none'' | A lookup table whose key set drives iteration. When ''.none'', the lowest-indexed connected ''NumberTable'' (verbose form) or the first lookup table named in the expression (shorthand form) is used instead — not a union of all connected tables. |
==== Output ====
^ Name ^ Type ^ Description ^
| Result | Lookup Table Type | A lookup table with keys from the base table and values computed by the expression. |
==== The ''line'' and ''column'' keywords in a row-iteration context ====
Within the expression, **''line'' refers to the key of the current row** being iterated, not a spatial row index, and **''column'' refers to the value already associated with that key** in the base lookup table — the row's own existing value, available without looking it up explicitly. This allows the expression to read the row's current value directly via ''column'', and to look up related values from //other// connected tables using the current row's key: for example, ''t1[line]'' retrieves the value in table ''t1'' whose key matches the row currently being computed.
==== Available expression features ====
**Available:** arithmetic and logical operators (sections [[#1_general_operators|1]] and [[#2_general_functions|2]]), scalar references (''vX''), lookup table queries (''tX[...]'') in all single-key and multi-column forms ([[#5_lookup_table_operators|section 5]], [[#6_multi-column_table_operators|section 6]]), ''line'' (as the current row key), and ''column'' (as the current row's value in the base lookup table).
**Not available:** ''iX'', ''iX[line,col]'', neighbourhood functions, neighbourhood indexing, and convolution. There is no spatial grid.
----
===== CalculateLookupTableKeysAndValues (''%%'') =====
[[Calculate Lookup Table Keys And Values]] evaluates **two separate expressions** per row of a base lookup table — one for the **key** and one for the **value** — and writes both into the output lookup table. This allows complete transformation of a table's key-value structure, or construction of an entirely new lookup table row by row.
==== Inputs and Parameters ====
^ Name ^ Type ^ Required ^ Default ^ Description ^
| Key Column Expression | Image Expression Type | **Yes** | — | Formula evaluated for each row to produce the output key. |
| Value Column Expression | Image Expression Type | **Yes** | — | Formula evaluated for each row to produce the output value. |
| Key Column Name | String | **Yes** | — | Name of the key column in the output lookup table. |
| Value Column Name | String | **Yes** | — | Name of the value column in the output lookup table. |
| Base Lookup Table | Lookup Table Type | No | ''.none'' | A lookup table whose row set drives iteration. |
==== Output ====
^ Name ^ Type ^ Description ^
| Result | Lookup Table Type | A lookup table with both keys and values computed by the respective expressions. |
==== Available expression features ====
Same as [[Calculate Lookup Table Values]]: ''line'' represents the key of the current row in the base table, and ''column'' represents the value already associated with that key; ''vX'' and ''tX[...]'' are available (sections [[#5_lookup_table_operators|5]] and [[#6_multi-column_table_operators|6]]); spatial and image operators are not. Both the key expression and the value expression share the same set of connected operands.
----
====== Connecting Data Inputs ======
All data referenced in any expression must be connected to the functor's ports before writing the expression. This is done through **hook** functors — [[Number Map]], [[Number Table]], and [[Number Value]] — which bind a connected data source to a numbered identifier used inside the expression. The same port types apply across all five functors:
* **Maps** are connected via a [[Number Map]] hook → referenced as ''i1'', ''i2'', …, ''i100''
* **Tables and lookup tables** are connected via a [[Number Table]] hook → referenced as ''t1'', ''t2'', …, ''t100''
* **Scalar values** are connected via a [[Number Value]] hook → referenced as ''v1'', ''v2'', …, ''v100''
> **Tip:** Give every connected functor a descriptive alias. The expression editor lists all available identifiers with their aliases at the top, making complex models much easier to read and maintain. The alias is also what generates the functor's variable name, and that variable name is exactly what the shorthand notation references: a map aliased ''regions'', for example, is bound to the variable ''regions'' and is then referenced in a shorthand expression as ''#regions'', a table or lookup table as ''%regions'', and a value as ''$regions''. See [[ego_script#calculator_functor_shorthand|Calculator functor shorthand]] for details on the shorthand notation.
> **Note:** Map hook connections (''NumberMap'' / ''iX'') are only meaningful in [[Calculate Map]] and [[Calculate Categorical Map]]. In [[Calculate Value]], [[Calculate Lookup Table Values]], and [[Calculate Lookup Table Keys And Values]] there is no cell context, and ''iX'' references cannot be used in the expression.
----
====== The Expression Language ======
The expression is written in Dinamica EGO's **Image Expression Language** — a concise algebra where every term operates on the current evaluation unit (a cell, a table row, or nothing, depending on the functor). The language has eight categories of operators and functions described below.
Unless a restriction is noted, every operator is available in all five calculator functors.
===== Identifier Syntax =====
^ Symbol ^ Refers to ^ Available in ^
| ''iX'' | Value of map X at the current cell | [[Calculate Map]], [[Calculate Categorical Map]] only |
| ''tX'' | Connected table or lookup table X (used with a bracket operator) | All five functors |
| ''vX'' | Connected scalar value X | All five functors |
| ''line'' | Spatial row index of the current cell, **starting at 1** //(map calculators)// **or** key of the current row //(table calculators)// | All except [[Calculate Value]] |
| ''column'' | Spatial column index of the current cell, **starting at 1** //(map calculators)// **or** value associated with the current row's key //(table calculators)// | All except [[Calculate Value]] |
X ranges from 1 to 100. In logical expressions, **zero is false** and any non-zero value is true.
----
====== 1. General Operators ======
The table below lists all infix and prefix operators in **descending precedence order** (highest precedence = evaluated first). All operators are available in all five calculator functors.
^ Precedence ^ Operator ^ Syntax ^ Description ^ Example ^
| 1 | **Conditional** | ''if EXPR then EXPR else EXPR'' | Evaluates to the second expression if the condition is true, otherwise the third. Can be nested. | ''if i1 > 0 then i1 else 0'' |
| 2 | **Boolean Or** | ''EXPR or EXPR'' / ''EXPR || EXPR'' | True if either argument is true. **Short-circuit evaluated** — the right side is skipped if the left is already true. | ''isNull(i1) || i1 > 100'' |
| 2 | **Boolean And** | ''EXPR and EXPR'' / ''EXPR && EXPR'' | True only if both arguments are true. **Short-circuit evaluated** — the right side is skipped if the left is already false. | ''not isNull(i1) and i1 > 0'' |
| 3 | **Equal** | ''EXPR = EXPR'' / ''EXPR == EXPR'' | True if both sides are equal. | ''i1 == 2'' |
| 3 | **Not Equal** | ''EXPR != EXPR'' / ''EXPR /= EXPR'' / ''EXPR <> EXPR'' | True if both sides differ. | ''i1 != 0'' |
| 4 | **Greater Than** | ''EXPR > EXPR'' | | ''i1 > i2'' |
| 4 | **Greater Than Or Equal** | ''EXPR >= EXPR'' | | ''i1 >= v1'' |
| 4 | **Less Than** | ''EXPR < EXPR'' | | ''i1 < 100'' |
| 4 | **Less Than Or Equal** | ''EXPR <= EXPR'' | | ''i1 <= i2'' |
| 5 | **Add** | ''EXPR + EXPR'' | | ''i1 + i2'' |
| 5 | **Subtract** | ''EXPR - EXPR'' | | ''i1 - i2'' |
| 6 | **Multiply** | ''EXPR * EXPR'' | | ''i1 * 2.5'' |
| 6 | **Divide** | ''EXPR / EXPR'' | | ''i1 / i2'' |
| 6 | **Modulo** | ''EXPR % EXPR'' | Remainder after integer division | ''i1 % 100'' |
| 7 | **Power** | ''EXPR ^ EXPR'' | Exponentiation | ''i1 ^ 3'' |
| 8 | **Catch Error (''?'')** | ''EXPR ? EXPR'' | If the left expression produces an algebraic error (division by zero, key not found, etc.), return the right expression instead. | ''(i1 / i2) ? (i1 - i2)'' |
| 9 | **Boolean Not** | ''not EXPR'' / ''! EXPR'' | Inverts a boolean value. | ''not isNull(i1)'' |
| 9 | **Negate** | ''-EXPR'' | Arithmetic negation. | ''-ceil(i1 + i2)'' |
> **Note on null and equality:** Writing ''i1 == null'' does **not** test for null — because null participates in no arithmetic comparison, it always produces null itself, poisoning the expression. Always use ''isNull(i1)'' instead. See the [[#null_value_handling|Null Value Handling]] section for full details.
----
====== 2. General Functions ======
===== Mathematical Functions =====
All mathematical functions are available in all five calculator functors.
^ Function ^ Syntax ^ Description ^ Example ^
| Square Root | ''sqrt(EXPR)'' | | ''sqrt(i1 / i4)'' |
| Sin | ''sin(EXPR)'' | Sine; input in radians | ''sin(i1 / i4)'' |
| Cos | ''cos(EXPR)'' | Cosine; input in radians | ''cos(i1 + i2)'' |
| Tan | ''tan(EXPR)'' | Tangent; input in radians | ''tan(i1 * i5 + 6)'' |
| Acos | ''acos(EXPR)'' | Arccosine; output in radians | ''acos(i1 + i2)'' |
| Asin | ''asin(EXPR)'' | Arcsine; output in radians | ''asin(i1 + i2)'' |
| Atan | ''atan(EXPR)'' | Arctangent; output in radians | ''atan(i1 + i2)'' |
| Exp | ''exp(EXPR)'' | Natural exponential (e^x) | ''exp(i1 + i2)'' |
| Natural Logarithm | ''ln(EXPR)'' | log base e | ''ln(i1 / i4)'' |
| Log base 10 | ''log(EXPR)'' | | ''log(i1 / i4)'' |
| Absolute Value | ''abs(EXPR)'' | | ''abs(i1 + i2)'' |
| Ceiling | ''ceil(EXPR)'' | Smallest integer >= value | ''ceil(i1 + i2)'' |
| Floor | ''floor(EXPR)'' | Largest integer <= value | ''floor(i1 + i2)'' |
| Round | ''round(EXPR)'' | Round to nearest integer | ''round(i1 / i4)'' |
| Maximum | ''max(EXPR, EXPR)'' | Greater of two values | ''max(i1, i2)'' |
| Minimum | ''min(EXPR, EXPR)'' | Lesser of two values | ''min(i1, i4)'' |
| Signal | ''signal(EXPR)'' | Returns +1 if positive, -1 if negative, 0 if zero | ''signal(i1 - 4)'' |
| Pi | ''pi'' | The constant pi (3.14159265358979323846) | ''i1 * pi / 180'' |
===== Clamping Functions =====
^ Function ^ Syntax ^ Description ^ Example ^
| Clamp | ''clamp(EXPR, EXPR_MIN, EXPR_MAX)'' | Constrains a value to [min, max]. Equivalent to: ''if EXPR < MIN then MIN else if EXPR > MAX then MAX else EXPR'' | ''clamp(v1, 1, 12)'' |
| ClampMod | ''clampMod(EXPR, EXPR_MIN, EXPR_MAX)'' | Like clamp, but wraps around using modulo when the value is outside the range. Useful for cyclic quantities such as years or angles. Approximately: ''(EXPR - MIN) % (MAX - MIN + 1) + MIN'' | ''clampMod(v1, 2010, 2054)'' |
===== Random / Stochastic Functions =====
These functions generate a new random sample **for each evaluation unit** each time the expression is evaluated. In [[Calculate Map]] and [[Calculate Categorical Map]], this means one sample per cell, making them suitable for spatially stochastic models. In [[Calculate Lookup Table Values]] and [[Calculate Lookup Table Keys And Values]], one sample is drawn per table row. In [[Calculate Value]], a single sample is drawn for the whole expression.
^ Function ^ Syntax ^ Description ^ Example ^
| Uniform (0-1) | ''rand'' | Generates a random value uniformly in [0, 1). Used as a keyword, not a function call. | ''if rand > 0.5 then 1 else i2'' |
| Uniform (bounded) | ''rUniform(EXPR_MIN, EXPR_MAX)'' | Generates a random value uniformly between the given bounds. | ''if rUniform(12, 15) > 14 then 1 else i2'' |
| Normal | ''rNormal(EXPR_MEAN, EXPR_STDDEV)'' | Generates a random value from a Normal (Gaussian) distribution with the given mean and standard deviation. | ''if rNormal(10, 2) > 9 then 1 else i2'' |
| Poisson | ''rPoisson(EXPR_LAMBDA)'' | Generates a random integer from a Poisson distribution with the given lambda. | ''if rPoisson(100) > 95 then 1 else i2'' |
===== Control Functions =====
^ Function ^ Syntax ^ Description ^ Example ^
| Literal value | ''2'', ''-3.5e-2'', etc. | Any numeric literal, including scientific notation. | ''2 + i1 / -3.5e-2'' |
| Abort | ''abort'' | Immediately halts model execution. Useful as a guard inside a conditional to catch unexpected states. | ''if i1 > 0 then i1 * i2 + 4 else abort'' |
----
====== 3. Value Operators ======
Available in all five calculator functors.
^ Operator ^ Syntax ^ Description ^ Example ^
| Get Variable Value | ''vX'' | Returns the scalar (constant) value connected to port X. | ''v1 + t1[v2 + 4]'' |
----
====== 4. Image Operators and Functions ======
> **Availability:** [[Calculate Map]] and [[Calculate Categorical Map]] only. These operators require a cell context that does not exist in [[Calculate Value]], [[Calculate Lookup Table Values]], or [[Calculate Lookup Table Keys And Values]].
>
> **Exception:** ''line'' and ''column'' are also available in the two lookup table calculators, where they take on row-oriented meanings instead of spatial ones: ''line'' is the key of the current row, and ''column'' is the value associated with that key in the base lookup table being iterated.
^ Operator ^ Syntax ^ Description ^ Example ^
| Get Image Value | ''iX'' | Returns the value of image X at the **current cell**. | ''i2'' |
| Get Image Value At Location | ''iX[LINE_EXPR, COL_EXPR]'' | Returns the value of image X at the **specified (line, column) coordinate**. If the target cell is null, **returns 0** (not null). | ''i1[line - 1, column - 2]'' |
| Get Image Null Value | ''null'' | Returns the null sentinel value for the current output image, making the current cell null. Using ''null'' in arithmetic always poisons the result. | ''if i1 > 2 then i1 else null'' |
| Get Image Null Value (specific) | ''null(iX)'' | Returns the null sentinel value defined for image X specifically. | ''if null(i2) > 2 then 1 else null'' |
| Is Null | ''isNull(EXPR)'' | Returns 1 if the expression result is null, 0 otherwise. The **correct** way to test for null. | ''if not isNull(i1) then i1 else i2'' |
| Get Line Number | ''line'' | In map calculators: returns the **row index** of the current cell, **counting from 1**. In lookup table calculators: returns the **key of the current row**. | ''line + 1'' |
| Get Column Number | ''column'' | In map calculators: returns the **column index** of the current cell being processed, **counting from 1**. In lookup table calculators: returns the **value associated with the key of the current row** in the base lookup table. | ''if column / 2 > 50 then 1 else null'' |
> **Co-located evaluation.** When an expression references more than one map (''i1'', ''i2'', …), the **current cell is shared**: every ''iX'' is evaluated at the same ''line'' and ''column'' for each step of the calculation, so ''i1'' and ''i2'' always refer to the same spatial location, not just "image 1" and "image 2" in some generic sense. The connected maps do **not** need to have matching extent, resolution, or pixel dimensions beforehand — Dinamica EGO reconciles this automatically through **image virtualization**: each input map is transparently wrapped in a virtual version sharing a common extent and the highest resolution among the inputs, so that "the current cell" lines up to the same point on the ground across all of them. The one requirement that virtualization does //not// relax is **projection** — all maps given to the calculator at the same time must share the same projection. ''iX[LINE_EXPR, COL_EXPR]'' breaks the shared-cell default, letting an expression sample a given image at an explicit coordinate instead of the current cell.
> **''line'' and ''column''** in map calculators are invaluable for creating geometric masks, distance ramps, or for passing precise coordinates into ''iX[LINE, COL]'' lookups. Both are **1-indexed** — the top-left cell of the map is at ''line = 1, column = 1'', not 0. In [[Calculate Lookup Table Values]] and [[Calculate Lookup Table Keys And Values]], both keywords serve a different, row-oriented role: ''line'' is the key of the current table row, and ''column'' is the value already associated with that key in the base lookup table — so ''column'' lets the expression read the row's existing value without a separate table lookup, while ''t1[line]'' (or ''%someTable[line]'' in shorthand) reads the corresponding value from any other connected table.
----
====== 5. Lookup Table Operators ======
These operators query a **Lookup Table** (''tX'') — a single-key table — and return the associated value. The key lookup rule is controlled by a prefix operator inside the brackets. Available in all five calculator functors.
**General syntax:** ''tX[RULE EXPR]''
> If ''tX'' is bound to a multi-column Table (not a Lookup Table), an error is reported. See section 6 for multi-column tables.
^ Operator ^ Syntax ^ Description ^ Example ^
| Exact match | ''tX[EXPR]'' | Returns the value whose key **equals** the expression. Returns null if not found. | ''t2[i1 + 2]'' |
| Equal lower bound | ''tX[<= EXPR]'' | Returns the value for the **greatest key <= EXPR**. | ''t2[<= 14]'' |
| Strict lower bound | ''tX[< EXPR]'' | Returns the value for the **greatest key < EXPR**. | ''t2[< i1 + 2]'' |
| Equal upper bound | ''tX[>= EXPR]'' | Returns the value for the **smallest key >= EXPR**. | ''t2[>= i1 + i3]'' |
| Strict upper bound | ''tX[> EXPR]'' | Returns the value for the **smallest key > EXPR**. | ''t2[> i7]'' |
| Closest key | ''tX[>< EXPR]'' | Returns the value for the key **nearest to EXPR** (ties go to the lower key). | ''t2[>< 3 + i7]'' |
| Linear interpolation | ''tX[/ EXPR]'' | Returns a **linearly interpolated value** between the two surrounding keys. | ''t2[/ i2]'' |
| Key existence test | ''tX[? EXPR]'' / ''tX[=? EXPR]'' / ''tX[==? EXPR]'' | Returns **1** if EXPR matches a key in the table, **0** otherwise. Does not retrieve a value. | ''t2[? i2]'' |
| Named attribute | ''tX["NAME"]'' | Returns the value bound to a **predefined attribute name** (e.g. ''"cellArea"''). Only valid for tables produced by [[Extract Map Attributes]] or [[Extract Lookup Table Attributes]]. | ''t2["cellArea"]'' |
The bound operators (''<='', ''<'', ''>='', ''>'', ''><'', ''/'') are especially useful for **range-based reclassification** and **interpolation**, where your table defines breakpoints rather than exact class codes.
----
====== 6. Multi-Column Table Operators ======
These operators query a regular **Table** (''tX'') — one with multiple key columns and one or more data columns — using a set of keys simultaneously. Available in all five calculator functors.
**General syntax:** ''tX[ [KEY1, KEY2, ...] ]'' or ''tX[ [KEY1, KEY2, ...] [COL] ]''
> If ''tX'' is bound to a Lookup Table (single-key), an error is reported.
^ Operator ^ Syntax ^ Description ^ Example ^
| Default column | ''tX[ [EXPR, EXPR, ...] ]'' | Returns the value in the **first data column** matching the given set of keys. | ''t2[ [i1 + 2, i2/2, t1[v2]] ]'' |
| Named column | ''tX[ [EXPR, EXPR, ...] ["COL_NAME"] ]'' | Returns the value in the **named data column** matching the given set of keys. | ''t2[ [i1 + 2, i2/2, t1[v2]] ["Area_In_Hectares"] ]'' |
| Indexed column | ''tX[ [EXPR, EXPR, ...] [EXPR] ]'' | Returns the value in the **column indexed by the second expression** matching the given set of keys. | ''t2[ [i1 + 2, i2/2, t1[v2]] [v1+2] ]'' |
These operators allow joining spatial data to rich tabular datasets at the cell level — for example, retrieving a transition probability from a multi-dimensional probability table keyed by land-use class and elevation zone.
----
====== 7. Image Neighborhood Functions ======
> **Availability:** [[Calculate Map]] and [[Calculate Categorical Map]] only. A spatial grid is required.
Neighborhood operators aggregate values from a rectangular window centred on the current cell.
**Full syntax:** ''nbN(IMAGE, h, w, y, x)'' \\
**Short syntax (window centred on current cell):** ''nbN(IMAGE, h, w)''
^ Parameter ^ Meaning ^
| ''N'' | Operator name (see table below) |
| ''IMAGE'' | An image identifier (''iX'') |
| ''h'' | Number of window rows |
| ''w'' | Number of window columns |
| ''y'' | Row coordinate to anchor the window centre (optional) |
| ''x'' | Column coordinate to anchor the window centre (optional) |
The window centre defaults to the current cell when ''y'' and ''x'' are omitted. For even-sized windows, the centre is displaced toward the top-left corner. **Null cells within the window are excluded from all calculations.**
^ Operator ^ Syntax ^ Description ^ Example ^
| Minimum | ''nbMin(...)'' | Minimum value among non-null cells in the window | ''nbMin(i4, 2, 3, line-1, column)'' |
| Maximum | ''nbMax(...)'' | Maximum value among non-null cells in the window | ''nbMax(i1, 4, 4) - 1'' |
| Sum | ''nbSum(...)'' | Sum of non-null cells in the window | ''nbSum(i3, 5, 5) + 7'' |
| Product | ''nbProd(...)'' | Product of all non-null cells in the window | ''if not isNull(i1) then nbProd(i1, 2, 2, 0, column) else 0'' |
| Count | ''nbCount(...)'' | Number of non-null cells in the window | ''nbCount(i2, 3, 3) + nbCount(i1, 3, 3, line, column+3)'' |
| Average | ''nbAverage(...)'' | Arithmetic mean of non-null cells in the window | ''round(nbAverage(i1, 7, 7))'' |
| Median | ''nbMedian(...)'' | Median of non-null cells. For an even count, the **greater** of the two central values is returned. | ''nbMedian(i1, 5, 5)'' |
| Mode | ''nbMode(...)'' | Most frequent value among non-null cells. Returns null if no mode exists; returns the **lesser** value if multiple modes tie. | ''nbMode(i1, 5, 5)'' |
| Variance | ''nbVar(...)'' | Population variance of non-null cells: sum of (xi - mean)^2 / n | ''nbVar(i4, 7, 7) / 25'' |
| Standard Deviation | ''nbStdDev(...)'' | Population standard deviation of non-null cells: sqrt of variance | ''nbStdDev(i2, 3, 3, line+1, column)'' |
----
====== 8. Image Neighborhood Indexing Functions ======
> **Availability:** [[Calculate Map]] and [[Calculate Categorical Map]] only.
These operators compute a neighbourhood statistic and then use the result as an **index** to retrieve a value from either a lookup table or a second image.
**Full syntax:** \\
''nbN(IMAGE, h, w, TABLE, y, x)'' \\
''nbN(IMAGE, h, w, IMAGE2, y, x)''
**Short syntax (window centred on current cell):** \\
''nbN(IMAGE, h, w, TABLE)'' \\
''nbN(IMAGE, h, w, IMAGE2)''
When a **TABLE** is provided: the statistic is used as a key to query the lookup table. \\
When an **IMAGE2** is provided: the statistic is used as a pixel coordinate to sample ''IMAGE2''.
^ Operator ^ Syntax ^ Description ^ Example ^
| MinRef | ''nbMinRef(...)'' | Finds the minimum in the window, then uses it as an index. | ''nbMinRef(i4, 2, 3, t1, line, column)'' |
| MaxRef | ''nbMaxRef(...)'' | Finds the maximum in the window, then uses it as an index. | ''nbMaxRef(i4, 2, 3, i1, line, column)'' |
----
====== 9. Convolution Operator ======
> **Availability:** [[Calculate Map]] and [[Calculate Categorical Map]] only.
''nbConvol'' applies a kernel-weighted convolution to an image — for spatial filtering such as Gaussian blur or edge detection.
**Syntax:** ''nbConvol(IMAGE, TABLE, h, w)'' / ''nbConvol(IMAGE, TABLE, h, w, y, x)''
^ Parameter ^ Meaning ^
| ''IMAGE'' | The image to convolve (''iX'') |
| ''TABLE'' | A Table whose entries are the kernel coefficients, indexed 1 to h*w, mapped **left-to-right, top-to-bottom** |
| ''h'' | Number of kernel rows |
| ''w'' | Number of kernel columns |
| ''y'', ''x'' | Anchor position (optional; defaults to window centre) |
**Kernel index mapping for a 3x3 kernel (h=3, w=3):**
^ Table key ^ Window position ^
| 1 | top-left |
| 2 | top-centre |
| 3 | top-right |
| 4 | mid-left |
| 5 | centre |
| 6 | mid-right |
| 7 | bottom-left |
| 8 | bottom-centre |
| 9 | bottom-right |
**Example:** Apply a Gaussian-blur kernel stored in ''t1'' over a 3x3 window on ''i1'':
nbConvol(i1, t1, 3, 3)
----
====== Null Value Handling ======
===== General rule (all five functors) =====
A null value in any operand **poisons the entire expression**: the result becomes null regardless of what the rest of the expression does. This is not a special case — it is the default behaviour for every operator and every operand type, across all five calculator functors.
^ Expression ^ Null behaviour ^
| ''i1 / 0'' | Always null (division by zero on a map cell) |
| ''v1 / 0'' | Always null — division by zero is null regardless of operand type |
| ''t1[v1]'' | Null if the key ''v1'' is not found in lookup table ''t1'' |
| ''i1 + t1[line] / v1 ^ 3'' | Null if the map cell ''i1'', the table lookup ''t1[line]'', or the value ''v1'' is null |
| ''if isNull(t1[v1]) then 1 else 2'' | **Never null** — ''isNull'' itself always resolves to 0 or 1 |
| ''if isNull(v1) then i2 else t1[line]'' | May be null, depending on ''i2'' or the table lookup ''t1[line]'' |
| ''(100 / v2) ? 0'' | **Never null** — div-by-zero on a value falls back to 0 |
| ''(t1[v1]) ? i1'' | If the key ''v1'' is not found in ''t1'', falls back to ''i1''; may still be null if ''i1'' is null |
The poison spreads through the entire chain: if ''i1'' is null, then ''i1 + 5'' is null, ''(i1 + 5) * v1'' is null, and so on. There is no way to "un-null" a result once a null has entered the calculation — except by explicitly testing for it first.
In a realistic expression, null can enter from several independent sources simultaneously. This expression computes a weighted transition probability from two input maps and a per-class calibration table:
(i1 * t1[i3] + i2 * (1 - t1[i3])) / v1
Here ''i1'' is a distance map, ''i2'' a slope map, ''i3'' a land-use class map, ''t1'' a calibration table keyed by class code, and ''v1'' a normalisation scalar. The result is null if //any// of the following is true at the current cell: ''i1'', ''i2'', or ''i3'' is null; the class code in ''i3'' is not a key in ''t1''; or ''v1'' is zero. A single missing class in the calibration table silently nulls every cell of that class, which may be difficult to diagnose. The defensive form makes each failure mode explicit:
if isNull(i1) or isNull(i2) or isNull(i3) then null
else (i1 * (t1[i3] ? 0) + i2 * (1 - (t1[i3] ? 0))) / v1
The ''?'' operator provides a fallback of 0 for any missing table key, so cells whose class is absent from the calibration table are treated as having zero weight rather than propagating null.
**Two safe patterns for handling nulls — applicable to map cells, table lookups, and scalar values alike:**
- ''isNull(EXPR)'' — test for null and branch:
if isNull(t1[v1]) then 0 else t1[v1]
- ''EXPR ? FALLBACK'' — catch any algebraic error and substitute a fallback:
(v1 / v2) ? 0
> **Note:** ''isNull()'' is immune to the poisoning rule — it always returns 0 or 1, never null, even when its argument is null. It is the only reliable way to branch on null.
If the computed real value exceeds the range of the chosen Cell Type, that cell is also written as null rather than wrapping or clipping. This range check applies to the map calculators only, since the other calculator functors do not write to a typed cell grid.
===== Exceptions in map calculators =====
> **Availability:** [[Calculate Map]] and [[Calculate Categorical Map]] only. The two exceptions below involve ''iX'' references and neighbourhood functions, which do not exist in the other three calculator functors.
* **Coordinate lookup** ''iX[LINE_EXPR, COL_EXPR]'' — accessing a map at a specific coordinate returns **0**, not null, when the target cell is null. This is the one case where a null input does not poison the output. It can be a source of subtle bugs: an expression that tests ''i1[line-1, column] > 0'' will silently treat a null neighbour as zero rather than null. A table or lookup-table key lookup (''tX[EXPR]'') that finds no matching key still returns null as normal — this exception applies only to map coordinate lookups.
* **Neighbourhood functions** ''nbN(iX, h, w)'' — operators such as ''nbSum'', ''nbAverage'', ''nbMax'', and so on aggregate over a window of cells and **exclude null cells from the calculation**. If ''i1'' is null at the current cell, the neighbourhood function simply ignores it and aggregates the remaining non-null cells in the window.
----
====== EGO Script Syntax ======
When writing expressions inside a ''.ego'' script file (see [[ego_script|EGO Script Language]]), the expression must be enclosed in square brackets ''[ ]''. Below are examples of each functor in both shorthand and verbose form.
> **A note on operand naming.** Throughout the expression-language tables above, operands are written generically as ''iX'', ''tX'', and ''vX'' — the **numbered** form, used when a port is connected via an explicit **hook** functor (''NumberMap'', ''NumberTable'', or ''NumberValue'') in the **verbose** form below. EGO Script's **shorthand** form instead refers to operands **by name** — the variable already bound elsewhere in the script — prefixed with a sigil that marks its type: ''#'' for a map, ''%'' for a table or lookup table, ''$'' for a value. So ''i1'' in a verbose expression corresponds to ''#someMapVariable'' in the shorthand version of the same expression, ''t1'' corresponds to ''%someTableVariable'', and ''v1'' corresponds to ''$someValueVariable''. The two forms are interchangeable but cannot be mixed within a single expression. See [[ego_script#calculator_functor_shorthand|Calculator functor shorthand]] in the EGO Script documentation for a full description of both forms.
===== CalculateMap (''#'') =====
// Shorthand — normalise a map to the [0, 1] range
result := # [ (#inputMap - $minVal) / ($maxVal - $minVal) ] .float32 .default .no .none;
// Verbose equivalent
result := CalculateMap {
expression = [ (i1 - v1) / (v2 - v1) ],
cellType = .float32,
nullValue = .default,
resultIsSparse = .no,
resultFormat = .none
} {{
// i1
NumberMap inputMap 1;
// v1
NumberValue minVal 1;
// v2
NumberValue maxVal 2;
}};
===== CalculateCategoricalMap (''##'') =====
// Shorthand — reclassify a continuous map into three categories
landUse := ## [
if #elevationMap < $lowThreshold then 1
else if #elevationMap < $highThreshold then 2
else 3
] .int8 .default .no .none;
// Verbose equivalent
landUse := CalculateCategoricalMap {
expression = [
if i1 < v1 then 1
else if i1 < v2 then 2
else 3
],
cellType = .int8,
nullValue = .default,
resultIsSparse = .no,
resultFormat = .none
} {{
// i1
NumberMap elevationMap 1;
// v1
NumberValue lowThreshold 1;
// v2
NumberValue highThreshold 2;
}};
===== CalculateValue (''$'') =====
// Shorthand — compute a weighted combination of two scalar inputs
blendedRate := $ [ $weight * $rateA + (1 - $weight) * $rateB ];
// Verbose equivalent
blendedRate := CalculateValue {
expression = [ v1 * v2 + (1 - v1) * v3 ]
} {{
// v1
NumberValue weight 1;
// v2
NumberValue rateA 2;
// v3
NumberValue rateB 3;
}};
// Shorthand — look up a scalar threshold from a calibration table
threshold := $ [ %calibrationTable[$targetClass] ];
// Verbose equivalent
threshold := CalculateValue {
expression = [ t1[v1] ]
} {{
// t1
NumberTable calibrationTable 1;
// v1
NumberValue targetClass 1;
}};
===== CalculateLookupTableValues (''%'') =====
// Shorthand — mark each row in a lookup table where value meets a threshold
hilltops := % [
if %saddleHeights[line] >= $minimumHeight and %saddleAngles[line] >= $minimumSlopeAngle then 1 else null
] "Top_Id" "Is_Hilltop" .none;
// Verbose equivalent
hilltops := CalculateLookupTableValues [
if t1[line] >= v1 and t2[line] >= v2 then 1 else null
] "Top_Id" "Is_Hilltop" .none {{
// t1
NumberTable saddleHeights 1;
// t2
NumberTable saddleAngles 2;
// v1
NumberValue minimumHeight 1;
// v2
NumberValue minimumSlopeAngle 2;
}};
// Shorthand — transform values using a calibration lookup table, iterating base table keys
dominantTops := % [
if %dominanceLookup[line] = line then 1 else null
] "Top_Id" "Is_Dominant" dominanceLookup;
===== CalculateLookupTableKeysAndValues (''%%'') =====
// Shorthand — extract two columns from a multi-column table into a new lookup table
nearestDistances := %% {
keyColumnExpression = [ %nearestPoints[[line]["Point_Id"]] ],
valueColumnExpression = [ %nearestPoints[[line]["Nearest_Distance"]] ],
keyColumnName = "Point_Id",
valueColumnName = "Nearest_Distance",
baseLookupTable = pointKeys
};
// Verbose equivalent
nearestDistances := CalculateLookupTableKeysAndValues [
t1[[line]["Point_Id"]]
] [
t1[[line]["Nearest_Distance"]]
] "Point_Id" "Nearest_Distance" pointKeys {{
// t1
NumberTable nearestPoints 1;
}};
----
====== Practical Examples ======
===== CalculateMap examples =====
==== Normalise a raster to [0, 1] ====
(i1 - v1) / (v2 - v1)
''i1'' = input map; ''v1'' = global minimum, ''v2'' = global maximum.
==== Weighted combination of two probability maps ====
i1 * v1 + i2 * (1 - v1)
''i1'', ''i2'' = the two maps to blend; ''v1'' = blending weight.
==== Convert degrees to radians and apply a trig function ====
sin(i1 * pi / 180)
''i1'' = map of values in degrees.
==== Clamp output to a valid range ====
clamp(i1 * v1 + i2 * v2, 0, 1)
''i1'', ''i2'' = input maps; ''v1'', ''v2'' = their respective blending weights.
==== Fill null cells with the local mean ====
if isNull(i1) then nbAverage(i1, 3, 3) else i1
''i1'' = input map.
==== Focal range (texture measure) ====
nbMax(i1, 5, 5) - nbMin(i1, 5, 5)
''i1'' = input map.
==== Stochastic perturbation with Gaussian noise ====
i1 + rNormal(0, v1)
''i1'' = input map; adds Gaussian noise with zero mean and standard deviation ''v1'' to every cell.
==== Coordinate-based gradient ramp ====
line / v1
Produces a north-to-south gradient scaled by scalar ''v1''.
==== Arbitrary pixel lookup (map sampling at computed location) ====
i2[round(i1), column]
For each cell, samples ''i2'' at the row given by image ''i1'', same column.
==== Guard against division by zero with a fallback ====
(i1 / i2) ? (i1 - i2)
''i1'' = numerator map, ''i2'' = denominator map. If ''i2'' is zero at a cell, falls back to ''i1 - i2'' instead of producing null.
----
===== CalculateCategoricalMap examples =====
==== Binary mask from a category map ====
if i1 == 2 then 1 else 0
''i1'' = input categorical map.
==== Multi-condition reclassification into categories ====
if i1 == 1 then 10
else if i1 == 2 then 20
else if i1 == 3 then 35
else null
''i1'' = input categorical map.
==== Reclassify a continuous map into classes using lookup table breakpoints ====
t1[<= i1]
''i1'' = continuous input map; ''t1'' = breakpoint lookup table mapping value thresholds to category codes. Assigns each cell the category value from ''t1'' whose key is the greatest key <= the cell value — implementing interval-based reclassification without if/else chains.
==== Assign a category based on multiple input maps ====
if i1 > v1 and i2 < v2 then 1
else if i1 > v1 then 2
else 3
''i1'' = slope map, ''i2'' = distance map; ''v1'', ''v2'' = threshold scalars.
==== Reclassify using a lookup table of region memberships ====
if %regionCounts[?#regions] then 1 else null
Assigns category 1 to every cell whose region identifier (map ''regions'') appears as a key in lookup table ''regionCounts'', null otherwise. Written in shorthand: the map is referenced as ''#regions'' and the lookup table as ''%regionCounts''.
----
===== CalculateValue examples =====
==== Compute a weighted average of two scalar parameters ====
v1 * v2 + (1 - v1) * v3
''v1'' = weight, ''v2'', ''v3'' = the two values to blend.
==== Look up a scalar threshold from a calibration table ====
t1[v1]
''t1'' = calibration lookup table, ''v1'' = the key to look up.
==== Derive a running counter increment ====
v1 + 1
When ''v1'' holds the previous iteration's counter value, this computes the next step.
==== Convert a parameter value using a linear formula ====
(v1 - v2) / (v3 - v2)
Normalises ''v1'' to the range defined by ''v2'' (minimum) and ''v3'' (maximum).
----
===== CalculateLookupTableValues examples =====
==== Mark rows that satisfy a threshold condition ====
if t1[line] >= v1 and t2[line] >= v2 then 1 else null
''t1'', ''t2'' = operand lookup tables; ''v1'', ''v2'' = threshold values. Iterates over all row keys; ''t1[line]'' and ''t2[line]'' retrieve the corresponding values from each table.
==== Apply a multiplicative scaling factor to existing table values ====
t1[line] * v1
Scales every value in table ''t1'' by a constant ''v1'', producing a new lookup table with the same keys.
==== Identify rows where a key equals its own value ====
if t1[line] = line then 1 else null
Returns 1 for rows where the value stored under that key equals the key itself.
==== Range-based reclassification via an interval table ====
t1[<= line]
For each key, looks up the value from ''t1'' whose key is the greatest key <= the current row key — interpolating class membership from a breakpoint table.
----
===== CalculateLookupTableKeysAndValues examples =====
==== Extract two columns from a multi-column table into a lookup table ====
// Key expression
t1[[line]["Point_Id"]]
// Value expression
t1[[line]["Nearest_Distance"]]
For each row in the base lookup table, the key is drawn from the ''"Point_Id"'' column of ''t1'' and the value from ''"Nearest_Distance"''.
==== Remap keys and scale values simultaneously ====
// Key expression
line * 10
// Value expression
t1[line] / v1
''t1'' = base lookup table being iterated; ''v1'' = scaling divisor. Multiplies each key by 10 and divides the corresponding value by ''v1''.
----
====== Multi-key table join ======
t1[ [i1, i2] ["TransitionProb"] ]
''i1'', ''i2'' = map layers providing the composite key values; ''t1'' = multi-key probability table. Looks up a transition probability using two map values as composite keys. Available in [[Calculate Map]] and [[Calculate Categorical Map]]; the same syntax works in the table calculators by substituting ''line'' or ''vX'' for ''iX''.
----
====== Expression Editor — Workflow ======
The steps differ by group of calculator functors. Each group is described separately below.
===== CalculateMap and CalculateCategoricalMap =====
- **Connect your inputs first.** Connect all required maps ([[Number Map]]), tables ([[Number Table]]), and scalars ([[Number Value]]) to the operator's ports before opening the editor.
- **Open the expression editor.** All connected identifiers appear with their aliases at the top.
- **Write the expression** using the listed identifiers.
- **Set Cell Type** if the default (Signed 32-bit Integer) does not suit your output — for example, float for probability maps or int8 for compact categorical maps.
- **Set Null Value** if you need a specific no-data sentinel.
===== CalculateValue =====
- **Connect your inputs first.** Connect all required tables ([[Number Table]]) and scalars ([[Number Value]]) to the operator's ports before opening the editor. Maps cannot be connected, since [[Calculate Value]] has no cell context.
- **Open the expression editor.** All connected identifiers appear with their aliases at the top.
- **Write the expression** using the listed identifiers. There is no Cell Type or Null Value to set — the result is a single scalar.
===== CalculateLookupTableValues and CalculateLookupTableKeysAndValues =====
- **Connect your inputs first.** Connect all required tables ([[Number Table]]) and scalars ([[Number Value]]) to the operator's ports before opening the editor.
- **Set the Key Column Name and Value Column Name** for the output lookup table.
- **Connect a Base Lookup Table**, or leave it as ''.none'', in which case the row set instead comes from a single connected table — the lowest-indexed ''NumberTable'' in verbose form, or the first lookup table referenced by name in the expression in shorthand form.
- **Open the expression editor.** All connected identifiers appear with their aliases at the top. [[Calculate Lookup Table Values]] has a single expression; [[Calculate Lookup Table Keys And Values]] has separate key and value expressions.
- **Write the expression(s)**, using ''line'' for the current row's key and ''column'' for the current row's existing value where needed.
----
====== Notes and Caveats ======
* **Choose the right functor for the output type.** Use [[Calculate Map]] for continuous rasters, [[Calculate Categorical Map]] for class-coded rasters (so that downstream functors treat them as categorical), [[Calculate Value]] for a single scalar, and the two lookup table calculators ([[Calculate Lookup Table Values]], [[Calculate Lookup Table Keys And Values]]) for row-by-row table construction.
* **''line'' and ''column'' are context-dependent.** In [[Calculate Map]] and [[Calculate Categorical Map]], ''line'' is the spatial row index and ''column'' is the spatial column index of the current pixel, both **starting at 1**. In [[Calculate Lookup Table Values]] and [[Calculate Lookup Table Keys And Values]], both are still available but take on row-oriented meanings: ''line'' is the key of the current table row, and ''column'' is the value already associated with that key in the base lookup table. A different table's value for that same key can be retrieved with ''%someTable[line]''. See [[#4_image_operators_and_functions|section 4]] for full details.
* **Native compilation.** Expression calculations across all five calculator functors can be compiled to native code automatically (requires the optional native expression support package), delivering near-C performance — no user action is needed beyond installing the package.
* **Overflow produces null.** If the result exceeds the Cell Type's range, the cell becomes null rather than wrapping. Applies to the map calculators only (the other functors return values or table entries that are not constrained to a cell type in the same way).
* **Neighbourhood functions ignore nulls.** All ''nbN'' operators ([[#7_image_neighborhood_functions|section 7]]) skip null cells in their window; only non-null cells contribute to the statistic.
* **''iX[LINE, COL]'' returns 0, not null, for out-of-bounds or null cells.** This is the one exception to the general null-propagation rule. See [[#4_image_operators_and_functions|section 4]] and [[#null_value_handling|Null Value Handling]].
----
====== Internal Names ======
^ Functor ^ Internal name ^
| Calculate Map | ''CalculateMap'' |
| Calculate Categorical Map | ''CalculateCategoricalMap'' |
| Calculate Value | ''CalculateValue'' |
| Calculate Lookup Table Values | ''CalculateLookupTableValues'' |
| Calculate Lookup Table Keys and Values | ''CalculateLookupTableKeysAndValues'' |