Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
calculate_python_expression [2026/08/31 16:51] hermann |
calculate_python_expression [2026/08/31 17:10] (current) hermann |
||
|---|---|---|---|
| Line 3: | Line 3: | ||
| ===== Description ===== | ===== Description ===== | ||
| - | This is a container functor that runs a Python instance with a user-defined expression. Like the other calculator functors, such as [[calculate_map|Calculate Map]] or [[calculate_lookup_table|Calculate Lookup Table]], data is connected through hook functors placed inside its block, rather than through regular input ports. See also [[calculate_r_expression|Calculate R Expression]] for the equivalent functor using R. | + | This is a container functor that runs a Python instance with a user-defined expression. Like the other calculator functors, such as [[Calculate Map]] or [[Calculate Lookup Table]], data is connected through hook functors placed inside its block, rather than through regular input ports. See also [[Calculate R Expression]] for the equivalent functor using R. |
| ===== Inputs ===== | ===== Inputs ===== | ||
| - | ^ Name ^ Type ^ Description ^ | + | ^ Name ^ Type ^ Description ^ |
| - | | Expression | [[code_type|Code Type]] | The expression to run on Python. Written directly as a Code constant using its own raw string syntax -- see [[#writing_the_expression_in_ego_script|Writing the expression in EGO Script]] below. | | + | | Expression | [[Code Type]] | The expression to run on Python. Written directly as a Code constant using its own raw string syntax -- see [[#writing_the_expression_in_ego_script|Writing the expression in EGO Script]] below. | |
| ===== Optional Inputs ===== | ===== Optional Inputs ===== | ||
| - | ^ Name ^ Type ^ Description ^ Default Value ^ | + | ^ Name ^ Type ^ Description ^ Default Value ^ |
| - | | Packages | [[string_type|String Type]] | Packages to install with pip before the expression runs, one per line. Each package can be identified by name or by a filename or URL pointing to the corresponding wheel; a package already installed is skipped. This is an advanced port. | None | | + | | Packages | [[String Type]] | Packages to install with pip before the expression runs, one per line. Each package can be identified by name or by a filename or URL pointing to the corresponding wheel; a package already installed is skipped. This is an advanced port. | None | |
| ===== Outputs ===== | ===== Outputs ===== | ||
| - | ^ Name ^ Type ^ Description ^ | + | ^ Name ^ Type ^ Description ^ |
| - | | Result | [[struct_type|Struct Type]] | Struct containing the output values generated by the expression, one entry per key assigned into dinamica.outputs. | | + | | Result | [[Struct Type]] | Struct containing the output values generated by the expression, one entry per key assigned into dinamica.outputs. | |
| ===== Group ===== | ===== Group ===== | ||
| - | [[functor_list#integration|Integration]] | + | [[Functor List#Integration | Integration]] |
| ===== Notes ===== | ===== Notes ===== | ||
| Line 30: | Line 30: | ||
| Data is passed into the expression through hook functors placed inside the container's block -- the same verbose-form hook mechanism used by the calculator functors: | Data is passed into the expression through hook functors placed inside the container's block -- the same verbose-form hook mechanism used by the calculator functors: | ||
| - | * Tables and lookup tables connect via a [[number_table|Number Table]] hook, available in the expression as dinamica.inputs["t1"], dinamica.inputs["t2"], ..., dinamica.inputs["t100"] | + | * Tables and lookup tables → [[Number Table]] → available in the expression as dinamica.inputs["t1"], dinamica.inputs["t2"], …, dinamica.inputs["t100"] |
| - | * Scalar values connect via a [[number_value|Number Value]] hook, available as dinamica.inputs["v1"], dinamica.inputs["v2"], ..., dinamica.inputs["v100"] | + | * Scalar values → [[Number Value]] → available as dinamica.inputs["v1"], dinamica.inputs["v2"], …, dinamica.inputs["v100"] |
| - | * Strings connect via a [[number_string|Number String]] hook, available as dinamica.inputs["s1"], dinamica.inputs["s2"], ..., dinamica.inputs["s100"] | + | * Strings → [[Number String]] → available as dinamica.inputs["s1"], dinamica.inputs["s2"], …, dinamica.inputs["s100"] |
| - | Maps cannot be connected -- this functor has no cell context. There is no shorthand notation. See [[calculate_functors|Calculate Functors -- Complete Operator Documentation]] for the general hook mechanism and syntax. | + | Maps cannot be connected -- this functor has no cell context. There is no shorthand notation. See [[Calculate Functors|Calculate Functors -- Complete Operator Documentation]] for the general hook mechanism and syntax. |
| - | Every table or lookup table arriving through dinamica.inputs is represented in Python as a list of lists: the first inner list contains the column names (the header row) and every subsequent inner list is a row of data. The header carries plain column names only -- no asterisk marking key columns, no type annotation -- so which columns were keys in the original table is information Python doesn't receive and can't recover from the input alone. Code that needs that distinction has to be told it separately, for instance by also connecting the key count as its own [[number_value|Number Value]] hook. | + | Every table or lookup table arriving through dinamica.inputs is represented in Python as a list of lists: the first inner list contains the column names (the header row) and every subsequent inner list is a row of data. The header carries plain column names only -- no asterisk marking key columns, no type annotation -- so which columns were keys in the original table is information Python doesn't receive and can't recover from the input alone. Code that needs that distinction has to be told it separately, for instance by also connecting the key count as its own [[Number Value]] hook. |
| ==== Expression outputs ==== | ==== Expression outputs ==== | ||
| Line 52: | Line 52: | ||
| ==== Retrieving outputs ==== | ==== Retrieving outputs ==== | ||
| - | Calculate Python Expression returns a single [[struct_type|Struct Type]] value (via its Result output port) containing every entry assigned to dinamica.outputs. To retrieve individual values from that struct, use the following functors from the Integration group: | + | Calculate Python Expression returns a single [[Struct Type]] value (via its Result output port) containing every entry assigned to dinamica.outputs. To retrieve individual values from that struct, use the following functors from the Integration group: |
| - | ^ Functor ^ Retrieves ^ | + | ^ Functor ^ Retrieves ^ |
| - | | [[extract_struct_number|Extract Struct Number]] | A numeric value (int or float assigned to dinamica.outputs) | | + | | [[Extract Struct Number]] | A numeric value (int or float assigned to dinamica.outputs) | |
| - | | [[extract_struct_string|Extract Struct String]] | A string value | | + | | [[Extract Struct String]] | A string value | |
| - | | [[extract_struct_table|Extract Struct Table]] | A table produced by dinamica.prepareTable() | | + | | [[Extract Struct Table]] | A table produced by dinamica.prepareTable() | |
| - | | [[extract_struct_lookup_table|Extract Struct Lookup Table]] | A lookup table produced by dinamica.prepareLookupTable() | | + | | [[Extract Struct Lookup Table]] | A lookup table produced by dinamica.prepareLookupTable() | |
| - | | [[extract_struct_tuple|Extract Struct Tuple]] | A tuple value | | + | | [[Extract Struct Tuple]] | A tuple value | |
| Each functor takes two inputs: the Struct returned by Calculate Python Expression, and the name of the entry to extract as a string constant. For example, to retrieve a numeric output named patchCount and a table output named filteredPatches: | Each functor takes two inputs: the Struct returned by Calculate Python Expression, and the name of the entry to extract as a string constant. For example, to retrieve a numeric output named patchCount and a table output named filteredPatches: | ||
| Line 83: | Line 83: | ||
| dinamica.package(packageName, installPath=None, loadPath=None) installs (if needed, via pip) and imports the requested module. Because it runs together with the script, it may fail if a package is already loaded in an incompatible version. | dinamica.package(packageName, installPath=None, loadPath=None) installs (if needed, via pip) and imports the requested module. Because it runs together with the script, it may fail if a package is already loaded in an incompatible version. | ||
| - | ^ Parameter ^ Type ^ Default ^ Description ^ | + | ^ Parameter ^ Type ^ Default ^ Description ^ |
| - | | packageName | str | -- | Identifies the package. Used as the default for both installPath and loadPath when those are omitted. | | + | | packageName | str | -- | Identifies the package. Used as the default for both installPath and loadPath when those are omitted. | |
| - | | installPath | str | packageName | What is passed to pip install. Can be a plain name, a version-pinned requirement, a wheel filename or URL, a git+ URL, or a name followed by extra pip flags. | | + | | installPath | str | packageName | What is passed to pip install. Can be a plain name, a version-pinned requirement, a wheel filename or URL, a git+ URL, or a name followed by extra pip flags. | |
| - | | loadPath | str | packageName | The name used to import the module in Python. | | + | | loadPath | str | packageName | The name used to import the module in Python. | |
| Simply install and load numpy: | Simply install and load numpy: | ||
| Line 127: | Line 127: | ||
| <code> | <code> | ||
| - | beautifulsoup4 | + | numpy |
| - | opencv-python | + | requests==2.31.0 |
| - | PyYAML | + | torchvision==0.19.1 --index-url https://download.pytorch.org/whl/cu121 |
| </code> | </code> | ||
| Line 135: | Line 135: | ||
| <code python> | <code python> | ||
| - | from bs4 import BeautifulSoup | + | import numpy as np |
| - | import cv2 as cv | + | from requests import Session |
| - | import yaml | + | from torchvision import transforms |
| </code> | </code> | ||
| - | ==== dinamica.prepareTable() ==== | + | === dinamica.prepareTable() === |
| Converts a list of lists into a table ready to be assigned to an output. The first inner list must be the header row. As with any table, each column's type is inferred from its own values: a column of int/float values produces a Real column, a column of str values produces a String column. | Converts a list of lists into a table ready to be assigned to an output. The first inner list must be the header row. As with any table, each column's type is inferred from its own values: a column of int/float values produces a Real column, a column of str values produces a String column. | ||
| - | ^ Parameter ^ Type ^ Default ^ Description ^ | + | ^ Parameter ^ Type ^ Default ^ Description ^ |
| - | | inputTable | list of lists | -- | The table data. First inner list is the header row; subsequent inner lists are data rows. | | + | | inputTable | list of lists | -- | The table data. First inner list is the header row; subsequent inner lists are data rows. | |
| - | | numKeys | int | -- | Number of key columns. Key column names will have an asterisk appended in the output. | | + | | numKeys | int | -- | Number of key columns. Key column names will have an asterisk appended in the output. | |
| - | ==== dinamica.prepareLookupTable() ==== | + | === dinamica.prepareLookupTable() === |
| Converts a list of lists into a lookup table ready to be assigned to an output. The first inner list must be the header row. Lookup tables are always Real-typed on both key and value sides -- there is no String option -- so every value in lut must be numeric. | Converts a list of lists into a lookup table ready to be assigned to an output. The first inner list must be the header row. Lookup tables are always Real-typed on both key and value sides -- there is no String option -- so every value in lut must be numeric. | ||
| - | ^ Parameter ^ Type ^ Default ^ Description ^ | + | ^ Parameter ^ Type ^ Default ^ Description ^ |
| - | | lut | list of lists | -- | The lookup table data. First inner list is the header row; subsequent inner lists are data rows. | | + | | lut | list of lists | -- | The lookup table data. First inner list is the header row; subsequent inner lists are data rows. | |
| - | ==== dinamica.toTable() ==== | + | === dinamica.toTable() === |
| Converts several Python data shapes into a valid Dinamica table for output. Column types are inferred the same way as dinamica.prepareTable() -- except for a flat list, which always produces a Real-typed lookup table with sequential keys, matching the Real-only rule for lookup tables. | Converts several Python data shapes into a valid Dinamica table for output. Column types are inferred the same way as dinamica.prepareTable() -- except for a flat list, which always produces a Real-typed lookup table with sequential keys, matching the Real-only rule for lookup tables. | ||
| - | ^ Parameter ^ Type ^ Default ^ Description ^ | + | ^ Parameter ^ Type ^ Default ^ Description ^ |
| - | | inputTable | list of lists; dict of lists; list of tuples; flat list; pandas.DataFrame; numpy.array | -- | The data to convert. A flat list produces a lookup table with sequential keys. A numpy.array must have its header as the first row. | | + | | inputTable | list of lists; dict of lists; list of tuples; flat list; pandas.DataFrame; numpy.array | -- | The data to convert. A flat list produces a lookup table with sequential keys. A numpy.array must have its header as the first row. | |
| - | | numKeys | int | -- | Number of key columns. Key column names will have an asterisk appended in the output. Ignored for a flat list, which always produces a lookup table with sequential keys. | | + | | numKeys | int | -- | Number of key columns. Key column names will have an asterisk appended in the output. Ignored for a flat list, which always produces a lookup table with sequential keys. | |
| ==== Examples ==== | ==== Examples ==== | ||
| Line 228: | Line 228: | ||
| ==== Writing the expression in EGO Script ==== | ==== Writing the expression in EGO Script ==== | ||
| - | Expression can be filled in directly as a text constant, using [[code_type|Code Type]]'s own raw string syntax -- the same ''$"<delimiter>( raw_characters )<delimiter>"'' form used by String constants. This is also the form the Dinamica EGO GUI's dedicated code editor generates when it writes the Expression port's value, so a hand-written script and one produced by the GUI take the same shape. See [[code_type|Code Type]] for the full grammar, including the base64 alternative form. | + | Expression can be filled in directly as a text constant, using [[Code Type]]'s own raw string syntax -- the same ''$"<delimiter>( raw_characters )<delimiter>"'' form used by String constants. This is also the form the Dinamica EGO GUI's dedicated code editor generates when it writes the Expression port's value, so a hand-written script and one produced by the GUI take the same shape. See [[Code Type]] for the full grammar, including the base64 alternative form. |
| The following counts the patches in a land cover areas table whose area meets a minimum threshold: | The following counts the patches in a land cover areas table whose area meets a minimum threshold: | ||
| Line 246: | Line 246: | ||
| </code> | </code> | ||
| - | Here landCoverAreas is bound to t1 and minimumArea to v1, each through a [[number_table|Number Table]] or [[number_value|Number Value]] hook. Calculate Python Expression returns a Struct containing all values assigned to dinamica.outputs; the ExtractStructNumber functor then pulls the patchCount entry out of that struct by name. See "Retrieving outputs" above for the full list of extraction functors. | + | Here landCoverAreas is bound to t1 and minimumArea to v1, each through a [[Number Table]] or [[Number Value]] hook. Calculate Python Expression returns a Struct containing all values assigned to dinamica.outputs; the ExtractStructNumber functor then pulls the patchCount entry out of that struct by name. See "Retrieving outputs" above for the full list of extraction functors. |
| A more involved example: installing numpy to compute area statistics for a land cover patches table and flag outlier patches, then retrieving both the scalar statistics and the resulting table: | A more involved example: installing numpy to compute area statistics for a land cover patches table and flag outlier patches, then retrieving both the scalar statistics and the resulting table: | ||
| Line 277: | Line 277: | ||
| </code> | </code> | ||
| - | Here landCoverPatches is bound to t1 through a single [[number_table|Number Table]] hook. | + | Here landCoverPatches is bound to t1 through a single [[Number Table]] hook. |
| ===== Internal Name ===== | ===== Internal Name ===== | ||
| CalculatePythonExpression | CalculatePythonExpression | ||