OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
viirs_noise.c
Go to the documentation of this file.
1 #include "viirs_sim_sdr.h"
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <ctype.h>
6 #include <gsl/gsl_rng.h>
7 #include <gsl/gsl_randist.h>
8 
9 int viirs_noise(ctl_struc *ctl, in_rec_struc *in_rec, int noise_stop)
10 /*-----------------------------------------------------------------------------
11  Program: viirs_noise.c
12 
13  Description: Add the VIIRS noise artifact to the simulated
14  radiance field
15 
16  Arguments:
17  Type Name I/O Description
18  ---- ---- --- -----------
19  ctl_struc * ctl I input controls
20  in_rec_struc * in_rec I/O controls for input record reading
21  int noise_stop I if 1, shut down the noise generation
22  do at program end
23 
24  Modification history:
25 
26  W. Robinson, SAIC 25 May 2011 Original development
27 
28 ----------------------------------------------------------------------------*/ {
29  int npix, nlin, ibnd, ilin, ipix;
30  double rad, noise, noise_sd, maxr, rad_lim;
31  const gsl_rng_type * T;
32  static gsl_rng * r;
33  static int noise_init = 0;
34  static float a0[N_VNIR_BND], a1[N_VNIR_BND], a2[N_VNIR_BND];
35  static float maxrad[N_VNIR_BND];
36 
37  /*
38  * close down if that switch is set
39  */
40  if (noise_stop == 1) {
41  gsl_rng_free(r);
42  } else {
43  /*
44  * do initialization
45  */
46  if (noise_init == 0) {
47  noise_init = 1;
48 
49  printf("%s, %d: Entering routine viirs_noise\n", __FILE__, __LINE__);
50  printf("noise_coef = %s\n", ctl->noise_coef);
51  /*
52  * read in the coefficients for the SNR for the bands
53  */
54  if (viirs_noise_coef_rd(ctl->noise_coef, a0, a1, a2, maxrad) != 0)
55  return 1;
56  /*
57  * set up for the random numbers needed
58  */
59  gsl_rng_env_setup();
60  T = gsl_rng_default;
61  r = gsl_rng_alloc(T);
62  }
63  /*
64  * for each pixel (in a line in a band) derive and apply the noise
65  * except for bad values
66  */
67  npix = in_rec->npix;
68  nlin = in_rec->ndet_scan;
69  for (ibnd = 0; ibnd < N_VNIR_BND; ibnd++) {
70  maxr = *(maxrad + ibnd);
71  for (ilin = 0; ilin < nlin; ilin++) {
72  for (ipix = 0; ipix < npix; ipix++) {
73  if (*(in_rec->bnd_q[ibnd] + ilin * npix + ipix) == 0) {
74  rad = *(in_rec->bnd_lt[ibnd] + ilin * npix + ipix);
75  /*
76  * limit the radiance used in the noise computation
77  * to the maxrad for that band
78  */
79  rad_lim = (rad > maxr) ? maxr : rad;
80 
81  noise_sd = rad_lim / (*(a0 + ibnd) + *(a1 + ibnd) * rad_lim +
82  *(a2 + ibnd) * rad_lim * rad_lim);
83  noise = gsl_ran_gaussian(r, noise_sd);
84  *(in_rec->bnd_lt[ibnd] + ilin * npix + ipix) = rad + noise;
85  }
86  } /* end pix loop */
87  } /* end line loop */
88  } /* end band loop */
89  }
90  /*
91  * and end
92  */
93  return 0;
94 }
95 
96 int viirs_noise_coef_rd(char *file, float *a0, float *a1, float *a2,
97  float *maxrad)
98 /*-----------------------------------------------------------------------------
99  routine: viirs_noise_coef_rd
100 
101  Description: read quadratic coefficients describing the SNR as a
102  f(radiance)
103 
104  Arguments:
105  Type Name I/O Description
106  ---- ---- --- -----------
107  char * file I text file containing the SNR coefficients
108  float * a0 O constant term of SNR for the VIS/NIR bands
109  float * a1 O linear term of SNR
110  float * a2 O quadratic term of SNR
111  float * maxrad O max radiance to use in SNR computation
112 
113  SNR = a0[band] + a1[band] * rad + a2[band] rad^2
114  with rad = TOA radiance || maxrad, whichever is smallest
115 
116  Modification history:
117 
118  W. Robinson, SAIC 25 May 2011 Original development
119 
120 ----------------------------------------------------------------------------*/ {
121  FILE *fp;
122  int items_set[N_VNIR_BND * 4], ipar, iord, ibnd, ibnd_no, val_set;
123  char line[80], name[80], value[80], parm[80];
124  char *p, *p1, *p2;
125  float fval;
126 
127  for (ipar = 0; ipar < N_VNIR_BND * 4; ipar++)
128  items_set[ipar] = 0;
129  /*
130  * open the file
131  */
132  if ((fp = fopen(file, "r")) == NULL) {
133  printf("%s, line %d: unable to open noise coefficient file: %s\n",
134  __FILE__, __LINE__, file);
135  return 1;
136  }
137  /*
138  * Loop through parameters to define
139  */
140  while (fgets(line, 80, fp)) {
141  memset(name, '\0', sizeof ( name));
142  memset(value, '\0', sizeof ( value));
143  /*
144  * Skip comment lines, empty lines, and lines without a
145  * name = value pair.
146  */
147  if (line[0] == '#' || line[0] == '\n')
148  continue;
149  if (!(p = strchr(line, '=')))
150  continue;
151 
152  /*
153  * Parse parameter name string
154  */
155  p1 = line;
156  while (isspace(*p1))
157  p1++;
158  p2 = p - 1;
159  while (isspace(*p2))
160  p2--;
161  strncpy(name, p1, p2 - p1 + 1);
162 
163  /*
164  * Parse parameter value string
165  */
166  p1 = p + 1;
167  while (isspace(*p1))
168  p1++;
169  p2 = p1;
170  while (!isspace(*p2))
171  p2++;
172  strncpy(value, p1, p2 - p1);
173  printf("noise coeff values are: %s = %s\n", name, value);
174 
175  /*
176  * for each parameter, set the array value
177  */
178  val_set = 0;
179  for (ibnd = 0; ibnd < N_VNIR_BND; ibnd++) {
180  ibnd_no = ibnd + 1;
181  for (iord = 0; iord < 3; iord++) {
182  sprintf(parm, "a%1.1d[%1.1d]", iord, ibnd_no);
183 
184  if (strcmp(name, parm) == 0) {
185  ipar = ibnd * 4 + iord;
186  items_set[ipar] = 1;
187  val_set = 1;
188  fval = (float) atof(value);
189  if (iord == 0)
190  *(a0 + ibnd) = fval;
191  else if (iord == 1)
192  *(a1 + ibnd) = fval;
193  else if (iord == 2)
194  *(a2 + ibnd) = fval;
195  break;
196  }
197  }
198  if (val_set == 1) break;
199 
200  sprintf(parm, "maxrad[%1.1d]", ibnd_no);
201  if (strcmp(name, parm) == 0) {
202  ipar = ibnd * 4 + 3;
203  items_set[ipar] = 1;
204  fval = (float) atof(value);
205  *(maxrad + ibnd) = fval;
206  break;
207  }
208  }
209  }
210  /*
211  * make sure all values were read from the file
212  */
213  for (ipar = 0; ipar < N_VNIR_BND * 4; ipar++)
214  if (items_set[ipar] == 0) {
215  printf("%s, %d: An item in the file %s was not set\n",
216  __FILE__, __LINE__, file);
217  return 1;
218  }
219  fclose(fp);
220  return 0;
221 }
int32 value
Definition: Granule.c:1235
int r
Definition: decode_rs.h:73
#define NULL
Definition: decode_rs.h:63
int nlin
Definition: get_cmp.c:28
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed file
Definition: HISTORY.txt:413
int viirs_noise(ctl_struc *ctl, in_rec_struc *in_rec, int noise_stop)
Definition: viirs_noise.c:9
#define isspace(c)
int viirs_noise_coef_rd(char *file, float *a0, float *a1, float *a2, float *maxrad)
Definition: viirs_noise.c:96
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second and prod_ix set to PARAM_TYPE_INT name_prefix is compared with the beginning of the product name If name_suffix is not empty the it must match the end of the product name The characters right after the prefix are read as an integer and prod_ix is set to that number strncpy(l2prod->name_prefix, "myprod", UNITLEN)
#define N_VNIR_BND
Definition: viirs_sim_sdr.h:31
int npix
Definition: get_cmp.c:27
float p[MODELMAX]
Definition: atrem_corl1.h:131