ocssw  1.0
/disk01/web/ocssw/build/src/geogen_modis/GEO_locate_one_scan.c (r8087/r7924)
Go to the documentation of this file.
00001 #include "GEO_earth.h"
00002 #include "GEO_global_arrays.h"
00003 #include "GEO_input.h"
00004 #include "GEO_inst.h"
00005 #include "GEO_output.h"
00006 #include "GEO_validation.h"
00007 #include "PGS_MODIS_35251.h"
00008 
00009 /* sample time for all the pixels in a scan (relative to sector start time */
00010 double sample_time[MAX_PADDED];
00011 
00012 PGSt_SMF_status GEO_locate_one_scan(
00013         GEO_param_struct const  * const geo_params,
00014         l1a_data_struct     * const l1a_data,
00015         int         const scan_number,
00016         qa_metadata_struct  * const qa_metadata,
00017         GEO_bcoord_struct   * const bounding_coords,
00018         MODFILE         * const geo_file
00019 )
00020 /*****************************************************************************
00021 !C
00022 
00023 !Description:
00024     Routine in Output group of the Level-1A geolocation software to
00025     geolocate one scan and write to output file.  For each sample in a
00026     scan, it call routines to:  compute and validate the Earth locations
00027     for the pixels, and compute and validate the sensor and solar angles
00028     for the pixels.  It then calls the routine to write the data for the
00029     entire scan to the geolocation product file.
00030 
00031 !Input Parameters:
00032 
00033     geo_params  structure containing geolocation process parameters
00034             from the parameter file.
00035     scan_number the scan number
00036     geo_file    structure used to reference the geolocation file in 
00037                         the MAPI library
00038 
00039 !Output Parameters:
00040 
00041     qa_metadata structure for accumulating data quality measures
00042     bounding_coords structure of the granules bounding coordinates
00043 
00044 Input/Output Parameters:
00045     l1a_data    data read from L1A file.
00046 
00047 Return values:
00048     MODIS_E_BAD_INPUT_ARG   One of the input arguments had an invalid value
00049     MODIS_E_GEO     A subroutine failed.
00050     PGS_S_SUCCESS       Otherwise.
00051 
00052 Externally Defined:
00053     BAD_DATA                        "GEO_validation.h"
00054     DBL_MIN                         "float.h"
00055     DETECTORS_1KM                   "GEO_geo.h"
00056     DETECTORS_QKM                   "GEO_geo.h"
00057     GEO_DOUBLE_FILLVALUE            "GEO_output.h"
00058     GOOD_DATA                       "GEO_validation.h"
00059     INVALID_INPUT_DATA              "GEO_geo.h"
00060     INVALID_SOLAR_ANGLES            "GEO_geo.h"
00061     MAX_FRAMES                      "GEO_geo.h"
00062     MAX_PADDED                      "GEO_geo.h"
00063     MAX_SCAN_NUMBER                 "GEO_geo.h"
00064     MODIS_E_BAD_INPUT_ARG           "PGS_MODIS_35251.h"
00065     MODIS_E_GEO                     "PGS_MODIS_35251.h"
00066     NO_ELLIPSE_INTERSECT            "GEO_geo.h"
00067     SAMPLES_QKM                     "GEO_geo.h"
00068     sample_time                     "GEO_global_arrays.h"
00069     SUCCESS                         "GEO_basic.h"
00070     TIMECODEASIZE           "smfio.h"
00071 
00072     Note: sample_time has external linkage, but is to be defined in this
00073     module.
00074 
00075 Called by:
00076     GEO_locate_one_granule
00077 
00078 Routines called:
00079     GEO_aggregate                   "GEO_earth.h"
00080     GEO_cumulate_GRing      "GEO_input.h"
00081     GEO_derived_products        "GEO_output.h"
00082     GEO_earth_location      "GEO_earth.h"
00083     GEO_get_bounding_coords     "GEO_output.h"
00084     GEO_get_sample_time             "GEO_inst.h"
00085         GEO_interp_ECR                  "GEO_earth.h"
00086     GEO_validate_derived_products   "GEO_validation.h"
00087     GEO_validate_earth_location "GEO_validation.h"
00088     GEO_write_one_scan      "GEO_output.h"
00089     modsmf              "smfio.h"
00090 
00091 !Revision History:
00092 $Log: GEO_locate_one_scan.c,v $
00093 Revision 6.7  2011/02/18 21:59:34  kuyper
00094 In order to resolve feature-request Bug 3446, changed to retrieve landsea
00095   mask at high resolution, and then aggregate to low resolution, filling in
00096   new waterpresent array.
00097 
00098 Revision 6.6  2010/06/29 20:11:22  kuyper
00099 Declared many arrays static, solely to reduce strain on stack.
00100 
00101 Revision 6.5  2010/06/18 20:11:25  kuyper
00102 Corrected handling of int32 arguments passed to sprintf().
00103 
00104 Revision 6.4  2010/05/27 17:58:07  kuyper
00105 Helped resolve Bug 1969 by creating rpy, filling it in by calling
00106   GEO_interp_ECR(), and passing it to GEO_write_one_scan().
00107 Helped resolve Bug 2470 by removing a parameter.
00108 Helped resolve Bug 2472 by filling in, aggregating, and writing out
00109   the ephemeris and attitude quality flags, and passing the entire Geolocation
00110   parameters struct to GEO_interp_ECR().
00111 Resolved Bug 2949 by removing pointless and dangerous code.
00112 Stopped passing num_detectors as an argument to GEO_aggregate().
00113 Changed to return a status code.
00114 
00115 James Kuyper        James.R.Kuyper@NASA.gov
00116 
00117 Revision 6.3  2009/05/31 22:08:40  kuyper
00118 Corrected to initialize sample_flags.
00119 Corrected to use DETECTORS_1KM as loop limit.
00120 
00121 Revision 6.2  2009/05/30 23:32:12  kuyper
00122 Corrected definition of sample_time to be at file scope.
00123 Removed macros no longer referenced.
00124 Corrected to validate geo_file.
00125 Corrected frame->samp.
00126 Changed to pass l1b_data to GEO_earth_location(), rather than
00127   scan_start_time[scan_number]
00128 Corrected expected return value for GEO_validate_derived_products().
00129 
00130 Revision 6.1  2009/05/28 22:51:25  kuyper
00131 Changed to support both high-resolution and low-resolution data, connected
00132   by a call to GEO_aggregate.
00133 Changed most global arrays to local arrays.
00134 Moved definition and setting of sample_time global into this function.
00135 Moved definition and setting of parameter globals into GEO_earth_location().
00136 Corrected to cumulate gflags only after validation of derived products,
00137   resolving Bug 2199.
00138 Changed interface of most subroutines.
00139 Dropped qa_flag member of frame_state_struct.
00140 Improved error messaging.
00141 Removed sc_ev_frame_state argument from GEO_write_one_scan; long obsolete..
00142 
00143 James Kuyper Jr.    James.R.Kuyper@nasa.gov
00144 
00145 Revision 5.4  2006/01/27 17:19:06  kuyper
00146 Corrected to set impulse_flag to GOOD_DATA only if GEO_interp_ECR() call
00147   succeeds.
00148 
00149 Revision 5.3  2005/12/02 22:42:05  kuyper
00150 Corrected to write scan data that does not depend upon earth view start time,
00151   even if earth view start time is a fill value.
00152 
00153 Revision 5.2  2004/10/14 20:22:53  kuyper
00154 Changed to pass geo_params->sol_elev_cor to GEO_interp_ECR().
00155 
00156 Revision 5.1  2004/08/30 17:02:27  vlin
00157 1. input parameter maneuver_list added.
00158 2. Check for invalid EV start time.
00159 3. call to GEO_write_one_scan updated.
00160 
00161 Revision 4.8  2004/05/12 19:45:26  kuyper
00162 Corrected to initialize impulse flag with GOOD_DATA, where appropriate,
00163 rather than relying upon default initialization (which is not actually
00164 guaranteed to occur).
00165 
00166 Revision 4.7  2004/04/09 18:09:08  kuyper
00167 Corrected to make MODIS_E_GEO error from GEO_interp_ECR() non-fatal.
00168 
00169 Revision 4.6  2003/12/26 19:08:49  vlin
00170 Two functions added in "Routines called" section.
00171 
00172 Revision 4.5  2003/10/22 19:31:06  vlin
00173 Beef up message for invalid input argument(s).
00174 
00175 Revision 4.4  2003/08/26 19:31:53  kuyper
00176 Corrected test for INVALID_SOLAR_ANGLES bit.
00177 
00178 Revision 4.3  2003/08/22 22:08:49  kuyper
00179 Changed to give a T_sc2ecr work area to GEO_interp_ECR().
00180 
00181 Revision 4.2  2003/08/22 14:24:50  kuyper
00182 Moved in definition of T_inst2ecr.
00183 Corrected transfer of eulerAngles.
00184 
00185 Revision 4.1  2003/08/13 20:40:15  kuyper
00186 Added calls to GEO_get_sample_time() and GEO_interp_ECR().
00187 Changed interface of GEO_derived_products to process an entire scan in one
00188   call, requiring splitting of the frame loop.
00189 Moved the definitions of sample_to_sensor and sample_solar_angles into this
00190   module.
00191 Added code to move eulerangles to sc_attitude.
00192 
00193 5/23/95
00194 Frederick S. Patt (patt@modis-xl.gsfc.nasa.gov)
00195 Finished coding.
00196 
00197 Requirements:
00198     PR03-F-3.1.1-1
00199     PR03-F-3.1.1-2
00200     PR03-F-3.1.2-1
00201     PR03-F-3.1.2-2
00202     PR03-F-3.1.3-1
00203     PR03-F-3.1.4-1
00204     PR03-F-3.2.1-1
00205     PR03-F-3.2.1-2
00206     PR03-F-3.2.2-1
00207     PR03-F-3.2.3-1
00208     PR03-F-3.2.3-2
00209     PR03-F-3.2.4-1
00210     PR03-F-3.3.1-1
00211     PR03-F-3.3.2-1
00212     PR03-F-3.3.3-1
00213     PR03-F-3.3.3-2
00214     PR03-F-3.4.1-1
00215     PR03-F-3.4.2-1
00216     PR03-F-3.4.3-1
00217     PR03-F-3.4.4-1
00218     PR03-F-3.5.1-1
00219     PR03-F-3.5.2-1
00220     PR03-F-3.5.3-1
00221     PR03-F-3.5.3-2
00222     PR03-F-3.5.3-3
00223     PR03-F-3.6.1-1
00224     PR03-F-3.6.2-1
00225     PR03-F-3.6.3-1
00226     PR03-F-3.6.3-2
00227     PR03-F_4.2-1
00228     PR03-F_4.2-2
00229 
00230 
00231 !Team-unique Header:
00232 
00233     This software is developed by the MODIS Science Data Support
00234     Team for the National Aeronautics and Space Administration,
00235     Goddard Space Flight Center, under contract NAS5-32373.
00236 
00237 !END
00238 **************************************************************************/
00239 
00240 {
00241     frame_state_struct  sc_ev_frame_state[MAX_FRAMES] = {{0.0}};
00242     int         samp, frame, det;
00243     int                 missing_count, outofbounds_count; /* flag counters */
00244     uint32 mask;
00245 
00246     /* sample time relative to sector start time*/
00247     double frame_time[MAX_FRAMES];
00248 
00249     /* The largest of the following arrays are declared static, not so their
00250      * values can be retained from one call to the next, but to minimize
00251      * strain on stack.
00252      */
00253     /* pixel-to-satellite angles (azimuth, zenith), and range */
00254     static double frame_to_sensor[DETECTORS_1KM][MAX_FRAMES][3];
00255 
00256     /* solar azimuth and zenith angles for all the pixels in a scan */
00257     /* azimuth, zenith */
00258     static double frame_solar_angles[DETECTORS_1KM][MAX_FRAMES][2];
00259 
00260     /* instrument to ECR transformation */
00261     double T_inst2ecr[MAX_PADDED][3][3];
00262 
00263     /* ECR ground location */
00264     static double ecr_sample_position[DETECTORS_QKM][MAX_PADDED][3];
00265     static double ecr_frame_position[DETECTORS_1KM][MAX_FRAMES][3];
00266 
00267     /* terrain corrected position in geodetic coordinates:
00268      * latitude, longitude, height
00269      */
00270     static double terrain_sample_position[DETECTORS_QKM][MAX_PADDED][3];
00271     static double terrain_frame_position[DETECTORS_1KM][MAX_FRAMES][3];
00272 
00273     /* Land/Water mask, and WaterPresent  */
00274     uint8 sample_landsea[DETECTORS_QKM][MAX_PADDED];
00275     uint8 frame_landsea[DETECTORS_1KM][MAX_FRAMES];
00276     uint8 frame_waterpresent[DETECTORS_1KM][MAX_FRAMES];
00277     uint8 land_seamask_qaflag;
00278 
00279     /* geolocation flags */
00280     uint8 sample_flags[DETECTORS_QKM][MAX_PADDED]={0};
00281     static uint8 frame_flags[DETECTORS_1KM][MAX_FRAMES];
00282 
00283     /* spacecraft ECR position */
00284     double ecr_sc_sample_position[MAX_PADDED][3];
00285     double ecr_sc_frame_position[MAX_FRAMES][3];
00286 
00287     /* spacecraft ECR velocity */
00288     double ecr_sc_velocity[MAX_PADDED][3];
00289 
00290     sc_state_struct sc_state[MAX_PADDED];
00291     char        asciiUTC[TIMECODEASIZE];
00292     PGSt_SMF_status interp_ecr_status;
00293     static int8     hires_offsets[3][DETECTORS_QKM][SAMPLES_QKM];
00294     PGSt_double     offsets[MAX_PADDED];
00295     double      T_sc2ecr[MAX_PADDED][3][3];
00296     uint32      sample_quality[MAX_PADDED][2];
00297     uint32      frame_quality[2][MAX_FRAMES];
00298     PGSt_double     rpy[3] =
00299     {THERMCORR_FVALUE, THERMCORR_FVALUE, THERMCORR_FVALUE};
00300     int         N_samp;
00301     int         padded_samples;
00302     char        filefunc[] = __FILE__ ", GEO_locate_one_scan";
00303     char        msgbuf[PGS_SMF_MAX_MSGBUF_SIZE];
00304     PGSt_SMF_status retval = PGS_S_SUCCESS;
00305 
00306     if(geo_params == NULL || l1a_data == NULL || qa_metadata == NULL ||
00307     geo_file == NULL || scan_number < 0 || scan_number >= MAX_SCAN_NUMBER)
00308     {
00309         sprintf(msgbuf, "geo_params:%p, l1a_data:%p, \n"
00310                "qa_metadata:%p, geo_file:%p, scan_number:%d",
00311            (void *)geo_params, (void *)l1a_data, (void *)qa_metadata,
00312            (void*)geo_file, scan_number);
00313     modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
00314 
00315     return MODIS_E_BAD_INPUT_ARG;
00316     }
00317 
00318     l1a_data->mirr_data[scan_number].impulse_flag = BAD_DATA;
00319 
00320     if ((fabs(scan_start_time[scan_number]-
00321                  l1a_data->fill_values.EV_start_time) < DBL_MIN) 
00322         || (l1a_data->frame_data[scan_number].EV_frames < 0)
00323     || (l1a_data->frame_data[scan_number].EV_frames > MAX_FRAMES))
00324     {
00325        sprintf(msgbuf, "EV_start_time:%f EV_frames:%ld",
00326        scan_start_time[scan_number],
00327        (long)(l1a_data->frame_data[scan_number].EV_frames));
00328        modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
00329        l1a_data->frame_data[scan_number].EV_frames = 0;
00330        padded_samples = 0;
00331        interp_ecr_status = MODIS_E_BAD_INPUT_ARG;
00332     }
00333     else
00334     {
00335     N_samp = geo_params->geometry_params.N_samp
00336         [geo_params->geometry_params.band_number];
00337     padded_samples =
00338         (l1a_data->frame_data[scan_number].EV_frames + 1) * N_samp - 1;
00339 
00340     for (samp = 0; samp < padded_samples; samp++)
00341     {
00342         sample_time[samp] =
00343         GEO_get_sample_time(&geo_params->geometry_params, samp);
00344         if(sample_time[samp] >= GEO_DOUBLE_FILLVALUE)
00345         {
00346         sprintf(msgbuf, "GEO_get_sample_time(%d)", samp);
00347         modsmf(MODIS_E_GEO, msgbuf, filefunc);
00348 
00349         return MODIS_E_GEO;
00350         }
00351         offsets[samp] = (PGSt_double)sample_time[samp];
00352     }
00353 
00354     for(frame=0; frame<l1a_data->frame_data[scan_number].EV_frames; frame++)
00355         frame_time[frame] = sample_time[N_samp * (frame + 1) - 1];
00356 
00357     if(padded_samples < MAX_PADDED) /* Mark the end of the data. */
00358         sample_time[padded_samples] = GEO_DOUBLE_FILLVALUE;
00359 
00360     interp_ecr_status = GEO_interp_ECR(
00361         l1a_data->frame_data[scan_number].EV_start, padded_samples, offsets,
00362         geo_params, asciiUTC, sc_state, T_sc2ecr, T_inst2ecr,
00363         ecr_sc_sample_position, ecr_sc_velocity, rpy, sample_quality);
00364     if(interp_ecr_status !=  PGS_S_SUCCESS)
00365     {
00366         sprintf(msgbuf, "GEO_interp_ECR(%f, %d)",
00367         l1a_data->frame_data[scan_number].EV_start, padded_samples);
00368         modsmf(MODIS_E_GEO, msgbuf, filefunc);
00369 
00370         /* Most MODIS_E_GEO returns are for reasons that should be
00371          * non-fatal.
00372          */
00373         if(interp_ecr_status != MODIS_E_GEO)
00374         retval = MODIS_E_GEO;
00375     }
00376     else
00377         l1a_data->mirr_data[scan_number].impulse_flag = GOOD_DATA;
00378     }
00379 
00380     /* Loop on samples in scan */
00381 
00382     for (samp=0; samp<padded_samples; samp++)
00383     {
00384     if(interp_ecr_status != PGS_S_SUCCESS)
00385     {
00386         for (det = 0; det < geo_params->num_detectors; det++)
00387         sample_flags[det][samp] |= INVALID_INPUT_DATA;
00388     }
00389     else if (l1a_data->mirr_data[scan_number].impulse_flag == GOOD_DATA)
00390     {
00391          /* Perform Earth location */
00392 
00393         if(GEO_earth_location(scan_number, samp,
00394         (GEO_param_struct*)geo_params, sample_time[samp], l1a_data,
00395         ecr_sc_sample_position, ecr_sc_velocity, T_inst2ecr,
00396         sample_flags, ecr_sample_position, terrain_sample_position)
00397         != PGS_S_SUCCESS)
00398         {
00399         sprintf(msgbuf, "GEO_earth_location(%d, %d)",
00400             scan_number, frame);
00401         modsmf(MODIS_E_GEO, msgbuf, filefunc);
00402         for (det = 0; det < geo_params->num_detectors; det++)
00403             sample_flags[det][samp] |= INVALID_INPUT_DATA;
00404 
00405         retval = MODIS_E_GEO;
00406         }
00407 
00408         /* Validate Earth location */
00409         if (GEO_validate_earth_location(
00410         l1a_data->mirr_data[scan_number].impulse_flag,
00411         terrain_sample_position, samp, geo_params->num_detectors,
00412         sample_flags) != SUCCESS)
00413         {
00414         sprintf(msgbuf, "GEO_validate_earth_location(%d, %d)",
00415             scan_number, samp);
00416         modsmf(MODIS_E_GEO, msgbuf, filefunc);
00417 
00418         retval = MODIS_E_GEO;
00419         }
00420     }
00421 
00422     }  /* End of sample loop */
00423 
00424     if(interp_ecr_status == PGS_S_SUCCESS)
00425     {
00426     if(l1a_data->mirr_data[scan_number].impulse_flag!=GOOD_DATA)
00427         land_seamask_qaflag = 1;
00428     else
00429     {
00430         if(GEO_landsea_mask(padded_samples, geo_params->num_detectors,
00431         terrain_sample_position, sample_flags, &land_seamask_qaflag,
00432         sample_landsea) != PGS_S_SUCCESS)
00433         {
00434         sprintf(msgbuf, "GEO_landsea_mask(%d, %d) failed.\n",
00435             padded_samples, geo_params->num_detectors);
00436         modsmf(MODIS_E_GEO, msgbuf, filefunc);
00437 
00438         retval = MODIS_E_GEO;
00439         }
00440     }
00441 
00442     if(GEO_aggregate(l1a_data->frame_data[scan_number].EV_frames, N_samp,
00443         geo_params->hires_scale, sample_flags, ecr_sample_position,
00444         ecr_sc_sample_position, terrain_sample_position, sample_quality,
00445         sample_landsea, ecr_frame_position, terrain_frame_position,
00446         frame_flags, ecr_sc_frame_position, hires_offsets, frame_quality,
00447         frame_landsea, frame_waterpresent) != PGS_S_SUCCESS)
00448     {
00449         sprintf(msgbuf, "GEO_aggregate(%d, %ld, %d, %f)",
00450         geo_params->num_detectors,
00451         (long)l1a_data->frame_data[scan_number].EV_frames, N_samp,
00452         geo_params->hires_scale);
00453         modsmf(MODIS_E_GEO, msgbuf, filefunc);
00454 
00455         retval = MODIS_E_GEO;
00456     }
00457 
00458     if(GEO_derived_products(l1a_data->frame_data[scan_number].EV_frames,
00459         DETECTORS_1KM, ecr_frame_position, ecr_sc_frame_position,
00460         frame_flags, terrain_frame_position, asciiUTC, frame_time,
00461         frame_solar_angles, frame_to_sensor) != PGS_S_SUCCESS)
00462     {
00463         sprintf(msgbuf, "GEO_derived_products(%ld, %d, \"%s\")",
00464         (long)l1a_data->frame_data[scan_number].EV_frames,
00465         DETECTORS_1KM, asciiUTC);
00466         modsmf(MODIS_E_GEO, msgbuf, filefunc);
00467 
00468         retval = MODIS_E_GEO;
00469     }
00470 
00471     for(frame=0; frame<l1a_data->frame_data[scan_number].EV_frames; frame++)
00472     {
00473         int ecr;
00474 
00475         if((frame_flags[0][frame] & INVALID_SOLAR_ANGLES) == 0)
00476         {
00477         /* Validate derived products */
00478         if (GEO_validate_derived_products(frame, DETECTORS_1KM,
00479             geo_params->range_scale, frame_to_sensor, frame_flags)
00480             != PGS_S_SUCCESS)
00481         {
00482             sprintf(msgbuf, "GEO_validate_derived_products(%d, %d, %f)",
00483             frame, DETECTORS_1KM, geo_params->range_scale);
00484             modsmf(MODIS_E_GEO, msgbuf, filefunc);
00485 
00486             retval = MODIS_E_GEO;
00487         }
00488         }
00489 
00490         /* Update data quality measurments */
00491         missing_count = 0;
00492         outofbounds_count = 0;
00493         for (det = 0; det < DETECTORS_1KM; det++)
00494         {
00495         int bit;
00496 
00497         if ((frame_flags[det][frame] & INVALID_INPUT_DATA) != 0)
00498             missing_count++;
00499 
00500         if ((frame_flags[det][frame] & INVALID_INPUT_DATA) == 0 &&
00501             (frame_flags[det][frame] & NO_ELLIPSE_INTERSECT) != 0 )
00502             outofbounds_count++;
00503 
00504         for (mask=1, bit=0; bit<8; bit++, mask*=2)
00505         {
00506             if ((unsigned)frame_flags[det][frame] & mask)
00507             qa_metadata->cumulated_gflags[bit]++;
00508         }
00509         }
00510         qa_metadata->no_of_pixels += DETECTORS_1KM;
00511         qa_metadata->missingdata += missing_count;
00512         qa_metadata->outofboundsdata += outofbounds_count;
00513 
00514         /* Subsampled frame data. */
00515         samp = N_samp*(frame + 1) - 1;
00516     
00517         for (ecr = 0; ecr < 3; ecr++)
00518         {
00519         sc_ev_frame_state[frame].positionECR[ecr] =
00520             ecr_sc_sample_position[samp][ecr];
00521         sc_ev_frame_state[frame].velocityECR[ecr] =
00522             ecr_sc_velocity[samp][ecr];
00523         /* This array is ued only by GEO_cumulate_GRing(), and those
00524          * are the only two fields used by that function.
00525          */
00526         }
00527     }
00528     }
00529 
00530     /* Write one scan of geolocation data to file */
00531     if (GEO_write_one_scan(frame_time, scan_number, l1a_data, geo_params,
00532     frame_to_sensor, frame_solar_angles, terrain_frame_position,
00533     frame_flags, hires_offsets, rpy, frame_quality, frame_landsea,
00534     frame_waterpresent, land_seamask_qaflag, geo_file) != PGS_S_SUCCESS)
00535     {
00536     sprintf(msgbuf, "GEO_write_one_scan(%d, \"%s\")",
00537         scan_number, geo_file->filename);
00538     modsmf(MODIS_E_GEO, msgbuf, filefunc);
00539 
00540     retval = MODIS_E_GEO;
00541     }
00542 
00543     if(interp_ecr_status == PGS_S_SUCCESS)
00544     {
00545     if (GEO_cumulate_GRing(geo_params,
00546         l1a_data->frame_data[scan_number].EV_frames, sc_ev_frame_state,
00547         frame_flags, ecr_frame_position) != PGS_S_SUCCESS)
00548     {
00549         sprintf(msgbuf, "GEO_cumulate_GRing(%ld)",
00550         (long)l1a_data->frame_data[scan_number].EV_frames);
00551         modsmf(MODIS_E_GEO, msgbuf, filefunc);
00552 
00553         retval = MODIS_E_GEO;
00554     }
00555 
00556     if (GEO_get_bounding_coords(terrain_frame_position, frame_flags,
00557         DETECTORS_1KM,
00558         l1a_data->frame_data[scan_number].EV_frames, bounding_coords)
00559         != SUCCESS)
00560     {
00561         sprintf(msgbuf, "GEO_get_bounding_coords(%d, %ld)", DETECTORS_1KM,
00562         (long)l1a_data->frame_data[scan_number].EV_frames);
00563         modsmf(MODIS_E_GEO, msgbuf, filefunc);
00564 
00565         retval = MODIS_E_GEO;
00566     }
00567     }
00568   
00569     return retval;
00570 }
00571