Asking and answering questions with Queries¶
Queries are a way to ask summarization questions about meshes. Queries results can be used with Triggers to adapt analysis and visualization actions. This section shows how to execute queries with Ascent and access query results. See Queries docs for deeper details on Queries.
Extracting mesh cycle and entropy of a time varying mesh¶
#include <iostream>
#include <sstream>
#include "ascent.hpp"
#include "conduit_blueprint.hpp"
#include "ascent_tutorial_cpp_utils.hpp"
using namespace ascent;
using namespace conduit;
int main(int argc, char **argv)
{
// Use Ascent to extract mesh cycle and entropy of a time varying mesh
Ascent a;
// open ascent
a.open();
// setup actions
Node actions;
Node &add_act = actions.append();
add_act["action"] = "add_queries";
// declare a queries to ask some questions
Node &queries = add_act["queries"] ;
// add a simple query expression (q1)
queries["q1/params/expression"] = "cycle()";;
queries["q1/params/name"] = "cycle";
// add a more complex query expression (q2)
queries["q2/params/expression"] = "entropy(histogram(field('gyre'), num_bins=128))";
queries["q2/params/name"] = "entropy_of_gyre";
// declare a scene to render the dataset
Node &add_scenes = actions.append();
add_scenes["action"] = "add_scenes";
Node &scenes = add_scenes["scenes"];
scenes["s1/plots/p1/type"] = "pseudocolor";
scenes["s1/plots/p1/field"] = "gyre";
// Set the output file name (ascent will add ".png")
scenes["s1/image_name"] = "out_gyre";
// print our full actions tree
std::cout << actions.to_yaml() << std::endl;
// gyre time varying params
int nsteps = 10;
float time_value = 0.0;
float delta_time = 0.5;
Node mesh;
Node info;
for( int step =0; step < nsteps; step++)
{
// call helper that generates a gyre time varying example mesh.
// gyre ref :https://shaddenlab.berkeley.edu/uploads/LCS-tutorial/examples.html
tutorial_gyre_example(time_value, mesh);
// update the example cycle
int cycle = 100 + step * 100;
mesh["state/cycle"] = cycle;
std::cout << "time: " << time_value << " cycle: " << cycle << std::endl;
// publish mesh to ascent
a.publish(mesh);
// update image name
std::ostringstream oss;
oss << "out_gyre_" << std::setfill('0') << std::setw(4) << step;
scenes["s1/image_name"] = oss.str();
// execute the actions
a.execute(actions);
// retrieve the info node that contains the query results
Node ts_info;
a.info(ts_info);
// add to our running info
info["expressions"].update(ts_info["expressions"]);
// update time
time_value = time_value + delta_time;
}
// close ascent
a.close();
// view the results of the cycle query
std::cout << info["expressions/cycle"].to_yaml() << std::endl;
// Note that query results can be indexed by cycle
// view the results of the cycle query
std::cout << info["expressions/entropy_of_gyre"].to_yaml() << std::endl;
// create an array with the entropy values from all
// cycles
Node entropy;
entropy.set(DataType::float64(nsteps));
float64 *entropy_vals_ptr = entropy.value();
// get the node that has the time history
Node &gyre = info["expressions/entropy_of_gyre"];
// reformat conduit data into summary array
for(int i=i; i < gyre.number_of_children(); i++ )
{
entropy_vals_ptr[i] = gyre[i]["value"].to_float64();
}
std::cout << "Entropy Result" << std::endl;
std::cout << entropy.to_yaml() << std::endl;
}
import conduit
import conduit.blueprint
import ascent
import numpy as np
from ascent_tutorial_py_utils import tutorial_gyre_example
# Use Ascent to extract mesh cycle and entropy of a time varying mesh
a = ascent.Ascent()
a.open()
# setup actions
actions = conduit.Node()
add_act = actions.append()
add_act["action"] = "add_queries"
# declare a queries to ask some questions
queries = add_act["queries"]
# add a simple query expression (q1)
queries["q1/params/expression"] = "cycle()"
queries["q1/params/name"] = "cycle"
# add a more complex query expression (q2)
queries["q2/params/expression"] = "entropy(histogram(field('gyre'), num_bins=128))"
queries["q2/params/name"] = "entropy_of_gyre"
# declare a scene to render the dataset
add_scenes = actions.append()
add_scenes["action"] = "add_scenes"
scenes = add_scenes["scenes"]
scenes["s1/plots/p1/type"] = "pseudocolor"
scenes["s1/plots/p1/field"] = "gyre"
# Set the output file name (ascent will add ".png")
scenes["s1/image_name"] = "out_gyre"
# view our full actions tree
print(actions.to_yaml())
# gyre time varying params
nsteps = 10
time = 0.0
delta_time = 0.5
info = conduit.Node()
for step in range(nsteps):
# call helper that generates a gyre time varying example mesh.
# gyre ref :https://shaddenlab.berkeley.edu/uploads/LCS-tutorial/examples.html
mesh = tutorial_gyre_example(time)
# update the example cycle
cycle = 100 + step * 100
mesh["state/cycle"] = cycle
print("time: {} cycle: {}".format(time,cycle))
# publish mesh to ascent
a.publish(mesh)
# update image name
scenes["s1/image_name"] = "out_gyre_%04d" % step;
# execute the actions
a.execute(actions)
# retrieve the info node that contains the query results
ts_info = conduit.Node()
a.info(ts_info)
# add to our running info
info["expressions"].update(ts_info["expressions"])
# update time
time = time + delta_time
# close ascent
a.close()
# view the results of the cycle query
print(info["expressions/cycle"].to_yaml())
# Note that query results can be indexed by cycle
# view the results of the cycle query
print(info["expressions/entropy_of_gyre"].to_yaml())
# create an array with the entropy values from all
# cycles
entropy = np.zeros(nsteps)
# get the node that has the time history
gyre = info["expressions/entropy_of_gyre"]
# transfer conduit data to our summary numpy array
for i in range(gyre.number_of_children()):
entropy[i] = gyre[i]["value"]
print("Entropy Result")
print(entropy)
Output
-
action: "add_queries"
queries:
q1:
params:
expression: "cycle()"
name: "cycle"
q2:
params:
expression: "entropy(histogram(field('gyre'), num_bins=128))"
name: "entropy_of_gyre"
-
action: "add_scenes"
scenes:
s1:
plots:
p1:
type: "pseudocolor"
field: "gyre"
image_name: "out_gyre"
time: 0.0 cycle: 100
time: 0.5 cycle: 200
time: 1.0 cycle: 300
time: 1.5 cycle: 400
time: 2.0 cycle: 500
time: 2.5 cycle: 600
time: 3.0 cycle: 700
time: 3.5 cycle: 800
time: 4.0 cycle: 900
time: 4.5 cycle: 1000
100:
type: "int"
value: 100
200:
type: "int"
value: 200
300:
type: "int"
value: 300
400:
type: "int"
value: 400
500:
type: "int"
value: 500
600:
type: "int"
value: 600
700:
type: "int"
value: 700
800:
type: "int"
value: 800
900:
type: "int"
value: 900
1000:
type: "int"
value: 1000
100:
value: 3.81580590726479
type: "double"
200:
value: 4.43027379899862
type: "double"
300:
value: 4.42357515605932
type: "double"
400:
value: 4.4133821818731
type: "double"
500:
value: 4.40290017527564
type: "double"
600:
value: 4.3643209637501
type: "double"
700:
value: 4.40290017527564
type: "double"
800:
value: 4.4133821818731
type: "double"
900:
value: 4.42357515605932
type: "double"
1000:
value: 4.43027379899862
type: "double"
Entropy Result
[3.81580591 4.4302738 4.42357516 4.41338218 4.40290018 4.36432096
4.40290018 4.41338218 4.42357516 4.4302738 ]