Source code for ska_pst.testutils.common.quantity_helper

# -*- coding: utf-8 -*-
#
# This file is part of the SKA PST project
#
# Distributed under the terms of the BSD 3-clause new license.
# See LICENSE for more info.

"""Module to provide helper method to convert quantities with units to a value."""

__all__ = ["convert_value_to_quantity", "QuantityType"]

import re
from typing import Tuple, TypeAlias, Union

import astropy.units as u

# add unit aliases that may arise in our tests, including using British spelling of metre.
u.add_enabled_aliases(
    {
        # add English spelling for metre
        "metre": u.m,
        "metres": u.m,
        # add second abbreviations
        "seconds": u.s,
        "sec": u.s,
        "secs": u.s,
        # minutes
        "minutes": u.min,
        "mins": u.min,
        # add hours
        "hours": u.h,
        # add milliseconds
        "milliseconds": u.ms,
    }
)

QuantityType: TypeAlias = Union[str, u.Quantity, Tuple[u.Quantity, u.Quantity]]
QUANTITY_REGEX = r"^(?:[1-9]\d*|0)?(?:\.\d+)?(?:\s+\w+)?$"
QUANTITY_RANGE_REGEX = r"^(?:[1-9]\d*|0)?(?:\.\d+)? to (?:[1-9]\d*|0)?(?:\.\d+)?(?:\s+\w+)?$"


[docs]def convert_value_to_quantity(value: str) -> QuantityType: """Convert a value string to a quantity. This tries to use the astropy.units package to see if it can convert it to a quantity. If the value starts with a number then it is expected to be a quantity (value with optional unit). If it isn't a number the string value is returned. This is method should be extended to handled the edge cases that may arise in the future. """ if re.match(QUANTITY_REGEX, value) is not None: return u.Quantity(value) elif re.match(QUANTITY_RANGE_REGEX, value) is not None: first, second = value.split(" to ", maxsplit=1) second_quantity = u.Quantity(second) first_quantity = u.Quantity(first) * second_quantity.unit return (first_quantity, second_quantity) else: return value