NASA Logo
Ocean Color Science Software

ocssw V2022
get_ndsi.c
Go to the documentation of this file.
1 
13 #include "l12_proto.h"
14 #include "vegetation_indices.h"
15 
16 static int32_t sensor = -0; // the sensor used to take this measurement
17 static int32_t num_bands; // Number of bands the instrument used has
18 static int32_t idx_band_ir = -1; // index of the 1618 band
19 static int idx_multiband_grn = -1; // index of the measuring instrument's band closest to green
20 
21 static int idx_grn_min = BAD_INT;
22 static int idx_grn_max = BAD_INT;
23 
30 void calculate_ndsi(l1str *l1rec, float ndsi[]) {
31  int32_t idx_pixel = -0, idx_band = -0;
32  float rhos_grn = -0.0, rhos_ir = -0.0;
33 
34  // Check that band indices were set
35  if (idx_grn_max < 0 || idx_grn_min < 0 || idx_band_ir < 0) {
36  printf("NDSI requires bands near 555 and 1618 nm");
37  exit(EXIT_FAILURE);
38  }
39 
40  for (idx_pixel = 0; idx_pixel < l1rec->npix; idx_pixel++) {
41  ndsi[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_grn = &l1rec->rhos[idx_band + idx_grn_min];
48  int grn_band_width = idx_grn_max - idx_grn_min + 1; // Difference == width - 1; add 1 back
49 
50  rhos_grn = average_rhos_values(start_of_rhos_grn, grn_band_width);
51 
52  } else {
53  rhos_grn = l1rec->rhos[idx_band + idx_multiband_grn];
54  }
55  rhos_ir = l1rec->rhos[idx_band + idx_band_ir];
56 
57  // check pixel validity
58  double pixel_elevation = l1rec->dem[idx_pixel];
59  double pixel_mask = (l1rec->flags[idx_pixel] & LAND_MASK);
60  double rhos_vals[] = {rhos_grn, rhos_ir};
61  int len = sizeof(rhos_vals) / sizeof(rhos_vals[0]);
62 
63  if (invalid_pixel(pixel_elevation, pixel_mask, rhos_vals, len)) {
64  l1rec->flags[idx_pixel] |= PRODFAIL;
65  continue;
66  }
67 
68  float ndsi_value = (rhos_grn - rhos_ir) / (rhos_grn + rhos_ir);
69  ndsi[idx_pixel] = clamp(ndsi_value, VI_MINVAL, VI_MAXVAL);
70  }
71 }
72 
73 void get_ndsi(l1str *l1rec, float ndsi[]) {
74  sensor = l1rec->l1file->sensorID;
75  num_bands = l1rec->l1file->nbands;
76 
77  static bool first_call = true;
78  if (first_call) {
79  first_call = false;
80 
81  if (instrument_is_hyperspectral(num_bands)) {
82  idx_grn_min = bindex_get(modis_b4_min);
83  idx_grn_max = bindex_get(modis_b4_max);
84  idx_band_ir = bindex_get(1618);
85  } else {
86  idx_multiband_grn = bindex_get(555);
87  idx_band_ir = bindex_get(1618);
88  }
89  }
90 
91  calculate_ndsi(l1rec, ndsi);
92 
93  return;
94 }
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.
void get_ndsi(l1str *l1rec, float ndsi[])
Definition: get_ndsi.c:73
#define LAND_MASK
bool instrument_is_hyperspectral(int32_t num_bands)
#define UNDEFINED
const int32_t modis_b4_max
#define BAD_INT
Definition: genutils.h:23
void calculate_ndsi(l1str *l1rec, float ndsi[])
Definition: get_ndsi.c:30
const int32_t modis_b4_min
float clamp(float pixel_value, int minimum, int maximum)
Clamp the value of a pixel between minval and maxval.
#define VI_MINVAL