NASA Logo
Ocean Color Science Software

ocssw V2022
get_cci.c
Go to the documentation of this file.
1 
14 #include "l12_proto.h"
15 #include "vegetation_indices.h"
16 
17 static int32_t num_bands; // Number of bands the instrument used has
18 static uint idx_modis_band_11 = -1;
19 static uint idx_modis_band_1 = -1;
20 static int idx_red_min = BAD_INT; // A band index for red
21 static int idx_red_max = BAD_INT; // A band index for red
22 static int idx_grn_min = BAD_INT; // A band index for green
23 static int idx_grn_max = BAD_INT; // A band index for green
24 
35 void calculate_cci(l1str *l1rec, float cci[]) {
36  double rhos_grn = -0.0;
37  double rhos_red = 0.0;
38  int32_t num_pixels = l1rec->npix;
39 
40  for (int32_t idx_pixel = 0; idx_pixel < num_pixels; idx_pixel++) {
41  cci[idx_pixel] = UNDEFINED;
42  int32_t idx_band = l1rec->l1file->nbands * idx_pixel;
43 
44  if (instrument_is_hyperspectral(num_bands)) { // In future, check for hyperspectral ins., not just OCI
45  uint grn_width = idx_grn_max - idx_grn_min + 1; // Difference == width - 1; add 1 back
46  uint red_width = idx_red_max - idx_red_min + 1; // Difference == width - 1; add 1 back
47  float *start_of_rhos_grn = &l1rec->rhos[idx_band + idx_grn_min];
48  float *start_of_rhos_red = &l1rec->rhos[idx_band + idx_red_min];
49 
50  rhos_grn = average_rhos_values(start_of_rhos_grn, grn_width);
51  rhos_red = average_rhos_values(start_of_rhos_red, red_width);
52  } else { // Multi band instrument
53  rhos_grn = l1rec->rhos[idx_band + idx_modis_band_11];
54  rhos_red = l1rec->rhos[idx_band + idx_modis_band_1];
55  }
56 
57  double rhos_values[] = {rhos_grn, rhos_red};
58  double pixel_elevation = l1rec->dem[idx_pixel];
59  double landmask = l1rec->flags[idx_pixel] & LAND_MASK;
60  size_t len_rhos_vals = sizeof(rhos_values) / sizeof(rhos_values[0]);
61  if (invalid_pixel(pixel_elevation, landmask, rhos_values, len_rhos_vals)) {
62  l1rec->flags[idx_pixel] |= PRODFAIL;
63  continue;
64  }
65 
66  double cci_value = (rhos_grn - rhos_red) / (rhos_grn + rhos_red);
67  cci[idx_pixel] = clamp(cci_value, VI_MINVAL, VI_MAXVAL);
68  }
69 
70  return;
71 }
72 
73 void get_cci(l1str *l1rec, float cci[]) {
74  num_bands = l1rec->l1file->nbands;
75 
76  static bool first_call = true;
77  if (first_call) {
78  first_call = false;
79 
80  if (instrument_is_hyperspectral(num_bands)) {
81  idx_grn_min = bindex_get(modis_b11_min);
82  idx_grn_max = bindex_get(modis_b11_max);
83  idx_red_min = bindex_get(red_min);
84  idx_red_max = bindex_get(red_max);
85 
86  if (idx_grn_min == DEFAULT_BAND_INDEX || idx_grn_max == DEFAULT_BAND_INDEX ||
87  idx_red_min == DEFAULT_BAND_INDEX || idx_red_max == DEFAULT_BAND_INDEX) {
88  printf("CCI requires bands near 555 and 645 nm\n");
89  exit(EXIT_FAILURE);
90  }
91  } else {
92  idx_modis_band_11 = bindex_get(555);
93  idx_modis_band_1 = bindex_get(645);
94 
95  if (idx_modis_band_11 < 0 || idx_modis_band_1 < 0) {
96  printf("CCI requires bands near 555 and 645 nm\n");
97  exit(EXIT_FAILURE);
98  }
99  }
100  }
101 
102  calculate_cci(l1rec, cci);
103 
104  return;
105 }
const int32_t modis_b11_min
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
void get_cci(l1str *l1rec, float cci[])
Definition: get_cci.c:73
#define PRODFAIL
Definition: l2_flags.h:41
const int32_t modis_b11_max
#define VI_MAXVAL
void calculate_cci(l1str *l1rec, float cci[])
Definition: get_cci.c:35
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
#define DEFAULT_BAND_INDEX
bool instrument_is_hyperspectral(int32_t num_bands)
const int32_t red_min
#define UNDEFINED
const int32_t red_max
#define BAD_INT
Definition: genutils.h:23
float clamp(float pixel_value, int minimum, int maximum)
Clamp the value of a pixel between minval and maxval.
#define VI_MINVAL