Binning Scheme#

\(N\)-point statistics are usually binned in coordinates (either separation in configuration space or wavenumber in Fourier space). Triumvirate allows flexible binning schemes to be used through the Binning class.

from triumvirate.dataobjs import Binning

Initialisation#

A Binning instance can be initialised in two ways: from a set of arguments or through a ParameterSet object.

With arguments#

Initialisation with arguments is simple: one needs to specify whether the binning scheme applies in configuration ('config') or Fourier ('fourier') space, what the bin range is (from bin_min to bin_max), how many bins (num_bins), and what binning scheme to use, e.g. linear ('lin') or logarithmic ('log') (see Binning for all pre-set options).

binning = Binning('fourier', 'lin', bin_min=0.005, bin_max=0.105, num_bins=10)

From a parameter set#

See also

For more information about the ParameterSet class, see Parameter Set.

For this example, we reuse the Python dictionary template to create a valid parameter set:

# DEMO: reuse a parameter template and set valid parameter values.

from triumvirate.parameters import (
    ParameterSet, fetch_paramset_template
)

param_dict = fetch_paramset_template('dict')

for ax_name in ['x', 'y', 'z']:  # not relevant here
    param_dict['boxsize'][ax_name] = 1000.
    param_dict['ngrid'][ax_name] = 64.

param_dict.update({
    'binning' : 'lin',                                   # default already set 
    'degrees' : {'ell1': None, 'ell2': None, 'ELL': 0},  # irrelevant here
    'range'   : [0.005, 0.105],
    'num_bins': 10,
})

paramset = ParameterSet(param_dict=param_dict)
paramset['space'] = 'fourier'  # previously unset as 'statistic_type' is unset

Now, we can use the from_parameter_set() classmethod to instantiate:

binning = Binning.from_parameter_set(paramset)

Hint

Arguments bin_min, bin_max and num_bins are self-evidently set by 'range' and 'num_bins' keys in the dictionary, and scheme by 'binning'. The coordinate space is inferred from 'statistic_type', if set; otherwise it must be specified.

Attributes#

In the examples above, we have set 10 wavenumber bins for \(k \in [0.005, 0.105]\) (in inverse-length units, typically \(h\,\mathrm{Mpc}^{-1}\)).

One could check the attributes of this binning scheme are as expected:

# DEMO: use `numpy` for formatted printing of floats.
import numpy as np
np.set_printoptions(precision=6)

print("Coordinate space:", binning.space)
print("Binning scheme:", binning.scheme)
print("Bin range:", np.asarray([binning.bin_min, binning.bin_max]))
print("Bin centres:", np.asarray(binning.bin_centres))
print("Bin edges:", np.asarray(binning.bin_edges))
print("Bin widths:", np.asarray( binning.bin_widths), "(should be uniform)")
print("Number of bins:", binning.num_bins)
Coordinate space: fourier
Binning scheme: lin
Bin range: [0.005 0.105]
Bin centres: [0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1 ]
Bin edges: [0.005 0.015 0.025 0.035 0.045 0.055 0.065 0.075 0.085 0.095 0.105]
Bin widths: [0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01 0.01] (should be uniform)
Number of bins: 10

Reset#

For a given binning scheme and coordinate space, one could reset the binning range and number of bins using set_bins():

bin_min_new, bin_max_new = 0.005, 0.205
num_bins_new = 5

binning.set_bins(bin_min_new, bin_max_new, num_bins_new)

The bin edges, centres and widths are automatically recalculated:

print("Bin range:", np.asarray([binning.bin_min, binning.bin_max]))
print("Bin centres:", np.asarray(binning.bin_centres))
print("Bin edges:", np.asarray(binning.bin_edges))
print("Bin widths:",np.asarray( binning.bin_widths))
print("Number of bins:", binning.num_bins)
Bin range: [0.005 0.205]
Bin centres: [0.025 0.065 0.105 0.145 0.185]
Bin edges: [0.005 0.045 0.085 0.125 0.165 0.205]
Bin widths: [0.04 0.04 0.04 0.04 0.04]
Number of bins: 5

Customisation#

Finally, one could completely specify the binning by providing the bin edges (with space fixed and scheme changed to 'custom'). The rest of bin attributes are automatically updated.

As an example:

bin_edges = np.logspace(-3., -1., num=6, base=10)

binning.set_custom_bins(bin_edges)

Again, we could check the automatically update attributes:

print("Binning scheme:", binning.scheme)
print("Bin range:", np.asarray([binning.bin_min, binning.bin_max]))
print("Bin centres:", np.asarray(binning.bin_centres))
print("Bin edges:", np.asarray(binning.bin_edges))
print("Bin widths:", np.asarray( binning.bin_widths))
print("Number of bins:", binning.num_bins)
Binning scheme: custom
Bin range: [0.001 0.1  ]
Bin centres: [0.001756 0.004411 0.011079 0.02783  0.069905]
Bin edges: [0.001    0.002512 0.00631  0.015849 0.039811 0.1     ]
Bin widths: [0.001512 0.003798 0.009539 0.023962 0.060189]
Number of bins: 5

Passing as an argument#

Whenever a callable in Triumvirate accepts the binning argument, you can pass an instance like binning above to it.