Input checks

The checks behind GRANDlib’s GRANDlib: errors and warnings, for use in new code: see Troubleshooting.

grand.basis.validate

Input checks for GRANDlib's public functions, with messages that help.

grand.basis.validate

Input checks for GRANDlib’s public functions, with messages that help.

Every check raises a standard exception – TypeError for the wrong kind of value, ValueError for a value of the right kind but out of range or of the wrong shape, FileNotFoundError for a missing file – so callers can catch them as usual. The message starts with GRANDlib:, names the function and the argument, says what was expected and shows what was given:

ValueError: GRANDlib: Geodetic: 'latitude' must be between -90 and 90 degrees, got 200.0

Warnings use GRANDlibWarning, so they can be filtered as a group:

import warnings
from grand.basis.validate import GRANDlibWarning
warnings.simplefilter("error", GRANDlibWarning)   # make them errors

Checks return the value converted to the form the code needs (a float, an int, a NumPy array), so a function can validate and convert in one line.

exception grand.basis.validate.GRANDlibWarning[source]

Bases: UserWarning

Warnings issued by GRANDlib: suspicious input that is still usable.

grand.basis.validate.warn(where, text, stacklevel=3)[source]

Issues a GRANDlibWarning pointing at the caller’s code.

Parameters:
  • where (str) – The function, class or field concerned.

  • text (str) – What is suspicious, and what will happen.

  • stacklevel (int, optional) – How far up the stack the warning points; the default points at the code that called the function doing the check.

grand.basis.validate.message(where, text)[source]

Formats an error or warning message: "GRANDlib: <where>: <text>".

Parameters:
  • where (str) – The function, class or field concerned, for example "Geodetic".

  • text (str) – What is wrong, and what was given.

Return type:

str

grand.basis.validate.as_real(value, name, where, finite=True)[source]

Checks value is a real number (not a string, not complex) and returns it as a float.

Parameters:
  • value (object) – The value given.

  • name (str) – The argument’s name, for the message.

  • where (str) – The function concerned, for the message.

  • finite (bool, optional) – Also refuse NaN and infinity.

Return type:

float

Raises:
  • TypeError – If value is not a real number.

  • ValueError – If finite and value is NaN or infinite.

grand.basis.validate.as_integer(value, name, where, minimum=None, maximum=None)[source]

Checks value is a whole number, optionally within limits, and returns it as an int.

A float with no fractional part (3.0) is accepted; 1.7 is not, nor is a boolean.

Parameters:
  • value (object) – The value given.

  • name (str) – The argument’s name, for the message.

  • where (str) – The function concerned, for the message.

  • minimum (int, optional) – Inclusive limits.

  • maximum (int, optional) – Inclusive limits.

Return type:

int

Raises:
  • TypeError – If value is not a number, or has a fractional part.

  • ValueError – If it lies outside the limits.

grand.basis.validate.as_array(value, name, where, ndim=None, shape=None, min_length=None, finite=False, dtype=<class 'float'>)[source]

Converts value to a NumPy array and checks its dimensions and contents.

Parameters:
  • value (array-like) – The value given.

  • name (str) – The argument’s name, for the message.

  • where (str) – The function concerned, for the message.

  • ndim (int, optional) – Required number of dimensions.

  • shape (tuple, optional) – Required shape; None in it matches any length, so (None, 3) means “any number of rows, three columns”.

  • min_length (int, optional) – Minimum length of the first axis.

  • finite (bool, optional) – Refuse NaN and infinity.

  • dtype (type, optional) – The dtype to convert to; float by default.

Return type:

numpy.ndarray

Raises:
  • TypeError – If value cannot be converted to numbers.

  • ValueError – If its shape, length or contents are wrong.

grand.basis.validate.in_range(value, name, where, minimum=None, maximum=None, unit='')[source]

Checks every element of value lies within [minimum, maximum].

Parameters:
  • value (float or numpy.ndarray) – The value given, already numeric. NaN passes; use finite checks to refuse it.

  • name (str) – For the message.

  • where (str) – For the message.

  • minimum (float, optional) – Inclusive limits.

  • maximum (float, optional) – Inclusive limits.

  • unit (str, optional) – The unit, for the message.

Returns:

value, unchanged.

Return type:

float or numpy.ndarray

Raises:

ValueError – If any element lies outside the limits.

grand.basis.validate.positive(value, name, where, unit='')[source]

Checks every element of value is strictly positive; returns it unchanged.

Raises:

ValueError –

grand.basis.validate.non_negative(value, name, where, unit='')[source]

Checks no element of value is negative; returns it unchanged.

Raises:

ValueError –

grand.basis.validate.nonzero(value, name, where)[source]

Checks no element of value is zero; returns it unchanged.

Raises:

ValueError –

grand.basis.validate.one_of(value, choices, name, where)[source]

Checks value is one of choices; returns it unchanged.

Raises:

ValueError – Listing the accepted values.

grand.basis.validate.same_length(where, **arrays)[source]

Checks the named arrays all have the same length (first axis).

Parameters:
  • where (str) – For the message.

  • **arrays (array-like) – The arrays, by argument name.

Raises:

ValueError – Giving each array’s length.

grand.basis.validate.existing_file(path, name, where)[source]

Checks path names an existing file; returns it unchanged.

Raises:
grand.basis.validate.existing_directory(path, name, where)[source]

Checks path names an existing directory; returns it unchanged.

Raises:
grand.basis.validate.coerce_to_dtype(value, dtype, where)[source]

Converts value for storage as dtype, refusing silent changes.

Used by the data-tree fields. For an integer dtype, the value must be a whole number within the dtype’s range (1.7 and -1 for an unsigned field are refused, rather than stored as 1 and 4294967295); for a float dtype, a real number. Text that reads as a number ("1618") is converted, with a GRANDlibWarning, as it always was; other text is refused. Works on scalars and arrays.

Parameters:
  • value (object) – The value given.

  • dtype (numpy.dtype or type) – The storage type.

  • where (str) – The field, for example "TRun.run_number".

Returns:

value as a NumPy array of dtype (0-d for a scalar).

Return type:

object

Raises:
  • TypeError – If value is not numeric, or not whole for an integer field.

  • ValueError – If it is out of the dtype’s range.

grand.basis.validate.field_check(kind, minimum=None, maximum=None, unit='', refuse=False)[source]

A check for one field of a CheckedFields dataclass.

The checks match the data-tree setters: a value of the wrong kind raises TypeError; a value outside the limits warns and is stored as given, or raises ValueError when refuse is set. None is always accepted (an unset field), and NaN is accepted for reals (unknown).

Parameters:
  • kind ({"real", "int", "str", "vector3"}) – What the field holds: a real number, a whole number, a string, or three real numbers.

  • minimum (float, optional) – Inclusive limits, for “real”, “int” and each value of “vector3”.

  • maximum (float, optional) – Inclusive limits, for “real”, “int” and each value of “vector3”.

  • unit (str, optional) – Unit of the limits, for the message.

  • refuse (bool, optional) – Raise rather than warn for a value outside the limits.

Returns:

check(value, where), returning the value to store.

Return type:

callable

class grand.basis.validate.CheckedFields[source]

Bases: object

Mixin: checks the fields named in _field_checks whenever they are set.

For dataclasses that hold the same quantities as the data trees – the grand.aoi classes and ShowerEvent – so they accept and refuse what the tree setters do. _field_checks maps a field name to a field_check().