ocssw  1.0
/disk01/web/ocssw/build/src/auto_qc/l1stat_chk/anal_noise.c (r8102/r2592)
Go to the documentation of this file.
00001 #include <string.h>
00002 #include <libgen.h>
00003 #include "l1stat.h"
00004 #include "l1stat_proto.h"
00005 extern int32 stat_status;
00006 
00007 void anal_noise( int32 rec, int32 nrec, int32 nscans, int32 nsamp, 
00008    int32 nbands, int16 *i16buf, int *spike_cnt, float *line_sd, 
00009    int32_t *cnt_coin_jmp, int32_t *jmp_hist )
00010 /*******************************************************************
00011 
00012    anal_noise
00013 
00014    purpose: check a buffer of level-1a data line by line and band by band
00015             to see if there is evidence of spike noise or an encrypted line
00016             only information is generated.  later, this will get combined
00017             with checks of other SDS data to evaluate the total noise
00018 
00019    Returns type: void - none
00020 
00021    Parameters: (in calling order)
00022       Type              Name            I/O     Description
00023       ----              ----            ---     -----------
00024       int32             rec              I      line # of this current 
00025                                                 batch of level-1a lines
00026       int32             nrec             I      # of lines in this array
00027       int32             nscans           I      total # scan lines
00028       int32             nsamp            I      # pixels per line
00029       int32             nbands           I      # of bands
00030       int16 *           i16buf           I      line by pixel by band
00031                                                 array of raw counts
00032       int *             spike_cnt        O      line by band array of
00033                                                 spike count 
00034       float *           line_sd          O      line by band array of
00035                                                 std deviation for line
00036       int32_t *            cnt_coin_jmp     O      size 8 count of co-incidences
00037                                                 (# times 1-8 bands for a 
00038                                                 pixel are on at once)
00039       int32_t *            jmp_hist         O      size 1024 histogram
00040                                                 of jump size
00041 
00042       access spike_cnt and line_sd to get band b, line l with
00043       index = b * nrec + l
00044 
00045    Modification history:
00046       Programmer        Date            Description of change
00047       ----------        ----            ---------------------
00048       W. Robinson       31-Jul-1998     Original development
00049 
00050 *******************************************************************/
00051   {
00052   int rec_num, irec, ibnd, ipix;
00053   short *spike_jmp, pixm1, pix, pixp1, isum;
00054   double apx, sum, sumsq, pix_jmp, sd;
00055   float jfact = 1.3;   /* 1.3 for HRPT, 5 for GAC?  It seems that GAC
00056                           and HRPT still get 'spikes' for good, cloud pix,
00057                           so usefullness may be limited at this time  */
00058   int32_t neighbor_diff;
00059 
00060   if( ( spike_jmp = (short *) malloc( nbands * nsamp * sizeof( short ) ) )
00061                 == NULL )
00062     {
00063     printf( "\n*****anal_noise: program error, unable to allocate space\n" );
00064     stat_status = stat_status | 1;
00065     }
00066   else
00067     {
00068    /*
00069     *  loop through the lines in this batch
00070     */
00071     rec_num = rec;
00072 
00073     for( irec = 0; irec < nrec; irec++, rec_num++ )
00074       {
00075       for( ibnd = 0; ibnd < nbands; ibnd++ )
00076         {
00077        /*
00078         *  Locate the spikes.  The general idea is to see if a pixel 
00079         *  is wildly different from it's next store neighbors
00080         *  a band-dependent minimum excursion will be imposed (to avoid
00081         *  classifying noise jumps as a spike) and a maximun
00082         *  neighbor change will also be imposed (to avois electronics
00083         *  overshoot points)
00084         */
00085         sum = 0.;
00086         sumsq = 0.;
00087         for( ipix = 1; ipix < ( nsamp - 1 ); ipix++ )
00088           {
00089           pixm1 = *( i16buf + ibnd + nbands * ( ( ipix - 1 ) + nsamp * irec ) );
00090           pix = *( i16buf + ibnd + nbands * ( ipix + nsamp * irec ) );
00091           pixp1 = *( i16buf + ibnd + nbands * ( ( ipix + 1 ) + nsamp * irec ) );
00092           neighbor_diff = fabs( pixm1 - pixp1 );
00093           pix_jmp = fabs( pix - ( pixm1 + pixp1 ) / 2. );
00094          /*
00095           * do not do points that have a large neighbor jump or a small
00096           * pixel jump
00097           */
00098 
00099           *( spike_jmp + ibnd + nbands * ipix ) = 0;
00100           if( pix_jmp > 15 && neighbor_diff < 200 )
00101             {
00102             if( pix_jmp > jfact * neighbor_diff )
00103               {
00104               (*( spike_cnt + ibnd + nbands * rec_num ) )++;
00105               *( spike_jmp + ibnd + nbands * ipix ) = pix_jmp;
00106              /*
00107               printf( "rec: %d, pix: %d, bnd: %d, jump: %f\n",
00108                  rec_num, ipix, ibnd, pix_jmp );
00109               */
00110               if( pix_jmp < 1024 )
00111               ( *( jmp_hist + (int) pix_jmp ) )++;
00112               }
00113             }
00114          /*
00115           *  accumulate the sum and sum square for the statistics
00116           */
00117           apx = (double) pix;
00118           sum += apx;
00119           sumsq += apx * apx;
00120           }  /* end pixel loop */
00121        /*
00122         *  compute the standard deviation for the line and band
00123         */
00124         sd = sumsq / nsamp - sum * sum / ( nsamp * nsamp );
00125         sd = ( sd > 0 ) ? sqrt( sd ) : 0.;
00126         *( line_sd + ibnd + nbands * ( rec_num ) ) = (float) sd;
00127        /*
00128         printf( "rec: %d, bnd: %d, sd: %f\n", irec, ibnd, sd );
00129         */
00130         }  /* end band loop */
00131      /*
00132       *  find frequency of pops occuring at same pixel
00133       */
00134       for( ipix = 1; ipix < nsamp - 1; ipix++ )
00135         {
00136         isum = 0;
00137         for( ibnd = 0; ibnd < nbands; ibnd++ )
00138           {
00139           if( *( spike_jmp + ibnd + nbands * ipix ) > 0 )
00140             isum++;
00141           }
00142         if( isum > 0 )
00143           {
00144          /*
00145           printf( "rec: %d, pix: %d, co-incident jumps: %d\n",
00146                 irec, ipix, isum );
00147           */
00148           (* ( cnt_coin_jmp + isum - 1 ) )++;
00149           }
00150         }
00151       }  /* end record loop */
00152    /*
00153     *  remove space for spike jumps
00154     */
00155     free( spike_jmp );
00156     }
00157   }