OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
get_cal_swf.c
Go to the documentation of this file.
1 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 
3  Function: get_cal_swf
4 
5  Reads and applies calibration table
6 
7  Return:
8  calibrated L1B radiances
9 
10  Sean Bailey, Futuretech Corporation, 2 Jun 2008
11 
12  Modification history:
13  Gene Eplee, SAIC, 17 June 2010 Changed fitting function type
14  descriptor from sds attribute to
15  sds fitting parameter variable
16 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
17 
18 #include <stdlib.h>
19 #include "hdf4utils.h"
20 #include <timeutils.h>
21 #include "call1a_proto.h"
22 #include "genutils.h"
23 #include "getcal_proto.h"
24 
25 #include <hdf.h>
26 #include <mfhdf.h>
27 
28 
29 float ***alloc3d_float(int m, int n, int o) {
30  int i, j;
31  float ***p;
32  p = malloc(m * sizeof (float *));
33 
34  for (i = 0; i < m; i++) {
35  p[ i ] = malloc(n * sizeof (float **));
36  for (j = 0; j < n; j++) {
37  p[ i ][ j ] = malloc(o * sizeof (float ***));
38  }
39  }
40 
41  return (p);
42 }
43 
44 float ****alloc4d_float(int l, int m, int n, int o) {
45  int i, j, k;
46  float ****p;
47  p = malloc(l * sizeof (float *));
48 
49  for (i = 0; i < l; i++) {
50  p[ i ] = malloc(m * sizeof (float **));
51  for (j = 0; j < m; j++) {
52  p[ i ][ j ] = malloc(n * sizeof (float ***));
53  for (k = 0; k < n; k++) {
54  p[ i ][ j ][ k ] = malloc(o * sizeof (float ****));
55 
56  }
57 
58  }
59  }
60 
61  return (p);
62 }
63 
64 int32_t ***alloc3d_long(int m, int n, int o) {
65  int i, j;
66  int32_t ***p;
67  p = malloc(m * sizeof (int32_t *));
68 
69  for (i = 0; i < m; i++) {
70  p[ i ] = malloc(n * sizeof (int32_t **));
71  for (j = 0; j < n; j++) {
72  p[ i ][ j ] = malloc(o * sizeof (int32_t ***));
73  }
74  }
75 
76  return (p);
77 }
78 
79 
80 #define NBAND 8
81 #define NTEMP 256
82 // #define NCOEF 5
83 #define NCOEF 6
84 #define NDET 4
85 #define NGAIN 4
86 #define NTDI 256
87 #define NKNEE 5
88 #define K1 0
89 #define K3 1
90 #define K4 2
91 #define MSIDE 3
92 #define DARK 5
93 #define GR 4
94 #define NK 4
95 
96 static short ftype[NK];
97 
98 static short gain3corr;
99 static float ***radcor;
100 static int32_t *k1_epoch;
101 // static int32_t *k1_ftype;
102 static int num_k1_epoch;
103 
104 static float ***g3corr;
105 static int32_t *gr_epoch;
106 // static int32_t *gr_ftype;
107 static int num_gr_epoch;
108 
109 static float ***cnts2rad;
110 static int32_t ***det_off;
111 
112 static float ***fptempcor;
113 static int32_t *k3_epoch;
114 // static int32_t *k3_ftype;
115 static int num_k3_epoch;
116 
117 static float ***scanmod;
118 static int32_t *k4_epoch;
119 // static int32_t *k4_ftype;
120 static int num_k4_epoch;
121 
122 static float ****msidecor;
123 static int32_t *ms_epoch;
124 // static int32_t *ms_ftype;
125 static int num_ms_epoch;
126 
127 static float ***dark_restore;
128 static int32_t *dkrest_epoch;
129 static int num_dkrest_epoch;
130 static int haveDarkRestore = 0;
131 
132 static float fp_temp[NBAND][NTEMP];
133 static short tdi_list[NDET][NTDI];
136 static float g_f[NBAND][1024];
137 
138 static int32_t ref_year;
139 static int32_t ref_day;
140 static int32_t ref_min;
141 static short prev_tdi[NBAND] = {-1, -1, -1, -1, -1, -1, -1, -1};
142 static short prev_gain[NBAND] = {-1, -1, -1, -1, -1, -1, -1, -1};
143 static int32_t prev_syear;
144 static int32_t prev_sday;
145 static int32_t prev_smsec;
146 static double ref_jsec;
147 
148 /* -------------------------------------------------------------------------- */
149 /* read_caltable() - called once to load cal table static arrays */
150 
151 /* -------------------------------------------------------------------------- */
152 
153 void read_caltable(char *cal_path) {
154 
155  static int firstCall = 1;
156  char name [H4_MAX_NC_NAME] = "";
157  char sdsname[H4_MAX_NC_NAME] = "";
158 
159  int32 sd_id;
160  int32 sds_id;
161  int32 rank;
162  int32 nt;
163  int32 dims[H4_MAX_VAR_DIMS];
164  int32 nattrs, attr_index, count, num_type;
165  char attr_name[64];
166  int32 start4[4] = {0, 0, 0, 0};
167  int32 start[3] = {0, 0, 0};
168  int32 status;
169  float *r;
170  int32_t *dr;
171 
172  int32_t i, j, k, l;
173  int m = 1;
174 
175  if (!firstCall) return;
176 
177  /* Open the cal cal_path... */
178  sd_id = SDstart(cal_path, DFACC_RDONLY);
179  if (sd_id == FAIL) {
180  fprintf(stderr, "-E- %s line %d: SDstart(%s, %d) failed.\n",
181  __FILE__, __LINE__, cal_path, DFACC_RDONLY);
182  exit(1);
183  }
184 
185  /* Functional type index */
186  strcpy(sdsname, "ftype");
187  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
188  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
189  status = SDreaddata(sds_id, start, NULL, dims, ftype);
190  if (status != 0) {
191  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
192  __FILE__, __LINE__, sdsname, cal_path);
193  exit(1);
194  } else {
195  status = SDendaccess(sds_id);
196  }
197 
198  /* Radiometric coefficients */
199  strcpy(sdsname, "radiometric_coef");
200  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
201  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
202  radcor = alloc3d_float(dims[0], dims[1], dims[2]);
203  m = 1;
204  for (i = 0; i < rank; i++)
205  m *= dims[i];
206  r = (float *) malloc(m * sizeof (float *));
207  /* Get epoch start times */
208  attr_index = SDfindattr(sds_id, "k1_epochs");
209  status = SDattrinfo(sds_id, attr_index, attr_name, &num_type, &count);
210  num_k1_epoch = count;
211  k1_epoch = (int32_t *) malloc(count * sizeof (int32_t *));
212  status = SDreadattr(sds_id, attr_index, k1_epoch);
213  /* Get functional type index*/
214  /* attr_index = SDfindattr(sds_id,"ftype index");
215  status = SDattrinfo(sds_id,attr_index,attr_name,&num_type, &count);
216  k1_ftype = (int32_t *) malloc(count * sizeof(int32_t *));
217  status = SDreadattr(sds_id,attr_index,k1_ftype); */
218 
219  /* Get the data...*/
220  status = SDreaddata(sds_id, start, NULL, dims, r);
221  if (status != 0) {
222  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
223  __FILE__, __LINE__, sdsname, cal_path);
224  exit(1);
225  } else {
226  status = SDendaccess(sds_id);
227  for (i = 0; i < dims[0]; i++) {
228  for (j = 0; j < dims[1]; j++) {
229  for (k = 0; k < dims[2]; k++) {
230  m = i * dims[1] * dims[2] + j * dims[2] + k;
231  radcor[i][j][k] = r[m];
232  }
233  }
234  }
235  }
236 
237  free(r);
238 
239  /* Get the dark counts */
240  strcpy(sdsname, "dark_counts");
241  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
242  if (sds_id >= 0) {
243  haveDarkRestore = 1;
244  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
245  dark_restore = alloc3d_float(dims[0], dims[1], dims[2]);
246  m = 1;
247  for (i = 0; i < rank; i++)
248  m *= dims[i];
249  r = (float *) malloc(m * sizeof (float *));
250  /* Get epoch start times */
251  attr_index = SDfindattr(sds_id, "dn0_epochs");
252  status = SDattrinfo(sds_id, attr_index, attr_name, &num_type, &count);
253  num_dkrest_epoch = count;
254  dkrest_epoch = (int32_t *) malloc(count * sizeof (int32_t *));
255  status = SDreadattr(sds_id, attr_index, dkrest_epoch);
256  status = SDreaddata(sds_id, start, NULL, dims, r);
257  if (status != 0) {
258  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
259  __FILE__, __LINE__, sdsname, cal_path);
260  exit(1);
261  } else {
262  status = SDendaccess(sds_id);
263  for (i = 0; i < dims[0]; i++) {
264  for (j = 0; j < dims[1]; j++) {
265  for (k = 0; k < dims[2]; k++) {
266  m = i * dims[1] * dims[2] + j * dims[2] + k;
267  dark_restore[i][j][k] = r[m];
268  }
269  }
270  }
271  }
272  free(r);
273 
274  }
275 
276 
277  /* Gain 3:1 correction coefficients */
278  strcpy(sdsname, "gainratio_coef");
279  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
280  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
281  if (status == 0) {
282  if (want_verbose)
283  printf("\nGain 3 correction applied.\n");
284  gain3corr = 1;
285  g3corr = alloc3d_float(dims[0], dims[1], dims[2]);
286  m = 1;
287  for (i = 0; i < rank; i++)
288  m *= dims[i];
289  r = (float *) malloc(m * sizeof (float *));
290  /* Get epoch start times */
291  attr_index = SDfindattr(sds_id, "gr_epochs");
292  status = SDattrinfo(sds_id, attr_index, attr_name, &num_type, &count);
293  num_gr_epoch = count;
294  gr_epoch = (int32_t *) malloc(count * sizeof (int32_t *));
295  status = SDreadattr(sds_id, attr_index, gr_epoch);
296  /* Get functional type index*/
297  /* attr_index = SDfindattr(sds_id,"ftype index");
298  status = SDattrinfo(sds_id,attr_index,attr_name,&num_type, &count);
299  gr_ftype = (int32_t *) malloc(count * sizeof(int32_t *));
300  status = SDreadattr(sds_id,attr_index,gr_ftype); */
301  /* Get the data...*/
302  status = SDreaddata(sds_id, start, NULL, dims, r);
303  if (status != 0) {
304  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
305  __FILE__, __LINE__, sdsname, cal_path);
306  exit(1);
307  } else {
308  status = SDendaccess(sds_id);
309  for (i = 0; i < dims[0]; i++) {
310  for (j = 0; j < dims[1]; j++) {
311  for (k = 0; k < dims[2]; k++) {
312  m = i * dims[1] * dims[2] + j * dims[2] + k;
313  g3corr[i][j][k] = r[m];
314  }
315  }
316  }
317  }
318 
319  free(r);
320  } else {
321  gain3corr = 0;
322  }
323 
324  /* Counts to Radiance coefficients */
325  strcpy(sdsname, "counts_to_radiance");
326  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
327  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
328  cnts2rad = alloc3d_float(dims[2], dims[1], dims[0]);
329  m = 1;
330  for (i = 0; i < rank; i++)
331  m *= dims[i];
332  r = (float *) malloc(m * sizeof (float *));
333  /* Get the data...*/
334  status = SDreaddata(sds_id, start, NULL, dims, r);
335  if (status != 0) {
336  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
337  __FILE__, __LINE__, sdsname, cal_path);
338  exit(1);
339  } else {
340  status = SDendaccess(sds_id);
341  for (i = 0; i < dims[0]; i++) {
342  for (j = 0; j < dims[1]; j++) {
343  for (k = 0; k < dims[2]; k++) {
344  m = i * dims[1] * dims[2] + j * dims[2] + k;
345  cnts2rad[k][j][i] = r[m];
346  }
347  }
348  }
349  }
350 
351  free(r);
352 
353 
354  /* Detector offsets */
355  strcpy(sdsname, "detector_offsets");
356  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
357  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
358  det_off = alloc3d_long(dims[2], dims[1], dims[0]);
359  m = 1;
360  for (i = 0; i < rank; i++)
361  m *= dims[i];
362  dr = (int32_t *) malloc(m * sizeof (int32_t *));
363  /* Get the data...*/
364  status = SDreaddata(sds_id, start, NULL, dims, dr);
365  if (status != 0) {
366  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
367  __FILE__, __LINE__, sdsname, cal_path);
368  exit(1);
369  } else {
370  status = SDendaccess(sds_id);
371  for (i = 0; i < dims[0]; i++) {
372  for (j = 0; j < dims[1]; j++) {
373  for (k = 0; k < dims[2]; k++) {
374  m = i * dims[1] * dims[2] + j * dims[2] + k;
375  det_off[k][j][i] = dr[m];
376  }
377  }
378  }
379  }
380 
381  free(dr);
382 
383  /* Temperature coefficients */
384  strcpy(sdsname, "temperature_coef");
385  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
386  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
387  fptempcor = alloc3d_float(dims[0], dims[1], dims[2]);
388  m = 1;
389  for (i = 0; i < rank; i++)
390  m *= dims[i];
391  r = (float *) malloc(m * sizeof (float *));
392  /* Get epoch start times */
393  attr_index = SDfindattr(sds_id, "k3_epochs");
394  status = SDattrinfo(sds_id, attr_index, attr_name, &num_type, &count);
395  num_k3_epoch = count;
396  k3_epoch = (int32_t *) malloc(count * sizeof (int32_t *));
397  status = SDreadattr(sds_id, attr_index, k3_epoch);
398  /* Get functional type index*/
399  /* attr_index = SDfindattr(sds_id,"ftype index");
400  status = SDattrinfo(sds_id,attr_index,attr_name,&num_type, &count);
401  k3_ftype = (int32_t *) malloc(count * sizeof(int32_t *));
402  status = SDreadattr(sds_id,attr_index,k3_ftype); */
403  /* Get the data...*/
404  status = SDreaddata(sds_id, start, NULL, dims, r);
405  if (status != 0) {
406  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
407  __FILE__, __LINE__, sdsname, cal_path);
408  exit(1);
409  } else {
410  status = SDendaccess(sds_id);
411  for (i = 0; i < dims[0]; i++) {
412  for (j = 0; j < dims[1]; j++) {
413  for (k = 0; k < dims[2]; k++) {
414  m = i * dims[1] * dims[2] + j * dims[2] + k;
415  fptempcor[i][j][k] = r[m];
416  }
417  }
418  }
419  }
420 
421  free(r);
422 
423  /* Scan Modulation correction*/
424  strcpy(sdsname, "scan_mod_coef");
425  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
426  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
427  scanmod = alloc3d_float(dims[0], dims[1], dims[2]);
428  m = 1;
429  for (i = 0; i < rank; i++)
430  m *= dims[i];
431  r = (float *) malloc(m * sizeof (float *));
432  /* Get epoch start times */
433  attr_index = SDfindattr(sds_id, "k4_epochs");
434  status = SDattrinfo(sds_id, attr_index, attr_name, &num_type, &count);
435  num_k4_epoch = count;
436  k4_epoch = (int32_t *) malloc(count * sizeof (int32_t *));
437  status = SDreadattr(sds_id, attr_index, k4_epoch);
438  /* Get functional type index*/
439  /* attr_index = SDfindattr(sds_id,"ftype index");
440  status = SDattrinfo(sds_id,attr_index,attr_name,&num_type, &count);
441  k4_ftype = (int32_t *) malloc(count * sizeof(int32_t *));
442  status = SDreadattr(sds_id,attr_index,k4_ftype); */
443  /* Get the data...*/
444  status = SDreaddata(sds_id, start, NULL, dims, r);
445  if (status != 0) {
446  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
447  __FILE__, __LINE__, sdsname, cal_path);
448  exit(1);
449  } else {
450  status = SDendaccess(sds_id);
451  for (i = 0; i < dims[0]; i++) {
452  for (j = 0; j < dims[1]; j++) {
453  for (k = 0; k < dims[2]; k++) {
454  m = i * dims[1] * dims[2] + j * dims[2] + k;
455  scanmod[i][j][k] = r[m];
456  }
457  }
458  }
459  }
460 
461  free(r);
462 
463  /* Mirror Side correction*/
464  strcpy(sdsname, "mirror_side_coef");
465  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
466  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
467  msidecor = alloc4d_float(dims[0], dims[1], dims[2], dims[3]);
468  m = 1;
469  for (i = 0; i < rank; i++)
470  m *= dims[i];
471  r = (float *) malloc(m * sizeof (float *));
472  /* Get epoch start times */
473  attr_index = SDfindattr(sds_id, "ms_epochs");
474  status = SDattrinfo(sds_id, attr_index, attr_name, &num_type, &count);
475  num_ms_epoch = count;
476  ms_epoch = (int32_t *) malloc(count * sizeof (int32_t *));
477  status = SDreadattr(sds_id, attr_index, ms_epoch);
478  /* Get functional type index*/
479  /* attr_index = SDfindattr(sds_id,"ftype index");
480  status = SDattrinfo(sds_id,attr_index,attr_name,&num_type, &count);
481  ms_ftype = (int32_t *) malloc(count * sizeof(int32_t *));
482  status = SDreadattr(sds_id,attr_index,ms_ftype); */
483  /* Get the data...*/
484  status = SDreaddata(sds_id, start4, NULL, dims, r);
485  if (status != 0) {
486  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
487  __FILE__, __LINE__, sdsname, cal_path);
488  exit(1);
489  } else {
490  status = SDendaccess(sds_id);
491  for (i = 0; i < dims[0]; i++) {
492  for (j = 0; j < dims[1]; j++) {
493  for (k = 0; k < dims[2]; k++) {
494  for (l = 0; l < dims[3]; l++) {
495  m = i * dims[1] * dims[2] * dims[3] + j * dims[2] * dims[3] + k * dims[3] + l;
496  msidecor[i][j][k][l] = r[m];
497  }
498  }
499  }
500  }
501  }
502 
503  free(r);
504 
505  /* Focal Plane Temperature Array*/
506  strcpy(sdsname, "fp_temp");
507  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
508  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
509  /* Get the data...*/
510  status = SDreaddata(sds_id, start, NULL, dims, fp_temp);
511  if (status != 0) {
512  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
513  __FILE__, __LINE__, sdsname, cal_path);
514  exit(1);
515  } else {
516  status = SDendaccess(sds_id);
517  }
518 
519  /* TDI List Array*/
520  strcpy(sdsname, "TDI_list");
521  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
522  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
523  /* Get the data...*/
524  status = SDreaddata(sds_id, start, NULL, dims, tdi_list);
525  if (status != 0) {
526  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
527  __FILE__, __LINE__, sdsname, cal_path);
528  exit(1);
529  } else {
530  status = SDendaccess(sds_id);
531  }
532 
533  /* Get Reference Date info */
534  attr_index = SDfindattr(sd_id, "Reference Year");
535  status = SDreadattr(sd_id, attr_index, &ref_year);
536  if (status != 0) {
537  printf("-E- %s Line %d: Error reading Reference Year from %s.\n",
538  __FILE__, __LINE__, cal_path);
539  exit(1);
540  }
541  attr_index = SDfindattr(sd_id, "Reference Day");
542  status = SDreadattr(sd_id, attr_index, &ref_day);
543  if (status != 0) {
544  printf("-E- %s Line %d: Error reading Reference Day from %s.\n",
545  __FILE__, __LINE__, cal_path);
546  exit(1);
547  }
548  attr_index = SDfindattr(sd_id, "Reference Minute");
549  status = SDreadattr(sd_id, attr_index, &ref_min);
550  if (status != 0) {
551  printf("-E- %s Line %d: Error reading Reference Minute from %s.\n",
552  __FILE__, __LINE__, cal_path);
553  exit(1);
554  }
555 
556  ref_jsec = yds2unix((int) ref_year, (int) ref_day, ((double) (ref_min)) / 1440.0);
557 
558  /* terminate access to the SD interface and close the cal_path */
559  status = SDend(sd_id);
560 
561  firstCall = 0;
562 }
563 
564 /* --------------------------------------------------------------------------*/
565 /* apply_time_coef - given the functional form index, coefficients */
566 /* and "x" parameter, returns "y" */
567 
568 /* --------------------------------------------------------------------------*/
569 float apply_time_coef(short functype, float coef[NCOEF], double param) {
570  float correction_factor;
571 
572  switch (functype) {
573  // default functype (0) - double exponential
574  case 0:
575  correction_factor = 1.0 / (coef[0] -
576  coef[1] * (1.0 - exp(-coef[2] * param)) -
577  coef[3] * (1.0 - exp(-coef[4] * param)));
578  break;
579  // functype (1) - quadratic
580  case 1:
581  correction_factor = 1.0 / (coef[0] + coef[1] * param + coef[2] * pow(param, 2));
582  break;
583  // functype (2) - exponential + linear
584  case 2:
585  correction_factor = 1.0 / (coef[0] -
586  coef[1] * (1.0 - exp(-coef[2] * param)) -
587  coef[3] * param);
588  break;
589  }
590 
591  return correction_factor;
592 }
593 
594 /* --------------------------------------------------------------------------*/
595 /* get_epoch_idx - returns the index for the epoch */
596 
597 /* --------------------------------------------------------------------------*/
598 int get_epoch_idx(int param, double jsec) {
599  int epidx = 0;
600  int32_t *epochs;
601  int cnt, i;
602 
603  switch (param) {
604  case K1:
605  epochs = k1_epoch;
606  cnt = num_k1_epoch;
607  break;
608  case GR:
609  epochs = gr_epoch;
610  cnt = num_gr_epoch;
611  break;
612  case K3:
613  epochs = k3_epoch;
614  cnt = num_k3_epoch;
615  break;
616  case K4:
617  epochs = k4_epoch;
618  cnt = num_k4_epoch;
619  break;
620  case MSIDE:
621  epochs = ms_epoch;
622  cnt = num_ms_epoch;
623  break;
624  case DARK:
625  epochs = dkrest_epoch;
626  cnt = num_dkrest_epoch;
627  break;
628  }
629  for (i = 0; i < cnt; i++) {
630  if (jsec > (double) epochs[i]) {
631  epidx = i;
632  }
633  }
634  return epidx;
635 }
636 
637 /* --------------------------------------------------------------------------*/
638 /* calc_knees_two - slightly modified version of the original... */
639 
640 /* --------------------------------------------------------------------------*/
641 void calc_knees_two(int16 *tdi, float32 counts[8][4][5], float32 rads[8][4][5]) {
642 
643  int16 dets[4];
644  int32 i, j, k;
645  int32 scnts[4]; /* saturation counts */
646  float32 srads[4]; /* saturation radiance */
647  float32 loc_slopes[4];
648  float32 slopes[NBAND][4][4];
649  int32 cnts[NBAND][4][4];
650  int32 oindex[NDET];
651 
652 
653  for (i = 0; i < NBAND; i++)
654  for (j = 0; j < 4; j++)
655  for (k = 0; k < 4; k++) {
656  slopes[i][j][k] = cnts2rad[i][j][k];
657  cnts[i][j][k] = det_off[i][j][k];
658  }
659 
660  for (i = 0; i < NBAND; i++) {
661  for (j = 0; j < 4; j++)
662  dets[j] = tdi_list[j][tdi[i]] - 1;
663  for (j = 0; j < NGAIN; j++) {
664  for (k = 0; k < NDET; k++) {
665  scnts[k] = 1023 - cnts[i][j][dets[k]];
666  srads[k] = scnts[k] * slopes[i][j][dets[k]];
667  loc_slopes[k] = slopes[i][j][dets[k]];
668  }
669 
670  sort_srads(srads, oindex);
671 
672  rads[i][j][0] = 0;
673  for (k = 1; k < 5; k++)
674  rads[i][j][k] = srads[oindex[k - 1]];
675 
676  counts[i][j][0] = 0;
677  counts[i][j][1] = (scnts[oindex[0]] +
678  srads[oindex[0]] / loc_slopes[oindex[1]] +
679  srads[oindex[0]] / loc_slopes[oindex[2]] +
680  srads[oindex[0]] / loc_slopes[oindex[3]]) / 4.0;
681 
682  counts[i][j][2] = (scnts[oindex[0]] + scnts[oindex[1]] +
683  srads[oindex[1]] / loc_slopes[oindex[2]] +
684  srads[oindex[1]] / loc_slopes[oindex[3]]) / 4.0;
685 
686 
687  counts[i][j][3] = (scnts[oindex[0]] + scnts[oindex[1]] +
688  scnts[oindex[2]] +
689  srads[oindex[2]] / loc_slopes[oindex[3]]) / 4.0;
690 
691  counts[i][j][4] = (scnts[oindex[0]] + scnts[oindex[1]] +
692  scnts[oindex[2]] + scnts[oindex[3]]) / 4.0;
693 
694  }
695  }
696 }
697 /* -------------------------------------------------------------------------- */
698 /* l1b_rad - returns calibrated L1B radiances */
699 
700 /* -------------------------------------------------------------------------- */
701 int32_t l1b_rad(int syear, int sday, int32_t smsec, int32_t msec,
702  char *dtype, int32_t nsta, int32_t ninc, int32_t npix,
703  float *dark_mean, short *gain, short *tdi,
704  short *scan_temp, float *inst_temp, int mside,
705  short *l1a_data, float *l1b_data, cal_mod_struc *cal_mod) {
706  int i, pixel, knee, n, count;
707  int band;
708  int l1_data_lo, l1_data_hi;
709  int dark;
710  float dark_ratio;
711  double delta_t;
712  int gn[NBAND];
713  float k1, gcorr, k3, k4, mirror;
714  int16 k1_ftype, gr_ftype, k4_ftype, ms_ftype;
715  int epoch_idx[NCOEF];
716  double jsec;
717  float coef[NCOEF];
718  float cal_offset = 0.;
719  int gain_flag, tdi_flag;
720  float slope;
721  short count1, count2;
722  short scanpix;
723  int called_calc_knees = 0;
724 
725  jsec = yds2unix(syear, sday, ((double) (msec)) / 1000.0);
726  delta_t = (jsec - (double) ref_jsec) / 86400.;
727 
728  // TDI, gain and scan_temp funny business...Gene E. got some 'spalin' to do ;)
729  for (band = 0; band < NBAND; band++) {
730  if (tdi[band] < 0)
731  tdi[band] = 0;
732  if (tdi[band] > 255)
733  tdi[band] = 255;
734  if (scan_temp[band] < 0)
735  scan_temp[band] = 0;
736  if (scan_temp[band] > 255)
737  scan_temp[band] = 255;
738  // Fix gain 2 / gain 3 telemetry bit flip
739  switch (gain[band]) {
740  case 0:
741  gn[band] = 0;
742  break;
743  case 1:
744  gn[band] = 2;
745  break;
746  case 2:
747  gn[band] = 1;
748  break;
749  case 3:
750  gn[band] = 3;
751  break;
752  }
753 
754  }
755 
756  for (band = 0; band < NBAND && tdi[band] == prev_tdi[band]; band++);
757  if (band < NBAND)
758  tdi_flag = 1;
759  else
760  tdi_flag = 0;
761 
762  // Calc knees ...
763 
764  if (syear != prev_syear || sday != prev_sday
765  || smsec != prev_smsec || tdi_flag) {
766  prev_syear = syear;
767  prev_sday = sday;
768  prev_smsec = smsec;
769 
770  for (band = 0; band < NBAND; band++)
771  prev_tdi[band] = tdi[band];
772 
774  called_calc_knees = 1;
775  }
776 
777 
778  for (band = 0; band < NBAND && gn[band] == prev_gain[band]; band++);
779 
780  if (band < NBAND)
781  gain_flag = 1;
782  else
783  gain_flag = 0;
784  // ... and then generate the 'radiance' LUT...
785  if (called_calc_knees || gain_flag) {
786  called_calc_knees = 0;
787  for (band = 0; band < NBAND; band++)
788  prev_gain[band] = gn[band];
789  for (band = 0; band < NBAND; band++) {
790  for (knee = 1; knee <= 4; knee++) {
791  n = 1;
792  while (((int16) cal_counts[band][gn[band]][knee] ==
793  (int16) cal_counts[band][gn[band]][knee - n]) && n <= knee)
794  n++;
795  count1 = (int16) cal_counts[band][gn[band]][knee - n] + 1;
796  count2 = (int16) cal_counts[band][gn[band]][knee];
797  if (knee == 1)
798  count1 = 0;
799  if (knee == 4)
800  count2 = 1023;
801  slope = (cal_rads[band][gn[band]][knee] -
802  cal_rads[band][gn[band]][knee - n]) /
803  (cal_counts[band][gn[band]][knee] -
804  cal_counts[band][gn[band]][knee - n]);
805  for (count = count1; count <= count2; count++)
806  g_f[band][count] =
807  slope * (count - cal_counts[band][gn[band]][knee - n]) +
808  cal_rads[band][gn[band]][knee - n];
809  }
810  }
811  }
812 
813  // ...and now for the real heavy lifting...
814  epoch_idx[0] = get_epoch_idx(K1, jsec);
815  epoch_idx[1] = get_epoch_idx(K3, jsec);
816  epoch_idx[2] = get_epoch_idx(MSIDE, jsec);
817  epoch_idx[3] = get_epoch_idx(K4, jsec);
818  epoch_idx[4] = get_epoch_idx(GR, jsec);
819 
820  for (band = 0; band < NBAND; band++) {
821 
822  // Radiometric decay correction
823  for (i = 0; i < NCOEF; i++) {
824  coef[i] = radcor[epoch_idx[0]][i][band];
825  }
826  k1_ftype = (int16) coef[NCOEF - 1];
827  k1 = apply_time_coef(k1_ftype, coef, delta_t);
828 
829  gcorr = 1.;
830  if (gain3corr) {
831  for (i = 0; i < NCOEF; i++) {
832  coef[i] = g3corr[epoch_idx[4]][i][band];
833  }
834  // gain3corr is NOT applied in the inverse...so invert it :)
835  gr_ftype = (int16) coef[NCOEF - 1];
836  gcorr = 1. / apply_time_coef(gr_ftype, coef, delta_t);
837  }
838  /* Check for override on system gain and offset */
839  /* and pass back the gain, offset used */
840  if (cal_mod->flag == 1) {
841  k1 = cal_mod->gain[band] * k1;
842  } else if (cal_mod->flag == 2) {
843  cal_offset = cal_mod->offset[band];
844  }
845  else if (cal_mod->flag == 3) {
846  k1 = cal_mod->gain[band] * k1;
847  cal_offset = cal_mod->offset[band];
848  } else {
849  cal_mod->gain[band] = k1;
850  cal_mod->offset[band] = cal_offset;
851  }
852 
853  // Temperature correction
854  for (i = 0; i < NCOEF; i++)
855  coef[i] = fptempcor[epoch_idx[1]][i][band];
856  // k3_ftype = (int16)fptempcor[epoch_idx[1]][NCOEF][band];
857  // k3 = apply_time_coef(k3_ftype,coef,delta_t);
858  k3 = (1.0 + coef[0]*(fp_temp[band][scan_temp[band]] - coef[1]));
859 
860  // Mirror side correction
861  for (i = 0; i < NCOEF; i++)
862  coef[i] = msidecor[epoch_idx[2]][i][mside][band];
863  ms_ftype = (int16) coef[NCOEF - 1];
864  mirror = apply_time_coef(ms_ftype, coef, delta_t);
865  if (mside == 1) mirror = 1.0 / mirror;
866 
867  // Scan modulation (a.k.a. RVS) correction
868  for (i = 0; i < NCOEF; i++)
869  coef[i] = scanmod[epoch_idx[3]][i][band];
870  k4_ftype = (int16) coef[NCOEF - 1];
871  for (pixel = 0; pixel < npix; pixel++) {
872 
873  scanpix = nsta + ninc*pixel;
874  // apply scan modulation correction to earth view data only...
875  if ((strcmp(dtype, "SOL") != 0) && (strcmp(dtype, "TDI") != 0) &&
876  (strcmp(dtype, "IGC") != 0))
877  k4 = apply_time_coef(k4_ftype, coef, scanpix - 643);
878  else k4 = 1.0;
879 
880  // If the cal table has the dark_count array, use it.
881  // If not, use the mean of the scene
882  if (haveDarkRestore) {
883  int dkidx = get_epoch_idx(DARK, jsec);
884 
885  dark = ceil(dark_restore[dkidx][gn[band]][band]);
886  dark_ratio = (float) dark - dark_restore[dkidx][gn[band]][band];
887 
888  } else {
889  dark = ceil(dark_mean[band]);
890  dark_ratio = (float) dark - dark_mean[band];
891  }
892 
893  l1_data_lo = l1a_data[band * npix + pixel] - dark;
894 
895  if (l1_data_lo < 0)
896  l1_data_lo = 0;
897  if (l1_data_lo > 1022)
898  l1_data_lo = 1022;
899 
900  l1_data_hi = l1_data_lo + 1;
901 
902  l1b_data[band * npix + pixel] = (k1 * gcorr * k3 * k4 * mirror * (g_f[band][l1_data_lo]*(1 - dark_ratio) + g_f[band][l1_data_hi] * dark_ratio) + cal_offset);
903 
904  }
905 
906  }
907 
908  return SUCCEED;
909 
910 }
911 
#define NDET
Definition: get_cal_swf.c:84
integer, parameter int16
Definition: cubeio.f90:3
float rads[BANDS_DIMS_1A][GAINS_DIMS_1A][KNEES_DIMS_1A]
Definition: l1a_seawifs.c:47
int r
Definition: decode_rs.h:73
void sort_srads(float32 *srads, int32 *oindex)
float dark_mean[8]
Definition: l1a_seawifs.c:34
int j
Definition: decode_rs.h:73
int status
Definition: l1_czcs_hdf.c:32
double yds2unix(int16_t year, int16_t day, double secs)
Definition: yds2unix.c:7
int16 * gain
Definition: l1_czcs_hdf.c:33
#define FAIL
Definition: ObpgReadGrid.h:18
void read_caltable(char *cal_path)
Definition: get_cal_swf.c:153
#define NULL
Definition: decode_rs.h:63
float *** alloc3d_float(int m, int n, int o)
Definition: get_cal_swf.c:29
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 band
int32_t *** alloc3d_long(int m, int n, int o)
Definition: get_cal_swf.c:64
int16_t * l1a_data
Definition: l1a_seawifs.c:84
float cal_rads[NBAND][NDET][NKNEE]
Definition: get_cal_swf.c:135
int32 * msec
Definition: l1_czcs_hdf.c:31
uint8 * counts
Definition: l1_czcs_hdf.c:30
int syear
Definition: l1_czcs_hdf.c:15
#define NCOEF
Definition: get_cal_swf.c:83
int32 smsec
Definition: l1_czcs_hdf.c:16
#define K1
Definition: get_cal_swf.c:88
int sday
Definition: l1_czcs_hdf.c:15
int32 nsta
Definition: l1_czcs_hdf.c:27
#define GR
Definition: get_cal_swf.c:93
#define MSIDE
Definition: get_cal_swf.c:91
int32_t mside
#define NTDI
Definition: get_cal_swf.c:86
float32 slope[]
Definition: l2lists.h:30
float **** alloc4d_float(int l, int m, int n, int o)
Definition: get_cal_swf.c:44
int32 ninc
Definition: l1_czcs_hdf.c:28
#define NBAND
Definition: get_cal_swf.c:80
#define NGAIN
Definition: get_cal_swf.c:85
int16_t tdi[BANDS_DIMS_1A]
Definition: l1a_seawifs.c:37
int want_verbose
integer, parameter double
#define NK
Definition: get_cal_swf.c:94
this program makes no use of any feature of the SDP Toolkit that could generate such a then geolocation is calculated at that and then aggregated up to Resolved feature request Bug by adding three new int8 SDSs for each high resolution pixel
Definition: HISTORY.txt:192
int16_t ref_day
Definition: l1a_seawifs.c:42
int32_t l1b_rad(int syear, int sday, int32_t smsec, int32_t msec, char *dtype, int32_t nsta, int32_t ninc, int32_t npix, float *dark_mean, short *gain, short *tdi, short *scan_temp, float *inst_temp, int mside, short *l1a_data, float *l1b_data, cal_mod_struc *cal_mod)
Definition: get_cal_swf.c:701
dtype
Definition: DDataset.hpp:31
void calc_knees_two(int16 *tdi, float32 counts[8][4][5], float32 rads[8][4][5])
Definition: get_cal_swf.c:641
Extra metadata that will be written to the HDF4 file l2prod rank
#define NTEMP
Definition: get_cal_swf.c:81
#define DARK
Definition: get_cal_swf.c:92
float apply_time_coef(short functype, float coef[NCOEF], double param)
Definition: get_cal_swf.c:569
#define K4
Definition: get_cal_swf.c:90
int get_epoch_idx(int param, double jsec)
Definition: get_cal_swf.c:598
int16_t ref_year
Definition: l1a_seawifs.c:41
float cal_counts[NBAND][NDET][NKNEE]
Definition: get_cal_swf.c:134
int i
Definition: decode_rs.h:71
#define K3
Definition: get_cal_swf.c:89
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int k
Definition: decode_rs.h:73
int npix
Definition: get_cmp.c:27
float p[MODELMAX]
Definition: atrem_corl1.h:131
#define NKNEE
Definition: get_cal_swf.c:87
int count
Definition: decode_rs.h:79