NASA Logo
Ocean Color Science Software

ocssw V2022
get_ndii.c
Go to the documentation of this file.
1 
11 #include "l12_proto.h"
12 #include "vegetation_indices.h"
13 
14 static int32_t idx_band_ir = -1; // index of the 1618 band
15 // index indicating location of the rhos values of NIR in a multiband instrument
16 static int idx_multiband_nir;
17 
18 static int idx_nir_min = BAD_INT; // A band index for NIR
19 static int idx_nir_max = BAD_INT; // A band index for NIR
20 
21 static int32_t num_bands; // Number of bands the instrument used has
22 
32 void calculate_ndii(l1str *l1rec, float ndii[]) {
33  int32_t idx_pixel = -0, idx_band = -0;
34  float rhos_nir = -0.0, rhos_ir = -0.0;
35 
36  // Check that band indices were set
37  if (idx_nir_max < 0 || idx_nir_min < 0 || idx_band_ir < 0) {
38  printf("NDII requires NIR bands between 670 and 875, and at 1618 nm");
39  exit(EXIT_FAILURE);
40  }
41 
42  for (idx_pixel = 0; idx_pixel < l1rec->npix; idx_pixel++) {
43  ndii[idx_pixel] = UNDEFINED;
44  idx_band = l1rec->l1file->nbands * idx_pixel;
45 
46  if (instrument_is_hyperspectral(num_bands)) { // Hyperspectral instrument
47 
48  // get average of rhos of nir
49  float *start_of_rhos_nir = &l1rec->rhos[idx_band + idx_nir_min];
50  int nir_band_width = idx_nir_max - idx_nir_min + 1;
51 
52  rhos_nir = average_rhos_values(start_of_rhos_nir, nir_band_width);
53  rhos_ir = l1rec->rhos[idx_band + idx_band_ir];
54 
55  } else {
56  rhos_nir = l1rec->rhos[idx_band + idx_multiband_nir];
57  rhos_ir = l1rec->rhos[idx_band + idx_band_ir];
58  }
59 
60  // check pixel validity
61  double pixel_elevation = l1rec->dem[idx_pixel];
62  double pixel_mask = (l1rec->flags[idx_pixel] & LAND_MASK);
63  double rhos_vals[] = {rhos_nir, rhos_ir};
64  int len = sizeof(rhos_vals) / sizeof(rhos_vals[0]);
65 
66  if (invalid_pixel(pixel_elevation, pixel_mask, rhos_vals, len)) {
67  l1rec->flags[idx_pixel] |= PRODFAIL;
68  continue;
69  }
70 
71  float ndii_value = (rhos_nir - rhos_ir) / (rhos_nir + rhos_ir);
72  ndii[idx_pixel] = clamp(ndii_value, VI_MINVAL, VI_MAXVAL);
73  }
74 }
75 
81 void get_ndii(l1str *l1rec, float prod[]) {
82  num_bands = l1rec->l1file->nbands;
83 
84  static bool first_call = true;
85  if (first_call) {
86  first_call = false;
87 
88  if (instrument_is_hyperspectral(num_bands)) { // TODO: Get rid of magic numbers
89  idx_nir_min = bindex_get(nir_min);
90  idx_nir_max = bindex_get(nir_max);
91  idx_band_ir = bindex_get(1618);
92  } else {
93  idx_multiband_nir = bindex_get(859);
94  idx_band_ir = bindex_get(1618);
95  }
96 
97  // Should I check for MODIS(A|T)?
98  }
99 
100  calculate_ndii(l1rec, prod); // Produce ndii product
101 }
void calculate_ndii(l1str *l1rec, float ndii[])
Definition: get_ndii.c:32
void get_ndii(l1str *l1rec, float prod[])
Main entry point for getting ndii.
Definition: get_ndii.c:81
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
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