Comparison Methods

We are currently developing methods for our readers and containers to be able for comparing between like objects. This could be used to compare the effect of changing fuel enrichment on pin powers or criticality, or used to compare the effect of different SERPENT settings. The BaseObject that every object should inherit from contains the bulk of the input checking, so each reader and object needs to implement a private _compare method with the following structure:

def _compare(self, other, lower, upper, sigma):
    return <boolean output of comparison>

Note

While these methods will iterate over many quantities, and some quantities may fail early on in the test, the comparison method should continue until all quantities have been tested.

The value sigma should be used to compare quantities with uncertainties by constructing intervals bounded by \(x\pm S\sigma\), where sigma\(=S\). Quantities that do not have overlapping confidence windows will be considered too different and should result in a False value being returned from the method.

The lower and upper arguments should be used to compare values that do not have uncertainties. Both will be float values, with lower less than or equal to upper. This functionality is implemented with the serpentTools.utils.directCompare() function, while the result is reported with serpentTools.utils.logDirectCompare().

Use of messaging module

Below is a non-definitive nor comprehensive list of possible comparison cases and the corresponding message that should be printed. Using a range of message types allows the user to be able to easily focus on things that are really bad by using our verbosity setting.

  • Two objects contain different data sets, e.g. different dictionary values - warning() displaying the missing items, and then apply test to items in both objects

  • Two items are identically zero, or arrays of zeros - debug()

  • Two items are outside of the sigma confidence intervals - error()

  • Two items without uncertainties have relative difference

  • Two items are identical - debug()

  • Two arrays are not of similar size - error()

High-level Logging and Comparison Utilities

The utils module contains a collection of functions that can be used to compare quantities and automatically log results. When possible, these routines should be favored over hand-writing comparison routines. If the situation calls for custom comparison functions, utilize or extend logging routines from Low-level Logging Utilities appropriately.

serpentTools.utils.compare.compareDictOfArrays(d0, d1, desc, lower=0, upper=10, sigma=2, u0={}, u1={}, relative=True)

High-level routine for evaluating the similarities of two dictionaries

The following tests are performed

  1. Find a set of keys that both exist in d0 and d1 and point to arrays with identical shapes using getKeyMatchingShapes()

  2. For each key in this common set, compare the values with logDirectCompare() or getLogOverlaps(). The latter is used if the key exists in u0 and u1, provided uncertainty arrays are of identical shapes.

Parameters
  • d0 (dict) – Reference dictionary

  • d1 (dict) – Dictionarie to be compared to the reference

  • desc (str) – Descption of the two dictionaries. Should describe what data they represent.

  • lower (float or int) – Lower limit for relative tolerances in percent Differences below this will be considered allowable

  • upper (float or int) – Upper limit for relative tolerances in percent. Differences above this will be considered failure and errors messages will be raised

  • sigma (int) – Size of confidence interval to apply to quantities with uncertainties. Quantities that do not have overlapping confidence intervals will fail

  • u0 (dict) –

  • u1 (dict) – If uncKeys is not None, then find the uncertainties for data in d0 and d1 under the same keys.

  • relative (bool) – If this evaluates to true, then uncertainties in u0 and u1 are relative.

Returns

True If all comparisons pass

Return type

bool

serpentTools.utils.compare.getCommonKeys(d0, d1, quantity, desc0='first', desc1='second', herald=<function error>)

Return a set of common keys from two dictionaries

Also supports printing warning messages for keys not found on one collection.

If d0 and d1 are dict, then the keys will be obtained with d1.keys(). Otherwise, assume we have an iterable of keys and convert to set.

Parameters
  • d0 (dict or iterable) –

  • d1 (dict or iterable) – Dictionary of keys or iterable of keys to be compared

  • quantity (str) – Indicator as to what is being compared, e.g. 'metadata'

  • desc0 (dict or None) –

  • desc1 (dict or None) – Description of the origin of each value set. Only needed if quiet evalues to True.

  • herald (callable) – Function that accepts a single string argument used to notify that differences were found. If the function is not a callable object, a serpentTools.messages.critical() message will be printed and serpentTools.messages.error() will be used.

Returns

Keys found in both d{{0, 1}}

Return type

set

serpentTools.utils.compare.directCompare(obj0, obj1, lower, upper)

Return True if values are close enough to each other.

Wrapper around various comparision tests for strings, numeric, and arrays.

Parameters
  • obj0 (str or float or int or numpy.ndarray) –

  • obj1 (str or float or int or numpy.ndarray) – Objects to compare

  • lower (float or int) – Lower limit for relative tolerances in percent Differences below this will be considered allowable

  • upper (float or int) – Upper limit for relative tolerances in percent. Differences above this will be considered failure and errors messages will be raised

  • quantity (str) – Description of the value being compared. Will be used to notify the user about any differences

Returns

Status code of the comparison.

  • 0 - Values are identical to floating point precision or, for strings/booleans, are identical with the == operator

  • 1 - Values are not identical, but the max difference is less than lower.

  • 10 - Values differ, with the max difference greater than lower but less than upper

  • 100 - Values differ by greater than or equal to upper

  • 200 - Values should be identical (strings, booleans), but are not

  • 250 - Numeric data has different shapes

  • 255 - Values are of different types

  • -1 - Type comparison is not supported. This means that developers should either implement a test for this data type, or use a different function

Return type

int

See also

  • logDirectCompare() - Function that utilizes this and logs the results using the serpentTools.messages module

serpentTools.utils.compare.logDirectCompare(obj0, obj1, lower, upper, quantity)

Compare objects using directCompare() and log the result

Parameters
  • obj0 (str or float or int or numpy.ndarray) –

  • obj1 (str or float or int or numpy.ndarray) – Objects to compare

  • lower (float or int) – Lower limit for relative tolerances in percent Differences below this will be considered allowable

  • upper (float or int) – Upper limit for relative tolerances in percent. Differences above this will be considered failure and errors messages will be raised

  • quantity (str) – Description of the value being compared. Will be used to notify the user about any differences

Returns

True if the objects agree according to tolerances, or numerics differ less than upper. False otherwise

Return type

bool

Raises

TypeError: – If the objects being compared are not supported by directCompare(). Developers should either extend the function or utilize a different comparison function

See also

serpentTools.utils.compare.splitDictByKeys(map0, map1, keySet=None)

Return various sub-sets and dictionaries from two maps.

Used to test the internal workings on getKeyMatchingShapes()

Parameters
  • map0 (dict) –

  • map1 (dict) – Dictionaries to compare

  • keySet (set or None) – Iterable collection of keys found in map0 and map1. Missing keys will be returned from this function under the missing0 and missing1 sets. If None, take to be the set of keys that exist in both maps

Returns

  • missing0 (set) – Keys that exist in keySet but not in map0

  • missing1 (set) – Keys that exist in keySet but not in map1

  • differentTypes (dict) – Dictionary with tuples {key: (t0, t1)} indicating the values map0[key] and map1[key] are of different types

  • badShapes (dict) – Dictionary with tuples {key: (t0, t1)} indicating the values map0[key] and map1[key] are arrays of different shapes

  • goodKeys (set) – Keys found in both map0 and map1 that are of the same type or point to arrays of the same shape

serpentTools.utils.compare.getKeyMatchingShapes(map0, map1, quantity, keySet=None, desc0='first', desc1='second')

Return a set of keys in map0/1 that point to arrays with identical shapes.

Parameters
  • keySet (set or list or tuple or iterable or None) – Iterable container with keys that exist in map0 and map1. The contents of map0/1 under these keys will be compared. If None, will be determined by splitDictByKeys()

  • map0 (dict) –

  • map1 (dict) – Two dictionaries containing at least all the keys in keySet. Objects under keys in keySet will have their sizes compared if they are numpy.ndarray. Non-arrays will be included only if their types are identical

  • quantity (str) – Indicator as to what is being compared, e.g. 'metadata'

  • desc0 (str) –

  • decs1 (str) – Descriptions of the two dictionaries being compared. Used to alert the user to the shortcomings of the two dictionaries

Returns

Set of all keys that exist in both dictionaries and are either identical types, or are arrays of identical shapes

Return type

set

serpentTools.utils.compare.getOverlaps(arr0, arr1, unc0, unc1, sigma, relative=True)

Return the indicies of overlapping confidence intervals

Parameters
  • arr0 (numpy.ndarray) –

  • arr1 (numpy.ndarray) – Arrays containing the expected values to be compared

  • unc0 (numpy.ndarray) –

  • unc1 (numpy.ndarray) – Associated absolute uncertainties, \(1\sigma\), corresponding to the values in arr0 and arr1

  • sigma (int) – Size of confidence interval to apply to quantities with uncertainties. Quantities that do not have overlapping confidence intervals will fail

  • relative (bool) – True if uncertainties are relative and should be multiplied by their respective values. Otherwise, assume values are absolute

Returns

Boolean array of equal shape to incoming arrays. Every index with True as the value indicates that the confidence intervals for the arrays overlap at those indices.

Return type

numpy.ndarray

Examples

Using absolute uncertainties:

>>> from numpy import ones, zeros, array
>>> a0 = ones(4)
>>> a1 = ones(4) * 0.5
>>> u0 = array([0, 0.2, 0.1, 0.2])
>>> u1 = array([1, 0.55, 0.25, 0.4])

Here, the first point in the confidence interval for a0 is completely contained within that of a1. The upper limit of a1[1] is contained within the confidence interval for a0. The confidence intervals for the third point do not overlap, while the lower bound of a0[3] is within the confidence interval of a1[3].

>>> getOverlaps(a0, a1, u0, u1, 1, relative=False)
array([True, True, False, True])

This function also works for multi-dimensional arrays as well.

>>> a2 = a0.reshape(2, 2)
>>> a3 = a1.reshape(2, 2)
>>> u2 = u0.reshape(2, 2)
>>> u3 = u1.reshape(2, 2)
>>> getOverlaps(a2, a3, u2, u3 1, relative=False)
array([[ True,  True],
       [False, False])
Raises

IndexError – If the shapes of incoming arrays do not agree

See also

  • getLogOverlaps() - High-level function that uses this to report if two values have overlapping confidence intervals

serpentTools.utils.compare.getLogOverlaps(quantity, arr0, arr1, unc0, unc1, sigma, relative=True)

Wrapper around getOverlaps() that logs the result

Parameters
  • quantity (str) – Name of the value being compared

  • arr0 (numpy.ndarray) –

  • arr1 (numpy.ndarray) –

  • unc0 (numpy.ndarray) –

  • unc1 (numpy.ndarray) – Arrays and their uncertainties to evaluate

  • sigma (int) – Size of confidence interval to apply to quantities with uncertainties. Quantities that do not have overlapping confidence intervals will fail

  • relative (bool) – If uncertainties are relative. Otherwise, assume absolute uncertainties.

Returns

True if all locations arr0 and arr1 are either identical or within allowable statistical variations.

Return type

bool

See also

  • getOverlaps() - This function performs all the comparisons while this function simply reports the output using serpentTools.messages

serpentTools.utils.docstrings.compareDocDecorator(f)

Decorator that updates doc strings for comparison methods.

Similar to serpentTools.plot.magicPlotDocDecorator() but for comparison functions

Low-level Logging Utilities

The messages module contains a collection of functions that can be used to notify the user about the results of a comparison routine.

serpentTools.messages.logIdentical(obj0, obj1, quantity)

Two objects are identical.

serpentTools.messages.logNotIdentical(obj0, obj1, quantity)

Values should be identical but aren’t.

serpentTools.messages.logAcceptableLow(obj0, obj1, quantity)

Two values differ, but inside nominal and acceptable ranges.

serpentTools.messages.logAcceptableHigh(obj0, obj1, quantity)

Two values differ, enough to merit a warning but not an error.

serpentTools.messages.logOutsideTols(obj0, obj1, quantity)

Two values differ outside acceptable tolerances.

serpentTools.messages.logIdenticalWithUncs(value, unc0, unc1, quantity)

Notify that two values have identical expected values.

serpentTools.messages.logInsideConfInt(value0, unc0, value1, unc1, quantity)

Two values are within acceptable statistical limits.

serpentTools.messages.logOutsideConfInt(value0, unc0, value1, unc1, quantity)

Two values are outside acceptable statistical limits.

serpentTools.messages.logDifferentTypes(type0, type1, quantity)

Two values are of different types.

serpentTools.messages.logMissingKeys(quantity, desc0, desc1, in0, in1, herald=<function error>)

Log a warning message that two objects contain different items

Parameters
  • quantity (str) – Indicator as to what is being compared, e.g. 'metadata'

  • desc0 (str) –

  • desc1 (str) – Descriptions of the two originators

  • in0 (set or iterable) –

  • in1 (set or iterable) – Items that are unique to originators 0 and 1, respectively

  • herald (callable) – Callable function that accepts a single string. This will be called with the error message. If not given, defaults to error()

serpentTools.messages.logBadTypes(quantity, desc0, desc1, types)

Log an error message for containers with mismatched types

Parameters
  • quantity (str) – Indicator as to what is being compared, e.g. 'metadata'

  • desc0 (str) –

  • desc1 (str) – Descriptions of the two originators

  • types (dict) – Dictionary where the keys represent the locations of items with mismatched types. Corresponding keys should be a list or tuple of the types for objects from desc0 and desc1 stored under key

serpentTools.messages.logBadShapes(obj0, obj1, quantity)

Log an error message that two arrays are of different shapes.

Parameters
  • obj0 (numpy.ndarray) –

  • obj1 (numpy.ndarray) – Arrays that have been compared and found to have different shapes

  • quantity (str) – Descriptor of the quantity being compared, e.g. what these objects represent