NASA Logo
Ocean Color Science Software

ocssw V2022
get_ndwi.c
Go to the documentation of this file.
1 
10 #include "l12_proto.h"
11 #include "vegetation_indices.h"
12 
13 static int32_t idx_band_swir = -1; // index of the 1250 band
14 // index indicating location of the rhos values of NIR in a multiband instrument
15 static int idx_multiband_nir;
16 static int idx_nir_min = BAD_INT; // A band index for NIR
17 static int idx_nir_max = BAD_INT; // A band index for NIR
18 
19 static int32_t num_bands; // Number of bands the instrument used has
20 
30 void calculate_ndwi(l1str *l1rec, float ndwi[]) {
31  int32_t idx_pixel = -0, idx_band = -0;
32  float rhos_nir = -0.0, rhos_swir = -0.0;
33 
34  // Check that band indices were set
35  if (idx_nir_max < 0 || idx_nir_min < 0 || idx_band_swir < 0) {
36  printf("NDWI requires NIR bands between 670 and 875, and at 1250 nm");
37  exit(EXIT_FAILURE);
38  }
39 
40  for (idx_pixel = 0; idx_pixel < l1rec->npix; idx_pixel++) {
41  ndwi[idx_pixel] = UNDEFINED;
42  idx_band = l1rec->l1file->nbands * idx_pixel;
43 
44  if (instrument_is_hyperspectral(num_bands)) { // Hyperspectral instrument
45 
46  // get average of rhos of nir
47  float *start_of_rhos_nir = &l1rec->rhos[idx_band + idx_nir_min];
48  int nir_band_width = idx_nir_max - idx_nir_min + 1; // Difference == width - 1; add 1 back
49 
50  rhos_nir = average_rhos_values(start_of_rhos_nir, nir_band_width);
51  // rhos_swir = l1rec->rhos[idx_band + idx_band_swir];
52 
53  } else {
54  rhos_nir = l1rec->rhos[idx_band + idx_multiband_nir];
55  }
56  rhos_swir = l1rec->rhos[idx_band + idx_band_swir];
57 
58  // check pixel validity
59  double pixel_elevation = l1rec->dem[idx_pixel];
60  double pixel_mask = (l1rec->flags[idx_pixel] & LAND_MASK);
61  double rhos_vals[] = {rhos_nir, rhos_swir};
62  int len = sizeof(rhos_vals) / sizeof(rhos_vals[0]);
63 
64  if (invalid_pixel(pixel_elevation, pixel_mask, rhos_vals, len)) {
65  l1rec->flags[idx_pixel] |= PRODFAIL;
66  continue;
67  }
68 
69  float ndwi_value = (rhos_nir - rhos_swir) / (rhos_nir + rhos_swir);
70  ndwi[idx_pixel] = clamp(ndwi_value, VI_MINVAL, VI_MAXVAL);
71  }
72 }
73 
79 void get_ndwi(l1str *l1rec, float prod[]) {
80  num_bands = l1rec->l1file->nbands;
81 
82  static bool first_call = true;
83  if (first_call) {
84  first_call = false;
85 
86  if (instrument_is_hyperspectral(num_bands)) { // TODO: Get rid of magic numbers
87  idx_nir_min = bindex_get(nir_min);
88  idx_nir_max = bindex_get(nir_max);
89  idx_band_swir = bindex_get(1250);
90  } else {
91  // get NIR and 1250 indices??
92  idx_multiband_nir = bindex_get(859);
93  idx_band_swir = bindex_get(1250);
94  }
95 
96  // Should I check for MODIS(A|T)?
97  }
98 
99  calculate_ndwi(l1rec, prod); // Produce NDWI product
100 }
float average_rhos_values(float rhos_values[], size_t length)
Get the average of rho_s values from a hyperspectral measurement to approximate a multi-band measurem...
read l1rec
#define PRODFAIL
Definition: l2_flags.h:41
#define VI_MAXVAL
int bindex_get(int32_t wave)
Definition: windex.c:45
bool invalid_pixel(double pixel_elevation, double pixel_mask, double rhos_values[], int len_rhos_values)
Check pixel attributes for validity.
#define LAND_MASK
bool instrument_is_hyperspectral(int32_t num_bands)
#define UNDEFINED
void get_ndwi(l1str *l1rec, float prod[])
Main entry point for getting NDWI.
Definition: get_ndwi.c:79
const int32_t nir_min
#define BAD_INT
Definition: genutils.h:23
const int32_t nir_max
float clamp(float pixel_value, int minimum, int maximum)
Clamp the value of a pixel between minval and maxval.
#define VI_MINVAL
void calculate_ndwi(l1str *l1rec, float ndwi[])
Definition: get_ndwi.c:30