==========
Histograms
==========
Histograms are a common type of calculation implemented in **freud** because custom histograms are hard to compute efficiently in pure Python.
The C++ ``Histogram`` class support weighted N-dimensional histograms with different spacings in each dimension.
The key to this flexibility is the ``Axis`` class, which defines the range spacing along a single axis; an N-dimensional ``Histogram`` is composed of a sequence of N ``Axis`` objects.
Binning values into the histogram is performed by binning along each axis.
The standard ``RegularAxis`` subclass of ``Axis`` defines an evenly spaced axis with bin centers defined as the center of each bin; additional subclasses may be defined to add different spacing if desired.
Multithreading is achieved through the ``ThreadLocalHistogram`` class, which is a simple wrapper around the ``Histogram`` that creates an equivalent histogram on each thread.
The standard pattern for parallel histogramming is to generate a ``ThreadLocalHistogram`` and add data into it, then call the ``Histogram::reduceOverThreads`` method to accumulate these data into a single histogram.
In case any additional post-processing is required per bin, it can also be executed in parallel by providing it as a lambda function to ``Histogram::reduceOverThreadsPerBin``.
Computing with Histograms
=========================
The ``Histogram`` class is designed as a data structure for the histogram.
Most histogram computations in **freud** involve standard neighbor finding to get bonds, followed by binning some function of these bonds into a histogram.
Examples include RDFs (binning bond distances), PMFTs (binning bonds by the different vector components of the bond), and bond order diagrams (binning bond angles).
An important distinction between histogram computations and most others is that histograms naturally support an accumulation of information over multiple frames of data, an operation that is ill-defined for many other computations.
As a result, histogram computations also need to implement some boilerplate for handling accumulating and averaging data over multiple frames.
The details of these computations are encapsulated by the ``BondComputeHistogram`` class, which contains a histogram, provides accessors to standard histogram properties like bin counts and axis sizes, and has a generic accumulation method that accepts a lambda compute function.
This signature is very similar to the utility functions for looping over neighbors, and in fact the function is transparently forwarded to ``locality::loopOverNeighbors``.
Any compute that matches this pattern should inherit from the ``BondComputeHistogram`` class and must implement an ``accumulate`` method to perform the computation and a ``reduce`` to reduce thread local histograms into a single histogram..