NASA Logo
Ocean Color Science Software

ocssw V2022
l1_aci.c
Go to the documentation of this file.
1 /* ============================================================================ */
2 /* module l1_aci_hdf.c - functions to read Pathfinder Class data for MSL12 */
3 /* */
4 /* Modified By: S. Walsh, RSMAS, January 2008 to read Pathfinder */
5 /* */
6 /* ============================================================================ */
7 
8 #include "l1_aci.h"
9 #include <math.h>
10 #include "l1.h"
11 #include "rawcal.h"
12 #include "runcal.h"
13 #include <hdf4utils.h>
14 
15 #include <hdf.h>
16 #include <mfhdf.h>
17 
18 #define NAVBANDS 5
19 #define NVIRBANDS 2
20 #define NTIRBANDS 3
21 
22 #define TEMP_REF 273.15 /* convert Bt's from Deg K to Deg C */
23 
24 #define NRADTAB 100 /* Radiance to temperature table size */
25 
26 #define SDNAME "Channel_"
27 //#define SDNAME ""
28 
29 static int32_t sd_id;
30 static int32_t sd_id_g;
31 static int32_t spix = 0;
32 //static int32_t sscan = 0; /* start scan in original granule */
33 
34 static float T_LOW = 185.; /* Limit of 180K in etbpsub.f */
35 static float T_HIGH = 370.; /* Limit of 375K in etbpsub.f */
36 
37 static int pdbg1 = -1;
38 static int ldbg1 = -1;
39 //static int pdbg1 = 174; /* 2003131211434.N16 */
40 //static int ldbg1 = 1952;
41 //static int pdbg1 = 141; /* 2009200225057.N16 */
42 //static int ldbg1 = 122;
43 
44 float etinvert_(int32_t *ich, float *radi);
45 float etintegrate_(int32_t *ich, float *etemp);
46 void etloadresp_(int32_t *lin, char *cal);
47 int32_t avconsh_(int32_t *lunin, int32_t *npix, int32_t *jday);
48 int32_t avlooph_(float *satz, float *solz, float *delphi, float *rayly,
49  float *aersol, float *aglint);
50 
51 /* ----------------------------------------------------------------------------------- */
52 /* openl1_aci_hdf() - opens a ACI L1B file for reading. */
53 /* */
54 /* B. Franz, SAIC, February 2003. */
55 
56 /* ----------------------------------------------------------------------------------- */
57 int openl1_aci(filehandle *file) {
58  int32_t npix;
59  int32_t nscan;
60  const char xsatida[10];
61 
62  int32_t sds_id;
63  int32_t rank;
64  int32_t dims[3];
65  int32_t type;
66  int32_t numattr;
67 
68  /* Open the HDF input file */
69  sd_id = SDstart(file->name, DFACC_RDONLY);
70  if (sd_id == FAIL) {
71  fprintf(stderr, "-E- %s line %d: SDstart(%s, %d) failed.\n",
72  __FILE__, __LINE__, file->name, DFACC_RDONLY);
73  return (HDF_FUNCTION_ERROR);
74  }
75 
76  /* Get pixel and scan dimensions */
77  sds_id = SDselect(sd_id, SDnametoindex(sd_id, (SDNAME"1")));
78  if (SDgetinfo(sds_id, NULL, &rank, dims, &type, &numattr) == -1) {
79  fprintf(stderr, "-E- %s line %d: error getting dimension info.\n",
80  __FILE__, __LINE__);
81  return (HDF_FUNCTION_ERROR);
82  }
83  npix = dims[1];
84  /* can't use dims for nscan because avhrr file is created before the */
85  /* actual number of scans is known - because missing scans need to */
86  /* be filled in */
87  // nscan = dims[0];
88  if (getHDFattr(sd_id, "Number of scans", "", (VOIDP) & nscan) != 0) {
89  printf("-E- %s line %d: Error reading Number of scans attribute.\n",
90  __FILE__, __LINE__);
91  return (1);
92  }
93 
94  if (getHDFattr(sd_id, "Orbit Number", "", (VOIDP) & file->orbit_number)
95  != 0) {
96  printf("-E- %s line %d: Error reading Orbit attribute.\n",
97  __FILE__, __LINE__);
98  return (1);
99  }
100 
101  /* Open the HDF geolocation input file.*/
102 
103  sd_id_g = SDstart(file->geofile, DFACC_RDONLY);
104  if (sd_id_g == FAIL) {
105  printf("Error opening geolocation file.\n");
106  fprintf(stderr, "-E- %s line %d: SDstart(%s, %d) failed.\n",
107  __FILE__, __LINE__, file->geofile, DFACC_RDONLY);
108  return (HDF_FUNCTION_ERROR);
109  }
110 
111  if (getHDFattr(sd_id, "Satellite", "", (VOIDP) xsatida) != 0) {
112  printf("-E- %s line %d: Error reading Satellite attribute.\n",
113  __FILE__, __LINE__);
114  return (1);
115  }
116 
117  if (getHDFattr(sd_id, "spatial_resolution", "", (VOIDP) & file->spatialResolution) != 0) {
118  printf("-W- %s line %d: Error reading spatial_resolution attribute.\n",
119  __FILE__, __LINE__);
120  }
121  file->subsensorID = satname2xsatid(xsatida);
122 
123  file->npix = npix;
124  file->ndets = 1;
125  file->nscan = nscan;
126  file->sd_id = sd_id;
127 
128  return (LIFE_IS_GOOD);
129 }
130 
131 /* ----------------------------------------------------------------------------------- */
132 /* readl1_aci_hdf() - reads 1 line (scan) from a ACI ingested CLASS file, loads l1rec. */
133 /* */
134 
135 /* ----------------------------------------------------------------------------------- */
136 int readl1_aci(filehandle *file, int32_t scan, l1str *l1rec) {
137  static int firstCall = 1;
138  static int firstScan = 1;
139 
140  static int16_t *ch1 = NULL;
141  static int16_t *ch2 = NULL;
142  static int16_t *ch3 = NULL;
143  static int16_t *ch4 = NULL;
144  static int16_t *ch5 = NULL;
145 
146  static float m[NAVBANDS];
147  static float b[NAVBANDS];
148 
149  static float rayly[2];
150  static float aersol[2];
151  static int year, jday, RelDay, LY, leap, month, day, hh, mm, ss;
152  static int32_t ms = 0;
153  static char starttime[17];
154 
155  static int startOfMonth[2][12] = {
156  { 0, 31, 59, 90, 120, 151, 181, 212, 243,
157  273, 304, 334},
158  { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305,
159  335}
160  };
161 
162  /* Jon Mittaz's calibration for ch4 and ch5 */
163  static double ch4_coeff[5] = {0.0351618, 1.24004, 0.979493, 8.6071114e-06,
164  8.6071114e-06};
165  static double ch5_coeff[5] = {0.0326272, 1.06256, 0.986256, 4.0256298e-06,
166  4.0256298e-06};
167 
168  static char ingester[5];
169 
170  int16_t *data = NULL;
171  int32_t npix = (int32_t) file->npix;
172  int32_t nbands = (int32_t) file->nbands;
173  int32_t nbandsir = (int32_t) file->nbandsir;
174  int32_t detnum = 1;
175  int32_t ich, iw, ip, ipb;
176  int32_t ii, jj;
177  int32_t dims[3];
178  /* lunin is used to open the noaa*.cal file. It's an almost random
179  * number chosen by searching for 'open' in the other fortran routines
180  * and selecting an unused number */
181  int32_t lunin = 23;
182 
183  static float radinc[3];
184  static float radbas[3];
185  static float radinv[3][NRADTAB];
186  static float teminc[3];
187  static float tembas[3];
188  static float teminv[3][NRADTAB];
189 
190  static int vbcksc[30];
191  static int vspace[50];
192  float rspc[3];
193  float radprt[3];
194  float avgbck[3];
195  float avgspc[3];
196  float64 sumbck[2][3];
197  float64 sumspc[2][5];
198 
199  char scaletype[128];
200  char startdate[15];
201  char satnam[12];
202 
203  static RAW_CAL *rawrec;
204  static RUN_CAL *runrec;
205 
206  static int32_t *scantime;
207 
208  char tmpstr[80];
209 
210  int32_t status;
211  int32_t irun, jrun, idif, iraw, jraw, ni;
212  float ai;
213  float ascan;
214  float percnt;
215  float trad, ttem, tnlc;
216  float tcor;
217  float prtemp;
218 
219  if (firstCall) {
220 
221  /* initialize index arrays */
222 
223  firstCall = 0;
224 
225  jj = 0;
226  for (ii = 0; ii < 50; ii++) {
227  vspace[ii] = jj;
228  jj += 5;
229  if (jj >= 50) {
230  jj = jj - 50 + 1;
231  }
232  }
233  jj = 0;
234  for (ii = 0; ii < 30; ii++) {
235  vbcksc[ii] = jj;
236  jj += 3;
237  if (jj >= 30) {
238  jj = jj - 30 + 1;
239  }
240  }
241 
242  if ((ch1 = (int16_t *) calloc(npix, sizeof (int16_t))) == NULL) {
243  printf("-E- %s line %d: Error allocating data space.\n",
244  __FILE__, __LINE__);
245  return (1);
246  }
247 
248  if (getHDFattr(sd_id, "Slope", SDNAME"1", (VOIDP) & m[0]) != 0) {
249  printf("-E- %s line %d: Error reading Channel_1 Slope attribute.\n",
250  __FILE__, __LINE__);
251  return (1);
252  }
253 
254  if (getHDFattr(sd_id, "Intercept", SDNAME"1", (VOIDP) & b[0]) != 0) {
255  printf(
256  "-E- %s line %d: Error reading Channel_1 Intercept attribute.\n",
257  __FILE__, __LINE__);
258  return (1);
259  }
260  if (getHDFattr(sd_id, "Scale_type", SDNAME"1", (VOIDP) & scaletype)
261  != 0) {
262  printf(
263  "-E- %s line %d: Error reading Channel_1 Scale_type attribute.\n",
264  __FILE__, __LINE__);
265  return (1);
266  }
267  if (strcmp(scaletype, "y= Slope * x + Intercept;") != 0) {
268  printf("-E- %s line %d: Channel_1 Scale_type must be linear.\n",
269  __FILE__, __LINE__);
270  return (1);
271  }
272 
273  if ((ch2 = (int16_t *) calloc(npix, sizeof (int16_t))) == NULL) {
274  printf("-E- %s line %d: Error allocating data space.\n",
275  __FILE__, __LINE__);
276  return (1);
277  }
278 
279  if (getHDFattr(sd_id, "Slope", SDNAME"2", (VOIDP) & m[1]) != 0) {
280  printf("-E- %s line %d: Error reading Channel_2 Slope attribute.\n",
281  __FILE__, __LINE__);
282  return (1);
283  }
284 
285  if (getHDFattr(sd_id, "Intercept", SDNAME"2", (VOIDP) & b[1]) != 0) {
286  printf(
287  "-E- %s line %d: Error reading Channel_2 Intercept attribute.\n",
288  __FILE__, __LINE__);
289  return (1);
290  }
291  if (getHDFattr(sd_id, "Scale_type", SDNAME"2", (VOIDP) & scaletype)
292  != 0) {
293  printf(
294  "-E- %s line %d: Error reading Channel_2 Scale_type attribute.\n",
295  __FILE__, __LINE__);
296  return (1);
297  }
298  if (strcmp(scaletype, "y= Slope * x + Intercept;") != 0) {
299  printf("-E- %s line %d: Channel_2 Scale_type must be linear.\n",
300  __FILE__, __LINE__);
301  return (1);
302  }
303 
304  if ((ch3 = (int16_t *) calloc(npix, sizeof (int16_t))) == NULL) {
305  printf("-E- %s line %d: Error allocating data space.\n",
306  __FILE__, __LINE__);
307  return (1);
308  }
309 
310  if (getHDFattr(sd_id, "Slope", SDNAME"3", (VOIDP) & m[2]) != 0) {
311  printf("-E- %s line %d: Error reading Channel_3 Slope attribute.\n",
312  __FILE__, __LINE__);
313  return (1);
314  }
315 
316  if (getHDFattr(sd_id, "Intercept", SDNAME"3", (VOIDP) & b[2]) != 0) {
317  printf(
318  "-E- %s line %d: Error reading Channel_3 Intercept attribute.\n",
319  __FILE__, __LINE__);
320  return (1);
321  }
322  if (getHDFattr(sd_id, "Scale_type", SDNAME"3", (VOIDP) & scaletype)
323  != 0) {
324  printf(
325  "-E- %s line %d: Error reading Channel_3 Scale_type attribute.\n",
326  __FILE__, __LINE__);
327  return (1);
328  }
329  if (strcmp(scaletype, "y= Slope * x + Intercept;") != 0) {
330  printf("-E- %s line %d: Channel_3 Scale_type must be linear.\n",
331  __FILE__, __LINE__);
332  return (1);
333  }
334 
335  if ((ch4 = (int16_t *) calloc(npix, sizeof (int16_t))) == NULL) {
336  printf("-E- %s line %d: Error allocating data space.\n",
337  __FILE__, __LINE__);
338  return (1);
339  }
340 
341  if (getHDFattr(sd_id, "Slope", SDNAME"4", (VOIDP) & m[3]) != 0) {
342  printf("-E- %s line %d: Error reading Channel_4 Slope attribute.\n",
343  __FILE__, __LINE__);
344  return (1);
345  }
346 
347  if (getHDFattr(sd_id, "Intercept", SDNAME"4", (VOIDP) & b[3]) != 0) {
348  printf(
349  "-E- %s line %d: Error reading Channel_4 Intercept attribute.\n",
350  __FILE__, __LINE__);
351  return (1);
352  }
353  if (getHDFattr(sd_id, "Scale_type", SDNAME"4", (VOIDP) & scaletype)
354  != 0) {
355  printf(
356  "-E- %s line %d: Error reading Channel_4 Scale_type attribute.\n",
357  __FILE__, __LINE__);
358  return (1);
359  }
360  if (strcmp(scaletype, "y= Slope * x + Intercept;") != 0) {
361  printf("-E- %s line %d: Channel_4 Scale_type must be linear.\n",
362  __FILE__, __LINE__);
363  return (1);
364  }
365 
366  if ((ch5 = (int16_t *) calloc(npix, sizeof (int16_t))) == NULL) {
367  printf("-E- %s line %d: Error allocating data space.\n",
368  __FILE__, __LINE__);
369  return (1);
370  }
371 
372  if (getHDFattr(sd_id, "Slope", SDNAME"5", (VOIDP) & m[4]) != 0) {
373  printf("-E- %s line %d: Error reading Channel_5 Slope attribute.\n",
374  __FILE__, __LINE__);
375  return (1);
376  }
377 
378  if (getHDFattr(sd_id, "Intercept", SDNAME"5", (VOIDP) & b[4]) != 0) {
379  printf(
380  "-E- %s line %d: Error reading Channel_5 Intercept attribute.\n",
381  __FILE__, __LINE__);
382  return (1);
383  }
384  if (getHDFattr(sd_id, "Scale_type", SDNAME"5", (VOIDP) & scaletype)
385  != 0) {
386  printf(
387  "-E- %s line %d: Error reading Channel_5 Scale_type attribute.\n",
388  __FILE__, __LINE__);
389  return (1);
390  }
391  if (strcmp(scaletype, "y= Slope * x + Intercept;") != 0) {
392  printf("-E- %s line %d: Channel_5 Scale_type must be linear.\n",
393  __FILE__, __LINE__);
394  return (1);
395  }
396 
397  if (getHDFattr(sd_id, "start date", "", (VOIDP) & startdate) != 0) {
398  printf("-E- %s line %d: Error reading start date attribute.\n",
399  __FILE__, __LINE__);
400  return (1);
401  }
402  /* convert yyyy-mm-dd to year, day */
403  sscanf(startdate, "%04d-%02d-%02d", &year, &month, &day);
404  if (((year % 400) == 0) || (((year % 4) == 0) && ((year % 100) != 0))) {
405  leap = 1;
406  LY = 366;
407  } else {
408  leap = 0;
409  LY = 365;
410  }
411 
412  jday = startOfMonth[leap][month - 1] + day;
413 
414  if (getHDFattr(sd_id, "start time", "", (VOIDP) & starttime) != 0) {
415  printf("-E- %s line %d: Error reading start time attribute.\n",
416  __FILE__, __LINE__);
417  return (1);
418  }
419  /* starttime is a float with a value in this form: hhmmss.ss */
420  // hh = starttime/10000.;
421  // mm = ((int)(starttime/100.) % 100);
422  // ss = ((int)(starttime-(100.0 * (mm+ (100.*hh)))) % 100);
423  // ms = (int32_t)(1000. * (starttime- (int)starttime));
424  /* starttime is "hh:mm:ss.sss UTC" */
425  sscanf(starttime, "%02d:%02d:%02d.%03d", &hh, &mm, &ss, &ms);
426 
427  if (getHDFattr(sd_id, "Satellite Name", "", (VOIDP) satnam) != 0) {
428  printf("-E- %s line %d: Error reading Satellite Name attribute.\n",
429  __FILE__, __LINE__);
430  return (1);
431  }
432 
433  if (getHDFattr(sd_id, "PRTEMP", "", (VOIDP) & prtemp) != 0) {
434  printf("-E- %s line %d: Error reading PRTEMP attribute.\n",
435  __FILE__, __LINE__);
436  return (1);
437  }
438  //printf(" I Mean baseplate temperature =%6.1fK\n",prtemp);
439  // Sue Walsh said to comment the ACI name out...
440  // strcpy(ingester, "ACI ");
441  // if (getDims(sd_id, "ACI Raw Running Calibration", dims) != 0) {
442  // printf(
443  // "-E- %s line %d: Error reading ACI Raw Running Calibration dim.\n",
444  // __FILE__, __LINE__);
445  // return (1);
446  // }
447  /* allocate number of bytes needed for data in this file */
448  if ((rawrec = (RAW_CAL *) malloc(dims[0])) == NULL) {
449  printf("-E- %s line %d: Error allocating rawcal data space.\n",
450  __FILE__, __LINE__);
451  return (1);
452  }
453  strcpy(tmpstr, ingester);
454  strcat(tmpstr, "Raw Running Calibration");
455  status = rdSDS(sd_id, tmpstr, 0, 0, 0, 0, (VOIDP) rawrec);
456  if (status != 0) {
457  printf("-E- %s line %d: Error reading %s.\n",
458  __FILE__, __LINE__, tmpstr);
459  return (1);
460  }
461 
462  strcpy(tmpstr, ingester);
463  strcat(tmpstr, "Running Calibration");
464  if (getDims(sd_id, tmpstr, dims) != 0) {
465  printf("-E- %s line %d: Error reading %s dim.\n",
466  __FILE__, __LINE__, tmpstr);
467  return (1);
468  }
469  /* allocate the number of bytes needed for the data in this file */
470  if ((runrec = (RUN_CAL *) malloc(dims[0])) == NULL) {
471  printf("-E- %s line %d: Error allocating runcal data space.\n",
472  __FILE__, __LINE__);
473  return (1);
474  }
475  status = rdSDS(sd_id, tmpstr, 0, 0, 0, 0, (VOIDP) runrec);
476 
477  /* Work-around for single-scan time errors */
478  // if (TAIsec < 0.0) {
479  // printf("-W- %s: bad time in geolocation file at frame %d, using previous.\n",
480  // __FILE__,(int)frame);
481  // TAIsec = lastTAIsec;
482  // } else
483  // lastTAIsec = TAIsec;
484  //
485  // usec = TAIsec + 725846400.0;
486  // unix2yds(usec,&year,&day,&dsec);
487  if (getDims(sd_id, "Scan start time", dims) != 0) {
488  printf("-E- %s line %d: Error reading Scan start time dim.\n",
489  __FILE__, __LINE__);
490  return (1);
491  }
492  if (dims[0] != l1rec->l1file->nscan) {
493  printf(
494  "-E- %s line %d: Error: Number of Scan start times (%d) must match Number of Scans (%d).\n",
495  __FILE__, __LINE__, dims[0], l1rec->l1file->nscan);
496  return (1);
497  }
498  if ((scantime = (int32_t *) malloc(dims[0] * sizeof (int32_t))) == NULL) {
499  printf("-E- %s line %d: Error allocating scantime data space.\n",
500  __FILE__, __LINE__);
501  return (1);
502  }
503  status = rdSDS(sd_id, "Scan start time", 0, 0, 0, 0, (VOIDP) scantime);
504  if (status != 0) {
505  printf("-E- %s line %d: Error reading scan start time\n",
506  __FILE__, __LINE__);
507  return (1);
508  }
509 
510  // /* degc option is now ONLY for sstref in nlsst* equations */
511  // if (file->input->degc == 1) {
512  // /* Convert to Deg C for calc */
513  // rabias = TEMP_REF;
514  // } else {
515  // /* Do calc in Deg K */
516  // rabias = 0.;
517  // }
518 
519  switch (file->subsensorID) {
520  case NO07:
521  printf("I Applying NOAA-7 visible degradation.\n");
522  m[0] = m[0] / (0.916 - 0.049 * ((float) year + ((float) jday / (float) LY) - 1981.5)
523  + 0.0050 * pow((float) year + ((float) jday / (float) LY) - 1981.5, 2));
524  b[0] = b[0] / (0.916 - 0.049 * ((float) year + ((float) jday / (float) LY) - 1981.5)
525  + 0.0050 * pow((float) year + ((float) jday / (float) LY) - 1981.5, 2));
526  m[1] = m[1] / (0.882 - 0.080 * ((float) year + ((float) jday / (float) LY) - 1981.5)
527  + 0.0110 * pow((float) year + ((float) jday / (float) LY) - 1981.5, 2));
528  b[1] = b[1] / (0.882 - 0.080 * ((float) year + ((float) jday / (float) LY) - 1981.5)
529  + 0.0110 * pow((float) year + ((float) jday / (float) LY) - 1981.5, 2));
530  break;
531  case NO09:
532  printf("I Applying NOAA-9 visible degradation.\n");
533  m[0] = m[0] / (0.953 - 0.051 * ((float) year + ((float) jday / (float) LY) - 1985.0));
534  b[0] = b[0] / (0.953 - 0.051 * ((float) year + ((float) jday / (float) LY) - 1985.0));
535  m[1] = m[1] / (0.866 - 0.026 * ((float) year + ((float) jday / (float) LY) - 1985.0));
536  b[1] = b[1] / (0.866 - 0.026 * ((float) year + ((float) jday / (float) LY) - 1985.0));
537  break;
538  case NO11:
539  printf("I Applying NOAA-11 visible degradation.\n");
540  m[0] = m[0] / (0.797 - 0.010 * ((float) year + ((float) jday / (float) LY) - 1989.0));
541  b[0] = b[0] / (0.797 - 0.010 * ((float) year + ((float) jday / (float) LY) - 1989.0));
542  m[1] = m[1] / (0.683 - 0.020 * ((float) year + ((float) jday / (float) LY) - 1989.0));
543  b[1] = b[1] / (0.683 - 0.020 * ((float) year + ((float) jday / (float) LY) - 1989.0));
544  break;
545  case NO14:
546  /* Dec 30, 1994 is base date */
547  RelDay = ((year - 1994) * 365 + (jday - 364));
548  printf("I Applying NOAA-14 visible degradation.\n");
549  /* Post-Launch Calibration for Noaa-14 */
550  /* C R Nagaraja Rao and Jianhua Chen */
551  /* NOAA/NESDIS */
552  /* (from web page, March 1997) */
553  m[0] = 0.0000232 * (float) RelDay + 0.109;
554  b[0] = -41.0 * m[0];
555  m[1] = 0.0000373 * (float) RelDay + 0.129;
556  b[1] = -41.0 * m[1];
557  break;
558  default:
559  printf("I No visible degradation available for NOAA-%2.0d.\n",
560  file->subsensorID);
561  break;
562 
563  }
564 
565  /* start running calibration */
566 
567  etloadresp_(&lunin, satnam);
568  /* for debug / info
569  printf(" t_low %10.4f\n",T_LOW);
570  printf(" t_high %10.4f\n",T_HIGH);
571  */
572  for (iw = 0; iw <= 2; iw++) {
573  ich = iw + 3;
574  radinc[iw] = (float) ((log10(etintegrate_(&ich, &T_HIGH))
575  - log10(etintegrate_(&ich, &T_LOW)))
576  / (float) (NRADTAB - 1));
577  radbas[iw] = (float) (log10(etintegrate_(&ich, &T_LOW)));
578  /* for debug / info
579  printf(" Ch %1d radbas %14.6E radinc %14.6E\n",ich,
580  radbas[iw],radinc[iw]);
581  printf(" Ch Idx radinv (LOG)\n");
582  */
583  radinv[iw][0] = T_LOW;
584  /* for debug / info
585  printf(" %2d %3d %14.6E\n",ich, 1, radinv[iw][0]);
586  */
587  for (ip = 1; ip < NRADTAB; ip++) {
588  ttem = pow(10., radbas[iw] + radinc[iw] * (float) (ip));
589  radinv[iw][ip] = etinvert_(&ich, &ttem);
590  /* for debug / info
591  printf(" %2d %3d %14.6E\n",ich, ip+1, radinv[iw][ip]);
592  */
593  }
594  teminc[iw] = (T_HIGH - T_LOW) / (float) (NRADTAB - 1);
595  tembas[iw] = T_LOW;
596  /* for debug / info
597  printf(" Ch %1d tembas %14.6E teminc %14.6E\n",ich,
598  tembas[iw],teminc[iw]);
599  printf(" Ch Idx teminv\n");
600  */
601  teminv[iw][0] = etintegrate_(&ich, &radinv[iw][0]);
602  /* for debug / info
603  printf(" %2d %3d %14.6E\n",ich, 1, teminv[iw][0]);
604  */
605  for (ip = 1; ip < NRADTAB; ip++) {
606  ttem = tembas[iw] + (teminc[iw] * (float) (ip));
607  teminv[iw][ip] = etintegrate_(&ich, &ttem);
608  /* for debug / info
609  printf(" %2d %3d %14.6E\n",ich, ip+1, teminv[iw][ip]);
610  */
611  }
612  }
613 
614  status = avconsh_(&lunin, &npix, &jday);
615 
616  /* end first */
617  }
618 
619  /* if (scan == ldbg1) { */
620  /* printf(" got to scan 1780\n"); */
621  /* } */
622  /* check to see if this scan line is a different day than the previous */
623  if (scan > 0 && (scantime[scan] < scantime[scan - 1])) {
624  /* crossed to the next day */
625  jday = jday + 1;
626  if (jday > LY) {
627  /* crossed to the next year */
628  jday -= LY;
629  year = year + 1;
630  }
631  }
632 
633  l1rec->scantime = yds2unix(year, jday, (double) (scantime[scan] / 1.e3));
634 
635  /* Get position and path geometry */
636  READ_SDS_ID(sd_id_g, "Longitude", l1rec->lon, scan, spix, 0, 0, 1, npix, 1,
637  1);
638  READ_SDS_ID(sd_id_g, "Latitude", l1rec->lat, scan, spix, 0, 0, 1, npix, 1,
639  1);
640  READ_SDS_ID(sd_id_g, "Solar Zenith Angle", l1rec->solz, scan, spix, 0, 0, 1,
641  npix, 1, 1);
642  READ_SDS_ID(sd_id_g, "Sensor Zenith Angle", l1rec->senz, scan, spix, 0, 0,
643  1, npix, 1, 1);
644  READ_SDS_ID(sd_id_g, "Relative Azimuth Angle", l1rec->delphi, scan, spix, 0,
645  0, 1, npix, 1, 1);
646 
647  for (ip = 0; ip < npix; ip++) {
648 
649  l1rec->pixnum[ip] = spix + ip;
650 
651  if (l1rec->lon[ip] < -181.0 || l1rec->lon[ip] > 181.0
652  || l1rec->lat[ip] < -91.0 || l1rec->lat[ip] > 91.0)
653  l1rec->navfail[ip] = 1;
654  }
655 
656  /* Read L1B data, scale to radiance, and copy relevant bands to L1 record */
657  READ_SDS_ID(sd_id, SDNAME"1", ch1, scan, spix, 0, 0, 1, npix, 1, 1);
658  READ_SDS_ID(sd_id, SDNAME"2", ch2, scan, spix, 0, 0, 1, npix, 1, 1);
659  READ_SDS_ID(sd_id, SDNAME"3", ch3, scan, spix, 0, 0, 1, npix, 1, 1);
660  READ_SDS_ID(sd_id, SDNAME"4", ch4, scan, spix, 0, 0, 1, npix, 1, 1);
661  READ_SDS_ID(sd_id, SDNAME"5", ch5, scan, spix, 0, 0, 1, npix, 1, 1);
662 
663  /* This check should somehow check the scan line number to see if it's
664  * the first or last boxsiz/2 lines at the beginning or end of the file.
665  *
666  * I'm assuming the boxsiz is 3 so only the first line doesn't get
667  * processed and that this routine is called for each scan line in order
668  * from first to last.
669  *
670  */
671 
672  if (firstScan) {
673  firstScan = 0;
674  /* what else happens on first line? */
675  return (LIFE_IS_GOOD);
676  }
677 
678  ascan = (float) scan + 1.0; /* ascan is one based */
679  irun = -1;
680  idif = 99999;
681 
682  /* numcal and numraw should always be the same */
683  for (ip = 0; ip < runrec->numcal; ip++) {
684  if (abs((int)(runrec->runcal[ip].cenlin - ascan)) < idif) {
685  idif = abs((int)(runrec->runcal[ip].cenlin - ascan));
686  irun = ip;
687  }
688  }
689 
690  if (irun == -1 || idif > runrec->intrvl) {
691  printf("-W- %s line %d: Hey, I can't find the RUNCAL entry!\n",
692  __FILE__, __LINE__);
693  printf("-W- scan: %f; first center scan: %f; last: %f", ascan,
694  runrec->runcal[0].cenlin,
695  runrec->runcal[runrec->numcal - 1].cenlin);
696  if (irun == -1) {
697  if (ascan < runrec->runcal[1].cenlin) {
698  irun = 0;
699  } else {
700  irun = runrec->numcal - 1;
701  }
702  }
703  }
704  if (ascan > runrec->runcal[irun].cenlin) {
705  if (irun < runrec->numcal - 1) {
706  jrun = irun + 1; /* next available entry */
707  } else {
708  jrun = irun; /* duplicate */
709  }
710  } else {
711  jrun = irun; /* next entry */
712  if (irun > 0) {
713  irun = irun - 1; /* previous entry */
714  }
715  }
716 
717  iraw = irun; /* should be the same */
718  jraw = jrun;
719 
720  if (runrec->runcal[irun].cenlin != runrec->runcal[jrun].cenlin) {
721  percnt = (ascan - runrec->runcal[irun].cenlin)
722  / (runrec->runcal[jrun].cenlin - runrec->runcal[irun].cenlin);
723  if (percnt < 0.0) {
724  percnt = 0.0; /* earlier than first set */
725  } else if (percnt > 1.0) {
726  percnt = 1.0; /* later than last set */
727  }
728  } else {
729  percnt = 0.0; /* use first set, duplicates */
730  }
731 
732  /* Decommutate raw telemetry data for sensor calibration */
733 
734  iw = 0; /* Force initialization for group */
735  for (ii = 1; ii <= 30; ii++) {
736  if (ii > iw * 10) {
737  iw++; /* Initialize for next group */
738  for (jj = 0; jj < 2; jj++) {
739  sumbck[jj][iw - 1] = 0.0;
740  }
741  }
742  sumbck[0][iw - 1] += rawrec->rawcal[iraw].bckscn[0][vbcksc[ii - 1]]
743  * (1.0 - percnt)
744  + rawrec->rawcal[jraw].bckscn[0][vbcksc[ii - 1]] * (percnt);
745  sumbck[1][iw - 1] += rawrec->rawcal[iraw].bckscn[1][vbcksc[ii - 1]]
746  * (1.0 - percnt)
747  + rawrec->rawcal[jraw].bckscn[1][vbcksc[ii - 1]] * (percnt);
748  }
749  for (iw = 0; iw < 3; iw++) {
750  if (sumbck[0][iw] > 0.0) {
751  avgbck[iw] = sumbck[1][iw] / sumbck[0][iw];
752  } else {
753  avgbck[iw] = 0.0;
754  }
755  }
756 
757  iw = 0; /* Force initialization for group 1 */
758  for (ii = 1; ii <= 50; ii++) {
759  if (ii > iw * 10) {
760  iw++; /* Initialize for next group */
761  for (jj = 0; jj < 2; jj++) {
762  sumspc[jj][iw - 1] = 0.0;
763  }
764  }
765  sumspc[0][iw - 1] += rawrec->rawcal[iraw].space[0][vspace[ii - 1]]
766  * (1.0 - percnt)
767  + rawrec->rawcal[jraw].space[0][vspace[ii - 1]] * (percnt);
768  sumspc[1][iw - 1] += rawrec->rawcal[iraw].space[1][vspace[ii - 1]]
769  * (1.0 - percnt)
770  + rawrec->rawcal[jraw].space[1][vspace[ii - 1]] * (percnt);
771  }
772  for (iw = 0; iw < 3; iw++) {
773  if (sumspc[0][iw + 2] > 0.0) {
774  avgspc[iw] = sumspc[1][iw + 2] / sumspc[0][iw + 2];
775 
776  } else {
777  avgspc[iw] = 0.0;
778  }
779  }
780 
781  prtemp = (1.0 - percnt) * runrec->runcal[irun].prtemp
782  + (percnt) * runrec->runcal[jrun].prtemp;
783 
784  for (iw = 0; iw < 3; iw++) {
785  /* Convert temperature to radiance */
786  ttem = prtemp;
787  if (ttem < tembas[iw])
788  ttem = tembas[iw];
789  ai = (ttem - tembas[iw]) / teminc[iw];
790  if (ai < 0)
791  ai = 0;
792  else if (ai > NRADTAB)
793  ai = NRADTAB - 2;
794  ni = ai; /* whole part */
795  ai = ai - ni; /* fractional part */
796  radprt[iw] = (1.0 - ai) * teminv[iw][ni] + ai * teminv[iw][ni + 1];
797  }
798 
799  rspc[0] = 0.0;
800  switch (file->subsensorID) {
801  case NO07:
802  rspc[1] = -5.86;
803  rspc[2] = -4.95;
804  break;
805  case NO09:
806  rspc[1] = -5.53; /* Based on Table 2A; edited data, Apr 93 */
807  rspc[2] = -3.06;
808  break;
809  case NO10:
810  rspc[1] = -7.29; /* Based on Rao memo, Jan 4, 94 */
811  rspc[2] = -7.29;
812  break;
813  case NO11:
814  rspc[1] = -8.05; /* Based on Rao memo, Jan 4, 94 */
815  rspc[2] = -3.51;
816  break;
817  case NO12:
818  rspc[1] = -5.51; /* Based on Rao memo, Jan 4, 94 */
819  rspc[2] = -2.51;
820  break;
821  case NO14:
822  rspc[1] = -4.05; /* Based on S. Brown memo, Nov 22, 94 */
823  rspc[2] = -2.29;
824  break;
825  case NO15:
826  rspc[1] = -4.50; /* Based on Draft KLM, app D.1-14 */
827  rspc[2] = -3.61;
828  break;
829  case NO16:
830  rspc[1] = -2.467; /* Based on Draft KLM, app D.2-15 */
831  rspc[2] = -2.009;
832  break;
833  case NO17:
834  rspc[1] = -8.55; /* Based on Draft KLM, app D.3-2 */
835  rspc[2] = -3.97;
836  break;
837  case NO18:
838  rspc[1] = -5.53; /* Based on Draft KLM, app D.4-2 */
839  rspc[2] = -2.22;
840  break;
841  case NO19:
842  rspc[1] = -5.49; /* Based on Draft KLM, app D.6-2 */
843  rspc[2] = -3.39;
844  break;
845  default:
846  rspc[1] = -99.;
847  rspc[2] = -99.;
848  }
849 
850  /* noaa-16,17,18,19 have channel 3a and 3b */
851  /* 3a is 1.6 um during the day */
852  /* 3b is 3.75 um at night */
853  /* earlier avhrr satellites just have the 3.75 um (day and night) */
854  /* so process channel 3 as visible during the day, and IR at night */
855  for (iw = 0; iw < nbands + 1; iw++) {
856 
857  switch (iw) {
858  case 0:
859  data = ch1;
860  break;
861  case 1:
862  data = ch2;
863  break;
864  case 2:
865  data = ch3;
866  break;
867  }
868 
869  for (ip = 0; ip < npix; ip++) {
870 
871  ipb = ip * nbands + iw;
872  l1rec->Lt[ipb] = 0.0;
873 
874  /* check for sentinel values and flag as appropriate */
875  if (data[ip] >= 32000) {
876 
877  switch (data[ip]) {
878 
879  default:
880  l1rec->hilt[ip] = 1;
881  l1rec->Lt[ipb] = 1000.0;
882  break;
883  }
884 
885  } else if (l1rec->solz[ip] < SOLZNIGHTA) {
886  /* only do channels 1 and 2 for daytime pixels */
887  /* only do channel 3 for daytime for noaa-16,17,18,19 */
888  if (iw == 2 && file->subsensorID != NO16 && file->subsensorID != NO17 &&
889  file->subsensorID != NO18 && file->subsensorID != NO19) {
890  /* this channel doesn't make the pixel bad */
891  // l1rec->hilt[ip] = 1;
892  l1rec->Lt[ipb] = 1000.0;
893  } else {
894  status = avlooph_(&l1rec->senz[ip], &l1rec->solz[ip],
895  &l1rec->delphi[ip], rayly, aersol,
896  &l1rec->glint_coef[ip]);
897 
898  trad = (data[ip] * m[iw]) + b[iw];
899  trad -= rayly[iw];
900 
901  if (aersol[iw] != 0.0) {
902  trad /= aersol[iw];
903  }
904  /* aermlt in pathnlc is 1.0 so we don't need it here */
905 
906  l1rec->Lt[ipb] = trad;
907  }
908  }
909  }
910  }
911 
912  for (iw = 0; iw < nbandsir; iw++) {
913 
914  switch (iw) {
915  case 0:
916  data = ch3;
917  break;
918  case 1:
919  data = ch4;
920  break;
921  case 2:
922  data = ch5;
923  break;
924  }
925 
926  for (ip = 0; ip < npix; ip++) {
927 
928  ipb = ip * NBANDSIR + iw;
929  l1rec->Ltir[ipb] = 0.0;
930  l1rec->Bt[ipb] = BT_LO;
931 
932  /* don't do channel 3 for daytime for noaa-16,17,18,19 */
933  if (iw == 0 && l1rec->solz[ip] < SOLZNIGHTA
934  && (file->subsensorID == NO16
935  || file->subsensorID == NO17
936  || file->subsensorID == NO18
937  || file->subsensorID == NO19)) {
938  continue;
939  } else {
940 
941  /* check for sentinel values and flag as appropriate */
942  if (data[ip] >= 32000) {
943 
944  switch (data[ip]) {
945 
946  default:
947  l1rec->hilt[ip] = 1;
948  l1rec->Lt[ipb] = 1000.0;
949  break;
950  }
951 
952  } else {
953  // if (ip == pdbg1 && scan == ldbg1) {
954  // printf(" got to 320,40\n");
955  // }
956  /* Miami calibration */
957  if (avgbck[iw] != avgspc[iw]) {
958  if (l1_input->newavhrrcal == 1
959  && file->subsensorID == NO16
960  && iw > 0) {
961  /* Jon Mittaz's calibration for ch4 and ch5 */
962  /* T_inst = prtemp, R_ICT = radprt[iw] */
963  /* C_S = avgspc[iw], C_BB = avgbck[iw] */
964  /* C = data[ip] */
965  if (iw == 1) {
966  /* avhrr channel 4 Bt11 */
967  if (ip == pdbg1 && scan == ldbg1) {
968  printf(" ch4_coeffs=%f %f %f %f %f\n",
969  ch4_coeff[0], ch4_coeff[1],
970  ch4_coeff[2], ch4_coeff[3],
971  ch4_coeff[4]);
972  printf(" T_inst, prtemp = %f \n", prtemp);
973  printf(" R_ICT, radprt = %f \n",
974  radprt[iw]);
975  printf(" C_S, avgspc = %f \n", avgspc[iw]);
976  printf(" C_BB, avgbck = %f \n", avgbck[iw]);
977  printf(" C, data = %d \n", data[ip]);
978  }
979  trad = ch4_coeff[0] * (prtemp - 288.) + ch4_coeff[1]
980  + ((((ch4_coeff[2] * radprt[iw]) - (ch4_coeff[3]
981  * (pow(avgspc[iw] - avgbck[iw], 2.0))))
982  / (avgspc[iw] - avgbck[iw])) * (avgspc[iw] - data[ip]))
983  + ch4_coeff[4] * (pow(avgspc[iw] - data[ip], 2.0));
984  } else if (iw == 2) {
985  /* avhrr channel 5 Bt12 */
986  if (ip == pdbg1 && scan == ldbg1) {
987  printf(" ch5_coeffs=%f %f %f %f %f\n",
988  ch5_coeff[0], ch5_coeff[1],
989  ch5_coeff[2], ch5_coeff[3],
990  ch5_coeff[4]);
991  printf(" T_inst, prtemp = %f \n", prtemp);
992  printf(" R_ICT, radprt = %f \n",
993  radprt[iw]);
994  printf(" C_S, avgspc = %f \n", avgspc[iw]);
995  printf(" C_BB, avgbck = %f \n", avgbck[iw]);
996  printf(" C, data = %d \n", data[ip]);
997  }
998  trad = ch5_coeff[0] * (prtemp - 288.) + ch5_coeff[1]
999  + ((((ch5_coeff[2] * radprt[iw]) - (ch5_coeff[3]
1000  * (pow(avgspc[iw] - avgbck[iw], 2.0))))
1001  / (avgspc[iw] - avgbck[iw])) * (avgspc[iw] - data[ip]))
1002  + ch5_coeff[4] * (pow(avgspc[iw] - data[ip], 2.0));
1003  }
1004 
1005  } else {
1006  trad = radprt[iw] * (avgspc[iw] - data[ip])
1007  / (avgspc[iw] - avgbck[iw])
1008  + rspc[iw] * (avgbck[iw] - data[ip])
1009  / (avgbck[iw] - avgspc[iw]);
1010  if (iw == 1) {
1011  /* apply non-linearity correction for channel 4 */
1012  switch (file->subsensorID) {
1013  case NO07:
1014  tnlc = 5.7843 - 1.0754e-1 * trad + 4.8042e-4 * pow(trad, 2);
1015  break;
1016  case NO09: /* Based on Table 2A; edited data, Apr 93 */
1017  tnlc = 5.24 + (.88643 - 1.) * trad + 6.033e-4 * pow(trad, 2);
1018  break;
1019  case NO10: /* Based on Rao memo, Jan 4, 94 */
1020  tnlc = 5.76 + (.88428 - 1.) * trad + 5.882e-4 * pow(trad, 2);
1021  break;
1022  case NO11: /* Based on Rao memo, Jan 4, 94 */
1023  tnlc = 7.21 + (.8412 - 1.) * trad + 8.739e-4 * pow(trad, 2);
1024  break;
1025  case NO12: /* Based on Rao memo, Jan 4, 94 */
1026  tnlc = 5.11 + (.88929 - 1.) * trad + 5.968e-4 * pow(trad, 2);
1027  break;
1028  case NO14: /* Based on S. Brown memo, Nov 22, 94 */
1029  tnlc = 3.72 + (.92378 - 1.) * trad
1030  + 3.822e-4 * pow(trad, 2);
1031  break;
1032  case NO15: /* Based on Draft KLM, app D.1-14 */
1033  tnlc = 4.76 + (-0.0932) * trad + 4.524e-4 * pow(trad, 2);
1034  break;
1035  case NO16: /* Based on Draft KLM, app D.2-15 */
1036  tnlc = 2.96 + (-0.05411) * trad + 2.4532e-4 * pow(trad, 2);
1037  break;
1038  case NO17: /* Based on Draft KLM, app D.3-2 */
1039  tnlc = 8.22 + (-0.15795) * trad + 7.5579e-4 * pow(trad, 2);
1040  break;
1041  case NO18: /* Based on Draft KLM, app D.4-2 */
1042  tnlc = 5.82 + (-0.11069) * trad + 5.2337e-4 * pow(trad, 2);
1043  break;
1044  case NO19: /* Based on Draft KLM, app D.6-2 */
1045  tnlc = 5.70 + (-0.11187) * trad + 5.4668e-4 * pow(trad, 2);
1046  break;
1047  default:
1048  tnlc = -99.;
1049  }
1050  trad += tnlc;
1051  } else if (iw == 2) {
1052  /* apply non-linearity correction for channel 5 */
1053  switch (file->subsensorID) {
1054  case NO07:
1055  tnlc = 4.4035 - 6.9038e-2 * trad + 2.5741e-4 * pow(trad, 2);
1056  break;
1057  case NO09: /* Based on Table 2A; edited data, Apr 93 */
1058  tnlc = 2.42 + (.95311 - 1.) * trad + 2.198e-4 * pow(trad, 2);
1059  break;
1060  case NO10: /* Based on Rao memo, Jan 4, 94 */
1061  tnlc = 5.76 + (.88428 - 1.) * trad + 5.882e-4 * pow(trad, 2);
1062  break;
1063  case NO11: /* Based on Rao memo, Jan 4, 94 */
1064  tnlc = 2.92 + (.94598 - 1.) * trad + 2.504e-4 * pow(trad, 2);
1065  break;
1066  case NO12: /* Based on Rao memo, Jan 4, 94 */
1067  tnlc = 1.91 + (.96299 - 1.) * trad + 1.775e-4 * pow(trad, 2);
1068  break;
1069  case NO14: /* Based on S. Brown memo, Nov 22, 94 */
1070  tnlc = 2.00 + (.96194 - 1.) * trad + 1.742e-4 * pow(trad, 2);
1071  break;
1072  case NO15: /* Based on Draft KLM, app D.1-14 */
1073  tnlc = 3.83 + (-0.0659) * trad + 2.811e-4 * pow(trad, 2);
1074  break;
1075  case NO16: /* Based on Draft KLM, app D.2-15 */
1076  tnlc = 2.25 + (-0.03665) * trad + 1.4854e-4 * pow(trad, 2);
1077  break;
1078  case NO17: /* Based on Draft KLM, app D.3-2 */
1079  tnlc = 4.31 + (-0.07318) * trad + 3.0976e-4 * pow(trad, 2);
1080  break;
1081  case NO18: /* Based on Draft KLM, app D.4-2 */
1082  tnlc = 2.67 + (-0.04360) * trad + 1.7715e-4 * pow(trad, 2);
1083  break;
1084  case NO19: /* Based on Draft KLM, app D.6-2 */
1085  tnlc = 3.58 + (-0.05991) * trad + 2.4985e-4 * pow(trad, 2);
1086  break;
1087  default:
1088  tnlc = -99.;
1089  }
1090  trad += tnlc;
1091  }
1092  }
1093 
1094  if (ip == pdbg1 && scan == ldbg1) {
1095  printf(" ch %d trad = %f\n", iw + 3, trad);
1096  printf(" newavhrrcal = %d\n",
1097  l1_input->newavhrrcal);
1098  printf(" xsatid = %d NO16=%d\n",
1099  file->subsensorID, NO16);
1100  }
1101  /* convert radiance to temperature */
1102  if (trad < 1.e-10)
1103  trad = 1.e-10;
1104  if (radinc[iw] != 0.0)
1105  ai = (log10(trad) - radbas[iw]) / radinc[iw];
1106  else
1107  ai = NRADTAB - 1;
1108  if (ai < 0.0)
1109  ai = 0.0;
1110  else if (ai >= NRADTAB - 1)
1111  ai = NRADTAB - 2;
1112  ni = ai; /* whole part */
1113  ai = ai - ni; /* fractional part */
1114  ttem = (1.0 - ai) * radinv[iw][ni] + ai * radinv[iw][ni + 1];
1115  if (ip == pdbg1 && scan == ldbg1) {
1116  printf(" ch %d ttem = %f\n", iw + 3, ttem);
1117  }
1118  if (l1_input->newavhrrcal
1119  == 1 && file->subsensorID == NO16) {
1120  /* convert Mittaz Bt's to old so we can test sst with old coeffs */
1121  // if (iw == 1) {
1122  // /* convert Mittaz Bt11 to old so we can test sst with old coeffs */
1123  // tcor = -10.306526 + 0.068776865*ttem - 0.00010926801*pow(ttem,2);
1124  // /* tcor is Walton-Mittaz so add Mittaz to get Walton */
1125  // ttem = ttem + tcor;
1126  // } else if (iw == 2) {}
1127  if (iw == 2) {
1128  /* use ch5 (Bt12) correction for ch4 (Bt11) also */
1129  /* convert Mittaz Bt12 to old so we can test sst with old coeffs */
1130  tcor = -6.9176245 + 0.038554339 * ttem - 4.7661371e-05 * pow(ttem, 2);
1131  /* tcor is Walton-Mittaz so add Mittaz to get Walton */
1132  ttem = ttem + tcor;
1133  /* add ch5 correction to ch4 also */
1134  /* ipb is ip*NBANDSIR+iw, so ch4 should be ipb-1 */
1135  l1rec->Bt[ipb - 1] = l1rec->Bt[ipb - 1] + tcor;
1136  if (ip == pdbg1 && scan == ldbg1) {
1137  printf(" real ch = %d, ttem = %f, tcor = %f\n", iw + 3 - 1, ttem, tcor);
1138  }
1139  }
1140  if (ip == pdbg1 && scan == ldbg1) {
1141  printf(" ch = %d, ttem = %f, tcor = %f\n", iw + 3, ttem, tcor);
1142  }
1143  }
1144  ttem = ttem - TEMP_REF; /* convert from Deg K to Deg C */
1145  l1rec->Bt[ipb] = ttem;
1146  }
1147  /* put top of the atmosphere counts in Ltir */
1148  l1rec->Ltir[ipb] = data[ip];
1149  // l1rec->prtemp[ip] = prtemp - TEMP_REF;
1150 
1151  }
1152  }
1153  }
1154  }
1155 
1156  l1rec->npix = file->npix;
1157  l1rec->detnum = (int32_t) detnum;
1158  l1rec->mside = 0;
1159 
1160  /* Convert IR bands to brightness temperature */
1161  // radiance2bt(l1rec,-1);
1162  return (LIFE_IS_GOOD);
1163 }
1164 
1165 int closel1_aci(filehandle *file) {
1166  if ((sd_id_g != sd_id) && SDend(sd_id_g)) {
1167  fprintf(stderr, "-E- %s line %d: SDend(%d) failed for file, %s.\n",
1168  __FILE__, __LINE__, sd_id, file->geofile);
1169  return (HDF_FUNCTION_ERROR);
1170  }
1171  if (SDend(sd_id)) {
1172  fprintf(stderr, "-E- %s line %d: SDend(%d) failed for file, %s.\n",
1173  __FILE__, __LINE__, sd_id, file->name);
1174  return (HDF_FUNCTION_ERROR);
1175  }
1176 
1177  return (LIFE_IS_GOOD);
1178 }
1179 
1180 const char* xsatid2name(int xsatid) {
1181  switch (xsatid) {
1182  case NO06:
1183  return "NO06";
1184  case NO07:
1185  return "NO07";
1186  case NO08:
1187  return "NO08";
1188  case NO09:
1189  return "NO09";
1190  case NO10:
1191  return "NO10";
1192  case NO11:
1193  return "NO11";
1194  case NO12:
1195  return "NO12";
1196  case NO14:
1197  return "NO14";
1198  case NO15:
1199  return "NO15";
1200  case NO16:
1201  return "NO16";
1202  case NO17:
1203  return "NO17";
1204  case NO18:
1205  return "NO18";
1206  case NO19:
1207  return "NO19";
1208  default:
1209  return "UNKNOWN";
1210  }
1211 }
1212 
1213 int satname2xsatid(const char* satname) {
1214  if (strcmp(satname, "NOA6") == 0)
1215  return NO06;
1216  else if (strcmp(satname, "NOA7") == 0)
1217  return NO07;
1218  else if (strcmp(satname, "NOA8") == 0)
1219  return NO08;
1220  else if (strcmp(satname, "NOA9") == 0)
1221  return NO09;
1222  else if (strcmp(satname, "NO10") == 0)
1223  return NO10;
1224  else if (strcmp(satname, "NO11") == 0)
1225  return NO11;
1226  else if (strcmp(satname, "NO12") == 0)
1227  return NO12;
1228  else if (strcmp(satname, "NO14") == 0)
1229  return NO14;
1230  else if (strcmp(satname, "NO15") == 0)
1231  return NO15;
1232  else if (strcmp(satname, "NO16") == 0)
1233  return NO16;
1234  else if (strcmp(satname, "NO17") == 0)
1235  return NO17;
1236  else if (strcmp(satname, "NO18") == 0)
1237  return NO18;
1238  else if (strcmp(satname, "NO19") == 0)
1239  return NO19;
1240  else
1241  return -999;
1242 }
1243 
int32_t avconsh_(int32_t *lunin, int32_t *npix, int32_t *jday)
#define NAVBANDS
Definition: l1_aci.c:18
#define NO14
Definition: l1_aci.h:12
Definition: rawcal.h:84
int rdSDS(int32_t fileID, const char sdsname[], int32_t start1, int32_t start2, int32_t edges1, int32_t edges2, void *array_data)
int32_t day
int status
Definition: l1_czcs_hdf.c:32
double yds2unix(int16_t year, int16_t day, double secs)
Definition: yds2unix.c:7
#define NO06
Definition: l1_aci.h:5
#define NBANDSIR
Definition: filehandle.h:23
int satname2xsatid(const char *satname)
Definition: l1_aci.c:1213
#define NO19
Definition: l1_aci.h:17
#define FAIL
Definition: ObpgReadGrid.h:18
#define NULL
Definition: decode_rs.h:63
#define NO16
Definition: l1_aci.h:14
MOD_PR01 Production producing one five minute granule of output data in each run It can be configured to produce as many as three five minute granules per run Each execution with one construction record and one date file for each dataset In normal these are created by which splits them out of the hour datasets For LANCE they are created by which merges all session MODIS L0 datasets overlapping the requested time and extracts from the merged data those packets which fall within that time period Each scan of data is stored in the L1A granule that covers the start time of that scan
Definition: MOD_PR01_pr.txt:19
read l1rec
void etloadresp_(int32_t *lin, char *cal)
int32_t jday(int16_t i, int16_t j, int16_t k)
Converts a calendar date to the corresponding Julian day starting at noon on the calendar date....
Definition: jday.c:14
int32 nscan
Definition: l1_czcs_hdf.c:19
#define READ_SDS_ID(sd_id, nam, ptr, s0, s1, s2, s3, e0, e1, e2, e3)
Definition: hdf4utils.h:109
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
character(len=1000) if
Definition: names.f90:13
#define LIFE_IS_GOOD
Definition: passthebuck.h:4
int getDims(int32_t fileID, const char sdsname[], int32_t dims[])
#define NO12
Definition: l1_aci.h:11
float etinvert_(int32_t *ich, float *radi)
Definition: runcal.h:81
#define NO17
Definition: l1_aci.h:15
#define NO09
Definition: l1_aci.h:8
l1_input_t * l1_input
Definition: l1_options.c:9
int getHDFattr(int32_t fileID, const char attrname[], const char sdsname[], void *data)
#define NO08
Definition: l1_aci.h:7
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
#define NO11
Definition: l1_aci.h:10
data_t b[NROOTS+1]
Definition: decode_rs.h:77
int closel1_aci(filehandle *file)
Definition: l1_aci.c:1165
const char * xsatid2name(int xsatid)
Definition: l1_aci.c:1180
#define NRADTAB
Definition: l1_aci.c:24
float etintegrate_(int32_t *ich, float *etemp)
int32_t nbands
int readl1_aci(filehandle *file, int32_t scan, l1str *l1rec)
Definition: l1_aci.c:136
int32_t avlooph_(float *satz, float *solz, float *delphi, float *rayly, float *aersol, float *aglint)
Extra metadata that will be written to the HDF4 file l2prod rank
#define SDNAME
Definition: l1_aci.c:26
#define BT_LO
Definition: l1.h:55
int32_t ch4
Definition: atrem_corl1.h:118
#define NO07
Definition: l1_aci.h:6
#define SOLZNIGHTA
Definition: l1.h:59
#define TEMP_REF
Definition: l1_aci.c:22
logical function leap(YEAR)
Definition: leap.f:10
int openl1_aci(filehandle *file)
Definition: l1_aci.c:57
#define abs(a)
Definition: misc.h:90
#define NO18
Definition: l1_aci.h:16
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int npix
Definition: get_cmp.c:28
#define HDF_FUNCTION_ERROR
Definition: passthebuck.h:7
#define NO10
Definition: l1_aci.h:9
#define NO15
Definition: l1_aci.h:13