ocssw  1.0
/disk01/web/ocssw/build/src/geogen_modis/GEO_validate_orbit_data.c (r8218/r3)
Go to the documentation of this file.
00001 /* file: GEO_validate_orbit_data.c */
00002 
00003 #include "PGS_MODIS_35251.h"
00004 #include "GEO_util.h"
00005 #include "GEO_validation.h"
00006 #include "smfio.h"
00007 
00008 int GEO_validate_orbit_data(
00009     int const number_of_scans, 
00010     double sc_position[MAX_SCAN_NUMBER*2][3],
00011     double sc_velocity[MAX_SCAN_NUMBER*2][3], 
00012     double time_stamp[MAX_SCAN_NUMBER*2],
00013     int ancil_flags[MAX_SCAN_NUMBER*2]
00014     )
00015 {
00016 /*
00017 !C*****************************************************************************
00018 !Description:   
00019         Routine in Validation group of the Level-1A geolocation
00020                 software to validate the orbit data.  Validation is performed
00021         using the algorithms described in the white paper by F. Patt, 
00022         June 15, 1995.  Checks performed consist of:  absolute limit
00023         check on individual position and velocity components; limit 
00024         check on magnitudes of position and velocity vectors; sanity
00025         check on angular momentum magnitude and Z component; and 
00026         consistency check of successive position and velocity values
00027         for each component.
00028 
00029 !Input Parameters:
00030                 int number_of_scans - the number of scans
00031         double sc_position[MAX_SCAN_NUMBER*2][3] - position data
00032         double sc_velocity[MAX_SCAN_NUMBER*2][3] - velocity data
00033         double time_stamp[MAX_SCAN_NUMBER*2] - ancillary time stamp
00034         int ancil_flags[MAX_SCAN_NUMBER*2] - ancillary data flags
00035             
00036 !Output Parameters:
00037         int ancil_flags[MAX_SCAN_NUMBER*2] - ancillary data flags
00038 
00039 Return parameter:
00040                 int err_stat - error status
00041 
00042 Global variables:
00043         double position_abs_limit[2] - position absolute limits
00044         double velocity_abs_limit[2] - velocity absolute limits
00045         double position_mag_limit[2] - position magnitude limits
00046         double velocity_mag_limit[2] - velocity magnitude limits
00047         double ang_mom_limit[2] - angular momentum magnitude limits
00048         double ang_mom_z_limit[2] - angular momentum Z component limits
00049         double orbit_consistency - orbit position/velocity consistency
00050           limit
00051 
00052 Call functions:
00053         int GEO_abs_limit_check(double, int, double, int)
00054         int GEO_find_next_flag(int, int, int)
00055         int GEO_vec_mul3(double, double, double)
00056         GEO_vec_length3(double, double, double)
00057                 modsmf(MODIS_X_MNEMONIC_STRING, "user message string", "function,
00058                 GEO_validate_orbit_data.c") - writes error status messages to log
00059 
00060 !Revision History:
00061         $Log: GEO_validate_orbit_data.c,v $
00062         Revision 1.8  1997/07/21 16:24:34  kuyper
00063         Baselined Version 1
00064 
00065  * Revision 1.8  1997/03/26  18:16:22  fhliang
00066  * Initial revision of SDST delivery of GEO_validate_orbit_data.c.
00067  *
00068         Revision 1.7  1997/01/19 23:52:52  kuyper
00069         Merged seed files.
00070 
00071         Revision 1.6  1996/12/16 22:03:24  kuyper
00072         Initialized lflags twice, to satisfy pr:qa.
00073 
00074         Revision 1.5  1996/08/29 20:22:14  kuyper
00075         Corrected initialization of lflags.
00076 
00077         Revision 1.4  1996/07/29 15:41:57  kuyper
00078         Use GOOD_DATA/BAD_DATA for flags, rather than SUCCESS/FAIL-values unchanged.
00079 
00080         Revision 1.3  1996/07/24  21:44:29  kuyper
00081         Standardized order of #include files.
00082         Declared arguments const.
00083         Inserted required '!'s in comments.
00084         Removed ret_val.
00085         Change j1,j2 to f1,f2, to avoid shadowing.
00086         Converted constants to double, to skip implied conversion.
00087         Corrected final check on num_valid.
00088 
00089         Revision 1.2  1996/07/18 21:23:04  kuyper
00090         Included self-checking header file.
00091         Replaced extern declarations with corresponding header files.
00092         Quick fix to GEO_abs_limit_check parameter mismatch; proper fix requires
00093         re-write of that function.
00094 
00095 
00096         6/19/95
00097         Frederick S. Patt (patt@modis-xl.gsfc.nasa.gov)
00098         Finished coding.
00099 
00100         7/3/95
00101         Tracey W. Holmes (holmes@modis-xl.gsfc.nasa.gov)
00102         Added SDP error messages.
00103 
00104         10/10/95
00105         Tracey W. Holmes
00106         Added DEBUG option.
00107 
00108 !Team-unique Header:
00109                 This software is developed by the MODIS Science Data Support
00110                 Team for the National Aeronautics and Space Administration,
00111                 Goddard Space Flight Center, under contract NAS5-32373.
00112 
00113 !END*************************************************************************
00114 */
00115 
00116 /* Local variable declarations */
00117 
00118   int i = 0; /* loop index */
00119   int j = 0; /* loop index */
00120   int f1 = 0; /* valid data index */
00121   int f2 = 0; /* valid data index */
00122   int num_samples = 0; /* number of samples */
00123   int num_valid = 0; /* number of valid samples */
00124   int valid = FALSE; /* valid pair found flag */
00125   double del = 0.0; /* orbit consistency measurement */
00126   int lflags[MAX_SCAN_NUMBER*2][3]={0}; /* local flag array */ 
00127   double pos_mag[MAX_SCAN_NUMBER*2]; /* position magnitude array */
00128   double vel_mag[MAX_SCAN_NUMBER*2]; /* velocity magnitude array */
00129   double ang_mom[3]; /* angular momentum vector */
00130   double ang_mom_mag[MAX_SCAN_NUMBER*2];/* angular momentum magnitude */
00131   double ang_mom_z[MAX_SCAN_NUMBER*2];/* angular momentum Z component */
00132 
00133   for(i=0; i<MAX_SCAN_NUMBER*2; i++)
00134   {
00135     for(j=0; j<3; j++)
00136       lflags[i][j] = GOOD_DATA;
00137   }
00138 
00139   /* Begin program logic */
00140   num_samples = number_of_scans * 2;
00141 
00142   /* Position absolute limit check */
00143   if (GEO_abs_limit_check(sc_position[0], num_samples*3, position_abs_limit,
00144       lflags[0]) == FAIL) {
00145     /* call SDP function to report error */
00146     modsmf(MODIS_E_NO_VAL_POS_SAMP, "",
00147     "GEO_abs_limit_check, GEO_validate_orbit_data.c");
00148 
00149     return FAIL;
00150   }
00151 
00152   /* Velocity absolute limit check */
00153   if (GEO_abs_limit_check(sc_velocity[0], num_samples*3, velocity_abs_limit,
00154       lflags[0]) == FAIL) {
00155     /* call SDP function to report error */
00156     modsmf(MODIS_E_NO_VAL_VEL_SAMP, "",
00157     "GEO_abs_limit_check, GEO_validate_orbit_data.c");
00158 
00159     return FAIL;
00160   }
00161 
00162   /* Transfer flags to output array */
00163   for (i = 0; i < num_samples; i++)
00164     if ((lflags[i][0] == BAD_DATA) || (lflags[i][1] == BAD_DATA) ||  
00165       (lflags[i][2] == BAD_DATA))
00166     ancil_flags[i] = BAD_DATA;
00167 
00168 
00169   /* Vector magnitude limit checks */
00170   for (i = 0; i < num_samples; i++) {
00171     GEO_vec_length3(sc_position[i], &pos_mag[i]);
00172     GEO_vec_length3(sc_velocity[i], &vel_mag[i]);
00173   }
00174   
00175   /* Position magnitude */
00176   if (GEO_abs_limit_check(pos_mag, num_samples, position_mag_limit, ancil_flags)
00177       == FAIL) {
00178     /* call SDP function to report error */
00179     modsmf(MODIS_E_NO_VAL_POS_SAMP, "",
00180     "GEO_abs_limit_check, GEO_validate_orbit_data.c");
00181 
00182     return FAIL;
00183   }
00184 
00185   /* Velocity magnitude */
00186   if (GEO_abs_limit_check(vel_mag, num_samples, velocity_mag_limit, ancil_flags)
00187       == FAIL) {
00188     /* call SDP function to report error */
00189     modsmf(MODIS_E_NO_VAL_VEL_SAMP, "",
00190     "GEO_abs_limit_check, GEO_validate_orbit_data.c");
00191 
00192     return FAIL;
00193   }
00194 
00195   /* Angular momentum sanity check */
00196   for (i = 0; i < num_samples; i++) {
00197     GEO_vec_mul3(sc_position[i], sc_velocity[i], ang_mom);
00198     GEO_vec_length3(ang_mom, &ang_mom_mag[i]);
00199     ang_mom_z[i] = ang_mom[2];
00200   }
00201 
00202   if (GEO_abs_limit_check(ang_mom_mag, num_samples, ang_mom_limit, ancil_flags)
00203       == FAIL) {
00204     /* call SDP function to report error */
00205     modsmf(MODIS_E_NO_VAL_ORB_SAMP, "",
00206     "GEO_abs_limit_check, GEO_validate_orbit_data.c");
00207     
00208     return FAIL;
00209   }
00210 
00211   if (GEO_abs_limit_check(ang_mom_z, num_samples, ang_mom_z_limit, ancil_flags)
00212       == FAIL) {
00213     /* call SDP function to report error */
00214     modsmf(MODIS_E_NO_VAL_ORB_SAMP, "",
00215     "GEO_abs_limit_check, GEO_validate_orbit_data.c");
00216     
00217     return FAIL;
00218   }
00219   /* End of angular momentum sanity check */
00220 
00221   /* Position/velocity consistency check */
00222   /* Loop through x, y, z */
00223   for (j = 0; j < 3; j++) {
00224    
00225     /* Check for at least two unflagged samples */
00226     f1 = GEO_find_next_flag(ancil_flags, num_samples, 0);  
00227     if ((f2 = GEO_find_next_flag(ancil_flags, num_samples, f1+1))
00228     == FAIL) {
00229       /* call SDP function to report error */
00230       modsmf(MODIS_E_ONE_UNFLAG, "",
00231       "GEO_find_next_flag, GEO_validate_orbit_data.c");
00232 
00233       return SUCCESS;
00234     }
00235 
00236   
00237     /* Check all unflagged samples */
00238     valid = FALSE;
00239     num_valid = 0;
00240     while (f2 != FAIL) {
00241 
00242       /* First find a valid pair */
00243       while ((f2 != FAIL) && (valid == FALSE)) {
00244 
00245     /* Compute position/velocity consistency difference */
00246     del = fabs(sc_position[f2][j] - sc_position[f1][j] - 
00247            (sc_velocity[f2][j] + sc_velocity[f1][j])*
00248            (time_stamp[f2] - time_stamp[f1])/2.0);
00249     if (del <= orbit_consistency) {
00250       num_valid += 2;
00251       valid = TRUE;
00252     }
00253     else {
00254       ancil_flags[f1] = BAD_DATA;
00255     }
00256     f1 = f2;
00257     f2 = GEO_find_next_flag(ancil_flags, num_samples, f2+1);
00258       }
00259       
00260       /* Now check remaining unflagged samples in array */
00261       while ((f2 != FAIL) && (valid == TRUE)) {
00262 
00263     /* Compute position/velocity consistency difference */
00264     del = fabs(sc_position[f2][j] - sc_position[f1][j] - 
00265            (sc_velocity[f2][j] + sc_velocity[f1][j])*
00266            (time_stamp[f2] - time_stamp[f1])/2.0);
00267     if (del > orbit_consistency) {
00268       ancil_flags[f2] = BAD_DATA;
00269       valid = FALSE;
00270     }
00271     else {
00272       num_valid += 1;
00273     }
00274     f1 = f2;
00275     f2 = GEO_find_next_flag(ancil_flags, num_samples, f2+1);
00276       }
00277 
00278       /* If not at end of array, move forward one sample */
00279       if (f2 != FAIL) {
00280     f1 = f2;
00281     f2 = GEO_find_next_flag(ancil_flags, num_samples, f2+1);
00282       }
00283     }
00284   } /* End of vector component loop */
00285 
00286   /* If no valid pairs found, return FAIL */
00287   if (num_valid == 0) {
00288 
00289     /* call SDP function to report error */
00290     modsmf(MODIS_E_NO_VAL_ORB_SAMP, "",
00291     "GEO_validate_orbit_data, GEO_validate_orbit_data.c");
00292 
00293     return FAIL;
00294   }
00295 
00296   return SUCCESS;
00297 }