ocssw  1.0
build/src/geogen_modis/GEO_write_granule_metadata.c (r10591/r7924)
Go to the documentation of this file.
00001 #include "PGS_TD.h"
00002 #include "GEO_earth.h"
00003 #include "GEO_output.h"
00004 #include "GEO_product.h"
00005 #include "PGS_MODIS_35251.h"
00006 #include "L1a_data.h"
00007 
00008 PGSt_SMF_status GEO_write_granule_metadata(
00009     MODFILE         * const geo_file,
00010     MODFILE         * const l1a_file,
00011     GEO_param_struct const  * const geo_parameter,
00012     GEO_bcoord_struct const * const bounding_coords,
00013     int         const version,
00014     l1a_data_struct     * const l1a_data,
00015     qa_metadata_struct  * const qa_metadata
00016 )
00017 
00018 /**********************************************************************
00019 !C 
00020 
00021 !Description:   
00022     Routine in Output group of the Level-1A geolocation software to write
00023     the granule-level metadata to the geolocation product file.
00024 
00025 !Input Parameters:
00026     geo_file    MAPI structure for geolocation file
00027     l1a_file    MAPI structure for Level 1A file
00028     geo_parameter   program parameters read from (or derived directly from)
00029             the geolocation parameter file
00030     bounding_coords the granule's bounding coordinates.
00031     version     version number of input/output files.
00032 
00033 !Output Parameters:
00034     None
00035 
00036 !Input/Output Parameters
00037     l1a_data    data read from L1A file
00038     qa_metadata Granule-level quality assurance metadata. Optional,
00039             can be null.
00040 
00041 Return Values:
00042     MODIS_E_GEO     If any subroutine fails.
00043     MODIS_E_GEO_EPH     If the ephemeris file contains an orbit number
00044                     that is inconsistent with the orbit time.
00045     MODIS_E_BAD_INPUT_ARG   If any pointer argument other than qa_metadata
00046                     is null.
00047     PGS_S_SUCCESS       Otherwise.
00048 
00049 Externally Defined:
00050     AVERAGE_TEMPERATURES        "GEO_product.h"
00051     FILL_INT8           "GEO_output.h"
00052     L1A_ENGINEERING_GRP     "L1a_data.h"
00053     MAPIOK              "mapi.h"
00054     MAX_SCAN_NUMBER         "GEO_geo.h"
00055     MODIS_E_BAD_INPUT_ARG       "PGS_MODIS_35251.h"
00056     MODIS_E_GEO         "PGS_MODIS_35251.h"
00057     MODIS_E_GEO_EPH                 "PGS_MODIS_35251.h"
00058     MODIS_W_GEO_EPHEMERIS       "PGS_MODIS_35251.h"
00059     MODIS_W_NO_GEO          "PGS_MODIS_35251.h"
00060     PGSd_EOS_AM         "PGS_TD.h"
00061     PGSd_EOS_PM         "PGS_TD.h"
00062     PGSd_PC_FILE_PATH_MAX           "PGS_PC.h"
00063     PGSd_PC_LINE_LENGTH_MAX     "PGS_PC.h"
00064     PGSEPH_E_NO_SC_EPHEM_FILE   "PGS_EPH.h"
00065     PGS_S_SUCCESS           "PGS_SMF.h"
00066     SUCCESS             "GEO_basic.h"
00067     TIMECODEASIZE           "smfio.h"
00068 
00069 Called by:
00070     GEO_locate_one_granule
00071 
00072 
00073 Routines Called:
00074     GEO_get_GRing_points        "GEO_earth.h"
00075     GEO_get_utcpole_metadata    "GEO_output.h"
00076     GEO_get_version_metadata    "GEO_output.h"
00077     GEO_update_L1A_metadata     "GEO_output.h"
00078     GEO_write_ECS_metadata      "GEO_output.h"
00079     GEO_write_geospecific_metadata  "GEO_output.h"
00080     GEO_write_input_metadata    "GEO_output.h"
00081     GEO_write_parameters        "GEO_output.h"
00082     modsmf              "smfio.h"
00083     PGS_EPH_GetEphMet       "PGS_EPH.h"
00084         PGS_TD_UTCtoTAI                 "PGS_TD_Prototypes.h"
00085     putMODIStable           "mapi.h"
00086     PGS_SMF_GenerateStatusReport    "PGS_SMF.h"
00087 
00088 
00089 !Revision History:
00090 $Log: GEO_write_granule_metadata.c,v $
00091 Revision 6.3  2010/06/30 21:28:26  kuyper
00092 Added casts of cumulated_gflags to a printable type.
00093 
00094 Revision 6.2  2010/06/18 20:57:58  kuyper
00095 Corrected format of LogReport message.
00096 
00097 Revision 6.1  2010/05/28 21:50:04  kuyper
00098 Helped resolve Bug 2470 by removing a parameter.
00099 Changed to return an SMF status code.
00100 Improved several error messages.
00101 Corrected sprintf() format codes for C90 compatibility.
00102 Improved const-safety.
00103 
00104 James Kuyper Jr.        James.R.Kuyper@NASA.gov
00105 
00106 Revision 5.6  2008/12/19 19:07:29  kuyper
00107 Corrected size of orbit_validation array.
00108 
00109 Revision 5.5  2008/12/15 21:12:59  kuyper
00110 Changed to make orbit number validation optional, controlled by a PCF
00111   parameter.
00112 
00113 Revision 5.4  2008/09/21 19:06:38  kuyper
00114 Increased size of message buffer to accomodate long path names.
00115 Changed to pass sc_tag to GEO_write_input_metadata().
00116 
00117 Revision 5.3  2005/10/05 16:51:09  vlin
00118 Code added to check for invalid Orbit Number from Ephemeris file.
00119 MOD_PR03 will fail if the orbit number is incorrect.
00120 vlin@saicmodis.com
00121 
00122 Revision 5.2  2004/10/15 22:03:17  kuyper
00123 Corrected position of bounding_coords parameter.
00124 
00125 Revision 5.1  2004/09/22 19:44:25  vlin
00126 Changed to pass bounding_coords to GEO_update_L1A_metadata().
00127 Added maneuver_list parameter, passed on to GEO_write_geospecific_metadata.
00128 Added a status report.    vlin@saicmodis.com
00129 
00130 Revision 4.5  2004/04/09 22:17:45  kuyper
00131 Changed FILL_BYTE to FILL_INT8.
00132 
00133 Revision 4.4  2004/01/23 21:40:35  vlin
00134 PGS_PC_GetUniversalReference not called and removed from prologue.
00135 
00136 Revision 4.3  2004/01/20 19:44:27  kuyper
00137 Corrected error messages.
00138 Added validity checks on file handles.
00139 
00140 Revision 4.2  2003/10/07 13:53:29  kuyper
00141 Corrected setting of equatorcrossingtime.
00142 
00143 Revision 4.1  2003/08/12 23:05:33  kuyper
00144 Corrected to identify l1a_data and qa_metadata as input/output.
00145 Added code to write the AverageTemperatures vdata record.
00146 Moved input pointer handling into GEO_write_input_metadata().
00147 Dropped code setting modisproductfilename.
00148 Simplified handling of orbitdescendtime.
00149 Changed to expect status codes from GEO_update_l1a_metadata() and
00150   GEO_write_ECS_metadata.
00151 Changed format for RMS error.
00152 
00153 Requirements:
00154       PR03-F-1-3
00155       PR03-F-1-3.1
00156       PR03-F-4.1-1
00157       PR03-F-4.1-1.6
00158       PR03-F-4.1-2
00159       PR03-I-1
00160       PR03-I-2
00161       PR03-S-1
00162 
00163       
00164 !Team-unique Header:
00165      This software is developed by the MODIS Science Data Support
00166      Team for the National Aeronautics and Space Administration,
00167      Goddard Space Flight Center, under contract NAS5-32373.
00168 
00169 !END
00170 *********************************************************************************/
00171 {
00172     static pointer_metadata_struct pointer_metadata;
00173 
00174     EPH_metadata_struct EPH_metadata={-1, -999.0*DEG2RAD, "", ""};
00175     GEO_GRing_struct GRing_points = {"N", {1, 2, 3, 4},
00176       {0.01, 0.01, 0.0,  0.0},  /* Latitude */
00177       {0.0,  0.01, 0.01, 0.0}   /* Longitude. */};
00178 
00179     utcpole_metadata_struct utcpole_metadata = {"", {0}};
00180     PGSt_double offset = 0.0;   /* offset from rangedatetime, seconds.*/
00181     PGSt_integer numOrbits=1;
00182     PGSt_tag sc_tag=PGSd_EOS_AM;
00183     int i;
00184     PGSt_SMF_status retval = PGS_S_SUCCESS;
00185     double pred_dtime; 
00186     char msgbuf[2*PGSd_PC_FILE_PATH_MAX];
00187     char orbitAscendTime[TIMECODEASIZE];
00188     char orbitdescendtime[TIMECODEASIZE];
00189     char rangedatetime[TIMECODEASIZE];
00190     char sci_abnorm[2]="1", sci_state[2]="1";
00191     PGSt_integer param_version=1;
00192     static char filefunc[] = __FILE__ ", GEO_write_granule_metadata";
00193     int rtcode;
00194 
00195     if (l1a_file==NULL || geo_file==NULL || l1a_data == NULL ||
00196     geo_parameter == NULL || bounding_coords == NULL)
00197     {
00198     sprintf(msgbuf, "l1a_file = %p, geo_file=%p, l1a_data = %p,\n"
00199             "geo_parameter = %p, bounding_coords=%p",
00200         (void*)l1a_file, (void*)geo_file, (void*)l1a_data,
00201         (void*)geo_parameter, (void*)bounding_coords);
00202     modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
00203 
00204     return MODIS_E_BAD_INPUT_ARG;
00205     }
00206 
00207     /* Read l1a_data.ECS_metadata and fill in uptcpole_metadata */
00208     if (GEO_get_utcpole_metadata(&(l1a_data->ECS_metadata), &utcpole_metadata)
00209     != PGS_S_SUCCESS) {
00210     modsmf(MODIS_E_GEO, "GEO_get_utcpole_metadata()", filefunc);
00211 
00212     retval = MODIS_E_GEO;
00213     }
00214 
00215     /* Write the geolocation geo_parameter's to the geolocation file*/
00216     if( SUCCESS != GEO_write_parameters(geo_file,
00217     (GEO_param_struct *)geo_parameter) )
00218     {
00219       sprintf(msgbuf, "GEO_write_parameters(\"%s\")", geo_file->filename);
00220       modsmf(MODIS_E_GEO, msgbuf, filefunc);
00221 
00222       retval = MODIS_E_GEO;
00223     }
00224 
00225     /* Calculate spatial metadata */
00226     rtcode = GEO_get_GRing_points(&GRing_points);
00227 
00228     /* Since the V2.1 GEO_get_GRing_points will return WARNING for several
00229      * 'sparse data' conditions (which are more likely to occur than the
00230      * functional failures) retval is set to FAIL only for a FAIL return.
00231      */
00232     if(rtcode != PGS_S_SUCCESS && rtcode != MODIS_W_NO_GEO)
00233     {
00234     modsmf(MODIS_E_GEO, "GEO_get_GRing_points()", filefunc);
00235 
00236     retval = MODIS_E_GEO;
00237     }
00238 
00239     sprintf(rangedatetime, "%.10sT%.15sZ",
00240     l1a_data->ECS_metadata.rangebeginningdate,
00241     l1a_data->ECS_metadata.rangebeginningtime);
00242     
00243     if(strncmp(geo_parameter->spacecraft_ID, "Terra", sizeof("Terra")) )
00244     {
00245     sc_tag = PGSd_EOS_PM;   /* Already validated; must be "Aqua" */
00246     param_version = 2;
00247     }
00248 
00249     rtcode = PGS_EPH_GetEphMet(sc_tag, 1, rangedatetime, &offset, &numOrbits,
00250     &EPH_metadata.orbitnumber, &orbitAscendTime, &orbitdescendtime,
00251     &EPH_metadata.equatorcrossinglongitude);
00252 
00253     if(rtcode != PGS_S_SUCCESS)
00254     {
00255     if(rtcode == PGSEPH_E_NO_SC_EPHEM_FILE)
00256         modsmf(MODIS_W_GEO_EPHEMERIS, rangedatetime, filefunc);
00257     else
00258     {
00259         sprintf(msgbuf, "PGS_EPH_GetEphMet(\"%s\")", rangedatetime);
00260         modsmf(MODIS_E_GEO, msgbuf, filefunc);
00261 
00262         retval = MODIS_E_GEO;
00263     }
00264     }
00265     else
00266     {
00267       static char orbit_validation[PGSd_PC_LINE_LENGTH_MAX];
00268       PGSt_double TAI_orbitdescendtime;
00269 
00270       if(orbit_validation[0] == '\0' && 
00271     (PGS_PC_GetConfigData(VALIDATE_ORBIT_NO_LUN, orbit_validation)
00272     != PGS_S_SUCCESS ||
00273     (strcmp(orbit_validation, "TRUE") && 
00274     strcmp(orbit_validation, "FALSE"))) )
00275       {
00276     sprintf(msgbuf, "PGS_PC_GetConfigData():\"%s\"", orbit_validation);
00277     modsmf(MODIS_E_GEO, msgbuf, filefunc);
00278     orbit_validation[0] = '\0';
00279       }
00280 
00281 
00282     /* Assumes that orbitdescendtime has the format of a UTC A time code:
00283      * "YYYY-MM-DDTHH:MM:SS.SSSSSSZ"
00284      */
00285       if (PGS_TD_UTCtoTAI(orbitdescendtime, &TAI_orbitdescendtime) !=
00286      PGS_S_SUCCESS)
00287       {
00288      sprintf(msgbuf, "PGS_TD_UTCtoTAI(\"%s\")", orbitdescendtime);
00289      modsmf(MODIS_E_GEO, msgbuf, filefunc);
00290 
00291      retval = MODIS_E_GEO;
00292       }
00293       else if(strcmp(orbit_validation, "TRUE")==0)
00294       {
00295     int step = (EPH_metadata.orbitnumber < 
00296            geo_parameter->orbit_valid_params.transition_orbit) ? 0 : 1;
00297     pred_dtime = geo_parameter->orbit_valid_params.descend_time_0[step] +
00298       geo_parameter->orbit_valid_params.period[step]*
00299       EPH_metadata.orbitnumber;
00300     if (abs(TAI_orbitdescendtime - pred_dtime) > 
00301            geo_parameter->orbit_valid_params.orbit_tolerance[step])
00302     {
00303       sprintf(msgbuf,". Orbit number = %d, orbit descend time = %s",
00304           EPH_metadata.orbitnumber, orbitdescendtime);
00305       modsmf(MODIS_E_GEO_EPH, msgbuf, filefunc);
00306 
00307       retval = MODIS_E_GEO_EPH;
00308     }
00309       }
00310 
00311       memcpy(EPH_metadata.equatorcrossingdate, orbitdescendtime, 10);
00312       EPH_metadata.equatorcrossingdate[10] = '\0';
00313       memcpy(EPH_metadata.equatorcrossingtime, orbitdescendtime+11, 15);
00314       EPH_metadata.equatorcrossingtime[15] = '\0';
00315     }
00316 
00317     if( GEO_update_L1A_metadata(l1a_file, &GRing_points, &EPH_metadata,
00318     (GEO_bcoord_struct *)bounding_coords) != PGS_S_SUCCESS)
00319     {
00320     sprintf(msgbuf, "GEO_update_L1A_metadata(%s)", l1a_file->filename);
00321     modsmf(MODIS_E_GEO, msgbuf, filefunc);
00322 
00323     retval = MODIS_E_GEO;
00324     }  
00325 
00326     if(GEO_write_input_metadata(geo_file, version, param_version,
00327     &pointer_metadata, sc_tag) != PGS_S_SUCCESS)
00328     {
00329     sprintf(msgbuf, "GEO_write_input_metadata(\"%s\", %ld, %ld )",
00330         geo_file->filename, (long)version, (long)param_version);
00331     modsmf(MODIS_E_GEO, msgbuf, filefunc);
00332 
00333     retval = MODIS_E_GEO;
00334     }
00335 
00336     /* Granule-level SCI_STATE and SCI_ABNORM */
00337     if (l1a_data->num_scans <= MAX_SCAN_NUMBER) /* array bounds protection */
00338     for(i=0; i<l1a_data->num_scans; i++)
00339     {
00340         if((l1a_data->frame_data[i].SCI_STATE!=1)
00341         && (l1a_data->frame_data[i].SCI_STATE != FILL_INT8) )
00342         sci_state[0] = '0';
00343     
00344         if((l1a_data->frame_data[i].SCI_ABNORM!=1)
00345         && (l1a_data->frame_data[i].SCI_ABNORM!= FILL_INT8) )
00346         sci_abnorm[0] = '0';
00347     }
00348     else
00349     sci_state[0] = sci_abnorm[0] = '0';
00350 
00351     if (qa_metadata)
00352     {
00353     sprintf(qa_metadata->rms_error,"%-8.3g", geo_parameter->RMS_error);
00354 
00355     if (retval != SUCCESS)
00356         qa_metadata->retval = retval;
00357     }
00358 
00359     if (GEO_get_version_metadata(&(l1a_data->ECS_metadata.version_metadata))
00360     != PGS_S_SUCCESS)
00361     {
00362     modsmf(MODIS_E_GEO, "GEO_get_version_metadata()", filefunc);
00363 
00364     retval = MODIS_E_GEO;
00365     }
00366 
00367     if(GEO_write_ECS_metadata(geo_file, &l1a_data->ECS_metadata, &EPH_metadata,
00368     (GEO_bcoord_struct *)bounding_coords, &GRing_points,
00369     &pointer_metadata, qa_metadata, sci_state, sci_abnorm) != PGS_S_SUCCESS)
00370     {
00371     sprintf(msgbuf, "GEO_write_ECS_metadata(\"%s\")", geo_file->filename);
00372     modsmf(MODIS_E_GEO, msgbuf, filefunc);
00373 
00374     retval = MODIS_E_GEO;
00375     }
00376 
00377     /* Write geolocation specific metadata */
00378     if(GEO_write_geospecific_metadata( geo_file, &l1a_data->granule_metadata,
00379     l1a_data->num_scans, geo_parameter, qa_metadata, &utcpole_metadata)
00380     != PGS_S_SUCCESS)
00381     {
00382     sprintf(msgbuf, "GEO_write_geospecific_metadata(\"%s\")",
00383         geo_file->filename);
00384     modsmf(MODIS_E_GEO, msgbuf, filefunc);
00385 
00386     retval = MODIS_E_GEO;
00387     }
00388 
00389     if(putMODIStable(geo_file, AVERAGE_TEMPERATURES, L1A_ENGINEERING_GRP,
00390     0, 1, (unsigned char*)l1a_data->temperatures) != MAPIOK)
00391     {
00392     modsmf(MODIS_E_GEO, "putMODIStable(\"" AVERAGE_TEMPERATURES "\")",
00393         filefunc);
00394 
00395     retval = MODIS_E_GEO;
00396     }
00397 
00398     /* Write to status report */
00399     sprintf(msgbuf,
00400     "Input file name: %s\n"
00401     "Output file name: %s\n"
00402     "Local Granule ID: %s\n"
00403     "scans: %d\n"
00404     "pixels: %d\n"
00405     "\tmissing: %d\n"
00406     "\tout of bounds: %d\n"
00407     "Cumulated gflags: %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu\n"
00408     "Bounding coordinates\n"
00409     "\teast: %f\n"
00410     "\twest: %f\n"
00411     "\tnorth: %f\n"
00412     "\tsouth: %f",
00413     l1a_file->filename, geo_file->filename,
00414     l1a_data->ECS_metadata.localinputgranuleid, l1a_data->num_scans,
00415     qa_metadata->no_of_pixels, qa_metadata->missingdata,
00416     qa_metadata->outofboundsdata,
00417     (unsigned long)qa_metadata->cumulated_gflags[0],
00418     (unsigned long)qa_metadata->cumulated_gflags[1],
00419     (unsigned long)qa_metadata->cumulated_gflags[2],
00420     (unsigned long)qa_metadata->cumulated_gflags[3],
00421     (unsigned long)qa_metadata->cumulated_gflags[4],
00422     (unsigned long)qa_metadata->cumulated_gflags[5],
00423     (unsigned long)qa_metadata->cumulated_gflags[6],
00424     (unsigned long)qa_metadata->cumulated_gflags[7],
00425     bounding_coords->eastcoord,
00426     bounding_coords->westcoord, bounding_coords->northcoord,
00427     bounding_coords->southcoord);
00428     PGS_SMF_GenerateStatusReport(msgbuf);
00429 
00430     return retval;
00431 }