OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
Metadata.c
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 File: Metadata.c
4 
5 External functions:
6  Write_Gran_Metadata
7  Gran_Meta_Cal
8 
9 Other functions:
10  Write_Global_Metadata
11  Get_Electronics_Status
12  Get_Elec_Config_Status_Per_Gran
13  Get_Elec_Config_Status
14 
15 Revision History:
16  $Log: Metadata.c,v $
17  Revision 1.34 2017-08-02 10:41:20-04 xgeng
18  Aqua V6.2.1 update for C6.1 reprcoessing
19 
20  Revision 1.33 2014-10-02 13:36:48-04 xgeng
21  Added doi attributes to NRT product
22 
23  Revision 1.32 2012-06-26 15:07:42-04 xgeng
24  added the doi metadata
25 
26  Revision 1.27 2009-08-31 13:39:45-04 xgeng
27  Corrected a bug in the output of dead subframe list and noisy subframe list
28 
29  Revision 1.26 2009/07/24 20:00:37 xgeng
30  Added an extension "NRT" to the LOCALGRANULEID to indentify the Near-Real-Time product.
31 
32  Revision 1.21 2008/11/18 16:30:09 xgeng
33  merge the branch for V6.0.1
34 
35  Revision 1.20.1.3 2008/06/02 15:44:09 xgeng
36  Calculated the deadSubframeDataPercent for 250m and 500m bands; Added the effect of dead subframe on the bad_data_flag and uncalibratedDataPercent; Output Detector Quality Flag2, deadSubframeDataPercent, dead_subframe, noisy_subframe.
37 
38  Revision 1.20 2006/10/27 14:35:32 ltan
39  Changed to write PGEVersion value extracted from the PCF file (LUN 800500). Some comments regarding Night mode handling corrected.
40 
41 
42 *****************************************************************************/
43 
44 /*------------------------------------------------------------------
45  Must include PGS_MET.h before hdf includes as a typedef of
46  ATTRIBUTE in CUC/odldef.h conflicts with a #def in hdf includes.
47 ------------------------------------------------------------------*/
48 #include "MetadataP.h"
49 #include "Preprocess.h"
50 #include "L1B_Tables.h"
51 #include "PGS_TD.h"
52 #include "HDF_Lib.h"
53 #include "FNames.h"
54 #include "PGS_Error_Codes.h"
55 #include <time.h>
56 #include <libgen.h>
58 
59 #define TIMECODEASIZE 28
60 #define MECS_CORE "CoreMetadata.0"
61 #define MECS_ARCH "ArchiveMetadata.0"
62 
63 #define CALIBRATIONQUALITY_MACRO "marginal"
64 #define NADIRPOINTING_MACRO "Y"
65 #define ALGORITHMPACKAGENAME_MACRO "MODIS Level 1B Algorithm Package"
66 #define AUTOMATICQUALITYFLAG_MACRO "Suspect"
67 #define AUTOMATICQUALITYFLAGEXPLANATION_MACRO "not being investigated"
68 #define ANCILLARYINPUTTYPE_MACRO "Geolocation"
69 #define INSTRUMENTNAME_MACRO "Moderate Resolution Imaging SpectroRadiometer"
70 
73 
74 PGSt_SMF_status Write_Gran_Metadata
75  (Run_Time_Parameters_t *runtime_params,
76  L1B_Gran_Metadata_t *L1B_Gran_Meta,
77  QA_Data_t *QA,
80  L1A_granule_t *L1A_Gran,
81  boolean skip_night_hi_res)
82 /*
83 !C****************************************************************
84 !Description: Read metadata from input files and write to L1B files.
85 
86 !Input Parameters:
87  L1B_Gran_Metadata_t *L1B_Gran_Meta Contains metadata
88  QA_Data_t *QA Contains metadata
89  Preprocess_Data_t *PP Contains metadata
90  lookup_tables_t *tables Contains metadata
91  L1A_granule_t *L1A_Gran Contains satellite id
92  boolean skip_night_hi_res True if and only if all scans are
93  NIGHT mode and runtime parameter
94  Write_Night_Mode_HiRes_Data is False.
95 !Output Parameters:
96  none
97 
98 !Revision History:
99  $Log: Metadata.c,v $
100  Revision 1.34 2017-08-02 10:41:20-04 xgeng
101  Aqua V6.2.1 update for C6.1 reprcoessing
102 
103  Revision 1.33 2014-10-02 13:36:48-04 xgeng
104  Added doi attributes to NRT product
105 
106  Revision 1.32 2012-06-26 15:07:42-04 xgeng
107  added the doi metadata
108 
109  Revision 1.27 2009-08-31 13:39:45-04 xgeng
110  Corrected a bug in the output of dead subframe list and noisy subframe list
111 
112  Revision 1.26 2009/07/24 20:00:37 xgeng
113  Added an extension "NRT" to the LOCALGRANULEID to indentify the Near-Real-Time product.
114 
115  Revision 1.21 2008/11/18 16:30:09 xgeng
116  merge the branch for V6.0.1
117 
118  Revision 1.20.1.3 2008/06/02 15:44:09 xgeng
119  Calculated the deadSubframeDataPercent for 250m and 500m bands; Added the effect of dead subframe on the bad_data_flag and uncalibratedDataPercent; Output Detector Quality Flag2, deadSubframeDataPercent, dead_subframe, noisy_subframe.
120 
121  (continue at top of the file)
122 
123  Revision 1.7 2005/11/21 22:04:11 seadas
124  MDM: fixed minor bug in the LOCALGRANULEID field so now only the filename
125  and not the path is written
126 
127  Revision 1.6 2005/10/27 20:59:38 seadas
128  MAR: Updated from swdev 10/27/05.
129 
130  Revision 02.17 October 31, 2003 Razor Issue #195
131  Changed the source of PROCESSINGCENTER from the Run Time Parameters
132  read from PCF file instead of from QA LUTs.
133  Liqin Tan SAIC GSO (ltan@saicmodis.com)
134 
135  Revision 02.16 September 15, 2003 Razor Issue #181
136  Added PROCESSINGENVIRONMENT to Archived Metadata.
137  Liqin Tan SAIC GSO (ltan@saicmodis.com)
138 
139  Revision 02.15 September 3, 2002 Razor Issue #188
140  Change the form of ProductionHistory Archived Metadata variable.
141  Liqin Tan SAIC GSO (ltan@saicmodis.com)
142 
143  Revision 02.14 December 13, 2002 Razor Issue #189
144  Added ProductionHistory Archived Metadata variable
145  generation.
146  Alice Isaacman SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
147 
148  Revision 02.13 July 8, 2002 Razor Issue #185
149  Change source of copied metadata to Geolocation file.
150  Alice Isaacman SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
151 
152  Revision 02.11 November 12, 2001 (Razor Issue #169)
153  Added input parameter skip_night_hi_res and changed logic so that
154  250m and 500m data are not written when granule has no day mode
155  scans and runtime parameter Write_Night_Mode_HiRes_Data is False.
156  Moved output_file_indices_t to MetadataP.h.
157  Alice Isaacman SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
158 
159  Revision 02.10 1998/4/8 Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
160  Added functions to set, get, copy attribute based on original macros.
161  Added new granule metadata.
162 
163  Revision 01.03 1997/6/4 Zhidong Hao (hao@barebackride.gsfc.nasa.gov)
164 
165  Revision 01.02 1997/2/27 Neal Devine (neal.devine@gsfc.nasa.gov)
166  Rewrote ECSmetadata code for clarity and consistent with CCR.
167 
168  Revision 01.01 1996/09/26 Neal Devine (neal.devine@gsfc.nasa.gov)
169  Added multiple input and ancilinput files, taken from pcf, to metadata.
170 
171  Revision 01.00 1996/04/05 Neal Devine (neal.devine@gsfc.nasa.gov)
172  Original Development
173 
174 !Team-unique Header:
175  This software is developed by the MODIS Characterization Support
176  Team (MCST)for the National Aeronautics and Space Administration,
177  Goddard Space Flight Center, under contract NAS5-32373.
178 
179 
180 !References and Credits:
181  The time setting code was borrowed from Paul Fishers timea.c
182 
183  HDF portions developed at the National Center for Supercomputing
184  Applications at the University of Illinois at Urbana-Champaign.
185 
186 !Design Notes:
187 
188 !END********************************************************************
189 */
190 {
191  PGSt_PC_Logical in_fileID = 0;
192  intn hdf_return = FAIL;
193  int32 i = 0; /* for general indexing */
194  PGSt_integer Version = 1;
195  char OBC_fname[PGSd_PC_FILE_PATH_MAX];
196 
197  PGSt_SMF_status returnStatus = MODIS_S_OK;
198  char *location = "Write_Gran_Metadata";
199  PGSt_MET_all_handles mdhandles;
200  PGSt_integer version = 1;
201  int32 VersionID;
202  struct tm *curtime = NULL;
203  time_t t;
204  char *ptr = NULL;
205  char beginDateTimeA[30];
206  char beginDateTimeB[30];
207  char procDateTimeA[30];
208  char procDateTimeB[30];
209  char shortname[10];
210  char sub_shortname[6];
211  char ProductionHistory[MAX_PRODUCTIONHISTORY_SIZE];
212  char MCSTversion[MAX_MCST_VERSION_BUFFER];
213  char MOD01_ProductionHistory[MAX_PRODUCTIONHISTORY_SIZE];
214  char MOD03_ProductionHistory[MAX_PRODUCTIONHISTORY_SIZE];
215  const char delimiter[] = "_";
216  /* The following match the organization of "input_file_luns" */
217 
218  typedef enum
219  {
220  INDEX_LEADING_GRAN,
221  INDEX_MIDDLE_GRAN,
222  INDEX_TRAILING_GRAN,
223  INDEX_GEO_FILE,
224  INDEX_REFL_TABLES,
225  INDEX_EMISS_TABLES,
226  INDEX_QA_TABLES,
227  NUM_INPUT_FILES
228  } input_file_macros_t;
229 
230  /* Logical unit numbers for all input files. */
231 
232  int32 input_file_luns[NUM_INPUT_FILES] =
233  {
241  };
242 
243  /* The following are macros for the output files */
244 
245 
246  /* The following are LUNs for the MCF files and the output granules */
247 
248  int32 mcf_file_luns[NUM_OUTPUT_FILES] =
249  {
250  MCF_FILE_QKM,
251  MCF_FILE_HKM,
252  MCF_FILE_1KM,
254  };
255  int32 output_file_luns[NUM_OUTPUT_FILES] =
256  {
261  };
262 
263  char input_file_UR_name[NUM_INPUT_FILES][PGSd_PC_UREF_LENGTH_MAX];
264  char *input_filename_p[NUM_INPUT_FILES];
265  int32 out_sd_id[NUM_OUTPUT_FILES] = {FAIL, FAIL, FAIL, FAIL};
266  char L1B_modis_filenames[132];
267 
268  int R = 0; /* file_index, etc. */
269 
270  /*
271  * Starting output file index; changes to INDEX_L1B_EV_1000M_FILE
272  * when HiRes night mode is not written.
273  */
274  int16 start_output_file_index = INDEX_L1B_EV_250M_FILE;
275 
276  char str[80]; /* parameter value string of additional attributes */
277 
278  float64 eastboundingcoordinate[4] ;
279  float64 westboundingcoordinate[4] ;
280  float64 northboundingcoordinate[4] ;
281  float64 southboundingcoordinate[4] ;
282  char daynightflag[COMMON_TEXT_SIZE];
283  char equatorcrossingdate[MAX_DATE_TIME_SIZE];
284  char equatorcrossingtime[MAX_DATE_TIME_SIZE];
285 
286  float64 equatorcrossinglongitude;
287 
288  char exclusiongringflag[COMMON_TEXT_SIZE];
289  char rangebeginningdate[MAX_DATE_TIME_SIZE];
290  char rangebeginningtime[MAX_DATE_TIME_SIZE];
291  char rangeendingdate[MAX_DATE_TIME_SIZE];
292  char rangeendingtime[MAX_DATE_TIME_SIZE];
293  float64 gringpointlongitude[4];
294  float64 gringpointlatitude[4];
295  int32 gringpointsequenceno[4];
296 
297  int orbitnumber = 0;
298 
299  const char* extension = "NRT.hdf";
300  const char* product_version = "NRT.061";
301  if(strcmp(runtime_params->ReprocessingActual, "Near Real Time"))
302  {
303  extension += 4;
304  product_version += 4;
305 
306  }
307 
308  /* This is not necessary, but to supress
309  the warning messages (UMR) when run Purify
310  */
311  for (i = 0; i < 30; i++)
312  {
313  beginDateTimeA[i] = '\0';
314  beginDateTimeB[i] = '\0';
315  procDateTimeA[i] = '\0';
316  procDateTimeB[i] = '\0';
317  }
318 
319  in_fileID = FIRST_L1A_GRANULE;
320  out_sd_id[INDEX_L1B_EV_250M_FILE] =
321  L1B_Gran_Meta->L1B_Gran_sd_id[INDEX_L1B_250m];
322  out_sd_id[INDEX_L1B_EV_500M_FILE] =
323  L1B_Gran_Meta->L1B_Gran_sd_id[INDEX_L1B_500m];
324  out_sd_id[INDEX_L1B_EV_1000M_FILE] =
325  L1B_Gran_Meta->L1B_Gran_sd_id[INDEX_L1B_1km];
326 
327  /*--------------------------------------------
328  Reopen L1B_OBC file to write metadata
329  --------------------------------------------*/
330  returnStatus = PGS_PC_GetReference (L1B_OBC_FILE, &Version, OBC_fname);
331  if (returnStatus != PGS_S_SUCCESS)
332  {
333  returnStatus = MODIS_F_FILE_NOT_FOUND;
334  L1BErrorMsg(location, returnStatus,
335  "Could not retrieve file name from PCF.",
336  "PGS_PC_GetReference", L1B_OBC_FILE, NULL, True);
337  return returnStatus;
338  }
339 
340  out_sd_id[INDEX_L1B_OBC_FILE] = SDstart (OBC_fname, DFACC_RDWR);
341  if (out_sd_id[INDEX_L1B_OBC_FILE] == FAIL)
342  {
343  returnStatus = MODIS_F_FILE_NOT_OPENED;
344  L1BErrorMsg(location, returnStatus,
345  "Could not open file for SD read/write access.",
346  "SDstart", L1B_OBC_FILE, NULL, True);
347  return returnStatus;
348  }
349 
350  /*----------------------------------
351  Generate processing time.
352  ----------------------------------*/
353  if((t = time(NULL)) == -1)
355  "time() failed in Write_Gran_Metadata(), Metadata.c");
356 
357  if(!(curtime = (struct tm *)gmtime(&t)))
359  "localtime() failed in Write_Gran_Metadata(), Metadata.c");
360 
361  /* obtain CCSDS ASCII time code A */
362  if((strftime(procDateTimeA, TIMECODEASIZE,
363  "%Y-%m-%dT%H:%M:%S.000000Z", curtime)) == 0)
365  "strftime() failed in Write_Gran_Metadata(), Metadata.c");
366 
367  /*---------------------------------------------------------------------
368  Generate MODIS Output file names for each of 3 resolutions and OBC.
369  ---------------------------------------------------------------------*/
370  pgs_in.fileID = in_fileID;
371  pgs_in.version = 1;
372  pgs_in.hdfAttr = "CoreMetadata.0";
373 
374  get_string_attr( "RANGEBEGINNINGDATE", beginDateTimeA);
375  beginDateTimeA[10] = 'T';
376  get_string_attr( "RANGEBEGINNINGTIME", &beginDateTimeA[11]);
377  beginDateTimeA[26] = 'Z';
378 
379  if (PGS_TD_ASCIItime_AtoB(beginDateTimeA, beginDateTimeB) != PGS_S_SUCCESS)
381  "PGS_TD_ASCIItime_AtoB() in Write_Gran_Metadata(), Metadata.c");
382 
383  if(PGS_TD_ASCIItime_AtoB(procDateTimeA, procDateTimeB) != PGS_S_SUCCESS )
385  "PGS_TD_ASCIItime_AtoB() in Write_Gran_Metadata(), Metadata.c");
386 
387  /*
388  * Generate LOCALGRANULEID
389  */
390 
391  if (L1A_Gran->satellite_id == TERRA)
392  strcpy(sub_shortname, "MOD02");
393  else /* must be "Aqua", otherwise the code error out at Read_QA_Tables. */
394  strcpy(sub_shortname, "MYD02");
395 
396  /* initialize the doi metadata */
397  strcpy(L1B_Gran_Meta->doi_attr_name, "identifier_product_doi");
398  strcpy(L1B_Gran_Meta->doi_authority_attr_name, "identifier_product_doi_authority");
399  strcpy(L1B_Gran_Meta->doi_authority_para_value, "http://dx.doi.org");
400 
401  /*------------------------------------------------
402  Get input & ancil file names from pcf file
403  ------------------------------------------------*/
404  for ( R = 0 ; R < NUM_INPUT_FILES ; R++ )
405  {
406  if (R == INDEX_LEADING_GRAN &&
408  ;
409  else if (R == INDEX_TRAILING_GRAN &&
411  ;
412  else
413  {
414  version = 1;
415  returnStatus = PGS_PC_GetUniversalRef(input_file_luns[R], &version,
416  &input_file_UR_name[R][0]);
417  if (returnStatus != PGS_S_SUCCESS)
418  {
419  returnStatus = MODIS_F_FILE_NOT_FOUND;
420  L1BErrorMsg(location, returnStatus,
421  "Could not get universal reference from PCF.",
422  "PGS_PC_GetUniversalRef", input_file_luns[R], NULL, True);
423  return returnStatus;
424  }
425  }
426  }
427 
428  /*
429  * Assemble the INPUTPOINTER from the universal references of the input files
430  * except that the geolocation UR is placed in ANCILLARYINPUTPOINTER.
431  * The logic implemented also excludes any MOD01 granule that is treated as
432  * "missing".
433  */
434 
435  i = 0;
436  for ( R = 0; R < NUM_INPUT_FILES ; R++ )
437  {
438  if ( R == INDEX_GEO_FILE)
439  continue; /* Geolocation file name is put in ancillaryinputpointer */
440  if (R == INDEX_LEADING_GRAN &&
442  continue;
443  else if (R == INDEX_TRAILING_GRAN &&
445  continue;
446 
447  input_filename_p[i] = &input_file_UR_name[R][0];
448  for (ptr = &input_file_UR_name[R][0]; *ptr != '\0'; ptr++)
449  if (*ptr == '/') /* skip over the path name */
450  input_filename_p[i] = ptr+1;
451  i++;
452  }
453  input_filename_p[i] = NULL; /* Indicates end of array to PGS_MET_SetAttr */
454 
455  /*------------------------------------------------
456  Initialize metadata structures
457  ------------------------------------------------*/
458  /*
459  * If this is a NIGHT mode granule and the runtime parameter
460  * Write_Night_Mode_HiRes_Data is False, do not write the 250m and 500m
461  * resolution files, and so start with output file number 2, not 0.
462  */
463 
464  if (skip_night_hi_res == True)
465  start_output_file_index = INDEX_L1B_EV_1000M_FILE;
466  else
467  start_output_file_index = INDEX_L1B_EV_250M_FILE;
468 
469 
470  for (R = start_output_file_index; R < NUM_OUTPUT_FILES; R++)
471  {
472  returnStatus = PGS_MET_Init(mcf_file_luns[R], mdhandles);
473  if (returnStatus != PGS_S_SUCCESS)
474  {
475  returnStatus = MODIS_F_FILE_NOT_FOUND;
476  L1BErrorMsg(location, returnStatus,
477  "Could not initialize the PGS Metadata from MCF file.",
478  "PGS_MET_Init", mcf_file_luns[R], NULL, True);
479  return returnStatus;
480  }
481 
482  /* Check if the "ShortName" value agrees with the satellite id. */
483 
484  ptr = shortname;
485  returnStatus = PGS_MET_GetSetAttr(mdhandles[1], "ShortName", &ptr);
486  if (returnStatus != PGS_S_SUCCESS)
487  {
488  returnStatus = MODIS_F_READ_ERROR;
489  L1BErrorMsg(location, returnStatus,
490  "Could not get the value of \"ShortName\" from MCF file.",
491  "PGS_MET_GetSetAttr", mcf_file_luns[R], NULL, True);
492  return returnStatus;
493  }
494  if (!((L1A_Gran->satellite_id == TERRA &&
495  strncmp(shortname, "MOD", 3) == 0) ||
496  (L1A_Gran->satellite_id == AQUA &&
497  strncmp(shortname, "MYD", 3) == 0)))
498  {
499  returnStatus = MODIS_F_OUT_OF_RANGE;
500  L1BErrorMsg(location, returnStatus,
501  "ShortName in MCF file is not consistent with the"
502  " instrument name in L1A granule.",
503  NULL, mcf_file_luns[R],
504  "The MCF file could be invalid.", True);
505  return returnStatus;
506  }
507 
508  /* generate the doi parameter value for each L1B product */
509  ptr = &L1B_Gran_Meta->doi_para_value[R][0];
510  sprintf(ptr, "10.5067/MODIS/%s.%s", shortname, product_version);
511 
512  /*
513  * Read the VersionID from MCF and create the LocalGranuleID
514  */
515 
516  returnStatus = PGS_MET_GetSetAttr(mdhandles[1], "VersionID", &VersionID);
517  if (returnStatus != PGS_S_SUCCESS)
518  {
519  returnStatus = MODIS_F_READ_ERROR;
520  L1BErrorMsg(location, returnStatus,
521  "Could not get the value of \"VersionID\" from MCF file.",
522  "PGS_MET_GetSetAttr", mcf_file_luns[R], NULL, True);
523  return returnStatus;
524  }
525  if (VersionID < 1 || VersionID > 999)
526  {
527  returnStatus = MODIS_F_OUT_OF_RANGE;
528  L1BErrorMsg(location, returnStatus,
529  "VersionID is not in range of [1-999].",
530  NULL, mcf_file_luns[R],
531  "The MCF file could be invalid.", True);
532  return returnStatus;
533  }
534 
535 #ifdef SEADAS
536  Version = 1;
537  returnStatus = PGS_PC_GetReference (output_file_luns[R], &Version,
538  L1B_modis_filenames);
539  sprintf(L1B_modis_filenames, "%s", basename(L1B_modis_filenames));
540 #else
541  sprintf(L1B_modis_filenames,
542  "%s%s.A%4.4s%3.3s.%2.2s%2.2s.%03d.%4.4s%3.3s%2.2s%2.2s%2.2s.%s",
543  sub_shortname, file_sub_name[R],
544  &beginDateTimeB[0], &beginDateTimeB[5],
545  &beginDateTimeB[9],&beginDateTimeB[12],
546  VersionID, &procDateTimeB[0],
547  &procDateTimeB[5],&procDateTimeB[9],&procDateTimeB[12],
548  &procDateTimeB[15], extension);
549 #endif
550 
551  /*------------------------------------------------------
552  Set all "coremetadata.0" attributes not
553  initialized via PGS_MET_Init (not PCF/MCF).
554  ------------------------------------------------------*/
555  pgs_out_mdHandle = mdhandles[1]; /* [1] is for inventory (Core) metadata */
556 
557  pgs_in.fileID = in_fileID;
558  pgs_in.version = 1;
559  pgs_in.hdfAttr = "CoreMetadata.0";
560 
561  set_string_attr ( "PGEVERSION", runtime_params->PGE02_Version);
562 
563  copy_string_attr ( "RANGEBEGINNINGDATE" , rangebeginningdate );
564  copy_string_attr ( "RANGEBEGINNINGTIME" , rangebeginningtime );
565  copy_string_attr ( "RANGEENDINGDATE" , rangeendingdate );
566  copy_string_attr ( "RANGEENDINGTIME" , rangeendingtime );
567 
568  copy_string_attr ( "DAYNIGHTFLAG" , daynightflag );
569 
570  set_string_attr ( "ADDITIONALATTRIBUTENAME.1" ,
571  "AveragedBlackBodyTemperature" );
572  sprintf(str, "%7.2f", PP->PP_Emiss.T_bb_gran);
573  set_string_attr ( "PARAMETERVALUE.1" , str );
574  set_string_attr ( "ADDITIONALATTRIBUTENAME.2" ,
575  "AveragedMirrorTemperature" );
576  sprintf(str, "%7.2f", PP->PP_Emiss.T_mir_gran);
577  set_string_attr ( "PARAMETERVALUE.2" , str );
578  set_string_attr ( "ADDITIONALATTRIBUTENAME.3" ,
579  "AveragedFocalPlane1Temperature" );
580  sprintf(str, "%7.2f", PP->PP_Emiss.T_fp1);
581  set_string_attr ( "PARAMETERVALUE.3" , str );
582  set_string_attr ( "ADDITIONALATTRIBUTENAME.4" ,
583  "AveragedFocalPlane2Temperature" );
584  sprintf(str, "%7.2f", PP->PP_Emiss.T_fp2);
585  set_string_attr ( "PARAMETERVALUE.4" , str );
586  set_string_attr ( "ADDITIONALATTRIBUTENAME.5" ,
587  "AveragedFocalPlane3Temperature" );
588  sprintf(str, "%7.2f", PP->PP_Emiss.T_fp3);
589  set_string_attr ( "PARAMETERVALUE.5" , str );
590  set_string_attr ( "ADDITIONALATTRIBUTENAME.6" ,
591  "AveragedFocalPlane4Temperature" );
592  sprintf(str, "%7.2f", PP->PP_Emiss.T_fp4);
593  set_string_attr ( "PARAMETERVALUE.6" , str );
594  set_string_attr ( "ADDITIONALATTRIBUTENAME.7" ,
595  "CalibrationQuality" );
596 
597  set_string_attr ( "PARAMETERVALUE.7" ,
599 
600  set_string_attr ( "ADDITIONALATTRIBUTENAME.8" ,
601  "MissionPhase" );
602 
603  set_string_attr ( "PARAMETERVALUE.8" ,
604  tables->QA.common_QA_tables.mission_phase );
605 
606  set_string_attr ( "ADDITIONALATTRIBUTENAME.9" , "NadirPointing" );
607 
608  set_string_attr ( "PARAMETERVALUE.9" , NADIRPOINTING_MACRO);
609 
610  set_string_attr ( "ADDITIONALATTRIBUTENAME.10" , L1B_Gran_Meta->doi_attr_name );
611 
612  set_string_attr ( "PARAMETERVALUE.10" , &L1B_Gran_Meta->doi_para_value[R][0] );
613 
614  set_string_attr ( "ADDITIONALATTRIBUTENAME.11" , L1B_Gran_Meta->doi_authority_attr_name );
615 
616  set_string_attr ( "PARAMETERVALUE.11" , L1B_Gran_Meta->doi_authority_para_value );
617 
618  switch(R)
619  {
621  set_attr ( "QAPERCENTMISSINGDATA.1" ,
622  &L1B_Gran_Meta->qapercent_missing_250m);
623  set_attr ( "QAPERCENTINTERPOLATEDDATA.1" ,
624  &L1B_Gran_Meta->qapercent_interpolated_250m);
625  set_attr ( "QAPERCENTOUTOFBOUNDSDATA.1" ,
626  &L1B_Gran_Meta->qapercent_outofbound_250m);
627  set_string_attr ( "PARAMETERNAME.1" , "EV_250_RefSB" );
628  set_string_attr ( "AUTOMATICQUALITYFLAG.1",
630  set_string_attr ( "AUTOMATICQUALITYFLAGEXPLANATION.1",
632  break;
634  set_attr ( "QAPERCENTMISSINGDATA.1" ,
635  &L1B_Gran_Meta->qapercent_missing_500m);
636  set_attr ( "QAPERCENTINTERPOLATEDDATA.1" ,
637  &L1B_Gran_Meta->qapercent_interpolated_500m);
638  set_attr ( "QAPERCENTOUTOFBOUNDSDATA.1" ,
639  &L1B_Gran_Meta->qapercent_outofbound_500m);
640  set_string_attr ( "PARAMETERNAME.1" , "EV_500_RefSB" );
641  set_string_attr ( "AUTOMATICQUALITYFLAG.1",
643  set_string_attr ( "AUTOMATICQUALITYFLAGEXPLANATION.1",
645  break;
647  set_attr ( "QAPERCENTMISSINGDATA.1" ,
648  &L1B_Gran_Meta->refl_1km_qapercent_missing);
649  set_attr ( "QAPERCENTMISSINGDATA.2" ,
650  &L1B_Gran_Meta->emiss_qapercent_missing);
651  set_attr ( "QAPERCENTINTERPOLATEDDATA.1" ,
652  &L1B_Gran_Meta->qapercent_interpolated_refl_1km);
653  set_attr ( "QAPERCENTINTERPOLATEDDATA.2" ,
654  &L1B_Gran_Meta->qapercent_interpolated_emiss);
655  set_attr ( "QAPERCENTOUTOFBOUNDSDATA.1" ,
656  &L1B_Gran_Meta->refl_1km_qapercent_outofbound);
657  set_attr ( "QAPERCENTOUTOFBOUNDSDATA.2" ,
658  &L1B_Gran_Meta->emiss_qapercent_outofbound);
659  set_string_attr ( "PARAMETERNAME.1" , "EV_1KM_RefSB" );
660  set_string_attr ( "PARAMETERNAME.2" , "EV_1KM_Emissive" );
661  set_string_attr ( "AUTOMATICQUALITYFLAG.1",
663  set_string_attr ( "AUTOMATICQUALITYFLAG.2",
665  set_string_attr ( "AUTOMATICQUALITYFLAGEXPLANATION.1",
667  set_string_attr ( "AUTOMATICQUALITYFLAGEXPLANATION.2",
669  break;
670  default:
671  set_attr ( "QAPERCENTMISSINGDATA.1" ,
672  &L1B_Gran_Meta->refl_1km_qapercent_missing);
673  set_attr ( "QAPERCENTMISSINGDATA.2" ,
674  &L1B_Gran_Meta->emiss_qapercent_missing);
675  set_attr ( "QAPERCENTINTERPOLATEDDATA.1" ,
676  &L1B_Gran_Meta->qapercent_interpolated_refl_1km);
677  set_attr ( "QAPERCENTINTERPOLATEDDATA.2" ,
678  &L1B_Gran_Meta->qapercent_interpolated_emiss);
679  set_attr ( "QAPERCENTOUTOFBOUNDSDATA.1" ,
680  &L1B_Gran_Meta->refl_1km_qapercent_outofbound);
681  set_attr ( "QAPERCENTOUTOFBOUNDSDATA.2" ,
682  &L1B_Gran_Meta->emiss_qapercent_outofbound);
683  set_string_attr ( "PARAMETERNAME.1" , "EV_1KM_RefSB" );
684  set_string_attr ( "PARAMETERNAME.2" , "EV_1KM_Emissive" );
685  set_string_attr ( "AUTOMATICQUALITYFLAG.1",
687  set_string_attr ( "AUTOMATICQUALITYFLAG.2",
689  set_string_attr ( "AUTOMATICQUALITYFLAGEXPLANATION.1",
691  set_string_attr ( "AUTOMATICQUALITYFLAGEXPLANATION.2",
693  break;
694  }
695 
696  set_string_attr ( "REPROCESSINGPLANNED",
697  runtime_params->ReprocessingPlanned);
698  set_string_attr ( "REPROCESSINGACTUAL",
699  runtime_params->ReprocessingActual);
700 
701  set_ptrstring_attr ( "INPUTPOINTER" , input_filename_p);
702 
703  set_string_attr ( "ANCILLARYINPUTTYPE.1",
705  set_string_attr ( "ANCILLARYINPUTPOINTER.1",
706  &input_file_UR_name[INDEX_GEO_FILE][0]);
707  set_string_attr ( "LOCALGRANULEID" ,
708  L1B_modis_filenames);
709 
710  /*
711  * Generate the new "ProductionHistory" based on the MOD01 and MOD03
712  * PGEVERSIONS. Using the PGEVERSION ensures backwards compatibility with
713  * earlier version of MOD01 and MOD03 which did not write the
714  * "ProductionHistory" metadata variable.
715  */
716 
717  /* Get PGEVERSION from L1A in granule MOD01 */
718  get_string_attr ( "PGEVERSION", MOD01_ProductionHistory);
719 
720  /* Make the first part of the PGE02 ProductionHistory: */
721  sprintf(ProductionHistory, "PGE02:");
722  strcpy (MCSTversion, tables->QA.common_QA_tables.MCST_Version);
723  safe_strcat( ProductionHistory,
724  strtok(MCSTversion, delimiter),
725  /* Eliminate the "_Aqua/Terra" designator on the LUT version.*/
727  safe_strcat(ProductionHistory, ";PGE01:", MAX_PRODUCTIONHISTORY_SIZE);
728 
729  /*---------------------------------------------
730  Setup Archive metadata fields
731  ---------------------------------------------*/
732 
734  pgs_in.version = 1;
735  pgs_in.hdfAttr = "CoreMetadata.0";
736 
737  /* Get PGEVERSION from geolocation file MOD03 */
738  get_string_attr ( "PGEVERSION", MOD03_ProductionHistory);
739 
740  /* Add on the second part of the PGE02 ProductionHistory: */
741  if ( strcmp (MOD03_ProductionHistory, MOD01_ProductionHistory) )
742  /* MOD01 and MOD03 from different PGE01 versions */
743  {
744  safe_strcat(ProductionHistory, MOD01_ProductionHistory,
746  safe_strcat(ProductionHistory, ":mod01", MAX_PRODUCTIONHISTORY_SIZE);
747  safe_strcat(ProductionHistory, ";PGE01:", MAX_PRODUCTIONHISTORY_SIZE);
748  safe_strcat(ProductionHistory, MOD03_ProductionHistory,
750  safe_strcat(ProductionHistory, ":mod03", MAX_PRODUCTIONHISTORY_SIZE);
751  }
752  else
753  /* MOD01 and MOD03 from same PGE01 version */
754  {
755  safe_strcat(ProductionHistory, MOD01_ProductionHistory,
757  }
758 
759  copy_attr ( "ORBITNUMBER.1" , &orbitnumber );
760  copy_attr ( "EQUATORCROSSINGLONGITUDE.1", &equatorcrossinglongitude);
761 
762  copy_string_attr ( "EQUATORCROSSINGDATE.1", equatorcrossingdate);
763  copy_string_attr ( "EQUATORCROSSINGTIME.1", equatorcrossingtime);
764  copy_string_attr ( "EXCLUSIONGRINGFLAG.1" , exclusiongringflag);
765 
766  copy_attr ( "GRINGPOINTLATITUDE.1" , gringpointlatitude);
767  copy_attr ( "GRINGPOINTLONGITUDE.1" , gringpointlongitude);
768  copy_attr ( "GRINGPOINTSEQUENCENO.1", gringpointsequenceno);
769 
770 
771  pgs_out_mdHandle = mdhandles[2]; /* [2] is for Archive metadata */
772 
773  /* Write PGE02 ProductionHistory into Archive metadata */
774  set_string_attr ( "PRODUCTIONHISTORY", ProductionHistory);
775 
776  pgs_in.hdfAttr = "ArchiveMetadata.0";
777  copy_attr ( "EASTBOUNDINGCOORDINATE" , eastboundingcoordinate);
778  copy_attr ( "WESTBOUNDINGCOORDINATE" , westboundingcoordinate);
779  copy_attr ( "NORTHBOUNDINGCOORDINATE" , northboundingcoordinate);
780  copy_attr ( "SOUTHBOUNDINGCOORDINATE" , southboundingcoordinate);
781 
782  set_string_attr ( "ALGORITHMPACKAGENAME" ,
784  set_string_attr ( "ALGORITHMPACKAGEACCEPTANCEDATE",
785  tables->QA.common_QA_tables.AlgorithmPackageAcceptanceDate);
786  set_string_attr ( "ALGORITHMPACKAGEMATURITYCODE",
787  tables->QA.common_QA_tables.AlgorithmPackageMaturityCode);
788  set_string_attr ( "ALGORITHMPACKAGEVERSION",
789  tables->QA.common_QA_tables.MCST_Version);
790  set_string_attr ( "INSTRUMENTNAME", INSTRUMENTNAME_MACRO);
791  set_string_attr ( "PROCESSINGCENTER",
792  runtime_params->ProcessingCenter);
793  set_string_attr ( "PROCESSINGENVIRONMENT",
794  runtime_params->ProcessingEnvironment);
795 
796  /*-----------------------------------------------------
797  Write the core and archieve metadata to hdf files
798  -----------------------------------------------------*/
799  returnStatus = PGS_MET_Write(mdhandles[1], MECS_CORE, out_sd_id[R]);
800  if (returnStatus != PGS_S_SUCCESS)
801  {
802  returnStatus = MODIS_F_WRITE_ERROR;
803  L1BErrorMsg(location, returnStatus,
804  "Could not write ECS Core metadata to output granule.",
805  "PGS_MET_Write", output_file_luns[R], NULL, True);
806  return returnStatus;
807  }
808 
809  returnStatus = PGS_MET_Write(mdhandles[2], MECS_ARCH, out_sd_id[R]);
810  if (returnStatus != PGS_S_SUCCESS)
811  {
812  returnStatus = MODIS_F_WRITE_ERROR;
813  L1BErrorMsg(location, returnStatus,
814  "Could not write ECS Archive metadata to output granule.",
815  "PGS_MET_Write", output_file_luns[R], NULL, True);
816  return returnStatus;
817  }
818 
819  PGS_MET_Remove();
820  }
821 
822  returnStatus = Write_Global_Metadata(L1B_Gran_Meta,
823  QA,
824  tables,
825  out_sd_id[INDEX_L1B_OBC_FILE],
826  skip_night_hi_res);
827  if (returnStatus != MODIS_S_OK)
828  {
829  L1BErrorMsg(location, returnStatus, NULL,
830  "Write_Global_Metadata", 0, NULL, True);
831  return returnStatus;
832  }
833 
834 
835  /*-------------------------
836  Close L1B_OBC file
837  -------------------------*/
838  hdf_return = SDend(out_sd_id[INDEX_L1B_OBC_FILE]);
839  if (hdf_return == FAIL)
840  {
841  returnStatus = MODIS_F_HDF_ERROR;
842  L1BErrorMsg(location, returnStatus, NULL,
843  "SDend", L1B_OBC_FILE, NULL, True);
844  return returnStatus;
845  }
846 
847  return(MODIS_S_OK);
848 }
849 
850 void get_attr( char *field, void *value)
851 /*
852 !C****************************************************************
853 !Description:
854  Helper function to Write_Gran_Metadata(). Reads a non-string data item
855  from ECS metadata.
856 
857 !Input Parameters:
858  char *field name of data to read
859 
860 !Output Parameters:
861  char *value buffer to read data into
862 
863 !Revision History:
864  (continue at top of the file)
865 
866  Revision 01.01 November 24, 1999
867  Error message revised.
868  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
869 
870  Revision 01.00 1998/4/8
871  Original Development
872  Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
873 
874 !Team-unique Header:
875  This software is developed by the MODIS Characterization Support
876  Team (MCST)for the National Aeronautics and Space Administration,
877  Goddard Space Flight Center, under contract NAS5-32373.
878 
879 !References and Credits:
880  HDF portions developed at the National Center for Supercomputing
881  Applications at the University of Illinois at Urbana-Champaign.
882 
883 !Design Notes:
884  pgs_in is a global variable which holds the file LUN and other info
885  needed for PGS_MET_GetPCAttr.
886 
887 !END********************************************************************
888 */
889 {
890  int ret;
891  ret = PGS_MET_GetPCAttr(pgs_in.fileID,
892  pgs_in.version,
893  pgs_in.hdfAttr,
894  field,
895  value);
896  if (ret != PGS_S_SUCCESS)
897  {
898  char errorMessage[256];
899  sprintf(errorMessage, "Could not get metadata \"%s\" from %s.",
900  field, pgs_in.hdfAttr);
901  L1BErrorMsg("get_attr", MODIS_F_READ_ERROR, errorMessage,
902  "PGS_MET_GetPCAttr", pgs_in.fileID, NULL, True);
903  }
904 }
905 
906 void get_string_attr( char *field, char *value)
907 /*
908 !C****************************************************************
909 !Description:
910  Helper function to Write_Gran_Metadata(). Reads a string data item
911  from ECS metadata.
912 
913 !Input Parameters:
914  char *field name of data to read
915 
916 !Output Parameters:
917  char *value buffer to read data into
918 
919 !Revision History:
920  (continue at top of the file)
921 
922  Revision 01.01 November 24, 1999
923  Error message revised.
924  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
925 
926  Revision 01.00 1998/4/8
927  Original Development
928  Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
929 
930 !Team-unique Header:
931  This software is developed by the MODIS Characterization Support
932  Team (MCST)for the National Aeronautics and Space Administration,
933  Goddard Space Flight Center, under contract NAS5-32373.
934 
935 !References and Credits:
936  HDF portions developed at the National Center for Supercomputing
937  Applications at the University of Illinois at Urbana-Champaign.
938 
939 !Design Notes:
940  pgs_in is a global variable which holds the file LUN and other info
941  needed for PGS_MET_GetPCAttr.
942 
943 !END********************************************************************
944 */
945 {
946  int ret;
947  ret = PGS_MET_GetPCAttr(pgs_in.fileID,
948  pgs_in.version,
949  pgs_in.hdfAttr,
950  field,
951  &value);
952  if (ret != PGS_S_SUCCESS)
953  {
954  char errorMessage[256];
955  sprintf(errorMessage, "Could not get metadata \"%s\" from %s.",
956  field, pgs_in.hdfAttr);
957  L1BErrorMsg("get_string_attr", MODIS_F_READ_ERROR, errorMessage,
958  "PGS_MET_GetPCAttr", pgs_in.fileID, NULL, True);
959  }
960 }
961 
962 void set_attr( char *field, void *value)
963 /*
964 !C*************************************************************************
965 !Description:
966  Helper function to Write_Gran_Metadata(). Writes data (non-string)
967  into the appropriate ECS metadata buffer identified by pgs_out_mdHandle.
968 
969 !Input Parameters:
970  char *field Name of field to write.
971  int value[] Pointer to value(s) to be written
972 
973 !Output Parameters:
974  none
975 
976 !Revision History:
977  (continue at top of the file)
978 
979  Revision 01.01 November 24, 1999
980  Error message revised.
981  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
982 
983  Revision 01.00 1998/4/8
984  Original Development
985  Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
986 
987 !Team-unique Header:
988  This software is developed by the MODIS Characterization Support
989  Team (MCST)for the National Aeronautics and Space Administration,
990  Goddard Space Flight Center, under contract NAS5-32373.
991 
992 !References and Credits:
993  HDF portions developed at the National Center for Supercomputing
994  Applications at the University of Illinois at Urbana-Champaign.
995 
996 !Design Notes:
997  pgs_out_mdHandle is a global variable identifying the buffer to write
998  the data into (either ECS core metadata or ECS archive metadata).
999 
1000 !END************************************************************************
1001 */
1002 {
1003  int ret;
1004  ret = PGS_MET_SetAttr(pgs_out_mdHandle, field, value);
1005  if (ret != PGS_S_SUCCESS)
1006  {
1007  char errorMessage[256];
1008  sprintf(errorMessage, "Toolkit error setting metadata \"%s\".", field);
1009  L1BErrorMsg("set_attr", MODIS_F_NOK, errorMessage,
1010  "PGS_MET_SetAttr", 0, NULL, True);
1011  }
1012 }
1013 
1014 void set_string_attr( char *field, char *value)
1015 /*
1016 !C**************************************************************************
1017 !Design Notes:
1018 
1019 !Description:
1020  Helper function to Write_Gran_Metadata(). Writes data (string)
1021  into the appropriate ECS metadata buffer identified by pgs_out_mdHandle.
1022 
1023 !Input Parameters:
1024  char *field Name of field to write.
1025  char *value Pointer to string value to be written
1026 
1027 !Output Parameters:
1028  none
1029 
1030 !Revision History:
1031  (continue at top of the file)
1032 
1033  Revision 01.01 November 24, 1999
1034  Error message revised.
1035  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
1036 
1037  Revision 01.00 1998/4/8
1038  Original Development
1039  Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
1040 
1041 !Team-unique Header:
1042  This software is developed by the MODIS Characterization Support
1043  Team (MCST)for the National Aeronautics and Space Administration,
1044  Goddard Space Flight Center, under contract NAS5-32373.
1045 
1046 !References and Credits:
1047  HDF portions developed at the National Center for Supercomputing
1048  Applications at the University of Illinois at Urbana-Champaign.
1049 
1050 !Design Notes:
1051  pgs_out_mdHandle is a global variable identifying the buffer to write
1052  the data into (either ECS core metadata or ECS archive metadata).
1053 
1054 !END********************************************************************
1055 */
1056 {
1057  int ret;
1058  ret = PGS_MET_SetAttr(pgs_out_mdHandle, field, &value);
1059  if (ret != PGS_S_SUCCESS)
1060  {
1061  char errorMessage[256];
1062  sprintf(errorMessage, "Toolkit error setting metadata \"%s\".", field);
1063  L1BErrorMsg("set_string_attr", MODIS_F_NOK, errorMessage,
1064  "PGS_MET_SetAttr", 0, NULL, True);
1065  }
1066 }
1067 
1068 
1069 void set_ptrstring_attr( char *field, char **value )
1070 /*
1071 !C*************************************************************************
1072 !Description:
1073  Helper function to Write_Gran_Metadata(). Writes data (array of strings)
1074  into the appropriate ECS metadata buffer identified by pgs_out_mdHandle.
1075 
1076 !Input Parameters:
1077  char *field Name of field to write.
1078  char **value Pointer to array of strings to be written
1079 
1080 !Output Parameters:
1081  none
1082 
1083 !Revision History:
1084  (continue at top of the file)
1085 
1086  Revision 01.01 November 24, 1999
1087  Error message revised.
1088  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
1089 
1090  Revision 01.00 1998/4/8
1091  Original Development
1092  Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
1093 
1094 !Team-unique Header:
1095  This software is developed by the MODIS Characterization Support
1096  Team (MCST)for the National Aeronautics and Space Administration,
1097  Goddard Space Flight Center, under contract NAS5-32373.
1098 
1099 !References and Credits:
1100  HDF portions developed at the National Center for Supercomputing
1101  Applications at the University of Illinois at Urbana-Champaign.
1102 
1103 !Design Notes:
1104  pgs_out_mdHandle is a global variable identifying the buffer to write
1105  the data into (either ECS core metadata or ECS archive metadata).
1106 
1107 !END********************************************************************
1108 */
1109 {
1110  int ret;
1111  ret = PGS_MET_SetAttr(pgs_out_mdHandle, field, value);
1112  if (ret != PGS_S_SUCCESS)
1113  {
1114  char errorMessage[256];
1115  sprintf(errorMessage, "Toolkit error setting metadata \"%s\".", field);
1116  L1BErrorMsg("set_ptrstring_attr", MODIS_F_NOK, errorMessage,
1117  "PGS_MET_SetAttr", 0, NULL, True);
1118  }
1119 }
1120 
1121 void copy_attr( char *field, void *value)
1122 /*
1123 !C****************************************************************
1124 !Description: Helper function to Write_Gran_Metadata()
1125 
1126 !Input Parameters:
1127  pgs_meta_t pgs_in
1128  char *field
1129  void *value
1130 
1131 !Output Parameters:
1132  none
1133 
1134 !Revision History:
1135  (continue at top of the file)
1136 
1137  Revision 01.00 1998/4/8
1138  Original Development
1139  Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
1140 
1141 !Team-unique Header:
1142 
1143 !References and Credits:
1144  This software is developed by the MODIS Characterization Support
1145  Team (MCST)for the National Aeronautics and Space Administration,
1146  Goddard Space Flight Center, under contract NAS5-32373.
1147 
1148  The time setting code was borrowed from Paul Fishers timea.c
1149 
1150  HDF portions developed at the National Center for Supercomputing
1151  Applications at the University of Illinois at Urbana-Champaign.
1152 
1153 !Design Notes:
1154 
1155 !END********************************************************************
1156 */
1157 {
1158  get_attr( field, value);
1159  set_attr( field, value);
1160 }
1161 
1162 void copy_string_attr( char *field, char *value)
1163 /*
1164 !C****************************************************************
1165 !Description: Helper function to Write_Gran_Metadata()
1166 
1167 !Input Parameters:
1168  pgs_meta_t pgs_in
1169  char *field
1170  int value[]
1171 
1172 !Output Parameters:
1173  none
1174 
1175 !Revision History:
1176  (continue at top of the file)
1177 
1178  Revision 01.00 1998/4/8
1179  Original Development
1180  Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
1181 
1182 !Team-unique Header:
1183 
1184 !References and Credits:
1185  This software is developed by the MODIS Characterization Support
1186  Team (MCST)for the National Aeronautics and Space Administration,
1187  Goddard Space Flight Center, under contract NAS5-32373.
1188 
1189  The time setting code was borrowed from Paul Fishers timea.c
1190 
1191  HDF portions developed at the National Center for Supercomputing
1192  Applications at the University of Illinois at Urbana-Champaign.
1193 
1194 !Design Notes:
1195 
1196 !END********************************************************************
1197 */
1198 {
1199  get_string_attr( field, value);
1200  set_string_attr( field, value);
1201 }
1202 
1203 PGSt_SMF_status Gran_Meta_Cal(L1A_granule_t *L1A_Gran,
1204  L1B_granule_t *L1B_Gran,
1205  Preprocess_Data_t *PP,
1206  QA_Data_t *QA,
1207  L1B_Scan_Metadata_t *L1B_Scan_Meta,
1208  L1B_Gran_Metadata_t *L1B_Gran_Meta)
1209 /*
1210 !C****************************************************************
1211 !Description: pass the values from L1A_Gran, L1B_Gran, PP, tables, QA, to
1212  L1B_Gran_Meta and calculate some granule metadata values.
1213 
1214 !Input Parameters:
1215  L1A_granule_t *L1A_Gran contains information about middle L1A granule
1216  L1B_granule_t *L1B_Gran contains L1B granule level information
1217  Preprocess_Data_t *PP contains focal plane set point
1218  QA_Data_t *QA contains QA data
1219  L1B_Gran_Metadata_t *L1B_Gran_Meta contains bit QA flag
1220 
1221 !Output Parameters:
1222  L1B_Gran_Metadata_t *L1B_Gran_Meta contains granule level metadata
1223 
1224 !Revision History:
1225  (continue at top of the file)
1226 
1227  Revision 01.06 June 23, 2003, Razor Issue #192
1228  Changed the telemetry mnemonic which determines whether the nadir aperture
1229  door (NAD) is open from "CR_DR_NAD_OPEN" to the equivalent "CR_DR_NAD_CLSD"
1230  mnemonic and altered the L1B code logic to correctly use the new value. It
1231  was discovered that at two different times in the history of the MODIS/Terra
1232  instrument the mnemonic "CR_DR_NAD_OPEN" did not correctly reflect the state
1233  of the NAD, whereas the mnemonic "CR_DR_NAD_CLSD" has been consistently
1234  reliable.
1235  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
1236 
1237  Revision 01.05 March 27, 2003, Razor Issue #173
1238  Enclosed the rows in the initializer of array-of-struct "temp" with braces
1239  for ANSI-C compliance.
1240  Liqin Tan, SAIC GSO (ltan@saicmodis.com)
1241 
1242  Revision 01.04 April 25, 2002 Razor Issue #183
1243  Changed initialization of structure "temp" to match definition.
1244  Gwyn Fireman, SAIC GSO (fireman@mcst.gsfc.nasa.gov)
1245 
1246  Revision 01.03 September 21, 2000
1247  Corrected calculation of % RSB in night mode, razor issue 137.
1248  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
1249 
1250  ... (many changes not logged) ...
1251 
1252  Revision 01.02 August 28, 1999
1253  Added checking if the data read from L1A are valid.
1254  Zhenying Gu (zgu@mcst.gsfc.nasa.gov) and Jim Rogers (rogers@mcst.gsfc.nasa.gov)
1255 
1256  Revision 01.01 Feb 22, 1999
1257  Change dthe calculation of num_day_scans to a simple assignment from
1258  L1A_Gran->num_day_scans.
1259  Jim Rogers (rogers@mcst.gsfc.nasa.gov)
1260 
1261  Revision 01.00 1998/4/8
1262  Original Development
1263  Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
1264 
1265 !Team-unique Header:
1266  This software is developed by the MODIS Characterization Support
1267  Team (MCST)for the National Aeronautics and Space Administration,
1268  Goddard Space Flight Center, under contract NAS5-32373.
1269 
1270 !References and Credits:
1271  HDF portions developed at the National Center for Supercomputing
1272  Applications at the University of Illinois at Urbana-Champaign.
1273 
1274 !Design Notes:
1275 
1276 !END********************************************************************
1277 */
1278 {
1279  PGSt_SMF_status returnStatus;
1280  char *location = "Gran_Meta_Cal";
1281  int32 B, B_38, D, S;
1282  int32 missing_pixels, outofbound_pixels,
1283  interpolated_pixels, total_pixels;
1284 
1285  /* The following three variables are used to calculate percentages
1286  * of some low quality data.
1287  */
1288 
1289  int32 num_pixels_per_250m_det;
1290  int32 num_pixels_per_500m_det;
1291  int32 num_pixels_per_1km_det;
1292 
1293  enum {
1294  NAD_Door,
1295  SVD_Door,
1296  SDD_Door,
1297  SDD_Screen,
1298  NUM_Config
1299  }Door_Screen_Config;
1300 
1301  struct {
1302  char *vname; /*vdata_name*/
1303  char *fname; /*field_name*/
1304  uint16 buffer;
1305  } temp[NUM_Config] = {
1306  {"Telemetry Major Cycle 3A of 7", "CR_DR_NAD_CLSD", 1},
1307  {"Telemetry Major Cycle 3A of 7", "CR_DR_SVD_OPEN", 0},
1308  {"Telemetry Major Cycle 3A of 7", "CR_DR_SDD_OPEN", 0},
1309  {"Telemetry Major Cycle 3A of 7", "CR_DR_SDS_OPEN", 0}
1310  };
1311  int32 day_bands_at_night;
1312  uint32 day_bands_at_night_mask;
1313 
1314  /* Calculate the percentages of different kinds of low quality data
1315  * for each detector.
1316  */
1317 
1318 
1319  num_pixels_per_250m_det = L1A_Gran->num_scans * EV_250m_FRAMES;
1320  num_pixels_per_500m_det = L1A_Gran->num_scans * EV_500m_FRAMES;
1321  num_pixels_per_1km_det = L1A_Gran->num_scans * EV_1km_FRAMES;
1322 
1323  L1B_Gran_Meta->missAllScanDataPercent =
1324  100*(float32)QA->QA_common.num_missing_scans/L1A_Gran->num_scans;
1325 
1326  for (D = 0; D < NUM_250M_BANDS*DETECTORS_PER_250M_BAND; D++)
1327  {
1328  L1B_Gran_Meta->missInScanDataPercent[D] =
1329  100*(float32)QA->QA_common.num_missing_data_in_scans[D]/
1330  num_pixels_per_250m_det;
1331  L1B_Gran_Meta->nightRSBPercent[D] = 100. * (float32)
1333  L1A_Gran->num_scans;
1334  L1B_Gran_Meta->deadDetectorDataPercent[D] =
1335  100*(float32)QA->QA_common.num_dead_detector_EV_data[D]/
1336  num_pixels_per_250m_det;
1337  L1B_Gran_Meta->deadSubframeDataPercent[D] =
1338  100*(float32)QA->QA_common.num_dead_subframe_EV_data[D]/
1339  num_pixels_per_250m_det;
1340  L1B_Gran_Meta->sectorRotateDataPercent[D] =
1341  100*(float32)QA->QA_common.num_sector_rotation_EV_data[D]/
1342  num_pixels_per_250m_det;
1343  L1B_Gran_Meta->saturatedDataPercent[D] =
1344  100*(float32)QA->QA_common.num_saturated_EV_data[D]/
1345  num_pixels_per_250m_det;
1346  L1B_Gran_Meta->noBGDataPercent[D] =
1347  100*(float32)QA->QA_common.num_no_bg_DN_EV_data[D]/
1348  num_pixels_per_250m_det;
1349  L1B_Gran_Meta->badDNStarStarRSBDataPercent[D] =
1350  100*(float32)QA->QA_common.num_bad_dn_star_star_RSB_EV_data[D]/
1351  num_pixels_per_250m_det;
1352  L1B_Gran_Meta->exceedMaxForScalingPercent[D] =
1353  100*(float32)QA->QA_common.num_exceed_max_for_scaling[D]/
1354  num_pixels_per_250m_det;
1355  L1B_Gran_Meta->NADClosedDataPercent[D] =
1356  100*(float32)QA->QA_common.num_nadir_door_closed_EV_data[D]/
1357  num_pixels_per_250m_det;
1358  L1B_Gran_Meta->moonInSVPTEBDataPercent[D] = 0;
1359  }
1360 
1363  {
1364  L1B_Gran_Meta->missInScanDataPercent[D] =
1365  100*(float32)QA->QA_common.num_missing_data_in_scans[D]/
1366  num_pixels_per_500m_det;
1367  L1B_Gran_Meta->nightRSBPercent[D] = 100. * (float32)
1369  L1A_Gran->num_scans;
1370  L1B_Gran_Meta->deadDetectorDataPercent[D] =
1371  100*(float32)QA->QA_common.num_dead_detector_EV_data[D]/
1372  num_pixels_per_500m_det;
1373  L1B_Gran_Meta->deadSubframeDataPercent[D] =
1374  100*(float32)QA->QA_common.num_dead_subframe_EV_data[D]/
1375  num_pixels_per_500m_det;
1376  L1B_Gran_Meta->sectorRotateDataPercent[D] =
1377  100*(float32)QA->QA_common.num_sector_rotation_EV_data[D]/
1378  num_pixels_per_500m_det;
1379  L1B_Gran_Meta->saturatedDataPercent[D] =
1380  100*(float32)QA->QA_common.num_saturated_EV_data[D]/
1381  num_pixels_per_500m_det;
1382  L1B_Gran_Meta->noBGDataPercent[D] =
1383  100*(float32)QA->QA_common.num_no_bg_DN_EV_data[D]/
1384  num_pixels_per_500m_det;
1385  L1B_Gran_Meta->badDNStarStarRSBDataPercent[D] =
1386  100*(float32)QA->QA_common.num_bad_dn_star_star_RSB_EV_data[D]/
1387  num_pixels_per_500m_det;
1388  L1B_Gran_Meta->exceedMaxForScalingPercent[D] =
1389  100*(float32)QA->QA_common.num_exceed_max_for_scaling[D]/
1390  num_pixels_per_500m_det;
1391  L1B_Gran_Meta->NADClosedDataPercent[D] =
1392  100*(float32)QA->QA_common.num_nadir_door_closed_EV_data[D]/
1393  num_pixels_per_500m_det;
1394  L1B_Gran_Meta->moonInSVPTEBDataPercent[D] = 0;
1395  }
1396 
1397  for (; D < NUM_DETECTORS; D++)
1398  {
1399  L1B_Gran_Meta->missInScanDataPercent[D] =
1400  100*(float32)QA->QA_common.num_missing_data_in_scans[D]/
1401  num_pixels_per_1km_det;
1402 
1403  if (D < NUM_REFLECTIVE_DETECTORS - 10 ||
1404  (D >= (NUM_REFLECTIVE_DETECTORS - 10)
1405  + BAND26 * 10 && D < NUM_REFLECTIVE_DETECTORS + BAND26 * 10))
1406  L1B_Gran_Meta->nightRSBPercent[D] = 100. * (float32)
1408  L1A_Gran->num_scans;
1409  else
1410  L1B_Gran_Meta->nightRSBPercent[D] = 0;
1411 
1412 /************************* Begin Band 26 Section **************************/
1413 #ifdef WRITE_BAND_26_SDS
1414  if (D >= (NUM_REFLECTIVE_DETECTORS - 10) + BAND26 * 10 &&
1415  D < NUM_REFLECTIVE_DETECTORS + BAND26 * 10)
1416  L1B_Gran_Meta->nightRSBPercent[D] = 0;
1417 #endif /* WRITE_BAND_26_SDS */
1418 /************************** End Band 26 Section ***************************/
1419 
1420  L1B_Gran_Meta->deadDetectorDataPercent[D] =
1421  100*(float32)QA->QA_common.num_dead_detector_EV_data[D]/
1422  num_pixels_per_1km_det;
1423  L1B_Gran_Meta->sectorRotateDataPercent[D] =
1424  100*(float32)QA->QA_common.num_sector_rotation_EV_data[D]/
1425  num_pixels_per_1km_det;
1426  L1B_Gran_Meta->saturatedDataPercent[D] =
1427  100*(float32)QA->QA_common.num_saturated_EV_data[D]/
1428  num_pixels_per_1km_det;
1429  L1B_Gran_Meta->noBGDataPercent[D] =
1430  100*(float32)QA->QA_common.num_no_bg_DN_EV_data[D]/
1431  num_pixels_per_1km_det;
1432  L1B_Gran_Meta->badDNStarStarRSBDataPercent[D] =
1433  100*(float32)QA->QA_common.num_bad_dn_star_star_RSB_EV_data[D]/
1434  num_pixels_per_1km_det;
1435  L1B_Gran_Meta->exceedMaxForScalingPercent[D] =
1436  100*(float32)QA->QA_common.num_exceed_max_for_scaling[D]/
1437  num_pixels_per_1km_det;
1438  L1B_Gran_Meta->NADClosedDataPercent[D] =
1439  100*(float32)QA->QA_common.num_nadir_door_closed_EV_data[D]/
1440  num_pixels_per_1km_det;
1441  L1B_Gran_Meta->moonInSVPTEBDataPercent[D] =
1442  100*(float32)QA->QA_common.num_moon_in_SVP_TEB_EV_data[D]/
1443  num_pixels_per_1km_det;
1444  }
1445 
1446  for (D = 0; D < NUM_DETECTORS; D++){
1447  L1B_Gran_Meta->uncalibratedDataPercent[D] =
1448  L1B_Gran_Meta->missAllScanDataPercent +
1449  L1B_Gran_Meta->nightRSBPercent[D] +
1450  L1B_Gran_Meta->missInScanDataPercent[D] +
1451  L1B_Gran_Meta->deadDetectorDataPercent[D] +
1452  L1B_Gran_Meta->sectorRotateDataPercent[D] +
1453  L1B_Gran_Meta->saturatedDataPercent[D] +
1454  L1B_Gran_Meta->noBGDataPercent[D] +
1455  L1B_Gran_Meta->badDNStarStarRSBDataPercent[D] +
1456  L1B_Gran_Meta->exceedMaxForScalingPercent[D] +
1457  L1B_Gran_Meta->NADClosedDataPercent[D] +
1458  L1B_Gran_Meta->moonInSVPTEBDataPercent[D];
1460  L1B_Gran_Meta->uncalibratedDataPercent[D] +=
1461  L1B_Gran_Meta->deadSubframeDataPercent[D] ;
1462  }
1463 
1464  /* Calculate last value of bit QA flag and if there is any change for each bit */
1465 
1468  L1B_Scan_Meta->Bit_QA_Flags[L1A_Gran->num_scans - 1];
1469  for (S = 0; S < L1A_Gran->num_scans - 1; S++)
1470  {
1472  (L1B_Scan_Meta->Bit_QA_Flags[S+1]^
1473  L1B_Scan_Meta->Bit_QA_Flags[S]);
1474  }
1475 
1476  /******** Special case for Day bands at Night bit (bit 11) **********
1477  * For bit 11 in the bit_QA_flags_change and bit_QA_flags_last_value,
1478  * the logic is different than that defined above. If there are more
1479  * than 15 scans in the Bit QA Flags with bit 11 set to 1, then set
1480  * bit 11 to 1 in BOTH attributes. If there are 15 or fewer scans in
1481  * the Bit QA Flags with bit 11 set to 1, then set bit 11 in BOTH
1482  * attributes to zero. This is done as a stop-gap measure to prevent
1483  * the granule-level flag in the MCST QA databases from being in error.
1484  */
1485 
1486  day_bands_at_night = 0;
1487  day_bands_at_night_mask = 0x00000800;
1488  for (S = 0; S < L1A_Gran->num_scans - 1; S++)
1489  {
1490  if (L1B_Scan_Meta->Bit_QA_Flags[S] & day_bands_at_night_mask)
1491  day_bands_at_night++;
1492  }
1493  if (day_bands_at_night > 15)
1494  {
1495  QA->QA_common.bit_QA_flags_change |= day_bands_at_night_mask;
1496  QA->QA_common.bit_QA_flags_last_value |= day_bands_at_night_mask;
1497  }
1498  else
1499  {
1500  QA->QA_common.bit_QA_flags_change &= ~day_bands_at_night_mask;
1501  QA->QA_common.bit_QA_flags_last_value &= ~day_bands_at_night_mask;
1502  }
1503 
1504  /*******************************************************************/
1505 
1506  L1B_Gran_Meta->L1A_Gran_sd_id = L1A_Gran->sd_id;
1507  L1B_Gran_Meta->L1B_Gran_sd_id[0] = L1B_Gran->sd_id[0];
1508  L1B_Gran_Meta->L1B_Gran_sd_id[1] = L1B_Gran->sd_id[1];
1509  L1B_Gran_Meta->L1B_Gran_sd_id[2] = L1B_Gran->sd_id[2];
1510  L1B_Gran_Meta->incomplete_scans = L1A_Gran->incomplete_scans;
1511  L1B_Gran_Meta->max_ev_frames = L1A_Gran->max_ev_frames;
1512  L1B_Gran_Meta->num_scans = L1A_Gran->num_scans;
1513  L1B_Gran_Meta->num_day_scans = L1A_Gran->num_day_scans;
1514  L1B_Gran_Meta->num_night_scans = L1A_Gran->num_night_scans;
1515  L1B_Gran_Meta->Extract_Pixel_Offset = L1A_Gran->Extract_Pixel_Offset;
1516  L1B_Gran_Meta->Extract_Pixel_Count = L1A_Gran->Extract_Pixel_Count;
1517  L1B_Gran_Meta->Extract_Line_Offset = L1A_Gran->Extract_Line_Offset;
1518  L1B_Gran_Meta->Extract_Line_Count = L1A_Gran->Extract_Line_Count;
1519 
1520  for (B = 0; B < NUM_BANDS; B++)
1521  {
1522  L1B_Gran_Meta->total_pixels[B] = L1B_Gran->total_pixels[B];
1523  L1B_Gran_Meta->valid_pixels[B] = L1B_Gran->valid_pixels[B];
1524  L1B_Gran_Meta->saturated_pixels[B] = L1B_Gran->saturated_pixels[B];
1525  L1B_Gran_Meta->missing_pixels[B] = L1B_Gran->missing_pixels[B];
1526  L1B_Gran_Meta->validEVPercent[B] =
1527  100 *(float32)L1B_Gran_Meta->valid_pixels[B] /
1528  L1B_Gran_Meta->total_pixels[B];
1529  L1B_Gran_Meta->satEVPercent[B] =
1530  100 *(float32)L1B_Gran_Meta->saturated_pixels[B] /
1531  L1B_Gran_Meta->total_pixels[B];
1532  L1B_Gran_Meta->missEVPercent[B] =
1533  100 *(float32)L1B_Gran_Meta->missing_pixels[B] /
1534  L1B_Gran_Meta->total_pixels[B];
1535 
1536  /* The bad data flag is not set in Reflective_Cal and Emissive_Cal for
1537  * dead detectors, because the EV data for that pixel may be interpolated.
1538  * Check the number of interpolated pixels and dead detector pixels for
1539  * each band. If they are not equal, set this flag.
1540  * should also consider dead subframe
1541  */
1542 
1543  if (L1B_Gran->bad_data_flag[B] == 1 ||
1544  L1B_Gran->interpolated_pixels[B] !=
1545  (L1B_Gran->dead_detector_pixels[B]+L1B_Gran->dead_subframe_pixels[B]))
1546  L1B_Gran->bad_data_flag[B] = 1;
1547  }
1548 
1549  missing_pixels = 0;
1550  outofbound_pixels = 0;
1551  interpolated_pixels = 0;
1552  total_pixels = 0;
1553 
1554  for (B = 0; B < NUM_250M_BANDS; B++)
1555  {
1556  missing_pixels += L1B_Gran->missing_pixels[B];
1557  outofbound_pixels += L1B_Gran->saturated_pixels[B]
1558  + L1B_Gran->negative_value_below_noise_pixels[B];
1559  interpolated_pixels += L1B_Gran->interpolated_pixels[B];
1560  total_pixels += L1B_Gran->total_pixels[B];
1561  }
1562 
1563  L1B_Gran_Meta->qapercent_missing_250m =
1564  (int32)(100 * (float32)missing_pixels/total_pixels + 0.5);
1565  if (L1B_Gran_Meta->qapercent_missing_250m < 0 ||
1566  L1B_Gran_Meta->qapercent_missing_250m > 100) {
1567  returnStatus = MODIS_F_OUT_OF_RANGE;
1568  L1BErrorMsg(location, returnStatus,
1569  "QAPERCENTMISSINGDATA for 250m bands is out of range [0, 100]",
1570  NULL, 0, NULL, True);
1571  }
1572 
1573  L1B_Gran_Meta->qapercent_outofbound_250m =
1574  (int32)(100 * (float32)outofbound_pixels/total_pixels + 0.5);
1575  if (L1B_Gran_Meta->qapercent_outofbound_250m < 0 ||
1576  L1B_Gran_Meta->qapercent_outofbound_250m > 100) {
1577  returnStatus = MODIS_F_OUT_OF_RANGE;
1578  L1BErrorMsg(location, returnStatus,
1579  "QAPERCENTOUTOFBOUNDSDATA for 250m bands is out of range [0, 100]",
1580  NULL, 0, NULL, True);
1581  }
1582 
1583  L1B_Gran_Meta->qapercent_interpolated_250m =
1584  (int32)(100 * (float32) interpolated_pixels/total_pixels + 0.5);
1585  if (L1B_Gran_Meta->qapercent_interpolated_250m < 0 ||
1586  L1B_Gran_Meta->qapercent_interpolated_250m > 100) {
1587  returnStatus = MODIS_F_OUT_OF_RANGE;
1588  L1BErrorMsg(location, returnStatus,
1589  "QAPERCENTINTERPOLATEDDATA for 250m bands is out of range [0, 100]",
1590  NULL, 0, NULL, True);
1591  }
1592 
1593  missing_pixels = 0;
1594  outofbound_pixels = 0;
1595  interpolated_pixels = 0;
1596  total_pixels = 0;
1597 
1598  for (B = NUM_250M_BANDS; B < NUM_250M_BANDS + NUM_500M_BANDS; B++)
1599  {
1600  missing_pixels += L1B_Gran->missing_pixels[B];
1601  outofbound_pixels += L1B_Gran->saturated_pixels[B]
1602  + L1B_Gran->negative_value_below_noise_pixels[B];
1603  interpolated_pixels += L1B_Gran->interpolated_pixels[B];
1604  total_pixels += L1B_Gran->total_pixels[B];
1605  }
1606 
1607  L1B_Gran_Meta->qapercent_missing_500m =
1608  (int32)(100 * (float32)missing_pixels/total_pixels + 0.5);
1609  if (L1B_Gran_Meta->qapercent_missing_500m < 0 ||
1610  L1B_Gran_Meta->qapercent_missing_500m > 100) {
1611  returnStatus = MODIS_F_OUT_OF_RANGE;
1612  L1BErrorMsg(location, returnStatus,
1613  "QAPERCENTMISSINGDATA for 500m bands is out of range [0, 100]",
1614  NULL, 0, NULL, True);
1615  }
1616 
1617  L1B_Gran_Meta->qapercent_outofbound_500m =
1618  (int32)(100 * (float32)outofbound_pixels/total_pixels + 0.5);
1619  if (L1B_Gran_Meta->qapercent_outofbound_500m < 0 ||
1620  L1B_Gran_Meta->qapercent_outofbound_500m > 100) {
1621  returnStatus = MODIS_F_OUT_OF_RANGE;
1622  L1BErrorMsg(location, returnStatus,
1623  "QAPERCENTOUTOFBOUNDSDATA for 500m bands is out of range [0, 100]",
1624  NULL, 0, NULL, True);
1625  }
1626 
1627  L1B_Gran_Meta->qapercent_interpolated_500m =
1628  (int32)(100 * (float32) interpolated_pixels/total_pixels + 0.5);
1629  if (L1B_Gran_Meta->qapercent_interpolated_500m < 0 ||
1630  L1B_Gran_Meta->qapercent_interpolated_500m > 100) {
1631  returnStatus = MODIS_F_OUT_OF_RANGE;
1632  L1BErrorMsg(location, returnStatus,
1633  "QAPERCENTINTERPOLATEDDATA for 500m bands is out of range [0, 100]",
1634  NULL, 0, NULL, True);
1635  }
1636 
1637  missing_pixels = 0;
1638  outofbound_pixels = 0;
1639  interpolated_pixels = 0;
1640  total_pixels = 0;
1641  for(; B < NUM_REFLECTIVE_BANDS - 1; B++) /* band 26 */
1642  {
1643  missing_pixels += L1B_Gran->missing_pixels[B];
1644  outofbound_pixels += L1B_Gran->saturated_pixels[B]
1645  + L1B_Gran->negative_value_below_noise_pixels[B];
1646  interpolated_pixels += L1B_Gran->interpolated_pixels[B];
1647  total_pixels += L1B_Gran->total_pixels[B];
1648  }
1649 
1650  missing_pixels += L1B_Gran->missing_pixels[MODIS_BAND26_INDEX];
1651  outofbound_pixels += L1B_Gran->saturated_pixels[MODIS_BAND26_INDEX]
1653  interpolated_pixels += L1B_Gran->interpolated_pixels[MODIS_BAND26_INDEX];
1654  total_pixels += L1B_Gran->total_pixels[MODIS_BAND26_INDEX];
1655 
1656  L1B_Gran_Meta->refl_1km_qapercent_missing =
1657  (int32)(100 * (float32)missing_pixels/total_pixels + 0.5);
1658  if (L1B_Gran_Meta->refl_1km_qapercent_missing < 0 ||
1659  L1B_Gran_Meta->refl_1km_qapercent_missing > 100) {
1660  returnStatus = MODIS_F_OUT_OF_RANGE;
1661  L1BErrorMsg(location, returnStatus,
1662  "QAPERCENTMISSINGDATA for 1km reflective bands is "
1663  "out of range [0, 100]",
1664  NULL, 0, NULL, True);
1665  }
1666 
1667  L1B_Gran_Meta->refl_1km_qapercent_outofbound =
1668  (int32)(100 * (float32)outofbound_pixels/total_pixels + 0.5);
1669  if (L1B_Gran_Meta->refl_1km_qapercent_outofbound < 0 ||
1670  L1B_Gran_Meta->refl_1km_qapercent_outofbound > 100) {
1671  returnStatus = MODIS_F_OUT_OF_RANGE;
1672  L1BErrorMsg(location, returnStatus,
1673  "QAPERCENTOUTOFBOUNDSDATA for 1km reflective bands is "
1674  "out of range [0, 100]",
1675  NULL, 0, NULL, True);
1676  }
1677 
1678  L1B_Gran_Meta->qapercent_interpolated_refl_1km =
1679  (int32)(100 * (float32) interpolated_pixels/total_pixels + 0.5);
1680  if (L1B_Gran_Meta->qapercent_interpolated_refl_1km < 0 ||
1681  L1B_Gran_Meta->qapercent_interpolated_refl_1km > 100) {
1682  returnStatus = MODIS_F_OUT_OF_RANGE;
1683  L1BErrorMsg(location, returnStatus,
1684  "QAPERCENTINTERPOLATEDDATA for 1km reflective bands is"
1685  " out of range [0, 100]",
1686  NULL, 0, NULL, True);
1687  }
1688 
1689 
1690  missing_pixels = 0;
1691  outofbound_pixels = 0;
1692  interpolated_pixels = 0;
1693  total_pixels = 0;
1694 
1695  for(; B < NUM_BANDS; B++)
1696  {
1697  if(B == MODIS_BAND26_INDEX)
1698  continue;
1699 
1700  missing_pixels += L1B_Gran->missing_pixels[B];
1701  outofbound_pixels += L1B_Gran->saturated_pixels[B]
1702  + L1B_Gran->negative_value_below_noise_pixels[B];
1703  interpolated_pixels += L1B_Gran->interpolated_pixels[B];
1704  total_pixels += L1B_Gran->total_pixels[B];
1705  }
1706 
1707  L1B_Gran_Meta->emiss_qapercent_missing =
1708  (int32)(100 * (float32)missing_pixels/total_pixels + 0.5);
1709  if (L1B_Gran_Meta->emiss_qapercent_missing < 0 ||
1710  L1B_Gran_Meta->emiss_qapercent_missing > 100) {
1711  returnStatus = MODIS_F_OUT_OF_RANGE;
1712  L1BErrorMsg(location, returnStatus,
1713  "QAPERCENTMISSINGDATA for emissive bands is "
1714  "out of range [0, 100]",
1715  NULL, 0, NULL, True);
1716  }
1717 
1718  L1B_Gran_Meta->emiss_qapercent_outofbound =
1719  (int32)(100 * (float32)outofbound_pixels/total_pixels + 0.5);
1720  if (L1B_Gran_Meta->emiss_qapercent_outofbound < 0 ||
1721  L1B_Gran_Meta->emiss_qapercent_outofbound > 100) {
1722  returnStatus = MODIS_F_OUT_OF_RANGE;
1723  L1BErrorMsg(location, returnStatus,
1724  "QAPERCENTOUTOFBOUNDSDATA for emissive bands is "
1725  "out of range [0, 100]",
1726  NULL, 0, NULL, True);
1727  }
1728 
1729  L1B_Gran_Meta->qapercent_interpolated_emiss =
1730  (int32)(100 * (float32)interpolated_pixels/total_pixels + 0.5);
1731  if (L1B_Gran_Meta->qapercent_interpolated_emiss < 0 ||
1732  L1B_Gran_Meta->qapercent_interpolated_emiss > 100) {
1733  returnStatus = MODIS_F_OUT_OF_RANGE;
1734  L1BErrorMsg(location, returnStatus,
1735  "QAPERCENTINTERPOLATEDDATA for emissive bands is"
1736  " out of range [0, 100]",
1737  NULL, 0, NULL, True);
1738  }
1739 
1740  L1B_Gran_Meta->FPSetPointState = PP->PP_Emiss.fp_set_point_state[0];
1741  for (S = 1; S < L1A_Gran->num_scans; S++)
1742  if(L1B_Gran_Meta->FPSetPointState != PP->PP_Emiss.fp_set_point_state[S])
1743  L1B_Gran_Meta->FPSetPointState = 0;
1744 
1745  returnStatus = MODIS_S_OK;
1746 
1747  /* New QA */
1748 
1749  L1B_Gran_Meta->Door_Screen_Configuration = 0;
1750  for (Door_Screen_Config = NAD_Door;
1751  Door_Screen_Config < NUM_Config; Door_Screen_Config++)
1752  {
1753  returnStatus = read_vdata (L1A_Gran->v_id,
1754  0,
1755  1,
1756  temp[Door_Screen_Config].vname,
1757  temp[Door_Screen_Config].fname,
1758  (VOIDP)&temp[Door_Screen_Config].buffer);
1759  if (returnStatus != MODIS_S_OK)
1760  {
1761  L1BErrorMsg(location, returnStatus, NULL,
1762  "read_vdata", FIRST_L1A_GRANULE, NULL, True);
1763  return returnStatus;
1764  }
1765 
1766  if (temp[Door_Screen_Config].buffer > 1)
1767  {
1768  char msgbuf[256];
1769  sprintf(msgbuf, "Value[0] of \"%s\" is out of the range [0,1].",
1770  temp[Door_Screen_Config].fname);
1771  returnStatus = MODIS_F_OUT_OF_RANGE;
1772  L1BErrorMsg(location, returnStatus, msgbuf, NULL, FIRST_L1A_GRANULE,
1774  return returnStatus;
1775  }
1776  }
1777 
1778  if (temp[NAD_Door].buffer == 0)
1779  L1B_Gran_Meta->Door_Screen_Configuration |= 0x80;
1780  if (temp[SVD_Door].buffer == 1)
1781  L1B_Gran_Meta->Door_Screen_Configuration |= 0x40;
1782  if (temp[SDD_Door].buffer == 1)
1783  L1B_Gran_Meta->Door_Screen_Configuration |= 0x20;
1784  if (temp[SDD_Screen].buffer == 1)
1785  L1B_Gran_Meta->Door_Screen_Configuration |= 0x10;
1786 
1787  for (B = 0; B < NUM_REFLECTIVE_BANDS - 1; B++)
1788  {
1789  if(L1B_Gran->bad_data_flag[B] == 1)
1790  L1B_Gran_Meta->Reflective_Band_Identification[B] = 1;
1791  else
1792  L1B_Gran_Meta->Reflective_Band_Identification[B] = 0;
1793  }
1794  /* for band 26 */
1795  if(L1B_Gran->bad_data_flag[MODIS_BAND26_INDEX] == 1)
1796  L1B_Gran_Meta->Reflective_Band_Identification[B] = 1;
1797  else
1798  L1B_Gran_Meta->Reflective_Band_Identification[B] = 0;
1799 
1800  B_38 = NUM_REFLECTIVE_BANDS - 1;
1801 
1802  for (B = 0; B < NUM_EMISSIVE_BANDS; B++, B_38++)
1803  {
1804  if(B_38 == MODIS_BAND26_INDEX)
1805  B_38++;
1806  if(L1B_Gran->bad_data_flag[B_38] == 1)
1807  L1B_Gran_Meta->Emissive_Band_Identification[B] = 1;
1808  else
1809  L1B_Gran_Meta->Emissive_Band_Identification[B] = 0;
1810  }
1811 
1812  L1B_Gran_Meta->All_L1B_Error_Flag_Off = 0;
1813 
1814  for (B = 0; B < NUM_EMISSIVE_BANDS; B++)
1815  for(D = 0; D < DETECTORS_PER_1KM_BAND; D++)
1816  {
1817  L1B_Gran_Meta->Thermal_Detector_Noise[B][D] =
1818  QA->QA_emiss.NEdL[B * 10 + D] ;
1819  L1B_Gran_Meta->Thermal_Detector_Relative_Response_Change[B][D] =
1820  QA->QA_emiss.change_b1[B * 10 + D] ;
1821  }
1822 
1823  /*
1824  * Determine the Electronics Configuration Status and the Electronics
1825  * Configuration Change.
1826  */
1827 
1828  returnStatus = Get_Elec_Config_Status(&QA->QA_common,
1829  L1A_Gran->v_id,
1830  L1A_Gran->num_scans,
1831  L1B_Gran_Meta->Elec_config_status,
1832  L1B_Gran_Meta->Elec_config_change);
1833  if (returnStatus != MODIS_S_OK)
1834  {
1835  L1BErrorMsg(location, returnStatus, NULL,
1836  "Get_Elec_Config_Status", 0, NULL, True);
1837  return returnStatus;
1838  }
1839 
1840  /* Store the Earth-Sun Distance into L1B_Gran_Meta */
1841 
1842  L1B_Gran_Meta->Earth_Sun_Dist = L1B_Gran->Earth_Sun_Dist;
1843 
1844  return(returnStatus);
1845 }
1846 
1847 
1848 PGSt_SMF_status Write_Global_Metadata
1849  (L1B_Gran_Metadata_t *L1B_Gran_Meta,
1850  QA_Data_t *QA,
1852  int32 OBC_sd_id,
1853  boolean skip_night_hi_res)
1854 /*
1855 !C****************************************************************
1856 !Description: This function writes the MODIS Level 1B Product Granule
1857  Metadata stored as global attributes, which are described
1858  in 1.3) of the EV file specifications, and MODIS Level 1B
1859  QA Granule Metadata, which are described in 1.4) of
1860  of the EV file specifications into EV files and OBC file.
1861 
1862 !Input Parameters:
1863  L1B_Gran_Metadata_t *L1B_Gran_Meta contains granule metadata
1864  QA_Data_t *QA contains QA granule metadata
1865  lookup_tables_t *tables contains granule metadata
1866  implemented directly from LUTs
1867  int32 OBC_sd_id OBC file id for sds interface
1868  boolean skip_night_hi_res True if and only if all scans are
1869  NIGHT mode and runtime parameter
1870  Write_Night_Mode_HiRes_Data is False.
1871 
1872 !Output Parameters:
1873  none
1874 
1875 !Revision History:
1876  (continue at top of the file)
1877 
1878  Revision 01.03 January 17, 2002 Razor Issue #172
1879  Improve portability of code to 64-bit mode.
1880  Cast strlen returns to int32 in calls to SDSetattr.
1881  Alice Isaacman, SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
1882 
1883  Revision 01.02 November 19, 2000 (Razor Issue #169)
1884  Added input parameter skip_night_hi_res and changed logic so that
1885  250m and 500m data are not written when granule has no day mode
1886  scans and runtime parameter Write_Night_Mode_HiRes_Data is False.
1887  Alice Isaacman SAIC GSO (Alice.R.Isaacman.1@gsfc.nasa.gov)
1888 
1889  Revision 01.01 1999/8/20
1890  Moved Manager's quality indices to common QA
1891  Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
1892 
1893  Revision 01.00 1998/10/30
1894  Original Development(This function is part of the original function
1895  Write_Gran_Metadata())
1896  Zhenying Gu (zgu@gscmail.gsfc.nasa.gov)
1897 
1898 !Team-unique Header:
1899  This software is developed by the MODIS Characterization Support
1900  Team (MCST)for the National Aeronautics and Space Administration,
1901  Goddard Space Flight Center, under contract NAS5-32373.
1902 
1903 !References and Credits:
1904  HDF portions developed at the National Center for Supercomputing
1905  Applications at the University of Illinois at Urbana-Champaign.
1906 
1907 !Design Notes:
1908 
1909 !END********************************************************************
1910 */
1911 {
1912  PGSt_SMF_status returnStatus;
1913  char *location = "Write_Global_Metadata";
1914  int32 out_sd_id[4] = {0, 0, 0, 0};
1915  int32 R;
1916  int32 hdf_return = FAIL;
1917  int32 lun;
1918  /*
1919  * Starting output file index; changes to INDEX_L1B_EV_1000M_FILE
1920  * when HiRes night mode is not written.
1921  */
1922  int16 start_output_file_index = INDEX_L1B_EV_250M_FILE;
1923 
1924  out_sd_id[0] = L1B_Gran_Meta->L1B_Gran_sd_id[0];
1925  out_sd_id[1] = L1B_Gran_Meta->L1B_Gran_sd_id[1];
1926  out_sd_id[2] = L1B_Gran_Meta->L1B_Gran_sd_id[2];
1927  out_sd_id[3] = OBC_sd_id;
1928 
1929  /*---------------------------------------
1930  Write Native HDF metadata
1931  ---------------------------------------*/
1932  /*
1933  * If this is a NIGHT mode granule and the runtime parameter
1934  * Write_Night_Mode_HiRes_Data is False, do not write the 250m and 500m
1935  * resolution files, and so start with output file number 2, not 0.
1936  */
1937 
1938  if (skip_night_hi_res == True)
1939  start_output_file_index = INDEX_L1B_EV_1000M_FILE;
1940  else
1941  start_output_file_index = INDEX_L1B_EV_250M_FILE;
1942 
1943  for ( R = start_output_file_index ; R < NUM_OUTPUT_FILES ; R++)
1944  {
1945  /* Get logical number for the file for L1BErrorMsg */
1946 
1947  switch (R)
1948  {
1950  break;
1952  break;
1954  break;
1955  case INDEX_L1B_OBC_FILE: lun = L1B_OBC_FILE;
1956  break;
1957  default: lun = 0;
1958  }
1959 
1960  hdf_return = SDsetattr (out_sd_id[R],
1961  "Number of Scans",
1962  DFNT_INT32, 1,
1963  (VOIDP)&L1B_Gran_Meta->num_scans);
1964  if (hdf_return == FAIL)
1965  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
1966  "Could not write Number of Scans.",
1967  "SDsetattr", lun, NULL, True);
1968 
1969  hdf_return = SDsetattr (out_sd_id[R],
1970  "Number of Day mode scans",
1971  DFNT_INT32, 1,
1972  (VOIDP)&L1B_Gran_Meta->num_day_scans);
1973  if (hdf_return == FAIL)
1974  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
1975  "Could not write Number of Day mode scans.",
1976  "SDsetattr", lun, NULL, True);
1977 
1978  hdf_return = SDsetattr (out_sd_id[R],
1979  "Number of Night mode scans",
1980  DFNT_INT32, 1,
1981  (VOIDP)&L1B_Gran_Meta->num_night_scans);
1982  if (hdf_return == FAIL)
1983  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
1984  "Could not write Number of Night mode scans.",
1985  "SDsetattr", lun, NULL, True);
1986 
1987  hdf_return = SDsetattr (out_sd_id[R],
1988  "Incomplete Scans",
1989  DFNT_INT32, 1,
1990  (VOIDP)&L1B_Gran_Meta->incomplete_scans);
1991  if (hdf_return == FAIL)
1992  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
1993  "Could not write Incomplete Scans.",
1994  "SDsetattr", lun, NULL, True);
1995 
1996  hdf_return = SDsetattr (out_sd_id[R],
1997  "Max Earth View Frames",
1998  DFNT_INT32, 1,
1999  (VOIDP)&L1B_Gran_Meta->max_ev_frames);
2000  if (hdf_return == FAIL)
2001  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2002  "Could not write Max Earth View Frames.",
2003  "SDsetattr", lun, NULL, True);
2004 
2005  hdf_return = SDsetattr (out_sd_id[R],
2006  "%Valid EV Observations",
2008  (VOIDP)L1B_Gran_Meta->validEVPercent);
2009  if (hdf_return == FAIL)
2010  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2011  "Could not write %Valid EV Observations.",
2012  "SDsetattr", lun, NULL, True);
2013 
2014  hdf_return = SDsetattr (out_sd_id[R],
2015  "%Saturated EV Observations",
2017  (VOIDP)L1B_Gran_Meta->satEVPercent);
2018  if (hdf_return == FAIL)
2019  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2020  "Could not write %Saturated EV Observations.",
2021  "SDsetattr", lun, NULL, True);
2022 
2023  hdf_return = SDsetattr (out_sd_id[R],
2024  "% L1A EV All Scan Data are Missing",
2025  DFNT_FLOAT32, 1,
2026  (VOIDP)&L1B_Gran_Meta->missAllScanDataPercent);
2027  if (hdf_return == FAIL)
2028  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2029  "Could not write % L1A EV All Scan Data are Missing.",
2030  "SDsetattr", lun, NULL, True);
2031 
2032  hdf_return = SDsetattr (out_sd_id[R],
2033  "% L1A EV RSB DN Not in Day Mode",
2035  (VOIDP)L1B_Gran_Meta->nightRSBPercent);
2036  if (hdf_return == FAIL)
2037  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2038  "Could not write % L1A EV RSB DN Not in Day Mode.",
2039  "SDsetattr", lun, NULL, True);
2040 
2041  hdf_return = SDsetattr (out_sd_id[R],
2042  "% L1A EV DN Missing Within Scan",
2044  (VOIDP)L1B_Gran_Meta->missInScanDataPercent);
2045  if (hdf_return == FAIL)
2046  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2047  "Could not write % L1A EV DN Missing Within Scan.",
2048  "SDsetattr", lun, NULL, True);
2049 
2050  hdf_return = SDsetattr (out_sd_id[R],
2051  "% Dead Detector EV Data",
2053  (VOIDP)L1B_Gran_Meta->deadDetectorDataPercent);
2054  if (hdf_return == FAIL)
2055  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2056  "Could not write % Dead Detector EV Data.",
2057  "SDsetattr", lun, NULL, True);
2058 
2059  hdf_return = SDsetattr (out_sd_id[R],
2060  "% Dead Subframe EV Data",
2062  (VOIDP)L1B_Gran_Meta->deadSubframeDataPercent);
2063 
2064  if (hdf_return == FAIL)
2065  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2066  "Could not write % Dead Subframe EV Data.",
2067  "SDsetattr", lun, NULL, True);
2068 
2069  hdf_return = SDsetattr (out_sd_id[R],
2070  "% Sector Rotation EV Data",
2072  (VOIDP)L1B_Gran_Meta->sectorRotateDataPercent);
2073 
2074  if (hdf_return == FAIL)
2075  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2076  "Could not write % Sector Rotation EV Data.",
2077  "SDsetattr", lun, NULL, True);
2078 
2079  hdf_return = SDsetattr (out_sd_id[R],
2080  "% Saturated EV Data",
2082  (VOIDP)L1B_Gran_Meta->saturatedDataPercent);
2083  if (hdf_return == FAIL)
2084  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2085  "Could not write % Saturated EV Data.",
2086  "SDsetattr", lun, NULL, True);
2087 
2088  hdf_return = SDsetattr (out_sd_id[R],
2089  "% TEB EV Data With Moon in SVP",
2091  (VOIDP)L1B_Gran_Meta->moonInSVPTEBDataPercent);
2092  if (hdf_return == FAIL)
2093  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2094  "Could not write % TEB EV Data With Moon in SVP.",
2095  "SDsetattr", lun, NULL, True);
2096 
2097  hdf_return = SDsetattr (out_sd_id[R],
2098  "% EV Data Where Cannot Compute BG DN",
2100  (VOIDP)L1B_Gran_Meta->noBGDataPercent);
2101  if (hdf_return == FAIL)
2102  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2103  "Could not write % EV Data Where Cannot Compute BG DN.",
2104  "SDsetattr", lun, NULL, True);
2105 
2106  hdf_return = SDsetattr (out_sd_id[R],
2107  "% RSB EV Data With dn** Below Scale",
2109  (VOIDP)L1B_Gran_Meta->badDNStarStarRSBDataPercent);
2110  if (hdf_return == FAIL)
2111  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2112  "Could not write % RSB EV Data With dn** Below Scale.",
2113  "SDsetattr", lun, NULL, True);
2114 
2115  hdf_return = SDsetattr (out_sd_id[R],
2116  "% EV Data Where Nadir Door Closed",
2118  (VOIDP)L1B_Gran_Meta->NADClosedDataPercent);
2119  if (hdf_return == FAIL)
2120  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2121  "Could not write % EV Data Where Nadir Door Closed.",
2122  "SDsetattr", lun, NULL, True);
2123 
2124  hdf_return = SDsetattr (out_sd_id[R],
2125  "% EV Data Not Calibrated",
2127  (VOIDP)L1B_Gran_Meta->uncalibratedDataPercent);
2128  if (hdf_return == FAIL)
2129  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2130  "Could not write % EV Data Not Calibrated.",
2131  "SDsetattr", lun, NULL, True);
2132 
2133  write_extract_metadata(out_sd_id[R],
2134  L1B_Gran_Meta->Extract_Pixel_Offset,
2135  L1B_Gran_Meta->Extract_Pixel_Count,
2136  L1B_Gran_Meta->Extract_Line_Offset,
2137  L1B_Gran_Meta->Extract_Line_Count);
2138 
2139  hdf_return = SDsetattr (out_sd_id[R],
2140  "Bit QA Flags Last Value",
2141  DFNT_UINT32, 1,
2142  (VOIDP)&QA->QA_common.bit_QA_flags_last_value);
2143  if (hdf_return == FAIL)
2144  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2145  "Could not write Bit QA Flags Last Value.",
2146  "SDsetattr", lun, NULL, True);
2147 
2148  hdf_return = SDsetattr (out_sd_id[R],
2149  "Bit QA Flags Change",
2150  DFNT_UINT32, 1,
2151  (VOIDP)&QA->QA_common.bit_QA_flags_change);
2152  if (hdf_return == FAIL)
2153  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2154  "Could not write Bit QA Flags Change.",
2155  "SDsetattr", lun, NULL, True);
2156 
2157  hdf_return = SDsetattr (out_sd_id[R],
2158  "Granule Average QA Values",
2160  (VOIDP) QA->QA_common.granule_averages);
2161  if (hdf_return == FAIL)
2162  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2163  "Could not write Granule Average QA Values.",
2164  "SDsetattr", lun, NULL, True);
2165 
2166  hdf_return = SDsetattr (out_sd_id[R],
2167  "Electronics Redundancy Vector",
2168  DFNT_UINT32, 2,
2169  (VOIDP)L1B_Gran_Meta->Elec_config_status);
2170  if (hdf_return == FAIL)
2171  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2172  "Could not write Electronics Redundancy Vector.",
2173  "SDsetattr", lun, NULL, True);
2174 
2175  hdf_return = SDsetattr (out_sd_id[R],
2176  "Electronics Configuration Change",
2177  DFNT_UINT32, 2,
2178  (VOIDP)L1B_Gran_Meta->Elec_config_change);
2179  if (hdf_return == FAIL)
2180  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2181  "Could not write Electronics Configuration Change.",
2182  "SDsetattr", lun, NULL, True);
2183 
2184  hdf_return = SDsetattr (out_sd_id[R],
2185  "Reflective LUT Serial Number and Date of Last Change",
2186  DFNT_CHAR8, (int32)strlen(tables->refl.Serial_Number),
2187  (VOIDP)tables->refl.Serial_Number);
2188  if (hdf_return == FAIL)
2189  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2190  "Could not write Reflective LUT Serial Number.",
2191  "SDsetattr", lun, NULL, True);
2192 
2193  hdf_return = SDsetattr (out_sd_id[R],
2194  "Emissive LUT Serial Number and Date of Last Change",
2195  DFNT_CHAR8, (int32)strlen(tables->emiss.Serial_Number),
2196  (VOIDP)tables->emiss.Serial_Number);
2197  if (hdf_return == FAIL)
2198  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2199  "Could not write Emissive LUT Serial Number.",
2200  "SDsetattr", lun, NULL, True);
2201 
2202  hdf_return = SDsetattr (out_sd_id[R],
2203  "QA LUT Serial Number and Date of Last Change",
2204  DFNT_CHAR8,
2205  (int32)strlen(tables->QA.common_QA_tables.Serial_Number),
2206  (VOIDP)tables->QA.common_QA_tables.Serial_Number);
2207  if (hdf_return == FAIL)
2208  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2209  "Could not write QA LUT Serial Number.",
2210  "SDsetattr", lun, NULL, True);
2211 
2212  hdf_return = SDsetattr (out_sd_id[R],
2213  "Focal Plane Set Point State",
2214  DFNT_INT8, 1,
2215  (VOIDP)&L1B_Gran_Meta->FPSetPointState);
2216  if (hdf_return == FAIL)
2217  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2218  "Could not write Focal Plane Set Point State.",
2219  "SDsetattr", lun, NULL, True);
2220 
2221  hdf_return = SDsetattr (out_sd_id[R],
2222  "Doors and Screens Configuration", DFNT_INT8, 1,
2223  (VOIDP)&L1B_Gran_Meta->Door_Screen_Configuration);
2224  if (hdf_return == FAIL)
2225  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2226  "Could not write Doors and Screens Config.",
2227  "SDsetattr", lun, NULL, True);
2228 
2229  hdf_return = SDsetattr (out_sd_id[R],
2230  "Reflective Bands With Bad Data",
2231  DFNT_INT8,
2233  (VOIDP)L1B_Gran_Meta->Reflective_Band_Identification);
2234  if (hdf_return == FAIL)
2235  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2236  "Could not write Reflective Bands With Bad Data.",
2237  "SDsetattr", lun, NULL, True);
2238 
2239  hdf_return = SDsetattr (out_sd_id[R],
2240  "Emissive Bands With Bad Data",
2241  DFNT_INT8,
2243  (VOIDP)L1B_Gran_Meta->Emissive_Band_Identification);
2244  if (hdf_return == FAIL)
2245  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2246  "Could not write Emissive Bands With Bad Data.",
2247  "SDsetattr", lun, NULL, True);
2248 
2249  hdf_return = SDsetattr (out_sd_id[R],
2250  "Noise in Black Body Thermistors",
2251  DFNT_UINT8, NUM_THERMISTORS,
2252  (VOIDP)QA->QA_emiss.noise_T_bb);
2253  if (hdf_return == FAIL)
2254  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2255  "Could not write Noise in Black Body Thermistors.",
2256  "SDsetattr", lun, NULL, True);
2257 
2258  hdf_return = SDsetattr (out_sd_id[R],
2259  "Noise in Average BB Temperature",
2260  DFNT_UINT8, 1,
2261  (VOIDP)&QA->QA_emiss.noise_T_bb_avg);
2262  if (hdf_return == FAIL)
2263  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2264  "Could not write Noise in Average BB Temperature.",
2265  "SDsetattr", lun, NULL, True);
2266 
2267  hdf_return = SDsetattr (out_sd_id[R],
2268  "Noise in LWIR FPA Temperature",
2269  DFNT_UINT8, 1,
2270  (VOIDP)&QA->QA_emiss.noise_T_lwir);
2271  if (hdf_return == FAIL)
2272  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2273  "Could not write Noise in LWIR FPA Temperature.",
2274  "SDsetattr", lun, NULL, True);
2275 
2276  hdf_return = SDsetattr (out_sd_id[R],
2277  "Noise in MWIR FPA Temperature",
2278  DFNT_UINT8, 1,
2279  (VOIDP)&QA->QA_emiss.noise_T_mwir);
2280  if (hdf_return == FAIL)
2281  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2282  "Could not write Noise in MWIR FPA Temperature.",
2283  "SDsetattr", lun, NULL, True);
2284 
2285  hdf_return = SDsetattr (out_sd_id[R],
2286  "Noise in Scan Mirror Thermistor #1",
2287  DFNT_UINT8, 1,
2288  (VOIDP)&QA->QA_emiss.noise_T_mir1);
2289  if (hdf_return == FAIL)
2290  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2291  "Could not write Noise in Scan Mirror Thermistor #1.",
2292  "SDsetattr", lun, NULL, True);
2293 
2294  hdf_return = SDsetattr (out_sd_id[R],
2295  "Noise in Scan Mirror Thermistor #2",
2296  DFNT_UINT8, 1,
2297  (VOIDP)&QA->QA_emiss.noise_T_mir2);
2298  if (hdf_return == FAIL)
2299  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2300  "Could not write Noise in Scan Mirror Thermistor #2.",
2301  "SDsetattr", lun, NULL, True);
2302 
2303  hdf_return = SDsetattr (out_sd_id[R],
2304  "Noise in Scan Mirror Thermistor Average",
2305  DFNT_UINT8, 1,
2306  (VOIDP)&QA->QA_emiss.noise_T_mir_avg);
2307  if (hdf_return == FAIL)
2308  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2309  "Could not write Noise in Scan Mirror Thermistor Avg.",
2310  "SDsetattr", lun, NULL, True);
2311 
2312  hdf_return = SDsetattr (out_sd_id[R],
2313  "Noise in Instrument Temperature",
2314  DFNT_UINT8, 1,
2315  (VOIDP)&QA->QA_emiss.noise_T_ins);
2316  if (hdf_return == FAIL)
2317  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2318  "Could not write Noise in Instrument Temperature.",
2319  "SDsetattr", lun, NULL, True);
2320 
2321  hdf_return = SDsetattr (out_sd_id[R],
2322  "Noise in Cavity Temperature", DFNT_UINT8, 1,
2323  (VOIDP)&QA->QA_emiss.noise_T_cav);
2324  if (hdf_return == FAIL)
2325  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2326  "Could not write Noise in Cavity Temperature.",
2327  "SDsetattr", lun, NULL, True);
2328 
2329  returnStatus = write_sds_rank2 (out_sd_id[R],
2330  "Noise in Thermal Detectors",
2331  "number of emissive bands",
2332  "detectors per 1km band",
2335  "uint8",
2336  L1B_Gran_Meta->Thermal_Detector_Noise);
2337  if (returnStatus != MODIS_S_OK)
2338  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2339  "Could not write Noise in Thermal Detectors.",
2340  "write_sds_rank2", lun, NULL, True);
2341 
2342  returnStatus = write_sds_rank2
2343  (out_sd_id[R],
2344  "Change in relative responses of thermal detectors",
2345  "number of emissive bands",
2346  "detectors per 1km band",
2349  "uint8",
2350  (VOIDP)L1B_Gran_Meta->Thermal_Detector_Relative_Response_Change);
2351  if (returnStatus != MODIS_S_OK)
2352  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2353  "Could not write Change in relative responses of "
2354  "thermal detectors.",
2355  "write_sds_rank2", lun, NULL, True);
2356 
2357  hdf_return = SDsetattr (out_sd_id[R],
2358  "Noise in Temperature of NIR FPA",
2359  DFNT_UINT8, 1,
2360  (VOIDP)&QA->QA_refl.noise_T_nir);
2361  if (hdf_return == FAIL)
2362  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2363  "Could not write Noise in Temperature of NIR FPA.",
2364  "SDsetattr", lun, NULL, True);
2365 
2366  hdf_return = SDsetattr (out_sd_id[R],
2367  "Noise in Temperature of Vis FPA",
2368  DFNT_UINT8, 1,
2369  (VOIDP)&QA->QA_refl.noise_T_vis);
2370  if (hdf_return == FAIL)
2371  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2372  "Could not write Noise in Temperature of Vis FPA.",
2373  "SDsetattr", lun, NULL, True);
2374 
2375  returnStatus = write_sds_rank3 (out_sd_id[R],
2376  "DC Restore Change for Thermal Bands",
2377  "number of scans",
2378  "number of emissive bands",
2379  "detectors per 1km band",
2380  L1B_Gran_Meta->num_scans,
2383  "int8",
2385  if (returnStatus != MODIS_S_OK)
2386  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2387  "Could not write DC Restore Change for Thermal Bands.",
2388  "write_sds_rank3", lun, NULL, True);
2389 
2390  returnStatus = write_sds_rank3
2391  (out_sd_id[R],
2392  "DC Restore Change for Reflective 250m Bands",
2393  "number of scans",
2394  "number of 250m bands",
2395  "detectors per 250m band",
2396  L1B_Gran_Meta->num_scans,
2397  NUM_250M_BANDS,
2399  "int8",
2401  if (returnStatus != MODIS_S_OK)
2402  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2403  "Could not write DC Restore Change for Reflective 250m Bands.",
2404  "write_sds_rank3", lun, NULL, True);
2405 
2406  returnStatus = write_sds_rank3
2407  (out_sd_id[R],
2408  "DC Restore Change for Reflective 500m Bands",
2409  "number of scans",
2410  "number of 500m bands",
2411  "detectors per 500m band",
2412  L1B_Gran_Meta->num_scans,
2413  NUM_500M_BANDS,
2415  "int8",
2417  if (returnStatus != MODIS_S_OK)
2418  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2419  "Could not write DC Restore Change for Reflective 500m Bands.",
2420  "write_sds_rank3", lun, NULL, True);
2421 
2422  returnStatus = write_sds_rank3
2423  (out_sd_id[R],
2424  "DC Restore Change for Reflective 1km Bands",
2425  "number of scans",
2426  "number of 1km reflective bands",
2427  "detectors per 1km band",
2428  L1B_Gran_Meta->num_scans,
2431  "int8",
2433  if (returnStatus != MODIS_S_OK)
2434  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2435  "Could not write DC Restore Change for Reflective 1km Bands.",
2436  "write_sds_rank3", lun, NULL, True);
2437 
2438  hdf_return = SDsetattr (out_sd_id[R],
2439  "Dead Detector List",
2440  DFNT_INT8,
2441  NUM_DETECTORS,
2442  (VOIDP)tables->QA.common_QA_tables.dead_detector);
2443  if (hdf_return == FAIL)
2444  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2445  "Could not write Dead Detector List.",
2446  "SDsetattr", lun, NULL, True);
2447 
2448  hdf_return = SDsetattr (out_sd_id[R],
2449  "Noisy Detector List",
2450  DFNT_INT8,
2451  NUM_DETECTORS,
2452  (VOIDP)tables->QA.common_QA_tables.noisy_detector);
2453  if (hdf_return == FAIL)
2454  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2455  "Could not write Noisy Detector List.",
2456  "SDsetattr", lun, NULL, True);
2457 
2458  /*output noisy and dead subframe list */
2459  hdf_return = SDsetattr (out_sd_id[R],
2460  "Dead Subframe List",
2461  DFNT_INT8,
2463  (VOIDP)tables->QA.common_QA_tables.dead_subframe);
2464  if (hdf_return == FAIL)
2465  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2466  "Could not write Dead Subframe List.",
2467  "SDsetattr", lun, NULL, True);
2468 
2469  hdf_return = SDsetattr (out_sd_id[R],
2470  "Noisy Subframe List",
2471  DFNT_INT8,
2473  (VOIDP)tables->QA.common_QA_tables.noisy_subframe);
2474  if (hdf_return == FAIL)
2475  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2476  "Could not write Noisy Subframe List.",
2477  "SDsetattr", lun, NULL, True);
2478 
2479  /* Detector Quality Flag */
2480 
2481  hdf_return = SDsetattr (out_sd_id[R],
2482  "Detector Quality Flag",
2483  DFNT_UINT8,
2484  NUM_DETECTORS,
2485  (VOIDP)tables->QA.common_QA_tables.Detector_Quality_Flag);
2486  if (hdf_return == FAIL)
2487  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2488  "Could not write Detector Quality Flag.",
2489  "SDsetattr", lun, NULL, True);
2490 
2491  /* Detector Quality Flag2 */
2492 
2493  hdf_return = SDsetattr (out_sd_id[R],
2494  "Detector Quality Flag2",
2495  DFNT_UINT8,
2497  (VOIDP)tables->QA.common_QA_tables.Detector_Quality_Flag2);
2498  if (hdf_return == FAIL)
2499  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2500  "Could not write Detector Quality Flag2.",
2501  "SDsetattr", lun, NULL, True);
2502 
2503  /* Earth-Sun distance */
2504 
2505  hdf_return = SDsetattr (out_sd_id[R],
2506  "Earth-Sun Distance",
2507  DFNT_FLOAT32, 1,
2508  (VOIDP)&L1B_Gran_Meta->Earth_Sun_Dist);
2509  if (hdf_return == FAIL)
2510  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2511  "Could not write Earth-Sun distance.",
2512  "SDsetattr", lun, NULL, True);
2513 
2514  /* Solar irradiance */
2515 
2516  hdf_return = SDsetattr (out_sd_id[R],
2517  "Solar Irradiance on RSB Detectors over pi",
2518  DFNT_FLOAT32,
2520  (VOIDP) tables->refl.E_sun_over_pi);
2521 
2522  if (hdf_return == FAIL)
2523  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2524  "Could not write E_sun_over_pi.",
2525  "SDsetattr", lun, NULL, True);
2526 
2527  /* set doi global attribute */
2528  hdf_return = SDsetattr (out_sd_id[R],
2529  L1B_Gran_Meta->doi_attr_name,
2530  DFNT_CHAR8, (int32)strlen(L1B_Gran_Meta->doi_para_value[R]),
2531  &L1B_Gran_Meta->doi_para_value[R][0]);
2532 
2533  if (hdf_return == FAIL)
2534  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2535  "Could not write identifier_product_doi.",
2536  "SDsetattr", lun, NULL, True);
2537 
2538  /* set doi authority global attribute */
2539  hdf_return = SDsetattr (out_sd_id[R],
2540  L1B_Gran_Meta->doi_authority_attr_name,
2541  DFNT_CHAR8, (int32)strlen(L1B_Gran_Meta->doi_authority_para_value),
2542  L1B_Gran_Meta->doi_authority_para_value);
2543 
2544  if (hdf_return == FAIL)
2545  L1BErrorMsg(location, MODIS_F_WRITE_ERROR,
2546  "Could not write identifier_product_doi_authority.",
2547  "SDsetattr", lun, NULL, True);
2548 
2549 
2550  }
2551 
2552  return(MODIS_S_OK);
2553 }
2554 
2555 PGSt_SMF_status Get_Electronics_Status(int32 v_id,
2556  int32 num_scans,
2557  char *vname,
2558  char *fname,
2559  int16 *final_value,
2560  int16 *is_changed,
2561  boolean *no_valid_value)
2562 /*
2563 !C**********************************************************************
2564 !Description: This function computes the final status of the electronics
2565  and determines if any change occurred within the granule
2566  for the electronics.
2567 
2568 !Input Parameters:
2569  int32 v_id file id used for vdata interface
2570  int32 num_scans number of scans in the granule represented by v_id
2571  char * vname vdata name of the telemetry point for the interested
2572  electronics
2573  char * fname telemetry field name for the electronics
2574 
2575 !Output Parameters:
2576  int16 * final_value the address of the final value of the telemetry
2577  point corresponding to the interested electronics.
2578  The final value is in set [0, 1].
2579  int16 * is_changed the address of the change status of the telemetry
2580  point. 0 = no change, 1 = change occured within
2581  granule.
2582  boolean *no_valid_value True = no valid value for the telemetry field
2583  within the granule, False = there is at least
2584  one valid value for the telemetry field within
2585  the granule.
2586 
2587 !Revision History:
2588  (continue at top of the file)
2589 
2590  Revision 01.00 Sept. 7, 1999
2591  Initial development
2592  Zhenying Gu(zgu@mcst.gsfc.nasa.gov)
2593 
2594 !Team-unique Header:
2595  This software is developed by the MODIS Characterization Support
2596  Team (MCST)for the National Aeronautics and Space Administration,
2597  Goddard Space Flight Center, under contract NAS5-32373.
2598 
2599 !References and Credits:
2600  HDF portions developed at the National Center for Supercomputing
2601  Applications at the University of Illinois at Urbana-Champaign.
2602 
2603 !Design Notes:
2604  If there is no valid scan for the telemetry field corresponding
2605  to the electronics, the final value of the telemetry field is set
2606  to 0 and the change status is set to 0.
2607 
2608 !END********************************************************************
2609 */
2610 
2611 {
2612  PGSt_SMF_status returnStatus;
2613  char *location = "Get_Electronics_Status";
2614  uint16 values[MAX_NUM_SCANS]; /* values of the telemetry point for
2615  all scans in the granule */
2616  uint16 temp_final_value; /* temporary variable to store the
2617  last valid value */
2618  uint16 last_valid_scans[MAX_NUM_SCANS]; /* the scan from which the
2619  information is taken for the current scan */
2620  boolean first_valid_value_found; /* flag to indicate if there has been a
2621  valid value found while looping through scans */
2622 
2623  int16 S; /* scan index */
2624 
2625  /* Check the input parameters */
2626 
2627  if (vname == NULL || fname == NULL || final_value == NULL ||
2628  is_changed == NULL)
2629  {
2630  returnStatus = MODIS_F_INVALID_ARGUMENT;
2631  L1BErrorMsg(location, returnStatus,
2632  "One of vname, fname, final_value or is_changed is invalid.",
2633  NULL, 0, NULL, True);
2634  return returnStatus;
2635  }
2636 
2637  if (num_scans <= 0 || num_scans > MAX_NUM_SCANS)
2638  {
2639  returnStatus = MODIS_F_INVALID_ARGUMENT;
2640  L1BErrorMsg(location, returnStatus, "num_scans is invalid.",
2641  NULL, 0, NULL, True);
2642  return returnStatus;
2643  }
2644 
2645  /* Initialization */
2646 
2647  *is_changed = 0;
2648  first_valid_value_found = False;
2649  temp_final_value = 0;
2650 
2651  /* Read the vdata field and the "LAST_VALID_SCAN" field */
2652 
2653  returnStatus = read_vdata(v_id, 0, num_scans, vname, fname, values);
2654  if (returnStatus != MODIS_S_OK)
2655  {
2656  L1BErrorMsg(location, returnStatus, NULL, "read_vdata", 0, NULL, False);
2657  return returnStatus;
2658  }
2659 
2660  returnStatus = read_vdata(v_id, 0, num_scans, vname,
2661  "LAST_VALID_SCAN", last_valid_scans);
2662  if (returnStatus != MODIS_S_OK)
2663  {
2664  L1BErrorMsg(location, returnStatus, NULL, "read_vdata", 0, NULL, False);
2665  return returnStatus;
2666  }
2667 
2668  for (S = 0; S < num_scans; S++)
2669  {
2670  if (values[S] != 0 && values[S] != 1)
2671  {
2672  char msgbuf[256];
2673  sprintf(msgbuf,
2674  "Value[%d] of telemetry \"%s\" is out of the range [0,1].",
2675  S, fname);
2676  returnStatus = MODIS_F_OUT_OF_RANGE;
2677  L1BErrorMsg(location, returnStatus, msgbuf, NULL, 0,
2679  return returnStatus;
2680  }
2681 
2682 
2683  /*
2684  * If current value is valid and different from the temporary final
2685  * value, it means there is a change. Update the final value.
2686  */
2687 
2688 
2689  if (last_valid_scans[S] != L1A_MISSING_ENG_PACKET)
2690  {
2691  if (first_valid_value_found == True && values[S] != temp_final_value)
2692  *is_changed = 1;
2693 
2694  temp_final_value = values[S];
2695  first_valid_value_found = True;
2696  }
2697  }
2698 
2699  *final_value = temp_final_value;
2700  *no_valid_value = !first_valid_value_found;
2701 
2702  return returnStatus;
2703 }
2704 
2705 PGSt_SMF_status Get_Elec_Config_Status_Per_Gran
2706  (int32 v_id,
2707  int32 num_scans,
2708  uint32 *Elec_config_status,
2709  uint32 *Elec_config_change,
2710  uint32 *Elec_config_invalid_flag)
2711 /*
2712 !C**********************************************************************
2713 !Description: This function determines the final status of a set of
2714  telemetry fields electronics and determines if any change
2715  occurred within the granule for each of the fields. It also
2716  indicates if there is valid data for the telemetry fields
2717  within the granule.
2718 
2719 !Input Parameters:
2720  int32 v_id vdata interface for L1A file
2721  int32 num_scans number of scans in the L1A file
2722 
2723 !Output Parameters:
2724 
2725  uint32 Elec_config_status[E_VECTOR_SIZE]
2726  the final valid value for the corresponding
2727  telemetry point within the granule with one
2728  bit representing one field.
2729  Values are 0=OFF and 1=ON
2730  uint32 Elec_config_change[E_VECTOR_SIZE]
2731  identifies if any change occurred within
2732  the granule for the corresponding telemetry
2733  point with one bit representing one field.
2734  uint32 Elec_config_invalid_flag[E_VECTOR_SIZE]
2735  identifies if there is no valid value for
2736  the telemetry fields within the whole granule
2737 
2738 !Revision History:
2739  (continue at top of the file)
2740 
2741  Revision 01.01 March 2003, Razor Issue #173
2742  Enclosed the rows in the initializer of array-of-struct "Elec_config_fields"
2743  with braces for ANSI-C compliance.
2744  Liqin Tan, SAIC GSO (ltan@saicmodis.com)
2745 
2746  Revision 01.00 Oct. 29, 1999
2747  Initial development
2748  Zhenying Gu(zgu@mcst.gsfc.nasa.gov)
2749 
2750 !Team-unique Header:
2751  This software is developed by the MODIS Characterization Support
2752  Team (MCST)for the National Aeronautics and Space Administration,
2753  Goddard Space Flight Center, under contract NAS5-32373.
2754 
2755 !References and Credits:
2756  HDF portions developed at the National Center for Supercomputing
2757  Applications at the University of Illinois at Urbana-Champaign.
2758 
2759 !Design Notes:
2760  If the final valid value for a telemetry field is 0, set the
2761  corresponding bit (see file specification for which bit represents
2762  which telemetry field.) in Elec_config_status to be 0. If the final
2763  valid value for a telemetry field is 1, set the bit to 1. If there
2764  is no valid value for a telemetry within the granule, set the
2765  corresponding bit in Elec_config_status to 0 and set the
2766  corresponding bit in Elec_config_invalid_flag to 1. If there is valid
2767  value change for a telemetry field within the granule, set the
2768  corresponding bit in Elec_config_change to 1. Otherwise set it to
2769  0.
2770 !END********************************************************************
2771 */
2772 {
2773  PGSt_SMF_status returnStatus = MODIS_S_OK;
2774  char *location = "Get_Elec_Config_Status_Per_Gran";
2775  int16 i;
2776  int16 final_value; /* the value of electronics field in the last scan */
2777  int16 is_changed; /* the change status of the electronics field in */
2778  /* the granule */
2779  boolean no_valid_value; /* flag indicating if there is valid value */
2780  /* for a telemetry field within the granule */
2781  int16 ivar; /* index for number of word used for electronics */
2782  /* configuration status (or change) */
2783  int32 mask; /* bit mask used to set the every bit of the */
2784  /* attributes */
2785  int32 total_fields; /* index to keep track of all the fields have */
2786  /* been looped through */
2787  int32 num_elec_config_elements = 0; /* number of the telemetry fields */
2788  /* in the Electronics configuration */
2789 
2790  struct {
2791  char *vname;
2792  char *fname;
2793  }Elec_config_fields[] = {
2794  {"Telemetry Major Cycle 0 of 7", "CR_BB_A_PWR_ON"},
2795  {"Telemetry Major Cycle 0 of 7", "CR_BB_B_PWR_ON"},
2796  {"Telemetry Major Cycle 1 of 7", "CR_CE_A_ON"},
2797  {"Telemetry Major Cycle 1 of 7", "CR_CE_B_ON"},
2798  {"Telemetry Major Cycle 1 of 7", "CR_CP_A_ON_M"},
2799  {"Telemetry Major Cycle 1 of 7", "CR_CP_B_ON_M"},
2800  {"Telemetry Major Cycle 3B of 7", "CR_FI_A_ON"},
2801  {"Telemetry Major Cycle 3B of 7", "CR_FI_B_ON"},
2802  {"Telemetry Major Cycle 3B of 7", "CR_FO_BLK1_ON"},
2803  {"Telemetry Major Cycle 3B of 7", "CR_FO_BLK2_ON"},
2804  {"Telemetry Major Cycle 3B of 7", "CR_FO_BLK3_ON"},
2805  {"Telemetry Major Cycle 3B of 7", "CR_FO_BLK4_ON"},
2806  {"Telemetry Major Cycle 3C of 7", "CR_FR_A_ON"},
2807  {"Telemetry Major Cycle 3C of 7", "CR_FR_B_ON"},
2808  {"Telemetry Major Cycle 4B of 7", "CS_FR_PC_DCR_ON"},
2809  {"Telemetry Major Cycle 4B of 7", "CS_FR_PV_DCR_ON"},
2810  {"Telemetry Major Cycle 4A of 7", "CR_PCLW_A_ON"},
2811  {"Telemetry Major Cycle 4A of 7", "CR_PCLW_B_ON"},
2812  {"Telemetry Major Cycle 4A of 7", "CR_PVLW_A_ON"},
2813  {"Telemetry Major Cycle 4A of 7", "CR_PVLW_B_ON"},
2814  {"Telemetry Major Cycle 4B of 7", "CR_PVSM_A_ON"},
2815  {"Telemetry Major Cycle 4B of 7", "CR_PVSM_B_ON"},
2816  {"Telemetry Major Cycle 4B of 7", "CR_PVNIR_A_ON"},
2817  {"Telemetry Major Cycle 4B of 7", "CR_PVNIR_B_ON"},
2818  {"Telemetry Major Cycle 4B of 7", "CR_PVVIS_A_ON"},
2819  {"Telemetry Major Cycle 4B of 7", "CR_PVVIS_B_ON"},
2820  {"Telemetry Major Cycle 4A of 7", "CR_PVLWA_ECAL_ON"},
2821  {"Telemetry Major Cycle 4A of 7", "CR_PVLWB_ECAL_ON"},
2822  {"Telemetry Major Cycle 4B of 7", "CR_PVNIRA_ECALON"},
2823  {"Telemetry Major Cycle 4B of 7", "CR_PVNIRB_ECALON"},
2824  {"Telemetry Major Cycle 4B of 7", "CR_PVSMA_ECAL_ON"},
2825  {"Telemetry Major Cycle 4B of 7", "CR_PVSMB_ECAL_ON"},
2826  {"Telemetry Major Cycle 4B of 7", "CR_PVVISA_ECALON"},
2827  {"Telemetry Major Cycle 4B of 7", "CR_PVVISB_ECALON"},
2828  {"Telemetry Major Cycle 5A of 7", "CR_RC_SMHTR_ON"},
2829  {"Telemetry Major Cycle 5A of 7", "CR_RC_LWHTR_ON"},
2830  {"Telemetry Major Cycle 5B of 7", "CR_SA_A_SCAN_ON"},
2831  {"Telemetry Major Cycle 5B of 7", "CR_SA_B_SCAN_ON"},
2832  {"Telemetry Major Cycle 5B of 7", "CR_SM_SDSM_A_ON"},
2833  {"Telemetry Major Cycle 5B of 7", "CR_SM_SDSM_B_ON"},
2834  {"Telemetry Major Cycle 5B of 7", "CR_SR_A_ON"},
2835  {"Telemetry Major Cycle 5B of 7", "CR_SR_B_ON"},
2836  {"Telemetry Major Cycle 6 of 7", "CR_TG_A_ON"},
2837  {"Telemetry Major Cycle 6 of 7", "CR_TG_B_ON"},
2838  {NULL, NULL}
2839  };
2840 
2841  /* check input parameters */
2842 
2843  if (num_scans <= 0 || num_scans > MAX_NUM_SCANS)
2844  {
2845  returnStatus = MODIS_F_INVALID_ARGUMENT;
2846  L1BErrorMsg(location, returnStatus, "number of scans is out of range",
2847  NULL, 0, NULL, True);
2848  return returnStatus;
2849  }
2850 
2851  /* initialization */
2852 
2853  total_fields = 0;
2854 
2855  /* count up number of elements in Elec_config_fields */
2856 
2857  while (Elec_config_fields[num_elec_config_elements].vname!= NULL)
2858  num_elec_config_elements++;
2859 
2860  if (num_elec_config_elements > E_VECTOR_SIZE * 32)
2861  {
2862  returnStatus = MODIS_F_NOK;
2863  L1BErrorMsg(location, returnStatus, "macro E_VECTOR_SIZE is too small",
2864  NULL, 0, NULL, True);
2865  return returnStatus;
2866  }
2867 
2868  for (ivar = 0; ivar < E_VECTOR_SIZE; ivar++)
2869  {
2870  /* initialization */
2871 
2872  Elec_config_status[ivar] = 0;
2873  Elec_config_change[ivar] = 0;
2874  Elec_config_invalid_flag[ivar] = 0;
2875 
2876  /* mask starts at the least significant bit */
2877 
2878  mask = 1;
2879 
2880  for (i = 0; i < 32 && total_fields < num_elec_config_elements;
2881  i++, total_fields++)
2882  {
2883  /*
2884  * Get the final value, change status and valid value information
2885  * for the field.
2886  */
2887 
2888  returnStatus = Get_Electronics_Status
2889  (v_id,
2890  num_scans,
2891  Elec_config_fields[total_fields].vname,
2892  Elec_config_fields[total_fields].fname,
2893  &final_value,
2894  &is_changed,
2895  &no_valid_value);
2896  if (returnStatus != MODIS_S_OK)
2897  {
2898  L1BErrorMsg(location, returnStatus, NULL,
2899  "Get_Electronics_Status", 0, NULL, False);
2900  return returnStatus;
2901  }
2902 
2903  /*
2904  * Pack final value, change status and valid value information
2905  * into three output variables, respectively. Each bit in each
2906  * variable represents a specific value for a telemetry field.
2907  */
2908 
2909  if (final_value == 1)
2910  Elec_config_status[ivar] |= mask;
2911 
2912  if (is_changed == 1)
2913  Elec_config_change[ivar] |= mask;
2914 
2915  if (no_valid_value == True)
2916  Elec_config_invalid_flag[ivar] |= mask;
2917 
2918  /* shift mask to next more significant bit */
2919 
2920  mask *= 2;
2921  }
2922  }
2923 
2924  return returnStatus;
2925 }
2926 
2927 
2928 
2929 PGSt_SMF_status Get_Elec_Config_Status(QA_Common_t *QA_common,
2930  int32 v_id,
2931  int32 num_scans,
2932  uint32 *Elec_config_status,
2933  uint32 *Elec_config_change)
2934 /*
2935 !C**********************************************************************
2936 !Description: This function computes the final status of the electronics
2937  and determines if any change occurred within the granule
2938  or between the last scan of the leading granule and the first
2939  scan of the middle granule for the electronics. It also
2940  indicates if there is valid data for the telemetry fields
2941  within the granule.
2942 
2943 !Input Parameters:
2944  QA_Common_t *QA_common containing the information if the leading
2945  granule is missing
2946  int32 v_id vdata interface for middle L1A granule
2947  int32 num_scans number of scans in the middle L1A granule
2948 
2949 !Output Parameters:
2950  uint32 Elec_config_status[E_VECTOR_SIZE]
2951  the final valid value for the corresponding
2952  telemetry point within the granule with one
2953  bit represents one field.
2954  Values are 0=OFF and 1=ON
2955 
2956  uint32 Elec_config_change[E_VECTOR_SIZE]
2957  identifies if any change occurred within
2958  the granule or between the last valid value of
2959  the leading granule and the last valid value of
2960  the middle granule for the corresponding telemetry
2961  point with one bit represent one field.
2962 
2963 !Revision History:
2964  (continue at top of the file)
2965 
2966  Revision 01.00 Nov. 1, 1999
2967  Initial development
2968  Zhenying Gu(zgu@mcst.gsfc.nasa.gov)
2969 
2970 !Team-unique Header:
2971  This software is developed by the MODIS Characterization Support
2972  Team (MCST)for the National Aeronautics and Space Administration,
2973  Goddard Space Flight Center, under contract NAS5-32373.
2974 
2975 !References and Credits:
2976  HDF portions developed at the National Center for Supercomputing
2977  Applications at the University of Illinois at Urbana-Champaign.
2978 
2979 !Design Notes:
2980  Check the valid values of the electronics telemetry fields for every
2981  scan in the leading L1A granule and middle L1A granule. See function
2982  Get_Elec_Config_Status_Per_Gran for the listing and order of fields. The
2983  final valid value of the telemetry point corresponds to a electronics
2984  within the middle L1A granule is considered to be the status of the
2985  electronics in that granule. The corresponding bit of the attribute
2986  "Electronics Configuration Status" is set to be 1 if the final valid
2987  value is 1 and 0 if that value is 0. If there is any change among the
2988  valid values of one of the telemetry points within the granule or
2989  between the final valid value of the leading granule and that of the
2990  middle granule, the corresponding bit of the attribute "Electronics
2991  Configuration Change" is set to 1. If there is no valid value for some
2992  of the electronics telemetry fields in the middle granule, the most
2993  significant bits of the second words of both attributes are set to 1 as
2994  a flag for the analysts. If there is no valid value for some of the
2995  electronics telemetry fields in the leading granule, the comparision of
2996  the final values of those fields in the leading granule and those in the
2997  middle granule is not made.
2998 !END********************************************************************
2999 */
3000 
3001 {
3002  PGSt_SMF_status returnStatus;
3003  char *location = "Get_Elec_Config_Status";
3004  intn hdf_return;
3005  int32 i;
3006  int32 Leading_v_id; /* vdata interface for leading L1A granule */
3007  int32 Leading_sd_id; /* sds interface for leading L1A granule */
3008  int32 num_scans_leading; /* number of scans in leading L1A granule */
3009  uint32 Leading_Elec_config_status[E_VECTOR_SIZE];
3010  /* The Electronics Configuration Status
3011  in leading L1A granule */
3012  uint32 Leading_Elec_config_change[E_VECTOR_SIZE];
3013  /* The Electronics Configuration Change
3014  in leading L1A granule */
3015  uint32 Leading_Elec_config_invalid_flag[E_VECTOR_SIZE];
3016  /* identifies if there are valid values
3017  for the telemetry points within
3018  leading L1A granule */
3019  uint32 Elec_config_invalid_flag[E_VECTOR_SIZE];
3020  /* identifies if there are valid values
3021  for the telemetry points within
3022  middle L1A granule */
3023  PGSt_integer Version = 1;
3024  char file_name[PGSd_PC_FILE_PATH_MAX];
3025  /* leading granule file name */
3026 
3027  /* Check if the input parameter num_scans has valid value */
3028 
3029  if (num_scans <= 0 || num_scans > MAX_NUM_SCANS)
3030  {
3031  returnStatus = MODIS_F_INVALID_ARGUMENT;
3032  L1BErrorMsg(location, returnStatus, "number of scans is out of range",
3033  NULL, 0, NULL, True);
3034  return returnStatus;
3035  }
3036 
3037 
3038  /*
3039  * Check if the leading granule is missing. If it is missing, only the
3040  * Electronics Configuration Status and the Electronics Configuration
3041  * Change for the middle granule need to be calculated.
3042  */
3043 
3044 
3045  if (QA_common->missing_leading_granule == True)
3046  {
3047  returnStatus = Get_Elec_Config_Status_Per_Gran(v_id,
3048  num_scans,
3049  Elec_config_status,
3050  Elec_config_change,
3051  Elec_config_invalid_flag);
3052  if (returnStatus != MODIS_S_OK)
3053  {
3054  L1BErrorMsg(location, returnStatus, NULL,
3055  "Get_Elec_Config_Status_Per_Gran",
3057  return returnStatus;
3058  }
3059  }
3060 
3061  else
3062  {
3063  /* Get the file name of leading granule */
3064 
3065  returnStatus = PGS_PC_GetReference (LEADING_L1A_GRANULE,
3066  &Version,
3067  file_name);
3068  if (returnStatus != PGS_S_SUCCESS)
3069  {
3070  returnStatus = MODIS_F_FILE_NOT_FOUND;
3071  L1BErrorMsg(location, returnStatus,
3072  "Could not retrieve file name from PCF.",
3073  "PGS_PC_GetReference", LEADING_L1A_GRANULE, NULL, True);
3074  return returnStatus;
3075  }
3076 
3077  Leading_sd_id = SDstart(file_name, DFACC_RDONLY); /*for sds interfaces*/
3078  if (Leading_sd_id == FAIL)
3079  {
3080  returnStatus = MODIS_F_FILE_NOT_OPENED;
3081  L1BErrorMsg(location, returnStatus,
3082  "Could not open file for SD read access.",
3083  "SDstart",
3085  "The file may be missing, corrupted or not an HDF-4 file.",
3086  True);
3087  return returnStatus;
3088  }
3089 
3090  Leading_v_id = Hopen(file_name,DFACC_RDONLY,0); /* for vdate interface */
3091  if (Leading_v_id == FAIL)
3092  {
3093  returnStatus = MODIS_F_FILE_NOT_OPENED;
3094  L1BErrorMsg(location, returnStatus,
3095  "Could not open file for Vdata read access.",
3096  "Hopen",
3098  "The file may be corrupted or not an HDF-4 file.",
3099  True);
3100  return returnStatus;
3101  }
3102 
3103  hdf_return = Vstart(Leading_v_id);
3104  if (hdf_return == FAIL)
3105  {
3106  returnStatus = MODIS_F_HDF_ERROR;
3107  L1BErrorMsg(location, returnStatus,
3108  "Could not initialize Vdata interface.",
3109  "Vstart",
3111  "The file may be corrupted or not an HDF-4 file.",
3112  True);
3113  return returnStatus;
3114  }
3115 
3116  returnStatus = read_attribute(Leading_sd_id, "Number of Scans",
3117  DFNT_INT32, (void *)&num_scans_leading);
3118  if (returnStatus != MODIS_S_OK)
3119  {
3120  L1BErrorMsg(location, returnStatus,
3121  "Could not read Number of Scans.",
3122  "read_attribute",
3125  True);
3126  return returnStatus;
3127  }
3128 
3129  /*
3130  * Determine the Electronics Configuration Status and the Electronics Configuration
3131  * Change within the leading granule. Also determine if there is valid data for each
3132  * of the telemetry fields compose the Electronics Configuration in the leading granule.
3133  */
3134 
3135  returnStatus = Get_Elec_Config_Status_Per_Gran
3136  (Leading_v_id,
3137  num_scans_leading,
3138  Leading_Elec_config_status,
3139  Leading_Elec_config_change,
3140  Leading_Elec_config_invalid_flag);
3141  if (returnStatus != MODIS_S_OK)
3142  {
3143  L1BErrorMsg(location, returnStatus, NULL,
3144  "Get_Elec_Config_Status_Per_Gran",
3146  return returnStatus;
3147  }
3148 
3149  /* Do the same thing as above for the middle granule */
3150 
3151  returnStatus = Get_Elec_Config_Status_Per_Gran
3152  (v_id,
3153  num_scans,
3154  Elec_config_status,
3155  Elec_config_change,
3156  Elec_config_invalid_flag);
3157  if (returnStatus != MODIS_S_OK)
3158  {
3159  L1BErrorMsg(location, returnStatus, NULL,
3160  "Get_Elec_Config_Status_Per_Gran",
3162  return returnStatus;
3163  }
3164 
3165 
3166  /*
3167  * If a telemetry field value changed within the middle granule, set the
3168  * corresponding bit to 1. If there is a change between the last valid
3169  * value of a telemetry field in the leading granule and that in the
3170  * middle granule, also set the corresponding bit to 1.
3171  */
3172 
3173 
3174  for (i = 0; i < E_VECTOR_SIZE; i++)
3175  Elec_config_change[i] = Elec_config_change[i] |
3176  ((~Leading_Elec_config_invalid_flag[i])&
3177  (Leading_Elec_config_status[i]^Elec_config_status[i]));
3178 
3179  /* Close the leading L1A file */
3180 
3181  hdf_return = SDend(Leading_sd_id);
3182  if (hdf_return == FAIL)
3183  L1BErrorMsg(location, MODIS_F_HDF_ERROR, NULL,
3184  "SDend", LEADING_L1A_GRANULE,
3185  "Memory or the disk file must have become corrupted.",
3186  True);
3187 
3188  hdf_return = Vend(Leading_v_id);
3189  if (hdf_return == FAIL)
3190  L1BErrorMsg(location, MODIS_F_HDF_ERROR, NULL,
3191  "Vend", LEADING_L1A_GRANULE,
3192  "Memory or the disk file must have become corrupted.",
3193  True);
3194 
3195  hdf_return = Hclose(Leading_v_id);
3196  if (hdf_return == FAIL)
3197  L1BErrorMsg(location, MODIS_F_HDF_ERROR, NULL,
3198  "Hclose", LEADING_L1A_GRANULE,
3199  "Memory or the disk file must have become corrupted.",
3200  True);
3201  }
3202 
3203 
3204  /*
3205  * If any of the telemetry fields has no valid value within the middle
3206  * granule, set the most significant bit of the second words of the
3207  * Electronics Configuration Status and the Electronics Configuration
3208  * Change to be 1.
3209  */
3210 
3211 
3212  if (Elec_config_invalid_flag[0] > 0 || Elec_config_invalid_flag[1] > 0)
3213  {
3214  Elec_config_change[1] |= 0x80000000;
3215  Elec_config_status[1] |= 0x80000000;
3216  }
3217 
3218  return returnStatus;
3219 }
3220 
3221 /* end of Metadata.c */
3222 
uint32 saturated_pixels[NUM_BANDS]
Definition: Metadata.h:93
uint8 change_b1[NUM_EMISSIVE_DETECTORS]
Definition: Granule.h:1042
float32 badDNStarStarRSBDataPercent[NUM_DETECTORS]
Definition: Metadata.h:155
#define MODIS_S_OK
#define MODIS_F_FILE_NOT_FOUND
#define COMMON_TEXT_SIZE
Definition: Granule.h:482
integer, parameter int16
Definition: cubeio.f90:3
int32 value
Definition: Granule.c:1235
#define ANCILLARYINPUTTYPE_MACRO
Definition: Metadata.c:68
int32 num_bad_dn_star_star_RSB_EV_data[NUM_DETECTORS]
Definition: Granule.h:1086
#define QA_TABLES_FILE
Definition: FNames.h:76
data_t t[NROOTS+1]
Definition: decode_rs.h:77
uint8 noise_T_cav
Definition: Granule.h:1040
PGSt_PC_Logical fileID
Definition: MetadataP.h:53
an array had not been initialized Several spelling and grammar corrections were which is read from the appropriate MCF the above metadata values were hard coded A problem calculating the average background DN for SWIR bands when the moon is in the space view port was corrected The new algorithm used to calculate the average background DN for all reflective bands when the moon is in the space view port is now the same as the algorithm employed by the thermal bands For non SWIR changes in the averages are typically less than Also for non SWIR the black body DNs remain a backup in case the SV DNs are not available For SWIR the changes in computed averages were larger because the old which used the black body suffered from contamination by the micron leak As a consequence of the if SV DNs are not available for the SWIR the EV pixels will not be the granule time is used to identify the appropriate tables within the set given for one LUT the first two or last two tables respectively will be used for the interpolation If there is only one LUT in the set of tables
Definition: HISTORY.txt:695
PGSt_SMF_status Write_Gran_Metadata(Run_Time_Parameters_t *runtime_params, L1B_Gran_Metadata_t *L1B_Gran_Meta, QA_Data_t *QA, Preprocess_Data_t *PP, lookup_tables_t *tables, L1A_granule_t *L1A_Gran, boolean skip_night_hi_res)
Definition: Metadata.c:75
#define MCF_FILE_1KM
Definition: FNames.h:66
int8 Emissive_Band_Identification[NUM_EMISSIVE_BANDS]
Definition: Metadata.h:116
uint8 noise_T_ins
Definition: Granule.h:1039
#define MODIS_F_WRITE_ERROR
float32 Earth_Sun_Dist
Definition: Metadata.h:136
uint32 valid_pixels[NUM_BANDS]
Definition: Metadata.h:92
int32 emiss_qapercent_missing
Definition: Metadata.h:133
QA_Common_t QA_common
Definition: Granule.h:1097
uint32 dead_subframe_pixels[NUM_BANDS]
Definition: Granule.h:883
uint32 interpolated_pixels[NUM_BANDS]
Definition: Granule.h:881
#define MCF_FILE_OBC
Definition: FNames.h:67
boolean missing_trailing_granule
Definition: Granule.h:1071
int write_extract_metadata(int32 sd_id, int32 extract_pixel_offset, int32 extract_pixel_count, int32 extract_line_offset, int32 extract_line_count)
char ReprocessingActual[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:737
uint32 valid_pixels[NUM_BANDS]
Definition: Granule.h:878
PGSt_SMF_status write_sds_rank3(int32 file_id, char *sds_name, char *dim_name1, char *dim_name2, char *dim_name3, int32 dim1, int32 dim2, int32 dim3, char *datatype, void *data)
Definition: HDF_Lib.c:1192
#define MCF_FILE_HKM
Definition: FNames.h:65
float32 saturatedDataPercent[NUM_DETECTORS]
Definition: Metadata.h:152
int32 num_sector_rotation_EV_data[NUM_DETECTORS]
Definition: Granule.h:1082
@ INDEX_L1B_OBC_FILE
Definition: MetadataP.h:63
int8 Reflective_Band_Identification[NUM_REFLECTIVE_BANDS]
Definition: Metadata.h:115
uint8 noise_T_bb[12]
Definition: Granule.h:1032
int32 num_nadir_door_closed_EV_data[NUM_DETECTORS]
Definition: Granule.h:1088
#define FAIL
Definition: ObpgReadGrid.h:18
int32 num_saturated_EV_data[NUM_DETECTORS]
Definition: Granule.h:1083
#define NULL
Definition: decode_rs.h:63
#define TERRA
Definition: Granule.h:549
uint32 Elec_config_status[E_VECTOR_SIZE]
Definition: Metadata.h:143
#define MODIS_BAND26_INDEX
Definition: Granule.h:446
#define FIRST_L1A_GRANULE
Definition: FNames.h:79
void set_ptrstring_attr(char *field, char **value)
Definition: Metadata.c:1069
float32 validEVPercent[NUM_BANDS]
Definition: Metadata.h:86
@ INDEX_L1B_EV_500M_FILE
Definition: MetadataP.h:61
int32 refl_1km_qapercent_missing
Definition: Metadata.h:130
float32 NADClosedDataPercent[NUM_DETECTORS]
Definition: Metadata.h:157
int32 qapercent_missing_250m
Definition: Metadata.h:124
float32 missAllScanDataPercent
Definition: Metadata.h:146
int32 L1B_Gran_sd_id[NUM_L1B_EV_FILES]
Definition: Metadata.h:72
uint8 noise_T_mir2
Definition: Granule.h:1037
int32 Extract_Pixel_Offset
Definition: Metadata.h:81
#define NUM_500M_BANDS
Definition: Granule.h:431
char doi_attr_name[PGSd_MET_MAX_STRING_SET_L]
Definition: Metadata.h:108
#define MODIS_F_OUT_OF_RANGE
int32 num_exceed_max_for_scaling[NUM_DETECTORS]
Definition: Granule.h:1087
int32 num_scans
Definition: Granule.h:749
int8 change_dc_restore[MAX_NUM_SCANS][NUM_EMISSIVE_BANDS][DETECTORS_PER_1KM_BAND]
Definition: Granule.h:1046
float tm[MODELMAX]
#define MODIS_W_TIME_INCORRECT
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
PGSt_SMF_status write_sds_rank2(int32 file_id, char *sds_name, char *dim_name1, char *dim_name2, int32 dim1, int32 dim2, char *datatype, void *data)
Definition: HDF_Lib.c:1062
Preprocess_Emiss_t PP_Emiss
Definition: Preprocess.h:176
#define TIMECODEASIZE
Definition: Metadata.c:59
#define DETECTORS_PER_500M_BAND
Definition: Granule.h:439
int32 num_moon_in_SVP_TEB_EV_data[NUM_DETECTORS]
Definition: Granule.h:1085
char doi_authority_attr_name[PGSd_MET_MAX_STRING_SET_L]
Definition: Metadata.h:110
#define DETECTORS_PER_1KM_BAND
Definition: Granule.h:438
void set_string_attr(char *field, char *value)
Definition: Metadata.c:1014
#define INSTRUMENTNAME_MACRO
Definition: Metadata.c:69
float32 deadSubframeDataPercent[NUM_HIGH_RESOLUTION_DETECTORS]
Definition: Metadata.h:150
int32 num_missing_scans
Definition: Granule.h:1077
int32 num_night_scans
Definition: Granule.h:759
#define L1B_EV_500M_FILE
Definition: FNames.h:70
uint32 total_pixels[NUM_BANDS]
Definition: Metadata.h:91
PGSt_SMF_status Get_Electronics_Status(int32 v_id, int32 num_scans, char *vname, char *fname, int16 *final_value, int16 *is_changed, boolean *no_valid_value)
Definition: Metadata.c:2555
int32 Extract_Line_Offset
Definition: Metadata.h:83
character(len=1000) if
Definition: names.f90:13
@ INDEX_L1B_250m
Definition: Granule.h:587
uint32 total_pixels[NUM_BANDS]
Definition: Granule.h:877
int32 num_day_scans
Definition: Granule.h:750
char PGE02_Version[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:738
#define LEADING_L1A_GRANULE
Definition: FNames.h:78
QA_Refl_t QA_refl
Definition: Granule.h:1099
#define GEOLOCATION_FILE
Definition: FNames.h:82
uint32 saturated_pixels[NUM_BANDS]
Definition: Granule.h:879
gringpointlatitude
Definition: sort_gring.py:36
int32 v_id
Definition: Granule.h:746
const int NUM_BANDS
#define MAX_PRODUCTIONHISTORY_SIZE
Definition: MetadataP.h:49
const int NUM_DETECTORS
#define L1B_EV_250M_FILE
Definition: FNames.h:69
void copy_string_attr(char *field, char *value)
Definition: Metadata.c:1162
int32 qapercent_missing_500m
Definition: Metadata.h:127
uint8 noise_T_vis
Definition: Granule.h:1053
float32 moonInSVPTEBDataPercent[NUM_DETECTORS]
Definition: Metadata.h:154
#define EMISSIVE_TABLES_FILE
Definition: FNames.h:75
void get_attr(char *field, void *value)
Definition: Metadata.c:850
int32 Extract_Pixel_Count
Definition: Metadata.h:82
uint32 bit_QA_flags_change
Definition: Granule.h:1091
@ BAND26
Definition: Granule.h:643
#define AQUA
Definition: Granule.h:550
float32 Earth_Sun_Dist
Definition: Granule.h:886
uint8 noise_T_mwir
Definition: Granule.h:1035
uint8 noise_T_bb_avg
Definition: Granule.h:1033
PGSt_SMF_status Write_Global_Metadata(L1B_Gran_Metadata_t *L1B_Gran_Meta, QA_Data_t *QA, lookup_tables_t *tables, int32 OBC_sd_id, boolean skip_night_hi_res)
Definition: Metadata.c:1849
gringpointlongitude
Definition: sort_gring.py:35
#define MODIS_F_READ_ERROR
int32 Extract_Line_Count
Definition: Granule.h:765
int32 refl_1km_qapercent_outofbound
Definition: Metadata.h:131
#define EV_1km_FRAMES
Definition: Granule.h:469
#define TRAILING_L1A_GRANULE
Definition: FNames.h:80
const int NUM_REFLECTIVE_BANDS
PGSt_SMF_status Gran_Meta_Cal(L1A_granule_t *L1A_Gran, L1B_granule_t *L1B_Gran, Preprocess_Data_t *PP, QA_Data_t *QA, L1B_Scan_Metadata_t *L1B_Scan_Meta, L1B_Gran_Metadata_t *L1B_Gran_Meta)
Definition: Metadata.c:1203
#define L1A_MISSING_ENG_PACKET
Definition: MetadataP.h:48
#define MCF_FILE_QKM
Definition: FNames.h:64
int32 qapercent_interpolated_emiss
Definition: Metadata.h:135
int32 Extract_Pixel_Offset
Definition: Granule.h:762
#define MECS_CORE
Definition: Metadata.c:60
@ INDEX_L1B_EV_250M_FILE
Definition: MetadataP.h:60
const int NUM_THERMISTORS
#define E_VECTOR_SIZE
Definition: Metadata.h:63
uint32 Bit_QA_Flags[MAX_NUM_SCANS]
Definition: L1B_Setup.h:73
#define NUM_HIGH_RESOLUTION_SUBFRAMES
Definition: Granule.h:426
char ReprocessingPlanned[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:736
endif() set(LIBS $
Definition: CMakeLists.txt:6
float32 sectorRotateDataPercent[NUM_DETECTORS]
Definition: Metadata.h:151
PGSt_SMF_status Get_Elec_Config_Status_Per_Gran(int32 v_id, int32 num_scans, uint32 *Elec_config_status, uint32 *Elec_config_change, uint32 *Elec_config_invalid_flag)
Definition: Metadata.c:2706
void SMF_ERROR(PGSt_SMF_code code, char *messagestring)
Definition: Granule.c:1345
int32 Extract_Line_Offset
Definition: Granule.h:764
#define EV_500m_FRAMES
Definition: Granule.h:471
a context in which it is NOT documented to do so subscript which cannot be easily calculated when extracting TONS attitude data from the Terra L0 files Corrected several defects in extraction of entrained ephemeris and and as HDF file for both the L1A and Geolocation enabling retrieval of South Polar DEM data Resolved Bug by changing to opent the geolocation file only after a successful read of the L1A and also by checking for fatal errors from not restoring C5 and to report how many of those high resolution values were water in the new WaterPresent SDS Added valid_range attribute to Land SeaMask Changed to bilinearly interpolate the geoid_height to remove artifacts at one degree lines Made corrections to const qualification of pointers allowed by new version of M API library Removed casts that are no longer for same not the geoid Corrected off by one error in calculation of high resolution offsets Corrected parsing of maneuver list configuration parameter Corrected to set Height SDS to fill values when geolocation when for elevation and land water mask
Definition: HISTORY.txt:114
int32 qapercent_outofbound_250m
Definition: Metadata.h:125
float32 missEVPercent[NUM_BANDS]
Definition: Metadata.h:88
int32 num_missing_data_in_scans[NUM_DETECTORS]
Definition: Granule.h:1079
int32 emiss_qapercent_outofbound
Definition: Metadata.h:134
float32 uncalibratedDataPercent[NUM_DETECTORS]
Definition: Metadata.h:158
int8 change_dc_restore_500m[MAX_NUM_SCANS][NUM_500M_BANDS][DETECTORS_PER_500M_BAND]
Definition: Granule.h:1058
float32 satEVPercent[NUM_BANDS]
Definition: Metadata.h:87
PGSt_integer version
Definition: MetadataP.h:54
#define NUM_HIGH_RESOLUTION_DETECTORS
Definition: Granule.h:425
@ INDEX_L1B_EV_1000M_FILE
Definition: MetadataP.h:62
int safe_strcat(char *buf, char *str, int buflen)
Definition: Granule.c:834
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
int8 Door_Screen_Configuration
Definition: Metadata.h:114
#define MODIS_F_NOK
#define L1B_EV_1000M_FILE
Definition: FNames.h:71
float32 missInScanDataPercent[NUM_DETECTORS]
Definition: Metadata.h:148
#define True
Definition: Granule.h:537
#define basename(s)
Definition: l0chunk_modis.c:29
int32 sd_id[NUM_L1B_EV_FILES]
Definition: Granule.h:859
#define MAX_NUM_SCANS
Definition: Granule.h:422
int32 num_dead_detector_EV_data[NUM_DETECTORS]
Definition: Granule.h:1080
uint32 missing_pixels[NUM_BANDS]
Definition: Granule.h:880
pgs_meta_t pgs_in
Definition: Metadata.c:71
uint8 noise_T_nir
Definition: Granule.h:1054
@ INDEX_L1B_1km
Definition: Granule.h:589
int32 qapercent_outofbound_500m
Definition: Metadata.h:128
char * hdfAttr
Definition: MetadataP.h:55
char ProcessingCenter[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:742
const char * str
Definition: l1c_msi.cpp:35
HISTORY txt for MOD_PR01(step one of PGE01) History follows the following convention needed due to new Aqua ReprocessingActual and the expected LUT revision number from PCF Changed to use PGE version for ProductionHistory Added Archive including ProcessingEnvironment Corrected handling of bad to resovle GSFcd02514 Changed to check staged LUT revision number versus the expected LUT revision number from thereby resolving defect report MODxl02056 This change also avoids the memory access violation reported in MODur00039 Changed the way output arrays were initialized with fill values
Definition: HISTORY.txt:162
#define AUTOMATICQUALITYFLAGEXPLANATION_MACRO
Definition: Metadata.c:67
float32 granule_averages[MAX_NUM_GRAN_AVERAGES]
Definition: Granule.h:1092
uint8 noise_T_lwir
Definition: Granule.h:1034
uint32 bit_QA_flags_last_value
Definition: Granule.h:1090
int32 num_night_scans
Definition: Metadata.h:76
#define ALGORITHMPACKAGENAME_MACRO
Definition: Metadata.c:65
int32 num_rsb_at_night_scans
Definition: Granule.h:1078
#define REFLECTIVE_TABLES_FILE
Definition: FNames.h:74
uint8 noise_T_mir_avg
Definition: Granule.h:1038
uint8 Thermal_Detector_Noise[NUM_EMISSIVE_BANDS][DETECTORS_PER_1KM_BAND]
Definition: Metadata.h:120
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
int32 num_dead_subframe_EV_data[NUM_HIGH_RESOLUTION_DETECTORS]
Definition: Granule.h:1081
int32 incomplete_scans
Definition: Metadata.h:77
PGSt_SMF_status Get_Elec_Config_Status(QA_Common_t *QA_common, int32 v_id, int32 num_scans, uint32 *Elec_config_status, uint32 *Elec_config_change)
Definition: Metadata.c:2929
float32 noBGDataPercent[NUM_DETECTORS]
Definition: Metadata.h:153
int32 L1A_Gran_sd_id
Definition: Metadata.h:71
uint8 Thermal_Detector_Relative_Response_Change[NUM_EMISSIVE_BANDS][DETECTORS_PER_1KM_BAND]
Definition: Metadata.h:122
int16 bad_data_flag[NUM_BANDS]
Definition: Granule.h:885
int8 fp_set_point_state[MAX_NUM_SCANS]
Definition: Preprocess.h:169
uint32 missing_pixels[NUM_BANDS]
Definition: Metadata.h:94
#define MAX_MCST_VERSION_BUFFER
Definition: L1B_Tables.h:353
int32 num_no_bg_DN_EV_data[NUM_DETECTORS]
Definition: Granule.h:1084
uint32 Elec_config_change[E_VECTOR_SIZE]
Definition: Metadata.h:144
int32 qapercent_interpolated_500m
Definition: Metadata.h:129
QA_Emiss_t QA_emiss
Definition: Granule.h:1098
#define NUM_REFLECTIVE_DETECTORS
Definition: Granule.h:427
float32 nightRSBPercent[NUM_DETECTORS]
Definition: Metadata.h:147
int32 qapercent_interpolated_250m
Definition: Metadata.h:126
int32 incomplete_scans
Definition: Granule.h:760
uint8 noise_T_mir1
Definition: Granule.h:1036
int32 qapercent_interpolated_refl_1km
Definition: Metadata.h:132
int32 sd_id
Definition: Granule.h:747
void copy_attr(char *field, void *value)
Definition: Metadata.c:1121
void get_string_attr(char *field, char *value)
Definition: Metadata.c:906
#define MAX_DATE_TIME_SIZE
Definition: Metadata.h:66
#define NUM_250M_BANDS
Definition: Granule.h:430
boolean missing_leading_granule
Definition: Granule.h:1070
int32 satellite_id
Definition: Granule.h:748
#define MODIS_F_HDF_ERROR
char doi_para_value[NUM_L1B_EV_FILES+1][PGSd_MET_MAX_STRING_SET_L]
Definition: Metadata.h:109
for(i=0;i< NROOTS;i++) s[i]
Definition: decode_rs.h:85
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
#define L1B_OBC_FILE
Definition: FNames.h:72
#define WRITE_BAND_26_SDS
Definition: Granule.h:937
int32 Extract_Pixel_Count
Definition: Granule.h:763
int8 change_dc_restore_1km[MAX_NUM_SCANS][NUM_1000M_REFL_BANDS][DETECTORS_PER_1KM_BAND]
Definition: Granule.h:1060
#define R
Definition: make_L3_v1.1.c:96
#define MECS_ARCH
Definition: Metadata.c:61
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
void set_attr(char *field, void *value)
Definition: Metadata.c:962
#define MODIS_F_FILE_NOT_OPENED
@ INDEX_L1B_500m
Definition: Granule.h:588
char * pgs_out_mdHandle
Definition: Metadata.c:72
GNU GENERAL PUBLIC LICENSE Version
Definition: LICENSE.txt:2
#define NUM_1000M_REFL_BANDS
Definition: Granule.h:432
int8 change_dc_restore_250m[MAX_NUM_SCANS][NUM_250M_BANDS][DETECTORS_PER_250M_BAND]
Definition: Granule.h:1056
#define MAX_NUM_GRAN_AVERAGES
Definition: Granule.h:706
@ NUM_OUTPUT_FILES
Definition: MetadataP.h:64
const int NUM_EMISSIVE_BANDS
PGSt_SMF_status read_vdata(int32 v_id, int32 start_record, int32 records, char *vname, char *fname, void *buffer)
Definition: HDF_Lib.c:748
int i
Definition: decode_rs.h:71
#define MODIS_F_INVALID_ARGUMENT
uint32 dead_detector_pixels[NUM_BANDS]
Definition: Granule.h:882
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
float32 exceedMaxForScalingPercent[NUM_DETECTORS]
Definition: Metadata.h:156
int32 Extract_Line_Count
Definition: Metadata.h:84
#define NADIRPOINTING_MACRO
Definition: Metadata.c:64
char ProcessingEnvironment[MAX_RUNTIME_PARAM_SIZE]
Definition: Granule.h:741
uint8 NEdL[NUM_EMISSIVE_DETECTORS]
Definition: Granule.h:1041
int8 All_L1B_Error_Flag_Off
Definition: Metadata.h:117
float32 deadDetectorDataPercent[NUM_DETECTORS]
Definition: Metadata.h:149
#define AUTOMATICQUALITYFLAG_MACRO
Definition: Metadata.c:66
char doi_authority_para_value[PGSd_MET_MAX_STRING_SET_L]
Definition: Metadata.h:111
#define DETECTORS_PER_250M_BAND
Definition: Granule.h:440
version
Definition: setup.py:15
uint32 negative_value_below_noise_pixels[NUM_BANDS]
Definition: Granule.h:884
#define False
Definition: Granule.h:538
#define CALIBRATIONQUALITY_MACRO
Definition: Metadata.c:63
#define EV_250m_FRAMES
Definition: Granule.h:470