Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
ego_script [2011/10/21 18:26] hermann [Properties] |
ego_script [2015/09/14 02:31] admin [Overview] |
||
---|---|---|---|
Line 5: | Line 5: | ||
EGO Script is a simple language used to create and edit Dinamica EGO models. The file describing the model using the EGO Script format uses the extension ".ego". | EGO Script is a simple language used to create and edit Dinamica EGO models. The file describing the model using the EGO Script format uses the extension ".ego". | ||
- | They behave just like XML models, so it is possible to edit, load them on the graphical interface and save them again. However, beware that the Dinamica EGO graphical interface can change the model layout and input/output format based on the currently defined options. More tips on saving EGO scripts on the GUI at the end of this language tutorial. | + | They behave just like any XML models, so it is possible to edit, load them on the graphical interface and save them again. However, beware that the Dinamica EGO graphical interface can change the model layout and input/output format based on the currently defined options. More tips on saving EGO scripts on the GUI at the end of this language tutorial. |
===== Overview ===== | ===== Overview ===== | ||
Line 11: | Line 11: | ||
A simple EGO script model can be seen below: | A simple EGO script model can be seen below: | ||
- | <file cpp ego1.ego> | + | <file java ego1.ego> |
Script {{ | Script {{ | ||
// Loads a GeoTiff map. | // Loads a GeoTiff map. | ||
Line 28: | Line 28: | ||
The variables and parameters after the functor name are bound to the functor input ports. Those variables before the operator '':='' are bound to the functor output ports. | The variables and parameters after the functor name are bound to the functor input ports. Those variables before the operator '':='' are bound to the functor output ports. | ||
- | The sequence ''%%//%%'' mark the beginning of a comment. The comment continue until the end of line. | + | The sequence ''%%//%%'' marks the beginning of a comment. The comment continues until the end of line. |
Here is a slightly more complex example: | Here is a slightly more complex example: | ||
- | <file cpp ego2.ego> | + | <file java ego2.ego> |
Script {{ | Script {{ | ||
landscape := LoadCategoricalMap "c:/landscape.tif"; | landscape := LoadCategoricalMap "c:/landscape.tif"; | ||
- | cells hects m2s := CalcAreas landscape; | + | areas := CalcAreas landscape; |
- | SaveLookupTable hects "c:/area_in_hectares.csv"; | + | SaveTable areas "c:/areas.csv"; |
}}; | }}; | ||
</file> | </file> | ||
- | Note that functor [[Calc Areas]] produces three lookup tables, representing the calculated area in cells, hectares and square meters. | + | Note that functor [[Calc Areas]] produces a table, representing the calculated area in cells, hectares and square meters. |
It is possible to omit variables representing outputs or ignore them using the variable ''_'' (underline). So the previous example can be re-written as shown below: | It is possible to omit variables representing outputs or ignore them using the variable ''_'' (underline). So the previous example can be re-written as shown below: | ||
- | <file cpp ego3.ego> | + | <file java ego3.ego> |
Script {{ | Script {{ | ||
landscape := LoadCategoricalMap "c:/landscape.tif"; | landscape := LoadCategoricalMap "c:/landscape.tif"; | ||
Line 64: | Line 64: | ||
It is also possible to use the input and output names to bind variables and parameters. The previous example can be rewritten as | It is also possible to use the input and output names to bind variables and parameters. The previous example can be rewritten as | ||
- | <file cpp ego4.ego> | + | <file java ego4.ego> |
Script {{ | Script {{ | ||
{ landscape=map } := LoadCategoricalMap { filename="c:/landscape.tif" }; | { landscape=map } := LoadCategoricalMap { filename="c:/landscape.tif" }; | ||
Line 78: | Line 78: | ||
It is possible to freely mix both styles. So you can write the previous input as | It is possible to freely mix both styles. So you can write the previous input as | ||
- | <file cpp ego4.ego> | + | <file java ego4.ego> |
Script {{ | Script {{ | ||
landscape := LoadCategoricalMap { filename="c:/landscape.tif" }; | landscape := LoadCategoricalMap { filename="c:/landscape.tif" }; | ||
Line 88: | Line 88: | ||
It is also possible to inline a definition of functor pretty much like nesting function calls in other programming languages: | It is also possible to inline a definition of functor pretty much like nesting function calls in other programming languages: | ||
- | <file cpp ego5.ego> | + | <file java ego5.ego> |
Script {{ | Script {{ | ||
{ hects=cellAreaInHectares } := CalcAreas (LoadCategoricalMap { filename="c:/landscape.tif" }); | { hects=cellAreaInHectares } := CalcAreas (LoadCategoricalMap { filename="c:/landscape.tif" }); | ||
Line 103: | Line 103: | ||
You can define a single line comment preceding the text with a '%%//%%'. | You can define a single line comment preceding the text with a '%%//%%'. | ||
- | <code cpp> | + | <code java> |
// This is a single line comment. | // This is a single line comment. | ||
</code> | </code> | ||
Line 109: | Line 109: | ||
Multi-line comments can be defined surrounding the text with '%%/*%%' and '%%*/%%'. | Multi-line comments can be defined surrounding the text with '%%/*%%' and '%%*/%%'. | ||
- | <code cpp> | + | <code java> |
/* This is a multi-line | /* This is a multi-line | ||
comment */ | comment */ | ||
Line 116: | Line 116: | ||
It is worth noting that there is a very important difference between both comment styles: multi-line comment style are not preserved if the model is opened using the graphical interface. Usually this is not a problem since multi-line comment can be defined using the '%%//%%' style. Ex: | It is worth noting that there is a very important difference between both comment styles: multi-line comment style are not preserved if the model is opened using the graphical interface. Usually this is not a problem since multi-line comment can be defined using the '%%//%%' style. Ex: | ||
- | <code cpp> | + | <code java> |
// This is a multi-line | // This is a multi-line | ||
// comment | // comment | ||
Line 125: | Line 125: | ||
The sequence ''==='' is used to separate the brief and extended comments of a functor. | The sequence ''==='' is used to separate the brief and extended comments of a functor. | ||
- | <code cpp> | + | <code java> |
// Generate the initial 'seed' | // Generate the initial 'seed' | ||
// | // | ||
Line 165: | Line 165: | ||
The first syntax represents properties using comments. | The first syntax represents properties using comments. | ||
- | <code cpp> | + | <code java> |
/** name = value */ | /** name = value */ | ||
</code> | </code> | ||
Line 171: | Line 171: | ||
The other syntax uses the special symbol @. | The other syntax uses the special symbol @. | ||
- | <code cpp> | + | <code java> |
@name = value | @name = value | ||
</code> | </code> | ||
Line 179: | Line 179: | ||
Examples of properties can be seen below: | Examples of properties can be seen below: | ||
- | <code cpp> | + | <code java> |
/** | /** | ||
dff.date = Wed Oct 21 18:19:21 2009 | dff.date = Wed Oct 21 18:19:21 2009 | ||
Line 195: | Line 195: | ||
</code> | </code> | ||
- | <code cpp> | + | <code java> |
@alias = Largest Patch Area | @alias = Largest Patch Area | ||
@collapsed = yes | @collapsed = yes | ||
Line 217: | Line 217: | ||
^ Full Name ^ Description ^ Possible Values ^ | ^ Full Name ^ Description ^ Possible Values ^ | ||
- | | dff.date | The date when the model was writen for the last time | Any string | | + | | dff.date | The date when the model was written for the last time | Any string | |
| dff.version | The version of Dinamica EGO used to update the model the last time | Any string | | | dff.version | The version of Dinamica EGO used to update the model the last time | Any string | | ||
| metadata.title | The model title | Any string | | | metadata.title | The model title | Any string | | ||
Line 232: | Line 232: | ||
The syntax | The syntax | ||
- | <code cpp> | + | <code java> |
// The input map. | // The input map. | ||
// | // | ||
Line 240: | Line 240: | ||
and | and | ||
- | <code cpp> | + | <code java> |
@comment = "The input map. | @comment = "The input map. | ||
Line 248: | Line 248: | ||
are equivalent. | are equivalent. | ||
- | If used before the "Script" keyword, the // syntax is converted into a "metadata.title" and assigned to the model. | + | If used before the "Script" keyword, the <nowiki>//</nowiki> syntax is converted into a "metadata.title" and assigned to the model. |
==== Expression Calculation Syntax ==== | ==== Expression Calculation Syntax ==== | ||
- | FIXME Dinamica version: 1.9.0 | + | Since Dinamica EGO version 2.0, expressions in EGO Script can be represented using an additional special syntax. The example below illustrates: |
- | Expressions can be represented using an additional special syntax. The example below illustrates: | + | <code java> |
- | + | ||
- | <code cpp> | + | |
if #random <= ($mean - $min) / ($max - $min) then | if #random <= ($mean - $min) / ($max - $min) then | ||
$min + sqrt(#random * ($max - $min) * ($mean - $min)) | $min + sqrt(#random * ($max - $min) * ($mean - $min)) | ||
Line 272: | Line 270: | ||
The example below represents a fragment of a real model using the original syntax: | The example below represents a fragment of a real model using the original syntax: | ||
- | <code cpp> | + | <code java> |
patches := LoadCategoricalMap "../originals/landscape.ers" .no .no 0 0 .none; | patches := LoadCategoricalMap "../originals/landscape.ers" .no .no 0 0 .none; | ||
// ... | // ... | ||
Line 291: | Line 289: | ||
The model modified to use the special expression calculation syntax can be seen below: | The model modified to use the special expression calculation syntax can be seen below: | ||
- | <code cpp> | + | <code java> |
patches := LoadCategoricalMap "../originals/landscape.ers" .no .no 0 0 .none; | patches := LoadCategoricalMap "../originals/landscape.ers" .no .no 0 0 .none; | ||
// ... | // ... | ||
Line 298: | Line 296: | ||
// Isolate the patches of a single category. | // Isolate the patches of a single category. | ||
@collapsed = yes | @collapsed = yes | ||
- | singleCategoryPatches := #[ if #patches = $currenteCategoryId then 1 else null ]; | + | singleCategoryPatches := #[ if #patches = $currenteCategoryId then 1 else null ] .uint8 0 .no; |
</code> | </code> | ||
+ | |||
+ | ===== Complex Example ===== | ||
+ | |||
+ | <code java> | ||
+ | @title = Calc Patch Sizes, Mean Patch Sizes and Patch Size Standard Deviations | ||
+ | @author = Dinamica Team | ||
+ | @organization = CSR / UFMG | ||
+ | @metaversion = 1.0 | ||
+ | @description = Calculate the patch sizes, the mean patch sizes and the patch size standard deviation of different categories. | ||
+ | @notes = "The model input is a map where the non-null values identify the patches. | ||
+ | |||
+ | The output is a table per category containing the patch sizes and two additional tables containing the mean patch size and the patch size standard deviation per category." | ||
+ | @showproperties = yes | ||
+ | @version = 1.9.32 | ||
+ | Script {{ | ||
+ | // The input map. | ||
+ | // | ||
+ | // Non-null values identify the patches. | ||
+ | patches := LoadCategoricalMap "../originals/landscape.ers" .no .no 0 0 .none .none; | ||
+ | |||
+ | ForEachCategory patches {{ | ||
+ | step = step; | ||
+ | |||
+ | // Patch size standard deviations. | ||
+ | currentPatchSizeStandardDeviations := MuxLookupTable [ | ||
+ | "Category" "Patch_Size_Standard_Deviations_In_Hectares" | ||
+ | ] updatedPatchSizeStandardDeviations; | ||
+ | |||
+ | // Mean Patch sizes. | ||
+ | currentMeanPatchSizes := MuxLookupTable [ | ||
+ | "Category" "Mean_Patch_Sizes_In_Hectares" | ||
+ | ] updatedPatchMeans; | ||
+ | |||
+ | // Current category. | ||
+ | currentCategory := Step step; | ||
+ | |||
+ | // Calculate the sizes of a set of patches and their corresponding mean and | ||
+ | // standard deviation. | ||
+ | @collapsed = yes | ||
+ | Group {{ | ||
+ | // Isolate the patches of a single category. | ||
+ | @collapsed = yes | ||
+ | singleCategoryIndividualizedPatches := # [ | ||
+ | if #patches = $currentCategory then | ||
+ | #patches | ||
+ | else | ||
+ | null | ||
+ | ] .int32 .default .no .none; | ||
+ | |||
+ | // Calculate the patch size, the mean patch size and patch size standard | ||
+ | // deviation. | ||
+ | @collapsed = yes | ||
+ | Group {{ | ||
+ | // Individualize the patches. | ||
+ | individualizedPatches := CalcPatchLabelMap { | ||
+ | source = singleCategoryIndividualizedPatches, | ||
+ | initialPatchLabel = 1, | ||
+ | onlyOrthogonalsAreAllowed = .no, | ||
+ | windowLines = 3, | ||
+ | windowColumns = 3, | ||
+ | cellType = .int32, | ||
+ | nullValue = .default, | ||
+ | patchLabelsAreSparse = .no | ||
+ | }; | ||
+ | |||
+ | attributes := ExtractMapAttributes individualizedPatches .yes .yes; | ||
+ | |||
+ | // Calculate the mean patch size. | ||
+ | // | ||
+ | // The calculation uses the total patch size and the number of individual patches. | ||
+ | @collapsed = yes | ||
+ | mean := $ [ | ||
+ | (%attributes["cellArea"] * %attributes["nonNullCells"] / %attributes["uniqueCells"]) ? 0 | ||
+ | ] .no 0; | ||
+ | |||
+ | // Calculate the patch sizes. | ||
+ | _ patchSizesInHectares _ := CalcAreas individualizedPatches; | ||
+ | |||
+ | // Calculate the patch size standard deviation. | ||
+ | @collapsed = yes | ||
+ | Group {{ | ||
+ | // Calculate the patch size standard deviation. | ||
+ | @collapsed = no | ||
+ | LogPolicy .warning .no {{ | ||
+ | // Calculate the SUM(Xi - MEAN)^2, where Xi is the current patch size. | ||
+ | @collapsed = yes | ||
+ | ForEachCategory individualizedPatches {{ | ||
+ | step0 = step; | ||
+ | |||
+ | // Accumulated value of SUM(Xi - MEAN)^2. | ||
+ | currentAccumulatedValue := MuxValue 0 updatedAccumulatedValue; | ||
+ | |||
+ | // Current patch id. | ||
+ | currentPatchId := Step step0; | ||
+ | |||
+ | // Calculate the updated accumulated value of SUM(Xi - MEAN)^2 for the current | ||
+ | // patch size. | ||
+ | @collapsed = yes | ||
+ | updatedAccumulatedValue := $ [ | ||
+ | $currentAccumulatedValue + ((%patchSizesInHectares[$currentPatchId] - $mean) ^ 2) | ||
+ | ] .no 0; | ||
+ | }}; | ||
+ | }}; | ||
+ | |||
+ | // Provide 0 as the default accumulated value even if the input map has no patches | ||
+ | // for the current categories. | ||
+ | accumulatedValue := ValueJunction updatedAccumulatedValue 0; | ||
+ | |||
+ | // Calculate the standard deviation using the SUM(Xi - MEAN)^2. | ||
+ | @collapsed = yes | ||
+ | standardDeviation := $ [ | ||
+ | sqrt($accumulatedValue / %attributes["uniqueCells"]) ? 0 | ||
+ | ] .no 0; | ||
+ | }}; | ||
+ | |||
+ | // Update the mean table with the mean patch size of the current category. | ||
+ | updatedPatchMeans := SetLookupTableValue currentMeanPatchSizes currentCategory mean; | ||
+ | |||
+ | // Update the table of standard deviations with the standard deviation of the | ||
+ | // current category. | ||
+ | updatedPatchSizeStandardDeviations := SetLookupTableValue currentPatchSizeStandardDeviations currentCategory standardDeviation; | ||
+ | }}; | ||
+ | }}; | ||
+ | |||
+ | // Save a table of patch sizes per category. | ||
+ | SaveLookupTable patchSizesInHectares "patch_sizes.csv" 2 step .none; | ||
+ | }}; | ||
+ | |||
+ | // Save the mean patch sizes as a table. | ||
+ | SaveLookupTable updatedPatchMeans "mean_patch_sizes.csv" 2 .none .none; | ||
+ | |||
+ | // Save the patch size standard deviations as a table. | ||
+ | SaveLookupTable updatedPatchSizeStandardDeviations "patch_size_standard_deviations.csv" 2 .none .none; | ||
+ | }}; | ||
+ | </code> | ||
+ | |||