Data Binning

Ascent provides a multi-dimensional data binning capability that allows you to calculate spatial distributions, find extreme values, etc. With the right approach, you can implement mesh agnostic analysis that can be used across simulation codes. You can also map the binned result back onto the original mesh topology to enable further analysis, like deviations from an average. These examples show how to define and execute binning operations using Ascent’s query interface. See Ascent’s Data Binning docs for deeper details about Data Binning.

Binning data spatially

C++

#include <iostream>
#include <sstream>

#include "ascent.hpp"
#include "conduit_blueprint.hpp"

#include "ascent_tutorial_cpp_utils.hpp"

using namespace ascent;
using namespace conduit;

const int EXAMPLE_MESH_SIDE_DIM = 32;

int main(int argc, char **argv)
{
    Node mesh;
    conduit::blueprint::mesh::examples::braid("hexs",
                                              EXAMPLE_MESH_SIDE_DIM,
                                              EXAMPLE_MESH_SIDE_DIM,
                                              EXAMPLE_MESH_SIDE_DIM,
                                              mesh);

    // Use Ascent to bin an input mesh in a few ways
    Ascent a;

    // open ascent
    a.open();

    // publish mesh to ascent
    a.publish(mesh);

    // 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"] ;

    // Create a 1D binning projected onto the x-axis
    queries["q1/params/expression"] = "binning('radial','max', [axis('x',num_bins=20)])";
    queries["q1/params/name"] = "1d_binning";

    // Create a 2D binning projected onto the x-y plane
    queries["q2/params/expression"] = "binning('radial','max', [axis('x',num_bins=20), axis('y',num_bins=20)])";
    queries["q2/params/name"] = "2d_binning";

    // Create a binning that emulates a line-out, that is, bin all values
    // between x = [-1,1], y = [-1,1] along the z-axis in 20 bins.
    // The result is a 1x1x20 array
    queries["q3/params/expression"] = "binning('radial','max', [axis('x',[-1,1]), axis('y', [-1,1]), axis('z', num_bins=20)])";
    queries["q3/params/name"] = "3d_binning";

    // print our full actions tree
    std::cout << actions.to_yaml() << std::endl;

    // execute the actions
    a.execute(actions);

    // retrieve the info node that contains the query results
    Node info;
    a.info(info);

    // close ascent
    a.close();

    //
    // We can use the included example python scripts to plot binning results,
    // which are stored in an ascent yaml session file:
    //  plot_binning_1d.py
    //  plot_binning_2d.py
    //  plot_binning_3d.py
    //

    //
    // We can also examine when the results by looking at the expressions
    // results in the output info
    //
    std::cout << info["expressions"].to_yaml() << std::endl;
}

Helper scripts for plotting the results from the session file created in the C++ example:

Python


import conduit
import conduit.blueprint
import ascent
import numpy as np


mesh = conduit.Node()
conduit.blueprint.mesh.examples.braid("hexs",
                                      25,
                                      25,
                                      25,
                                      mesh)


# Use Ascent to bin an input mesh in a few ways
a = ascent.Ascent()

# open ascent
a.open()

# publish mesh to ascent
a.publish(mesh)

# 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"] 

# Create a 1D binning projected onto the x-axis
queries["q1/params/expression"] = "binning('radial','max', [axis('x',num_bins=20)])";
queries["q1/params/name"] = "1d_binning"

# Create a 2D binning projected onto the x-y plane
queries["q2/params/expression"] = "binning('radial','max', [axis('x',num_bins=20), axis('y',num_bins=20)])";
queries["q2/params/name"] = "2d_binning"

# Create a binning that emulates a line-out, that is, bin all values
# between x = [-1,1], y = [-1,1] along the z-axis in 20 bins.
# The result is a 1x1x20 array
queries["q3/params/expression"] = "binning('radial','max', [axis('x',[-1,1]), axis('y', [-1,1]), axis('z', num_bins=20)])";
queries["q3/params/name"] = "3d_binning"

# print our full actions tree
print(actions.to_yaml())

# execute the actions
a.execute(actions)



# plot the results 
try:
    import sys
    import yaml #pip install --user pyyaml
    import matplotlib.pyplot as plt
except:
    print("matplotlib not installed, skipping bin result plots")
    sys.exit(0)

# grab info from last execution which includes our binning results
info = conduit.Node()
a.info(info)

#####
# plot the 1d binning result
#####
binning = info.fetch_existing('expressions/1d_binning')
cycles = binning.child_names()
bins = []

# loop through each cycle and grab the bins
for cycle in cycles:
  bins.append(binning[cycle + '/attrs/value/value'])

# create the coordinate axis using bin centers
x_axis = binning[cycles[0]]['attrs/bin_axes/value/x']
x_min = x_axis['min_val']
x_max = x_axis['max_val']
x_bins = x_axis['num_bins']

x_delta = (x_max - x_min) / float(x_bins)
x_start = x_min + 0.5 * x_delta
x_vals = []
for b in range(0,x_bins):
  x_vals.append(b * x_delta + x_start)

# plot the curve from the last cycle
plt.figure(0)
plt.plot(x_vals, bins[-1])
plt.xlabel('x position')
plt.ylabel('max radial')
plt.savefig("1d_binning.png")

#####
# plot the 2d binning result
#####
binning = info.fetch_existing('expressions/2d_binning')
cycles = binning.child_names()
bins = []

# loop through each cycle and grab the bins
for cycle in cycles:
  bins.append(binning[cycle + '/attrs/value/value'])

# extract the values for the unifom bins
def bin_values(axis_name):
  # create the coordinate axis using bin centers
  axis = binning[cycles[0]]['attrs/bin_axes/value/' + axis_name]
  a_min = axis['min_val']
  a_max = axis['max_val']
  a_bins = axis['num_bins']

  a_delta = (a_max - a_min) / float(a_bins)
  a_start = a_min + 0.5 * a_delta

  axis_vals = []
  for b in range(0,a_bins):
    axis_vals.append(b * a_delta + a_start)
  return axis_vals, a_bins

x_vals, x_size = bin_values('x')
y_vals, y_size = bin_values('y')
x, y = np.meshgrid(x_vals, y_vals)
# plot the curve from the last cycle
# Note: values are strided in the order the axes were declared in
# the query, that is the axis listed first varies the fastest
values = np.array(bins[-1]).reshape(x_size, y_size)


# plot the curve from the last cycle
plt.figure(1)
plt.pcolormesh(x, y, values, shading='auto', cmap = 'viridis');
plt.xlabel('x position')
plt.ylabel('y position')
cbar = plt.colorbar()
cbar.set_label('max radial value')
plt.savefig('2d_binning.png')


#####
# plot the 3d binning result
#####
binning = info.fetch_existing('expressions/3d_binning')
cycles = binning.child_names()
bins = []

# loop through each cycle and grab the bins
for cycle in cycles:
  bins.append(binning[cycle + '/attrs/value/value'])

# create the coordinate axis using bin centers
z_axis =  binning[cycles[0]]['attrs/bin_axes/value/z']
z_min = z_axis['min_val']
z_max = z_axis['max_val']
z_bins = z_axis['num_bins']

z_delta = (z_max - z_min) / float(z_bins)
z_start = z_min + 0.5 * z_delta
z_vals = []
for b in range(0,z_bins):
  z_vals.append(b * z_delta + z_start)

# plot the curve from the last cycle
plt.figure(2)
plt.plot(z_vals, bins[-1])
plt.xlabel('z position')
plt.ylabel('max radial')
plt.savefig("3d_binning.png")

# close ascent
a.close()

(results plotting code is included in the python example source)

Output

- 
  action: "add_queries"
  queries: 
    q1: 
      params: 
        expression: "binning('radial','max', [axis('x',num_bins=20)])"
        name: "1d_binning"
    q2: 
      params: 
        expression: "binning('radial','max', [axis('x',num_bins=20), axis('y',num_bins=20)])"
        name: "2d_binning"
    q3: 
      params: 
        expression: "binning('radial','max', [axis('x',[-1,1]), axis('y', [-1,1]), axis('z', num_bins=20)])"
        name: "3d_binning"


1d_binning: 
  100: 
    type: "binning"
    attrs: 
      value: 
        value: [173.205080756888, 166.089879507819, 162.799392012201, 156.80870455144, 154.131449230971, 149.470101138104, 147.507914389338, 144.370606455485, 143.212728260794, 141.752080920773, 141.458141608263, 142.338138534905, 143.212728260794, 145.805024257929, 147.507914389338, 151.681521877532, 154.131449230971, 159.70185541273, 162.799392012201, 169.562085173567]
        type: "array"
      reduction_var: 
        value: "radial"
        type: "string"
      reduction_op: 
        value: "max"
        type: "string"
      bin_axes: 
        value: 
          x: 
            num_bins: 20
            clamp: 0
            min_val: -10.0
            max_val: 10.0000002
      association: 
        value: "element"
        type: "string"
    time: 3.1415
2d_binning: 
  100: 
    type: "binning"
    attrs: 
      value: 
        value: [173.205080756888, 166.089879507819, 162.799392012201, 156.80870455144, 154.131449230971, 149.470101138104, 147.507914389338, 144.370606455485, 143.212728260794, 141.752080920773, 141.458141608263, 142.338138534905, 143.212728260794, 145.805024257929, 147.507914389338, 151.681521877532, 154.131449230971, 159.70185541273, 162.799392012201, 169.562085173567, 166.089879507819, 158.655904869135, 155.207893209283, 148.912114678501, 146.090217731926, 141.163590238975, 139.084265402001, 135.752422016134, 134.520383625762, 132.964282874354, 132.650872225497, 133.588898328056, 134.520383625762, 137.276921490021, 139.084265402001, 143.503073674421, 146.090217731926, 151.955686623405, 155.207893209283, 162.287241652971, 162.799392012201, 155.207893209283, 151.681521877532, 145.232957219231, 142.338138534905, 137.276921490021, 135.137806875183, 131.70616556512, 130.435913671972, 128.830487404618, 128.506995400272, 129.47504671219, 130.435913671972, 133.276956516862, 135.137806875183, 139.681516739426, 142.338138534905, 148.352029516992, 151.681521877532, 158.918037893595, 156.80870455144, 148.912114678501, 145.232957219231, 138.484438281714, 135.445463065916, 130.116413097411, 127.857556016816, 124.224964606256, 122.877399708006, 121.1718707806, 120.827876131149, 121.856946887252, 122.877399708006, 125.889137426373, 127.857556016816, 132.650872225497, 135.445463065916, 141.752080920773, 145.232957219231, 152.775228854382, 154.131449230971, 146.090217731926, 142.338138534905, 135.445463065916, 132.336719333974, 126.877164124498, 124.559577911663, 120.827876131149, 119.441990848862, 117.686686109385, 117.332474061118, 118.391930990339, 119.441990848862, 122.538192988533, 124.559577911663, 129.47504671219, 132.336719333974, 138.784675898703, 142.338138534905, 150.02601231269, 149.470101138104, 141.163590238975, 137.276921490021, 130.116413097411, 126.877164124498, 121.1718707806, 118.7429827052, 114.822398261662, 113.363118650359, 111.512167854475, 111.138278560982, 112.256210589067, 113.363118650359, 116.620822467905, 118.7429827052, 123.889447546268, 126.877164124498, 133.588898328056, 137.276921490021, 145.232957219231, 147.507914389338, 139.084265402001, 135.137806875183, 127.857556016816, 124.559577911663, 118.7429827052, 116.263363167355, 112.256210589067, 110.763127183157, 108.867980843137, 108.484978843872, 109.629970761074, 110.763127183157, 114.095091508564, 116.263363167355, 121.514891624757, 124.559577911663, 131.38975389946, 135.137806875183, 143.212728260794, 144.370606455485, 135.752422016134, 131.70616556512, 124.224964606256, 120.827876131149, 114.822398261662, 112.256210589067, 108.100619871716, 106.549319773637, 104.577839209338, 104.179066206162, 105.370857877813, 106.549319773637, 110.008986483741, 112.256210589067, 117.686686109385, 120.827876131149, 127.857556016816, 131.70616556512, 139.979186798369, 143.212728260794, 134.520383625762, 130.435913671972, 122.877399708006, 119.441990848862, 113.363118650359, 110.763127183157, 106.549319773637, 104.975097388858, 102.973481932338, 102.568471584417, 103.778760917067, 104.975097388858, 108.484978843872, 110.763127183157, 116.263363167355, 119.441990848862, 126.54867900602, 130.435913671972, 138.784675898703, 141.752080920773, 132.964282874354, 128.830487404618, 121.1718707806, 117.686686109385, 111.512167854475, 108.867980843137, 104.577839209338, 102.973481932338, 100.93217965911, 100.518944844406, 101.753614810242, 102.973481932338, 106.549319773637, 108.867980843137, 114.45932257555, 117.686686109385, 124.89329472649, 128.830487404618, 137.276921490021, 141.458141608263, 132.650872225497, 128.506995400272, 120.827876131149, 117.332474061118, 111.138278560982, 108.484978843872, 104.179066206162, 102.568471584417, 100.518944844406, 100.104004188277, 101.343729499387, 102.568471584417, 106.157952721963, 108.484978843872, 114.095091508564, 117.332474061118, 124.559577911663, 128.506995400272, 136.973379003627, 142.338138534905, 133.588898328056, 129.47504671219, 121.856946887252, 118.391930990339, 112.256210589067, 109.629970761074, 105.370857877813, 103.778760917067, 101.753614810242, 101.343729499387, 102.568471584417, 103.778760917067, 107.327772642672, 109.629970761074, 115.184329492627, 118.391930990339, 125.558067458249, 129.47504671219, 137.882001762339, 143.212728260794, 134.520383625762, 130.435913671972, 122.877399708006, 119.441990848862, 113.363118650359, 110.763127183157, 106.549319773637, 104.975097388858, 102.973481932338, 102.568471584417, 103.778760917067, 104.975097388858, 108.484978843872, 110.763127183157, 116.263363167355, 119.441990848862, 126.54867900602, 130.435913671972, 138.784675898703, 145.805024257929, 137.276921490021, 133.276956516862, 125.889137426373, 122.538192988533, 116.620822467905, 114.095091508564, 110.008986483741, 108.484978843872, 106.549319773637, 106.157952721963, 107.327772642672, 108.484978843872, 111.884807716288, 114.095091508564, 119.441990848862, 122.538192988533, 129.47504671219, 133.276956516862, 141.458141608263, 147.507914389338, 139.084265402001, 135.137806875183, 127.857556016816, 124.559577911663, 118.7429827052, 116.263363167355, 112.256210589067, 110.763127183157, 108.867980843137, 108.484978843872, 109.629970761074, 110.763127183157, 114.095091508564, 116.263363167355, 121.514891624757, 124.559577911663, 131.38975389946, 135.137806875183, 143.212728260794, 151.681521877532, 143.503073674421, 139.681516739426, 132.650872225497, 129.47504671219, 123.889447546268, 121.514891624757, 117.686686109385, 116.263363167355, 114.45932257555, 114.095091508564, 115.184329492627, 116.263363167355, 119.441990848862, 121.514891624757, 126.54867900602, 129.47504671219, 136.058688444923, 139.681516739426, 147.507914389338, 154.131449230971, 146.090217731926, 142.338138534905, 135.445463065916, 132.336719333974, 126.877164124498, 124.559577911663, 120.827876131149, 119.441990848862, 117.686686109385, 117.332474061118, 118.391930990339, 119.441990848862, 122.538192988533, 124.559577911663, 129.47504671219, 132.336719333974, 138.784675898703, 142.338138534905, 150.02601231269, 159.70185541273, 151.955686623405, 148.352029516992, 141.752080920773, 138.784675898703, 133.588898328056, 131.38975389946, 127.857556016816, 126.54867900602, 124.89329472649, 124.559577911663, 125.558067458249, 126.54867900602, 129.47504671219, 131.38975389946, 136.058688444923, 138.784675898703, 144.946077023619, 148.352029516992, 155.743325220301, 162.799392012201, 155.207893209283, 151.681521877532, 145.232957219231, 142.338138534905, 137.276921490021, 135.137806875183, 131.70616556512, 130.435913671972, 128.830487404618, 128.506995400272, 129.47504671219, 130.435913671972, 133.276956516862, 135.137806875183, 139.681516739426, 142.338138534905, 148.352029516992, 151.681521877532, 158.918037893595, 169.562085173567, 162.287241652971, 158.918037893595, 152.775228854382, 150.02601231269, 145.232957219231, 143.212728260794, 139.979186798369, 138.784675898703, 137.276921490021, 136.973379003627, 137.882001762339, 138.784675898703, 141.458141608263, 143.212728260794, 147.507914389338, 150.02601231269, 155.743325220301, 158.918037893595, 165.839083019703]
        type: "array"
      reduction_var: 
        value: "radial"
        type: "string"
      reduction_op: 
        value: "max"
        type: "string"
      bin_axes: 
        value: 
          x: 
            num_bins: 20
            clamp: 0
            min_val: -10.0
            max_val: 10.0000002
          y: 
            num_bins: 20
            clamp: 0
            min_val: -10.0
            max_val: 10.0000002
      association: 
        value: "element"
        type: "string"
    time: 3.1415
3d_binning: 
  100: 
    type: "binning"
    attrs: 
      value: 
        value: [100.93217965911, 88.1654862497835, 81.7982086006836, 69.110597695576, 62.7997494642961, 50.2853460261932, 44.1122397779914, 32.0963689389232, 26.4043637802337, 16.7617820087311, 14.0609643340022, 21.1530274977484, 26.4043637802337, 38.0316971695213, 44.1122397779914, 56.5206950578556, 62.7997494642961, 75.445261700171, 81.7982086006836, 94.544199288728]
        type: "array"
      reduction_var: 
        value: "radial"
        type: "string"
      reduction_op: 
        value: "max"
        type: "string"
      bin_axes: 
        value: 
          x: 
            bins: [-1.0, 1.0]
            clamp: 0
          y: 
            bins: [-1.0, 1.0]
            clamp: 0
          z: 
            num_bins: 20
            clamp: 0
            min_val: -10.0
            max_val: 10.0000002
      association: 
        value: "element"
        type: "string"
    time: 3.1415