OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
Granule.c
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 File: Granule.c
4 
5 External functions:
6  Aggregate_L1B
7  Close_L1A_Granule
8  Close_L1B_Granule
9  Read_L1A_EV_Scan
10  safe_strcat
11  L1BErrorMsg
12  SMF_ERROR
13  Bad_L1A_Error_Out
14  Write_L1B_EV_Scan
15  Fill_Dead_Detector_SI
16  Open_and_Read_L1A
17  Get_Satellite_ID
18  Read_Run_Time_Parameters
19 
20 Other functions:
21  Compute_Aggregates
22  Write_L1B_SI_UI
23 
24 Revision History:
25  $Log: Granule.c,v $
26  Revision 1.27 2012-06-27 15:58:24-04 xgeng
27  correced an error message
28 
29  Revision 1.26 2008-01-31 16:45:17-05 ltan
30  Relax the RVS correction limit range. Removed the ScanType of "Mixed" from the code.
31 
32  Revision 1.24 2006/10/30 14:53:59 ltan
33  Changed to write PGEVersion value extracted from the PCF file (LUN 800500). Also check to make sure the PGE Version from the PCF matchs code macro PGE02_VERSION.
34 
35  Revision 1.22 2005/01/18 19:34:42 ltan
36  Added new file attributes prefixed with HDFEOS_FractionalOffset
37 
38 *****************************************************************************/
39 
40 #include "L1B_Tables.h"
41 #include "GranuleP.h"
42 #include "HDF_Lib.h"
43 #include "PGS_PC.h"
44 #include "PGS_TD.h"
45 #include "PGS_MET.h"
46 #include "PGS_Error_Codes.h"
47 #include "FNames.h"
48 #include <string.h>
49 #include <math.h>
50 #include <time.h>
52 
53 /* MOD_PR02 exit code */
54 
56 
57 /*----------------------------------------------------------------------------
58  The following are external variables used by other modules
59  ---------------------------------------------------------------------------*/
60 
64 };
65 
69 };
70 
74 };
75 
77 
80 
81 PGSt_SMF_status Aggregate_L1B (L1B_Scan_t *L1B_Scan)
82 /*
83 !C**********************************************************************
84 !Description:
85  For one scan of calibrated earth-view data, this routine performs
86  spatial integration (or aggregation) of each of the higher
87  resolution bands (250m or 500m) so that they appear at a lower
88  resolution appropriate for the 500m or 1km L1B granule products.
89 
90 !Input Parameters:
91  L1B_Scan_t *L1B_Scan (->SI, ->UI)
92 
93 !Output Parameters:
94  L1B_Scan_t *L1B_Scan (->SI_aggr, ->UI_aggr, ->SU_aggr)
95 
96 !Revision History:
97  (continue at top of the file)
98 
99  Revision 02.11 July 1998
100  Modified the routine to match the change of L1B_Scant_t change.
101  Zhenying Gu (zgu@ltpmail.gsfc.nasa.gov)
102 
103  Revision 01.00 April 1997
104  Initial development
105  (based on the routine Compute_Aggregates, which
106  is a C translation of the FORTRAN code written
107  by Vicky Lin & Rich Hucek)
108  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
109 
110 !Team-unique Header:
111  This software is developed by the MODIS Characterization Support
112  Team (MCST)for the National Aeronautics and Space Administration,
113  Goddard Space Flight Center, under contract NAS5-32373.
114 
115 !References and Credits:
116  HDF portions developed at the National Center for Supercomputing
117  Applications at the University of Illinois at Urbana-Champaign.
118 
119 !Design Notes:
120 
121 !END********************************************************************
122 */
123 {
124  PGSt_SMF_status returnStatus = MODIS_S_OK;
125  int16 B = 0;
126  int16 line_dim = 0;
127  int16 pixel_dim = 0;
128 
129  /*------------------
130  250_to_500m
131  -------------------*/
134 
135  for (B = 0; B < L1B_BANDS_AT_RES[INDEX_250M]; B++)
136  {
137  returnStatus = Compute_Aggregates
138  (2, line_dim, pixel_dim,
139  (VOIDP)L1B_Scan->SI.EV_250m_RefSB[B],
140  (VOIDP)L1B_Scan->UI.EV_250m_RefSB_UI[B],
141  (VOIDP)L1B_Scan->EV_250m_Aggr500m_RefSB[B],
142  (VOIDP)L1B_Scan->EV_250m_Aggr500m_RefSB_UI[B],
143  (VOIDP)L1B_Scan->EV_250m_Aggr500m_RefSB_SU[B]);
144  if (returnStatus != MODIS_S_OK)
145  SMF_ERROR(returnStatus,
146  "Compute_Aggregates(250_to_500m) in "
147  "Aggregate_L1B(), Granule.c");
148  }
149 
150 
151  /*---------------------------
152  250_to_1km & 500_to_1km
153  ---------------------------*/
155  pixel_dim = EV_1km_FRAMES;
156 
157  if ((RFLAG & 1) == 0) {
158  for (B = 0; B < L1B_BANDS_AT_RES[INDEX_250M]; B++)
159  {
160  returnStatus = Compute_Aggregates
161  (4, line_dim, pixel_dim,
162  (VOIDP)L1B_Scan->SI.EV_250m_RefSB[B],
163  (VOIDP)L1B_Scan->UI.EV_250m_RefSB_UI[B],
164  (VOIDP)L1B_Scan->EV_250m_Aggr1km_RefSB[B],
165  (VOIDP)L1B_Scan->EV_250m_Aggr1km_RefSB_UI[B],
166  (VOIDP)L1B_Scan->EV_250m_Aggr1km_RefSB_SU[B]);
167  if (returnStatus != MODIS_S_OK)
168  SMF_ERROR(returnStatus,
169  "Compute_Aggregates(250_to_1km) in "
170  "Aggregate_L1B(), Granule.c");
171  }
172  }
173 
174  if ((RFLAG & 2) == 0) {
175  for (B = 0; B < L1B_BANDS_AT_RES[INDEX_500M]; B++)
176  {
177  returnStatus = Compute_Aggregates
178  (2, line_dim, pixel_dim,
179  (VOIDP)L1B_Scan->SI.EV_500m_RefSB[B],
180  (VOIDP)L1B_Scan->UI.EV_500m_RefSB_UI[B],
181  (VOIDP)L1B_Scan->EV_500m_Aggr1km_RefSB[B],
182  (VOIDP)L1B_Scan->EV_500m_Aggr1km_RefSB_UI[B],
183  (VOIDP)L1B_Scan->EV_500m_Aggr1km_RefSB_SU[B]);
184  if (returnStatus != MODIS_S_OK)
185  SMF_ERROR(returnStatus,
186  "Compute_Aggregates(500_to_1km) in "
187  "Aggregate_L1B(), Granule.c");
188  }
189  }
190 
191  return(MODIS_S_OK);
192 }
193 
194 
195 PGSt_SMF_status Close_L1A_Granule (L1A_granule_t *L1A_Gran,
196  L1A_Scan_t *L1A_Scan)
197 /*
198 !C**********************************************************************
199 !Description:
200  This routine ends access to all L1A SDSs and ends the SD and Vdata
201  interfaces to the L1A middle granule file.
202 
203 !Input Parameters:
204  L1A_granule_t *L1A_Gran
205  L1A_Scan_t *L1A_Scan
206 
207 !Output Parameters:
208  L1A_granule_t *L1A_Gran
209  L1A_Scan_t *L1A_Scan
210 
211 !Revision History:
212  (continue at top of the file)
213 
214  Revision 02.11 July 1998
215  Removed Cleanup_L1A_Granule ( the arrays are changed to static allocated )
216  Zhenying Gu (zgu@ltpmail.gsfc.nasa.gov)
217 
218  Revision 02.00 March 1997
219  Modified to match changes in L1A_granule_t & L1A_Scan_t.
220  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
221 
222  (Neal's version between 01.01 & 02.00 ......???)
223 
224  Revision 01.01 1996/04/05
225  Updated to match Version Design Document.
226  John Hannon(hannon@highwire.gsfc.nasa.gov)
227  Joan Baden (baden@highwire.gsfc.nasa.gov)
228 
229  Revision 01.00 1993
230  Initial development
231  Geir E. Kvaran(geir@highwire.gsfc.nasa.gov)
232 
233 !Team-unique Header:
234 
235 !References and Credits:
236  This software is developed by the MODIS Characterization Support
237  Team (MCST)for the National Aeronautics and Space Administration,
238  Goddard Space Flight Center, under contract NAS5-32373.
239 
240  HDF portions developed at the National Center for Supercomputing
241  Applications at the University of Illinois at Urbana-Champaign.
242 
243 !Design Notes:
244 
245 !END********************************************************************
246 */
247 {
248  PGSt_SMF_status returnStatus = MODIS_S_OK;
249  int16 R = 0;
250 
251  /*Close L1A EV SDS's*/
252  for (R = 0; R < NUM_L1A_RESOLUTIONS; R++) {
253  if ((RFLAG & (1 << R)) != 0) continue;
254  if (SDendaccess(L1A_Scan->sds_id[R]) == FAIL)
255  return(MODIS_F_NOK);
256  }
257 
258  /*Clode L1A file*/
259  if (SDend(L1A_Gran->sd_id) == FAIL) /* close the SD interface */
260  return(MODIS_F_NOK);
261 
262  if (Vend(L1A_Gran->v_id) == FAIL)
263  return(MODIS_F_NOK);
264 
265  if (Hclose(L1A_Gran->v_id) == FAIL) /* close the Vdata interface */
266  return(MODIS_F_NOK);
267 
268  return(returnStatus);
269 }
270 
271 PGSt_SMF_status Close_L1B_Granule (L1B_granule_t *L1B_Gran,
272  L1B_Scan_t *L1B_Scan,
273  boolean skip_night_hi_res)
274 /*
275 !C**********************************************************************
276 !Description:
277  This routine ends SDS access to all open EV SDSs and ends swath interface
278  to all L1B EV granule files.
279 
280 !Input Parameters:
281  L1B_granule_t *L1B_Gran
282  L1B_Scan_t *L1B_Scan
283  Run_Time_Parameters_t *runtime_params Values read from PCF file.
284  boolean skip_night_hi_res Logical; TRUE if and only
285  if all scans in the granule
286  are in NIGHT mode.
287 
288 !Output Parameters:
289  L1B_granule_t *L1B_Gran
290  L1B_Scan_t *L1B_Scan
291 
292 !Revision History:
293  (continue at top of the file)
294 
295  Revision 02.21 November 13, 2001 (Razor Issue #169)
296  Added skip_night_hi_res to input variables.
297  Changed logic so that 250m and 500m data are not written when granule
298  has no day mode scans and runtime parameter
299  Write_Night_Mode_HiRes_Data is False.
300  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
301 
302  Revision 02.20 May 1999
303  Added band 26 section.
304  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
305 
306  Revision 02.11 July 1998
307  Removed Cleanup_L1B_Granule(), because all arrays are changed to
308  static allocated.
309  Zhenying Gu (zgu@ltpmail.gsfc.nasa.gov)
310 
311  Revision 02.00 March 1997
312  Modified to match changes in L1B_granule_t & L1B_Scan_t.
313  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
314 
315  (Neal's version between 01.01 & 02.00 ......???)
316 
317  Revision 01.01 1996/04/05
318  Uppdated to match Version 1 Design Document.
319  John Hannon(hannon@highwire.gsfc.nasa.gov)
320  Joan Baden (baden@highwire.gsfc.nasa.gov)
321 
322  Revision 01.00 1993
323  Initial development
324  Geir E. Kvaran(geir@highwire.gsfc.nasa.gov)
325 
326 !Team-unique Header:
327 
328 !References and Credits:
329  This software is developed by the MODIS Characterization Support
330  Team (MCST)for the National Aeronautics and Space Administration,
331  Goddard Space Flight Center, under contract NAS5-32373.
332 
333  HDF portions developed at the National Center for Supercomputing
334  Applications at the University of Illinois at Urbana-Champaign.
335 
336 !Design Notes:
337  Code to make Vgroup has been removed. It is not currently implemented
338  in SDS_Services, although it could be.
339 !END********************************************************************
340 */
341 {
342  PGSt_SMF_status returnStatus = MODIS_S_OK;
343  int16 R = 0;
344  int16 f = 0;
345  int16 start_output_index = 0;
346 
347  if (skip_night_hi_res == True)
348  start_output_index = INDEX_L1B_1km;
349  else
350  start_output_index = INDEX_L1B_250m;
351 
352  /*Close L1B EV SDS's*/
353 
354  for (R = start_output_index; R < NUM_L1A_RESOLUTIONS; R++)
355  {
356  if ((RFLAG & (1 << R)) != 0) continue;
357  if (SDendaccess(L1B_Scan->SI_sds_id[R]) == FAIL) return(MODIS_F_NOK);
358  if (SDendaccess(L1B_Scan->UI_sds_id[R]) == FAIL) return(MODIS_F_NOK);
359  }
360  if (skip_night_hi_res == False)
361  {
362  if (SDendaccess(L1B_Scan->EV_250m_Aggr500m_RefSB_sds_id) == FAIL)
363  return(MODIS_F_NOK);
364  if (SDendaccess(L1B_Scan->EV_250m_Aggr500m_RefSB_UI_sds_id) == FAIL)
365  return(MODIS_F_NOK);
366  if (SDendaccess(L1B_Scan->EV_250m_Aggr500m_RefSB_SU_sds_id) == FAIL)
367  return(MODIS_F_NOK);
368  }
369 
370  if (SDendaccess(L1B_Scan->EV_250m_Aggr1km_RefSB_sds_id) == FAIL)
371  return(MODIS_F_NOK);
372  if (SDendaccess(L1B_Scan->EV_250m_Aggr1km_RefSB_UI_sds_id) == FAIL)
373  return(MODIS_F_NOK);
374  if (SDendaccess(L1B_Scan->EV_250m_Aggr1km_RefSB_SU_sds_id) == FAIL)
375  return(MODIS_F_NOK);
376  if (SDendaccess(L1B_Scan->EV_500m_Aggr1km_RefSB_sds_id) == FAIL)
377  return(MODIS_F_NOK);
378  if (SDendaccess(L1B_Scan->EV_500m_Aggr1km_RefSB_UI_sds_id) == FAIL)
379  return(MODIS_F_NOK);
380  if (SDendaccess(L1B_Scan->EV_500m_Aggr1km_RefSB_SU_sds_id) == FAIL)
381  return(MODIS_F_NOK);
382 
383 /************************* Begin Band 26 Section **************************/
384 #ifdef WRITE_BAND_26_SDS
385 /*
386  * Close SDS access to the band 26 SDSs.
387  */
388  if (SDendaccess(L1B_Scan->Band26.SI_sds_id) == FAIL)
389  return(MODIS_F_NOK);
390  if (SDendaccess(L1B_Scan->Band26.UI_sds_id) == FAIL)
391  return(MODIS_F_NOK);
392 #endif /* WRITE_BAND_26_SDS */
393 /************************** End Band 26 Section ***************************/
394 
395  /*
396  * If this granule has no day mode scans and the runtime parameter
397  * Write_Night_Mode_HiRes_Data is False, the 250m and 500m
398  * resolution files were not written, and so start with output
399  * file number 2, not 0.
400  */
401 
402  if (skip_night_hi_res == True)
403  start_output_index = INDEX_L1B_1km;
404  else
405  start_output_index = INDEX_L1B_250m;
406 
407 
408  /*Close L1B EV files*/
409  for (f = start_output_index; f < NUM_L1B_EV_FILES; f++)
410  if (SWclose(L1B_Gran->sw_f_id[f]) == FAIL) return(MODIS_F_NOK);
411 
412  return(returnStatus);
413 }
414 
415 
416 PGSt_SMF_status Compute_Aggregates (int16 scale,
417  int16 line_dim_lower,
418  int16 frame_dim_lower,
419  uint16 *SI_in,
420  uint8 *UI_in,
421  uint16 *SI_out,
422  uint8 *UI_out,
423  int8 *SU_out)
424 /*
425 !C****************************************************************************
426 !Description:
427  Perform spatial integration (aggregation) of higher resolution L1B data to
428  appear as lower resolution data. This function computes the aggregated
429  scaled integer, the aggregated uncertainty index and the number of samples
430  used in aggregation.
431 
432 !Input Parameters:
433  int16 scale spatial integration factor, in both the along track
434  and along scan directions of the data. (there are
435  limited valid values -- see the local variables)
436  int16 line_dim_lower line dimension (along track) of lower resolution data
437  int16 frame_dim_lower frame dimension (along scan) of lower resolution data
438  uint16 *SI_in scaled integer data of higher resolution
439  (size = line_dim_lower * scale * frame_dim_lower * scale)
440  uint8 *UI_in uncertainty index data of higher resolution
441  (size = line_dim_lower * scale * frame_dim_lower * scale)
442 
443 !Output Parameters:
444  uint16 *SI_out aggregated scaled integer data at lower resolution
445  (array size = line_dim_lower * frame_dim_lower).
446  uint8 *UI_out aggregated uncertainty index data at lower resolution
447  (array size = line_dim_lower * frame_dim_lower).
448  int8 *SU_out number of samples used in each aggregation
449  (array size = line_dim_lower * frame_dim_lower).
450 
451 !Revision History:
452  (continue at top of the file)
453 
454  Revision 01.01, January 9, 2001, Razor issue 149
455  The assumption on how the first samples of different resolution data are
456  registered was corrected. Also added design notes, made variable names more
457  meaningful, improved efficiency slightly and added comments.
458  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
459 
460  Revision 01.00 April 1997
461  Initial development
462  (this is a translation of the FORTRAN code,
463  Aggregate_L1B, of Vicky Lin & Richard Hucek)
464  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
465 
466 !Team-unique Header:
467  This software is developed by the MODIS Characterization Support
468  Team (MCST)for the National Aeronautics and Space Administration,
469  Goddard Space Flight Center, under contract NAS5-32373.
470 
471 !References and Credits:
472  This code is translated from the FORTRAN code written by
473  Vicky Lin (vlin@ltpmail.gsfc.nasa.gov)
474  Richard Hucek (rhucek@ltpmail.gsfc.nasa.gov)
475  HDF portions developed at the National Center for Supercomputing
476  Applications at the University of Illinois at Urbana-Champaign.
477 
478 !Design Notes:
479  1. For the input and output arrays of data, each array represents a
480  2D array, similar to:
481  A[line_dim_lower][frame_dim_lower] (lower resolution)
482  A[line_dim_lower*scale][frame_dim_lower*scale] (higher resolution)
483  Thus, each higher resolution array has scale^2 times the values of
484  a lower resolution array.
485  2. In the line dimension (along track), each set of scale lines of the
486  higher resolution are averaged (using uniform weighting) to form
487  one aggregated line at the lower resolution.
488  3. In the frame dimension (along scan), the effective response of a
489  detector of either resolution is a triangle function, with the peak of
490  the triangle at the effective location of the frame, and the base
491  of the triangle having a total width of 2 times the frame width. The
492  triangular responses are overlapping by 1/2 the frame width
493  (see the Geolocation ATBD for an explanation and diagram).
494  4. The frames of different resolutions are registered such that the 1st
495  frame of any line at one resolution is aligned with the first frame
496  in a line of a different resolution.
497  5. To aggregate in the frame dimension, (2*scale-1) consecutive values
498  are chosen with triangular weighting to form the aggregated response.
499  Because of the assumption in item 4 above, the first (scale-1) frames
500  are missing from the first aggregate in any given line.
501 
502 !END**************************************************************************
503 */
504 {
505  int16 lines_to_aggregate; /* number of lines of higher resolution data
506  * to aggregate to one line of lower resolution
507  * data (same as input value of "scale").
508  */
509  int16 frames_to_aggregate; /* number of frames (triangle functions) of
510  * higher resolution data to aggregate to one
511  * frame of lower resolution data (2*scale-1).
512  */
513  int16 line_offset; /* essentially this is the index of the first
514  * line of higher resolution data to use in
515  * one aggregation across the set of lines.
516  */
517  int16 frame_offset; /* essentially this is the index of the first
518  * frame of higher resolution data to use in
519  * one aggregation across the set of frames.
520  */
521  int16 frame_dim_higher; /* number of higher resolution frames in each
522  * line of higher resolution data (must be
523  * frame_dim_lower * scale).
524  */
525  int16 L1; /* line index in lower resolution data */
526  int16 F1; /* frame index in lower resolution data */
527  int16 L2; /* line index in higher resolution data */
528  int16 L; /* line index in one set of higher resolution
529  * lines to aggregate.
530  */
531  int16 F; /* frame index in one set of higher resolution
532  * frames to aggregate.
533  */
534  int16 F_start; /* starting frame index within one set of
535  * higher resolution frames to aggregate.
536  * (not necessarily 0 because of design note 4).
537  */
538  int16 scale_index; /* index in 1st dimension of W and SqW arrays */
539  int32 index_higher; /* array index within any higher resolution
540  * array (must be int32).
541  */
542  int32 index_lower; /* array index within any lower resolution
543  * array (must be int32).
544  */
545  int8 samples; /* used to count number of valid samples used
546  * in one aggregation.
547  */
548  float32 sum_W; /* accumulates the weight factors */
549  float32 sum_WSI; /* accumulates the weighted scaled integer */
550  float32 sum_SqW; /* accumulates the square of the weight factors */
551  float32 sum_SqWUI; /* accumulates the square of the weighted UI */
552 
553  /*
554  * The following define how many valid scale factors are handled by this
555  * function and the maximum number of frames for triangle weighting.
556  */
557 
558 #define NUM_SCALE_FACTORS 2
559 #define MAX_AGGR_FRAMES 7
560 
561  /*
562  * The following arrays hold the valid scale factors and the associated
563  * weighting factors, for aggregating along the frame (scan) dimension.
564  * W = weight
565  * SqW = square of weight.
566  * The number of frames to aggregate is (2 * scale - 1).
567  */
568 
569  int16 valid_scale_values[NUM_SCALE_FACTORS] = {2, 4};
570 
571  float32 W[NUM_SCALE_FACTORS][MAX_AGGR_FRAMES] = {
572  {1, 2, 1, 0, 0, 0, 0},
573  {1, 2, 3, 4, 3, 2, 1}
574  };
575 
576  float32 SqW[NUM_SCALE_FACTORS][MAX_AGGR_FRAMES] = {
577  {1, 4, 1, 0, 0, 0, 0},
578  {1, 4, 9, 16, 9, 4, 1}
579  };
580 
581  /*************************************************************************/
582 
583  /*
584  * Determine the "scale_index", the index in the W and SqW arrays.
585  * This checks the value of "scale" in the process.
586  */
587 
588  for (scale_index = 0; scale_index < NUM_SCALE_FACTORS; scale_index++)
589  {
590  if (scale == valid_scale_values[scale_index])
591  break;
592  }
593  if (scale_index == NUM_SCALE_FACTORS)
594  {
595  char errmsg[512];
596  sprintf (errmsg, "Input argument (scale = %d) is invalid.", scale);
597  L1BErrorMsg("Compute_Aggregates", MODIS_F_INVALID_ARGUMENT, errmsg, NULL, 0,
598  NULL, True);
599  }
600 
601 
602  lines_to_aggregate = scale;
603  frames_to_aggregate = 2 * scale - 1;
604  frame_dim_higher = frame_dim_lower * scale;
605 
606  line_offset = 0;
607  for (L1 = 0; L1 < line_dim_lower; L1++, line_offset += scale)
608  {
609 
610  /*
611  * frame_offset starts negative. For the first aggregation of a line,
612  * we will start at the peak of the triangle weight to compensate.
613  */
614 
615  frame_offset = - (scale - 1);
616  for (F1 = 0; F1 < frame_dim_lower; F1++, frame_offset += scale)
617  {
618 
619  /*
620  * Because the first frames of different resolutions align, for the
621  * first aggregate of a line we are missing some frames on the left side
622  * of the triangle weighting function. Set F_start so that we will
623  * have a valid frame index later.
624  */
625 
626  if (F1 == 0)
627  F_start = scale - 1; /* start at the peak of triangle weighting */
628  else
629  F_start = 0; /* start at beginning of triangle weighting */
630 
631  samples = 0;
632  sum_W = 0;
633  sum_WSI = 0;
634  sum_SqW = 0;
635  sum_SqWUI = 0;
636 
637  for (L = 0; L < lines_to_aggregate; L++)
638  {
639  L2 = line_offset + L;
640 
641  index_higher = L2 * frame_dim_higher + frame_offset + F_start;
642  for (F = F_start; F < frames_to_aggregate; F++, index_higher++)
643  {
644  if (SI_in[index_higher] <= DN15_SAT)
645  {
646  samples++;
647  sum_W += W[scale_index][F];
648  sum_WSI += W[scale_index][F] * SI_in[index_higher];
649  sum_SqW += SqW[scale_index][F];
650  sum_SqWUI += SqW[scale_index][F] * UI_in[index_higher] * UI_in[index_higher];
651  }
652  }
653  }
654 
655  index_lower = L1 * frame_dim_lower + F1;
656  if (samples > 0)
657  {
658  SI_out[index_lower] = (uint16)(sum_WSI / sum_W + 0.5);
659  UI_out[index_lower] = (uint8)(sqrt((double)(sum_SqWUI / sum_SqW)) + 0.5);
660  SU_out[index_lower] = samples;
661  }
662  else
663  {
664  SI_out[index_lower] = AGGREGATION_FAIL_SI;
665  UI_out[index_lower] = BAD_DATA_UI;
666  SU_out[index_lower] = 0;
667  }
668  }
669  }
670 
671  return(MODIS_S_OK);
672 }
673 
674 PGSt_SMF_status Read_L1A_EV_Scan (int16 S,
675  L1A_granule_t *L1A_Gran,
676  L1A_Scan_t *L1A_Scan)
677 /*
678 !C**************************************************************************
679 !Description:
680  For the input scan index, S, this routine reads earth-view (EV) scaled
681  integer data for each of the four L1A EV SDSs: EV_250m, EV_500m,
682  EV_1km_day, and EV_1km_night. If the scan is not a "Day" mode scan,
683  then only the data from the EV_1km_night SDS is read.
684 
685 !Input Parameters:
686  int16 S current scan index
687  L1A_granule_t *L1A_Gran contains day-night flag, number of scans
688  and valid SDS ids for each L1A EV SDS.
689 
690 !Output Parameters:
691  L1A_Scan_t *L1A_Scan filled SDS data for all resolutions of 1 scan
692 
693 !Revision History:
694  (continue at top of the file)
695 
696  Revision 02.1.2, January 22, 2001
697  Corrected variable names and simplified the logic within this function
698  to remove unnecessary lines. Added design notes.
699  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
700 
701  Revision 02.1.1 July 1997
702  Modified to match change in L1A_Scan_t;
703  Zhenying Gu (zgu@ltpmail.gsfc.nasa.gov)
704 
705  Revision 02.00 March 1997
706  Modified to match change in L1A_Scan_t;
707  limited processing to EV data.
708  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
709 
710  (Neal's version between 01.01 & 02.00......???)
711 
712  Revision 01.01 1996/04/05
713  Update to match Version 1 Design Document
714  John Hannon(hannon@highwire.gsfc.nasa.gov)
715  Joan Baden (baden@highwire.gsfc.nasa.gov)
716 
717  Revision 01.00 1993
718  Initial development
719  Geir E. Kvaran(geir@highwire.gsfc.nasa.gov)
720 
721 !Team-unique Header:
722  This software is developed by the MODIS Characterization Support
723  Team (MCST)for the National Aeronautics and Space Administration,
724  Goddard Space Flight Center, under contract NAS5-32373.
725 
726 !References and Credits:
727  HDF portions developed at the National Center for Supercomputing
728  Applications at the University of Illinois at Urbana-Champaign.
729 
730 !Design Notes:
731  1. We only need to read the 250m, 500m and 1km_day SDS data if the scan
732  is a "Day" scan, according to the day-night flag. We always read the
733  1km_night data.
734  2. The L1A SDSs are oversized in terms of the number of frames. We
735  read the full set of data for 1 scan to make the internal read
736  more efficient (each call will read one stream of data from the file
737  rather than having to read many disjointed streams of data).
738 !END************************************************************************
739 */
740 {
741  int16 R; /* L1A resolution index */
742  int16 D; /* Detector index */
743  int16 B; /* Band index */
744  int32 start[3] = {0, 0, 0}; /* starting indices, each dimension */
745  /* (must be initialized to zero) */
746  int32 edge[3]; /* # of elements to read, each dimension */
747  intn hdf_return;
748  char *location = "Read_L1A_EV_Scan"; /* This function name */
749  int16 *ev_data_p[NUM_L1A_RESOLUTIONS]; /* pointers to each SDS data */
750  int32 offset;
751 
752  /*
753  * Check gross validity of inputs.
754  */
755 
756  if (S < 0 || S >= L1A_Gran->num_scans || !L1A_Scan || !L1A_Gran) {
758  "Scan index (S), L1A_Gran or L1A_Scan value is invalid.",
761  }
762 
763  /*
764  * Assign data pointers.
765  */
766 
767  ev_data_p[INDEX_250M] = (int16 *) L1A_Scan->EV_250m;
768  ev_data_p[INDEX_500M] = (int16 *) L1A_Scan->EV_500m;
769  ev_data_p[INDEX_1000M_DAY] = (int16 *) L1A_Scan->EV_1km_day;
770  ev_data_p[INDEX_1000M_NIGHT] = (int16 *) L1A_Scan->EV_1km_night;
771 
772  /*
773  * Loop through L1A resolutions and read one scan of L1A data.
774  * (see design notes regarding which SDSs to read).
775  */
776 
777  for (R = 0; R < NUM_L1A_RESOLUTIONS; R++)
778  {
779  if ((RFLAG & (1 << R)) != 0) continue;
780 
781  if (strcmp(L1A_Gran->ScanType[S],"Day") == SAME ||
782  R == INDEX_1000M_EMISS)
783  {
784  if (L1A_Gran->Extract_Pixel_Offset == -1 &&
785  L1A_Gran->Extract_Pixel_Count == -1) {
786 
787  start[0] = S * DETECT_PER_BAND_AT_RES[R];
788  edge[0] = DETECT_PER_BAND_AT_RES[R];
789  edge[1] = L1A_BANDS_AT_RES[R];
790  edge[2] = EV_1km_FRAMES * BAND_RATIO_AT_RES[R];
791 
792  hdf_return = SDreaddata (L1A_Scan->sds_id[R], start, NULL, edge,
793  ev_data_p[R]);
794  if (hdf_return == FAIL) {
795  char errmsg[256];
796  char *resnames[NUM_L1A_RESOLUTIONS] = {
797  "250m", "500m", "1km_day", "1km_night"
798  };
799  sprintf (errmsg, "Could not read L1A SDS: EV_%s.", resnames[R]);
800  L1BErrorMsg(location, MODIS_F_READ_ERROR, errmsg,
801  "SDreaddata", FIRST_L1A_GRANULE, NULL, True);
802  return MODIS_F_READ_ERROR;
803  }
804  } else {
805 
806  /* Clear buffer */
807  memset(ev_data_p[R], 0, DETECT_PER_BAND_AT_RES[R] * L1A_BANDS_AT_RES[R] *
809 
810  for (D = 0; D < DETECT_PER_BAND_AT_RES[R]; D++)
811 
812  for (B = 0; B < L1A_BANDS_AT_RES[R]; B++) {
813  start[0] = S*DETECT_PER_BAND_AT_RES[R] + D;
814  start[1] = B;
815  start[2] = 0;
816  edge[0] = 1;
817  edge[1] = 1;
818  edge[2] = L1A_Gran->Extract_Pixel_Count * BAND_RATIO_AT_RES[R];
819 
821  B*EV_1km_FRAMES + L1A_Gran->Extract_Pixel_Offset) *
823 
824  hdf_return = SDreaddata (L1A_Scan->sds_id[R], start, NULL, edge,
825  &ev_data_p[R][offset]);
826  }
827  }
828  }
829  }
830 
831  return MODIS_S_OK;
832 }
833 
834 
835 #include <string.h> /* for the strcat function */
836 
837 int safe_strcat(char *buf, char *str, int buflen)
838 /*
839 !C*****************************************************************************
840 !Description:
841  Safely concatenate a string onto a buffer. If neccessary, truncate the
842  string to fit onto the end of the buffer, allowing a null to be at the end.
843  Return values:
844  0: the string was completely and successfully concatenated onto the end
845  of the buffer.
846  1: the buffer did not exist, the string did not exist or the buffer was
847  to small to hold the entire string -- in which case as many characters
848  as possible from the string are concatenated onto the end of the buffer.
849 
850 !Input Parameters:
851  char *buf Buffer holding characters to which we are concatenating
852  a string onto the end of.
853  char *str The string to be placed at the end of the buffer.
854  int buflen The memory length of the buffer (not the string length).
855 
856 !Output Parameters:
857  (none)
858 
859 !Revision History:
860  (continue at top of the file)
861 
862  Revision 1.0.1 January 17, 2002 Razor Issue #172
863  Improve portability of code to 64-bit mode.
864  Change variables j, nb, and ns to type size_t.
865  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
866 
867  Revision 1.0 Nov. 1, 1999
868  Initial development.
869  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
870 
871 !Team-unique Header:
872  This software is developed by the MODIS Characterization Support
873  Team (MCST)for the National Aeronautics and Space Administration,
874  Goddard Space Flight Center, under contract NAS5-32373.
875 
876 !References and Credits:
877  HDF portions developed at the National Center for Supercomputing
878  Applications at the University of Illinois at Urbana-Champaign.
879 
880 !Design Notes:
881 
882 
883 !END******************************************************************************
884 */
885 {
886  int i; /* indexes */
887  size_t j;
888  size_t nb; /* string length of buf */
889  size_t ns; /* string length of str */
890  int mx; /* maximum number of non-null chars allowed in buffer */
891 
892  if (!buf || !str || buflen <= 0) return 1;
893 
894  /* Compute total length of required memory. */
895 
896  nb = strlen(buf);
897  ns = strlen(str);
898  if ((nb + ns) < buflen) {
899  strcat(buf, str);
900  return 0;
901  }
902  else {
903  mx = buflen - 1;
904  for (i = 0, j = nb; j < mx; i++, j++) buf[j] = str[i];
905  buf[mx] = '\0';
906  return 1;
907  }
908 }
909 
910 
911 /*
912  * The following are global values to use for the "other_msg" input to
913  * L1BErrorMsg. These errors may occur many times.
914  */
915 
916 char Invalid_MOD01_Msg[] = "\
917 The MOD01 granule appears to be invalid. Data values are present\n\
918 that are not allowed by the MOD01 file specifications.";
919 
920 
922  char *L1B_location, /* name of L1B function that error occurred in */
923  PGSt_SMF_code code, /* associated error code for this error */
924  char *input_message, /* short (usually 1-line) description of error */
925  char *assoc_function, /* name of an associated function that failed */
926  int32 lun, /* associated LUN for the file being accessed */
927  char *other_msg, /* other message to add such as probable cause */
928  boolean error_out /* flag to tell whether or not to call SMF_ERROR */
929 )
930 /*
931 !C**********************************************************************
932 !Description:
933  Format an error message and write it to the LogReport and LogStatus
934  files. If the flag "error_out" is True, then also call SMF_ERROR.
935  Otherwise, this function will simply return to continue processing.
936  The general form of the message created is:
937 
938  ERROR in [L1B_location]():
939  [input_message]
940  Call to [assoc_function]() failed.
941  File LUN: [lun] ([type of file for this LUN])
942  [other_msg]
943 
944  If an input is NULL (for char *) or zero (for int32), then that part of
945  the message is not included.
946 
947 !Input Parameters:
948  char *L1B_location name of L1B function that error occurred in
949  PGSt_SMF_code code associated error code for this error
950  char *input_message short (usually 1-line) description of error
951  char *assoc_function name of an associated function that failed
952  int32 LUN associated LUN for the file being accessed
953  char *other_msg other message to add such as probable cause
954  boolean error_out flag to tell whether or not to call SMF_ERROR
955 
956 !Output Parameters:
957  (none)
958 
959 !Revision History:
960  (continue at top of the file)
961 
962  Revision 1.02 October 16, 2004 Razor Issue #200
963  Casted Int32 variables in sprintf calls to "long" with the
964  format specifier "%ld" for better code portability.
965  Liqin Tan, SAIC GSO (ltan@saicmodis.com)
966 
967  Revision 1.01 August 15, 2002
968  Add messages regarding "ProcessingEnvironment", "MCST LUT Version",
969  and "Write_Night_Mode_HiRes_Data".
970  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
971 
972  Revision 1.0 Nov. 4, 1999
973  Initial development.
974  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
975 
976 !Team-unique Header:
977  This software is developed by the MODIS Characterization Support
978  Team (MCST)for the National Aeronautics and Space Administration,
979  Goddard Space Flight Center, under contract NAS5-32373.
980 
981 !References and Credits:
982  HDF portions developed at the National Center for Supercomputing
983  Applications at the University of Illinois at Urbana-Champaign.
984 
985 !Design Notes:
986  The messages going to the LogStatus and LogReport are formatted to
987  look similar to each other.
988 
989  The message size should be smaller than PGS_SMF_MAX_MSGBUF_SIZE
990  due to internal limits in PGS_SMF_SetDynamicMsg. This routine will
991  fill up the message buffer until there is no more room and then
992  call PGS_SMF_SetDynamicMsg. Thus, a message may appear truncated.
993 
994  The same size message buffer is assumed for the LogReport message.
995  This could result in the LogReport message being truncated from the
996  message written to the log status file (since the L1B_location is added
997  at the beginning of the LogReport file).
998 
999  This restriction may not be necessary. The source code for
1000  PGS_SMF_GenerateStatusReport does not appear to have any string
1001  length restrictions.
1002 
1003  The lun (if one of the list of L1B LUNs) is used to determine the
1004  the category of the file (e.g., QA_Lookup_Tables_file).
1005 
1006  All "Concatenate" operations will use the "safe_strcat" function that
1007  ensures that the string can be concatenated onto the end and that flags
1008  when a message is truncated.
1009 
1010 !END********************************************************************
1011 */
1012 {
1013  PGSt_SMF_status returnStatus; /* Return value for some PGS functs */
1014  char msg[PGS_SMF_MAX_MSGBUF_SIZE]; /* Buffer for LogStatus message */
1015  char report[PGS_SMF_MAX_MSGBUF_SIZE]; /* Buffer for LogReport message */
1016  char lunstr[PGS_SMF_MAX_MSGBUF_SIZE]; /* Buffer for LUN string */
1017  char category[PGS_SMF_MAX_MSGBUF_SIZE]; /* Buffer for file category */
1018  PGSt_SMF_boolean internal_failure; /* Flags internal function failure. */
1019 
1020  /*
1021  * First, format the message to be written to the LogStatus file.
1022  * The L1B function name is not needed for that message (it is an argument
1023  * to the PGS_SMF_SetDynamicMsg function).
1024  */
1025 
1026  /* initialize the message buffer */
1027 
1028  strcpy(msg, "");
1029 
1030  /* Add the specific input message */
1031 
1032  if (input_message) {
1033  safe_strcat(msg, input_message, PGS_SMF_MAX_MSGBUF_SIZE);
1034  if (msg[strlen(msg)-1] != '\n')
1035  safe_strcat(msg, "\n", PGS_SMF_MAX_MSGBUF_SIZE);
1036  }
1037 
1038  /* Add the associated function name */
1039 
1040  if (assoc_function) {
1041  safe_strcat(msg, "Call to ", PGS_SMF_MAX_MSGBUF_SIZE);
1042  safe_strcat(msg, assoc_function, PGS_SMF_MAX_MSGBUF_SIZE);
1043  safe_strcat(msg, "() failed.\n", PGS_SMF_MAX_MSGBUF_SIZE);
1044  }
1045 
1046  /* Add the LUN information */
1047 
1048  if (lun != 0) {
1049  sprintf(lunstr, "File LUN: %ld\nFile type: ", (long)lun);
1050  safe_strcat(msg, lunstr, PGS_SMF_MAX_MSGBUF_SIZE);
1051  switch (lun) {
1052  case MCF_FILE_QKM:
1053  strcpy(category, "MOD02QKM MCF\n"); break;
1054  case MCF_FILE_HKM:
1055  strcpy(category, "MOD02HKM MCF\n"); break;
1056  case MCF_FILE_1KM:
1057  strcpy(category, "MOD021KM MCF\n"); break;
1058  case MCF_FILE_OBC:
1059  strcpy(category, "MOD02OBC MCF\n"); break;
1060  case L1B_EV_250M_FILE:
1061  strcpy(category, "MOD02QKM output granule\n"); break;
1062  case L1B_EV_500M_FILE:
1063  strcpy(category, "MOD02HKM output granule\n"); break;
1064  case L1B_EV_1000M_FILE:
1065  strcpy(category, "MOD021KM output granule\n"); break;
1066  case L1B_OBC_FILE:
1067  strcpy(category, "MOD02OBC output granule\n"); break;
1068  case REFLECTIVE_TABLES_FILE:
1069  strcpy(category, "Reflective_Lookup_Tables_file\n"); break;
1070  case EMISSIVE_TABLES_FILE:
1071  strcpy(category, "Emissive_Lookup_Tables_file\n"); break;
1072  case QA_TABLES_FILE:
1073  strcpy(category, "QA_Lookup_Tables_file\n"); break;
1074  case LEADING_L1A_GRANULE:
1075  strcpy(category, "previous MOD01 input granule\n"); break;
1076  case FIRST_L1A_GRANULE:
1077  strcpy(category, "current MOD01 input granule\n"); break;
1078  case TRAILING_L1A_GRANULE:
1079  strcpy(category, "following MOD01 input granule\n"); break;
1080  case GEOLOCATION_FILE:
1081  strcpy(category, "MOD03 input granule\n"); break;
1083  "PCF File; ProcessingEnvironment; not required.\n"); break;
1085  "PCF File; invalid MCSTLUTVersion value\n"); break;
1087  "PCF File; invalid Write_Night_Mode_HiRes_Data value\n"); break;
1088  default:
1089  strcpy(category, "invalid value, L1B defect\n"); break;
1090  }
1091  safe_strcat(msg, category, PGS_SMF_MAX_MSGBUF_SIZE);
1092 
1093  }
1094 
1095  /*
1096  * Add the other message
1097  */
1098 
1099  if (other_msg) {
1100  safe_strcat(msg, other_msg, PGS_SMF_MAX_MSGBUF_SIZE);
1101  }
1102 
1103  /*
1104  * Write the message to the LogStatus file.
1105  */
1106 
1107  internal_failure = PGS_FALSE;
1108  returnStatus = PGS_SMF_SetDynamicMsg(code, msg, L1B_location);
1109  if (returnStatus != PGS_S_SUCCESS)
1110  internal_failure = PGS_TRUE;
1111 
1112  /*
1113  * Now format the same message to be written to the LogReport file.
1114  * Make the appearance of the message similar in the LogReport file.
1115  */
1116 
1117  strcpy(report, "");
1118 
1119  /* Add the L1B location */
1120 
1121  if (L1B_location)
1122  {
1123  safe_strcat(report, L1B_location, PGS_SMF_MAX_MSGBUF_SIZE);
1124  safe_strcat(report, "():", PGS_SMF_MAX_MSGBUF_SIZE);
1125  }
1126  else
1127  {
1128  safe_strcat(report, ":", PGS_SMF_MAX_MSGBUF_SIZE);
1129  }
1130 
1131  /* Add the textual and numerical equivalents of the exit code. */
1132 
1133  switch (code) {
1134  case MODIS_F_OUT_OF_MEMORY:
1135  safe_strcat(report, "MODIS_F_OUT_OF_MEMORY:",
1136  PGS_SMF_MAX_MSGBUF_SIZE); break;
1137  case MODIS_F_MEM_FREE_FAIL:
1138  safe_strcat(report, "MODIS_F_MEM_FREE_FAIL:",
1139  PGS_SMF_MAX_MSGBUF_SIZE); break;
1141  safe_strcat(report, "MODIS_F_FILE_NOT_FOUND:",
1142  PGS_SMF_MAX_MSGBUF_SIZE); break;
1143  case MODIS_F_READ_ERROR:
1144  safe_strcat(report, "MODIS_F_READ_ERROR:",
1145  PGS_SMF_MAX_MSGBUF_SIZE); break;
1146  case MODIS_F_WRITE_ERROR:
1147  safe_strcat(report, "MODIS_F_WRITE_ERROR:",
1148  PGS_SMF_MAX_MSGBUF_SIZE); break;
1149  case MODIS_F_OUT_OF_RANGE:
1150  safe_strcat(report, "MODIS_F_OUT_OF_RANGE:",
1151  PGS_SMF_MAX_MSGBUF_SIZE); break;
1152  case MODIS_W_OUT_OF_RANGE:
1153  safe_strcat(report, "MODIS_W_OUT_OF_RANGE:",
1154  PGS_SMF_MAX_MSGBUF_SIZE); break;
1156  safe_strcat(report, "MODIS_W_TIME_INCORRECT:",
1157  PGS_SMF_MAX_MSGBUF_SIZE); break;
1158  case MODIS_F_NOK:
1159  safe_strcat(report, "MODIS_F_NOK:",
1160  PGS_SMF_MAX_MSGBUF_SIZE); break;
1161  case MODIS_F_HDF_ERROR:
1162  safe_strcat(report, "MODIS_F_HDF_ERROR:",
1163  PGS_SMF_MAX_MSGBUF_SIZE); break;
1164  case MODIS_F_NO_MORE:
1165  safe_strcat(report, "MODIS_F_NO_MORE:",
1166  PGS_SMF_MAX_MSGBUF_SIZE); break;
1167  case MODIS_S_NO_MORE:
1168  safe_strcat(report, "MODIS_S_NO_MORE:",
1169  PGS_SMF_MAX_MSGBUF_SIZE); break;
1171  safe_strcat(report, "MODIS_F_FILE_NOT_OPENED:",
1172  PGS_SMF_MAX_MSGBUF_SIZE); break;
1174  safe_strcat(report, "MODIS_F_FILE_NOT_CREATED:",
1175  PGS_SMF_MAX_MSGBUF_SIZE); break;
1177  safe_strcat(report, "MODIS_F_INVALID_ARGUMENT:",
1178  PGS_SMF_MAX_MSGBUF_SIZE); break;
1179  case MODIS_E_TESTING:
1180  safe_strcat(report, "MODIS_E_TESTING:",
1181  PGS_SMF_MAX_MSGBUF_SIZE); break;
1182  case MODIS_S_OK:
1183  safe_strcat(report, "MODIS_S_OK:",
1184  PGS_SMF_MAX_MSGBUF_SIZE); break;
1185  default:
1186  safe_strcat(report, "UNKNOWN_CODE:",
1187  PGS_SMF_MAX_MSGBUF_SIZE); break;
1188  }
1189  sprintf(lunstr, "%d\n", code);
1190  safe_strcat(report, lunstr, PGS_SMF_MAX_MSGBUF_SIZE);
1191 
1192  /*
1193  * Add the previously formatted message written to LogStatus file.
1194  * Write the total message to the LogReport file.
1195  */
1196 
1197  safe_strcat(report, msg, PGS_SMF_MAX_MSGBUF_SIZE);
1198  returnStatus = PGS_SMF_GenerateStatusReport(report);
1199  if (returnStatus != PGS_S_SUCCESS)
1200  internal_failure = PGS_TRUE;
1201 
1202  /*
1203  * If there is an internal failure, write fatal error message and
1204  * error out. (The way that SMF_ERROR is designed, the error message
1205  * will probably not get written anyway.)
1206  */
1207 
1208  if (internal_failure == PGS_TRUE)
1209  {
1211  "Fatal error in HDFFuncErrorMsg: Failed to write to\n"
1212  "PGS_SMF_SetDynamicMsg or to PGS_SMF_GenerateStatusReport");
1213  }
1214 
1215  /*
1216  * Call SMF_ERROR to error out if the flag is set to True.
1217  */
1218 
1219  if (error_out == True)
1220  SMF_ERROR(code, NULL);
1221 }
1222 
1223 
1224 /*
1225  * The following variable contains error message information used in
1226  * SMF_ERROR. The first entry in the variable is the
1227  * default (in case of input error) and the last entry in the table
1228  * must be NULL.
1229  */
1230 
1231  static struct
1232  {
1233  char *name; /* macro name of the error code */
1234  int32 value; /* numerical value of the code */
1235  char *actions; /* operator actions to take */
1236  } err_msg_info[] =
1237  {
1238 
1239  { "MODIS_F_NOK", MODIS_F_NOK, "\
1240  Operator Actions:\n\
1241  Contact MCST.\n"
1242  },
1243 
1244  { "MODIS_F_OUT_OF_MEMORY", MODIS_F_OUT_OF_MEMORY, "\
1245  Operator Actions:\n\
1246  Check the system health to see if it is overloaded.\n\
1247  Try re-running the PGE with system loading reduced.\n\
1248  Contact MCST.\n"
1249  },
1250 
1251  { "MODIS_F_MEM_FREE_FAIL", MODIS_F_MEM_FREE_FAIL, "\
1252  Operator Actions:\n\
1253  Contact MCST.\n"
1254  },
1255 
1256  { "MODIS_F_FILE_NOT_FOUND", MODIS_F_FILE_NOT_FOUND, "\
1257  Operator Actions:\n\
1258  Check previous messages to identify LUN of the file and other possible causes.\n\
1259  Check the PCF file to ensure that UR exists and PCF format is correct.\n\
1260  Check the PCF file to ensure that file names and directories are correct.\n\
1261  Contact MCST.\n"
1262  },
1263 
1264  { "MODIS_F_READ_ERROR", MODIS_F_READ_ERROR, "\
1265  Operator Actions:\n\
1266  Check previous messages to identify LUN of the file and other possible causes.\n\
1267  Check the PCF file to ensure that file names and directories are correct.\n\
1268  Check the file type and size to see if it is consistent with file category.\n\
1269  Contact MCST.\n"
1270  },
1271 
1272  { "MODIS_F_WRITE_ERROR", MODIS_F_WRITE_ERROR, "\
1273  Operator Actions:\n\
1274  Check previous messages to identify LUN of the file and other possible causes.\n\
1275  Check the PCF file to ensure that file names and directories are correct.\n\
1276  Check available system disk space.\n\
1277  Check to see if file has been moved or corrupted during execution.\n\
1278  Contact MCST.\n"
1279  },
1280 
1281  { "MODIS_F_OUT_OF_RANGE", MODIS_F_OUT_OF_RANGE, "\
1282  Operator Actions:\n\
1283  Check previous messages to identify LUN of the file and other possible causes.\n\
1284  Contact MCST.\n\
1285  Also contact SDST if the LUN corresponds to a MOD01 or MOD03 granule.\n"
1286  },
1287 
1288  { "MODIS_W_OUT_OF_RANGE", MODIS_W_OUT_OF_RANGE, "\
1289  Operator Actions:\n\
1290  Contact MCST.\n"
1291  },
1292 
1293  { "MODIS_W_TIME_INCORRECT", MODIS_W_TIME_INCORRECT, "\
1294  Operator Actions:\n\
1295  Check Leap Seconds and other toolkit files and environment variables.\n\
1296  Notify L1B product users that time in product may be incorrect.\n\
1297  Contact MCST.\n"
1298  },
1299 
1300  { "MODIS_F_HDF_ERROR", MODIS_F_HDF_ERROR, "\
1301  Operator Actions:\n\
1302  Check previous messages to identify LUN of the file and other possible causes.\n\
1303  Contact MCST.\n"
1304  },
1305 
1306  { "MODIS_F_NO_MORE", MODIS_F_NO_MORE, "\
1307  Operator Actions:\n\
1308  Contact MCST.\n"
1309  },
1310 
1311  { "MODIS_S_NO_MORE", MODIS_S_NO_MORE, NULL },
1312 
1313  { "MODIS_F_FILE_NOT_OPENED", MODIS_F_FILE_NOT_OPENED, "\
1314  Operator Actions:\n\
1315  Check previous messages to identify LUN of the file and other possible causes.\n\
1316  Check the PCF file to ensure that file names and directories are correct.\n\
1317  Contact MCST.\n"
1318  },
1319 
1320  { "MODIS_F_FILE_NOT_CREATED", MODIS_F_FILE_NOT_CREATED, "\
1321  Operator Actions:\n\
1322  Check previous messages to identify LUN of the file and other possible causes.\n\
1323  Check the PCF file to ensure that file names and directories are correct.\n\
1324  Check file permissions of the system.\n\
1325  Contact MCST.\n"
1326  },
1327 
1328  { "MODIS_F_INVALID_ARGUMENT", MODIS_F_INVALID_ARGUMENT, "\
1329  Operator Actions:\n\
1330  Contact MCST.\n"
1331  },
1332 
1333  { "MODIS_E_TESTING", MODIS_E_TESTING, "\
1334  Operator Actions:\n\
1335  Contact MCST.\n"
1336  },
1337 
1338  { "MODIS_S_OK", MODIS_S_OK, NULL },
1339 
1340  { NULL, 0, NULL } /*** Must be NULL terminated ***/
1341  };
1342 
1343 
1344 void SMF_ERROR (PGSt_SMF_code code, char *messagestring)
1345 /*
1346 !C**************************************************************************
1347 !Description:
1348  Provides the interface to the Status Message Facility in the SDP Toolkit.
1349  A message is formed using the format string from the L1B "seed" file,
1350  the input message string and the local time. The message is written to
1351  both the LogStatus file and the LogReport file. Additionally, operator
1352  actions are written as the last messages to the files.
1353 
1354  IMPORTANT: This function will invoke "exit" for fatal error codes or
1355  internal failures that should not occur (such as the environment or
1356  seed messages do not function). See other comments in design notes.
1357 
1358 !Input Parameters:
1359  PGSt_SMF_code code One of the L1B message codes defined in
1360  PGS_Error_Codes.h" and in the seed file.
1361  char * messagestring A string which contains a specific error
1362  message. The function name should be already
1363  part of the string, if appropriate.
1364 
1365 !Output Parameters:
1366  (none)
1367 
1368 !Revision History:
1369  (continue at top of the file)
1370 
1371  Revision 2.0.1 January 17, 2002 Razor Issue #172
1372  Improve portability of code to 64-bit mode.
1373  Change variable n to type size_t. Use n instead of i in strlen operations.
1374  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
1375 
1376  Revision 02.00 Oct. 27, 1999
1377  Added checks on input validity (NULL, string length). Reformatted
1378  message so that it does not appear all on one line. Added "MOD_PR02"
1379  to the beginning to distinguish the source from other processes that
1380  may write to the same Log files. Added additional error messages and
1381  warnings. Function was completely restructured. Added design notes.
1382  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
1383 
1384  Revision 01.00 199604/05
1385  Initial development, new function for Version 1.
1386  John Hannon(hannon@highwire.gsfc.nasa.gov)
1387 
1388 !Team-unique Header:
1389  This software is developed by the MODIS Characterization Support
1390  Team (MCST)for the National Aeronautics and Space Administration,
1391  Goddard Space Flight Center, under contract NAS5-32373.
1392 
1393 !References and Credits:
1394  This routine is based on the CHECK_ERR function used by Geir Kvaran
1395  in the Beta version of the code.
1396  HDF portions developed at the National Center for Supercomputing
1397  Applications at the University of Illinois at Urbana-Champaign.
1398 
1399 !Design Notes:
1400 
1401  The final form of the message consists of three parts, concatenated together:
1402  1. leading part: string from the seed file associated with this code
1403  2. middle part: the input "messagestring"
1404  3. last part: the local time that the error occurred
1405  Note that the string from the seed file actually is the format string for the
1406  sprintf function (it has two "%s" fields for the middle and trailing parts).
1407 
1408  If the total message is too large to fit into the maximum size allowed by the
1409  Toolkit (PGS_SMF_MAX_MSGBUF_SIZE - 1), then the user supplied message is
1410  truncated so that it will fit. In this case, the process will exit only if the
1411  original message code was fatal.
1412 
1413  Side effect: The input messagestring may be modified by this function if the
1414  string length is too long. Thus, the calling function should not plan on using
1415  the string afterward.
1416 
1417  For a NULL or zero-length messagestring, assume that the seed file message is
1418  the complete message.
1419 
1420  Note: The following conditions could cause an exit invocation:
1421  1. The input "code" corresponds to a fatal error, or
1422  2. There is an internal failure inside this function.
1423  An internal failure is a failure of one of the PGS toolkit functions. Other
1424  errors that occur may generate warnings, but will not halt the process
1425  in and of themselves.
1426 
1427  Depending on the internal failure, there may be no error messages written.
1428  If absolutely no message of any kind comes out, perhaps the LogStatus and
1429  LogReport files are not set properly in the PCF.
1430 
1431 !END***************************************************************************
1432 */
1433 {
1434  PGSt_SMF_status returnStatus; /* Return value for some PGS functs */
1435  char msgfmt[PGS_SMF_MAX_MSGBUF_SIZE]; /* Holds the format retrieved from
1436  * the seed file (format associated with
1437  * the particular input error code).
1438  */
1439 #define ASCTIMEBUF 26
1440  char timestr[ASCTIMEBUF]; /* Holds the local time in a string.
1441  * The time function "asctime_r" sets a
1442  * null-terminated string of length 25.
1443  */
1444  char msgstr[PGS_SMF_MAX_MSGBUF_SIZE]; /* Holds the modified input message (could
1445  * be truncated or have newlines added)
1446  */
1447  char buf[PGS_SMF_MAX_MSGBUF_SIZE]; /* Holds the final concatenated message. */
1448  struct tm *tptr; /* used in getting time string */
1449  time_t local; /* used in getting time string */
1450  PGSt_SMF_boolean internal_failure; /* Flags any internal function failure. */
1451  size_t n; /* temporary variable */
1452 
1453  char *defaultmsgfmt = "Error running...%sTIME:%s"; /* backup value */
1454  PGSt_SMF_code internal_failure_code = MODIS_F_NOK; /* value to use for internal
1455  * failure.
1456  */
1457  char *s; /* temporary variable */
1458  int32 i; /* loop index */
1459  int32 imsg; /* index in "err_mgs_info" for this code */
1460 
1461 /*************************** MACRO WRITE_MSG(c,m) *********************************
1462  Writes a string to both the LogStatus and LogReport. For writing to the
1463  LogStatus, the function name is not input (set to NULL). Note that if either
1464  call fails, then we probably will not get any messages at all. There is one
1465  final check on the string length, although this should be OK.
1466  c = SMF message code
1467  m = message string to be written
1468 **********************************************************************************/
1469 #define WRITE_MSG(c,m) \
1470  if (strlen(m) > (PGS_SMF_MAX_MSGBUF_SIZE - 1)) { \
1471  m[strlen(m)-1] = '\0'; \
1472  } \
1473  returnStatus = PGS_SMF_SetDynamicMsg(c, m, NULL); \
1474  if (returnStatus != PGS_S_SUCCESS) \
1475  internal_failure = PGS_TRUE; \
1476  returnStatus = PGS_SMF_GenerateStatusReport(m); \
1477  if (returnStatus != PGS_S_SUCCESS) \
1478  internal_failure = PGS_TRUE;
1479 
1480  /******************* Begin code ***************/
1481 
1482  /*
1483  * Initialize flag to false.
1484  */
1485 
1486  internal_failure = PGS_FALSE;
1487 
1488  /*
1489  * Get the seed file message format string for this error code.
1490  */
1491 
1492  returnStatus = PGS_SMF_GetMsgByCode(code, msgfmt);
1493  if (returnStatus != PGS_S_SUCCESS)
1494  {
1495  char errmsg[] = "MOD_PR02 Warning in SMF_ERROR: Call to PGS_SMF_GetMsgByCode failed.\n"
1496  "Seed file may not be set up properly or code is invalid.\n"
1497  "The input message will be printed below and process will exit.\n";
1498  WRITE_MSG(internal_failure_code,errmsg);
1499  internal_failure = PGS_TRUE;
1500  strcpy(msgfmt, defaultmsgfmt);
1501  }
1502 
1503  /*
1504  * Form the local time and copy the time string into the timestr.
1505  * If the time functions fail, copy a small error message into the timestr.
1506  */
1507 
1508  local = time(NULL);
1509  tptr = localtime(&local);
1510  s = asctime(tptr);
1511  if (s)
1512  {
1513  strcpy(timestr, s);
1514  }
1515  else
1516  {
1517  strcpy(timestr,"WARNING: asctime failed"); /* this string must be < 26 chars! */
1518  }
1519  if (strlen(timestr) > (ASCTIMEBUF-1))
1520  {
1521  strcpy(timestr,"WARNING: asctime failed"); /* this string must be < 26 chars! */
1522  }
1523 
1524  /*
1525  * Put the input message into the msgstr. Truncate if necessary.
1526  */
1527 
1528  if (!messagestring)
1529  {
1530  strcpy(msgstr, "MOD_PR02. ");
1531  }
1532  else if (!strlen(messagestring))
1533  {
1534  strcpy(msgstr, "MOD_PR02. ");
1535  }
1536  else
1537  {
1538  strcpy(msgstr, "MOD_PR02:");
1539  if (messagestring[0] != '\n')
1540  strcat(msgstr, "\n");
1541  n = PGS_SMF_MAX_MSGBUF_SIZE - 1 - strlen(msgfmt) -
1542  strlen(timestr) - strlen(msgstr);
1543  if (strlen(messagestring) > n)
1544  messagestring[n] = '\0';
1545  strcat(msgstr, messagestring);
1546  n = strlen(msgstr);
1547  if (msgstr[n-1] != '\n')
1548  strcat(msgstr, "\n");
1549  }
1550 
1551  /*
1552  * Form the final message string.
1553  */
1554 
1555  sprintf(buf, msgfmt, msgstr, timestr);
1556 
1557  /*
1558  * Determine index of operator actions, based on exit code.
1559  */
1560 
1561  i = 0; imsg = 0;
1562  while (err_msg_info[i].name)
1563  {
1564  if (code == err_msg_info[i].value)
1565  {
1566  imsg = i;
1567  break;
1568  }
1569  i++;
1570  }
1571 
1572  /*
1573  * Determine string length of operator actions.
1574  */
1575 
1576  if (err_msg_info[imsg].actions)
1577  n = strlen(err_msg_info[imsg].actions);
1578  else
1579  n = 0;
1580 
1581  /*
1582  * If there is room, append the operator actions to the end of the message
1583  * buffer to be written. Otherwise, write the message buffer and the write
1584  * the operator actions separately.
1585  */
1586 
1587  if (n == 0)
1588  {
1589  WRITE_MSG(code,buf);
1590  }
1591  else if ((strlen(buf)+n) < PGS_SMF_MAX_MSGBUF_SIZE)
1592  {
1593  strcat(buf, err_msg_info[imsg].actions);
1594  WRITE_MSG(code,buf);
1595  }
1596  else
1597  {
1598  WRITE_MSG(code,buf);
1599  WRITE_MSG(code,err_msg_info[imsg].actions);
1600  }
1601 
1602  /*
1603  * Test to see if the code corresponds to a fatal error or if there was any
1604  * internal failure and then exit.
1605  */
1606 
1607  if ((PGS_SMF_TestFatalLevel(code)) == PGS_TRUE || internal_failure == PGS_TRUE)
1608  {
1609 
1611 
1612  }
1613 }
1614 
1615 void Bad_L1A_Error_Out(char *name, char *message)
1616 /*
1617 !C*******************************************************************
1618 !Description: This function posts a error message to log file including
1619  the name of the data and the description of the problem
1620  when bad L1A data are read.
1621 
1622 !Input Parameters:
1623  char * name the name of the data being read
1624  char * message error message
1625 
1626 !Output Parameters:
1627 
1628 !Revision History:
1629  (continue at top of the file)
1630 
1631  Revision 01.00 August 27, 1999
1632  Initial development
1633  Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
1634  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
1635 
1636 !Team-unique Header:
1637 
1638 !References and Credits:
1639  This software is developed by the MODIS Characterization Support
1640  Team (MCST)for the National Aeronautics and Space Administration,
1641  Goddard Space Flight Center, under contract NAS5-32373.
1642 
1643  HDF portions developed at the National Center for Supercomputing
1644  Applications at the University of Illinois at Urbana-Champaign.
1645 
1646 !Design Notes:
1647 
1648 
1649 !END********************************************************************
1650 */
1651 {
1652  char buffer [MAX_ERROR_MESSAGE_LENGTH];
1653  char *default_message = "Bad L1A data.\n";
1654  char *fmt = "\
1655 ERROR READING DATA FROM ONE OF THE MOD01 FILES INPUT TO PGE02.\n\
1656  Name of MOD01 data: %s\n\
1657  Error: %s\n\
1658 This error is due to:\n\
1659 (1) the MOD01 file is corrupted,\n\
1660 (2) the process MOD_PR01 (in PGE01) has a bug in it, or\n\
1661 (3) there is an address bug in MOD_PR02.";
1662 
1663  if (strlen(fmt) + strlen(name) + strlen(message) < MAX_ERROR_MESSAGE_LENGTH)
1664  sprintf(buffer, fmt, name, message);
1665  else
1666  sprintf(buffer, "%s", default_message);
1667 
1668  SMF_ERROR(MODIS_F_NOK, buffer);
1669 }
1670 
1671 
1672 PGSt_SMF_status Write_L1B_EV_Scan (int16 S,
1673  L1B_granule_t *L1B_Gran,
1674  L1B_Scan_t *L1B_Scan,
1675  boolean isdaymode)
1676 /*
1677 !C**********************************************************************
1678 !Description:
1679  This routine writes one scan of L1B EV data, including scaled integers,
1680  uncertainty indices and samples used, as appropriate. For a day-mode
1681  scan, all resolutions are written. For a night mode scan, only data
1682  for the emissive bands are written.
1683 
1684 !Input Parameters:
1685  int16 S current scan index
1686  L1B_granule_t *L1B_Gran
1687  L1B_Scan_t *L1B_Scan
1688  boolean isdaymode Flag denoting that scan is a day mode scan
1689  (if True)
1690 !Output Parameters:
1691 
1692 !Revision History:
1693  (continue at top of the file)
1694 
1695  Revision 03.10 May 13, 1999
1696  Added band 26 section.
1697  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
1698 
1699  Revision 03.00 March 1997
1700  Modified to match changes in L1B_Scan_t and in file spec;
1701  limited processing to EV data.
1702  Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
1703 
1704  Revision 02.00 1996/06/28
1705  New version using SDS_Services Currently corresponds to version 1 specification
1706  Neal Devine(neal.devine@gsfc.nasa.gov)
1707 
1708  Revision 01.01 1996/04/05
1709  Updated to match Version q Design Document
1710  Joan Baden(baden@highwire.gsfc.nasa.gov)
1711  John Hannon(hannon@highwire.gsfc.nasa.gov)
1712 
1713  Revision 01.00 1993
1714  Initial development
1715  Geir E. Kvaran(geir@highwire.gsfc.nasa.gov)
1716 
1717 !Team-unique Header:
1718 
1719 !References and Credits:
1720  This software is developed by the MODIS Characterization Support
1721  Team (MCST)for the National Aeronautics and Space Administration,
1722  Goddard Space Flight Center, under contract NAS5-32373.
1723 
1724  HDF portions developed at the National Center for Supercomputing
1725  Applications at the University of Illinois at Urbana-Champaign.
1726 
1727 !Design Notes:
1728  New version subsumes version 1 functions Write_L1B_PixelQuality,
1729  Write_L1B_EngMem, and Write_L1B_Slice, which are no longer needed.
1730 
1731 !END********************************************************************
1732 */
1733 {
1734  PGSt_SMF_status returnStatus;
1735  int16 R = 0;
1736  int32 start[3] = {0, 0, 0};
1737  int32 edge[3] = {0, 0, 0};
1738 
1739 /*------------------------------------------------------------------------------
1740  This macro writes a set of three EV_Aggr SDS's (SI & UI & SU)
1741 ------------------------------------------------------------------------------*/
1742 #define WRITE_EV_Aggr_SDS(SI_id, SI, UI_id, UI, SU_id, SU) \
1743  if(SDwritedata(SI_id,start,NULL,edge,SI) == FAIL) \
1744  return(MODIS_F_WRITE_ERROR); \
1745  if(SDwritedata(UI_id,start,NULL,edge,UI) == FAIL) \
1746  return(MODIS_F_WRITE_ERROR); \
1747  if(SDwritedata(SU_id,start,NULL,edge,SU) == FAIL) \
1748  return(MODIS_F_WRITE_ERROR)
1749 /*----------------------------------------------------------------------------*/
1750 
1751  if (S >= L1B_Gran->num_scans)
1752  return(MODIS_F_NO_MORE);
1753 
1754 /************************* Begin Band 26 Section **************************/
1755 #ifdef WRITE_BAND_26_SDS
1756  /*
1757  * Write this scan's worth of Band 26 data. These are always written,
1758  * regardless of day or night. Note that since these are 2D SDSs,
1759  * we pass in the address of start[1] and edge[1], since the last
1760  * two dimensions of the 3D EV SDSs are the same as the two
1761  * dimensions for these SDSs.
1762  */
1766  if (SDwritedata(L1B_Scan->Band26.SI_sds_id, &start[1], NULL, &edge[1],
1767  (VOIDP)L1B_Scan->Band26.SI) == FAIL)
1768  return(MODIS_F_WRITE_ERROR);
1769  if (SDwritedata(L1B_Scan->Band26.UI_sds_id, &start[1], NULL, &edge[1],
1770  (VOIDP)L1B_Scan->Band26.UI) == FAIL)
1771  return(MODIS_F_WRITE_ERROR);
1772 
1773 #endif /* WRITE_BAND_26_SDS */
1774 /************************** End Band 26 Section ***************************/
1775 
1776  for (R = 0; R < NUM_L1A_RESOLUTIONS; R++)
1777  {
1778  start[1] = S * DETECT_PER_BAND_AT_RES[R];
1779  edge[0] = L1B_BANDS_AT_RES[R];
1780  edge[1] = DETECT_PER_BAND_AT_RES[R];
1781  edge[2] = EV_1km_FRAMES * BAND_RATIO_AT_RES[R];
1782  if (!isdaymode && R != INDEX_1000M_EMISS)
1783  continue;
1784 
1785  returnStatus = Write_L1B_SI_UI(S, L1B_Scan, R);
1786  if (returnStatus != MODIS_S_OK)
1787  SMF_ERROR(returnStatus, "Write_L1B_SI_UI() in Write_L1B_EV_Scan(), Granule.c");
1788 
1789  switch(R)
1790  {
1791  case INDEX_250M:
1792  break;
1793 
1794  case INDEX_500M:
1795  edge[0] = L1B_BANDS_AT_RES[INDEX_250M];
1797  L1B_Scan->EV_250m_Aggr500m_RefSB,
1799  L1B_Scan->EV_250m_Aggr500m_RefSB_UI,
1801  L1B_Scan->EV_250m_Aggr500m_RefSB_SU);
1802  break;
1803 
1804  case INDEX_1000M_REFL:
1805  edge[0] = L1B_BANDS_AT_RES[INDEX_250M];
1807  L1B_Scan->EV_250m_Aggr1km_RefSB,
1809  L1B_Scan->EV_250m_Aggr1km_RefSB_UI,
1811  L1B_Scan->EV_250m_Aggr1km_RefSB_SU);
1812 
1813  edge[0] = L1B_BANDS_AT_RES[INDEX_500M];
1815  L1B_Scan->EV_500m_Aggr1km_RefSB,
1817  L1B_Scan->EV_500m_Aggr1km_RefSB_UI,
1819  L1B_Scan->EV_500m_Aggr1km_RefSB_SU);
1820  break;
1821 
1822  case INDEX_1000M_EMISS:
1823  ;
1824  }/*End of switch*/
1825  }/*End of loop over R: L1A_resolution*/
1826 
1827  return(MODIS_S_OK);
1828 }
1829 
1830 
1831 PGSt_SMF_status Write_L1B_SI_UI (int16 S, L1B_Scan_t *L1B_Scan, int16 R)
1832 /*
1833 !C**********************************************************************
1834 !Description:
1835  For a given resolution, this routine writes one scan of L1B EV scaled
1836  integer and uncertainty index data to the appropriate L1B granule.
1837 
1838 !Input Parameters:
1839  int16 S current scan index
1840  L1B_Scan_t *L1B_Scan
1841  int16 R
1842 !Output Parameters:
1843 
1844 !Revision History:
1845  (continue at top of the file)
1846 
1847  Revision 01.00 1998
1848  Initial development
1849  Zhenying Gu(zgu@ltpmail.gsfc.nasa.gov)
1850 
1851 !Team-unique Header:
1852 
1853 !References and Credits:
1854  This software is developed by the MODIS Characterization Support
1855  Team (MCST)for the National Aeronautics and Space Administration,
1856  Goddard Space Flight Center, under contract NAS5-32373.
1857 
1858  HDF portions developed at the National Center for Supercomputing
1859  Applications at the University of Illinois at Urbana-Champaign.
1860 
1861 !Design Notes:
1862 
1863 !END********************************************************************
1864 */
1865 {
1866  int32 start[3] = {0, 0, 0};
1867  int32 edge[3] = {0, 0, 0};
1868  start[1] = S * DETECT_PER_BAND_AT_RES[R];
1869  edge[0] = L1B_BANDS_AT_RES[R];
1870  edge[1] = DETECT_PER_BAND_AT_RES[R];
1871  edge[2] = EV_1km_FRAMES * BAND_RATIO_AT_RES[R];
1872 
1873  if ((RFLAG & (1 << R)) != 0) return(MODIS_S_OK);
1874 
1875  switch (R){
1876  case 0:
1877  if (SDwritedata(L1B_Scan->SI_sds_id[R], start, NULL, edge,
1878  (VOIDP)L1B_Scan->SI.EV_250m_RefSB) == FAIL)
1879  return(MODIS_F_WRITE_ERROR);
1880  if (SDwritedata(L1B_Scan->UI_sds_id[R], start, NULL, edge,
1881  (VOIDP)L1B_Scan->UI.EV_250m_RefSB_UI) == FAIL)
1882  return(MODIS_F_WRITE_ERROR);
1883  break;
1884 
1885  case 1:
1886  if (SDwritedata(L1B_Scan->SI_sds_id[R], start, NULL, edge,
1887  (VOIDP)L1B_Scan->SI.EV_500m_RefSB) == FAIL)
1888  return(MODIS_F_WRITE_ERROR);
1889  if (SDwritedata(L1B_Scan->UI_sds_id[R], start, NULL, edge,
1890  (VOIDP)L1B_Scan->UI.EV_500m_RefSB_UI) == FAIL)
1891  return(MODIS_F_WRITE_ERROR);
1892  break;
1893 
1894  case 2:
1895  if (SDwritedata(L1B_Scan->SI_sds_id[R], start, NULL, edge,
1896  (VOIDP)L1B_Scan->SI.EV_1km_RefSB) == FAIL)
1897  return(MODIS_F_WRITE_ERROR);
1898  if (SDwritedata(L1B_Scan->UI_sds_id[R], start, NULL, edge,
1899  (VOIDP)L1B_Scan->UI.EV_1km_RefSB_UI) == FAIL)
1900  return(MODIS_F_WRITE_ERROR);
1901  break;
1902 
1903  case 3:
1904  if (SDwritedata(L1B_Scan->SI_sds_id[R], start, NULL, edge,
1905  (VOIDP)L1B_Scan->SI.EV_1km_Emissive) == FAIL)
1906  return(MODIS_F_WRITE_ERROR);
1907  if (SDwritedata(L1B_Scan->UI_sds_id[R], start, NULL, edge,
1908  (VOIDP)L1B_Scan->UI.EV_1km_Emissive_UI) == FAIL)
1909  return(MODIS_F_WRITE_ERROR);
1910  break;
1911 
1912  default: break;
1913  }
1914 
1915  return(MODIS_S_OK);
1916 }
1917 
1918 PGSt_SMF_status Fill_Dead_Detector_SI (boolean isdaymode,
1919  int8 *dead_detector,
1920  L1B_Scan_t *L1B_Scan,
1921  L1B_granule_t *L1B_Gran,
1922  QA_Common_t *QA_Common)
1923 /*
1924 !C************************************************************************
1925 !Description:
1926  This function fills in reasonable pixel values in one Level 1B EV
1927  product file SDSs, for pixels that correspond to dead detectors.
1928  Values from adjacent (live) detectors are used to determine the values
1929  to assign to the dead-detector pixels. If possible, a linear average
1930  from adjacent pixels is calculated. This operation is applied only to
1931  the native resolution L1B data sets, not aggregated data sets.
1932 
1933 !Input Parameters:
1934  boolean isdaymode A flag that denotes that the scan is a
1935  day-mode scan. Some RSB SDSs are computed only
1936  if the scan is a day-mode scan.
1937  int8 *dead_detector Array spanning 490 MODIS detectors which
1938  identifies a non-functional detector (if = 1).
1939  L1B_Scan_t *L1B_Scan Scan data to be written to the EV products.
1940  Includes the scaled integers that may be
1941  modified.
1942 
1943 !Output Parameters:
1944  L1B_Scan_t *L1B_Scan SI pixel values corresponding to dead detectors
1945  may be changed. Other values should be unchanged.
1946  L1B_granule_t *L1B_Gran Contains interpolated pixel values for each band.
1947  QA_Common_t *QA_Common Contains number of dead detector EV data for each
1948  detector.
1949 
1950 !Revision History:
1951  (continue at top of the file)
1952 
1953  Revision 01.01 March 2003, Razor Issue #173
1954  Initialized SI, SI_prev,and SI_subs to 0 for ANSI-C compliance.
1955  Liqin Tan, SAIC GSO (ltan@saicmodis.com)
1956 
1957  Revision 01.00 June 15, 2000
1958  Initial development
1959  Jim Rogers (rogers@mcst.gfsc.nasa.gov)
1960 
1961 !Team-unique Header:
1962  This software is developed by the MODIS Science Data Support
1963  Team for the National Aeronautics and Space Administration,
1964  Goddard Space Flight Center, under contract NAS5-32373.
1965 
1966 !References and Credits:
1967  HDF portions developed at the National Center for Supercomputing
1968  Applications at the University of Illinois at Urbana-Champaign.
1969 
1970 !Design Notes:
1971 
1972  The change is accomplished on a scan-by-scan basis on the native-resolution
1973  SDSs only. No artificial values are used in forming aggregated SI values.
1974  There is no "cross-over" of information between scans. The logic is as
1975  follows. If a detector is flagged as "dead" by the detector quality flag
1976  LUT, then the SI values of nearest "live" detectors in the same frame and
1977  subsample are used to form a linear average value for the dead detector SI
1978  value. This linear average is accomplished independently for each frame and
1979  subsample of the scan line of the dead detector. There are conditions
1980  checked for:
1981 
1982  1) if the dead detector is either the first or last detector in the set,
1983  then the second or next-to-last value is simply copied (no linear average).
1984 
1985  2) if an adjacent value to be used in either averaging or copying is an
1986  "unusable" value (>32767), then it is not used to form the artificial value.
1987  For example, if we started off with two values to form a linear average but
1988  one of the values is unusable, then the remaining valid value is simply
1989  copied.
1990 
1991  3) If there are no usable values available to form the artificial value,
1992  then the pixel value remains at 65533 (the "dead detector" SI value).
1993 
1994  In the product, users may read the "Dead Detector List" attribute to
1995  determine which detectors were classified as dead and thus which scan lines
1996  may have the artificial values filled in.
1997 
1998 !END**********************************************************************
1999 */
2000 {
2001  /* Define order and number of SDSs that may need to be modified.
2002  * These are in different multi-dimensional arrays.
2003  */
2004 
2005 typedef enum {
2006 #ifdef WRITE_BAND_26_SDS
2007  FDD_RSB_BAND26,
2008 #endif /* WRITE_BAND_26_SDS */
2009  FDD_RSB_250M,
2010  FDD_RSB_500M,
2011  FDD_RSB_1KM_DAY,
2012  FDD_TEB_1KM,
2013  NUM_FDD_DATA_SETS
2014 } data_set_enum_t;
2015 #define MAX_BANDS_PER_FDD_SET 16
2016 
2017  /* Declare arrays which describe features (such as dimensions)
2018  * of the SDSs.
2019  */
2020 
2021  int32 num_bands_per_set[NUM_FDD_DATA_SETS] =
2022  {
2023 #ifdef WRITE_BAND_26_SDS
2024  1,
2025 #endif /* WRITE_BAND_26_SDS */
2030  };
2031 
2032  int32 num_dets_per_set[NUM_FDD_DATA_SETS] =
2033  {
2034 #ifdef WRITE_BAND_26_SDS
2036 #endif /* WRITE_BAND_26_SDS */
2041  };
2042 
2043  int32 num_frames_per_set[NUM_FDD_DATA_SETS] =
2044  {
2045 #ifdef WRITE_BAND_26_SDS
2046  EV_1km_FRAMES,
2047 #endif /* WRITE_BAND_26_SDS */
2050  EV_1km_FRAMES,
2052  };
2053 
2054  /* The following denotes whether the data set is "Day" only */
2055 
2056  boolean isdayonly[NUM_FDD_DATA_SETS] =
2057  {
2058 #ifdef WRITE_BAND_26_SDS
2059  False,
2060 #endif /* WRITE_BAND_26_SDS */
2061  True,
2062  True,
2063  True,
2064  False
2065  };
2066 
2067  boolean qa_flag; /* to check if the qa parameter values for band 26 is
2068  * already adjusted.
2069  */
2070 
2071  /* We will use dead_detector to fill the array below.
2072  * This is static because values are determined one time
2073  * and then saved for subsequent scans.
2074  */
2075 
2076  static int8 dead_det_array [NUM_FDD_DATA_SETS][MAX_BANDS_PER_FDD_SET]
2078 
2079  /* The following static variable is used to determine if we have
2080  * already defined the above array (we only need to fill it for
2081  * one scan -- it is the same for all scans).
2082  */
2083 
2084  static boolean dead_det_array_is_filled = False;
2085 
2086  /* The following static variables is used to map the index of
2087  * bands through all bands to the index of bands within each L1A
2088  * resolution.
2089  */
2090 
2091  static int8 band_38[NUM_FDD_DATA_SETS][MAX_BANDS_PER_FDD_SET];
2092 
2093  /* The following static variables is used to map the index of
2094  * detectors through all detectors to the index of detectors within
2095  * each band within each L1A resolution.
2096  */
2097 
2098  static int16 det_490[NUM_FDD_DATA_SETS][MAX_BANDS_PER_FDD_SET]
2100 
2101  int32 R; /* Index through L1A resolutions */
2102  int32 B; /* Index through bands within one L1A resolution */
2103  int32 B_38; /* Index through all bands, in order */
2104  int32 D; /* Index through detectors within a band */
2105  int32 D_490; /* Index through all detectors, in order */
2106  int32 B_emiss; /* Index through L1B emissive bands */
2107  int32 B26_RSB; /* index of band 26 inside L1B RSB band set */
2108  int32 D_prev; /* index of previous detector. */
2109  int32 D_subs; /* index of subsequent detector. */
2110  int32 iset; /* index of data set being operated on */
2111  int32 F; /* Frame index (frame and sample) */
2112 
2113  PGSt_SMF_status returnStatus = MODIS_S_OK;
2114  char *location = "Fill_Dead_Detector_SI";
2115 
2116  /* Utility pointers -- to an array of frames */
2117 
2118  uint16 *SI = 0; /* SI for scan line in question */
2119  uint16 *SI_prev = 0; /* SI for previous scan line */
2120  uint16 *SI_subs = 0; /* SI for subsequent scan line */
2121 
2122  /************************* Declarations complete ***********************/
2123 
2124 
2125  if (dead_det_array_is_filled == False)
2126  {
2127 
2128  /* Assemble new dead detector array having more convenient
2129  * dimensionality.
2130  */
2131 
2132  /* Initialize to a bad value so we can check later */
2133 
2134  for (iset = 0; iset < NUM_FDD_DATA_SETS; iset++)
2135  {
2136  for (B = 0; B < MAX_BANDS_PER_FDD_SET; B++)
2137  {
2138  for (D = 0; D < MAX_DETECTORS_PER_BAND; D++)
2139  {
2140  dead_det_array [iset][B][D] = -1;
2141  }
2142  }
2143  }
2144 
2145  /* Fill the 3D dead detector array. */
2146 
2147  B_38 = 0;
2148  D_490 = 0;
2149  R = INDEX_250M;
2150  for (B = 0; B < L1A_BANDS_AT_RES[R]; B++, B_38++)
2151  {
2152  band_38[FDD_RSB_250M][B] = B_38;
2153  for (D = 0; D < DETECT_PER_BAND_AT_RES[R]; D++, D_490++)
2154  {
2155  dead_det_array[FDD_RSB_250M][B][D] = dead_detector[D_490];
2156  det_490[FDD_RSB_250M][B][D] = D_490;
2157  }
2158  }
2159  R = INDEX_500M;
2160  for (B = 0; B < L1A_BANDS_AT_RES[R]; B++, B_38++)
2161  {
2162  band_38[FDD_RSB_500M][B] = B_38;
2163  for (D = 0; D < DETECT_PER_BAND_AT_RES[R]; D++, D_490++)
2164  {
2165  dead_det_array[FDD_RSB_500M][B][D] = dead_detector[D_490];
2166  det_490[FDD_RSB_500M][B][D] = D_490;
2167  }
2168  }
2169  R = INDEX_1000M_DAY;
2170  for (B = 0; B < L1A_BANDS_AT_RES[R]; B++, B_38++)
2171  {
2172  band_38[FDD_RSB_1KM_DAY][B] = B_38;
2173  for (D = 0; D < DETECT_PER_BAND_AT_RES[R]; D++, D_490++)
2174  {
2175  dead_det_array[FDD_RSB_1KM_DAY][B][D] = dead_detector[D_490];
2176  det_490[FDD_RSB_1KM_DAY][B][D] = D_490;
2177  }
2178  }
2179  R = INDEX_1000M_NIGHT;
2180  B_emiss = 0;
2181  B26_RSB = L1B_BANDS_AT_RES[INDEX_1000M_DAY] - 1;
2182  for (B = 0; B < L1A_BANDS_AT_RES[R]; B++, B_38++)
2183  {
2184  if (B == MODIS_BAND26_INDEX_AT_RES)
2185  {
2186  band_38[FDD_RSB_1KM_DAY][B26_RSB] = B_38;
2187 #ifdef WRITE_BAND_26_SDS
2188  band_38[FDD_RSB_BAND26][0] = B_38;
2189 #endif /* WRITE_BAND_26_SDS */
2190 
2191  for (D = 0; D < DETECT_PER_BAND_AT_RES[R]; D++, D_490++)
2192  {
2193  dead_det_array[FDD_RSB_1KM_DAY][B26_RSB][D] = dead_detector[D_490];
2194  det_490[FDD_RSB_1KM_DAY][B26_RSB][D] = D_490;
2195 #ifdef WRITE_BAND_26_SDS
2196  dead_det_array[FDD_RSB_BAND26][0][D] = dead_detector[D_490];
2197  det_490[FDD_RSB_BAND26][0][D] = D_490;
2198 #endif /* WRITE_BAND_26_SDS */
2199  }
2200  }
2201  else
2202  {
2203  band_38[FDD_TEB_1KM][B_emiss] = B_38;
2204  for (D = 0; D < DETECT_PER_BAND_AT_RES[R]; D++, D_490++)
2205  {
2206  dead_det_array[FDD_TEB_1KM][B_emiss][D] = dead_detector[D_490];
2207  det_490[FDD_TEB_1KM][B_emiss][D] = D_490;
2208  }
2209  B_emiss++;
2210  }
2211  }
2212 
2213  /* Check for a bad value -- make sure we assigned each one. */
2214 
2215  for (iset = 0; iset < NUM_FDD_DATA_SETS; iset++)
2216  {
2217  for (B = 0; B < num_bands_per_set[iset]; B++)
2218  {
2219  for (D = 0; D < num_dets_per_set[iset]; D++)
2220  {
2221  if (dead_det_array [iset][B][D] == -1)
2222  {
2223  returnStatus = MODIS_F_NOK;
2224  L1BErrorMsg(location, returnStatus,
2225  "Dead detector array values not properly assigned.",
2226  NULL, 0, NULL, True);
2227  return returnStatus;
2228  }
2229  }
2230  }
2231  }
2232 
2233  dead_det_array_is_filled = True;
2234  }
2235 
2236  /* Main loop through all data sets. */
2237 
2238  for (iset = 0; iset < NUM_FDD_DATA_SETS; iset++)
2239  {
2240 
2241  /* Skip this set if it is day only and scan is not day */
2242 
2243  if (isdaymode == False && isdayonly[iset] == True)
2244  continue;
2245 
2246  /* Loop through bands in this data set */
2247 
2248  for (B = 0; B < num_bands_per_set[iset]; B++)
2249  {
2250  B_38 = band_38[iset][B];
2251 
2252  qa_flag = True;
2253 
2254 #ifdef WRITE_BAND_26_SDS
2255  if (iset != FDD_RSB_BAND26 && B_38 == MODIS_BAND26_INDEX)
2256  qa_flag = False;
2257 #endif /* WRITE_BAND_26_SDS */
2258 
2259  /* Loop through detectors */
2260 
2261  for (D = 0; D < num_dets_per_set[iset]; D++)
2262  {
2263 
2264  /* If this detector is not "dead", skip it.
2265  * (leave pixels as they are).
2266  */
2267 
2268  if (dead_det_array[iset][B][D] == 0)
2269  continue;
2270 
2271  /* Determine D_prev by going back
2272  * and finding the 1st non-dead detector.
2273  */
2274 
2275  D_prev = D - 1;
2276  while (D_prev >= 0)
2277  {
2278  if (dead_det_array[iset][B][D_prev] == 0)
2279  break;
2280  D_prev--;
2281  }
2282 
2283  /* Determine D_subs in a similar way. */
2284 
2285  D_subs = D + 1;
2286  while (D_subs < num_dets_per_set[iset])
2287  {
2288  if (dead_det_array[iset][B][D_subs] == 0)
2289  break;
2290  D_subs++;
2291  }
2292 
2293  if (D_subs == num_dets_per_set[iset])
2294  D_subs = -1;
2295 
2296  /* If both D_prev and D_subs are invalid, continue
2297  * (omit this detector)
2298  */
2299 
2300  if (D_prev == -1 && D_subs == -1)
2301  continue;
2302 
2303  if (D_prev == D_subs) /*** Should not happen ***/
2304  continue;
2305 
2306  /* Assign the data to be used for filling in values */
2307 
2308 #ifdef WRITE_BAND_26_SDS
2309  if (iset == FDD_RSB_BAND26)
2310  {
2311  SI = L1B_Scan->Band26.SI[D];
2312  if (D_prev >= 0)
2313  SI_prev = L1B_Scan->Band26.SI[D_prev];
2314  if (D_subs >= 0)
2315  SI_subs = L1B_Scan->Band26.SI[D_subs];
2316  }
2317 
2318  else
2319 #endif /* WRITE_BAND_26_SDS */
2320  if (iset == FDD_RSB_250M)
2321  {
2322  SI = L1B_Scan->SI.EV_250m_RefSB[B][D];
2323  if (D_prev >= 0)
2324  SI_prev = L1B_Scan->SI.EV_250m_RefSB[B][D_prev];
2325  if (D_subs >= 0)
2326  SI_subs = L1B_Scan->SI.EV_250m_RefSB[B][D_subs];
2327  }
2328 
2329  else if (iset == FDD_RSB_500M)
2330  {
2331  SI = L1B_Scan->SI.EV_500m_RefSB[B][D];
2332  if (D_prev >= 0)
2333  SI_prev = L1B_Scan->SI.EV_500m_RefSB[B][D_prev];
2334  if (D_subs >= 0)
2335  SI_subs = L1B_Scan->SI.EV_500m_RefSB[B][D_subs];
2336  }
2337 
2338  else if (iset == FDD_RSB_1KM_DAY)
2339  {
2340  SI = L1B_Scan->SI.EV_1km_RefSB[B][D];
2341  if (D_prev >= 0)
2342  SI_prev = L1B_Scan->SI.EV_1km_RefSB[B][D_prev];
2343  if (D_subs >= 0)
2344  SI_subs = L1B_Scan->SI.EV_1km_RefSB[B][D_subs];
2345  }
2346 
2347  else if (iset == FDD_TEB_1KM)
2348  {
2349  SI = L1B_Scan->SI.EV_1km_Emissive[B][D];
2350  if (D_prev >= 0)
2351  SI_prev = L1B_Scan->SI.EV_1km_Emissive[B][D_prev];
2352  if (D_subs >= 0)
2353  SI_subs = L1B_Scan->SI.EV_1km_Emissive[B][D_subs];
2354  }
2355 
2356  /* At long last, fill the array of values to be written */
2357 
2358  D_490 = det_490[iset][B][D];
2359 
2360  if (D_prev == -1)
2361  {
2362  for (F = 0; F < num_frames_per_set[iset]; F++)
2363  {
2364  if (SI_subs[F] <= DN15_SAT && SI[F] == DEAD_DETECTOR_SI)
2365  {
2366  SI[F] = SI_subs[F];
2367  if (qa_flag)
2368  {
2369  L1B_Gran->interpolated_pixels[B_38]++;
2370  L1B_Gran->valid_pixels[B_38]++;
2371  QA_Common->num_dead_detector_EV_data[D_490]--;
2372  }
2373  }
2374  }
2375  }
2376 
2377  else if (D_subs == -1)
2378  {
2379  for (F = 0; F < num_frames_per_set[iset]; F++)
2380  {
2381  if (SI_prev[F] <= DN15_SAT && SI[F] == DEAD_DETECTOR_SI)
2382  {
2383  SI[F] = SI_prev[F];
2384  if (qa_flag)
2385  {
2386  L1B_Gran->interpolated_pixels[B_38]++;
2387  L1B_Gran->valid_pixels[B_38]++;
2388  QA_Common->num_dead_detector_EV_data[D_490]--;
2389  }
2390  }
2391  }
2392  }
2393 
2394  else
2395  {
2396  float32 fract = ((float32) (D - D_prev)) /
2397  ((float32) (D_subs - D_prev));
2398  for (F = 0; F < num_frames_per_set[iset]; F++)
2399  {
2400  if (SI_subs[F] <= DN15_SAT && SI_prev[F] <= DN15_SAT &&
2401  SI[F] == DEAD_DETECTOR_SI)
2402  {
2403  SI[F] = (uint16)((float32)SI_prev[F] +
2404  (fract * ((float32)SI_subs[F] -
2405  (float32)SI_prev[F])));
2406  if (qa_flag)
2407  {
2408  L1B_Gran->interpolated_pixels[B_38]++;
2409  L1B_Gran->valid_pixels[B_38]++;
2410  QA_Common->num_dead_detector_EV_data[D_490]--;
2411  }
2412  }
2413 
2414  else if (SI_subs[F] <= DN15_SAT &&
2415  SI[F] == DEAD_DETECTOR_SI)
2416  {
2417  SI[F] = SI_subs[F];
2418  if (qa_flag)
2419  {
2420  L1B_Gran->interpolated_pixels[B_38]++;
2421  L1B_Gran->valid_pixels[B_38]++;
2422  QA_Common->num_dead_detector_EV_data[D_490]--;
2423  }
2424  }
2425 
2426  else if (SI_prev[F] <= DN15_SAT &&
2427  SI[F] == DEAD_DETECTOR_SI)
2428  {
2429  SI[F] = SI_prev[F];
2430  if (qa_flag)
2431  {
2432  L1B_Gran->interpolated_pixels[B_38]++;
2433  L1B_Gran->valid_pixels[B_38]++;
2434  QA_Common->num_dead_detector_EV_data[D_490]--;
2435  }
2436  }
2437  }
2438  }
2439 
2440  } /* loop through D */
2441  } /* loop through B */
2442  } /* loop through iset */
2443 
2444 
2445  return returnStatus;
2446 }
2447 
2448 PGSt_SMF_status Open_and_Read_L1A
2449  (Run_Time_Parameters_t *runtime_params,
2450  L1A_granule_t *L1A_Gran,
2451  boolean *skip_night_hi_res)
2452 
2453 /*
2454 !C**************************************************************************
2455 !Description: This function opens the L1A granule to be processed and reads
2456  in data for all members of the L1A_granule_t structure. The
2457  file remains open (both SD and Vdata) upon function exit.
2458 
2459 !Input Parameters:
2460  Run_Time_Parameters_t *runtime_params Values read from PCF file.
2461 
2462 !Output Parameters:
2463  L1A_granule_t *L1A_Gran contains SD file interface ID, Vdata
2464  file interface ID, number of scans and
2465  other data relating to the middle
2466  granule
2467 
2468 !Revision History:
2469  (continue at top of the file)
2470 
2471  Revision 01.02 June 4, 2002 Razor Issue #169
2472  Changed logic to check whether any scans are in day mode and if so, set
2473  skip_night_hi_res to False.
2474  Gwyn Fireman & Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
2475 
2476  Revision 01.01 November 12, 2001 (Razor Issue #169)
2477  Added boolean skip_night_hi_res as output variable.
2478  Alice Isaacman (Alice.R.Isaacman.1@gsfc.nasa.gov), SAIC GSO
2479 
2480  Revision 01.00 June 27, 2000
2481  Initial development.
2482  Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
2483 
2484 !Team-unique Header:
2485  This software is developed by the MODIS Science Data Support
2486  Team for the National Aeronautics and Space Administration,
2487  Goddard Space Flight Center, under contract NAS5-32373.
2488 
2489 !References and Credits
2490  HDF portions developed at the National Center for Supercomputing
2491  Applications at the University of Illinois at Urbana-Champaign.
2492 
2493 !Design Notes:
2494 !END********************************************************************
2495 */
2496 {
2497  PGSt_SMF_status returnStatus = MODIS_S_OK;
2498  intn hdf_return = 0;
2499  PGSt_integer Version = 1;
2500  char file_name[PGSd_PC_FILE_PATH_MAX];
2501  int32 S; /* scan index */
2502  int32 middle_scan;
2503  int32 geo_satellite_id;
2504  char *location = "Open_and_Read_L1A";
2505  char *satelliteInstrument;
2506 
2507  /*
2508  * Will be set to TRUE by PCF file only if writing 250m and
2509  * 500m files when in night mode is desired.
2510  */
2511  boolean write_nightmode_hires = 0;
2512  boolean is_nightmode_data = 0;
2513 
2514  /*
2515  * Prepare for opening file: convert logical ID to physical name
2516  */
2517 
2518  returnStatus = PGS_PC_GetReference (FIRST_L1A_GRANULE, &Version, file_name);
2519  if (returnStatus != PGS_S_SUCCESS)
2520  {
2521  returnStatus = MODIS_F_FILE_NOT_FOUND;
2522  L1BErrorMsg(location, returnStatus, "Could not retrieve file name from PCF.",
2523  "PGS_PC_GetReference", FIRST_L1A_GRANULE, NULL, True);
2524  return returnStatus;
2525  }
2526 
2527  /*
2528  * Open file for HDF science data (SD) access.
2529  */
2530 
2531  L1A_Gran->sd_id = SDstart(file_name,DFACC_RDONLY); /*for SD interface */
2532  if (L1A_Gran->sd_id == FAIL)
2533  {
2534  returnStatus = MODIS_F_FILE_NOT_OPENED;
2535  L1BErrorMsg(location, returnStatus, "Could not open file for SD read access.",
2536  "SDstart", FIRST_L1A_GRANULE,
2537  "The file may be missing, corrupted or not an HDF-4 file.", True);
2538  return returnStatus;
2539  }
2540 
2541  /*
2542  * Open file for HDF Vdata access and initialize Vdata interface.
2543  * Call Hopen() and Vstart() in the same place.
2544  */
2545 
2546  L1A_Gran->v_id = Hopen(file_name,DFACC_RDONLY,0);
2547  if (L1A_Gran->v_id == FAIL)
2548  {
2549  SDend (L1A_Gran->sd_id);
2550  returnStatus = MODIS_F_FILE_NOT_OPENED;
2551  L1BErrorMsg(location, returnStatus, "Could not open file for Vdata read access.",
2552  "Hopen", FIRST_L1A_GRANULE,
2553  "The file may be corrupted or not an HDF-4 file.", True);
2554  return returnStatus;
2555  }
2556 
2557  hdf_return = Vstart (L1A_Gran->v_id); /*initialize internal structures*/
2558  if (hdf_return == FAIL)
2559  {
2560  SDend (L1A_Gran->sd_id); Hclose (L1A_Gran->v_id);
2561  returnStatus = MODIS_F_HDF_ERROR;
2562  L1BErrorMsg(location, returnStatus, "Could not initialize Vdata interface.",
2563  "Vstart", FIRST_L1A_GRANULE,
2564  "The file may be corrupted or not an HDF-4 file.", True);
2565  return returnStatus;
2566  }
2567 
2568  /*
2569  * Read num_scans
2570  */
2571 
2572  returnStatus = read_attribute (L1A_Gran->sd_id, "Number of Scans",
2573  DFNT_INT32, (void *)&L1A_Gran->num_scans);
2574  if (returnStatus != MODIS_S_OK)
2575  {
2576  L1BErrorMsg(location, returnStatus, "Could not read Number of Scans.",
2577  "read_attribute", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True);
2578  return returnStatus;
2579  }
2580 
2581  if (L1A_Gran->num_scans <= 0)
2582  {
2583  returnStatus = MODIS_F_OUT_OF_RANGE;
2585  L1BErrorMsg(location, returnStatus,
2586  "Number of Scans in the MOD01 granule is less than "
2587  "or equal to 0.\n"
2588  "The MOD01 granule is probably empty (no valid data)",
2590  return returnStatus;
2591  }
2592 
2593  if (L1A_Gran->num_scans > MAX_NUM_SCANS)
2594  {
2595  returnStatus = MODIS_F_OUT_OF_RANGE;
2596  L1BErrorMsg(location, returnStatus,
2597  "Number of Scans in the MOD01 granule is greater "
2598  "than MAX_NUM_SCANS.",
2600  "If the file is valid, the code macro must be increased.", True);
2601  return returnStatus;
2602  }
2603 
2604  /*
2605  * Read num_day_scans
2606  */
2607 
2608  returnStatus = read_attribute (L1A_Gran->sd_id, "Number of Day mode scans",
2609  DFNT_INT32, (VOIDP)&L1A_Gran->num_day_scans);
2610  if (returnStatus != MODIS_S_OK)
2611  {
2612  L1BErrorMsg(location, returnStatus, "Could not read Number of Day "
2613  "mode scans.",
2614  "read_attribute", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True);
2615  return returnStatus;
2616  }
2617 
2618  /*
2619  * Set skip_night_hi_res flag
2620  */
2621 
2622  if (strcmp(runtime_params->Write_Night_Mode_HiRes_Data, "0") == 0)
2623  write_nightmode_hires = False;
2624  else
2625  write_nightmode_hires = True;
2626 
2627  if (L1A_Gran->num_day_scans == 0)
2628  is_nightmode_data = True;
2629  else
2630  is_nightmode_data = False;
2631 
2632  if (is_nightmode_data == True && write_nightmode_hires == False)
2633  *skip_night_hi_res = True;
2634  else
2635  *skip_night_hi_res = False;
2636 
2637  /*
2638  * Read L1A ScanType
2639  */
2640 
2641  returnStatus = read_sds_rank2 (L1A_Gran->sd_id, "Scan Type",
2642  L1A_Gran->num_scans, SCAN_TYPE_TEXT_SIZE,
2643  (void *)L1A_Gran->ScanType);
2644  if (returnStatus != MODIS_S_OK)
2645  {
2646  L1BErrorMsg(location, returnStatus, "Could not read Scan Type.",
2647  "read_sds_rank2", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True);
2648  return returnStatus;
2649  }
2650 
2651  for (S = 0; S < L1A_Gran->num_scans; S++)
2652  {
2653  if (strcmp(L1A_Gran->ScanType[S], "Day") != 0 &&
2654  strcmp(L1A_Gran->ScanType[S], "Night") != 0 &&
2655  strcmp(L1A_Gran->ScanType[S], "Other") != 0)
2656  {
2657  returnStatus = MODIS_F_OUT_OF_RANGE;
2658  L1BErrorMsg(location, returnStatus,
2659  "Scan Type is not \"Day\", \"Night\", or \"Other\".",
2661  return returnStatus;
2662  }
2663  }
2664 
2665  /*
2666  * Read L1A EVStartTime_TAIsecond
2667  */
2668 
2669  returnStatus = read_sds_rank1 (L1A_Gran->sd_id, "EV start time",
2670  L1A_Gran->num_scans,
2671  (void *)L1A_Gran->EVStartTime_TAIsecond);
2672  if (returnStatus != MODIS_S_OK)
2673  {
2674  L1BErrorMsg(location, returnStatus, "Could not read EV start time.",
2675  "read_sds_rank1", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True);
2676  return returnStatus;
2677  }
2678 
2679  /*
2680  * Determine data collection time. The valid EV start time for the scan
2681  * closest to the middle scan is chosen to be the data collection time.
2682  * This time is used for time-dependent look up tables.
2683  */
2684 
2685  middle_scan = L1A_Gran->num_scans/2;
2686  L1A_Gran->data_collection_time = 0;
2687  for (S = 0; middle_scan-S >= 0 &&
2688  middle_scan+S < L1A_Gran->num_scans; S++) {
2689  if (L1A_Gran->EVStartTime_TAIsecond[middle_scan-S] > 0) {
2690  L1A_Gran->data_collection_time =
2691  L1A_Gran->EVStartTime_TAIsecond[middle_scan-S];
2692  break;
2693  }
2694  else if (L1A_Gran->EVStartTime_TAIsecond[middle_scan+S] > 0) {
2695  L1A_Gran->data_collection_time =
2696  L1A_Gran->EVStartTime_TAIsecond[middle_scan+S];
2697  break;
2698  }
2699  }
2700 
2701  if (L1A_Gran->data_collection_time == 0) {
2702  returnStatus = MODIS_F_NOK;
2703  L1BErrorMsg(location, returnStatus,
2704  "No valid or only one valid EV start time in the "
2705  "array \"EV start time\"",
2706  NULL, 0, NULL, True);
2707  return returnStatus;
2708  }
2709 
2710  /*
2711  * Read L1A MirrorSide
2712  */
2713 
2714  returnStatus = read_sds_rank1 (L1A_Gran->sd_id, "Mirror side",
2715  L1A_Gran->num_scans,
2716  (void *)L1A_Gran->MirrorSide);
2717  if ( returnStatus != MODIS_S_OK)
2718  {
2719  L1BErrorMsg(location, returnStatus, "Could not read Mirror side.",
2720  "read_sds_rank1", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True);
2721  return returnStatus;
2722  }
2723 
2724  for (S = 0; S < L1A_Gran->num_scans; S++)
2725  {
2726  if (L1A_Gran->MirrorSide[S] != 0 && L1A_Gran->MirrorSide[S] != 1
2727  && L1A_Gran->MirrorSide[S] != -1)
2728  {
2729  returnStatus = MODIS_F_OUT_OF_RANGE;
2730  L1BErrorMsg(location, returnStatus, "Mirror side is not [-1, 0, 1].",
2732  return returnStatus;
2733  }
2734  }
2735 
2736  /*
2737  * Read num_night_scans
2738  */
2739 
2740  returnStatus = read_attribute (L1A_Gran->sd_id,
2741  "Number of Night mode scans",
2742  DFNT_INT32,
2743  (VOIDP)&L1A_Gran->num_night_scans);
2744  if (returnStatus != MODIS_S_OK)
2745  {
2746  L1BErrorMsg(location, returnStatus,
2747  "Could not read Number of Night mode scans.",
2748  "read_attribute", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True);
2749  return returnStatus;
2750  }
2751 
2752  /*
2753  * Read incomplete_scans
2754  */
2755 
2756  returnStatus = read_attribute (L1A_Gran->sd_id,
2757  "Incomplete Scans", DFNT_INT32,
2758  (VOIDP)&L1A_Gran->incomplete_scans);
2759  if (returnStatus != MODIS_S_OK)
2760  {
2761  L1BErrorMsg(location, returnStatus,
2762  "Could not read number of incomplete scans.",
2763  "read_attribute",
2765  return returnStatus;
2766  }
2767 
2768  /*
2769  * Read max_ev_frames
2770  */
2771 
2772  returnStatus = read_attribute (L1A_Gran->sd_id,
2773  "Max Earth Frames", DFNT_INT32,
2774  (VOIDP)&L1A_Gran->max_ev_frames);
2775  if (returnStatus != MODIS_S_OK)
2776  {
2777  L1BErrorMsg(location, returnStatus,
2778  "Could not read maximum number of EV frames.",
2779  "read_attribute", FIRST_L1A_GRANULE,
2781  return returnStatus;
2782  }
2783 
2784  /* Read Extract Metadata */
2785  read_extract_metadata(L1A_Gran->sd_id,
2786  &L1A_Gran->Extract_Pixel_Offset,
2787  &L1A_Gran->Extract_Pixel_Count,
2788  &L1A_Gran->Extract_Line_Offset,
2789  &L1A_Gran->Extract_Line_Count);
2790 
2791  /*
2792  * Read scan quality array
2793  */
2794 
2795  returnStatus = read_sds_rank2(L1A_Gran->sd_id, "Scan quality array",
2796  L1A_Gran->num_scans,
2798  (VOIDP)L1A_Gran->scan_quality);
2799  if (returnStatus != MODIS_S_OK) {
2800  L1BErrorMsg(location, returnStatus, "Could not read scan quality array",
2801  "read_sds_rank2", FIRST_L1A_GRANULE, NULL, True);
2802  return returnStatus;
2803  }
2804 
2805  /*
2806  * Determine if a scan is completely missing based on the second element
2807  * of Scan quality array.
2808  */
2809 
2810  for (S = 0; S < L1A_Gran->num_scans; S++)
2811  {
2812  if (L1A_Gran->scan_quality[S][0] == 0)
2813  L1A_Gran->missing_scan[S] = True;
2814  else
2815  L1A_Gran->missing_scan[S] = False;
2816  }
2817 
2818  /*
2819  * Determine the satellite
2820  */
2821 
2822  returnStatus = Get_Satellite_ID(FIRST_L1A_GRANULE, &L1A_Gran->satellite_id);
2823  if (returnStatus != MODIS_S_OK)
2824  {
2825  L1BErrorMsg(location, returnStatus, "Could not get satellite ID.",
2826  "Get_Satellite_ID", FIRST_L1A_GRANULE, Invalid_MOD01_Msg, True);
2827  return returnStatus;
2828  }
2829 
2830  /*
2831  * Determine the satellite instrument value in geo file.
2832  */
2833 
2834  returnStatus = Get_Satellite_ID(GEOLOCATION_FILE, &geo_satellite_id);
2835  if (returnStatus != MODIS_S_OK)
2836  {
2837  L1BErrorMsg(location, returnStatus, "Could not get satellite ID.",
2838  "Get_Satellite_ID", GEOLOCATION_FILE,
2839  "The geolocation file is invalid.", True);
2840  return returnStatus;
2841  }
2842 
2843  /*
2844  * Check if the geo granule and L1A granule is for the same instrument.
2845  */
2846 
2847  if (geo_satellite_id != L1A_Gran->satellite_id)
2848  {
2849  returnStatus = MODIS_F_NOK;
2850  L1BErrorMsg(location, returnStatus,
2851  "*** INCORRECT GEOLOCATION FILE ***\n"
2852  "The satellite instrument in the geolocation file (lun 600000) is\n"
2853  "different from that in the middle L1A granule (lun 500001).",
2854  NULL, 0, NULL, True);
2855  return returnStatus;
2856  }
2857 
2858  /*
2859  * Check the run time parameter SatelliteInstrument from the PCF file against
2860  * the satellite inherent in the L1A data.
2861  */
2862 
2863  satelliteInstrument = runtime_params->SatelliteInstrument;
2864  if (!((strcmp(satelliteInstrument, "AM1M") == 0 &&
2865  L1A_Gran->satellite_id == TERRA) ||
2866  (strcmp(satelliteInstrument, "PM1M") == 0 &&
2867  L1A_Gran->satellite_id == AQUA)))
2868  {
2869  returnStatus = MODIS_F_NOK;
2870  L1BErrorMsg(location, returnStatus,
2871  "The satellite instrument set in the PCF does not match\n"
2872  "the value inherent in the middle L1A granule.",
2873  NULL, 0, NULL, True);
2874  return returnStatus;
2875  }
2876 
2877  RFLAG = 0;
2878  if (SDnametoindex(L1A_Gran->sd_id, "EV_250m") == -1 ||
2879  SDnametoindex(L1A_Gran->sd_id, "BB_250m") == -1 ||
2880  SDnametoindex(L1A_Gran->sd_id, "SV_250m") == -1 ||
2881  SDnametoindex(L1A_Gran->sd_id, "SD_250m") == -1 ||
2882  SDnametoindex(L1A_Gran->sd_id, "SRCA_250m") == -1) {
2883  RFLAG = RFLAG | 1;
2884  }
2885 
2886  if (SDnametoindex(L1A_Gran->sd_id, "EV_500m") == -1 ||
2887  SDnametoindex(L1A_Gran->sd_id, "BB_500m") == -1 ||
2888  SDnametoindex(L1A_Gran->sd_id, "SV_500m") == -1 ||
2889  SDnametoindex(L1A_Gran->sd_id, "SD_500m") == -1 ||
2890  SDnametoindex(L1A_Gran->sd_id, "SRCA_500m") == -1) {
2891  RFLAG = RFLAG | 2;
2892  }
2893 
2894  if (SDnametoindex(L1A_Gran->sd_id, "EV_1km_day") == -1 ||
2895  SDnametoindex(L1A_Gran->sd_id, "BB_1km_day") == -1 ||
2896  SDnametoindex(L1A_Gran->sd_id, "SV_1km_day") == -1 ||
2897  SDnametoindex(L1A_Gran->sd_id, "SD_1km_day") == -1 ||
2898  SDnametoindex(L1A_Gran->sd_id, "SRCA_1km_day") == -1) {
2899  RFLAG = RFLAG | 4;
2900  }
2901 
2902  if (SDnametoindex(L1A_Gran->sd_id, "EV_1km_night") == -1 ||
2903  SDnametoindex(L1A_Gran->sd_id, "BB_1km_night") == -1 ||
2904  SDnametoindex(L1A_Gran->sd_id, "SV_1km_night") == -1 ||
2905  SDnametoindex(L1A_Gran->sd_id, "SD_1km_night") == -1 ||
2906  SDnametoindex(L1A_Gran->sd_id, "SRCA_1km_night") == -1) {
2907  RFLAG = RFLAG | 8;
2908  }
2909 
2910  if (SDfindattr(L1A_Gran->sd_id, "B_13_scale_parm") != -1)
2911  RSCL_FLAG = RSCL_FLAG | 1;
2912  if (SDfindattr(L1A_Gran->sd_id, "B_16_scale_parm") != -1)
2913  RSCL_FLAG = RSCL_FLAG | 2;
2914  if (SDfindattr(L1A_Gran->sd_id, "B_10_scale_parm") != -1)
2915  RSCL_FLAG = RSCL_FLAG | 4;
2916  if (SDfindattr(L1A_Gran->sd_id, "B_12_scale_parm") != -1)
2917  RSCL_FLAG = RSCL_FLAG | 8;
2918 
2919  returnStatus = MODIS_S_OK; /* Successful completion of function */
2920  return returnStatus; /* L1A granule remains open */
2921 }
2922 
2923 PGSt_SMF_status Get_Satellite_ID (PGSt_PC_Logical lun, int32 *satellite_ID)
2924 /*
2925 !C**************************************************************************
2926 !Description: This function reads the metadata "SHORTNAME" from the file
2927  designated by the lun and determines the satelitte name.
2928 
2929 !Input Parameters:
2930  int32 lun logic identifier of the file.
2931 
2932 !Output Parameters:
2933  int32 *satellite_ID identifier of the satellite (TERRA = 0, AQUA = 1,
2934  INVALID_SATELLITE_ID = -1)
2935 
2936 !Revision History:
2937  (continue at top of the file)
2938 
2939  Revision 01.00 June 27, 2000
2940  Initial development.
2941  Zhenying Gu (zgu@mcst.gsfc.nasa.gov)
2942 
2943 !Team-unique Header:
2944  This software is developed by the MODIS Science Data Support
2945  Team for the National Aeronautics and Space Administration,
2946  Goddard Space Flight Center, under contract NAS5-32373.
2947 
2948 !References and Credits
2949  HDF portions developed at the National Center for Supercomputing
2950  Applications at the University of Illinois at Urbana-Champaign.
2951 
2952 !Design Notes:
2953 !END********************************************************************
2954 */
2955 {
2956  PGSt_SMF_status returnStatus = MODIS_S_OK;
2957  PGSt_integer Version = 1;
2958  char shortname[10];
2959  char *shortnameptr;
2960  char *attrName = "SHORTNAME";
2961  char *location = "Get_Satellite_ID";
2962 
2963  /* To use the address of the shortname[], a pointer is needed. */
2964 
2965  shortnameptr = shortname;
2966 
2967  /* Get the shortname */
2968 
2969  returnStatus = PGS_MET_GetPCAttr(lun, Version, "CoreMetadata.0",
2970  attrName, &shortnameptr);
2971  if (returnStatus != PGS_S_SUCCESS)
2972  {
2973  returnStatus = MODIS_F_READ_ERROR;
2974  L1BErrorMsg (location, returnStatus, "Could not get metadata \"SHORTNAME\".",
2975  "PGS_MET_GetPCAttr", lun, NULL, True);
2976  }
2977 
2978  if (strncmp(shortname, "MOD", 3) == 0)
2979  *satellite_ID = TERRA;
2980  else if (strncmp(shortname, "MYD", 3) == 0)
2981  *satellite_ID = AQUA;
2982  else
2983  *satellite_ID = INVALID_SATELLITE_ID;
2984 
2985  return MODIS_S_OK;
2986 }
2987 
2988 PGSt_SMF_status Read_Run_Time_Parameters (Run_Time_Parameters_t *runtime_params)
2989 /*
2990 !C**************************************************************************
2991 !Description:
2992  Read all run-time parameters from the PCF file and set the values in the
2993  output variable.
2994 
2995 !Input Parameters:
2996  none
2997 
2998 !Output Parameters:
2999  Run_Time_Parameters_t *runtime_params
3000  contains SatelliteInstrument,
3001  ReprocessingPlanned,
3002  ReprocessingActual,
3003  PGE02_Version,
3004  MCST_LUT_Version,
3005  Write_Night_Mode_HiRes_Data,
3006  ProcessingEnvironment
3007 !Revision History:
3008  (continue at top of the file)
3009 
3010  Revision 01.07 October 31, 2003 Razor Issue #195
3011  Added the code of reading the ProcessingCenter value from the
3012  Run_Time_Parameters_t structure.
3013  Liqin Tan, SAIC GSO (ltan@saicmodis.com)
3014 
3015  Revision 01.06 October 2, 2002 Razor Issue #183
3016  Bug fix to setting ProcessingEnvironment. The function used, while POSIX
3017  compliant, was on the list of functions forbidden by the SDP Toolkit.
3018  "getenv" was subsituted.
3019  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
3020 
3021  Revision 01.05 August 19, 2002 Razor Issue #183
3022  Revised setting ProcessingEnvironment. It is now set by calling
3023  the appropriate POSIX function from within the module, rather
3024  than read from the PCF file. This is to avoid seeing error messages
3025  from the SDP Toolkit for each granule when the field is left blank
3026  in the PCF file, which is allowable.
3027  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
3028 
3029  Revision 01.04 April 25, 2002 Razor Issue #183
3030  Corrected syntax for setting ProcessingEnvironment to blank
3031  Gwyn Fireman, SAIC GSO (fireman@mcst.gsfc.nasa.gov)
3032 
3033  Revision 01.03 March 21, 2002 Razor Issue #181
3034  Added ProcessingEnvironment parameter as per SDST
3035  request for Collection 4
3036  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
3037 
3038  Revision 01.02 November 12, 2001
3039  Added Write_Night_Mode_HiRes_Data (Razor issue #169)
3040  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
3041 
3042  Revision 01.01 November 6, 2001
3043  Added MCST_LUT_Version (Razor issue #167)
3044  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
3045 
3046  Revision 01.00 February 21, 2001
3047  Initial development.
3048  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
3049 
3050 !Team-unique Header:
3051  This software is developed by the MODIS Science Data Support
3052  Team for the National Aeronautics and Space Administration,
3053  Goddard Space Flight Center, under contract NAS5-32373.
3054 
3055 !References and Credits
3056  HDF portions developed at the National Center for Supercomputing
3057  Applications at the University of Illinois at Urbana-Champaign.
3058 
3059 !Design Notes:
3060 
3061 !END********************************************************************
3062 */
3063 {
3064  PGSt_SMF_status returnStatus;
3065 
3066  char *location = "Read_Run_Time_Parameters";
3067  /* Default ProcessingEnvironment identifier */
3068  char thisname[MAX_PROCESSING_ENVIRONMENT_STRLEN] = "";
3069  char *ename; /* Value of environment variable from "getenv" calls */
3070  char *osnames[4] = {"OS", "OSTYPE", "BRAND", "MACHINE"};
3071  char *hostnames[3] = {"HOST", "HOSTNAME", "HOSTTYPE"};
3072  char *revision = "REVISION";
3073 
3074  int16 j = 0; /* A counter */
3075 
3076  if (!runtime_params)
3077  {
3078  returnStatus = MODIS_F_INVALID_ARGUMENT;
3079  L1BErrorMsg(location, returnStatus, "Input runtime_params is NULL.",
3080  NULL, 0, NULL, True);
3081  return returnStatus;
3082  }
3083 
3084  /*
3085  * Read and check the SatelliteInstrument value.
3086  */
3087 
3088  returnStatus = PGS_PC_GetConfigData(SATELLITE_INSTRUMENT_LUN,
3089  runtime_params->SatelliteInstrument);
3090  if (returnStatus != PGS_S_SUCCESS)
3091  {
3092  returnStatus = MODIS_F_NOK;
3093  L1BErrorMsg(location, returnStatus,
3094  "Failed to get parameter SatelliteInstrument from PCF file.",
3095  "PGS_PC_GetConfigData", SATELLITE_INSTRUMENT_LUN,
3096  "Invalid PCF file", True);
3097  return returnStatus;
3098  }
3099  if (!(strcmp(runtime_params->SatelliteInstrument, "AM1M") == 0 ||
3100  strcmp(runtime_params->SatelliteInstrument, "PM1M") == 0))
3101  {
3102  char errmsg[256];
3103  sprintf (errmsg,
3104  "The SatelliteInstrument value (%s) in the PCF is invalid.",
3105  runtime_params->SatelliteInstrument);
3106  returnStatus = MODIS_F_NOK;
3107  L1BErrorMsg(location, returnStatus, errmsg,
3109  return returnStatus;
3110  }
3111 
3112  /*
3113  * Set the ProcessingEnvironment value. This
3114  * is not a mandatory entry and it is acceptable that
3115  * the value be missing or blank, but in practice it is easier to set it
3116  * within L1B and avoid seeing error messages when it is not in the PCF file.
3117  */
3118 
3119  strcpy((runtime_params->ProcessingEnvironment), "");
3120 
3121  /*
3122  * Obtain the processing environment fields
3123  * by calling the POSIX "getenv" function
3124  */
3125 
3126  for (j = 0; j < 4; j++)
3127  {
3128  ename = getenv(osnames[j]);
3129 
3130  if (ename != NULL)
3131 
3132  {
3133  /* Concatenate the desired names onto the ProcessingEnvironment string. */
3136 
3137  break;
3138  }
3139  }
3140 
3141  for (j = 0; j < 3; j++)
3142  {
3143  ename = getenv(hostnames[j]);
3144 
3145  if (ename != NULL)
3146 
3147  {
3148  /* Concatenate the desired names onto the ProcessingEnvironment string. */
3151 
3152  break;
3153  }
3154  }
3155 
3156  ename = getenv(revision);
3157 
3158  if (ename != NULL)
3159 
3160  {
3161  /* Concatenate the desired names onto the ProcessingEnvironment string. */
3164  }
3165 
3166  /*
3167  * If the function getenv fails to return any values it is OK.
3168  */
3169 
3170  safe_strcat(runtime_params->ProcessingEnvironment, thisname,
3172 
3173  /*
3174  * Read the ReprocessingPlanned value. This is not checked for specific
3175  * values because it is not clear that there is a constant set of valids
3176  * for this field (some could be added in the future).
3177  */
3178 
3179  returnStatus = PGS_PC_GetConfigData(REPROCESSING_PLANNED_LUN,
3180  runtime_params->ReprocessingPlanned);
3181  if (returnStatus != PGS_S_SUCCESS)
3182  {
3183  returnStatus = MODIS_F_NOK;
3184  L1BErrorMsg(location, returnStatus,
3185  "Failed to get parameter ReprocessingPlanned from PCF file.",
3186  "PGS_PC_GetConfigData", REPROCESSING_PLANNED_LUN,
3187  "Invalid PCF file", True);
3188  return returnStatus;
3189  }
3190  if (strlen(runtime_params->ReprocessingPlanned) == 0)
3191  {
3192  returnStatus = MODIS_F_NOK;
3193  L1BErrorMsg(location, returnStatus,
3194  "The ReprocessingPlanned value in the PCF is invalid (no string).",
3196  return returnStatus;
3197  }
3198 
3199  /*
3200  * Read the ReprocessingActual value. This is not checked for specific
3201  * values because it is not clear that there is a constant set of valids
3202  * for this field (some could be added in the future).
3203  */
3204 
3205  returnStatus = PGS_PC_GetConfigData(REPROCESSING_ACTUAL_LUN,
3206  runtime_params->ReprocessingActual);
3207  if (returnStatus != PGS_S_SUCCESS)
3208  {
3209  returnStatus = MODIS_F_NOK;
3210  L1BErrorMsg(location, returnStatus,
3211  "Failed to get parameter ReprocessingActual from PCF file.",
3212  "PGS_PC_GetConfigData", REPROCESSING_ACTUAL_LUN,
3213  "Invalid PCF file", True);
3214  return returnStatus;
3215  }
3216  if (strlen(runtime_params->ReprocessingActual) == 0)
3217  {
3218  returnStatus = MODIS_F_NOK;
3219  L1BErrorMsg(location, returnStatus,
3220  "The ReprocessingActual value in the PCF is invalid (no string).",
3222  return returnStatus;
3223  }
3224 
3225  /*
3226  * Read the Write_Night_Mode_HiRes_Data value. This value must be
3227  * True (1) or False (0).
3228  */
3229  returnStatus = PGS_PC_GetConfigData(WRITE_NIGHT_HIRES_LUN,
3230  runtime_params->Write_Night_Mode_HiRes_Data);
3231  if (returnStatus != PGS_S_SUCCESS)
3232  {
3233  returnStatus = MODIS_F_NOK;
3234  L1BErrorMsg(location, returnStatus,
3235  "Failed to get parameter Write_Night_Mode_HiRes_Data "
3236  "from PCF file.",
3237  "PGS_PC_GetConfigData", WRITE_NIGHT_HIRES_LUN,
3238  "Invalid PCF file", True);
3239  return returnStatus;
3240  }
3241  if (!(strcmp(runtime_params->Write_Night_Mode_HiRes_Data, "0") == 0 ||
3242  strcmp(runtime_params->Write_Night_Mode_HiRes_Data, "1") == 0))
3243  {
3244  returnStatus = MODIS_F_NOK;
3245  L1BErrorMsg(location, returnStatus,
3246  "The Write_Night_Mode_HiRes_Data value in the PCF file is "
3247  "invalid (must be 0 (False) or 1 (True)).",
3249  return returnStatus;
3250  }
3251 
3252  /*
3253  * Read the PGE02 Version value from PCF file.
3254  */
3255 
3256  returnStatus = PGS_PC_GetConfigData(PGE02_VERSION_LUN,
3257  runtime_params->PGE02_Version);
3258 
3259  if (returnStatus != PGS_S_SUCCESS)
3260  {
3261  returnStatus = MODIS_F_NOK;
3262  L1BErrorMsg(location, returnStatus,
3263  "Failed to get parameter PGE02_Version from PCF file.",
3264  "PGS_PC_GetConfigData", PGE02_VERSION_LUN,
3265  "Invalid PCF file", True);
3266  return returnStatus;
3267  }
3268  if (strlen(runtime_params->PGE02_Version) == 0)
3269  {
3270  returnStatus = MODIS_F_NOK;
3271  L1BErrorMsg(location, returnStatus,
3272  "The PGE02_Version value in the PCF is invalid (no string).",
3274  return returnStatus;
3275  }
3276 
3277  /*
3278  * Check the PGE02 version given in the PCF file against the code macro.
3279  */
3280 
3281  if (strcmp(runtime_params->PGE02_Version, PGE02_VERSION))
3282  {
3283  returnStatus = MODIS_F_OUT_OF_RANGE;
3284  char errmsg[512];
3285  sprintf(errmsg, "The PGE02 version in PCF file (%s) does not match the expected value (%s).",
3286  runtime_params->PGE02_Version, PGE02_VERSION);
3287  L1BErrorMsg(location, returnStatus,
3288  errmsg, NULL, 0,
3289  "Code files must have the same PGE02 version as specified in the PCF file.",
3290  True);
3291 
3292  return returnStatus;
3293  }
3294 
3295  /*
3296  * Read the MCST_LUT_Version value. This is not checked for specific
3297  * values because the values vary with the MCST LUT Version numbers.
3298  */
3299 
3300  returnStatus = PGS_PC_GetConfigData(MCST_LUT_VERSION_LUN,
3301  runtime_params->MCST_LUT_Version);
3302 
3303  if (returnStatus != PGS_S_SUCCESS)
3304  {
3305  returnStatus = MODIS_F_NOK;
3306  L1BErrorMsg(location, returnStatus,
3307  "Failed to get parameter MCST_LUT_Version from PCF file.",
3308  "PGS_PC_GetConfigData", MCST_LUT_VERSION_LUN,
3309  "Invalid PCF file", True);
3310  return returnStatus;
3311  }
3312  if (strlen(runtime_params->MCST_LUT_Version) == 0)
3313  {
3314  returnStatus = MODIS_F_NOK;
3315  L1BErrorMsg(location, returnStatus,
3316  "The MCST_LUT_Version value in the PCF is invalid (no string).",
3318  return returnStatus;
3319  }
3320 
3321  /*
3322  * Read the ProcessingCenter value from the Run_Time_Parameters_t
3323  * structure.
3324  */
3325 
3326  returnStatus = PGS_PC_GetConfigData(PROCESSING_CENTER_LUN,
3327  runtime_params->ProcessingCenter);
3328  if (returnStatus != PGS_S_SUCCESS)
3329  {
3330  returnStatus = MODIS_F_NOK;
3331  L1BErrorMsg(location, returnStatus,
3332  "Failed to get parameter ProcessingCenter from PCF file.",
3333  "PGS_PC_GetConfigData", PROCESSING_CENTER_LUN,
3334  "Invalid PCF file", True);
3335  return returnStatus;
3336  }
3337  if (strlen(runtime_params->ProcessingCenter) == 0)
3338  {
3339  returnStatus = MODIS_F_NOK;
3340  L1BErrorMsg(location, returnStatus,
3341  "The ProcessingCenter value in the PCF is invalid (no string).",
3343  return returnStatus;
3344  }
3345 
3346  return MODIS_S_OK;
3347 }
3348 
int8 EV_500m_Aggr1km_RefSB_SU[NUM_500M_BANDS][DETECTORS_PER_1KM_BAND][EV_1km_FRAMES]
Definition: Granule.h:1014
uint16 EV_500m_Aggr1km_RefSB[NUM_500M_BANDS][DETECTORS_PER_1KM_BAND][EV_1km_FRAMES]
Definition: Granule.h:985
int8 EV_250m_Aggr500m_RefSB_SU[NUM_250M_BANDS][DETECTORS_PER_500M_BAND][EV_500m_FRAMES]
Definition: Granule.h:1006
PGSt_SMF_status Open_and_Read_L1A(Run_Time_Parameters_t *runtime_params, L1A_granule_t *L1A_Gran, boolean *skip_night_hi_res)
Definition: Granule.c:2450
#define MODIS_S_OK
#define MODIS_F_FILE_NOT_FOUND
boolean missing_scan[MAX_NUM_SCANS]
Definition: Granule.h:769
integer, parameter int16
Definition: cubeio.f90:3
int32 value
Definition: Granule.c:1235
#define QA_TABLES_FILE
Definition: FNames.h:76
char MCST_LUT_Version[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:739
#define NUM_SCALE_FACTORS
#define SCAN_QUALITY_ARRAY_NUM_ELEMENTS
Definition: Granule.h:488
#define MCF_FILE_1KM
Definition: FNames.h:66
#define ASCTIMEBUF
uint16 SI[DETECTORS_PER_1KM_BAND][EV_1km_FRAMES]
Definition: Granule.h:949
#define MODIS_F_WRITE_ERROR
int j
Definition: decode_rs.h:73
===========================================================================V4.1.3 12/18/2002============================================================================Changes which do not affect scientific output:1. The R *LUT was eliminated and the equivalent formulation for R *, i.e. 1/(m1 *e_sun_over_pi), was substituted for it in the only instance of its use, which is in the calculation of the RSB uncertainty index. This reduces the size of the Reflective LUT HDF file by approximately 1/4 to 1/3. The equivalent formulation of R *differed from the new by at most 0.056% in test granules and uncertainty differences of at most 1 count(out of a range of 0-15) were found in no more than 1 in 100, 000 pixels. 2. In Preprocess.c, a small error where the trailing dropped scan counter was incremented when the leading dropped scan counter should have been was fixed. This counter is internal only and is not yet used for any purpose. 3. NEW MYD02OBC Metadata Configuration Files. MCST wishes to have the OBC files archived even when the Orbit Number is recorded as "-1". Accordingly, ECS has delivered new MCF files for OBC output having all elements in the OrbitCalculatedSpatialDomain container set to "MANDATORY=FALSE". 4. pgs_in.version is now reset to "1" in Metadata.c before the call to look up the geolocation gringpoint information.============================================================================V4.1.1 CODE SPECIFIC TO MODIS/AQUA(FM1) 10/03/2002============================================================================Two changes were made to the code which do not affect scientific output:1. A bug which caused PGE02 to fail when scans were dropped between granules was fixed.(The length of the error message generated was shortened.) 2. Messages regarding an invalid MCST LUT Version or an invalid Write High Resolution Night Mode Output value in the PCF file were added.==============================================================================V4.1.0 CODE SPECIFIC TO MODIS/AQUA(FM1)(NEVER USED IN PRODUCTION) 07/30/2002==============================================================================Changes which impact scientific output of code:1. The LUT type of the RVS corrections was changed to piecewise linear. In addition the RVS LUTs were changed from listing the RVS corrections to listing the quadratic coefficients necessary to make the RVS corrections. The coefficients are now calculated by interpolating on the granule collection time and the RVS corrections are then generated using the interpolated coefficients. Previously used Emissive and Reflective RVS LUT tables were eliminated and new ones introduced. Several changes were made to the code which should not affect scientific output. They are:1. The ADC correction algorithm and related LUTs were stripped from the code.(The ADC correction has always been set to "0" so this has no scientific impact.) 2. Some small changes to the code, chiefly to casting of variables, were added to make it LINUX-compatible. Output of code run on LINUX machines displays differences of at most 1 scaled integer(SI) from output of code run on IRIX machines. The data type of the LUT "dn_sat_ev" was changed to float64 to avoid discrepancies seen between MOD_PR02 run on LINUX systems and IRIX systems where values were flagged under one operating system but not the other. 3. Checking for non-functioning detectors, sector rotation, incalculable values of the Emissive calibration factor "b1", and incalculable values of SV or BB averages was moved outside the loop over frames in Emissive_Cal.c since none of these quantities are frame-dependent. 4. The code was altered so that if up to five scans are dropped between the leading/middle or middle/trailing granules, the leading or trailing granule will still be used in emissive calibration to form a cross-granule average. QA bits 25 and 26 are set for a gap between the leading/middle and middle/trailing granules respectively. This may in rare instances lead to a change in emissive calibration coefficients for scans at the beginning or end of a granule. 5.(MODIS/AQUA ONLY) The name of the seed(error message) file was changed from "MODIS_36100.h" to "MODIS_36110.h". 6. Metadata.c was changed so that the source of the geolocation metadata is the input geolocation file rather than the L1A granule. 7. To reduce to overall size of the reflective LUT HDF files, fill values were eliminated from all LUTs previously dimensioned "BDSM"([NUM_REFLECTIVE_BANDS] *[MAX_DETECTORS_PER_BAND] *[MAX_SAMPLES_PER_BAND] *[NUM_MIRROR_SIDES]) in the LUT HDF files. Each table piece is stored in the HDF file with dimensions NUM_REFLECTIVE_INDICES, where NUM_REFLECTIVE_INDICES=[NUM_250M_BANDS *DETECTORS_PER_250M_BAND *SAMPLES_PER_250M_BAND *NUM_MIRROR_SIDES]+[NUM_500M_BANDS *DETECTORS_PER_500M_BAND *SAMPLES_PER_500M_BAND *NUM_MIRROR_SIDES]+[NUM_1000M_BANDS *DETECTORS_PER_1KM_BAND *SAMPLES_PER_1KM_BAND *NUM_MIRROR_SIDES] with SAMPLES_PER_250M_BAND=4, SAMPLES_PER_500M_BAND=2, and SAMPLES_PER_1KM_BAND=1. Values within each table piece appear in the order listed above. The overall dimensions of time dependent BDSM LUTs are now[NUM_TIMES] *[NUM_REFLECTIVE_INDICES], where NUM_TIMES is the number of time dependent table pieces. 8. Checking for non-functioning detectors, sector rotation, incalculable values of the Emissive calibration factor "b1", and incalculable values of SV or BB averages was moved outside the loop over frames in Emissive_Cal.c since none of these quantities are frame-dependent. 9. The code was altered so that if up to five scans are dropped between the leading/middle or middle/trailing granules, the leading or trailing granule will still be used in emissive calibration to form a cross-granule average. QA bits 25 and 26 are set for a gap between the leading/middle and middle/trailing granules respectively. This may in rare instances lead to a change in emissive calibration coefficients for scans at the beginning or end of a granule. 10. The array of b1s in Preprocess.c was being initialized to -1 outside the loop over bands, which meant that if b1 could not be computed, the value of b1 from the previous band for that scan/detector combination was used. The initialization was moved inside the band loop.============================================================================V3.1.0(Original Aqua-specific code version) 02/06/2002============================================================================AQUA-Specific changes made:1. A correction to a problem with blackbody warmup on bands 33, 35, and 36 was inserted. PC Bands 33, 35, and 36 on MODIS Aqua saturate on BB warmup before 310K, which means current code will not provide correct b1 calibration coefficients when the BB temperatures are above the saturation threshold. A LUT with default b1s and band-dependent temperature thresholds will be inserted in code. If the BB temperature is over the saturation threshold for the band, the default b1 from the table is used. 2. The number of possible wavelengths in the Emissive LUT RSR file was changed to 67 in order to accommodate the Aqua RSR tables. 3. Several changes to the upper and lower bound limits on LUT values were inserted. Changes to both Aqua and Terra Code:1. A check was put into Emissive_Cal.c to see whether the value of b1 being used to calibrate a pixel is negative. If so, the pixel is flagged with the newly created flag TEB_B1_NOT_CALCULATED, value 65526, and the number of pixels for which this occurs is counted in the QA_common table. 2. The array of b1s in Preprocess.c was being initialized to -1 outside the loop over bands, which meant that if b1 could not be computed, the value of b1 from the previous band for that scan/detector combination was used. The initialization was moved inside the band loop. 3. Minor code changes were made to eliminate compiler warnings when the code is compiled in 64-bit mode. 4. Temperature equations were upgraded to be MODIS/Aqua or MODIS/Terra specific and temperature conversion coefficients for Aqua were inserted.========================================================================================================================================================ALL CHANGES BELOW ARE TO COMMON TERRA/AQUA CODE USED BEFORE 02/06/2002========================================================================================================================================================v3.0.1 11/26/2001============================================================================Several small changes to the code were made, none of which changes the scientific output:1. The code was changed so that production of 250m and 500m resolution data when all scans of a granule are in night mode may be turned off/on through the PCF file. 2. A check on the times of the leading and trailing granules was inserted. If a leading or trailing granule does not immediately precede or follow(respectively) the middle granule, it is treated as a missing granule and a warning message is printed. 3. The code now reads the "MCST Version Number"(e.g. "3.0.1.0_Terra") from the PCF file and checks it against the MCST Version number contained in the LUT HDF files. This was done to allow the user to make sure the code is being run using the correct LUT files.(The designators "0_Terra", "1_Terra", etc.) refer to the LUT versions.) 4. A small bug in Preprocess.c was corrected code
Definition: HISTORY.txt:661
uint16 EV_1km_RefSB[NUM_1000M_REFL_BANDS][DETECTORS_PER_1KM_BAND][EV_1km_FRAMES]
Definition: Granule.h:901
uint32 interpolated_pixels[NUM_BANDS]
Definition: Granule.h:881
#define L(lambda, T)
Definition: PreprocessP.h:185
category
Definition: __init__.py:2
#define MCF_FILE_OBC
Definition: FNames.h:67
#define BAD_DATA_UI
Definition: Granule.h:533
uint16 EV_500m_RefSB[NUM_500M_BANDS][DETECTORS_PER_500M_BAND][EV_500m_FRAMES]
Definition: Granule.h:897
char ReprocessingActual[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:737
uint32 valid_pixels[NUM_BANDS]
Definition: Granule.h:878
#define MCF_FILE_HKM
Definition: FNames.h:65
PGSt_SMF_status Write_L1B_SI_UI(int16 S, L1B_Scan_t *L1B_Scan, int16 R)
Definition: Granule.c:1832
int32 UI_sds_id[NUM_L1A_RESOLUTIONS]
Definition: Granule.h:966
uint8 EV_250m_Aggr500m_RefSB_UI[NUM_250M_BANDS][DETECTORS_PER_500M_BAND][EV_500m_FRAMES]
Definition: Granule.h:994
@ INDEX_1000M_DAY
Definition: Granule.h:571
uint16 EV_1km_Emissive[NUM_1000M_EMISS_BANDS][DETECTORS_PER_1KM_BAND][EV_1km_FRAMES]
Definition: Granule.h:905
#define FAIL
Definition: ObpgReadGrid.h:18
uint8 UI[DETECTORS_PER_1KM_BAND][EV_1km_FRAMES]
Definition: Granule.h:950
#define MODIS_F_OUT_OF_MEMORY
@ INDEX_500M
Definition: Granule.h:570
#define NULL
Definition: decode_rs.h:63
#define REPROCESSING_PLANNED_LUN
Definition: FNames.h:87
#define TERRA
Definition: Granule.h:549
#define PGE02_VERSION_LUN
Definition: FNames.h:84
#define MODIS_BAND26_INDEX
Definition: Granule.h:446
int32 EV_500m_Aggr1km_RefSB_sds_id
Definition: Granule.h:965
#define FIRST_L1A_GRANULE
Definition: FNames.h:79
Band_26_t Band26
Definition: Granule.h:1022
PGSt_SMF_status Fill_Dead_Detector_SI(boolean isdaymode, int8 *dead_detector, L1B_Scan_t *L1B_Scan, L1B_granule_t *L1B_Gran, QA_Common_t *QA_Common)
Definition: Granule.c:1919
uint8 EV_250m_Aggr1km_RefSB_UI[NUM_250M_BANDS][DETECTORS_PER_1KM_BAND][EV_1km_FRAMES]
Definition: Granule.h:998
#define MODIS_E_TESTING
PGSt_SMF_status Get_Satellite_ID(PGSt_PC_Logical lun, int32 *satellite_ID)
Definition: Granule.c:2924
#define MAX_BANDS_PER_FDD_SET
int32 EV_250m_Aggr500m_RefSB_SU_sds_id
Definition: Granule.h:970
int32 EV_500m_Aggr1km_RefSB_SU_sds_id
Definition: Granule.h:972
#define NUM_500M_BANDS
Definition: Granule.h:431
int32 SI_sds_id
Definition: Granule.h:947
#define MODIS_F_OUT_OF_RANGE
int32 num_scans
Definition: Granule.h:749
#define MODIS_BAND26_INDEX_AT_RES
Definition: Granule.h:447
float tm[MODELMAX]
#define MODIS_W_TIME_INCORRECT
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
@ INDEX_250M
Definition: Granule.h:569
float64 data_collection_time
Definition: Granule.h:755
#define DETECTORS_PER_500M_BAND
Definition: Granule.h:439
int16 BAND_RATIO_AT_RES[NUM_L1A_RESOLUTIONS]
Definition: Granule.c:73
PGSt_SMF_status Write_L1B_EV_Scan(int16 S, L1B_granule_t *L1B_Gran, L1B_Scan_t *L1B_Scan, boolean isdaymode)
Definition: Granule.c:1673
#define DETECTORS_PER_1KM_BAND
Definition: Granule.h:438
int16 EV_1km_day[DETECTORS_PER_1KM_BAND][NUM_1000M_DAY_BANDS][EV_1km_FRAMES]
Definition: Granule.h:787
int8 EV_250m_Aggr1km_RefSB_SU[NUM_250M_BANDS][DETECTORS_PER_1KM_BAND][EV_1km_FRAMES]
Definition: Granule.h:1010
int32 num_night_scans
Definition: Granule.h:759
PGSt_SMF_status Aggregate_L1B(L1B_Scan_t *L1B_Scan)
Definition: Granule.c:78
#define L1B_EV_500M_FILE
Definition: FNames.h:70
#define MODIS_F_MEM_FREE_FAIL
uint16 EV_250m_RefSB[NUM_250M_BANDS][DETECTORS_PER_250M_BAND][EV_250m_FRAMES]
Definition: Granule.h:893
#define DN15_SAT
Definition: Granule.h:1103
const double F
@ INDEX_L1B_250m
Definition: Granule.h:587
#define MODIS_F_FILE_NOT_CREATED
char Write_Night_Mode_HiRes_Data[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:740
int32 num_day_scans
Definition: Granule.h:750
char PGE02_Version[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:738
PGSt_SMF_status read_sds_rank1(int32 file_id, char *sds_name, int32 dim, void *data)
Definition: HDF_Lib.c:359
#define INVALID_SATELLITE_ID
Definition: Granule.h:551
#define LEADING_L1A_GRANULE
Definition: FNames.h:78
#define GEOLOCATION_FILE
Definition: FNames.h:82
int32 v_id
Definition: Granule.h:746
#define PROCESSING_CENTER_LUN
Definition: FNames.h:91
int32 MOD_PR02_Failure_Exit_Code
Definition: Granule.c:52
int32 sds_id[NUM_L1A_RESOLUTIONS]
Definition: Granule.h:775
#define L1B_EV_250M_FILE
Definition: FNames.h:69
uint8 EV_500m_RefSB_UI[NUM_500M_BANDS][DETECTORS_PER_500M_BAND][EV_500m_FRAMES]
Definition: Granule.h:916
uint8 EV_500m_Aggr1km_RefSB_UI[NUM_500M_BANDS][DETECTORS_PER_1KM_BAND][EV_1km_FRAMES]
Definition: Granule.h:1002
#define WRITE_EV_Aggr_SDS(SI_id, SI, UI_id, UI, SU_id, SU)
@ NUM_L1B_EV_FILES
Definition: Granule.h:590
double precision function f(R1)
Definition: tmd.lp.f:1454
#define EMISSIVE_TABLES_FILE
Definition: FNames.h:75
#define NUM_1000M_EMISS_BANDS
Definition: Granule.h:434
#define SAME
Definition: Granule.h:494
int16 RFLAG
Definition: Granule.c:75
L1B_Scan_UI_t UI
Definition: Granule.h:987
int16 L1A_BANDS_AT_RES[NUM_L1A_RESOLUTIONS]
Definition: Granule.c:63
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 offsets between the high resolution geolocation and a bi linear interpolation extrapolation of the positions This can be used to reconstruct the high resolution geolocation Resolved Bug by delaying cumulation of gflags until after validation of derived products Resolved Bug by setting Latitude and Longitude to the correct fill resolving to support Near Real Time because they may be unnecessary if use of entrained ephemeris and attitude data is turned resolving bug report Corrected to filter out Aqua attitude records with missing status helping resolve bug report
Definition: HISTORY.txt:235
#define AQUA
Definition: Granule.h:550
#define MODIS_F_NO_MORE
#define MODIS_F_READ_ERROR
int32 Extract_Line_Count
Definition: Granule.h:765
#define SATELLITE_INSTRUMENT_LUN
Definition: FNames.h:85
int32 SI_sds_id[NUM_L1A_RESOLUTIONS]
Definition: Granule.h:962
#define EV_1km_FRAMES
Definition: Granule.h:469
#define TRAILING_L1A_GRANULE
Definition: FNames.h:80
#define MCF_FILE_QKM
Definition: FNames.h:64
int32 EV_250m_Aggr500m_RefSB_UI_sds_id
Definition: Granule.h:967
#define PGE02_VERSION
Definition: L1B_Tables.h:340
int32 Extract_Pixel_Offset
Definition: Granule.h:762
int32 scan_quality[MAX_NUM_SCANS][SCAN_QUALITY_ARRAY_NUM_ELEMENTS]
Definition: Granule.h:754
#define DEAD_DETECTOR_SI
Definition: Granule.h:521
char * actions
Definition: Granule.c:1236
instead the metadata field ProcessingEnvinronment is filled in from the output of a call to the POSIX compliant function uname from within the L1B code A small bug in L1B_Tables an incorrect comparison of RVS coefficients for TEBs to RVS coefficients for RSBs was being made This was replaced with a comparison between TEB coefficients This error never resulted in an incorrect RVS correction but did lead to recalculating the coefficients for each detector in a thermal band even if the coefficients were the same for all detectors To reduce to overall size of the reflective LUT HDF fill values were eliminated from all LUTs previously dimensioned where and where NUM_TIMES is the number of time dependent table pieces In Preprocess a small error where the trailing dropped scan counter was incremented when the leading dropped scan counter should have been was fixed This counter is internal only and is not yet used for any chiefly to casting of were added to make it LINUX compatible Output of code run on LINUX machines displays differences of at most scaled sector incalculable values of the Emissive calibration factor and incalculable values of SV or BB averages was moved outside the loop over frames in Emissive_Cal c since none of these quantities are frame dependent Initialization of b1 and XMS values in Preprocess c routine Process_OBCENG_Emiss was moved inside the detector loops The code was altered so that if up to five scans are dropped between the leading middle or middle trailing the leading or trailing granule will still be used in emissive calibration to form a cross granule average QA bits and are set for a gap between the leading middle and middle trailing granules respectively This may in rare instances lead to a change in emissive calibration coefficients for scans at the beginning or end of a granule A small bug in the Band correction algorithm was corrected an uncertainty value was being checked against an upper bound whereas the proper quantity to be checked was the corresponding which is the product of the Band radiance times the ratio of the Band to Band scaling factors times the LUT correction value for that detector In addition a new LUT which allows for a frame offset with regard to the Band radiance was added A LUT which switches the correction off or on was also added Changes which do not affect scientific output of the the pixel is flagged with the newly created flag and the number of pixels for which this occurs is counted in the QA_common table The array of b1s in Preprocess c was being initialized to outside the loop over which meant that if b1 could not be the value of b1 from the previous band for that scan detector combination was used The initialization was moved inside the band loop Minor code changes were made to eliminate compiler warnings when the code is compiled in bit mode Temperature equations were upgraded to be MODIS AQUA or MODIS TERRA specific and temperature conversion coefficients for AQUA were MOD_PR02 will not cease execution if the value of this parameter is not but will print a message
Definition: HISTORY.txt:644
#define INDEX_1000M_EMISS
Definition: Granule.h:576
char ReprocessingPlanned[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:736
PGSt_SMF_status Compute_Aggregates(int16 scale, int16 line_dim_lower, int16 frame_dim_lower, uint16 *SI_in, uint8 *UI_in, uint16 *SI_out, uint8 *UI_out, int8 *SU_out)
Definition: Granule.c:413
void SMF_ERROR(PGSt_SMF_code code, char *messagestring)
Definition: Granule.c:1345
uint16 EV_250m_Aggr500m_RefSB[NUM_250M_BANDS][DETECTORS_PER_500M_BAND][EV_500m_FRAMES]
Definition: Granule.h:977
char ScanType[MAX_NUM_SCANS][SCAN_TYPE_TEXT_SIZE]
Definition: Granule.h:752
int32 Extract_Line_Offset
Definition: Granule.h:764
uint8 EV_250m_RefSB_UI[NUM_250M_BANDS][DETECTORS_PER_250M_BAND][EV_250m_FRAMES]
Definition: Granule.h:912
#define EV_500m_FRAMES
Definition: Granule.h:471
int16 EV_500m[DETECTORS_PER_500M_BAND][NUM_500M_BANDS][EV_500m_FRAMES]
Definition: Granule.h:783
int32 EV_250m_Aggr1km_RefSB_SU_sds_id
Definition: Granule.h:971
int32 EV_250m_Aggr500m_RefSB_sds_id
Definition: Granule.h:963
@ L2
Definition: make_L3_v1.1.c:57
int safe_strcat(char *buf, char *str, int buflen)
Definition: Granule.c:834
#define MAX_PROCESSING_ENVIRONMENT_STRLEN
Definition: Granule.h:730
PGSt_SMF_status read_attribute(int32 s_id, char *attr_name, int32 TypeID, void *buffer)
Definition: HDF_Lib.c:33
int32 max_ev_frames
Definition: Granule.h:761
#define MODIS_F_NOK
instead the metadata field ProcessingEnvinronment is filled in from the output of a call to the POSIX compliant function uname from within the L1B code A small bug in L1B_Tables an incorrect comparison of RVS coefficients for TEBs to RVS coefficients for RSBs was being made This was replaced with a comparison between TEB coefficients This error never resulted in an incorrect RVS correction but did lead to recalculating the coefficients for each detector in a thermal band even if the coefficients were the same for all detectors To reduce to overall size of the reflective LUT HDF fill values were eliminated from all LUTs previously dimensioned where and where NUM_TIMES is the number of time dependent table pieces In Preprocess a small error where the trailing dropped scan counter was incremented when the leading dropped scan counter should have been was fixed This counter is internal only and is not yet used for any chiefly to casting of were added to make it LINUX compatible Output of code run on LINUX machines displays differences of at most scaled sector incalculable values of the Emissive calibration factor and incalculable values of SV or BB averages was moved outside the loop over frames in Emissive_Cal c since none of these quantities are frame dependent Initialization of b1 and XMS values in Preprocess c routine Process_OBCENG_Emiss was moved inside the detector loops The code was altered so that if up to five scans are dropped between the leading middle or middle trailing the leading or trailing granule will still be used in emissive calibration to form a cross granule average QA bits and are set for a gap between the leading middle and middle trailing granules respectively This may in rare instances lead to a change in emissive calibration coefficients for scans at the beginning or end of a granule A small bug in the Band correction algorithm was corrected an uncertainty value was being checked against an upper bound whereas the proper quantity to be checked was the corresponding SI
Definition: HISTORY.txt:595
uint8 EV_1km_RefSB_UI[NUM_1000M_REFL_BANDS][DETECTORS_PER_1KM_BAND][EV_1km_FRAMES]
Definition: Granule.h:920
#define L1B_EV_1000M_FILE
Definition: FNames.h:71
#define MODIS_W_OUT_OF_RANGE
int32 num_scans
Definition: Granule.h:860
#define True
Definition: Granule.h:537
#define REPROCESSING_ACTUAL_LUN
Definition: FNames.h:88
#define MAX_NUM_SCANS
Definition: Granule.h:422
int32 num_dead_detector_EV_data[NUM_DETECTORS]
Definition: Granule.h:1080
#define PROCESSING_ENVIRONMENT_LUN
Definition: FNames.h:86
@ INDEX_L1B_1km
Definition: Granule.h:589
#define WRITE_NIGHT_HIRES_LUN
Definition: FNames.h:90
char ProcessingCenter[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:742
const char * str
Definition: l1c_msi.cpp:35
uint8 EV_1km_Emissive_UI[NUM_1000M_EMISS_BANDS][DETECTORS_PER_1KM_BAND][EV_1km_FRAMES]
Definition: Granule.h:924
#define MODIS_S_NO_MORE
void Bad_L1A_Error_Out(char *name, char *message)
Definition: Granule.c:1616
PGSt_SMF_status Close_L1A_Granule(L1A_granule_t *L1A_Gran, L1A_Scan_t *L1A_Scan)
Definition: Granule.c:192
PGSt_SMF_status read_sds_rank2(int32 file_id, char *sds_name, int32 dim1, int32 dim2, void *data)
Definition: HDF_Lib.c:449
@ INDEX_1000M_NIGHT
Definition: Granule.h:572
PGSt_SMF_status Read_L1A_EV_Scan(int16 S, L1A_granule_t *L1A_Gran, L1A_Scan_t *L1A_Scan)
Definition: Granule.c:671
#define REFLECTIVE_TABLES_FILE
Definition: FNames.h:74
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 offsets between the high resolution geolocation and a bi linear interpolation extrapolation of the positions This can be used to reconstruct the high resolution geolocation Resolved Bug by delaying cumulation of gflags until after validation of derived products Resolved Bug by setting Latitude and Longitude to the correct fill resolving to support Near Real Time because they may be unnecessary if use of entrained ephemeris and attitude data is turned resolving bug report Corrected to filter out Aqua attitude records with missing status helping resolve bug MOD_PR03 will still correctly write scan and pixel data that does not depend upon the start time
Definition: HISTORY.txt:248
#define SCAN_TYPE_TEXT_SIZE
Definition: Granule.h:481
int16 EV_250m[DETECTORS_PER_250M_BAND][NUM_250M_BANDS][EV_250m_FRAMES]
Definition: Granule.h:779
int32 sw_f_id[NUM_L1B_EV_FILES]
Definition: Granule.h:857
#define MAX_AGGR_FRAMES
char * name
Definition: Granule.c:1234
#define F1
Definition: anc.h:25
#define NUM_1000M_NIGHT_BANDS
Definition: Granule.h:437
#define MAX_ERROR_MESSAGE_LENGTH
Definition: Granule.h:483
#define AGGREGATION_FAIL_SI
Definition: Granule.h:524
int32 incomplete_scans
Definition: Granule.h:760
int32 sd_id
Definition: Granule.h:747
data_t s[NROOTS]
Definition: decode_rs.h:75
#define NUM_250M_BANDS
Definition: Granule.h:430
int32 satellite_id
Definition: Granule.h:748
int16 EV_1km_night[DETECTORS_PER_1KM_BAND][NUM_1000M_NIGHT_BANDS][EV_1km_FRAMES]
Definition: Granule.h:791
int16 L1B_BANDS_AT_RES[NUM_L1A_RESOLUTIONS]
Definition: Granule.c:58
#define MODIS_F_HDF_ERROR
int16 RSCL_FLAG
Definition: Granule.c:76
int32 EV_250m_Aggr1km_RefSB_sds_id
Definition: Granule.h:964
l2prod offset
string msg
Definition: mapgen.py:227
#define L1B_OBC_FILE
Definition: FNames.h:72
#define MAX_DETECTORS_PER_BAND
Definition: Granule.h:474
int16 DETECT_PER_BAND_AT_RES[NUM_L1A_RESOLUTIONS]
Definition: Granule.c:68
int32 Extract_Pixel_Count
Definition: Granule.h:763
#define R
Definition: make_L3_v1.1.c:96
void L1BErrorMsg(char *L1B_location, PGSt_SMF_code code, char *input_message, char *assoc_function, int32 lun, char *other_msg, boolean error_out)
Definition: Granule.c:918
char Invalid_MOD01_Msg[]
Definition: Granule.c:913
#define MODIS_F_FILE_NOT_OPENED
#define NUM_1000M_DAY_BANDS
Definition: Granule.h:436
@ NUM_L1A_RESOLUTIONS
Definition: Granule.h:573
PGSt_SMF_status Close_L1B_Granule(L1B_granule_t *L1B_Gran, L1B_Scan_t *L1B_Scan, boolean skip_night_hi_res)
Definition: Granule.c:268
int32 EV_250m_Aggr1km_RefSB_UI_sds_id
Definition: Granule.h:968
GNU GENERAL PUBLIC LICENSE Version
Definition: LICENSE.txt:2
#define NUM_1000M_REFL_BANDS
Definition: Granule.h:432
char SatelliteInstrument[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:735
int i
Definition: decode_rs.h:71
#define MODIS_F_INVALID_ARGUMENT
PGSt_SMF_status Read_Run_Time_Parameters(Run_Time_Parameters_t *runtime_params)
Definition: Granule.c:2989
int read_extract_metadata(int32 sd_id, int32 *extract_pixel_offset, int32 *extract_pixel_count, int32 *extract_line_offset, int32 *extract_line_count)
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
uint16 EV_250m_Aggr1km_RefSB[NUM_250M_BANDS][DETECTORS_PER_1KM_BAND][EV_1km_FRAMES]
Definition: Granule.h:981
int16 MirrorSide[MAX_NUM_SCANS]
Definition: Granule.h:751
L1B_Scan_SI_t SI
Definition: Granule.h:973
char ProcessingEnvironment[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:741
int32 EV_500m_Aggr1km_RefSB_UI_sds_id
Definition: Granule.h:969
float64 EVStartTime_TAIsecond[MAX_NUM_SCANS]
Definition: Granule.h:753
#define DETECTORS_PER_250M_BAND
Definition: Granule.h:440
int32 UI_sds_id
Definition: Granule.h:948
#define MCST_LUT_VERSION_LUN
Definition: FNames.h:89
#define WRITE_MSG(c, m)
#define False
Definition: Granule.h:538
int32_t nb
Definition: atrem_corl1.h:132
#define INDEX_1000M_REFL
Definition: Granule.h:575
#define EV_250m_FRAMES
Definition: Granule.h:470