From d29519e77327d40432b857f75842543467ae5f0c Mon Sep 17 00:00:00 2001
From: Paolo Veglio <paolo.veglio@ssec.wisc.edu>
Date: Tue, 31 Jan 2023 17:22:14 +0000
Subject: [PATCH] first draft of testing functions

---
 read_data.py            |  79 ++++++++++++++++++++------
 tests/test_read_data.py | 120 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 182 insertions(+), 17 deletions(-)
 create mode 100644 tests/test_read_data.py

diff --git a/read_data.py b/read_data.py
index a2e64c5..415fc69 100644
--- a/read_data.py
+++ b/read_data.py
@@ -3,7 +3,6 @@ import numpy as np
 import numpy.typing as npt
 
 import ancillary_data as anc
-import scene as scn
 
 import os
 import logging
@@ -14,6 +13,7 @@ from attrs import define, field, validators, Factory
 _DTR = np.pi/180.
 _RTD = 180./np.pi
 _bad_data = -999.0
+_datapath = '/ships19/hercules/pveglio/mvcm_viirs_hires'
 
 logging.basicConfig(level=logging.INFO, format='%(name)s - %(levelname)s - %(message)s')
 # logging.basicConfig(level=logging.INFO, filename='logfile.log', 'filemode='w',
@@ -50,16 +50,28 @@ class CollectInputs(object):
     dims [optional]: str
         name of the dimensions for the arrays in the xarray.Dataset output
     """
-    file_name_geo: str = field(default='', validator=[validators.instance_of(str), ])
-    file_name_l1b: str = field(default='', validator=[validators.instance_of(str), ])
-    ancillary_dir: str = field(default='', validator=[validators.instance_of(str), ])
-    sst_file: str = field(default='', validator=[validators.instance_of(str), ])
-    ndvi_file: str = field(default='', validator=[validators.instance_of(str), ])
-    geos_file_before: str = field(default='', validator=[validators.instance_of(str), ])
-    geos_file_after: str = field(default='', validator=[validators.instance_of(str), ])
-    geos_land: str = field(default='', validator=[validators.instance_of(str), ])
-    geos_ocean: str = field(default='', validator=[validators.instance_of(str), ])
-    geos_constants: str = field(default='', validator=[validators.instance_of(str), ])
+    file_name_geo: str = field(default=f'{_datapath}/VNP03MOD.A2022173.1312.001.2022174012746.uwssec.nc',
+                               validator=[validators.instance_of(str), ])
+    file_name_l1b: str = field(default=f'{_datapath}/VNP02MOD.A2022173.1312.001.2022174011547.uwssec.nc',
+                               validator=[validators.instance_of(str), ])
+    ancillary_dir: str = field(default=f'{_datapath}/ancillary',
+                               validator=[validators.instance_of(str), ])
+    sst_file: str = field(default='oisst.20220622',
+                          validator=[validators.instance_of(str), ])
+    eco_file: str = field(default='goge1_2_img.v1',
+                          validator=[validators.instance_of(str), ])
+    ndvi_file: str = field(default='NDVI.FM.c004.v2.0.WS.00-04-177.hdf',
+                           validator=[validators.instance_of(str), ])
+    geos_file_1: str = field(default='GEOS.fpit.asm.inst3_2d_asm_Nx.GEOS5124.20220622_1200.V01.nc4',
+                             validator=[validators.instance_of(str), ])
+    geos_file_2: str = field(default='GEOS.fpit.asm.inst3_2d_asm_Nx.GEOS5124.20220622_1500.V01.nc4',
+                             validator=[validators.instance_of(str), ])
+    geos_land: str = field(default='GEOS.fpit.asm.tavg1_2d_lnd_Nx.GEOS5124.20220622_1330.V01.nc4',
+                           validator=[validators.instance_of(str), ])
+    geos_ocean: str = field(default='GEOS.fpit.asm.tavg1_2d_ocn_Nx.GEOS5124.20220622_1330.V01.nc4',
+                            validator=[validators.instance_of(str), ])
+    geos_constants: str = field(default='GEOS.fp.asm.const_2d_asm_Nx.00000000_0000.V01.nc4',
+                                validator=[validators.instance_of(str), ])
 
     dims: tuple = field(default=('number_of_lines', 'number_of_pixels'),
                         validator=[validators.instance_of(tuple), ])
@@ -335,10 +347,12 @@ class ReadAncillary(CollectInputs):
         sst: npt.NDArray[float]
             array containing the Reynolds SST interpolated at the sensor's resolution
         """
+        if not os.path.isfile(os.path.join(self.ancillary_dir, self.sst_file)):
+            logging.error('SST file not found')
         sst = np.empty(self.out_shape, dtype=np.float32).ravel()
         sst = anc.py_get_Reynolds_SST(self.latitude.ravel(), self.longitude.ravel(), self.resolution,
                                       self.ancillary_dir, self.sst_file, sst)
-        logging.debug('SST read successfully')
+        logging.debug('SST file read successfully')
         return sst.reshape(self.out_shape)
 
     def get_ndvi(self) -> npt.NDArray[float]:
@@ -352,14 +366,30 @@ class ReadAncillary(CollectInputs):
         ndvi: npt.NDArray[float]
             NDVI interpolated at the sensor's resolution
         """
+        if not os.path.isfile(os.path.join(self.ancillary_dir, self.ndvi_file)):
+            logging.error('NDVI file not found')
         ndvi = np.empty(self.out_shape, dtype=np.float32).ravel()
         ndvi = anc.py_get_NDVI_background(self.latitude.ravel(), self.longitude.ravel(), self.resolution,
                                           self.ancillary_dir, self.ndvi_file, ndvi)
-        logging.debug('NDVI read successfully')
+        logging.debug('NDVI file read successfully')
         return ndvi.reshape(self.out_shape)
 
-    def get_eco(self):
-        pass
+    def get_eco(self) -> npt.NDArray[float]:
+        """Read ECO file
+
+        Parameters
+        ----------
+
+        Returns
+        -------
+        eco: npt.NDArray[float]
+            Olson ecosystem type interpolated at the sensor's resolution
+        """
+        eco = np.empty(self.out_shape, dtype=np.ubyte).ravel()
+        eco = anc.py_get_Olson_eco(self.latitude.ravel(), self.longitude.ravel(), self.resolution,
+                                   self.ancillary_dir, eco)
+        logging.debug('Olson ecosystem file read successfully')
+        return eco.reshape(self.out_shape)
 
     def get_geos(self) -> Dict:
         """Read GEOS-5 data and interpolate the fields to the sensor resolution
@@ -372,13 +402,24 @@ class ReadAncillary(CollectInputs):
         geos_data: Dict
             dictionary containing all quantities required by MVCM (see geos_variables here below)
         """
+        if not os.path.isfile(os.path.join(self.ancillary, self.geos_file_1)):
+            logging.error('GEOS-5 file 1 not found')
+        if not os.path.isfile(os.path.join(self.ancillary, self.geos_file_2)):
+            logging.error('GEOS-5 file 2 not found')
+        if not os.path.isfile(os.path.join(self.ancillary, self.geos_land_file)):
+            logging.error('GEOS-5 land file not found')
+        if not os.path.isfile(os.path.join(self.ancillary, self.geos_ocean_file)):
+            logging.error('GEOS-5 ocean file not found')
+        if not os.path.isfile(os.path.join(self.ancillary, self.geos_constants_file)):
+            logging.error('GEOS-5 constants file not found')
+
         geos_variables = ['tpw', 'snow_fraction', 'ice_fraction', 'ocean_fraction',
                           'land_ice_fraction', 'surface_temperature']
         geos_data = {var: np.empty(self.out_shape, dtype=np.float32).ravel() for var in geos_variables}
 
         geos_data = anc.py_get_GEOS(self.latitude.ravel(), self.longitude.ravel(), self.resolution,
-                                    self.get_granule_time(), self.ancillary_dir, self.geos_file_before,
-                                    self.geos_file_after, self.geos_land, self.geos_ocean,
+                                    self.get_granule_time(), self.ancillary_dir, self.geos_file_1,
+                                    self.geos_file_2, self.geos_land, self.geos_ocean,
                                     self.geos_constants, geos_data)
 
         for var in list(geos_variables):
@@ -400,6 +441,7 @@ class ReadAncillary(CollectInputs):
         """
         ancillary_data = xr.Dataset()
         ancillary_data['sst'] = (self.dims, self.get_sst())
+        ancillary_data['ecosystem'] = (self.dims, self.get_eco())
         ancillary_data['ndvi'] = (self.dims, self.get_ndvi())
 
         geos_tmp = self.get_geos()
@@ -408,6 +450,8 @@ class ReadAncillary(CollectInputs):
 
         return ancillary_data
 
+
+"""
     scene_flags = scn.find_scene(viirs, sunglint_angle)
     scene = scn.scene_id(scene_flags)
 
@@ -534,3 +578,4 @@ def get_data(satellite: str,
     data.drop_vars(['latitude', 'longitude'])
 
     return data
+"""
diff --git a/tests/test_read_data.py b/tests/test_read_data.py
new file mode 100644
index 0000000..e070170
--- /dev/null
+++ b/tests/test_read_data.py
@@ -0,0 +1,120 @@
+import numpy as np
+import xarray as xr
+import os
+
+import pytest
+
+import read_data as rd
+
+
+@pytest.fixture
+def fixturepath():
+    return os.path.join(os.path.dirname(__file__), 'fixtures')
+
+
+# @pytest.fixture()
+# def l1b_file(fixturepath):
+#     return os.path.join(fixturepath, '')
+
+
+# @pytest.fixture()
+# def geo_file(fixturepath):
+#     return os.path.join(fixturepath, '')
+
+
+# @pytest.fixture
+# def ancillary_dir(fixturepath):
+#     return os.path.join(fixturepath, '')
+
+
+@pytest.fixture
+def sst_file():
+    return 'oisst.20220622'
+
+
+@pytest.fixture
+def ndvi_file():
+    return 'NDVI.FM.c004.v2.0.WS.00-04.177.hdf'
+
+
+@pytest.fixture
+def geos_file_1():
+    return 'GEOS.fpit.asm.inst3_2d_asm_Nx.GEOS5124.20220622_1200.V01.nc4'
+
+
+@pytest.fixture
+def geos_file_2():
+    return 'GEOS.fpit.asm.inst3_2d_asm_Nx.GEOS5124.20220622_1500.V01.nc4'
+
+
+@pytest.fixture
+def geos_land():
+    return 'GEOS.fpit.asm.tavg1_2d_lnd_Nx.GEOS5124.20220622_1330.V01.nc4'
+
+
+@pytest.fixture
+def geos_ocean():
+    return 'GEOS.fpit.asm.tavg1_2d_ocn_Nx.GEOS5124.20220622_1330.V01.nc4'
+
+
+@pytest.fixture
+def geos_constants():
+    return 'GEOS.fp.asm.const_2d_asm_Nx.00000000_0000.V01.nc4'
+
+
+@pytest.fixture
+def ref_file(fixturepath):
+    return os.path.join(fixturepath, 'ref_ancillary.nc')
+
+
+def test_sst(fixturepath, sst_file, ref_file):
+    viirs = rd.ReadData(satellite='snpp',
+                        sensor='viirs')
+    geo = viirs.read_viirs_geo()
+    ancillary = rd.ReadAncillary(latitude=geo.latitude.values,
+                                 longitude=geo.longitude.values,
+                                 resolution=1,
+                                 ancillary_dir=fixturepath,
+                                 sst_file=sst_file)
+    sst = ancillary.get_sst()
+    check_differences(ref_file, sst, 'sst')
+
+
+def test_ndvi(fixturepath, ndvi_file, ref_file):
+    viirs = rd.ReadData(satellite='snpp',
+                        sensor='viirs')
+    geo = viirs.read_viirs_geo()
+    ancillary = rd.ReadAncillary(latitude=geo.latitude.values,
+                                 longitude=geo.longitude.values,
+                                 resolution=1,
+                                 ancillary_dir=fixturepath,
+                                 ndvi_file=ndvi_file)
+    ndvi = ancillary.get_ndvi()
+    check_differences(ref_file, ndvi, 'ndvi')
+
+
+def test_geos(fixturepath, geos_file_1, geos_file_2, geos_land, geos_ocean,
+              geos_constants, ref_file):
+    viirs = rd.ReadData(satellite='snpp',
+                        sensor='viirs')
+    geo = viirs.read_viirs_geo()
+    ancillary = rd.ReadAncillary(latitude=geo.latitude.values,
+                                 longitude=geo.longitude.values,
+                                 resolution=1,
+                                 ancillary_dir=fixturepath,
+                                 geos_file_1=geos_file_1,
+                                 geos_file_2=geos_file_2,
+                                 geos_land=geos_land,
+                                 geos_ocean=geos_ocean,
+                                 geos_constants=geos_constants)
+    geos_data = ancillary.get_geos()
+
+    for var in list(geos_data.keys()):
+        check_differences(ref_file, geos_data[var], f'geos_{var}')
+
+
+def check_differences(ref_file, test_data, var_name):
+    ref_data = xr.open_dataset(ref_file)
+    check = np.allclose(ref_data[var_name].values, test_data, equal_nan=True)
+
+    assert check
-- 
GitLab