OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
wr_bnd_scan.c
Go to the documentation of this file.
1 #include "viirs_sim_sdr.h"
2 #include "l12_parms.h"
3 #include <stdlib.h>
4 
5 int wr_bnd_scan(int iscn, out_rec_struc *out_rec)
6 /*-----------------------------------------------------------------------------
7  Program: wr_bnd_scan
8 
9  Description: write a scan of band data to the VIIRS SDRs
10 
11  Arguments:
12  Type Name I/O Description
13  ---- ---- --- -----------
14  int iscn I scan to write
15  out_rec_struc * out_rec I/O output record controls
16 
17  Modification history:
18 
19  W. Robinson, SAIC 15 Dec 2008 Original development
20  W. Robinson, SAIC 15 Mar 2010 re-orient for scan based writing
21  W. Robinson, SAIC 19 Nov 2010 collect, report the rad, refl/bbt
22  min, max, note q1 is primary quantity carried in out_rec->lt,
23  while q2 is derived from it, currently q1 = radiance for
24  reflective and bbt for emissive bands, q2 is reflectance
25  for reflective and radiance for emissive
26 
27 ----------------------------------------------------------------------------*/ {
28  static unsigned short *bnd_short;
29  static float *bnd_float;
30  float tmpval, tmpval2, scale, offset, mu0, lam_um;
31  static int entry = 0;
32  int ilin, nlin, loc, ipix, ibnd, start[2], count[2];
33  h5io_str lcl_id;
34  static float min_q1[MAX_BND], max_q1[MAX_BND],
35  min_q2[MAX_BND], max_q2[MAX_BND];
36  static int min_sq1[MAX_BND], max_sq1[MAX_BND],
37  min_sq2[MAX_BND], max_sq2[MAX_BND];
38  /*
39  * initialize the record of min, max values
40  */
41  if (iscn == 0) {
42  for (ibnd = 0; ibnd < out_rec->nbnd; ibnd++) {
43  min_q1[ibnd] = 999.;
44  max_q1[ibnd] = -999.;
45  min_q2[ibnd] = 999.;
46  max_q2[ibnd] = -999.;
47  min_sq1[ibnd] = 99999;
48  max_sq1[ibnd] = -99999;
49  min_sq2[ibnd] = 99999;
50  max_sq2[ibnd] = -99999;
51  }
52  }
53  /*
54  * prepare the output short and float buffers for final output scaled
55  * and unscaled data
56  */
57  nlin = out_rec->ndet_scan;
58  if (entry == 0) {
59  entry = 1;
60  if ((bnd_short = (unsigned short *)
61  malloc(nlin * out_rec->npix * sizeof ( unsigned short))) == NULL) {
62  printf("%s, %d: Unable to allocate bnd_short storage\n",
63  __FILE__, __LINE__);
64  return 1;
65  }
66  if ((bnd_float = (float *)
67  malloc(nlin * out_rec->npix * sizeof ( float))) == NULL) {
68  printf("%s, %d: Unable to allocate bnd_float storage\n",
69  __FILE__, __LINE__);
70  return 1;
71  }
72  }
73 
74  ilin = out_rec->ndet_scan * iscn;
75  start[0] = ilin;
76  start[1] = 0;
77  count[0] = out_rec->ndet_scan;
78  count[1] = out_rec->npix;
79  /*
80  * output all the band data
81  */
82  for (ibnd = 0; ibnd < out_rec->nbnd; ibnd++) {
83  lam_um = (float) out_rec->lam_band[ibnd] / 1000.;
84  /*
85  * either convert the primary radiance quantity: Lt / BBT to unsigned
86  * short and output or output directly
87  */
88  lcl_id = out_rec->bnd_dat_id[1][ibnd]; /* set for BBT out */
89  scale = out_rec->refl_scale[ibnd];
90  offset = out_rec->refl_offset[ibnd];
91 
92  if (out_rec->meas_typ[ibnd] == 0) {
93  lcl_id = out_rec->bnd_dat_id[0][ibnd]; /* or set for rad out */
94  scale = out_rec->scale[ibnd];
95  offset = out_rec->offset[ibnd];
96  }
97  if (out_rec->out_bnd_typ[ibnd] == 0) /* for scaled output of rad / BBT */ {
98  for (ilin = 0; ilin < nlin; ilin++) {
99  for (ipix = 0; ipix < out_rec->npix; ipix++) {
100  loc = ilin * out_rec->npix + ipix;
101  if (*(out_rec->bnd_q[ibnd] + loc) == 1)
102  *(bnd_short + loc) = ONBOARD_PT_UINT16_FILL;
103  else if (*(out_rec->bnd_q[ibnd] + loc) == 2)
104  *(bnd_short + loc) = MISS_UINT16_FILL;
105  else {
106  tmpval2 = *(out_rec->bnd_lt[ibnd] + loc);
107  tmpval = (tmpval2 - offset) / scale;
108  if ((tmpval < 0.) || (tmpval >= SOUB_UINT16_FILL)) {
109  *(bnd_short + loc) = SOUB_UINT16_FILL;
110  } else {
111  *(bnd_short + loc) = (unsigned short) tmpval;
112  if (tmpval < min_sq1[ibnd]) min_sq1[ibnd] = (int) tmpval;
113  if (tmpval > max_sq1[ibnd]) max_sq1[ibnd] = (int) tmpval;
114 
115  if (tmpval2 < min_q1[ibnd]) min_q1[ibnd] = tmpval2;
116  if (tmpval2 > max_q1[ibnd]) max_q1[ibnd] = tmpval2;
117  }
118  }
119  }
120  }
121  if (h5io_wr_ds_slice(&lcl_id, start, count, bnd_short) != 0) {
122  printf(
123  "%s, %d: radiance (short) scan write failure, scan %d, band %d\n",
124  __FILE__, __LINE__, iscn, ibnd);
125  }
126  } else
127  /*
128  * for unscaled output of rad / BBT
129  */ {
130  for (ilin = 0, loc = 0; ilin < nlin; ilin++)
131  for (ipix = 0; ipix < out_rec->npix; ipix++, loc++)
132  if (*(out_rec->bnd_q[ibnd] + loc) == 1)
133  *(bnd_float + loc) = ONBOARD_PT_FLOAT32_FILL;
134  else if (*(out_rec->bnd_q[ibnd] + loc) == 2)
135  *(bnd_float + loc) = MISS_FLOAT32_FILL;
136  else {
137  tmpval = *(out_rec->bnd_lt[ibnd] + loc);
138  *(bnd_float + loc) = tmpval;
139  if (tmpval < min_q1[ibnd]) min_q1[ibnd] = tmpval;
140  if (tmpval > max_q1[ibnd]) max_q1[ibnd] = tmpval;
141  }
142 
143  if (h5io_wr_ds_slice(&lcl_id, start, count, bnd_float) != 0) {
144  printf(
145  "%s, %d: radiance (float) scan write failure, scan %d, band %d\n",
146  __FILE__, __LINE__, iscn, ibnd);
147  }
148  }
149  /*
150  * end primary quantity output, start on the secondary
151  *
152  * convert the radiance to reflectance or bbt to radiance
153  */
154  if (out_rec->meas_typ[ibnd] == 0) {
155  /*
156  * for reflective bands, convert radiance to reflectance, scale and output
157  * Note assumption: all reflectances are scaled
158  */
159  lcl_id = out_rec->bnd_dat_id[1][ibnd];
160  for (ilin = 0; ilin < nlin; ilin++) {
161  for (ipix = 0; ipix < out_rec->npix; ipix++) {
162  loc = ilin * out_rec->npix + ipix;
163  if (*(out_rec->bnd_q[ibnd] + loc) == 1)
164  *(bnd_short + loc) = ONBOARD_PT_UINT16_FILL;
165  else if (*(out_rec->bnd_q[ibnd] + loc) == 2)
166  *(bnd_short + loc) = MISS_UINT16_FILL;
167  else {
168  mu0 = cos(*(out_rec->solz + loc) / RADEG);
169  tmpval2 = *(out_rec->bnd_lt[ibnd] + loc) * PI /
170  (out_rec->f0[ibnd] * mu0);
171  tmpval = (tmpval2 - out_rec->refl_offset[ibnd])
172  / out_rec->refl_scale[ibnd];
173  if ((tmpval < 0.) || (tmpval >= SOUB_UINT16_FILL))
174  *(bnd_short + loc) = SOUB_UINT16_FILL;
175  else {
176  *(bnd_short + loc) = (unsigned short) tmpval;
177  if (tmpval < min_sq2[ibnd]) min_sq2[ibnd] = (int) tmpval;
178  if (tmpval > max_sq2[ibnd]) max_sq2[ibnd] = (int) tmpval;
179 
180  if (tmpval2 < min_q2[ibnd]) min_q2[ibnd] = tmpval2;
181  if (tmpval2 > max_q2[ibnd]) max_q2[ibnd] = tmpval2;
182  }
183  }
184  }
185  }
186  if (h5io_wr_ds_slice(&lcl_id, start, count, bnd_short) != 0) {
187  printf("%s, %d: reflectance scan write failure, scan %d, band %d\n",
188  __FILE__, __LINE__, iscn, ibnd);
189  }
190  } else {
191  /*
192  * for emissive bands, convert bbt to radiance and output
193  * Note assumption: if primary quantity is scaled, then this
194  * will also be scaled
195  */
196  lcl_id = out_rec->bnd_dat_id[0][ibnd];
197  for (ilin = 0; ilin < nlin; ilin++) {
198  for (ipix = 0; ipix < out_rec->npix; ipix++) {
199  loc = ilin * out_rec->npix + ipix;
200  /*
201  * make the radiance from brightness temp
202  */
203  if (*(out_rec->bnd_q[ibnd] + loc) == 1)
204  *(bnd_float + loc) = ONBOARD_PT_FLOAT32_FILL;
205  else if (*(out_rec->bnd_q[ibnd] + loc) == 2)
206  *(bnd_float + loc) = MISS_FLOAT32_FILL;
207  else {
208  tmpval = bbt_2_rad(*(out_rec->bnd_lt[ibnd] + loc), lam_um);
209  *(bnd_float + loc) = tmpval;
210  if (tmpval < min_q2[ibnd]) min_q2[ibnd] = tmpval;
211  if (tmpval > max_q2[ibnd]) max_q2[ibnd] = tmpval;
212  }
213  /*
214  * convert if scaled output
215  */
216  if (out_rec->out_bnd_typ[ibnd] == 0) {
217  if (*(out_rec->bnd_q[ibnd] + loc) == 1)
218  *(bnd_short + loc) = ONBOARD_PT_UINT16_FILL;
219  else if (*(out_rec->bnd_q[ibnd] + loc) == 2)
220  *(bnd_short + loc) = MISS_UINT16_FILL;
221  else {
222  tmpval = (*(bnd_float + loc) - out_rec->offset[ibnd])
223  / out_rec->scale[ibnd];
224  *(bnd_short + loc) = (unsigned short) tmpval;
225  if (tmpval < min_sq2[ibnd]) min_sq2[ibnd] = (int) tmpval;
226  if (tmpval > max_sq2[ibnd]) max_sq2[ibnd] = (int) tmpval;
227  }
228  }
229  }
230  }
231  /*
232  * output the radiance
233  */
234  if (out_rec->out_bnd_typ[ibnd] == 0) {
235  if (h5io_wr_ds_slice(&lcl_id, start, count, bnd_short) != 0) {
236  printf(
237  "%s, %d: emissive radiance scan write failure, scan %d, band %d\n",
238  __FILE__, __LINE__, iscn, ibnd);
239  }
240  } else {
241  if (h5io_wr_ds_slice(&lcl_id, start, count, bnd_float) != 0) {
242  printf(
243  "%s, %d: emissive radiance scan write failure, scan %d, band %d\n",
244  __FILE__, __LINE__, iscn, ibnd);
245  }
246  }
247  }
248  /*
249  * write the scan of pixel level quality: QF1_VIIRSMBNDSDR
250  */
251  if (h5io_wr_ds_slice(&(out_rec->qual1_m_id[ibnd]), start, count,
252  out_rec->qual1_m[ibnd]) != 0) {
253  printf(
254  "%s, %d: scan write to QF1_VIIRSMBNDSDR failed. scan %d, band %d\n",
255  __FILE__, __LINE__, iscn, ibnd);
256  }
257  }
258  /*
259  * remove any allocations for the transfer and report the min, max encountered
260  */
261  if (iscn == out_rec->nscan - 1) {
262  free(bnd_short);
263  free(bnd_float);
264 
265  printf("%s, %d: info - Data minimum, maximum\n\n", __FILE__, __LINE__);
266  printf(" Radiance (W / m^2 sr um) BBT (deg K for 12-16)\n");
267  printf(" unscaled scaled\n");
268  printf("Band Minimum Maximum Minimum Maximum\n");
269  for (ibnd = 0; ibnd < out_rec->nbnd; ibnd++)
270  printf("%4d %8.4f %8.4f %6d %6d\n", ibnd + 1, min_q1[ibnd],
271  max_q1[ibnd], min_sq1[ibnd], max_sq1[ibnd]);
272 
273  printf(
274  "\n Reflectance (no units) Rad (W / m^2 sr um for 12-16)\n\n");
275  printf(" unscaled scaled\n");
276  printf("Band Minimum Maximum Minimum Maximum\n");
277  for (ibnd = 0; ibnd < out_rec->nbnd; ibnd++)
278  printf("%4d %8.6f %8.6f %6d %6d\n", ibnd + 1, min_q2[ibnd],
279  max_q2[ibnd], min_sq2[ibnd], max_sq2[ibnd]);
280  }
281  return 0;
282 }
int h5io_wr_ds_slice(h5io_str *ds_id, int *start, int *count, void *data)
Definition: h5io.c:1175
const unsigned short MISS_UINT16_FILL
Definition: RsViirs.h:46
#define NULL
Definition: decode_rs.h:63
const float ONBOARD_PT_FLOAT32_FILL
Definition: RsViirs.h:55
#define MAX_BND
Definition: viirs_sim_sdr.h:34
float bbt_2_rad(float bbt, float lam)
Definition: bbt_2_rad.c:9
const unsigned short SOUB_UINT16_FILL
Definition: RsViirs.h:51
const unsigned short ONBOARD_PT_UINT16_FILL
Definition: RsViirs.h:47
int nlin
Definition: get_cmp.c:28
character(len=1000) if
Definition: names.f90:13
#define PI
Definition: l3_get_org.c:6
const float MISS_FLOAT32_FILL
Definition: VcstCmnConsts.h:85
#define RADEG
Definition: czcs_ctl_pt.c:5
data_t loc[NROOTS]
Definition: decode_rs.h:78
float mu0
l2prod offset
int wr_bnd_scan(int iscn, out_rec_struc *out_rec)
Definition: wr_bnd_scan.c:5
int count
Definition: decode_rs.h:79