Skip to content

Commit a9ff51c

Browse files
Implemented Qartod Timing/Gap Test
1 parent 2ab0bfc commit a9ff51c

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

ioos_qc/timing_gap.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env python
2+
"""Timing/Gap Test based on the IOOS QARTOD manuals."""
3+
4+
import logging
5+
import warnings
6+
from collections import namedtuple
7+
from numbers import Real as N
8+
from typing import Dict, List, Optional, Sequence, Tuple, Union
9+
from datetime import datetime, timedelta
10+
from enum import IntEnum
11+
import numpy as np
12+
import pandas as pd
13+
14+
try:
15+
from numba.core.errors import NumbaTypeError
16+
except ImportError:
17+
NumbaTypeError = TypeError
18+
19+
from ioos_qc.utils import (
20+
add_flag_metadata,
21+
great_circle_distance,
22+
isfixedlength,
23+
isnan,
24+
mapdates,
25+
)
26+
27+
L = logging.getLogger(__name__)
28+
29+
30+
class QartodFlags:
31+
"""Primary flags for QARTOD."""
32+
33+
GOOD = 1
34+
UNKNOWN = 2
35+
SUSPECT = 3
36+
FAIL = 4
37+
MISSING = 9
38+
39+
40+
FLAGS = QartodFlags # Default name for all check modules
41+
NOTEVAL_VALUE = QartodFlags.UNKNOWN
42+
43+
def timing_gap_test(tim_stmp: float, tim_inc: float) -> np.ndarray:
44+
"""
45+
Timing/Gap Test checks if the data has arrived within the expected time window.
46+
47+
Parameters
48+
----------
49+
tim_stmp : float
50+
Timestamp of the most recent data.
51+
tim_inc : float
52+
Allowed time increment or window for data to arrive (in seconds).
53+
54+
Returns
55+
-------
56+
flag_arr : np.ndarray
57+
An array with the flag, 1 for Pass, 4 for Fail.
58+
"""
59+
60+
# Get the current timestamp
61+
now = datetime.now().timestamp()
62+
63+
# Calculate the time difference between the current time and the data's timestamp
64+
time_diff = now - tim_stmp
65+
66+
# Initialize flag array with a passing value
67+
flag_arr = np.ma.ones(1, dtype="uint8")
68+
69+
# If the time difference exceeds the allowed increment, flag as Fail
70+
if time_diff > tim_inc:
71+
flag_arr[0] = QartodFlags.FAIL
72+
73+
return flag_arr

tests/test_timing_gap.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import logging
2+
import unittest
3+
import warnings
4+
5+
import numpy as np
6+
import numpy.testing as npt
7+
import pandas as pd
8+
import pytest
9+
from datetime import datetime, timedelta
10+
11+
from ioos_qc import timing_gap
12+
13+
L = logging.getLogger("ioos_qc")
14+
L.setLevel(logging.INFO)
15+
L.handlers = [logging.StreamHandler()]
16+
17+
18+
class QartodTimingTest(unittest.TestCase):
19+
def test_timing_gap_test(self):
20+
# Example 1: Data is within the expected time window
21+
tim_stmp = datetime.now().timestamp() - 3000
22+
tim_inc = 3600 # 1 hour window
23+
24+
flag_arr = timing_gap.timing_gap_test(tim_stmp, tim_inc)
25+
self.assertEqual(flag_arr[0], timing_gap.QartodFlags.GOOD, "Timing test should pass when data is within window.")
26+
27+
# Example case 2: Data is outside the expected time window
28+
tim_stmp = datetime.now().timestamp() - 7200
29+
tim_inc = 3600 # 1 hour window
30+
31+
flag_arr = timing_gap.timing_gap_test(tim_stmp, tim_inc)
32+
self.assertEqual(flag_arr[0], timing_gap.QartodFlags.FAIL, "Timing test should fail when data is outside the window.")
33+
34+
# Example case 3: (should fail)
35+
tim_stmp = datetime(2023, 2, 1, 12, 0, 0).timestamp()
36+
tim_inc = 3600 * 24 * 30 # 30-day window
37+
38+
flag_arr = timing_gap.timing_gap_test(tim_stmp, tim_inc)
39+
self.assertEqual(flag_arr[0], timing_gap.QartodFlags.FAIL, "Timing test should fail when data is beyond the 30-day window.")

0 commit comments

Comments
 (0)