OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
xcal.c
Go to the documentation of this file.
1 #include "xcal.h"
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 
6 #include <mfhdf.h>
7 
8 static int *xcal_wave;
9 static int nband = 0;
10 static int nwave;
11 static double pixwt = 1.0;
12 static int detfac = 1;
13 
14 int xcal_band(int wave) {
15  int iband = -1;
16  int iw;
17  static int firstCall = 1;
18 
19  if (firstCall) {
20  if ((xcal_wave = (int *) calloc(nwave, sizeof (int))) == NULL) {
21  printf("-E- : Error allocating memory to run_soa_sma\n");
22  exit(EXIT_FAILURE);
23  }
24  firstCall = 0;
25  }
26  for (iw = 0; iw < nband; iw++)
27  if (xcal_wave[iw] == wave)
28  iband = iw;
29 
30  return (iband);
31 }
32 
33 double *get_xcal(l1str *l1rec, int type, int wave) {
34  typedef double m_array[XTNMSIDE][XTNDET][MAXPIX];
35  static m_array *rvs, *m12, *m13;
36 
37  int bandnum;
38 
39  static int firstCall = 1;
40  int32_t ic, ip, im, id, it, it1, it2;
41  int32_t ncoef = 0, ntime = 0, ndet = 0, nmside = 0;
42 
43  if (firstCall == 1) {
44  nwave = l1rec->l1file->nbands;
45  if ((m12 = (m_array *) calloc(nwave, sizeof (m_array))) == NULL) {
46  printf("-E- : Error allocating memory to dray_for_i\n");
47  exit(EXIT_FAILURE);
48  }
49  if ((m13 = (m_array *) calloc(nwave, sizeof (m_array))) == NULL) {
50  printf("-E- : Error allocating memory to dray_for_i\n");
51  exit(EXIT_FAILURE);
52  }
53  if ((rvs = (m_array *) calloc(nwave, sizeof (m_array))) == NULL) {
54  printf("-E- : Error allocating memory to dray_for_i\n");
55  exit(EXIT_FAILURE);
56  }
57  firstCall = 0;
58  }
59  if ((bandnum = xcal_band(wave)) < 0) {
60 
61  double rvstab[XTNORDER][XTNDET][XTNMSIDE][XTNTIME];
62  double m12tab[XTNORDER][XTNDET][XTNMSIDE][XTNTIME];
63  double m13tab[XTNORDER][XTNDET][XTNMSIDE][XTNTIME];
64  int16_t yrtab [XTNTIME];
65  int16_t dytab [XTNTIME];
66  double sectab[XTNTIME];
67 
68  int32_t sensorID = l1rec->l1file->sensorID;
69  double rvsc1[XTNORDER];
70  double rvsc2[XTNORDER];
71  double m12c1[XTNORDER];
72  double m12c2[XTNORDER];
73  double m13c1[XTNORDER];
74  double m13c2[XTNORDER];
75  double ap, ap2, ap3, ap4, ap5, x1, x2;
76  double sec, wt;
77 
78  char *file;
79  file = (char *) calloc(FILENAME_MAX, sizeof (char)); //[FILENAME_MAX] = "";
80  char *name;
81  name = (char *) calloc(H4_MAX_NC_NAME, sizeof (char)); //[H4_MAX_NC_NAME] = "";
82  char *sdsname;
83  sdsname = (char *) calloc(H4_MAX_NC_NAME, sizeof (char)); //[H4_MAX_NC_NAME] = "";
84  int32_t sd_id;
85  int32_t rank;
86  int32_t nt;
87  int32_t dims[H4_MAX_VAR_DIMS];
88  int32_t nattrs;
89  int32_t sds_id;
90  int32_t start[5] = {0, 0, 0, 0, 0};
91  int32_t end [5] = {1, 1, 1, 1, 1};
92  int32_t status;
93 
94  bandnum = nband++;
95  xcal_wave[bandnum] = wave;
96 
97  sprintf(file, "%s%s%d%s", l1_input->xcal_file, "_", wave, ".hdf");
98 
99  printf("Loading XCAL rvs and polarization sensitivities from %s\n", file);
100 
101  sd_id = SDstart(file, DFACC_RDONLY);
102  if (sd_id == FAIL) {
103  fprintf(stderr, "-E- %s line %d: SDstart(%s, %d) failed.\n",
104  __FILE__, __LINE__, file, DFACC_RDONLY);
105  exit(1);
106  }
107 
108  status = SDreadattr(sd_id, SDfindattr(sd_id, "Number of Coefficients"), &ncoef);
109  if (status != 0) {
110  printf("-E- %s Line %d: Error reading global attribute %s from %s.\n",
111  __FILE__, __LINE__, "Number of Coefficients", file);
112  exit(1);
113  }
114  if (ncoef > XTNORDER) {
115  printf("-E- %s Line %d: mismatch in ncoef\n", __FILE__, __LINE__);
116  exit(1);
117  }
118 
119  status = SDreadattr(sd_id, SDfindattr(sd_id, "Number of Detectors"), &ndet);
120  if (status != 0) {
121  printf("-E- %s Line %d: Error reading global attribute %s from %s.\n",
122  __FILE__, __LINE__, "Number of Detectors", file);
123  exit(1);
124  }
125  if (ndet > XTNDET) {
126  printf("-E- %s Line %d: mismatch in ndet\n", __FILE__, __LINE__);
127  exit(1);
128  }
129 
130  status = SDreadattr(sd_id, SDfindattr(sd_id, "Number of Mirror Sides"), &nmside);
131  if (status != 0) {
132  printf("-E- %s Line %d: Error reading global attribute %s from %s.\n",
133  __FILE__, __LINE__, "Number of Mirror Sides", file);
134  exit(1);
135  }
136  if (nmside > XTNMSIDE) {
137  printf("-E- %s Line %d: mismatch in nmside\n", __FILE__, __LINE__);
138  exit(1);
139  }
140 
141  status = SDreadattr(sd_id, SDfindattr(sd_id, "Length of Time Series ndates"), &ntime);
142  if (status != 0) {
143  printf("-E- %s Line %d: Error reading global attribute %s from %s.\n",
144  __FILE__, __LINE__, "Length of Time Series ndates", file);
145  exit(1);
146  }
147  if (ntime > XTNTIME) {
148  printf("-E- %s Line %d: mismatch in ntime\n", __FILE__, __LINE__);
149  exit(1);
150  }
151 
152  strcpy(sdsname, "year");
153  start[0] = 0;
154  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
155  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
156  status = SDreaddata(sds_id, start, NULL, dims, (VOIDP) yrtab);
157  if (status != 0) {
158  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
159  __FILE__, __LINE__, sdsname, file);
160  exit(1);
161  } else {
162  status = SDendaccess(sds_id);
163  }
164 
165  strcpy(sdsname, "day");
166  start[0] = 0;
167  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
168  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
169  status = SDreaddata(sds_id, start, NULL, dims, (VOIDP) dytab);
170  if (status != 0) {
171  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
172  __FILE__, __LINE__, sdsname, file);
173  exit(1);
174  } else {
175  status = SDendaccess(sds_id);
176  }
177 
178  strcpy(sdsname, "M11");
179  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
180  for (ic = 0; ic < ncoef; ic++) for (id = 0; id < ndet; id++) for (im = 0; im < nmside; im++) for (it = 0; it < ntime; it++) {
181  start[0] = ic;
182  start[1] = id;
183  start[2] = im;
184  start[3] = it;
185  status = SDreaddata(sds_id, start, NULL, end, (VOIDP) & rvstab[ic][id][im][it]);
186  if (status != 0) {
187  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
188  __FILE__, __LINE__, sdsname, file);
189  exit(1);
190  }
191  }
192  status = SDendaccess(sds_id);
193 
194  strcpy(sdsname, "m12");
195  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
196  for (ic = 0; ic < ncoef; ic++) for (id = 0; id < ndet; id++) for (im = 0; im < nmside; im++) for (it = 0; it < ntime; it++) {
197  start[0] = ic;
198  start[1] = id;
199  start[2] = im;
200  start[3] = it;
201  status = SDreaddata(sds_id, start, NULL, end, (VOIDP) & m12tab[ic][id][im][it]);
202  if (status != 0) {
203  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
204  __FILE__, __LINE__, sdsname, file);
205  exit(1);
206  }
207  }
208  status = SDendaccess(sds_id);
209 
210  strcpy(sdsname, "m13");
211  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
212  for (ic = 0; ic < ncoef; ic++) for (id = 0; id < ndet; id++) for (im = 0; im < nmside; im++) for (it = 0; it < ntime; it++) {
213  start[0] = ic;
214  start[1] = id;
215  start[2] = im;
216  start[3] = it;
217  status = SDreaddata(sds_id, start, NULL, end, (VOIDP) & m13tab[ic][id][im][it]);
218  if (status != 0) {
219  printf("-E- %s Line %d: Error reading SDS %s from %s.\n",
220  __FILE__, __LINE__, sdsname, file);
221  exit(1);
222  }
223  }
224  status = SDendaccess(sds_id);
225 
226  status = SDend(sd_id);
227 
228 
229  for (it = 0; it < ntime; it++) {
230  if (yrtab[it] > 0)
231  sectab[it] = yds2unix(yrtab[it], dytab[it], 0.0);
232  else
233  break;
234  }
235  if (it != ntime) {
236  printf("-E- %s line %d: time field mismatch %d %d\n", __FILE__, __LINE__, it, ntime);
237  exit(1);
238  }
239 
240  sec = l1rec->scantime;
241  for (it = 0; it < ntime; it++) {
242  if (sectab[it] > sec) break;
243  }
244  if (it == 0)
245  it2 = it1 = it;
246  else if (it == ntime)
247  it2 = it1 = ntime - 1;
248  else {
249  it2 = MAX(MIN(it, ntime - 1), 1);
250  it1 = it2 - 1;
251  }
252 
253  for (im = 0; im < nmside; im++) for (id = 0; id < ndet; id++) {
254 
255  for (ic = 0; ic < ncoef; ic++) {
256  rvsc1[ic] = rvstab[ic][id][im][it1];
257  m12c1[ic] = m12tab[ic][id][im][it1];
258  m13c1[ic] = m13tab[ic][id][im][it1];
259  rvsc2[ic] = rvstab[ic][id][im][it2];
260  m12c2[ic] = m12tab[ic][id][im][it2];
261  m13c2[ic] = m13tab[ic][id][im][it2];
262  }
263  for (ic = ncoef; ic < XTNORDER; ic++) {
264  rvsc1[ic] = 0;
265  m12c1[ic] = 0;
266  m13c1[ic] = 0;
267  rvsc2[ic] = 0;
268  m12c2[ic] = 0;
269  m13c2[ic] = 0;
270  }
271 
272  if (it2 == it1)
273  wt = 0.0;
274  else
275  wt = (sec - sectab[it1]) / (sectab[it2] - sectab[it1]);
276 
277  if (sensorID == MODISA || sensorID == MODIST) {
278  switch (l1_input->resolution) {
279  case 250:
280  pixwt = 0.25;
281  detfac = 4;
282  break;
283  case 500:
284  pixwt = 0.5;
285  detfac = 2;
286  break;
287  }
288  }
289 
290  for (ip = 0; ip < l1rec->npix; ip++) {
291 
292  ap = (double) l1rec->pixnum[ip] * pixwt;
293  ap2 = ap*ap;
294  ap3 = ap2*ap;
295  ap4 = ap3*ap;
296  ap5 = ap4*ap;
297 
298  x1 = rvsc1[0] + ap * rvsc1[1] + ap2 * rvsc1[2] + ap3 * rvsc1[3] + ap4 * rvsc1[4] + ap5 * rvsc1[5];
299  x2 = rvsc2[0] + ap * rvsc2[1] + ap2 * rvsc2[2] + ap3 * rvsc2[3] + ap4 * rvsc2[4] + ap5 * rvsc2[5];
300  rvs[bandnum][im][id][ip] = x1 + wt * (x2 - x1);
301 
302  x1 = m12c1[0] + ap * m12c1[1] + ap2 * m12c1[2] + ap3 * m12c1[3] + ap4 * m12c1[4] + ap5 * m12c1[5];
303  x2 = m12c2[0] + ap * m12c2[1] + ap2 * m12c2[2] + ap3 * m12c2[3] + ap4 * m12c2[4] + ap5 * m12c2[5];
304  m12[bandnum][im][id][ip] = x1 + wt * (x2 - x1);
305 
306  x1 = m13c1[0] + ap * m13c1[1] + ap2 * m13c1[2] + ap3 * m13c1[3] + ap4 * m13c1[4] + ap5 * m13c1[5];
307  x2 = m13c2[0] + ap * m13c2[1] + ap2 * m13c2[2] + ap3 * m13c2[3] + ap4 * m13c2[4] + ap5 * m13c2[5];
308  m13[bandnum][im][id][ip] = x1 + wt * (x2 - x1);
309  }
310  }
311  free(file);
312  free(name);
313  free(sdsname);
314  }
315 
316  if (l1rec->mside > 1)
317  return 0x0;
318 
319  switch (type) {
320  case XRVS: return (&rvs[bandnum][l1rec->mside][l1rec->detnum / detfac][0]);
321  break;
322  case XM12: return (&m12[bandnum][l1rec->mside][l1rec->detnum / detfac][0]);
323  break;
324  case XM13: return (&m13[bandnum][l1rec->mside][l1rec->detnum / detfac][0]);
325  break;
326  default:
327  printf("-E- %s line %d: bad xcal type specified\n", __FILE__, __LINE__);
328  exit(1);
329  }
330 
331 
332 }
333 
334 double *get_fpm_xcal(char *fpm_file)
335 {
336  FILE *fp;
337  char *line = NULL;
338  char *ptr = NULL;
339  double *fpm_gains = NULL;
340  size_t bufsz = 100;
341  ssize_t llen;
342  int nbands, nsca;
343  int linenum, isca, ib, isb;
344 
345  if ((fp = fopen(fpm_file,"r")) == NULL)
346  {
347  printf("-E- %s line %d: Cannot open fpm xcal file %s\n",__FILE__,__LINE__, fpm_file);
348  exit(1);
349  }
350  if ((line = calloc(bufsz,sizeof(char))) == NULL)
351  {
352  printf("-E- %s line %d: Cannot allocate memory for line buffer\n",__FILE__,__LINE__);
353  exit(1);
354  }
355 
356  linenum = 0;
357  isca = 0;
358  while((llen = getline(&line, &bufsz, fp)) != -1)
359  {
360  if (linenum == 0)
361  {
362  if (strstr(line,"FPM") == NULL)
363  {
364  printf("-E- %s line %d: Missing FPM numbers in the first line of fpm xcal file %s\n",__FILE__,__LINE__, fpm_file);
365  exit(1);
366  }
367  else
368  {
369  sscanf(line,"%*[^=]= %d", &nsca);
370  linenum++;
371  continue;
372  }
373  }
374 
375  if (linenum == 1)
376  {
377  if (strstr(line,"BANDS") == NULL)
378  {
379  printf("-E- %s line %d: Missing FPM numbers in the first line of fpm xcal file %s\n",__FILE__,__LINE__, fpm_file);
380  exit(1);
381  }
382  else
383  {
384  sscanf(line,"%*[^=]= %d", &nbands);
385  fpm_gains = (double *)calloc(nbands, nsca*sizeof(double) );
386  if ( fpm_gains == NULL )
387  {
388  printf("-E- %s line %d: Cannot allocate memory for fpm gain buffer\n",__FILE__,__LINE__);
389  exit(1);
390  }
391  linenum++;
392  continue;
393  }
394  }
395 
396  //printf("nbands = %d, nsca = %d\n", nbands, nsca);
397  if ((ptr = strtok(line,",")) != NULL)
398  {
399  for (ib = 0; ib< nbands; ib++)
400  {
401  isb = isca*nbands + ib;
402  fpm_gains[isb] = atof(ptr);
403  ptr = strtok(NULL,",");
404  }
405  }
406  linenum++;
407  isca++;
408  }
409 
410  /* for (isca = 0; isca < nsca; isca++)
411  for (ib = 0; ib < nbands; ib++)
412  {
413  isb = isca*nbands + ib;
414  printf("fpm_gains = %lf\n", fpm_gains[isb]);
415  } */
416 
417  free( line );
418  fclose(fp);
419 
420  return fpm_gains;
421 }
#define MAX(A, B)
Definition: swl0_utils.h:26
#define MIN(x, y)
Definition: rice.h:169
#define XTNTIME
Definition: xcal.h:6
int status
Definition: l1_czcs_hdf.c:32
double yds2unix(int16_t year, int16_t day, double secs)
Definition: yds2unix.c:7
#define XTNDET
Definition: xcal.h:7
#define FAIL
Definition: ObpgReadGrid.h:18
#define NULL
Definition: decode_rs.h:63
read l1rec
#define XRVS
Definition: xcal.h:10
#define MODIST
Definition: sensorDefs.h:18
#define XTNORDER
Definition: xcal.h:9
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
int32_t im
Definition: atrem_corl1.h:161
int xcal_band(int wave)
Definition: xcal.c:14
#define XM13
Definition: xcal.h:12
double * get_fpm_xcal(char *fpm_file)
Definition: xcal.c:334
l1_input_t * l1_input
Definition: l1_options.c:9
integer, parameter double
#define XTNMSIDE
Definition: xcal.h:8
#define XM12
Definition: xcal.h:11
int32_t nband
double * get_xcal(l1str *l1rec, int type, int wave)
Definition: xcal.c:33
int32_t nbands
#define MAXPIX
Definition: l1.h:50
Extra metadata that will be written to the HDF4 file l2prod rank
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int32_t sensorID[MAXNFILES]
Definition: l2bin.cpp:97
#define MODISA
Definition: sensorDefs.h:19