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