OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
viirs_cal.c
Go to the documentation of this file.
1 #include "viirs_sim_sdr.h"
2 #include <math.h>
3 
4 int viirs_cal(ctl_struc *ctl, in_rec_struc *in_rec)
5 /*-----------------------------------------------------------------------------
6  Program: viirs_cal.c
7 
8  Description: convert dn values (either dark subtracted (dn) or
9  not (DN) based on the cal_dark_sub value) and gain indicator
10  into VIIRS radiances
11 
12  Returns type: int - 0 if good
13 
14  Arguments:
15  Type Name I/O Description
16  ---- ---- --- -----------
17  ctl_struc * ctl I input controls
18  in_rec_struc * in_rec I/O controls for input record reading
19 
20  Modification history:
21 
22  W. Robinson, SAIC 16 Sep 2010 Original development
23 
24 ----------------------------------------------------------------------------*/ {
25  static int first_time = 0, rvs_note = 0;
26  int ilin, idet, ipix, ibnd, igain, iham;
27  int npix, nbnd;
28  float c0, c1, c2, a0, a1, a2, dark, dn, lt, aoi, rvs_val;
29  float min_rvs[MAX_BND], max_rvs[MAX_BND];
30  static vir_gain_struc gain;
31  static vir_rvs_struc rvs;
32  /*
33  * set up the gain and rvs strucs from the source files
34  * for now, only do vis, NIR (7 bands)
35  */
36  iham = in_rec->ham_side;
37  nbnd = in_rec->nbnd;
38  if (first_time == 0) {
39  if (vset_cal_gain(ctl->count_cal_gain_file, &gain) != 0)
40  return 1;
41  /*
42  * check gain struct so it satisfys the needs
43  */
44  if (gain.nham != 2) {
45  printf("%s, %d: # of HAM sides in gain struct (%d) != 2\n", __FILE__,
46  __LINE__, gain.nham);
47  printf("\tgain file: %s\n", ctl->count_decal_gain_file);
48  return 1;
49  }
50  if (gain.ndet != NDET) {
51  printf(
52  "%s, %d: # of detectors in gain struct (%d) != the VIIRS # (%d)\n",
53  __FILE__, __LINE__, gain.ndet, NDET);
54  printf("\tgain file: %s\n", ctl->count_decal_gain_file);
55  return 1;
56  }
57  if (gain.ngain != 2) {
58  printf("%s, %d: # of gain states in gain struct (%d) != 2\n", __FILE__,
59  __LINE__, gain.nham);
60  printf("\tgain file: %s\n", ctl->count_decal_gain_file);
61  return 1;
62  }
63  if (gain.nbnd < N_VNIR_BND) {
64  printf("%s, %d: # of bands in gain struct (%d) not >= # needed # (%d)\n",
65  __FILE__, __LINE__, gain.nbnd, nbnd);
66  printf("\tgain file: %s\n", ctl->count_decal_gain_file);
67  return 1;
68  }
69 
70  if (vset_cal_rvs(ctl->count_decal_rvs_file, &rvs) != 0)
71  return 1;
72  /*
73  * check rvs struct so it satisfys the needs
74  */
75  if (rvs.nham != 2) {
76  printf("%s, %d: # of HAM sides in gain struct (%d) != 2\n", __FILE__,
77  __LINE__, rvs.nham);
78  printf("\trvs file: %s\n", ctl->count_decal_rvs_file);
79  return 1;
80  }
81  if (rvs.ndet != NDET) {
82  printf(
83  "%s, %d: # of detectors in gain struct (%d) != the VIIRS # (%d)\n",
84  __FILE__, __LINE__, rvs.ndet, NDET);
85  printf("\trvs file: %s\n", ctl->count_decal_rvs_file);
86  return 1;
87  }
88  if (rvs.nbnd < N_VNIR_BND) {
89  printf("%s, %d: # of bands in gain struct (%d) not >= # needed # (%d)\n",
90  __FILE__, __LINE__, rvs.nbnd, nbnd);
91  printf("\trvs file: %s\n", ctl->count_decal_rvs_file);
92  return 1;
93  }
94 
95  for (ibnd = 0; ibnd < N_VNIR_BND; ibnd++) {
96  min_rvs[ibnd] = 999.;
97  max_rvs[ibnd] = -999.;
98  }
99 
100  first_time = 1;
101  }
102  /*
103  * loop through the pixels, lines, and bands to get the lt
104  */
105  npix = in_rec->npix;
106  for (ipix = 0; ipix < npix; ipix++) {
107  /* get the aoi from the sample */
109 
110  for (ilin = 0; ilin < in_rec->ndet_scan; ilin++) {
111  /* get the detector from the line */
112  idet = ilin - in_rec->margin[0];
113  if (idet < 0) idet = 0;
114  if (idet >= NDET) idet = NDET - 1;
115 
116  for (ibnd = 0; ibnd < N_VNIR_BND; ibnd++) {
117  /*
118  * if the lt is not flagged, get it and de-cal
119  */
120  if (*(in_rec->bnd_q[ibnd] + ipix + npix * ilin) == 0) {
121  /*
122  * get the gain and dn from the input structure
123  */
124  igain = *(in_rec->gain_bit[ibnd] + ipix + npix * ilin);
125  dn = *(in_rec->dn[ibnd] + ipix + npix * ilin);
126  /*
127  * get the gain, rvs coeffs
128  */
129  c0 = *(gain.c0 + ibnd + gain.nbnd * (igain + gain.ngain *
130  (idet + gain.ndet * iham)));
131  c1 = *(gain.c1 + ibnd + gain.nbnd * (igain + gain.ngain *
132  (idet + gain.ndet * iham)));
133  c2 = *(gain.c2 + ibnd + gain.nbnd * (igain + gain.ngain *
134  (idet + gain.ndet * iham)));
135 
136  a0 = *(rvs.a0 + ibnd + rvs.nbnd * (idet + rvs.ndet * iham));
137  a1 = *(rvs.a1 + ibnd + rvs.nbnd * (idet + rvs.ndet * iham));
138  a2 = *(rvs.a2 + ibnd + rvs.nbnd * (idet + rvs.ndet * iham));
139 
140  rvs_val = a0 + a1 * aoi + a2 * aoi * aoi;
141  if ((rvs_val > 2.) || (rvs_val < .5)) {
142  printf("%s, %d: rvs val %f, odd at pix: %d, lin: %d, bnd: %d\n",
143  __FILE__, __LINE__, rvs_val, ipix, ilin, ibnd);
144  }
145  if (rvs_note == 0) {
146  /*
147  * record the min and max rvs for each band
148  */
149  if (rvs_val < min_rvs[ibnd])
150  min_rvs[ibnd] = rvs_val;
151  if (rvs_val > max_rvs[ibnd])
152  max_rvs[ibnd] = rvs_val;
153  }
154  /*
155  * remove dark count if required, apply the gain and rvs to calibrate
156  */
157  if (ctl->count_dark_opt == 1) {
158  dark = *(gain.dark + ibnd + gain.nbnd * (igain + gain.ngain *
159  (idet + gain.ndet * iham)));
160  dn = dn - dark;
161  }
162  lt = (c0 + c1 * dn + c2 * dn * dn) / rvs_val;
163  /*
164  * place the radiance back in the structure
165  */
166  *(in_rec->bnd_lt[ibnd] + ipix + npix * ilin) = lt;
167  }
168  /* else bad lt val, leave lt alone */
169  }
170  }
171  }
172  /*
173  * report the rvs min, max
174  */
175  if (rvs_note == 0) {
176  rvs_note = 1;
177  printf("\n\n%s, %d: info:\n", __FILE__, __LINE__);
178  printf("\nCalibration RVS min and max / band:\n");
179  printf("(file: %s\n", ctl->count_cal_rvs_file);
180  printf("\nM band Min RVS Max RVS\n");
181  for (ibnd = 0; ibnd < N_VNIR_BND; ibnd++)
182  printf(" %3d %9.6f %9.6f\n", ibnd + 1,
183  min_rvs[ibnd], max_rvs[ibnd]);
184  printf("----------------------------------------\n\n");
185  }
186  /*
187  * end loops and done
188  */
189  return 0;
190 }
int16 * gain
Definition: l1_czcs_hdf.c:33
#define MAX_BND
Definition: viirs_sim_sdr.h:34
int nbnd
Definition: get_cmp.c:29
int vset_cal_gain(char *, vir_gain_struc *)
Definition: vset_cal.c:16
int vset_cal_rvs(char *, vir_rvs_struc *)
Definition: vset_cal.c:280
int viirs_cal(ctl_struc *ctl, in_rec_struc *in_rec)
Definition: viirs_cal.c:4
#define VIR_SCAN_AOI
Definition: viirs_sim_sdr.h:54
int vir_xf_scan(float, int, int, float *)
Definition: vir_xf_scan.c:3
#define VIR_SCAN_UASMP
Definition: viirs_sim_sdr.h:52
#define NDET
Definition: polcor.c:13
#define N_VNIR_BND
Definition: viirs_sim_sdr.h:31
int npix
Definition: get_cmp.c:27