|
| 1 | +#!/usr/bin/env python3 |
| 2 | + |
| 3 | +import os |
| 4 | +import unittest |
| 5 | + |
| 6 | +import numpy as np |
| 7 | +from netCDF4 import Dataset, chartostring |
| 8 | + |
| 9 | +from aodntools import __version__ |
| 10 | +from aodntools.timeseries_products.common import NoInputFilesError |
| 11 | +from aodntools.timeseries_products.velocity_hourly_timeseries import velocity_hourly_aggregated |
| 12 | +from test_aodntools.base_test import BaseTestCase |
| 13 | + |
| 14 | +TEST_ROOT = os.path.dirname(__file__) |
| 15 | +BAD_FILE = 'IMOS_ANMN-NRS_BAD_VELOCITY_FILE.nc' |
| 16 | +INPUT_FILES = [ |
| 17 | + 'IMOS_ANMN-NRS_AETVZ_20181213T080000Z_NRSROT-ADCP_FV01_NRSROT-ADCP-1812-Sentinel-or-Monitor-Workhorse-ADCP-44_END-20181215T100000Z_C-20200430T000000Z.nc', |
| 18 | + 'IMOS_ANMN-NRS_AETVZ_20180816T080000Z_NRSROT-ADCP_FV01_NRSROT-ADCP-1808-Sentinel-or-Monitor-Workhorse-ADCP-44_END-20180822T053000Z_C-20200623T000000Z.nc', |
| 19 | + 'IMOS_ANMN-NRS_AETVZ_20191016T080000Z_NRSROT-ADCP_FV01_NRSROT-ADCP-1910-Sentinel-or-Monitor-Workhorse-ADCP-44_END-20191018T100000Z_C-20200430T000000Z.nc', |
| 20 | + BAD_FILE |
| 21 | +] |
| 22 | +EXPECTED_OUTPUT_FILE = os.path.join( |
| 23 | + TEST_ROOT, 'IMOS_ANMN-NRS_VZ_20180816_NRSROT_FV02_velocity-hourly-timeseries_END-20191018_C-20220502.nc' |
| 24 | +) |
| 25 | + |
| 26 | +OBS_VARS = {'TIME', 'instrument_index', 'CELL_INDEX'} |
| 27 | +INST_VARS = {'LATITUDE', 'LONGITUDE', 'NOMINAL_DEPTH', 'SECONDS_TO_MIDDLE'} |
| 28 | +STR_VARS = {'source_file', 'instrument_id'} |
| 29 | +for v in ['DEPTH', 'UCUR', 'VCUR', 'WCUR']: |
| 30 | + OBS_VARS.add(v) |
| 31 | + for s in ['_min', '_max', '_std', '_count']: |
| 32 | + OBS_VARS.add(v + s) |
| 33 | + |
| 34 | + |
| 35 | +class TestVelocityHourlyTimeseries(BaseTestCase): |
| 36 | + def test_velocity_hourly(self): |
| 37 | + output_file, bad_files = velocity_hourly_aggregated(INPUT_FILES, 'NRSROT', |
| 38 | + input_dir=TEST_ROOT, output_dir='/tmp') |
| 39 | + |
| 40 | + self.assertEqual(1, len(bad_files)) |
| 41 | + for file, errors in bad_files.items(): |
| 42 | + self.assertEqual(BAD_FILE, file) |
| 43 | + |
| 44 | + dataset = Dataset(output_file) |
| 45 | + |
| 46 | + # check dimensions and variables |
| 47 | + self.assertSetEqual(set(dataset.dimensions), {'OBSERVATION', 'INSTRUMENT', 'strlen'}) |
| 48 | + self.assertSetEqual(set(dataset.variables.keys()), OBS_VARS | INST_VARS | STR_VARS) |
| 49 | + |
| 50 | + for var in OBS_VARS: |
| 51 | + self.assertEqual(dataset.variables[var].dimensions, ('OBSERVATION',)) |
| 52 | + for var in INST_VARS: |
| 53 | + self.assertEqual(dataset.variables[var].dimensions, ('INSTRUMENT',)) |
| 54 | + for var in STR_VARS: |
| 55 | + self.assertEqual(dataset.variables[var].dimensions, ('INSTRUMENT', 'strlen')) |
| 56 | + |
| 57 | + for f in chartostring(dataset['source_file'][:]): |
| 58 | + self.assertIn(f, INPUT_FILES) |
| 59 | + |
| 60 | + # check attributes |
| 61 | + self.assertEqual(__version__, dataset.generating_code_version) |
| 62 | + self.assertIn(__version__, dataset.lineage) |
| 63 | + |
| 64 | + # check aggregated variable values |
| 65 | + expected = Dataset(EXPECTED_OUTPUT_FILE) |
| 66 | + self.assertEqual(len(expected['TIME']), len(dataset['TIME'])) |
| 67 | + |
| 68 | + non_match_vars = [] |
| 69 | + for var in set(expected.variables.keys()) - STR_VARS: |
| 70 | + if not all(np.isclose(dataset[var], expected[var], equal_nan=True)): |
| 71 | + non_match_vars.append(var) |
| 72 | + self.assertEqual(non_match_vars, []) |
| 73 | + |
| 74 | + def test_all_rejected(self): |
| 75 | + self.assertRaises(NoInputFilesError, velocity_hourly_aggregated, [BAD_FILE], 'NRSROT', |
| 76 | + input_dir=TEST_ROOT, output_dir='/tmp') |
| 77 | + |
| 78 | + |
| 79 | +if __name__ == '__main__': |
| 80 | + unittest.main() |
0 commit comments