Queries are a way to ask questions and get answers. Each query has to required parameters: an expression and a name.
Below is an example of a simple query.
actions: - action: "add_queries" queries: q1: params: expression: "cycle()" name: "my_cycle"
The results of queries can be accessed by the simulation and serve as a way to compose complex triggers, i.e., taking actions as a result of a condition. Query support is in beta, meaning its a part of Ascent currently under development.
Expressions are based on a simple python-like language that supports math evaluation and function calls.
Basic Data Types¶
There are three main integral types in the language:
- floating point:
'this is a string'
- boolean: only created as the result of a comparison
The supported math operators follow the standard operator precedence order:
f(args...): function call
a.attribute: attribute reference
*, /, %: multiplication, division, modulus (remainder)
+, -: addition, subtraction
not, or, and, <, <=, >, >=, !=, ==: comparisons
The expression language currently supports simple if-then-else semantics.
- action: "add_queries" queries: q1: params: expression: "if cycle() > 100 then 1 else 0" name: "cycle_bigger_than_100"
Both branches of the if-then-else will be execute.
The expression system supports functions both required and optional (named) parameters. Functions can both accept and return complex objects like histograms or arrays. Additionally, function overloading is supported and the overload type is resolved by the function parameters.
cycle(): returns the current simulation cycle
field("braid"): returns a field object for the simulation field specified
histogram(field("braid"), num_bins=128): returns a histogram of the
entropy(histogram(field("braid"), num_bins=128)): returns a the entropy of the histogram of the
The result of the expression is stored internally and can be accessed in two ways.
- Through the
ascent.Info(info_node)call. This can be used as a way to feed information back the simulation.
- As an identifier in a subsequent expression.
Queries are executed in the same order they are declared, and since the result of each query stored, each query can be thought of as an assignment statement in a program, with one query building on the previous queries.
- action: "add_queries" queries: q1: params: expression: "1+1" name: "two" q2: params: expression: "two + 1" name: "result"
In the above example,
q1 is evaluated and the result is stored in the identifier
q2, the identifier is referenced and the expression evaluates to
Since the results of queries are stored, we can access values from previous executions.
history function allows expressions to have a temporal component, which is a powerful tool
when tracking simulation state and adaptively responding to user defined events.
The history function can be called on any existing query.
The history of a query can be indexed in two ways:
relative_index: a positive value that indicates how far back in history to access. If the index exceeds the current history, the value is clamped to the last index. An index of 0 is equivalent to the current time value and and index of 1 is the value of the identifier on the last execution.
absolute_index: the index of the value to access. 0 is the first query result.
Here is an example of a use case for the history function:
- action: "add_queries" queries: q1: params: # get the maximum value of a field expression: "max(field('pressure'))" name: "max_pressure" q2: params: expression: "max_pressure - history(max_pressure, relative_index = 1) > 100" name: "result"
In the above example, q2 will evaluate to true if the maximum value of pressure jumps over 100 units since the last in invocation, possibly indicating that an interesting event inside the simulation occurred.
Ascent saves the results of all queries into a file called ascent_session.yaml when the simulation exits. This file is convenient for creating plotting scripts that consume the results of queries. The session file is capable of surviving simulation restarts, and it will continue adding to the file from the last time. If the restart occurs at a cycle in the past (i.e., if the session was saved at cycle 200 and the simulation was restarted at cycle 150), all newer entries will be removed.
If the simulation crashes, there is no promise that the session file will successfully written out, so Ascent provides an explicit action to save the session file. Its important to note that this involves IO, so its a good idea to only use this actions periodically.
- action: "save_session"