Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
calculate_functors [2026/07/06 20:04]
hermann
calculate_functors [2026/07/23 03:55] (current)
hermann
Line 35: Line 35:
 | Null Value | Null Value Type | No | Based on Cell Type | Sentinel value representing "no data" in the output. | | 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 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. |+| 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. Prefer this port over a ''​NumberMap''​ hook when the map is needed only for format purposes — a hook defines an identifier in the expression namespace and blocks abbreviated syntax if that identifier is unused in the expression. |
  
 ==== Output ==== ==== Output ====
Line 61: Line 61:
 | Null Value | Null Value Type | No | Based on Cell Type | Sentinel value representing "no data" in the output. | | 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 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. |+| Result Format | Map Type | No | None | Optional reference map whose spatial format is applied to the output. Prefer this port over a ''​NumberMap''​ hook when the map is needed only for format purposes — a hook defines an identifier in the expression namespace and blocks abbreviated syntax if that identifier is unused in the expression. |
  
 ==== Output ==== ==== Output ====
Line 110: Line 110:
 | Key Column Name | String | **Yes** | — | Name of the key column in the output lookup 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. | | 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 ''​NumberTable''​ hook with the lowest list index that is connected to a **lookup table** (not a regular table) is used as the row source (verbose form), or the first lookup table named in the expression (shorthand form) — not a union of all connected tables. |+| Base Lookup Table | Lookup Table Type | No | ''​.none''​ | A lookup table whose key set drives iteration. When ''​.none'',​ the ''​NumberTable''​ hook with the lowest list index that is connected to a **lookup table** (not a regular table) is used as the row source (verbose form), or the first lookup table named in the expression (shorthand form) — not a union of all connected tables. Prefer this port over a ''​NumberTable''​ hook when the table is needed only to define the row set and is not referenced in the expression, to keep abbreviated syntax available. |
  
 ==== Output ==== ==== Output ====
Line 140: Line 140:
 | Key Column Name | String | **Yes** | — | Name of the key column in the output lookup 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. | | 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. |+| Base Lookup Table | Lookup Table Type | No | ''​.none''​ | A lookup table whose row set drives iteration. Prefer this port over a ''​NumberTable''​ hook when the table is needed only to define the row set and is not referenced in the expression, to keep abbreviated syntax available. |
  
 ==== Output ==== ==== Output ====
Line 209: Line 209:
 | 9 | **Boolean Not** | ''​not EXPR''​ / ''​! EXPR''​ | Inverts a boolean value. | ''​not isNull(i1)''​ | | 9 | **Boolean Not** | ''​not EXPR''​ / ''​! EXPR''​ | Inverts a boolean value. | ''​not isNull(i1)''​ |
 | 9 | **Negate** | ''​-EXPR''​ | Arithmetic negation. | ''​-ceil(i1 + i2)''​ | | 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. 
  
 ---- ----
Line 241: Line 239:
  
 ===== Clamping Functions ===== ===== Clamping Functions =====
 +
 +All clamping functions are available in all five calculator functors.
  
 ^ Function ^ Syntax ^ Description ^ Example ^ ^ Function ^ Syntax ^ Description ^ Example ^
Line 248: Line 248:
 ===== Random / Stochastic Functions ===== ===== 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.+All stochastic ​functions ​are available in all five calculator functors. They 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 ^ ^ Function ^ Syntax ^ Description ^ Example ^
Line 259: Line 259:
  
 ^ Function ^ Syntax ^ Description ^ Example ^ ^ Function ^ Syntax ^ Description ^ Example ^
-| Literal value | ''​2'',​ ''​-3.5e-2'',​ etc. | Any numeric literal, including scientific notation. | ''​2 + i1 / -3.5e-2''​ | +| Literal value | ''​2'',​ ''​-3.5e-2'',​ etc. | Any numeric literal, including scientific notation. Available in all five calculator functors. | ''​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''​ |+| Abort | ''​abort''​ | Immediately halts model execution. Useful as a guard inside a conditional to catch unexpected states. Available in all five calculator functors. | ''​if i1 > 0 then i1 * i2 + 4 else abort''​ |
 | Is Null | ''​isNull(EXPR)''​ | Returns 1 if the expression is null, 0 otherwise. Immune to the null poisoning rule — always resolves to 0 or 1. Available in all five calculator functors. | ''​if not isNull(i1) then i1 else i2''​ | | Is Null | ''​isNull(EXPR)''​ | Returns 1 if the expression is null, 0 otherwise. Immune to the null poisoning rule — always resolves to 0 or 1. Available in all five calculator functors. | ''​if not isNull(i1) then i1 else i2''​ |
 +| Null | ''​null''​ | Makes the current evaluation unit null — the cell, row, or scalar result is marked as missing and any further arithmetic using it propagates null. This is an **abstract** null, not a numeric value; it cannot be used in arithmetic and has no numeric representation. Available in all five calculator functors. | ''​if i1 > 2 then i1 else null''​ |
 +
 +> **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.
  
 ---- ----
Line 282: Line 285:
 ^ Operator ^ Syntax ^ Description ^ Example ^ ^ Operator ^ Syntax ^ Description ^ Example ^
 | Get Image Value | ''​iX''​ | Returns the value of image X at the **current cell**. | ''​i2''​ | | 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 Value At Location | ''​iX[LINE_EXPR,​ COL_EXPR]''​ | Returns the value of image X at the **specified (line, column) coordinate**. Coordinates outside the image boundary are **mirrored** back into range. For a row coordinate ''​cellLine''​ in an image of N rows, ''​cellLine''​ is normally expected to be in the range [1, N]. When ''​cellLine''​ is outside this range, it is mirrored back: if ''​cellLine''​ ≤ 0, the effective row is ''​1 − cellLine''​ (for instance, ''​cellLine''​ = 0 → row 1, ''​cellLine''​ = −1 → row 2, ''​cellLine''​ = −2 → row 3); if ''​cellLine''​ > N, the effective row is ''​2N + 1 − cellLine''​ (for instance, ''​cellLine''​ = N+1 → row N, ''​cellLine''​ = N+2 → row N−1, ''​cellLine''​ = N+3 → row N−2). The same formula applies independently to the column coordinate ''​cellCol''​. 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 nullUsing ''​null''​ in arithmetic ​always poisons the result. | ''​if i1 > 2 then i1 else null''​ | +| Get Image Null Sentinel ​Value | ''​null(iX)''​ | Returns the **numeric ​sentinel value** stored in image X to represent missing data (e.g. −132767, or any other number defined when the image was created)Unlike the abstract ​''​null'' ​keyword, this is a real number that participates normally ​in arithmetic ​— but be aware that using it as if it were a regular data value may produce misleading results. | ''​if null(i2) > 2 then 1 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''​ |+
 | 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 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''​ | | 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''​ |
Line 330: Line 332:
 | 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]] ]''​ | | 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"​] ]''​ | | 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] ]''​ |+| Indexed column | ''​tX[ [EXPR, EXPR, ...] [EXPR] ]''​ | Returns the value in the **column indexed by the second expression** matching the given set of keys. Column indices are **1-based**. | ''​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. 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.
Line 353: Line 355:
 | ''​x''​ | Column 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.**+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. When any cell in the window falls outside the image boundary, its coordinate is resolved using the same mirror formula as ''​iX[LINE,​ COL]'',​ applied **independently to each out-of-bounds cell**: for a row coordinate ''​cellLine''​ in an image of N rows, if ''​cellLine''​ ≤ 0 the effective row is ''​1 − cellLine'',​ and if ''​cellLine''​ > N the effective row is ''​2N + 1 − cellLine'';​ the same applies to column coordinates. This applies to every cell in the window — not just the anchor position — so a window near the edge of the image will sample mirrored cells for all positions that extend beyond the boundary. **Null cells within the window are excluded from all calculations.**
  
 ^ Operator ^ Syntax ^ Description ^ Example ^ ^ Operator ^ Syntax ^ Description ^ Example ^
Line 373: Line 375:
 > **Availability:​** [[Calculate Map]] and [[Calculate Categorical Map]] only. > **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.+These operators compute a neighbourhood statistic and then use the result as an **index** to retrieve a value from either a connected Lookup Table or a second image. ''​TABLE''​ below always refers to a **Lookup Table** specifically — see section 5 for the operators that query one directly. 
 + 
 +> If ''​TABLE''​ is bound to a multi-column Table (not a Lookup Table), an error is reported. See section 6 for multi-column tables.
  
 **Full syntax:** \\ **Full syntax:** \\
Line 383: Line 387:
 ''​nbN(IMAGE,​ h, w, IMAGE2)''​ ''​nbN(IMAGE,​ h, w, IMAGE2)''​
  
-When a **TABLE** is provided: the statistic is used as a key to query the lookup table. \\+When a **TABLE** ​(Lookup Table) ​is provided: the statistic is used as a key to query it, equivalent to ''​TABLE[statistic]''​ from section 5. \\
 When an **IMAGE2** is provided: the statistic is used as a pixel coordinate to sample ''​IMAGE2''​. When an **IMAGE2** is provided: the statistic is used as a pixel coordinate to sample ''​IMAGE2''​.
  
 ^ Operator ^ Syntax ^ Description ^ Example ^ ^ 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)''​ | +| MinRef | ''​nbMinRef(...)''​ | Finds the minimum in the window, then uses it as an index into the Lookup Table (or a coordinate into IMAGE2). | ''​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)''​ |+| MaxRef | ''​nbMaxRef(...)''​ | Finds the maximum in the window, then uses it as an index into the Lookup Table (or a coordinate into IMAGE2). | ''​nbMaxRef(i4,​ 2, 3, i1, line, column)''​ |
  
 ---- ----
Line 399: Line 403:
  
 **Syntax:** ''​nbConvol(IMAGE,​ TABLE, h, w)''​ / ''​nbConvol(IMAGE,​ TABLE, h, w, y, x)''​ **Syntax:** ''​nbConvol(IMAGE,​ TABLE, h, w)''​ / ''​nbConvol(IMAGE,​ TABLE, h, w, y, x)''​
 +
 +> If ''​TABLE''​ is bound to a multi-column Table (not a Lookup Table), an error is reported. See section 6 for multi-column tables.
  
 ^ Parameter ^ Meaning ^ ^ Parameter ^ Meaning ^
 | ''​IMAGE''​ | The image to convolve (''​iX''​) | | ''​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** |+| ''​TABLE''​ | A **Lookup ​Table** whose entries are the kernel coefficients,​ indexed 1 to h*w, mapped **left-to-right,​ top-to-bottom**|
 | ''​h''​ | Number of kernel rows | | ''​h''​ | Number of kernel rows |
 | ''​w''​ | Number of kernel columns | | ''​w''​ | Number of kernel columns |
 | ''​y'',​ ''​x''​ | Anchor position (optional; defaults to window centre) | | ''​y'',​ ''​x''​ | Anchor position (optional; defaults to window centre) |
  
-**Kernel index mapping** — table keys are assigned left-to-right,​ top-to-bottom:+Each cell in the window is assigned ​a unique integer key, starting at 1 and advancing ​left-to-right, ​then top-to-bottom. The ''​TABLE''​ argument must be a Lookup Table containing one row per window cell, where the key is that cell's index and the value is its convolution coefficient. The result of ''​nbConvol''​ is the weighted sum of all pixel values in the window, each multiplied by the coefficient stored at the corresponding key in the table.
  
-**3×3 ​kernel:**+The grids below illustrate the index mapping for some common window sizes: 
 + 
 +**3×3 ​window (h=3, w=3):**
  
 ^  ^  col 1  ^  col 2  ^  col 3  ^ ^  ^  col 1  ^  col 2  ^  col 3  ^
Line 416: Line 424:
 ^ row 3 |  7  |  8  |  9  | ^ row 3 |  7  |  8  |  9  |
  
-**5×5 ​kernel:**+**5×5 ​window (h=5, w=5):**
  
 ^  ^  col 1  ^  col 2  ^  col 3  ^  col 4  ^  col 5  ^ ^  ^  col 1  ^  col 2  ^  col 3  ^  col 4  ^  col 5  ^
Line 424: Line 432:
 ^ row 4 |  16  |  17  |  18  |  19  |  20  | ^ row 4 |  16  |  17  |  18  |  19  |  20  |
 ^ row 5 |  21  |  22  |  23  |  24  |  25  | ^ row 5 |  21  |  22  |  23  |  24  |  25  |
 +
 +**3×5 window (h=3, w=5) — non-square example:**
 +
 +^  ^  col 1  ^  col 2  ^  col 3  ^  col 4  ^  col 5  ^
 +^ row 1 |  1  |  2  |  3  |  4  |  5  |
 +^ row 2 |  6  |  7  |  8  |  9  |  10  |
 +^ row 3 |  11  |  12  |  13  |  14  |  15  |
 +
 +In all cases the total number of keys required in the table is h × w.
  
 **Example:​** Apply a Gaussian-blur kernel stored in ''​t1''​ over a 3x3 window on ''​i1'':​ **Example:​** Apply a Gaussian-blur kernel stored in ''​t1''​ over a 3x3 window on ''​i1'':​
Line 437: Line 454:
  
 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. 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.
 +
 +> **Note:** The keyword ''​null''​ (available in all five functors) is an **abstract** sentinel — it carries no numeric value and cannot participate in arithmetic. It is distinct from ''​null(iX)''​ (available in map calculators only), which returns the **numeric** value that image X uses internally to mark missing cells. These two are not interchangeable:​ ''​null''​ poisons any expression that uses it; ''​null(iX)''​ is a regular number that happens to be the image'​s no-data sentinel.
  
 ^ Expression ^ Null behaviour ^ ^ Expression ^ Null behaviour ^
Line 485: Line 504:
 > **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. > **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 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.+  * **Coordinate lookup** ''​iX[LINE_EXPR,​ COL_EXPR]''​ — accessing a map at a specific coordinate returns **0**, not null, when the target cell **is null**Coordinates that fall **outside ​the image boundary** are mirrored back into range rather than producing an error. For row coordinate ''​cellLine''​ in an image of N rows, ''​cellLine''​ is normally expected to be in the range [1, N]. When ''​cellLine''​ is outside this range, it is mirrored back: if ''​cellLine''​ ≤ 0, the effective row is ''​1 − cellLine''​ (for instance, ''​cellLine''​ = 0 → row 1, ''​cellLine''​ = −1 → row 2, ''​cellLine''​ = −2 → row 3); if ''​cellLine''​ > N, the effective row is ''​2N + 1 − cellLine''​ (for instance, ''​cellLine''​ = N+1 → row N, ''​cellLine''​ = N+2 → row N−1, ''​cellLine''​ = N+3 → row N−2). The same formula applies independently to the column coordinate ''​cellCol''​. 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.   * **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.
  
Line 864: Line 883:
   * **Overflow produces null.** If the result exceeds the Cell Type's range, the cell becomes null rather than wrapping. Applies to [[Calculate Map]] and [[Calculate Categorical Map]] only — the only two functors with a Cell Type parameter.   * **Overflow produces null.** If the result exceeds the Cell Type's range, the cell becomes null rather than wrapping. Applies to [[Calculate Map]] and [[Calculate Categorical Map]] only — the only two functors with a Cell Type parameter.
   * **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.   * **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]].+  * **''​iX[LINE,​ COL]''​ returns 0, not null, when the target cell is null.** Coordinates outside the image boundary are mirrored rather than treated as out-of-bounds. 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]].
  
 ---- ----
Line 876: Line 895:
 | Calculate Lookup Table Values | ''​CalculateLookupTableValues''​ | | Calculate Lookup Table Values | ''​CalculateLookupTableValues''​ |
 | Calculate Lookup Table Keys and Values | ''​CalculateLookupTableKeysAndValues''​ | | Calculate Lookup Table Keys and Values | ''​CalculateLookupTableKeysAndValues''​ |
-