ocssw  1.0
/disk01/web/ocssw/build/src/libseawifs/l1a.c (r8218/r4879)
Go to the documentation of this file.
00001 /*
00002 
00003 $Header: /app/shared/RCS/irix-5.2/seawifsd/src/hdfio/L1A.V4.5/l1a.c,v 4.18 1996/01/17 16:53:52 seawifsd Exp seawifsd $
00004 $Log: l1a.c,v $
00005 Revision 4.18  1996/01/17 16:53:52  seawifsd
00006 added ON_TIME()/OFF_TIME() to report execution elapse time.
00007 
00008 Revision 4.17  1995/12/19 14:51:04  seawifsd
00009 fixed bug in testing main program. The bug only occurs when
00010 L1B HDF file was not created(specified). Fixes are done to
00011 use the fid of L1A HDF file instead of that of L1B.
00012 
00013 Revision 4.16  1995/12/07 19:21:01  seawifsd
00014 dded support to compile with calibration and straylight correction routines.
00015 added snode,enode,startclat,startclon,endclat,endclon and
00016 made it IO_SPEC_V4.4 and PROD_SPEC_V2.8 compliant.
00017 added l2_flags, checked and set HIGHLT1 flag. Created additional
00018 SDS to store L1B data in the test main program.
00019 
00020 Revision 4.15  1995/05/12 13:53:00  seawifsd
00021 1. code conformed to specifications IO_SPEC_V43, PROD_SPEC_V27,
00022 and NONPROD_SPEC_V12(no funtionality changes, just eliminate
00023 code related to versions before IO_SPEC_V42)
00024 
00025 Revision 4.14  1995/05/04 15:28:24  seawifsd
00026 changed all references to 'exist.h' to 'generic.h'.
00027 
00028 Revision 4.13  1995/04/03 16:06:36  seawifsd
00029 modified testing part of the l1a.c for more consistent and accurate output.
00030 
00031 Revision 4.12  1995/02/15 18:51:23  seawifsd
00032 added additional code to implement the objects 'scsol_z', 'entry_year',
00033 'entry_day', and 'csol_z'.
00034 renamed macro  LAKSHMI to EXTRA_FOR_BROWSE.
00035 specifically declared the datatype of fid[] and fid2[].
00036 added an optional third command parameter <skip> in the testing
00037 main program to indicate number of scan line to skip in displaying
00038 l1a science data. Corresponding print statements were revised to
00039 add this support and the support of TRANSPOSE_IMAGE macro.
00040 
00041 Revision 4.11  1995/01/27 18:20:33  seawifsd
00042 changed the order of mirror from mirror[bands][sides] to mirror[sides][bands]
00043 
00044 Revision 4.10  1995/01/17 20:03:18  seawifsd
00045 Jan. 17, 1994 V4.1
00046 
00047 Revision 4.2  1995/01/17 14:34:50  seawifsd
00048 added calling FORTRAN cdata_() before geonav_() because the changes
00049 in MOPS geonav.f code.
00050 
00051 Revision 4.1  1995/01/17 14:15:37  seawifsd
00052 Jan. 9, 1994, 4.0
00053 
00054 Revision 3.6  1994/12/15 16:06:42  seawifsd
00055 code conformed to IO_SPEC_V41, PROD_SPEC_V24 and NONPROD_SPEC_V10(no
00056 changes were needed from IO_SPEC_V40)
00057 
00058 Revision 3.5  1994/12/15 16:04:57  seawifsd
00059 made sure that the pointers passed into the i/o routines in the test
00060 main program are all null by declaring as static.
00061 
00062 Revision 3.4  1994/12/06 19:31:41  seawifsd
00063 made the code comformed to IO_SPEC_V40 and PROD_SPEC_V24.
00064 elliminated all references to IO_SPEC_V10 and related features under that
00065 version.
00066 made the L1A image data to be pixel interlaced(to fit the spec.) instead
00067 of the original band interlaced.(by define TRANSPOSE_IMAGE in wifs_conf.h)
00068 
00069 Revision 3.3  1994/11/08 18:45:55  seawifsd
00070 Nov. 8, 1994, 3.3a3
00071 
00072 Revision 3.3  1994/11/08 15:03:53  seawifsd
00073 Nov. 8, 1994, 3.3a2
00074 
00075 Revision 1.1.1.5  1994/11/03 20:24:00  frank
00076 renamed MIN macro to MINV.
00077 
00078 Revision 1.1.1.4  1994/11/01 16:02:28  frank
00079 added processing of 'meta_l1a.infiles' because of the new requirement
00080 from L1A Browse routines.
00081 
00082 Revision 1.1.1.3  1994/10/21 19:43:51  frank
00083 turned off some message printing by using PRINTF instead of printf.
00084 
00085 Revision 1.1.1.2  1994/10/05 20:14:01  frank
00086 1. updated L1A source code to fit the specification of the
00087 "SeaWiFS OPERATIONAL ARCHIVE PRODUCT SPECIFICATIONS" v 1.0, 07/22/94,
00088 and the "INTERFACE SPECIFICATIONS FOR SeaWiFS OPERATIONAL PRODUCT
00089 INPUT, OUTPUT, AND SENSOR CALIBRATION SOFTWARE" v 3.3 07/12/94
00090 
00091 Revision 1.1.1.1  1994/05/23 19:04:43  frank
00092 variables ptr_orb_vec, ptr_l_vert, ptr_sun_ref, ptr_att_ang, ptr_sen_mat,
00093 ptr_scan_ell, ptr_nflag, nsta, ninc, and npix are declared as PRIVATE(static)
00094 'int32_t *longptr' was added in get_l1a_record() routine and used as the
00095 lhs to nav.nflag so that to match the prototype.
00096 
00097 Revision 1.2  1994/05/10 18:44:37  seawifst
00098 May 6, 1994 version 1.2
00099 
00100 Revision 1.1  1994/04/19 13:23:38  seawifst
00101 Initial revision
00102 
00103 Removed all code that was only compiled when GENERAL, USE_STRUCT,
00104 or TESTCODE were defined. (687 lines of code removed.)
00105 Norman Kuring       6-Nov-1996
00106 
00107 Added code to handle "Calibration" Vgroup data.
00108 Norman Kuring       6-Nov-1996
00109 
00110 Removed all code that was only compiled when EVERYTHING was defined.
00111 Removed non-prototype style function definitions.
00112 Norman Kuring       7-Nov-1996
00113 
00114 Put back all of the GENERAL and EVERYTHING code.  Heavy sigh.
00115 Norman Kuring       25-Nov-1996
00116 
00117 fix values of l1a_data and geoloc when stray light processing is done.
00118 W. Robinson  3-Apr-1997
00119 
00120 W. Robinson , GSC, 20 Mar 98  update the dark restore calculation to filter
00121 unreasonable values and to take the median
00122  */
00123 
00124 
00125 #include    <stdio.h>
00126 #include    <string.h>
00127 #include <stdlib.h>
00128 /* for ceil used in STRAY_LIGHT_COEF macro */
00129 #include    <math.h>
00130 
00131 #include    "hdf.h"
00132 #include    "hdfhdr.h"
00133 #include    "hdfmac.h"
00134 #include    "usrhdr.h"
00135 #include    "usrmac.h"
00136 
00137 #include    "generic.h"
00138 
00139 #include    "ffm.h"
00140 #include    "cdl_object.h"
00141 #include    "hdf_object.h"
00142 #include    "SeaWiFS.h"
00143 #include    "navigation.h"
00144 #include    "l1a.h"
00145 #include    "level_1a_index.h"
00146 
00147 #include    "datatype.h"
00148 #include    "tlm.h"
00149 #include    "l1a_proto.h"
00150 
00151 /* prototype for get_WIFSinfo() */
00152 #include    "WIFSHDF.h"
00153 
00154 /* stray light */
00155 #include    "st_lt.h"
00156 #include    "cal_l1a.h"
00157 #include    "get_cal.h"
00158 #ifndef NO_SET_HIGHLT1
00159 #include    "l2_flags.h"
00160 #endif /* !NO_SET_HIGHLT1 */
00161 
00162 /* cpp_processing_start_here_please_do_not_delete_this_line */
00163 
00164 /* Make following as default in all future release(040194)      */
00165 
00166 
00167 #define FIRST_GET_L1A_OPEN  1
00168 
00169 #ifndef DEFAULT_BUFFER_BLKSIZE
00170 #define DEFAULT_BUFFER_BLKSIZE  10
00171 #endif
00172 
00173 #define BLKSIZE_NOT_CHANGED 0
00174 #define BLKSIZE_CHANGED     1
00175 
00176 PRIVATE int fid[MAX_HDF_L1AGET];
00177 
00178 /*
00179    Following are for get_l1a_record routine to keep track of:
00180    1. current access record number
00181    2. total record number
00182  */
00183 
00184 /* blocksize(in term of record) for each read access on each file   */
00185 PRIVATE int blksize[MAX_HDF_L1AGET];
00186 
00187 /* start record number for the biginning of the block. If       */
00188 /* blksize[prod_ID]=1, blksrec[prod_ID] is equal to crec[prod_ID]   */
00189 PRIVATE int blksrec[MAX_HDF_L1AGET];
00190 
00191 /* flag is set if blksize for the prod_ID is changed            */
00192 PRIVATE int blksize_changed[MAX_HDF_L1AGET];
00193 
00194 #define CLEAR   0
00195 #define INIT    1
00196 #define RECORDS 2
00197 
00198 #ifndef NO_SET_HIGHLT1
00199 #define FIRST_KNEE  1
00200 /* this global variable is in the code with calibrate_l1a()     */
00201 extern float32  cal_counts[BANDS_DIMS_1A][GAINS_DIMS_1A][KNEES_DIMS_1A];
00202 extern  float32 cal_rads[BANDS_DIMS_1A][GAINS_DIMS_1A][KNEES_DIMS_1A];
00203 
00204 /* global storage space for BAND 8 gain value to be used in stray_light */
00205 short   gain8;
00206 
00207 #endif /* !NO_SET_HIGHLT1 */
00208 
00209 /* buffer space to save flag values for stray-light/out-of-band     */
00210 /* correction and ltyp_frac for each L1A file               */
00211 PRIVATE char    *cal_table_file[MAX_HDF_L1AGET];
00212 PRIVATE short   stray_light_flag[MAX_HDF_L1AGET];
00213 #define STRAY_LIGHT_COMPLETE    0
00214 #define STRAY_LIGHT_LATE_START  1
00215 #define STRAY_LIGHT_EARLY_STOP  2
00216 #define STRAY_LIGHT_RANDOM  4
00217 PRIVATE short   stray_light_calling_flag[MAX_HDF_L1AGET];
00218 PRIVATE short   stray_light_scan_no[MAX_HDF_L1AGET];
00219 PRIVATE float   ltyp_frac_coef[MAX_HDF_L1AGET];
00220 PRIVATE short   out_band_flag[MAX_HDF_L1AGET];
00221 PRIVATE short   recursive_flag[MAX_HDF_L1AGET];
00222 PRIVATE short   recursive_free;
00223 #define PIX_SUB_V   4.0
00224 #define GAC_STRAY_LIGHT_COEF(v) (ceil(roundingup = v/PIX_SUB_V))
00225 #define LAC_STRAY_LIGHT_COEF(v) (v)
00226 #define STRAY_LIGHT_COEF(v,dtyp)    (strcmp(dtyp,"GAC")?LAC_STRAY_LIGHT_COEF(v):GAC_STRAY_LIGHT_COEF(v))
00227 
00228 #define NTRY_WARNING    5
00229 #define NTRY_LIMIT  20
00230 
00231 
00232 #ifdef L1A_INIT_NEEDED
00233 
00234 #ifdef PROTOTYPE
00235 PRIVATE void init(void)
00236 #else
00237 PRIVATE void init()
00238 #endif
00239 {
00240     char    *FUNC = "l1a_init";
00241     int i,j;
00242 
00243     ON_TIME();
00244     /* invalidate all fids                      */
00245     for(i=0; i < MAX_HDF_L1AGET; i++) {
00246         fid[i] = -1;
00247         blksize_changed[i] = BLKSIZE_NOT_CHANGED;
00248         blksize[i] = DEFAULT_BUFFER_BLKSIZE;
00249         /* set to zero, indicate no call to get_l1a_record yet  */
00250         blksrec[i] = 0;
00251         cal_table_file[i] = NULL;
00252         stray_light_flag[i] = 0;
00253         ltyp_frac_coef[i] = 0.0;
00254         out_band_flag[i] = 0;
00255         recursive_flag[i] = FALSE;
00256         recursive_free = 0;
00257         stray_light_calling_flag[i] = STRAY_LIGHT_COMPLETE;
00258         stray_light_scan_no[i] = 1;
00259     }
00260     OFF_TIME();
00261 }
00262 
00263 #endif // L1A_INIT_NEEDED
00264 
00265 /*------------------------------------------------------------------------------
00266 
00267     calculate the mean and standard deviation of the 8 bands of 
00268     dark-restore values for each band
00269     W. Robinson, GSC, 18 Mar 98  change dark computation to filter
00270         dark values <5, > 35 and then find the median on the remainder
00271         Note routines d_stats, i16comp and d_sd are a part of this now
00272 
00273 ------------------------------------------------------------------------------*/
00274 #ifdef PROTOTPE
00275 int dark_rest_stat(int16 *data, int nrec, float *dark_mean, float *dark_std)
00276 #else
00277 int dark_rest_stat(data, nrec, dark_mean, dark_std)
00278   int16     *data;                  /* 8 bands of dark restore data */
00279   int       nrec;                   /* number of scan lines */
00280   float     *dark_mean;             /* 8 bands of dark restore mean values */
00281   float     *dark_std;              /* 8 bands of dark restore std values */
00282 #endif
00283 {
00284   int16 *dark_f;
00285   int32 num_out, bad, i, j;
00286   void d_stats( int32, int16 *, float *, float * );
00287  /*
00288   *  filter the dark values first
00289   */
00290   dark_f = malloc( nrec * 8 * sizeof( int16 ) );
00291 
00292   num_out = 0;
00293  /*
00294   *  loop over the lines
00295   */
00296   for( i = 0; i < nrec; i++ )
00297     {
00298    /*
00299     *  any band with dark count outside the limit will disqualify the line
00300     */
00301     bad = 0;
00302     for( j = 0; j < 8; j++ )
00303       {
00304       if( *( data + i * 8 + j ) < 5 || *( data + i * 8 + j ) > 35 )
00305         {
00306         bad = 1;
00307         }
00308       }
00309     if( bad == 0 )
00310       {
00311       for( j = 0; j < 8; j++ )
00312         {
00313         *( dark_f + num_out * 8 + j ) = *( data + i * 8 + j );
00314         }
00315       num_out++;
00316       }
00317     }
00318  /*
00319   *  get the stats 
00320   */
00321   d_stats( num_out, dark_f, dark_mean, dark_std );
00322   free( dark_f );
00323   return 0;
00324   }
00325 
00326 
00327 void d_stats( int32 num, int16 *arr, float *median, float *sd )
00328 /*******************************************************************
00329 
00330    d_stats
00331 
00332    purpose: get the statistics on the dark restore: median and sd
00333         around it
00334 
00335    Returns type: void , none
00336 
00337    Parameters: (in calling order)
00338       Type              Name            I/O     Description
00339       ----              ----            ---     -----------
00340       int32             num             I       number of points
00341       int16 *           arr             I       dark restores for bands 1 - 8
00342                                                 channel is fastest dim
00343       float *           median          O       returned median
00344       float *           sd              O       std deviation around the median
00345 
00346    Modification history:
00347       Programmer        Date            Description of change
00348       ----------        ----            ---------------------
00349       W. Robinson       18-Mar-1998     Original development
00350 
00351       B. Franz          03-Jul-2003     Don't free what you don't malloc (s_arr)
00352 
00353 *******************************************************************/
00354   {
00355   int i16comp( int16 *, int16 * );
00356   void d_sd( int32, int16 *, float *, float * );
00357   int i, j;
00358   int16 *s_arr;
00359 
00360  /*
00361   *  for median, we need to sort the values using system function
00362   *  qsort.  We'll sort each band and then collect the median
00363   */
00364   if( num < 1 )
00365     {
00366     for( i = 0; i < 8; i++ )
00367       {
00368       *( median + i ) = 20;
00369       }
00370     }
00371   else
00372     {
00373     s_arr = malloc( num * sizeof( int16 ) );
00374     for( i = 0; i < 8; i++ )
00375       {
00376       for( j = 0; j < num; j++ )
00377         {
00378         *( s_arr + j ) = *( arr + j * 8 + i );
00379         }
00380       qsort( s_arr, num, sizeof( int16 ),
00381               (int (*)(const void*,const void*))i16comp );
00382      /*
00383       *  get the median
00384       */
00385       *( median + i ) = s_arr[ num / 2 ];
00386       }
00387       free( s_arr );
00388     }
00389  /*
00390   * then get the standard deviation around the mean
00391   */
00392   d_sd( num, arr, median, sd );
00393   }
00394 
00395 int i16comp( int16 *p1, int16 *p2 )
00396 /***********************************************************************
00397    routine called with qsort to sort the i*16 values
00398 *******************************************************************/
00399   {
00400   return *p1 - *p2;
00401   }
00402 
00403 void d_sd( int32 num, int16 *arr, float *mean, float *sd )
00404 /*******************************************************************
00405 
00406    d_sd
00407 
00408    purpose: get the standard deviation around the mean
00409 
00410    Returns type: void, no return
00411 
00412    Parameters: (in calling order)
00413       Type              Name            I/O     Description
00414       ----              ----            ---     -----------
00415       int32             num             I       # of values to get sd for
00416       int16 *           arr             I       array of dark values, 8
00417                                                 band by num lines
00418       float *           mean            I       size 8 bands mean to 
00419                                                 compute sd around
00420       float *           sd              O       returned sd in 8 bands
00421 
00422 
00423    Modification history:
00424       Programmer        Date            Description of change
00425       ----------        ----            ---------------------
00426       W. Robinson       18-Mar-1998     Original development
00427 
00428 *******************************************************************/
00429   {
00430   double tmp;
00431   int i, j;
00432 
00433  /* zero out the sd */
00434   for( j = 0; j < 8; j++ )
00435     *( sd + j ) = 0;
00436 
00437   if( num >= 2 )
00438     {
00439     for( i = 0; i < num; i++ )
00440       {
00441       for( j = 0; j < 8; j++ )
00442         {
00443         tmp = mean[j] - *( arr + i * 8 + j );
00444         *( sd + j ) += tmp * tmp;
00445         }
00446       }
00447     for( j = 0; j < 8; j++ )
00448       {
00449       *( sd + j ) = sqrt( *( sd + j ) / ( num - 1 ) );
00450       }
00451     }
00452   }
00453