Beispiel #1
0
def test_floats(value):
    """Functional test to ensure the validate_datetime() method
    runs properly on float values."""
    ensure_numeric(value,
                   valid_types=[float],
                   nan_acceptable=True,
                   inf_acceptable=True)
Beispiel #2
0
def test_nan_inf():
    """Tests to ensure ensure_numeric() throws ValueErrors
    for NaN and infinite values when those parameters are
    set to `False`."""
    with pytest.raises(ValueError):
        # Test for NaN values
        assert ensure_numeric(nan,
                              valid_types=[int, float],
                              nan_acceptable=False)
    with pytest.raises(ValueError):
        # Test for infinite values
        assert ensure_numeric(inf,
                              valid_types=[int, float],
                              inf_acceptable=False)
Beispiel #3
0
def calculate_declination_degrees(
    B_degrees: Union[int, float, Iterable[Union[int, float]]]
) -> Union[float, Iterable[float]]:
    """
    The declination is the angular position of the sun
    at solar noon with respect to the plane of the
    equator (north is positive).  The declination angle
    must be between -23.45 and 23.45 degrees.
    The equation is from Spencer (1971).

    The equation used is from Duffie & Beckman (2006)
    Equation 1.6.1b.

    :param B_degrees: A numeric value (generally a float)
        which is calculated based on the day of the year,
        in units of degrees.

    :returns: A float value representing the
        declination angle of the sun.
    """

    # Type-check `B_degrees`
    ensure_numeric(
        B_degrees,
        valid_types=[int, float, np.number],
        nan_acceptable=False,
        inf_acceptable=False,
    )
    # Range-check `B_degrees` and `G_sc`
    validate_numeric_value(
        B_degrees,
        minimum=calculate_B_degrees(1),
        maximum=calculate_B_degrees(366),
    )

    # Convert `B_degrees` to radians for use in the calculation
    B_radians = np.radians(B_degrees)
    declination_degrees = (180.0 / np.pi *
                           (0.006918 - (0.399912 * np.cos(B_radians)) +
                            (0.070257 * np.sin(B_radians)) -
                            (0.006758 * np.cos(2 * B_radians)) +
                            (0.000907 * np.sin(2 * B_radians)) -
                            (0.002697 * np.cos(3 * B_radians)) +
                            (0.00148 * np.sin(3 * B_radians))))

    # Range-check `declination_degrees` before returning
    validate_numeric_value(declination_degrees, minimum=-23.45, maximum=23.45)

    return declination_degrees
Beispiel #4
0
def calculate_E_min(
    B_degrees: Union[int, float, Iterable[Union[int, float]]]
) -> Union[float, Iterable[float]]:
    """
    E is the equation of time (in minutes), which is
    based on the day of the year.
    The equation is given by Spencer (1971).

    The equation used is from Duffie & Beckman (2006)
    Equation 1.5.3.

    :param B_degrees: A numeric value (generally a float)
        which is calculated based on the day of the year,
        in units of degrees.

    :returns: A float value representing the equation of
        time for the given `B_degrees`, in units of minutes.
    """

    # Type-check `B_degrees`
    ensure_numeric(
        B_degrees,
        valid_types=[int, float, np.number],
        nan_acceptable=False,
        inf_acceptable=False,
    )
    # Range-check `B_degrees`
    validate_numeric_value(
        B_degrees,
        minimum=calculate_B_degrees(1),
        maximum=calculate_B_degrees(366),
    )
    # Convert `B_degrees` to radians for use in the calculation
    B_radians = np.radians(B_degrees)
    return 229.2 * (0.000075 + (0.001868 * np.cos(B_radians)) -
                    (0.032077 * np.sin(B_radians)) -
                    (0.014615 * np.cos(2 * B_radians)) -
                    (0.04089 * np.sin(2 * B_radians)))
Beispiel #5
0
def calculate_B_degrees(
        day_number: Union[int,
                          Iterable[int]]) -> Union[float, Iterable[float]]:
    """
    B is a preliminary value used in calculating the extraterrestrial
    radiation incident on the plane normal to the radiation on the
    `day_number` day of the year (G_on),
    per an equation given by Spencer (1971).

    The equation used is from Duffie & Beckman (2006)
    Equation 1.4.2.

    :param day_number: An integer representing the day number
        (of the year) of a specific date.  For example,
        January 1 corresponds to day number 1, and
        December 31 corresponds to day number 365
        (or 366, if a leap year).

    :returns: A float value, in units of degrees.
    """

    # Ensure `day_number` is an integer
    ensure_numeric(
        day_number,
        valid_types=[int, np.number],
        nan_acceptable=False,
        inf_acceptable=False,
    )
    # Ensure `day_number` is in the proper range
    validate_numeric_value(day_number, minimum=1, maximum=366)

    try:
        return (day_number - 1) * 360.0 / 365.0
    except TypeError:
        # When `day_number` is an iterable, but not a numpy array
        return (np.array(day_number) - 1) * 360.0 / 365
Beispiel #6
0
def test_iterable():
    """Functional test to ensure the validate_datetime() method
    runs properly on iterables."""
    ensure_numeric([1, 2, 3],
                   valid_types=[int],
                   nan_acceptable=True,
                   inf_acceptable=True)
    ensure_numeric(
        [1.2, -2.4, 3.7, inf],
        valid_types=[float],
        nan_acceptable=True,
        inf_acceptable=True,
    )
    ensure_numeric(
        [1, 2.5, inf, nan],
        valid_types=[int, float],
        nan_acceptable=True,
        inf_acceptable=True,
    )
Beispiel #7
0
def test_invalid_types():
    """Tests to ensure ensure_numeric() throws TypeErrors
    for invalid types."""
    with pytest.raises(TypeError):
        # Test for strings
        assert ensure_numeric("blah", valid_types=[int, float])
Beispiel #8
0
def test_integers(value):
    """Functional test to ensure the validate_datetime() method
    runs properly on integer values."""
    ensure_numeric(value, valid_types=[int])
Beispiel #9
0
    Equation 1.4.1b.

    :param B_degrees: A numeric value (generally a float)
        which is calculated based on the day of the year,
        in units of degrees.
    :param G_sc: The extraterrestrial solar radiation,
        assumed to be 1,367 W/m2 by default.

    :returns: A float value corresponding to `G_on` in units
        of W/m2.
    """

    # Type-check `B_degrees` and `G_sc`
    ensure_numeric(
        B_degrees,
        valid_types=[int, float, np.number],
        nan_acceptable=False,
        inf_acceptable=False,
    )
    ensure_numeric(
        G_sc,
        valid_types=[int, float, np.number],
        nan_acceptable=False,
        inf_acceptable=False,
    )

    # Range-check `B_degrees` and `G_sc`
    validate_numeric_value(
        B_degrees,
        minimum=calculate_B_degrees(1),
        maximum=calculate_B_degrees(366),
    )