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