diff --git a/main.py b/main.py
index 2836c5971f522439a795a51028b078582f7aeac6..29acf57277e0e8608d5b4e0593fe54316bb4f297 100644
--- a/main.py
+++ b/main.py
@@ -1,9 +1,32 @@
-import tests
 import ruamel_yaml as yml
 import numpy as np
 
+import read_data as rd
+import tests
+
 
 def main():
+    datapath = '/ships19/hercules/pveglio/neige_data/snpp_test_input'
+    fname_l1b = 'VNP02MOD.A2014213.1548.001.2017301015346.uwssec.bowtie_restored_scaled.nc'
+    fname_geo = 'VNP03MOD.A2014213.1548.001.2017301015705.uwssec.nc'
+    thresh_file = '/home/pveglio/mvcm_leo/thresholds/new_thresholds.mvcm.snpp.v1.0.0.yaml'
+
+    viirs_data = rd.read_data(f'{datapath}/{fname_l1b}', f'{datapath}/{fname_geo}')
+
+    with open(thresh_file) as f:
+        text = f.read()
+    thresholds = yml.safe_load(text)
+
+    confidence = np.zeros(2, viirs_data['M01'].shape[0], viirs_data['M01'].shape[1])
+
+    confidence[0, :, :] = tests.test_11um(viirs_data.M15.values, thresholds['Daytime_Ocean'])
+    confidence[1, :, :] = tests.test_11_4diff(viirs_data.M15.values, viirs_data.M13.values,
+                                              thresholds['Daytime_Ocean'])
+
+    return confidence
+
+
+def test_main():
 
     rad1 = [[255, 260, 265, 248, 223],
             [278, 285, 270, 268, 256],
@@ -13,7 +36,6 @@ def main():
             [280, 281, 272, 270, 267]]
     thresh_file = '/home/pveglio/mvcm_leo/thresholds/new_thresholds.mvcm.snpp.v1.0.0.yaml'
 
-
     with open(thresh_file) as f:
         text = f.read()
 
@@ -23,12 +45,9 @@ def main():
     confidence = np.zeros((2, rad1.shape[0], rad1.shape[1]))
 
     thresholds = yml.safe_load(text)
-    thr_11um = thresholds['Daytime_Ocean']
-    thr_11_4diff = thresholds['Daytime_Ocean']
-
-    confidence[0, :, :] = tests.test_11um(rad1, thr_11um['bt11'])
-    confidence[1, :, :] = tests.test_11_4diff(rad1, rad2, thr_11_4diff['test11_4lo'])
 
+    confidence[0, :, :] = tests.test_11um(rad1, thresholds['Daytime_Ocean'])
+    confidence[1, :, :] = tests.test_11_4diff(rad1, rad2, thresholds['Daytime_Ocean'])
 
     print(f'Confidence[0,:,:]: \n {confidence[0, :, :]}')
     print(f'Confidence[1,:,:]: \n {confidence[1, :, :]}')
@@ -37,4 +56,4 @@ def main():
 
 
 if __name__ == "__main__":
-    main()
+    test_main()
diff --git a/read_data.py b/read_data.py
index 90037500d114439738d51760654cb6f9b1a62bad..036847406c3b61b314104e19b377806265d99c5f 100644
--- a/read_data.py
+++ b/read_data.py
@@ -1,8 +1,11 @@
-from netCDF4 import Dataset
+# from netCDF4 import Dataset
 
 import xarray as xr
 import numpy as np
 
+_DTR = np.pi/180.
+_RTD = 180./np.pi
+
 
 def read_data(sensor: str, l1b_filename: str, geo_filename: str):
 
@@ -28,6 +31,26 @@ def read_data(sensor: str, l1b_filename: str, geo_filename: str):
 
     in_data = in_data.merge(data)
 
+    relazi = relative_azimuth_angle(data['sensor_azimuth'].values, data['solar_azimuth'].values)
+    sunglint = sun_glint_angle(data['sensor_zenith'].values, data['solar_zenith'].values, relazi)
+
+    in_data['relative_azimuth'] = (('number_of_lines', 'number_of_pixels'), relazi)
+    in_data['sunglint_angle'] = (('number_of_lines', 'number_of_pixels'), sunglint)
+
     return in_data
 
 
+def relative_azimuth_angle(sensor_azimuth: float, solar_azimuth: float) -> float:
+    rel_azimuth = np.abs(180. - np.abs(sensor_azimuth - solar_azimuth))
+    return rel_azimuth
+
+
+def sun_glint_angle(sensor_zenith: float, solar_zenith: float, rel_azimuth: float) -> float:
+    cossna = (np.sin(sensor_zenith*_DTR) * np.sin(solar_zenith*_DTR) * np.cos(rel_azimuth*_DTR) +
+              np.cos(sensor_zenith*_DTR) * np.cos(solar_zenith*_DTR))
+    sunglint_angle = np.arccos(cossna) * _RTD
+    return sunglint_angle
+
+
+def correct_reflectances():
+    pass
diff --git a/tests.py b/tests.py
index a5070ee1d7adbd3a8813235be3c6e606a1beea82..5564ea7e334850130b4972ef5172cf65b9f78e3b 100644
--- a/tests.py
+++ b/tests.py
@@ -1,29 +1,86 @@
 import numpy as np
 
-
-_test_rad = np.random.randint(25, size=[6, 8])
-#_test_thr = [15, 10, 5, 1, 1]
-_test_thr = [5, 10, 15, 1, 1]
+import utils
 
 
 def test_11um(rad, threshold):
 
-    #if (~np.isnan(rad) or threshold[4] == 1.0):
-    confidence = conf_test(rad, threshold)
+    thr = threshold['bt11']
+    if thr[4] == 1:
+        # the C code has the line below that I don't quite understand the purpose of.
+        # It seems to be setting the bit to 0 if the BT value is greater than the midpoint
+        #
+        # if (m31 >= dobt11[1]) (void) set_bit(13, pxout.testbits);
+
+        confidence = utils.conf_test(rad, thr)
 
     return confidence
 
 
 def test_11_4diff(rad1, rad2, threshold):
 
-    raddiff = rad1 - rad2;
-    confidence = conf_test(raddiff, threshold)
+    day = True
+    sunglint = False
+    thr = threshold['test11_4lo']
+    raddiff = rad1 - rad2
+
+    if day is True and sunglint is False:
+        confidence = utils.conf_test(raddiff, thr)
+
+    return confidence
+
+
+def nir_refl_test(rad, threshold):
+
+    sunglint = False
+    sza = 0
+    refang = 0
+    vza = 0
+    dtr = 0
+    band_n = 2
+    vzcpow = 0
+
+    sunglint_thr = np.zeros((4,))
+    # ref2 [5]
+    # b2coeffs [4]
+    # b2mid [1]
+    # b2bias_adj [1]
+    # b2lo [1]
+    # vzcpow [3] (in different place)
+
+    coeffs = threshold['b2coeffs']
+    hicut0 = coeffs[0] + coeffs[1]*sza + coeffs[2]*np.power(sza, 2) + coeffs[3]*np.power(sza, 3)
+    hicut0 = (hicut0 * 0.01) + threshold['b2adj']
+    hicut0 = hicut0 * threshold['b2bias_adj']
+    midpt0 = hicut0 + (threshold['b2mid'] * threshold['b2bias_adj'])
+    locut0 = midpt0 + (threshold['b2lo'] * threshold['b2bias_adj'])
+
+    if sunglint is True:
+        # Keep in mind that band_n uses MODIS band numbers (2=0.86um and 7=2.1um)
+        # For VIIRS would be 2=M7 (0.865um) and 7=M11 (2.25um)
+        sunglint_thr = utils.get_sunglint_thresholds(refang, threshold['Sun_Glint'],
+                                                     band_n, sunglint_thr)
+        locut1 = sunglint[0]
+        midpt1 = sunglint[1]
+        hicut1 = sunglint[2]
+    else:
+        locut1 = locut0
+        midpt1 = midpt0
+        hicut1 = hicut0
+
+    cosvza = np.cos(vza*dtr)
+    locut2 = locut1 * (1./np.power(cosvza, vzcpow[0]))
+    midpt2 = midpt1 * (1./np.power(cosvza, vzcpow[0]))
+    hicut2 = hicut1 * (1./np.power(cosvza, vzcpow[0]))
+
+    corr_thr = [locut2, hicut2, 1.0, midpt2]
+    confidence = utils.conf_test(rad, corr_thr)
 
     return confidence
 
 
-def simple_threshold_test(rad, threshold):
-    return conf_test(rad, threshold)
+def vis_nir_ratio_test(rad1, rad2, threshold):
+    pass
 
 
 class CloudMaskTests(object):
@@ -51,177 +108,12 @@ class CloudMaskTests(object):
         pass
 
 
-def conf_test(rad=_test_rad, thr=_test_thr):
-    '''
-    Assuming a linear function between min and max confidence level, the plot below shows
-    how the confidence (y axis) is computed as function of radiance (x axis).
-    This case illustrates alpha < gamma, obviously in case alpha > gamma, the plot would be
-    flipped.
-                       gamma
-    c  1                 ________
-    o  |                /
-    n  |               /
-    f  |              /
-    i  |     beta    /
-    d 1/2    |....../
-    e  |           /
-    n  |          /
-    c  |         /
-    e  0________/
-       |      alpha
-    --------- radiance ---------->
-    '''
-
-    coeff = np.power(2, (thr[3] - 1))
-    hicut = thr[0]
-    beta = thr[1]
-    locut = thr[2]
-    power = thr[3]
-    radshape = rad.shape
-    rad = rad.reshape((rad.shape[0]*rad.shape[1]))
-    c = np.zeros(rad.shape)
-
-    if hicut > locut:
-        gamma = thr[0]
-        alpha = thr[2]
-        flipped = False
-    else:
-        gamma = thr[2]
-        alpha = thr[0]
-        flipped = True
-
-    # Rad between alpha and beta
-    range_ = 2. * (beta - alpha)
-    s1 = (rad[rad <= beta] - alpha) / range_
-    if flipped is False:
-        c[rad <= beta] = coeff * np.power(s1, power)
-    if flipped is True:
-        c[rad <= beta] = 1. - (coeff * np.power(s1, power))
-
-    # Rad between beta and gamma
-    range_ = 2. * (beta - gamma)
-    s1 = (rad[rad > beta] - gamma) / range_
-    if flipped is False:
-        c[rad > beta] = 1. - (coeff * np.power(s1, power))
-    if flipped is True:
-        c[rad > beta] = coeff * np.power(s1, power)
-
-    # Rad outside alpha-gamma interval
-    if flipped is False:
-        c[rad > gamma] = 1
-        c[rad < alpha] = 0
-    if flipped is True:
-        c[rad > gamma] = 0
-        c[rad < alpha] = 1
-
-    c[c > 1] = 1
-    c[c < 0] = 0
-
-    confidence = c.reshape(radshape)
-
-    return confidence
-
-
-def conf_test_dble(rad, coeffs):
-    '''
-
-            gamma1                         gamma2
-    c  1_______                               ________
-    o  |       \                             /
-    n  |        \                           /
-    f  |         \                         /
-    i  |          \   beta1       beta2   /
-    d 1/2          \....|          |...../
-    e  |            \                   /
-    n  |             \                 /
-    c  |              \               /
-    e  0               \_____________/
-       |             alpha1       alpha2
-    --------------------- radiance ------------------------->
-    '''
-
-    hicut = [coeffs[0], coeffs[1]]
-    locut = [coeffs[2], coeffs[3]]
-    midpt = [coeffs[4], coeffs[5]]
-    power = coeffs[6]
-
-    gamma1 = hicut[0]
-    gamma2 = hicut[1]
-    alpha1 = locut[0]
-    alpha2 = locut[1]
-    beta1 = midpt[0]
-    beta2 = midpt[1]
-
-    coeff = np.power(2, (power - 1))
-    radshape = rad.shape
-    rad = rad.reshape((rad.shape[0]*rad.shape[1]))
-    c = np.zeros(rad.shape)
-
-    # Find if interval between inner cutoffs passes or fails test
-    if (alpha1 - gamma1 > 0):
-
-       # Value is within range of lower set of limits
-        range_ = 2 * (beta1 - alpha1)
-        s1 = (rad[(rad <= alpha1) & (rad >= beta1)] - alpha1) / range_
-        c[(rad <= alpha1) & (rad >= beta1)] = coeff * np.power(s1, power)
-
-        range_ = 2 * (beta1 - gamma1)
-        s1 = (rad[(rad <= alpha1) & (rad < beta1)] - gamma1) / range_
-        c[(rad <= alpha1) & (rad < beta1)] = coeff * np.power(s1, power)
-
-        # Value is within range of upper set of limits
-        range_ = 2 * (beta2 - alpha2)
-        s1 = (rad[(rad > alpha1) & (rad <= beta2)] - alpha2) / range_
-        c[(rad > alpha1) & (rad <= beta2)] = coeff * np.power(s1, power)
-
-        range_ = 2 * (beta2 - gamma2)
-        s1 = (rad[(rad > alpha1) & (rad > beta2)] - gamma2) / range_
-        c[(rad > alpha1) & (rad > beta2)] = coeff * np.power(s1, power)
-
-        # Inner region fails test
-        # Check for value beyond function range
-        c[(rad > alpha1) & (rad < alpha2)] = 0
-        c[(rad < gamma1) | (rad > gamma2)] = 1
-
-    else:
-
-        # Value is withing range of lower set of limits
-        range_ = 2 * (beta1 - alpha1)
-        s1 = (rad[(rad <= gamma1) & (rad <= beta1)] - alpha1) / range_
-        c[(rad <= gamma1) & (rad <= beta1)] = coeff * np.power(s1, power)
-
-        range_ = 2 * (beta1 - gamma1)
-        s1 = (rad[(rad <= gamma1) & (rad > beta1)] - gamma1) / range_
-        c[(rad <= gamma1) & (rad > beta1)] = coeff * np.power(s1, power)
-
-        # Value is within range of upper set of limits
-        range_ = 2 * (beta2 - alpha2)
-        s1 = (rad[(rad > gamma1) & (rad >= beta2)] - alpha2) / range_
-        c[(rad > gamma1) & (rad >= beta2)] = coeff * np.power(s1, power)
-
-        range_ = 2 * (beta2 - gamma2)
-        s1 = (rad[(rad > gamma1) & (rad < beta2)] - gamma2) / range_
-        c[(rad > gamma1) & (rad < beta2)] = coeff * np.power(s1, power)
-
-        # Inner region passes test
-        # Check for value beyond function range
-        c[(rad > gamma1) & (rad < gamma2)] = 1
-        c[(rad < alpha1) | (rad > alpha2)] = 0
-
-    c[c>1] = 1
-    c[c<0] = 0
-
-    confidence = c.reshape(radshape)
-
-    return confidence
-
-
 def test():
     rad = np.random.randint(50, size=[4, 8])
-    #coeffs = [5, 42, 20, 28, 15, 35, 1]
-    #coeffs = [20, 28, 5, 42, 15, 35, 1]
+    # coeffs = [5, 42, 20, 28, 15, 35, 1]
+    # coeffs = [20, 28, 5, 42, 15, 35, 1]
     coeffs = [35, 15, 20, 1, 1]
-    #confidence = conf_test_dble(rad, coeffs)
+    # confidence = conf_test_dble(rad, coeffs)
     confidence = test_11um(rad, coeffs)
     print(rad)
     print('\n')
diff --git a/utils.py b/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..5be3d78aad42764e0c96c6288027983243a5f1c5
--- /dev/null
+++ b/utils.py
@@ -0,0 +1,225 @@
+import numpy as np
+
+_test_rad = np.random.randint(25, size=[6, 8])
+# _test_thr = [15, 10, 5, 1, 1]
+_test_thr = [5, 10, 15, 1, 1]
+
+
+# this function creates a map of sunglint areas, based on the different angles set in the
+# threshold file. The goal is to create an array of indices that I can use to quickly assign
+# different coefficients depending on the angle interval. This will be mostly used in the
+# function get_sunglint_thresholds().
+# All of this is because we want to be able to process the whole array, instead of iterating
+# over all pixels one by one.
+def sunglint_scene(refang, sunglint_thr):
+    sunglint_flag = np.zeros(refang.shape)
+    sunglint_flag[refang <= sunglint_thr['bounds'][3]] = 1
+    sunglint_flag[refang <= sunglint_thr['bounds'][2]] = 2
+    sunglint_flag[refang <= sunglint_thr['bounds'][1]] = 3
+    return sunglint_flag
+
+
+def get_sunglint_thresholds(refang, thresholds, band_n, sunglint):
+
+    band = f'band{band_n}'
+
+#    if refang > thresholds['bounds'][3]:
+#       sunglint = sunglint
+#        # dosgref[2] = hicnf
+#        # dosgref[0] = locnf
+#        # dosgref[1] = mdcnf
+#        # sunglint[3] = doref2[3]
+
+    if refang <= thresholds['bounds'][1]:
+        sunglint = thresholds[f'{band}_0deg']
+
+    else:
+
+        if (refang > thresholds['bounds'][1] and refang <= thresholds['bounds'][2]):
+            lo_ang = thresholds['bounds'][1]
+            hi_ang = thresholds['bounds'][2]
+            lo_ang_val = thresholds[f'{band}_10deg'][0]
+            hi_ang_val = thresholds[f'{band}_10deg'][1]
+            power = thresholds[f'{band}_10deg'][3]
+            conf_range = thresholds[f'{band}_10deg'][2]
+
+        elif (refang > thresholds['bounds'][2] and refang <= thresholds['bounds'][3]):
+            lo_ang = thresholds['bounds'][2]
+            hi_ang = thresholds['bounds'][3]
+            lo_ang_val = thresholds[f'{band}_20deg'][0]
+            hi_ang_val = sunglint[1]
+            power = thresholds[f'{band}_20deg'][3]
+            conf_range = thresholds[f'{band}_20deg'][2]
+
+        a = (refang - lo_ang) / (hi_ang - lo_ang)
+        midpt = lo_ang_val + a*(hi_ang_val - lo_ang_val)
+        sunglint[1] = midpt
+        sunglint[2] = midpt - conf_range
+        sunglint[0] = midpt + conf_range
+        sunglint[3] = power
+
+    return sunglint
+
+
+def conf_test(rad=_test_rad, thr=_test_thr):
+    '''
+    Assuming a linear function between min and max confidence level, the plot below shows
+    how the confidence (y axis) is computed as function of radiance (x axis).
+    This case illustrates alpha < gamma, obviously in case alpha > gamma, the plot would be
+    flipped.
+                       gamma
+    c  1                 ________
+    o  |                /
+    n  |               /
+    f  |              /
+    i  |     beta    /
+    d 1/2    |....../
+    e  |           /
+    n  |          /
+    c  |         /
+    e  0________/
+       |      alpha
+    --------- radiance ---------->
+    '''
+
+    coeff = np.power(2, (thr[3] - 1))
+    hicut = thr[0]
+    beta = thr[1]
+    locut = thr[2]
+    power = thr[3]
+    radshape = rad.shape
+    rad = rad.reshape((rad.shape[0]*rad.shape[1]))
+    c = np.zeros(rad.shape)
+
+    if hicut > locut:
+        gamma = thr[0]
+        alpha = thr[2]
+        flipped = False
+    else:
+        gamma = thr[2]
+        alpha = thr[0]
+        flipped = True
+
+    # Rad between alpha and beta
+    range_ = 2. * (beta - alpha)
+    s1 = (rad[rad <= beta] - alpha) / range_
+    if flipped is False:
+        c[rad <= beta] = coeff * np.power(s1, power)
+    if flipped is True:
+        c[rad <= beta] = 1. - (coeff * np.power(s1, power))
+
+    # Rad between beta and gamma
+    range_ = 2. * (beta - gamma)
+    s1 = (rad[rad > beta] - gamma) / range_
+    if flipped is False:
+        c[rad > beta] = 1. - (coeff * np.power(s1, power))
+    if flipped is True:
+        c[rad > beta] = coeff * np.power(s1, power)
+
+    # Rad outside alpha-gamma interval
+    if flipped is False:
+        c[rad > gamma] = 1
+        c[rad < alpha] = 0
+    if flipped is True:
+        c[rad > gamma] = 0
+        c[rad < alpha] = 1
+
+    c[c > 1] = 1
+    c[c < 0] = 0
+
+    confidence = c.reshape(radshape)
+
+    return confidence
+
+
+def conf_test_dble(rad, coeffs):
+    # '''
+    #            gamma1                         gamma2
+    #    c  1_______                               ________
+    #    o  |       \                             /
+    #    n  |        \                           /
+    #    f  |         \                         /
+    #    i  |          \   beta1       beta2   /
+    #    d 1/2          \....|          |...../
+    #    e  |            \                   /
+    #    n  |             \                 /
+    #    c  |              \               /
+    #    e  0               \_____________/
+    #       |             alpha1       alpha2
+    #    --------------------- radiance ------------------------->
+    # '''
+
+    hicut = [coeffs[0], coeffs[1]]
+    locut = [coeffs[2], coeffs[3]]
+    midpt = [coeffs[4], coeffs[5]]
+    power = coeffs[6]
+
+    gamma1 = hicut[0]
+    gamma2 = hicut[1]
+    alpha1 = locut[0]
+    alpha2 = locut[1]
+    beta1 = midpt[0]
+    beta2 = midpt[1]
+
+    coeff = np.power(2, (power - 1))
+    radshape = rad.shape
+    rad = rad.reshape((rad.shape[0]*rad.shape[1]))
+    c = np.zeros(rad.shape)
+
+    # Find if interval between inner cutoffs passes or fails test
+    if (alpha1 - gamma1 > 0):
+
+        # Value is within range of lower set of limits
+        range_ = 2 * (beta1 - alpha1)
+        s1 = (rad[(rad <= alpha1) & (rad >= beta1)] - alpha1) / range_
+        c[(rad <= alpha1) & (rad >= beta1)] = coeff * np.power(s1, power)
+
+        range_ = 2 * (beta1 - gamma1)
+        s1 = (rad[(rad <= alpha1) & (rad < beta1)] - gamma1) / range_
+        c[(rad <= alpha1) & (rad < beta1)] = coeff * np.power(s1, power)
+
+        # Value is within range of upper set of limits
+        range_ = 2 * (beta2 - alpha2)
+        s1 = (rad[(rad > alpha1) & (rad <= beta2)] - alpha2) / range_
+        c[(rad > alpha1) & (rad <= beta2)] = coeff * np.power(s1, power)
+
+        range_ = 2 * (beta2 - gamma2)
+        s1 = (rad[(rad > alpha1) & (rad > beta2)] - gamma2) / range_
+        c[(rad > alpha1) & (rad > beta2)] = coeff * np.power(s1, power)
+
+        # Inner region fails test
+        # Check for value beyond function range
+        c[(rad > alpha1) & (rad < alpha2)] = 0
+        c[(rad < gamma1) | (rad > gamma2)] = 1
+
+    else:
+
+        # Value is withing range of lower set of limits
+        range_ = 2 * (beta1 - alpha1)
+        s1 = (rad[(rad <= gamma1) & (rad <= beta1)] - alpha1) / range_
+        c[(rad <= gamma1) & (rad <= beta1)] = coeff * np.power(s1, power)
+
+        range_ = 2 * (beta1 - gamma1)
+        s1 = (rad[(rad <= gamma1) & (rad > beta1)] - gamma1) / range_
+        c[(rad <= gamma1) & (rad > beta1)] = coeff * np.power(s1, power)
+
+        # Value is within range of upper set of limits
+        range_ = 2 * (beta2 - alpha2)
+        s1 = (rad[(rad > gamma1) & (rad >= beta2)] - alpha2) / range_
+        c[(rad > gamma1) & (rad >= beta2)] = coeff * np.power(s1, power)
+
+        range_ = 2 * (beta2 - gamma2)
+        s1 = (rad[(rad > gamma1) & (rad < beta2)] - gamma2) / range_
+        c[(rad > gamma1) & (rad < beta2)] = coeff * np.power(s1, power)
+
+        # Inner region passes test
+        # Check for value beyond function range
+        c[(rad > gamma1) & (rad < gamma2)] = 1
+        c[(rad < alpha1) | (rad > alpha2)] = 0
+
+    c[c > 1] = 1
+    c[c < 0] = 0
+
+    confidence = c.reshape(radshape)
+
+    return confidence