ocssw  1.0
/disk01/web/ocssw/build/src/l2gen/l1a_seawifs.c (r8218/r4879)
Go to the documentation of this file.
00001 #include "hdf.h"
00002 #include "mfhdf.h"
00003 #include "l1a.h"
00004 #include "navigation.h"
00005 #include "l1a_proto.h"
00006 #include "eng_qual.h"
00007 #include "l12_proto.h"
00008 #include "l1a_seawifs.h"
00009 #include "call1a_proto.h"
00010 #include "getcal_proto.h"
00011 #include "st_proto.h"
00012 #include "hdf_utils.h"
00013 
00014 #define   LAC_PIXEL_NUM           1285
00015 #define   GAC_PIXEL_NUM           248
00016 #define   NREC_IN_BUF             10
00017 #define   STBUFSIZ                5
00018 #define   NOTDONE                 0
00019 #define   FIRST_KNEE              1
00020 #define   MASK_HIGHLT1            16
00021 #define   GENBUFSIZ               NREC_IN_BUF*sizeof(float)*40 /* size of inst_ana */
00022 
00023 static int evalmask;
00024 
00025 int16   syear, sday;       /* data start date                  */
00026 int32   smsec;             /* data start time                  */
00027 int16   eyear, eday;       /* data end date                    */
00028 int32   emsec;             /* data end time                    */
00029 int32   nscan;             /* number of scans                  */
00030 int32   npix;              /* number pixels per scan           */
00031 int32   spix;              /* start pixel number (from 0)      */
00032 int32   dpix;              /* LAC pixel increment              */
00033 float   dark_mean[8];      /* Mean of dark restore counts      */
00034 float   dark_std[8];       /* Std dev  of dark restore counts  */
00035 
00036 int16   tdi[BANDS_DIMS_1A] = {0,0,0,0,0,0,0,0};
00037 
00038 int16           entry_year;
00039 int16           entry_day;
00040 int16           ref_year;
00041 int16           ref_day;
00042 int16           ref_minute;
00043 float32         fp_temps[256][BANDS_DIMS_1A];
00044 float32         scan_mod[2][1285];
00045 float32         counts[BANDS_DIMS_1A][GAINS_DIMS_1A][KNEES_DIMS_1A];
00046 float32         rads[BANDS_DIMS_1A][GAINS_DIMS_1A][KNEES_DIMS_1A];
00047 
00048 float64         t_const[BANDS_DIMS_1A];
00049 float64         t_linear_1[BANDS_DIMS_1A];
00050 float64         t_exponential_1[BANDS_DIMS_1A];
00051 float64         t_linear_2[BANDS_DIMS_1A];
00052 float64         t_exponential_2[BANDS_DIMS_1A];
00053 float64         cal_offs[BANDS_DIMS_1A];
00054 float64         inst_tcorr[BANDS_DIMS_1A];
00055 float64         inst_tref[BANDS_DIMS_1A];
00056 float64         fp_tcorr[BANDS_DIMS_1A];
00057 float64         fp_tref[BANDS_DIMS_1A];
00058 float64         ms1_const[BANDS_DIMS_1A];
00059 float64         ms1_linear_1[BANDS_DIMS_1A];
00060 float64         ms1_exponential_1[BANDS_DIMS_1A];
00061 float64         ms1_linear_2[BANDS_DIMS_1A];
00062 float64         ms1_exponential_2[BANDS_DIMS_1A];
00063 float64         ms2_const[BANDS_DIMS_1A];
00064 float64         ms2_linear_1[BANDS_DIMS_1A];
00065 float64         ms2_exponential_1[BANDS_DIMS_1A];
00066 float64         ms2_linear_2[BANDS_DIMS_1A];
00067 float64         ms2_exponential_2[BANDS_DIMS_1A];
00068 
00069 char            cal_path_tab[128];
00070 char            dtype[8];
00071 
00072 extern float32 cal_counts[BANDS_DIMS_1A][GAINS_DIMS_1A][KNEES_DIMS_1A];
00073 extern float32 cal_rads[BANDS_DIMS_1A][GAINS_DIMS_1A][KNEES_DIMS_1A];
00074 
00075 
00076 float32 pcal_counts[BANDS_DIMS_1A][GAINS_DIMS_1A][KNEES_DIMS_1A];
00077 float32 pcal_rads[BANDS_DIMS_1A][GAINS_DIMS_1A][KNEES_DIMS_1A];
00078 short l2_flags_buffer[LAC_PIXEL_NUM];
00079 
00080 int32           nsta;
00081 int32           ninc;
00082 
00083 int16   *l1a_data     = NULL;  /* raw radiances band-int-by-pix    */
00084 int16   *l1a_back     = NULL;  /* raw radiances band-int-by-pix    */
00085 float   *l1b_buffer   = NULL;  /* l1b radiances band-int-by-pix    */
00086 int32   *msec;
00087 int16   *side;
00088 int16   *dark_rest;
00089 float32 *tilt;
00090 
00091 float32 ylat[LAC_PIXEL_NUM];
00092 float32 xlon[LAC_PIXEL_NUM];
00093 float32 solz[LAC_PIXEL_NUM];
00094 float32 sola[LAC_PIXEL_NUM];
00095 float32 senz[LAC_PIXEL_NUM];
00096 float32 sena[LAC_PIXEL_NUM];
00097 
00098 
00099 int16   stray_light = -1;     /* num pixels to apply sl correct.  */
00100 float   Ltyp_frac   = 0.25;   /* fraction of B8 for sl threshold  */
00101 int16   out_band    = 0;      /* if <= 0, no out of band correct. */
00102 
00103 
00104 typedef struct {
00105   int16   gain[8];
00106   int16   tdi[8];
00107   int16   scan_temp[8];
00108   float32 inst_temp[40];
00109   float32 orb_vec[3];
00110   float32 sun_ref[3];
00111   float32 sen_mat[3*3];
00112   float32 scan_ell[6];
00113 } inputBuffer;
00114 
00115 
00116 int32 do_st = 1;
00117 
00118 
00119 int32 get_l1a_rec(int32 sd_id, int32 recno, cal_mod_struc *cal_mod,
00120           int16 *l1a_dum, float32 **l1b_data, int16 **l2_flags)
00121 {
00122 
00123     int32   status = 0;
00124 
00125     /*                                                                 */
00126     /* local vars                                                      */
00127     /*                                                                 */
00128     int32   ipix;                  /* pixel number                     */
00129     int32   idet;                  /* detector number                  */
00130     int32   irec;
00131     int32   start[3]={0,0,0};
00132     int32   edges[3];
00133 
00134     int16   band_buf[LAC_PIXEL_NUM * 8];
00135     int32   scan_no;
00136     int16   gain8;
00137     int32   AS_pixels;
00138     float   Styp_frac = 0.9;
00139     int32   sl_scan;
00140     int16   *l1a_ptr;
00141     int16   *gain_ptr;
00142 
00143     static inputBuffer rdBuf[NREC_IN_BUF];
00144     static inputBuffer bkBuf[STBUFSIZ-2];
00145     byte   genBuf[GENBUFSIZ];
00146 
00147     static int32 crec = -1;
00148     static int16 recursive_flag = 0;
00149     static int16 n_read = 0;
00150     static int32 max_rec_in_rdbuf;
00151     static int32 offset;
00152     static int32 i,j;
00153     static int32 stray_light_scan_no;
00154 
00155     static float *st_l1b_data;
00156     static int16 *st_l2_flags;
00157 
00158     static int32 initial = 1;
00159     static byte  first = 1;
00160 
00161 
00162     static int16 hi_Lt[LAC_PIXEL_NUM];  /* whether radiance > knee */
00163     int   pixvalue;/* l1a pixel value           */
00164     int   pixdark;/* dark_restore value for each pixel  */
00165     float kneevalue; /* radiance at first knee      */
00166 
00167     /*                                                                 */
00168     /* Read L1A data scan by scan, build L1B record, and write.        */
00169 
00170     /* If reading out-of-sequence, force restart from beginning to get stlight */
00171     /* baf, 05-oct-2001.                                                       */
00172     if (first || recno < crec) {
00173       max_rec_in_rdbuf = recno - 1;
00174       stray_light_scan_no = recno;
00175     }
00176 
00177     crec = recno;
00178 
00179     if (crec > nscan) return 0;
00180 
00181 
00182     if (crec > max_rec_in_rdbuf) {
00183 
00184       memcpy(&bkBuf, &rdBuf[NREC_IN_BUF - STBUFSIZ + 2], 
00185          sizeof(inputBuffer) * (STBUFSIZ - 2));
00186       memcpy(l1a_back, &l1a_data[(NREC_IN_BUF - STBUFSIZ + 2)*npix*8], 
00187          npix * 8 * (STBUFSIZ - 2) * sizeof(int16));
00188 
00189       n_read = (nscan - max_rec_in_rdbuf >= NREC_IN_BUF) ? 
00190     NREC_IN_BUF : nscan - max_rec_in_rdbuf;
00191 
00192 
00193       edges[0] = 1;
00194       start[1] = 0;
00195       edges[1] = npix;
00196       edges[2] = 8;
00197       for (irec=0;irec<n_read;irec++) {
00198     start[0] = recno-1 + irec;
00199     status = SDreaddata(SDselect(sd_id, SDnametoindex(sd_id,"l1a_data")), 
00200                 start, NULL, edges, (VOIDP) band_buf);
00201     for (ipix=0;ipix<npix;ipix++)
00202       for (idet=0;idet<8;idet++) 
00203         l1a_data[irec*(8*npix)+idet*npix+ipix] = 
00204           band_buf[ipix*8+idet];
00205       }
00206 
00207 
00208       status = rdSDS(sd_id,"gain",recno-1,0,n_read,8,(VOIDP) genBuf);
00209       for (i=0;i<n_read;i++) 
00210     memcpy(&rdBuf[i].gain,&genBuf[i*8*2],8*2);
00211  
00212       status = rdSDS(sd_id,"tdi",recno-1,0,n_read,8,(VOIDP) genBuf);
00213       for (i=0;i<n_read;i++) 
00214     memcpy(&rdBuf[i].tdi,&genBuf[i*8*2],8*2);
00215 
00216       status = rdSDS(sd_id,"scan_temp",recno-1,0,n_read,8,(VOIDP) genBuf); 
00217       for (i=0;i<n_read;i++) 
00218     memcpy(&rdBuf[i].scan_temp,&genBuf[i*8*2],8*2);
00219 
00220       status = rdSDS(sd_id,"inst_ana",recno-1,0,n_read,40,(VOIDP) genBuf); 
00221       for (i=0;i<n_read;i++)
00222         memcpy(&rdBuf[i].inst_temp,&genBuf[i*40*4],40*4);
00223 
00224       status = rdSDS(sd_id,"orb_vec",recno-1,0,n_read,3,(VOIDP) genBuf); 
00225       for (i=0;i<n_read;i++) 
00226     memcpy(&rdBuf[i].orb_vec,&genBuf[i*3*4],3*4);
00227 
00228       status = rdSDS(sd_id,"sun_ref",recno-1,0,n_read,3,(VOIDP) genBuf); 
00229       for (i=0;i<n_read;i++) 
00230     memcpy(&rdBuf[i].sun_ref,&genBuf[i*3*4],3*4);
00231 
00232       status = rdSDS(sd_id,"scan_ell",recno-1,0,n_read,6,(VOIDP) genBuf); 
00233       for (i=0;i<n_read;i++) 
00234     memcpy(&rdBuf[i].scan_ell,&genBuf[i*6*4],6*4);
00235 
00236 
00237       start[0] = recno-1;
00238       edges[0] = n_read;
00239       start[1] = 0;
00240       edges[1] = 3;
00241       edges[2] = 3;
00242       status = SDreaddata(SDselect(sd_id, SDnametoindex(sd_id,"sen_mat")), 
00243               start, NULL, edges, (VOIDP) genBuf);
00244       for (i=0;i<n_read;i++) 
00245     memcpy(&rdBuf[i].sen_mat,&genBuf[i*9*4],9*4);
00246 
00247 
00248       offset = max_rec_in_rdbuf + 1;
00249       max_rec_in_rdbuf += n_read;
00250     }
00251 
00252     if ((crec - offset) >= 0) {
00253       j = crec - offset;
00254       gain8 = rdBuf[j].gain[7];
00255       gain_ptr = rdBuf[j].gain;
00256       l1a_ptr = &l1a_data[j*8*npix];
00257 
00258       status = l1b_rad(syear,sday,smsec,msec[recno-1],
00259             dtype, nsta, ninc, npix, 
00260             dark_mean, rdBuf[j].gain, rdBuf[j].tdi, 
00261             rdBuf[j].scan_temp, rdBuf[j].inst_temp, side[recno-1],
00262             &l1a_data[j*8*npix], l1b_buffer, cal_mod);
00263 /*
00264           calibrate_l1a(cal_path_tab,syear,sday,smsec,eday,msec[recno-1],
00265             dtype, nsta, ninc, npix, 
00266             dark_mean, rdBuf[j].gain, rdBuf[j].tdi, 
00267             rdBuf[j].scan_temp, rdBuf[j].inst_temp, side[recno-1],
00268             &l1a_data[j*8*npix], l1b_buffer, cal_mod);
00269 */
00270 
00271       if (!recursive_flag) {
00272     geonav_(rdBuf[j].orb_vec,rdBuf[j].sen_mat,rdBuf[j].scan_ell,
00273         rdBuf[j].sun_ref,&nsta,&ninc,&npix,
00274         ylat,xlon,solz,sola,senz,sena);
00275 
00276       }
00277     }   else {
00278       j = (STBUFSIZ - 2) + (crec - offset);
00279       gain8 = bkBuf[j].gain[7];
00280       gain_ptr = bkBuf[j].gain;
00281       l1a_ptr = &l1a_back[j*8*npix];
00282 
00283       if (!recursive_flag) { 
00284     geonav_(bkBuf[j].orb_vec,bkBuf[j].sen_mat,bkBuf[j].scan_ell,
00285         bkBuf[j].sun_ref,&nsta,&ninc,&npix,
00286         ylat,xlon,solz,sola,senz,sena);
00287 
00288       }
00289     }
00290 
00291     if (first) {
00292       memcpy(pcal_counts,cal_counts,sizeof(cal_counts));
00293       memcpy(pcal_rads,cal_rads,sizeof(cal_rads));
00294       first = 0;
00295     }
00296 
00297     if (!recursive_flag) {
00298       for (ipix=0; ipix < npix ; ipix++) {
00299     hi_Lt[ipix] = FALSE;
00300         /* HILT check limited to bands 7 & 8, BAF, 23 Jan 2002 */
00301         /* Use dark_mean rather than dark_rest, BAF, 7 July 2003 */
00302     for(idet=6;(idet<8)&&(hi_Lt[ipix] == FALSE);idet++) {
00303       pixvalue = l1a_ptr[ipix + npix * idet];
00304       /*
00305       pixdark = dark_rest[8*(recno-1)+idet];
00306       */
00307       pixdark = dark_mean[idet];
00308       kneevalue = pcal_counts[idet][gain_ptr[idet]][FIRST_KNEE];
00309       hi_Lt[ipix] = ((pixvalue - pixdark) >= kneevalue);
00310     }
00311       }
00312     }
00313 
00314 
00315     scan_no = crec;
00316     AS_pixels = stray_light;
00317 
00318     if (do_st == 0) {
00319 
00320       for (ipix=0; ipix < npix ; ipix++) 
00321           l2_flags_buffer[ipix] = 0;
00322 
00323     } else if (!recursive_flag) {
00324 
00325       do {
00326     if (stray_light_scan_no != scan_no) {
00327 
00328       recursive_flag = 1;
00329 
00330       status = get_l1a_rec(sd_id, stray_light_scan_no, cal_mod, 
00331                    l1a_dum, &st_l1b_data, &st_l2_flags);
00332     }
00333       }
00334       while (stray_light_corr(&initial,Ltyp_frac,Styp_frac,
00335                   nscan,npix,stray_light_scan_no++,dtype,
00336                   gain8,&pcal_rads[0][0][0],l1b_buffer,&sl_scan,
00337                   l2_flags_buffer,&AS_pixels) == NOTDONE);
00338       recursive_flag = 0;
00339       crec = scan_no;
00340 
00341     } 
00342 
00343 
00344 
00345     for (ipix=0; ipix < npix ; ipix++) {
00346         if (hi_Lt[ipix]) 
00347             l2_flags_buffer[ipix] |= MASK_HIGHLT1;
00348     } 
00349 
00350     *l1b_data = l1b_buffer;
00351     *l2_flags = l2_flags_buffer;
00352       
00353     return (0);
00354 }
00355 
00356 
00357 int openl1a_seawifs(filehandle *file)
00358 {
00359 
00360     /*                                                                 */
00361     /* input files                                                     */
00362     /*                                                                 */
00363     char    *cal_path = file->calfile;
00364 
00365     /*                                                                 */
00366     /* get_l1a_open interface                                          */
00367     /*                                                                 */
00368     int32 fileID;
00369     int32 status;
00370 
00371 
00372     /*                                                                 */
00373     /* set static global evaluation switch                             */
00374     /*                                                                 */
00375     evalmask = file->input->evalmask;
00376 
00377     /* open the file and get the file ID */
00378     fileID = SDstart(file->name, DFACC_RDONLY);
00379 
00380     if (fileID < 0) {
00381       fprintf(stderr,
00382           "-E %s Line %d: Error opening %s for reading.\n",
00383           __FILE__,__LINE__,file->name);
00384       return(1);
00385     }
00386 
00387     status = getHDFattr(fileID, "Start Year", "", (VOIDP) &syear);
00388     status = getHDFattr(fileID, "Start Day", "", (VOIDP) &sday);
00389     status = getHDFattr(fileID, "Start Millisec", "", (VOIDP) &smsec);
00390     status = getHDFattr(fileID, "End Year", "", (VOIDP) &eyear);
00391     status = getHDFattr(fileID, "End Day", "", (VOIDP) &eday);
00392     status = getHDFattr(fileID, "End Millisec", "", (VOIDP) &emsec);
00393     status = getHDFattr(fileID, "Number of Scan Lines", "", (VOIDP) &nscan);
00394     status = getHDFattr(fileID, "Data Type", "", (VOIDP) &dtype);
00395 
00396     status = getHDFattr(fileID, "Pixels per Scan Line", "", (VOIDP) &npix);
00397     status = getHDFattr(fileID, "LAC Pixel Start Number", "", (VOIDP) &nsta);
00398     status = getHDFattr(fileID, "LAC Pixel Subsampling", "", (VOIDP) &ninc);
00399 
00400     status = getHDFattr(fileID, "Orbit Node Longitude", "", (VOIDP)&file->orbit_node_lon);
00401     status = getHDFattr(fileID, "Orbit Number", "", (VOIDP)&file->orbit_number);
00402     status = getHDFattr(fileID, "Node Crossing Time", "", (VOIDP)&file->node_crossing_time[0]);
00403 
00404     if (file->input != NULL) {
00405         Ltyp_frac   = file->input->sl_frac;
00406         stray_light = file->input->sl_pixl;
00407     } 
00408 
00409     if (stray_light == 0)
00410         do_st = 0;
00411     else {
00412         do_st = 1;
00413         if (stray_light < 0) {
00414             if (strcmp(dtype,"GAC") == 0) 
00415                 stray_light = 4;
00416             else
00417                 stray_light = 3;
00418         }
00419     }
00420 
00421 
00422     /* get the current calibration model solution */
00423     if (cal_path == NULL) {
00424        fprintf(stderr,
00425               "-E %s Line %d: No calibration file specified.\n",
00426               __FILE__,__LINE__);
00427         exit(1);
00428     }
00429 
00430     read_caltable(cal_path);
00431 
00432 /*
00433         status = get_cal(cal_path, syear, sday, eday, smsec, npix, nsta, ninc,
00434              dtype, tdi, &entry_year, &entry_day, &ref_year, 
00435              &ref_day, &ref_minute, fp_temps, scan_mod, t_const,
00436                      t_linear_1, t_exponential_1, t_linear_2, t_exponential_2,
00437              cal_offs, inst_tcorr, inst_tref, fp_tcorr, fp_tref, 
00438                      ms1_const, ms1_linear_1, ms1_exponential_1, ms1_linear_2, 
00439                      ms1_exponential_2, ms2_const, ms2_linear_1, 
00440                      ms2_exponential_1, ms2_linear_2, ms2_exponential_2, 
00441                      counts, rads);
00442 */
00443 
00444     if (status < 0) {
00445       fprintf(stderr,
00446           "-E- %s line %d: Error applying calibration table \"%s\".\n",
00447           __FILE__,__LINE__,cal_path);
00448       exit(status);
00449     }
00450 
00451 
00452     /* call cdata.f to initialize global FORTRAN common block data  */
00453     cdata_();
00454 
00455 
00456     file->npix     = npix;
00457     file->nscan    = nscan;
00458     file->sensorID = SEAWIFS;
00459     file->sd_id = fileID;
00460 
00461     strcpy(cal_path_tab, cal_path);
00462 
00463     l1a_data = (int16 *) calloc(npix*8*NREC_IN_BUF, sizeof(int16));
00464     l1a_back = (int16 *) calloc(npix*8*(STBUFSIZ-2), sizeof(int16));
00465     l1b_buffer = (float *) calloc(npix*8, sizeof(float));
00466 
00467     msec = (int32 *) calloc(nscan, sizeof(int32));
00468     status = rdSDS(file->sd_id,"msec",0,0,0,0, (VOIDP) msec);
00469     side = (int16 *) calloc(nscan, sizeof(int16));
00470     status = rdSDS(file->sd_id,"side",0,0,0,0, (VOIDP) side);
00471 
00472     dark_rest = (int16 *) calloc(nscan*8, sizeof(int16));
00473     status = rdSDS(file->sd_id,"dark_rest",0,0,0,0, (VOIDP) dark_rest);
00474     dark_rest_stat(dark_rest, nscan, dark_mean, dark_std);
00475     free(dark_rest);
00476 
00477     tilt = (float32 *) calloc(nscan, sizeof(float32));
00478     status = rdSDS(file->sd_id,"tilt",0,0,0,0, (VOIDP) tilt);
00479 
00480     spix = nsta - 1;
00481     dpix = ninc;
00482     
00483     return (status);
00484 }
00485 
00486 
00487 int readl1a_seawifs(filehandle *file, int32 recnum, l1str *l1rec)
00488 {
00489 
00490     /*                                                                 */
00491     /* get_l1a_rec interface                                           */
00492     /*                                                                 */
00493     static cal_mod_struc cal_mod;  /* cal modification structure       */
00494     static int16   *l2_flags;      /* radiance quality flags for L2    */
00495     static float32 *l1b_data;
00496 
00497     int32   i;
00498     int32   status = 0;
00499     
00500     int32  nwave = l1rec->nbands;
00501     int32 *bindx = (int32*)l1rec->bindx;
00502 
00503     /*                                                                 */
00504     /* local vars                                                      */
00505     /*                                                                 */
00506     int32   ipix;                  /* pixel number                     */
00507     int32    iw, ib;
00508 
00509     int16 *l1a_dum = NULL;
00510 
00511     static int32  prev_recnum = -1;
00512 
00513     static int16 first = 1;
00514     static int32 ntilts;
00515     static int16 tilt_flags[20];
00516     static int16 tilt_ranges[2*20];
00517 
00518     int16  bad_tilt;
00519     int32  nflag[8];
00520 
00521 
00522     /* If reading out-of-sequence, force restart from beginning to get stlight */
00523     /* baf, 05-oct-2001.                                                       */
00524     if (recnum < prev_recnum) {
00525         printf("Reading out-of-sequence %d %d\n",recnum,prev_recnum);
00526         prev_recnum = -1;
00527     }
00528 
00529 
00530     /* Get tilt info */
00531     /* ------------- */
00532     if (first) {
00533       status = rdSDS(file->sd_id,"ntilts",0,0,0,0,(VOIDP) &ntilts); 
00534       status = rdSDS(file->sd_id,"tilt_flags",0,0,0,0,(VOIDP) tilt_flags); 
00535       status = rdSDS(file->sd_id,"tilt_ranges",0,0,0,0,(VOIDP) tilt_ranges); 
00536       first = 0;
00537     }
00538 
00539 
00540     /* Check for bad or changing tilt */
00541     /* ------------------------------ */
00542     for (i=0; i<ntilts; i++) {
00543       if (tilt_ranges[2*i] <= recnum+1 && tilt_ranges[2*i+1] >= recnum)
00544     break;
00545       if (tilt_flags[i] == 0 ||    /* nadir */
00546       tilt_flags[i] == 1 ||    /* fwd */
00547       tilt_flags[i] == 2 )     /* aft */
00548         bad_tilt = 0;              /* tilt result is ok */
00549       else if (tilt_flags[i] == 3) /* tilt is changing */
00550         bad_tilt = 1;
00551       else                         /* tilt is unknown */
00552         bad_tilt = 2;
00553     }
00554 
00555 
00556     /* Get nav flag */
00557     /* ------------ */
00558     status = rdSDS(file->sd_id,"nflag",recnum,0,1,8,(VOIDP) &nflag); 
00559 
00560 
00561     /* Get l1a data */
00562     /* ------------ */
00563     for (i=prev_recnum+1; i<=recnum; i++)
00564       status = get_l1a_rec(file->sd_id, i+1, &cal_mod, l1a_dum, 
00565                &l1b_data, &l2_flags);
00566 
00567     /*                                                              */
00568     /* Copy scan geolocation and view geometry                      */
00569     /*                                                              */
00570     memcpy(l1rec->lat , ylat, npix*sizeof(float));
00571     memcpy(l1rec->lon , xlon, npix*sizeof(float));
00572     memcpy(l1rec->solz, solz, npix*sizeof(float));
00573     memcpy(l1rec->sola, sola, npix*sizeof(float));
00574     memcpy(l1rec->senz, senz, npix*sizeof(float));
00575     memcpy(l1rec->sena, sena, npix*sizeof(float));
00576 
00577     /*                                                              */
00578     /* Copy L1B radiances, pixel interlaced by band. Add per-band   */
00579     /* view angles.                                                 */
00580     /*                                                              */
00581     for (ipix = 0; ipix < file->npix; ipix++) {
00582       l1rec->pixnum[ipix] = spix + ipix*dpix;
00583       for (iw=0; iw<nwave; iw++) {
00584         ib = bindx[iw];
00585     l1rec->Lt   [ipix*NBANDS+ib] = l1b_data[iw*npix+ipix];
00586       }
00587       l1rec->stlight[ipix]  = ((l2_flags[ipix] & STRAYLIGHT) > 0);
00588       l1rec->hilt   [ipix]  = ((l2_flags[ipix] & HILT)    > 0);
00589       l1rec->navwarn[ipix]  = (nflag[7] & 1) | (nflag[0] & 1);
00590     }
00591 
00592 
00593     /*                                                              */
00594     /* Set scan time in L1B output record                           */
00595     /*                                                              */
00596     *l1rec->year = syear;
00597     *l1rec->day = sday;
00598     *l1rec->msec = msec[recnum];
00599     if (msec[recnum] < smsec) {                 /* adjust for day rollover */
00600         *l1rec->day += 1;
00601         if (*l1rec->day > (365 + (*l1rec->year % 4 == 0))) {
00602              *l1rec->year += 1;
00603              *l1rec->day   = 1;
00604         }
00605     }
00606 
00607     l1rec->tilt  = tilt[recnum];
00608     l1rec->mside = side[recnum];
00609 
00610     prev_recnum = recnum;
00611 
00612     return(status);
00613 }
00614 
00615 
00616 int readl1a_lonlat_seawifs(filehandle *file, int32 recnum, l1str *l1rec)
00617 {
00618     int32   status;
00619     int32   start[3];
00620     int32   edges[3];
00621 
00622     inputBuffer rdBuf;
00623 
00624     if (recnum > nscan) return 0;
00625 
00626     status = rdSDS(file->sd_id,"orb_vec",recnum,0,1,3,(VOIDP) rdBuf.orb_vec);
00627     status = rdSDS(file->sd_id,"sun_ref",recnum,0,1,3,(VOIDP) rdBuf.sun_ref);
00628     status = rdSDS(file->sd_id,"scan_ell",recnum,0,1,6,(VOIDP) rdBuf.scan_ell);
00629 
00630     start[0] = recnum;
00631     edges[0] = 1;
00632     start[1] = 0;
00633     edges[1] = 3;
00634     start[2] = 0;
00635     edges[2] = 3;
00636     status = SDreaddata(SDselect(file->sd_id, SDnametoindex(file->sd_id, "sen_mat")), 
00637                         start, NULL, edges, (VOIDP) rdBuf.sen_mat);
00638 
00639     geonav_lonlat_(rdBuf.orb_vec, rdBuf.sen_mat, rdBuf.scan_ell,
00640                    rdBuf.sun_ref,&nsta,&ninc,&npix,
00641                    l1rec->lat,l1rec->lon);
00642 
00643     return(0);
00644 }
00645 
00646 
00647 int closel1a_seawifs(filehandle *file)
00648 {
00649   free(l1a_data);
00650   free(l1a_back);
00651   free(l1b_buffer);
00652   free(msec);
00653   free(side);
00654   free(tilt);
00655 
00656   SDend(file->sd_id);
00657 
00658   return(0);
00659 }
00660 
00661 
00662