ocssw  1.0
/disk01/web/ocssw/build/src/viirs_sim_sdr/init_sdr.c (r8085/r5919)
Go to the documentation of this file.
00001 #include "viirs_sim_sdr.h"
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #include <libgen.h>
00006 #include <time.h>
00007 /*  this is used mainly in setting up the grougs in the output SDRs */
00008 char *core_g_nm[] = { "VIIRS-MOD-GEO-TC", "VIIRS-M1-SDR",
00009      "VIIRS-M2-SDR", "VIIRS-M3-SDR", "VIIRS-M4-SDR", "VIIRS-M5-SDR",
00010      "VIIRS-M6-SDR", "VIIRS-M7-SDR", "VIIRS-M8-SDR", "VIIRS-M9-SDR", 
00011      "VIIRS-M10-SDR", "VIIRS-M11-SDR", "VIIRS-M12-SDR", "VIIRS-M13-SDR", 
00012      "VIIRS-M14-SDR", "VIIRS-M15-SDR", "VIIRS-M16-SDR" };
00013 
00014 int init_sdr( ctl_struc *ctl, sdr_info_struc *sdr_info, in_rec_struc *in_rec, 
00015   out_rec_struc *out_rec )
00016 /*-----------------------------------------------------------------------------
00017     Program:   init_sdr.c
00018 
00019     Description:  create the geolocation and band files with everything but 
00020       data lines
00021 
00022     Arguments:
00023         Type      Name         I/O   Description
00024         ----      ----         ---   -----------
00025         ctl_struc *  ctl        I    input controls
00026         sdr_info_struc * sdr_info I  general SDR information
00027         in_rec_struc * in_rec    I/O  controls for input record reading
00028         out_rec_struc *  out_rec  I/O  controls for output file writing
00029 
00030     Modification history:
00031 
00032     W. Robinson, SAIC  15 Oct 2008  Original development
00033 
00034 ----------------------------------------------------------------------------*/
00035   {
00036   h5io_str dat1_g_id, dat2_g_id;
00037   char out_file[500], grp_nam[50], *sdr_base;
00038   int isdr;
00039   char lcl_out_bnd_typ[] = { 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 };
00040   char lcl_meas_typ[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 };
00041  /*
00042   *  set the radiance storage and type flag
00043   */
00044   for( isdr = 0; isdr < MAX_BND; isdr++ )
00045     {
00046     out_rec->out_bnd_typ[isdr] = lcl_out_bnd_typ[isdr];
00047     out_rec->meas_typ[isdr] = lcl_meas_typ[isdr];
00048     }
00049  /*
00050   *  initialize the lat, lon limit values
00051   */
00052   in_rec->ll_lims[0] = 99.;
00053   in_rec->ll_lims[1] = -99.;
00054   in_rec->ll_lims[2] = 200.;
00055   in_rec->ll_lims[3] = -200.;
00056   in_rec->ll_lims[4] = 200.;
00057   in_rec->ll_lims[5] = -200.;
00058  /*
00059   *  based on the controls and the input scan format, set controls for
00060   *  output scan format information
00061   *  base state is to leave as-is (out_scn_fmt = 2)
00062   */
00063   out_rec->nbnd = in_rec->nbnd;
00064   out_rec->npix = in_rec->npix;
00065   out_rec->nlin = in_rec->nlin;
00066   out_rec->nscan = in_rec->nscan;
00067   out_rec->scn_fmt = in_rec->scn_fmt;
00068   out_rec->margin[0] = in_rec->margin[0];
00069   out_rec->margin[1] = in_rec->margin[1];
00070   out_rec->ndet_scan = in_rec->ndet_scan;
00071 
00072   if( ctl->out_scn_fmt == 0 )  /* make aggregated */
00073     {
00074     out_rec->scn_fmt = 0;
00075     out_rec->npix = 3200;
00076     out_rec->nlin = in_rec->nscan * NDET;
00077     out_rec->margin[0] = 0;
00078     out_rec->margin[1] = 0;
00079     out_rec->ndet_scan = NDET;
00080     }
00081   else if( ctl->out_scn_fmt == 1 )  /* make unaggregated with no margin */
00082     {
00083     out_rec->margin[0] = 0;
00084     out_rec->margin[1] = 0;
00085     out_rec->ndet_scan = NDET;
00086     out_rec->nlin = in_rec->nscan * NDET;
00087 
00088     if( in_rec->scn_fmt == 0 )
00089       {
00090       printf( 
00091         "%s, %d: Warning - requested output format (%d) of unaggregated\n",
00092         __FILE__, __LINE__, in_rec->scn_fmt );
00093       printf( "          will default to input scan format of aggregated\n" );
00094       out_rec->npix = 3200;
00095       out_rec->scn_fmt = 0;
00096       }
00097     else
00098       {
00099       out_rec->npix = 6304;
00100       out_rec->scn_fmt = 1;
00101       }
00102     }
00103  /*
00104   *  go through the SDR files and initialize each one
00105   */
00106   for( isdr = 0; isdr < in_rec->nbnd + 1; isdr++ )
00107     {
00108    /*
00109     *  divide the work among creating the major parts of the file
00110     *  first, open output file and set up the top attributes
00111     */
00112     if( gen_sdr_fname( isdr, ctl->out_loc, sdr_info, ctl->fname_opt, 
00113       out_file ) != 0 )
00114       {
00115       printf( "%s, %d: Unable to generate output file for sdr index %d\n\n",
00116         __FILE__, __LINE__, isdr );
00117       return 1;
00118       }
00119     sdr_base = basename( out_file );
00120     strcpy( sdr_info->sdr_files[isdr], sdr_base );
00121     if( h5io_openw( out_file, ctl->sdr_overwrite,
00122       &( out_rec->sdr_fid[isdr] ) ) != 0 )
00123       {
00124       printf( "%s, %d: Unable to open output geo file: \n%s\n\n", 
00125         __FILE__, __LINE__, out_file );
00126       return 1;
00127       }
00128     if( init_sdr_top( isdr, sdr_info, out_rec ) != 0 ) return 1;
00129    /*
00130     *  and then make the data group and write the data
00131     */
00132     if( h5io_mk_grp( &( out_rec->sdr_fid[isdr] ), "All_Data", 
00133       &( out_rec->sdr_dat_gid[0][isdr] ) ) != 0 )
00134       {
00135       printf( "%s, %d - could not create data group: All_Data\n", 
00136         __FILE__, __LINE__ );
00137       return 1;
00138       }
00139     sprintf( grp_nam, "%s_All", core_g_nm[isdr] );
00140     if( h5io_mk_grp( &( out_rec->sdr_dat_gid[0][isdr] ), grp_nam, 
00141       &( out_rec->sdr_dat_gid[1][isdr] )) != 0 )
00142       {
00143       printf( "%s, %d - could not create data group: %s\n", 
00144         __FILE__, __LINE__, grp_nam );
00145       return 1;
00146       }
00147     if( isdr == 0 )
00148       {
00149       if( init_geo_data( sdr_info, in_rec, out_rec ) != 0 ) return 1;
00150       }
00151     else
00152       {
00153      /*
00154       *  allocate the dn storage here (depends on ctl) but do rest in 
00155       *  call to init_bnd_data
00156       */
00157       if( ctl->count_cal_opt != 0 )
00158         {
00159         if( ( in_rec->dn[ isdr - 1 ] = (float *)
00160           malloc( in_rec->ndet_scan * in_rec->npix * sizeof(float) ) )
00161           == NULL )
00162           {
00163           printf( "%s, %d: Error, allocation of dn storage failed\n",
00164           __FILE__, __LINE__ );
00165           return 1;
00166           }
00167         }
00168       if( ( in_rec->gain_bit[ isdr - 1 ] = (unsigned char *)
00169         calloc( in_rec->ndet_scan * in_rec->npix, sizeof(unsigned char) ) )
00170         == NULL )
00171         {
00172         printf( 
00173           "%s, %d: Error, allocation of count gain bit storage failed\n",
00174           __FILE__, __LINE__ );
00175         return 1;
00176         }
00177       if( ( in_rec->dn_sat[ isdr - 1 ] = (char *)
00178         calloc( in_rec->ndet_scan * in_rec->npix, sizeof(char) ) )
00179         == NULL )
00180         {
00181         printf(
00182           "%s, %d: Error, allocation of dn saturation storage failed\n",
00183           __FILE__, __LINE__ );
00184         return 1;
00185         }
00186       if( init_bnd_data( isdr - 1, sdr_info, in_rec, out_rec ) != 0 ) return 1;
00187       }
00188    /*
00189     *  make the other group pair for data products and fill
00190     */
00191     if( h5io_mk_grp( &(out_rec->sdr_fid[isdr]), 
00192       "Data_Products", &dat1_g_id ) != 0 )
00193       {
00194       printf( "%s, %d - could not create data group: Data_Products\n", 
00195         __FILE__, __LINE__ );
00196       return 1;
00197       }
00198     if( h5io_mk_grp( &dat1_g_id, core_g_nm[isdr], &dat2_g_id ) != 0 )
00199       {
00200       printf( "%s, %d - could not create data group: %s\n",
00201          __FILE__, __LINE__, core_g_nm[isdr] );
00202       return 1;
00203       }
00204    /*
00205     *  set up attributes in the group, the aggregate and granule datasets
00206     *  and their attributes
00207     */
00208     if( init_sdr_dpattr( isdr, &dat2_g_id, sdr_info ) != 0 ) return 1;
00209     if( init_sdr_agg( isdr, &dat2_g_id, sdr_info ) != 0 ) return 1;
00210     if( init_sdr_gran( isdr, &dat2_g_id, sdr_info, out_rec ) != 0 ) return 1;
00211    /*
00212     *  and finish up, closing the group ids
00213     */
00214     if( h5io_close( &dat2_g_id ) != 0 )
00215       {
00216       printf( "%s, %d - could not close dat2_g_id\n", __FILE__, __LINE__ );
00217       return 1;
00218       }
00219     if( h5io_close( &dat1_g_id ) != 0 )
00220       {
00221       printf( "%s, %d - could not close dat1_g_id\n", __FILE__, __LINE__ );
00222       return 1; 
00223       }
00224     }
00225  /*
00226   *  we still need to place the data lines
00227   */
00228   return 0;
00229   }
00230 
00231 int init_sdr_top( int isdr, sdr_info_struc *sdr_info, out_rec_struc *out_rec )
00232 /*-----------------------------------------------------------------------------
00233     Routine:   init_sdr_top
00234 
00235     Description:  make the top-level attributes for the geolocation or 
00236       band SDR file
00237 
00238     Arguments:
00239         Type      Name         I/O   Description
00240         ----      ----         ---   -----------
00241         int       isdr          I    SDR file to work on: 0 geo, > 0 band isdr
00242         sdr_info_struc * sdr_info I  general SDR information
00243         out_rec_struc * out_rec I    output dataset information
00244 
00245     Modification history:
00246 
00247     W. Robinson, SAIC  15 Oct 2008  Original development
00248     W. Robinson, SAIC  18 Mar 2010  place non-standard attributes here for the 
00249        non-aggregated file types
00250 
00251 ----------------------------------------------------------------------------*/
00252   {
00253   int i, n_attr = 13, dims_1_1[] = { 1, 1 }, len_geo;
00254   int dims_1[] = { 1 }, dims_2[] = { 2 };
00255   char geo_name[150], *bloc = ".";
00256   int16 lcl_scn_fmt, lcl_margin[2], lcl_ndet_scan;
00257   int32 lcl_npix, lcl_nlin;
00258 
00259   gen_sdr_fname( 0, bloc, sdr_info, 0, geo_name );
00260   len_geo = strlen( geo_name );
00261 
00262   h5attr_struc attrs[] = {
00263     { 1, 1, "Distributor", H5T_NATIVE_CHAR, 4, 2, dims_1_1,
00264        (void *) ( sdr_info->origin ) },
00265     { 1, 1, "Instrument_Short_Name", H5T_NATIVE_CHAR, 6, 2, dims_1_1, 
00266        (void *)"VIIRS" },
00267     { 1, 1, "Mission_Name", H5T_NATIVE_CHAR, 4, 2, dims_1_1,
00268        (void *)"NPP" },
00269     { 1, 1, "N_Dataset_Source", H5T_NATIVE_CHAR, 5, 2, dims_1_1,
00270        (void *)"OBPG" },
00271     { 1, 1, "N_GEO_Ref", H5T_NATIVE_CHAR, len_geo, 2, dims_1_1, 
00272        (void *)geo_name },
00273     { 1, 1, "N_HDF_Creation_Date", H5T_NATIVE_CHAR, 9, 2, dims_1_1,
00274        (void *) sdr_info->cre_date },
00275     { 1, 1, "N_HDF_Creation_Time", H5T_NATIVE_CHAR, 14, 2, dims_1_1,
00276        (void *) sdr_info->cre_time },
00277     { 1, 1, "Platform_Short_Name", H5T_NATIVE_CHAR, 4, 2, dims_1_1,
00278        (void *) "NPP" },
00279     { 0, 0, "Data Scan Format", H5T_STD_I16BE, 0, 1, dims_1, 
00280        (void *) &lcl_scn_fmt },
00281     { 0, 0, "Scan Margin (track, scan)", H5T_STD_I16BE, 0, 1, dims_2,
00282        (void *) lcl_margin },
00283     { 0, 0, "Pixels per Scan Line", H5T_STD_I32BE, 0, 1, dims_1,
00284        (void *) &lcl_npix },
00285     { 0, 0, "Number of Scan Lines", H5T_STD_I32BE, 0, 1, dims_1,
00286        (void *) &lcl_nlin },
00287     { 0, 0, "Number of Detectors per Scan", H5T_STD_I16BE, 0, 1, dims_1,
00288        (void *) &lcl_ndet_scan }
00289      };
00290  /*
00291   *  for the geo file, don't output the N_GEO_Ref attrib
00292   */
00293   if( isdr == 0 ) attrs[4].express = 0;
00294  /*
00295   *  for non-aggregated file formats, add the descriptors
00296   */
00297   if( out_rec->scn_fmt != 0 )
00298     {
00299     for( i = 0; i < 5; i++ )
00300       attrs[ i + 8 ].express = 1;
00301     lcl_scn_fmt = (int16) out_rec->scn_fmt;
00302     lcl_margin[0] = (int16) out_rec->margin[0];
00303     lcl_margin[1] = (int16) out_rec->margin[1];
00304     lcl_npix = (int32) out_rec->npix;
00305     lcl_nlin = (int32) out_rec->nlin;
00306     lcl_ndet_scan = (int16)out_rec->ndet_scan;
00307     }
00308  /*
00309   *  output the attributes to the location
00310   */
00311   if( wr_attr_seq( &( out_rec->sdr_fid[isdr] ), n_attr, attrs ) != 0 )
00312     {
00313     printf( "%s, %d: Could not write top attributes\n", __FILE__, __LINE__ );
00314     return 1;
00315     }
00316   return 0;
00317   }
00318 
00319 int init_geo_data( sdr_info_struc *sdr_info, in_rec_struc *in_rec, 
00320   out_rec_struc *out_rec )
00321 /*-----------------------------------------------------------------------------
00322     Routine:   init_geo_data
00323 
00324     Description:  make the data arrays for the geo file and fill some
00325       Also, get some data start, end times
00326 
00327     Arguments:
00328         Type      Name         I/O   Description
00329         ----      ----         ---   -----------
00330         sdr_info_struc * sdr_info I/O  general SDR information
00331         in_rec_struc * in_rec  I/O  input file information
00332         out_rec_struc * out_rec I/O  output file information
00333 
00334     Modification history:
00335 
00336     W. Robinson, SAIC  21 Oct 2008  Original development
00337     W. Robinson, SAIC  02 Oct 2009  use geoloc file attitude, position, 
00338                                     velocity in the SDR
00339 
00340 ----------------------------------------------------------------------------*/
00341   {
00342   h5io_str ds_id, in_ds_id, *gid;
00343   int dim_siz[2], dim_siz2[2], *arr_int, i;
00344   float *flt_data;
00345   double *dbl_data;
00346   int64 *llon_data;
00347   unsigned char *uchar_data;
00348  /*
00349   *  define gid for convenience
00350   */
00351   gid = &( out_rec->sdr_dat_gid[1][0] );
00352  /*
00353   *  datasets are:
00354   *  Height -- may be derivable but not necessary
00355   */
00356   dim_siz[0] = out_rec->nlin;
00357   dim_siz[1] = out_rec->npix;
00358 
00359   if( ( flt_data = (float *) malloc( out_rec->npix * out_rec->nlin *
00360     sizeof(float) ) ) == NULL )
00361     {
00362     printf( "%s, %d: Could not allocate local float buffer\n", 
00363       __FILE__, __LINE__ );
00364     return 1;
00365     }
00366 
00367   for( i = 0; i < out_rec->nlin * out_rec->npix; i++ )
00368     *( flt_data + i ) = 0;
00369   if( h5io_mk_ds( gid, "Height", H5T_IEEE_F32BE, 2, dim_siz,
00370      &ds_id ) != 0 )
00371     {
00372     printf( "%s, %d: Could not do h5io_mk_ds for Height\n", 
00373       __FILE__, __LINE__ );
00374     return 1;
00375     }
00376   if( h5io_wr_ds( &ds_id, (void *)flt_data ) != 0 )
00377     {
00378     printf( "%s, %d: Could not write to Height\n", __FILE__, __LINE__ );
00379     return 1;
00380     }
00381   if( h5io_close( &ds_id ) != 0 )
00382     {
00383     printf( "%s, %d: Could not close Height\n", __FILE__, __LINE__ );
00384     return 1;
00385     }
00386  /*
00387   *  Latitude
00388   *  The lat, lon, senz, sena, solz, sola arrays will be filled scae-by-scan
00389   *  later.  just create these datasets here (others will be filled here)
00390   */
00391   if( h5io_set_ds( &( in_rec->geo_fid ), "latitude",
00392     &( in_rec->geo_dat_id[0] ) ) != 0 )
00393     {
00394     printf( "%s, %d: Could not do h5io_set_ds for latitude\n", 
00395       __FILE__, __LINE__ );
00396     return 1;
00397     }
00398 
00399   dim_siz[0] = out_rec->nlin;
00400   dim_siz[1] = out_rec->npix;
00401   if( h5io_mk_ds( gid, "Latitude", H5T_IEEE_F32BE, 2, dim_siz,
00402     &( out_rec->geo_dat_id[0] ) ) != 0 )
00403     {
00404     printf( "%s, %d: Could not do h5io_mk_ds for Latitude\n", 
00405       __FILE__, __LINE__ );
00406     return 1;
00407     }
00408  /*
00409   *  allocate the data transfer buffer and make it the same for output
00410     **** good for now as long as out size = in size but will need change 
00411          if scn_fnt is changed
00412   */
00413   if( ( in_rec->lat = (float *) malloc( in_rec->npix * in_rec->ndet_scan * 
00414     sizeof(float) ) ) == NULL )
00415     {
00416     printf( "%s, %d: Could not allocate space for lat data transfer buffer\n",
00417       __FILE__, __LINE__ );
00418     return 1;
00419     }
00420   out_rec->lat = in_rec->lat;
00421  /*
00422   *  Longitude
00423   */
00424   if( h5io_set_ds( &( in_rec->geo_fid ), "longitude",
00425     &( in_rec->geo_dat_id[1] ) ) != 0 )
00426     {
00427     printf( "%s, %d: Could not do h5io_set_ds for longitude\n", 
00428       __FILE__, __LINE__ );
00429     return 1;
00430     }
00431 
00432   if( h5io_mk_ds( gid, "Longitude", H5T_IEEE_F32BE, 2, dim_siz,
00433     &( out_rec->geo_dat_id[1] ) ) != 0 )
00434     {
00435     printf( "%s, %d: Could not do h5io_mk_ds for Longitude\n", 
00436       __FILE__, __LINE__ );
00437     return 1;
00438     }
00439 
00440   if( ( in_rec->lon = (float *) malloc( in_rec->npix * in_rec->ndet_scan * 
00441     sizeof(float) ) ) == NULL )
00442     {
00443     printf( "%s, %d: Could not allocate space for lon data transfer buffer\n",
00444        __FILE__, __LINE__ );
00445     return 1;
00446     }
00447   out_rec->lon = in_rec->lon;
00448  /*
00449   *  MidTime - an 8 byte int of microsecs past 1/1958 -- for now,
00450   *  fill the ScanStartTime but leave this 0
00451   */
00452   llon_data = (int64 *) calloc( out_rec->nscan, sizeof(int64) );
00453   dim_siz2[0] = out_rec->nscan;
00454   if( h5io_mk_ds( gid, "MidTime", H5T_STD_I64BE, 1, dim_siz2, &ds_id )
00455     != 0 )
00456     {
00457     printf( "%s, %d: Could not do h5io_mk_ds for MidTime\n", 
00458       __FILE__, __LINE__ );
00459     return 1;
00460     }
00461   if( h5io_wr_ds( &ds_id, (void *)llon_data ) != 0 )
00462     {
00463     printf( "%s, %d: Could not write to MidTime\n", __FILE__, __LINE__ );
00464     return 1;
00465     }
00466   if( h5io_close( &ds_id ) != 0 )
00467     {
00468     printf( "%s, %d: Could not close MidTime\n", __FILE__, __LINE__ );
00469     return 1;
00470     }
00471   free( llon_data );
00472  /*
00473   *  ModeGran 1 value, 1 is day, so fill with 1  
00474   */
00475   uchar_data = (unsigned char *) malloc( out_rec->nscan *
00476     sizeof( unsigned char ) );
00477   *uchar_data = 1;
00478   dim_siz2[0] = 1;
00479   if( h5io_mk_ds( gid, "ModeGran", H5T_STD_U8BE, 1, dim_siz2, &ds_id )
00480     != 0 )
00481     {
00482     printf( "%s, %d: Could not do h5io_mk_ds for ModeGran\n", 
00483      __FILE__, __LINE__ );
00484     return 1;
00485     }
00486   if( h5io_wr_ds( &ds_id, (void *)uchar_data ) != 0 )
00487     {
00488     printf( "%s, %d: Could not write to ModeGran\n", __FILE__, __LINE__ );
00489     return 1;
00490     }
00491   if( h5io_close( &ds_id ) != 0 )
00492     {
00493     printf( "%s, %d: Could not close ModeGran\n", __FILE__, __LINE__ );
00494     return 1;
00495     }
00496   free( uchar_data );
00497  /*
00498   *  ModeScan 48 bytes, 1 is day, so fill with 1 
00499   */
00500   uchar_data = (unsigned char *) malloc( out_rec->nscan *
00501     sizeof( unsigned char ) );
00502   for( i = 0; i < out_rec->nscan; i++ )
00503     *( uchar_data + i ) = 1;
00504   dim_siz2[0] = out_rec->nscan;
00505   if( h5io_mk_ds( gid, "ModeScan", H5T_STD_U8BE, 1, dim_siz2, &ds_id )
00506     != 0 )
00507     {
00508     printf( "%s, %d: Could not do h5io_mk_ds for ModeScan\n", 
00509       __FILE__, __LINE__ );
00510     return 1;
00511     }
00512   if( h5io_wr_ds( &ds_id, (void *)uchar_data ) != 0 )
00513     {
00514     printf( "%s, %d: Could not write to ModeScan\n", __FILE__, __LINE__ );
00515     return 1;
00516     }
00517   if( h5io_close( &ds_id ) != 0 )
00518     {
00519     printf( "%s, %d: Could not close ModeScan\n", __FILE__, __LINE__ );
00520     return 1;
00521     }
00522   free( uchar_data );
00523  /*
00524   *  NumberOfScans
00525   */
00526   arr_int = (int *)malloc( sizeof( int ) );
00527   *arr_int = out_rec->nscan;
00528   dim_siz2[0] = 1;
00529   if( h5io_mk_ds( gid, "NumberOfScans", H5T_STD_I32BE, 1, dim_siz2, &ds_id )
00530     != 0 )
00531     {
00532     printf( "%s, %d: Could not do h5io_mk_ds for NumberOfScans\n", 
00533       __FILE__, __LINE__ );
00534     return 1;
00535     }
00536   if( h5io_wr_ds( &ds_id, (void *)arr_int ) != 0 )
00537     {
00538     printf( "%s, %d: Could not write to NumberOfScans\n", __FILE__, __LINE__ );
00539     return 1;
00540     }
00541   if( h5io_close( &ds_id ) != 0 )
00542     {
00543     printf( "%s, %d: Could not close NumberOfScans\n", __FILE__, __LINE__ );
00544     return 1;
00545     }
00546   free( arr_int );
00547  /*
00548   *  PadByte1 ( 3 values of 0)  -- just fill with 0 for the 3 values
00549   */
00550   uchar_data = (unsigned char *) malloc( 3 * sizeof( unsigned char ) );
00551   for( i = 0; i < 3; i++ )
00552     *( uchar_data + i ) = 0;
00553   dim_siz2[0] = 3;
00554   if( h5io_mk_ds( gid, "PadByte1", H5T_STD_U8BE, 1, dim_siz2, &ds_id )
00555     != 0 )
00556     {
00557     printf( "%s, %d: Could not do h5io_mk_ds for PadByte\n", 
00558       __FILE__, __LINE__ );
00559     return 1;
00560     }
00561   if( h5io_wr_ds( &ds_id, (void *)uchar_data ) != 0 )
00562     {
00563     printf( "%s, %d: Could not write to PadByte\n", __FILE__, __LINE__ );
00564     return 1;
00565     }
00566   if( h5io_close( &ds_id ) != 0 )
00567     {
00568     printf( "%s, %d: Could not close PadByte\n", __FILE__, __LINE__ );
00569     return 1;
00570     }
00571   free( uchar_data );
00572  /*
00573   *  QF1_SCAN_VIIRSSDRGEO - contains info on HAM encoder qual and attitude,
00574   *  ephem availability good is  48 * 0
00575   */
00576   uchar_data = (unsigned char *) malloc( out_rec->nscan * 
00577     sizeof( unsigned char ) );
00578   for( i = 0; i < out_rec->nscan; i++ )
00579     *( uchar_data + i ) = 0;
00580   dim_siz2[0] = out_rec->nscan;
00581   if( h5io_mk_ds( gid, "QF1_SCAN_VIIRSSDRGEO", H5T_STD_U8BE, 1, 
00582     dim_siz2, &ds_id ) != 0 )
00583     {
00584     printf( "%s, %d: Could not do h5io_mk_ds for QF1_SCAN_VIIRSSDRGEO\n", 
00585       __FILE__, __LINE__ );
00586     return 1;
00587     }
00588   if( h5io_wr_ds( &ds_id, (void *)uchar_data ) != 0 )
00589     {
00590     printf( "%s, %d: Could not write to QF1_SCAN_VIIRSSDRGEO\n", 
00591       __FILE__, __LINE__ );
00592     return 1;
00593     }
00594   if( h5io_close( &ds_id ) != 0 )
00595     {
00596     printf( "%s, %d: Could not close QF1_SCAN_VIIRSSDRGEO\n", 
00597       __FILE__, __LINE__ );
00598     return 1;
00599     }
00600   free( uchar_data );
00601  /*
00602   *  QF2_VIIRSSDRGEO - valid / invalid state for 4 items: input data,
00603   *  pointing, terrain and solar angles - all 0 for all pixels is all good
00604   */
00605   uchar_data = (unsigned char *) calloc( out_rec->npix * out_rec->nlin,
00606     sizeof( unsigned char ) );
00607   if( h5io_mk_ds( gid, "QF2_VIIRSSDRGEO", H5T_STD_U8BE, 2, dim_siz, &ds_id )
00608     != 0 )
00609     {
00610     printf( "%s, %d: Could not do h5io_mk_ds for QF2_VIIRSSDRGEO\n", 
00611       __FILE__, __LINE__ );
00612     return 1;
00613     }
00614   if( h5io_wr_ds( &ds_id, (void *)uchar_data ) != 0 )
00615     {
00616     printf( "%s, %d: Could not write to QF2_VIIRSSDRGEO\n", 
00617       __FILE__, __LINE__ );
00618     return 1;
00619     }
00620   if( h5io_close( &ds_id ) != 0 )
00621     {
00622     printf( "%s, %d: Could not close QF2_VIIRSSDRGEO\n", __FILE__, __LINE__ );
00623     return 1;
00624     }
00625   free( uchar_data );
00626  /*
00627   *  SCAttitude attitude information 48 X 3 from geoloc dataset
00628   *  convert from deg to arcsec
00629   */
00630   for( i = 0; i < out_rec->nscan * 3; i++ )
00631     *( flt_data + i ) = *( sdr_info->geo_att + i ) * 3600.;
00632  /*  free the space as it is no longer in use */
00633   free( sdr_info->geo_att );
00634   dim_siz2[0] = out_rec->nscan;
00635   dim_siz2[1] = 3;
00636   if( h5io_mk_ds( gid, "SCAttitude", H5T_IEEE_F32BE, 2, dim_siz2,
00637      &ds_id ) != 0 )
00638     {
00639     printf( "%s, %d: Could not do h5io_mk_ds for SCAttitude\n", 
00640       __FILE__, __LINE__ );
00641     return 1;
00642     }
00643   if( h5io_wr_ds( &ds_id, (void *)flt_data ) != 0 )
00644     {
00645     printf( "%s, %d: Could not write to SCAttitude\n", __FILE__, __LINE__ );
00646     return 1;
00647     }
00648   if( h5io_close( &ds_id ) != 0 )
00649     {
00650     printf( "%s, %d: Could not close SCAttitude\n", __FILE__, __LINE__ );
00651     return 1;
00652     }
00653  /*
00654   *  SCPosition SC position, ECR coords., from geoloc dataset
00655   */
00656   for( i = 0; i < out_rec->nscan * 3; i++ )
00657     *( flt_data + i ) = *( sdr_info->geo_pos + i ) * 1000.;
00658  /*  free the space as it is no longer in use */
00659   free( sdr_info->geo_pos );
00660   dim_siz2[0] = out_rec->nscan;
00661   dim_siz2[1] = 3;
00662   if( h5io_mk_ds( gid, "SCPosition", H5T_IEEE_F32BE, 2, dim_siz2,
00663      &ds_id ) != 0 )
00664     {
00665     printf( "%s, %d: Could not do h5io_mk_ds for SCPosition\n", 
00666       __FILE__, __LINE__ );
00667     return 1;
00668     }
00669   if( h5io_wr_ds( &ds_id, (void *)flt_data ) != 0 )
00670     {
00671     printf( "%s, %d: Could not write to SCPosition\n", __FILE__, __LINE__ );
00672     return 1;
00673     }
00674   if( h5io_close( &ds_id ) != 0 )
00675     {
00676     printf( "%s, %d: Could not close SCPosition\n", __FILE__, __LINE__ );
00677     return 1;
00678     }
00679  /*
00680   *  SCSolarAzimuthAngle - 48 array of az angle on solar diffuser
00681   */
00682   for( i = 0; i < out_rec->nscan; i++ )
00683     *( flt_data + i ) = 0.;
00684   dim_siz2[0] = out_rec->nscan;
00685   if( h5io_mk_ds( gid, "SCSolarAzimuthAngle", H5T_IEEE_F32BE, 1, dim_siz2, 
00686     &ds_id ) != 0 )
00687     {
00688     printf( "%s, %d: Could not do h5io_mk_ds for SCSolarAzimuthAngle\n", 
00689       __FILE__, __LINE__ );
00690     return 1;
00691     }
00692   if( h5io_wr_ds( &ds_id, (void *)flt_data ) != 0 )
00693     {
00694     printf( "%s, %d: Could not write to SCSolarAzimuthAngle\n", 
00695       __FILE__, __LINE__ );
00696     return 1;
00697     }
00698   if( h5io_close( &ds_id ) != 0 )
00699     {
00700     printf( "%s, %d: Could not close SCSolarAzimuthAngle\n", 
00701       __FILE__, __LINE__ );
00702     return 1;
00703     }
00704  /*
00705   *  SCSolarZenithAngle - a 48 array of zen angle on solar diffuser
00706   */
00707   for( i = 0; i < out_rec->nscan; i++ )
00708     *( flt_data + i ) = 0.;
00709   dim_siz2[0] = out_rec->nscan;
00710   if( h5io_mk_ds( gid, "SCSolarZenithAngle", H5T_IEEE_F32BE, 1, dim_siz2,
00711     &ds_id ) != 0 )
00712     {
00713     printf( "%s, %d: Could not do h5io_mk_ds for SCSolarZenithAngle\n", 
00714       __FILE__, __LINE__ );
00715     return 1;
00716     }
00717   if( h5io_wr_ds( &ds_id, (void *)flt_data ) != 0 )
00718     {
00719     printf( "%s, %d: Could not write to SCSolarZenithAngle\n", 
00720       __FILE__, __LINE__ );
00721     return 1;
00722     }
00723   if( h5io_close( &ds_id ) != 0 )
00724     {
00725     printf( "%s, %d: Could not close SCSolarZenithAngle\n", 
00726       __FILE__, __LINE__ );
00727     return 1;
00728     }
00729  /*
00730   *  SCVelocity -- get from geoloc dataset
00731   */
00732   dim_siz2[0] = out_rec->nscan;
00733   dim_siz2[1] = 3;
00734   for( i = 0; i < out_rec->nscan * 3; i++ )
00735     *( flt_data + i ) = *( sdr_info->geo_vel + i ) * 1000.;
00736  /*  free the space as it is no longer in use */
00737   free( sdr_info->geo_vel );
00738   if( h5io_mk_ds( gid, "SCVelocity", H5T_IEEE_F32BE, 2, dim_siz2,
00739      &ds_id ) != 0 )
00740     {
00741     printf( "%s, %d: Could not do h5io_mk_ds for SCVelocity\n", 
00742       __FILE__, __LINE__ );
00743     return 1;
00744     }
00745   if( h5io_wr_ds( &ds_id, (void *)flt_data ) != 0 )
00746     {
00747     printf( "%s, %d: Could not write to SCVelocity\n", __FILE__, __LINE__ );
00748     return 1;
00749     }
00750   if( h5io_close( &ds_id ) != 0 )
00751     {
00752     printf( "%s, %d: Could not close SCVelocity\n", __FILE__, __LINE__ );
00753     return 1;
00754     }
00755  /*
00756   *  SatelliteAzimuthAngle
00757   */
00758   if( h5io_set_ds( &( in_rec->geo_fid ), "sena", 
00759     &( in_rec->geo_dat_id[2] ) ) != 0 )
00760     {
00761     printf( "%s, %d: Could not do h5io_set_ds for sena\n", __FILE__, __LINE__ );
00762     return 1;
00763     }
00764 
00765   if( h5io_mk_ds( gid, "SatelliteAzimuthAngle", H5T_IEEE_F32BE, 2, 
00766     dim_siz, &( out_rec->geo_dat_id[2] ) ) != 0 )
00767     {
00768     printf( "%s, %d: Could not do h5io_mk_ds for SatelliteAzimuthAngle\n", 
00769       __FILE__, __LINE__ );
00770     return 1;
00771     }
00772 
00773   if( ( in_rec->sena = (float *) malloc( in_rec->npix * in_rec->ndet_scan * 
00774     sizeof(float) ) ) == NULL )
00775     {
00776     printf( 
00777       "%s, %d: Could not allocate transfer buffer for SatelliteAzimuthAngle\n", 
00778       __FILE__, __LINE__ );
00779     return 1;
00780     }
00781   out_rec->sena = in_rec->sena;
00782  /*
00783   *  SatelliteRange -- We may be able to get, but not necessary now
00784   *    Just zero out
00785   */
00786   for( i = 0; i < out_rec->npix * out_rec->nlin; i++ )
00787     *( flt_data + i ) = 0.;
00788   if( h5io_mk_ds( gid, "SatelliteRange", H5T_IEEE_F32BE, 2, dim_siz, &ds_id )
00789     != 0 )
00790     {
00791     printf( "%s, %d: Could not do h5io_mk_ds for SatelliteRange\n", 
00792       __FILE__, __LINE__ );
00793     return 1;
00794     }
00795   if( h5io_wr_ds( &ds_id, (void *)flt_data ) != 0 )
00796     {
00797     printf( "%s, %d: Could not write to SatelliteRange\n", __FILE__, __LINE__ );
00798     return 1;
00799     }
00800   if( h5io_close( &ds_id ) != 0 )
00801     {
00802     printf( "%s, %d: Could not close SatelliteRange\n", __FILE__, __LINE__ );
00803     return 1;
00804     }
00805  /*
00806   *  SatelliteZenithAngle
00807   */
00808   if( h5io_set_ds( &( in_rec->geo_fid), "senz", 
00809     &( in_rec->geo_dat_id[3] ) ) != 0 )
00810     {
00811     printf( "%s, %d: Could not do h5io_set_ds for senz\n", __FILE__, __LINE__ );
00812     return 1;
00813     }
00814 
00815   if( h5io_mk_ds( gid, "SatelliteZenithAngle", H5T_IEEE_F32BE, 2, 
00816     dim_siz, &( out_rec->geo_dat_id[3] ) ) != 0 )
00817     {
00818     printf( "%s, %d: Could not do h5io_mk_ds for SatelliteZenithAngle\n", 
00819       __FILE__, __LINE__ );
00820     return 1;
00821     }
00822 
00823   if( ( in_rec->senz = (float *) malloc( in_rec->npix * in_rec->ndet_scan * 
00824     sizeof(float) ) ) == NULL )
00825     {
00826     printf( 
00827       "%s, %d: Could not allocate transfer buffer for SatelliteZenithAngle\n", 
00828       __FILE__, __LINE__ );
00829     return 1;
00830     }
00831   out_rec->senz = in_rec->senz;
00832  /*
00833   *  SolarAzimuthAngle
00834   */
00835   if( h5io_set_ds( &( in_rec->geo_fid), "sola", 
00836     &( in_rec->geo_dat_id[4] ) ) != 0 )
00837     {
00838     printf( "%s, %d: Could not do h5io_set_ds on sola\n", __FILE__, __LINE__ );
00839     return 1;
00840     }
00841 
00842   if( h5io_mk_ds( gid, "SolarAzimuthAngle", H5T_IEEE_F32BE, 2, dim_siz, 
00843     &( out_rec->geo_dat_id[4] ) ) != 0 )
00844     {
00845     printf( "%s, %d: Could not do h5io_mk_ds for SolarAzimuthAngle\n", 
00846       __FILE__, __LINE__ );
00847     return 1;
00848     }
00849 
00850   if( ( in_rec->solz = (float *) malloc( in_rec->npix * in_rec->ndet_scan * 
00851     sizeof(float) ) ) == NULL )
00852     {
00853     printf( 
00854       "%s, %d: Could not allocate transfer buffer for SolarAzimuthAngle\n", 
00855       __FILE__, __LINE__ );
00856     return 1;
00857     }
00858   out_rec->solz = in_rec->solz;
00859  /*
00860   *  SolarZenithAngle
00861   */
00862   if( h5io_set_ds( &( in_rec->geo_fid), "solz", 
00863     &( in_rec->geo_dat_id[5] ) ) != 0 )
00864     {
00865     printf( "%s, %d: Could not do h5io_set_ds on solz\n", __FILE__, __LINE__ );
00866     return 1;
00867     }
00868 
00869   if( h5io_mk_ds( gid, "SolarZenithAngle", H5T_IEEE_F32BE, 2, dim_siz, 
00870     &( out_rec->geo_dat_id[5] ) ) != 0 )
00871     {
00872     printf( "%s, %d: Could not do h5io_mk_ds for SolarZenithAngle\n", 
00873       __FILE__, __LINE__ );
00874     return 1;
00875     }
00876 
00877   if( ( in_rec->sola = (float *) malloc( in_rec->npix * in_rec->ndet_scan * 
00878     sizeof(float) ) ) == NULL )
00879     {
00880     printf( "%s, %d: Could not allocate transfer buffer for SolarZenithAngle\n",
00881        __FILE__, __LINE__ );
00882     return 1;
00883     }
00884   out_rec->sola = in_rec->sola;
00885  /*
00886   *  StartTime, again the microsecs
00887   */
00888   dbl_data = (double *) malloc( out_rec->nscan * sizeof(double) );
00889   if( h5io_set_ds( &( in_rec->geo_fid), "time", &in_ds_id ) != 0 )
00890     {
00891     printf( "%s, %d: Could not do h5io_set_ds for time\n", __FILE__, __LINE__ );
00892     return 1;
00893     }
00894   if( h5io_rd_ds( &in_ds_id, (void *)dbl_data ) != 0 )
00895     {
00896     printf( "%s, %d: Could not read time\n", __FILE__, __LINE__ );
00897     return 1;
00898     }
00899   if( h5io_close( &in_ds_id ) != 0 )
00900     {
00901     printf( "%s, %d: Could not close time\n", __FILE__, __LINE__ );
00902     return 1;
00903     }
00904 
00905   llon_data = (int64 *) malloc( out_rec->nscan * sizeof(int64) );
00906   for( i = 0; i < out_rec->nscan; i++ )
00907     *( llon_data + i ) = sdr_info->t58_day +
00908        (int64) ( *( dbl_data + i ) * 1e6 );
00909   dim_siz2[0] = out_rec->nscan;
00910   if( h5io_mk_ds( gid, "StartTime", H5T_STD_I64BE, 1, dim_siz2, &ds_id )
00911     != 0 )
00912     {
00913     printf( "%s, %d: Could not do h5io_mk_ds for StartTime\n", 
00914       __FILE__, __LINE__ );
00915     return 1;
00916     }
00917   if( h5io_wr_ds( &ds_id, (void *)llon_data ) != 0 )
00918     {
00919     printf( "%s, %d: Could not write StartTime\n", __FILE__, __LINE__ );
00920     return 1;
00921     }
00922   if( h5io_close( &ds_id ) != 0 )
00923     {
00924     printf( "%s, %d: Could not close StartTime\n", __FILE__, __LINE__ );
00925     return 1;
00926     }
00927 
00928   free( flt_data );
00929   return 0;
00930   }
00931 
00932 
00933 int init_bnd_data( int ibnd, sdr_info_struc *sdr_info, in_rec_struc *in_rec,
00934   out_rec_struc *out_rec )
00935 /*-----------------------------------------------------------------------------
00936     Routine:   init_bnd_data
00937 
00938     Description:  make the data arrays for the band files and fill some
00939 
00940     Arguments:
00941         Type      Name         I/O   Description
00942         ----      ----         ---   -----------
00943         int       ibnd          I    band index 0 is band M1...
00944         sdr_info_struc * sdr_info I/O  general SDR information
00945         in_rec_struc * in_rec  I/O  input file information
00946         out_rec_struc * out_rec I/O  output file information
00947 
00948     Modification history:
00949 
00950     W. Robinson, SAIC  9 Dec 2008  Original development
00951     W. Robinson, SAIC  7 Jul 2010  add ability to make all 16 M bands
00952     W. Robinson, SAIC  24 Feb 2011 switch scale, offset values to those used
00953                           by IDPS (keep old method commented just in case)
00954 
00955 ----------------------------------------------------------------------------*/
00956   {
00957   h5io_str ds_id, *gid;
00958   int dim_siz[2], dim_siz2[2], *arr_int, i, isdr, iret;
00959   static unsigned char m_side = 0;
00960   unsigned char *uchar_data;
00961   unsigned int *uint32_data;
00962   float rad_fac[2], refl_fac[2]; /* versions of scale, offset for sdr
00963       scaled values */
00964   /*  float lam_um;  --- not used currently, but may come back */
00965  /*  these values are scale, offset used/found in IDPS SDR files.  Some 
00966      match my F0 assumptions well, but just use IDPS to avoid confusion 
00967      Used for RadianceFactors, ReflectanceFactors and 
00968      BrightnessTemperatureFactors */
00969   static float lcl_scale[] = { 0.0112657, 0.0125841, 1., 1., 1., 0.000752209,
00970     1., 0.00302196, 0.00141331, 0.00130450, 0.000582661, 5.17344e-05, 
00971     1., 0.000321547, 0.000313153, 0.000265539 };
00972   static float lcl_offset[] = { -0.21, -0.2, 0., 0., 0., -0.09, 0., -0.14,
00973     -0.09, -0.04, -0.02, 0., 0., -0.03, -0.02, -0.02 };
00974   static float lcl_scale_ref[] = { 2.28913e-05, 2.28913e-05, 2.28913e-05,
00975     2.28913e-05, 2.28913e-05, 2.28913e-05, 2.28913e-05, 2.28913e-05, 
00976     2.28913e-05, 2.28913e-05, 2.28913e-05, 0.00251805, 1., 0.00373892,
00977     0.00412044, 0.00425779 };
00978   static float lcl_offset_ref[] = { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 
00979     0., 203., 0., 120., 111., 103. };
00980  /*
00981   *  define gid for convenience
00982   */
00983   m_side = 0;
00984   isdr = ibnd + 1;  /*  isdr is also the commonly known band # M1, ...  */
00985   gid = &( out_rec->sdr_dat_gid[1][isdr] );
00986  /*
00987   *  datasets are:
00988   *  ModeGran 1 value, 1 is day, so fill with 1
00989   */
00990   uchar_data = (unsigned char *) malloc( out_rec->nscan *
00991     sizeof( unsigned char ) );
00992   *uchar_data = 1;
00993   dim_siz2[0] = 1;
00994   if( h5io_mk_ds( gid, "ModeGran", H5T_STD_U8BE, 1, dim_siz2, &ds_id )
00995     != 0 )
00996     {
00997     printf( "%s, %d: Could not do h5io_mk_ds for ModeGran\n", 
00998       __FILE__, __LINE__ );
00999     return 1;
01000     }
01001   if( h5io_wr_ds( &ds_id, (void *)uchar_data ) != 0 )
01002     {
01003     printf( "%s, %d: Could not write to ModeGran\n", __FILE__, __LINE__ );
01004     return 1;
01005     }
01006   if( h5io_close( &ds_id ) != 0 )
01007     {
01008     printf( "%s, %d: Could not close ModeGran\n", __FILE__, __LINE__ );
01009     return 1;
01010     }
01011   free( uchar_data );
01012  /*
01013   *  ModeScan 48 bytes, 1 is day, so fill with 1
01014   */
01015   uchar_data = (unsigned char *) malloc( out_rec->nscan *
01016     sizeof( unsigned char ) );
01017   for( i = 0; i < out_rec->nscan; i++ )
01018     *( uchar_data + i ) = 1;
01019   dim_siz2[0] = out_rec->nscan;
01020   if( h5io_mk_ds( gid, "ModeScan", H5T_STD_U8BE, 1, dim_siz2, &ds_id )
01021     != 0 )
01022     {
01023     printf( "%s, %d: Could not do h5io_mk_ds for ModeScan\n", 
01024       __FILE__, __LINE__ );
01025     return 1;
01026     }
01027   if( h5io_wr_ds( &ds_id, (void *)uchar_data ) != 0 )
01028     {
01029     printf( "%s, %d: Could not write to ModeScan\n", __FILE__, __LINE__ );
01030     return 1;
01031     }
01032   if( h5io_close( &ds_id ) != 0 )
01033     {
01034     printf( "%s, %d: Could not close ModeScan\n", __FILE__, __LINE__ );
01035     return 1;
01036     }
01037   free( uchar_data );
01038  /*
01039   *  NumberOfBadChecksums
01040   */
01041   arr_int = (int *)malloc( out_rec->nscan * sizeof( int ) );
01042   for( i = 0; i < out_rec->nscan; i++ )
01043     *( arr_int + i ) = 1;
01044   dim_siz2[0] = out_rec->nscan;
01045   if( h5io_mk_ds( gid, "NumberOfBadChecksums", H5T_STD_I32BE, 1, 
01046     dim_siz2, &ds_id ) != 0 )
01047     {
01048     printf( "%s, %d: Could not do h5io_mk_ds for NumberOfBadChecksums\n", 
01049       __FILE__, __LINE__ );
01050     return 1;
01051     }
01052   if( h5io_wr_ds( &ds_id, (void *)arr_int ) != 0 )
01053     {
01054     printf( "%s, %d: Could not write to NumberOfBadChecksums\n", 
01055       __FILE__, __LINE__ );
01056     return 1;
01057     }
01058   if( h5io_close( &ds_id ) != 0 )
01059     {
01060     printf( "%s, %d: Could not close NumberOfBadChecksums\n", 
01061       __FILE__, __LINE__ );
01062     return 1;
01063     }
01064   free( arr_int );
01065  /*
01066   *  NumberOfDiscardedPackets
01067   */
01068   arr_int = (int *)malloc( out_rec->nscan * sizeof( int ) );
01069   for( i = 0; i < out_rec->nscan; i++ )
01070     *( arr_int + i ) = 1;
01071   dim_siz2[0] = out_rec->nscan;
01072   if( h5io_mk_ds( gid, "NumberOfDiscardedPackets", H5T_STD_I32BE, 1,
01073     dim_siz2, &ds_id ) != 0 )
01074     {
01075     printf( "%s, %d: Could not do h5io_mk_ds for NumberOfDiscardedPackets\n",
01076       __FILE__, __LINE__ );
01077     return 1;
01078     }
01079   if( h5io_wr_ds( &ds_id, (void *)arr_int ) != 0 )
01080     {
01081     printf( "%s, %d: Could not write to NumberOfDiscardedPackets\n", 
01082       __FILE__, __LINE__ );
01083     return 1;
01084     }
01085   if( h5io_close( &ds_id ) != 0 )
01086     {
01087     printf( "%s, %d: Could not close NumberOfDiscardedPackets\n", 
01088       __FILE__, __LINE__ );
01089     return 1;
01090     }
01091   free( arr_int );
01092  /*
01093   *  NumberOfMissingPkts
01094   */
01095   arr_int = (int *)malloc( out_rec->nscan * sizeof( int ) );
01096   for( i = 0; i < out_rec->nscan; i++ )
01097     *( arr_int + i ) = 1;
01098   dim_siz2[0] = out_rec->nscan;
01099   if( h5io_mk_ds( gid, "NumberOfMissingPkts", H5T_STD_I32BE, 1,
01100     dim_siz2, &ds_id ) != 0 )
01101     {
01102     printf( "%s, %d: Could not do h5io_mk_ds for NumberOfMissingPkts\n",
01103       __FILE__, __LINE__ );
01104     return 1;
01105     }
01106   if( h5io_wr_ds( &ds_id, (void *)arr_int ) != 0 )
01107     {
01108     printf( "%s, %d: Could not write to NumberOfMissingPkts\n", 
01109       __FILE__, __LINE__ );
01110     return 1;
01111     }
01112   if( h5io_close( &ds_id ) != 0 )
01113     {
01114     printf( "%s, %d: Could not close NumberOfMissingPkts\n", 
01115       __FILE__, __LINE__ );
01116     return 1;
01117     }
01118   free( arr_int );
01119  /*
01120   *  NumberOfScans
01121   */
01122   arr_int = (int *)malloc( sizeof( int ) );
01123   *arr_int = out_rec->nscan;
01124   dim_siz[0] = 1;
01125   if( h5io_mk_ds( gid, "NumberOfScans", H5T_STD_I32BE, 1, dim_siz, &ds_id )
01126     != 0 )
01127     {
01128     printf( "%s, %d: Could not do h5io_mk_ds for NumberOfScans\n", 
01129       __FILE__, __LINE__ );
01130     return 1;
01131     }
01132   if( h5io_wr_ds( &ds_id, (void *)arr_int ) != 0 )
01133     {
01134     printf( "%s, %d: Could not write to NumberOfScans\n", __FILE__, __LINE__ );
01135     return 1;
01136     }
01137   if( h5io_close( &ds_id ) != 0 )
01138     {
01139     printf( "%s, %d: Could not close NumberOfScans\n", __FILE__, __LINE__ );
01140     return 1;
01141     }
01142   free( arr_int );
01143  /*
01144   *  PadByte1 ( 3 values of 0)  -- just fill with 0 for the 3 values
01145   */
01146   uchar_data = (unsigned char *) malloc( 3 * sizeof( unsigned char ) );
01147   for( i = 0; i < 3; i++ )
01148     *( uchar_data + i ) = 0;
01149   dim_siz[0] = 3;
01150   if( h5io_mk_ds( gid, "PadByte1", H5T_STD_U8BE, 1, dim_siz, &ds_id )
01151     != 0 )
01152     {
01153     printf( "%s, %d: Could not do h5io_mk_ds for PadByte1\n", 
01154       __FILE__, __LINE__ );
01155     return 1;
01156     }
01157   if( h5io_wr_ds( &ds_id, (void *)uchar_data ) != 0 )
01158     {
01159     printf( "%s, %d: Could not write to PadByte1\n", __FILE__, __LINE__ );
01160     return 1;
01161     }
01162   if( h5io_close( &ds_id ) != 0 )
01163     {
01164     printf( "%s, %d: Could not close PadByte1\n", __FILE__, __LINE__ );
01165     return 1;
01166     }
01167   free( uchar_data );
01168  /*
01169   *  QF1_VIIRSMBANDSDR  Qual flag for all pixels
01170   *  set up dataset ids for each band
01171   */
01172   dim_siz[0] = out_rec->nlin;
01173   dim_siz[1] = out_rec->npix;
01174   if( h5io_mk_ds( gid, "QF1_VIIRSMBANDSDR", H5T_STD_U8BE, 2, dim_siz, 
01175     &( out_rec->qual1_m_id[ibnd] ) ) != 0 )
01176     {
01177     printf( "%s, %d: Could not do h5io_mk_ds for QF1_VIIRSMBANDSDR\n", 
01178       __FILE__, __LINE__ );
01179     return 1;
01180     }
01181  /*
01182   *  and set a 0 filled default array
01183   */
01184   if( ( out_rec->qual1_m[ibnd] = ( unsigned char *) 
01185     calloc( out_rec->npix * out_rec->ndet_scan, sizeof( unsigned char ) ) )
01186     == NULL )
01187     {
01188     printf( "%s, %d: Could not allocate space for qual1_m output for band %d\n",
01189       __FILE__, __LINE__, ibnd );
01190     return 1;
01191     }
01192  /*
01193   *  QF2_SCAN_SDR has more qual plus HAM mirror side in low bit
01194   *  also set it in the sdr_info ham_side array
01195   */
01196   uchar_data = (unsigned char *) calloc( out_rec->nscan, 
01197     sizeof( unsigned char ) );
01198   for( i = 0; i < out_rec->nscan; i++ )
01199     {
01200     *( uchar_data + i ) = m_side;
01201     m_side = 1 - m_side;
01202     *( sdr_info->ham_side + i ) = m_side;
01203     }
01204   dim_siz[0] = out_rec->nscan;
01205   if( h5io_mk_ds( gid, "QF2_SCAN_SDR", H5T_STD_U8BE, 1, dim_siz, &ds_id )
01206     != 0 )
01207     {
01208     printf( "%s, %d: Could not do h5io_mk_ds for QF2_SCAN_SDR\n", 
01209       __FILE__, __LINE__ );
01210     return 1;
01211     }
01212   if( h5io_wr_ds( &ds_id, (void *)uchar_data ) != 0 )
01213     {
01214     printf( "%s, %d: Could not write to QF2_SCAN_SDR\n", __FILE__, __LINE__ );
01215     return 1;
01216     }
01217   if( h5io_close( &ds_id ) != 0 )
01218     {
01219     printf( "%s, %d: Could not close QF2_SCAN_SDR\n", __FILE__, __LINE__ );
01220     return 1;
01221     }
01222   free( uchar_data );
01223  /*
01224   *  QF3_SCAN_RDR  a nscan x 4 value array
01225   */
01226   dim_siz[0] = out_rec->nscan;
01227   dim_siz[1] = 4;
01228   uint32_data = (unsigned int *) 
01229     calloc( dim_siz[0] * dim_siz[1], sizeof( unsigned int ) );
01230   if( h5io_mk_ds( gid, "QF3_SCAN_RDR", H5T_STD_U32BE, 2, dim_siz, &ds_id )
01231     != 0 )
01232     {
01233     printf( "%s, %d: Could not do h5io_mk_ds for QF3_SCAN_RDR\n", 
01234       __FILE__, __LINE__ );
01235     return 1;
01236     }
01237   if( h5io_wr_ds( &ds_id, (void *)uint32_data ) != 0 )
01238     {
01239     printf( "%s, %d: Could not write to QF3_SCAN_RDR\n", __FILE__, __LINE__ );
01240     return 1;
01241     }
01242   if( h5io_close( &ds_id ) != 0 )
01243     {
01244     printf( "%s, %d: Could not close QF3_SCAN_RDR\n", __FILE__, __LINE__ );
01245     return 1;
01246     }
01247   free( uint32_data );
01248  /*
01249   * QF4_SCAN_SDR 768 values reduced line quality # lines in size
01250   */
01251   uchar_data = (unsigned char *) calloc( out_rec->nlin,
01252     sizeof( unsigned char ) );
01253   dim_siz2[0] = out_rec->nlin;
01254   if( h5io_mk_ds( gid, "QF4_SCAN_SDR", H5T_STD_U8BE, 1, dim_siz2, &ds_id )
01255     != 0 )
01256       {
01257     printf( "%s, %d: Could not do h5io_mk_ds for QF4_SCAN_SDR\n", 
01258       __FILE__, __LINE__ );
01259     return 1;
01260     }
01261   if( h5io_wr_ds( &ds_id, (void *)uchar_data ) != 0 )
01262     {
01263     printf( "%s, %d: Could not write to QF4_SCAN_SDR\n", __FILE__, __LINE__ );
01264     return 1;
01265     }
01266   if( h5io_close( &ds_id ) != 0 )
01267     {
01268     printf( "%s, %d: Could not close QF4_SCAN_SDR\n", __FILE__, __LINE__ );
01269     return 1;
01270     }
01271   free( uchar_data );
01272  /*
01273   * QF5_GRAN_BADDETECTOR 16 values 0 if not any bad detectors
01274   */
01275   uchar_data = (unsigned char *) calloc( out_rec->ndet_scan, 
01276     sizeof( unsigned char ) );
01277   dim_siz2[0] = out_rec->ndet_scan;
01278   if( h5io_mk_ds( gid, "QF5_GRAN_BADDETECTOR", H5T_STD_U8BE, 1, dim_siz2, 
01279     &ds_id ) != 0 )
01280       {
01281     printf( "%s, %d: Could not do h5io_mk_ds for QF5_GRAN_BADDETECTOR\n", 
01282       __FILE__, __LINE__ );
01283     return 1;
01284     }
01285   if( h5io_wr_ds( &ds_id, (void *)uchar_data ) != 0 )
01286     {
01287     printf( "%s, %d: Could not write to QF5_GRAN_BADDETECTOR\n", 
01288       __FILE__, __LINE__ );
01289     return 1;
01290     }
01291   if( h5io_close( &ds_id ) != 0 )
01292     {
01293     printf( "%s, %d: Could not close QF5_GRAN_BADDETECTOR\n", 
01294       __FILE__, __LINE__ );
01295     return 1;
01296     }
01297   free( uchar_data );
01298  /*
01299   *  Radiance This is a scan-by-scan output item
01300   */
01301   dim_siz[0] = out_rec->nlin;
01302   dim_siz[1] = out_rec->npix;
01303  /*
01304   *  There will have to be an initialization for the input radiance 
01305   *  dataset dependent on if we do a dummy or take from a L2. If we 
01306   *  follow the model for init_geo_data, it is put here.  However, input
01307   *  data for the TOA radiances either are dummy values or come from
01308   *  the L2 made by running l2gen in reverse.  So, the initialization of 
01309   *  input rads is best done in rd_l2_init under rd_sim_init. 
01310   */
01311  /*
01312   *  The radiance dataset is either unsigned short or float depending on
01313   *  the band number (argh), so set up accordingly
01314   */
01315   if( out_rec->out_bnd_typ[ibnd] == 0 )
01316     iret = h5io_mk_ds( gid, "Radiance", H5T_STD_U16BE, 2, dim_siz,
01317       &( out_rec->bnd_dat_id[0][ibnd] ) );
01318   else
01319     iret = h5io_mk_ds( gid, "Radiance", H5T_IEEE_F32BE, 2, dim_siz,
01320       &( out_rec->bnd_dat_id[0][ibnd] ) );
01321   if( iret != 0 )
01322     {
01323     printf( "%s, %d: Could not do h5io_mk_ds for Radiance\n", 
01324       __FILE__, __LINE__ );
01325     return 1;
01326     }
01327  /*
01328   *  allocate the data transfer buffer and make it the same for output
01329   *  Note that dn storage allocation (if needed) is done above in init_sdr
01330   */
01331   if( ( in_rec->bnd_lt[ibnd] = (float *) 
01332     malloc( in_rec->npix * in_rec->ndet_scan * sizeof(float) ) ) 
01333     == NULL )
01334     {
01335     printf( 
01336       "%s, %d: Could not allocate space for radiance data transfer buffer\n",
01337       __FILE__, __LINE__ );
01338     return 1;
01339     }
01340 
01341   out_rec->bnd_lt[ibnd] = in_rec->bnd_lt[ibnd];
01342  /*
01343   *  set up the flags for the radiances - for missing or bad value output
01344   */
01345   if( ( in_rec->bnd_q[ibnd] = (unsigned char *)
01346     malloc( in_rec->npix * in_rec->ndet_scan * sizeof(unsigned char) ) ) 
01347     == NULL )
01348     {
01349     printf( 
01350       "%s, %d: Could not allocate space for output radiance flag buffer\n",
01351       __FILE__, __LINE__ );
01352     return 1;
01353     }
01354   out_rec->bnd_q[ibnd] = in_rec->bnd_q[ibnd];
01355  /*
01356   *  RadianceFactors - 2 floats of scale and offset:
01357   *  only needed for scaled bands
01358   *  Lt = <scale> * count + <offset>
01359   *  short of finding min, max in granule, could do
01360   *  <offset> = 0, <scale> = 1.3 * f0(lambda) / ( PI * ( max_short - 10 ) )
01361   *  the f0 is in MKS already and the 1.3 is to allow some room
01362   *
01363   *  24 Feb 2011 WDR This and reflectance set-up does suprisingly well at 
01364   *  matching the IDPS scale... except for offset and in bands that saturate
01365   *  KEEP the old methods for setup and add the aray list set
01366   */
01367   dim_siz[0] = 2;
01368  /*
01369   *  The scaling is only set different from [1., 0.] for the scaled radiances
01370   */
01371   if( out_rec->out_bnd_typ[ibnd] == 0 )
01372     {
01373     /*  KEEP, initial way of computing using F0 or top BBT of 500K
01374        *** ALSO note that if this is used again, the scale, offset needs to 
01375        be for radiance all the way through, not changing to BBT for M12 - 16
01376     if( out_rec->meas_typ[ibnd] == 0 )
01377       {
01378       out_rec->scale[ibnd] = ( 1.3 * out_rec->f0[ibnd] ) / 
01379         ( M_PI * ( float ) ( SOUB_UINT16_FILL - 1 ) );
01380       out_rec->offset[ibnd] = 0.;
01381       }
01382     else
01383       {
01384       lam_um = (float) out_rec->lam_band[ibnd] /1000.;
01385       out_rec->scale[ibnd] = bbt_2_rad( 500., lam_um ) /
01386         (float) ( SOUB_UINT16_FILL - 1 );
01387       out_rec->offset[ibnd] = 0.;
01388       }
01389     */
01390    /*  Use IDPS scale offset for radiance scaling */
01391     out_rec->scale[ibnd] = lcl_scale[ibnd];
01392     out_rec->offset[ibnd] = lcl_offset[ibnd];
01393     }
01394   else
01395     {
01396     out_rec->scale[ibnd] = 1.;
01397     out_rec->offset[ibnd] = 0.;
01398     }
01399   rad_fac[0] = out_rec->scale[ibnd];
01400   rad_fac[1] = out_rec->offset[ibnd];
01401   if( h5io_mk_ds( gid, "RadianceFactors", H5T_IEEE_F32BE, 1, dim_siz, &ds_id )
01402     != 0 )
01403     {
01404     printf( "%s, %d: Could not do h5io_mk_ds for RadianceFactors\n", 
01405       __FILE__, __LINE__ );
01406     return 1;
01407     }
01408   if( h5io_wr_ds( &ds_id, (void *)rad_fac ) != 0 )
01409     {
01410     printf( "%s, %d: Could not write to RadianceFactors\n", 
01411       __FILE__, __LINE__ );
01412     return 1;
01413     }
01414   if( h5io_close( &ds_id ) != 0 )
01415     {
01416     printf( "%s, %d: Could not close RadianceFactors\n", __FILE__, __LINE__ );
01417     return 1;
01418     }
01419   if( out_rec->meas_typ[ibnd] == 0 )
01420     {
01421    /*
01422     *  Reflectance - just set up the dataset for output
01423     */
01424     dim_siz[0] = out_rec->nlin;
01425     dim_siz[1] = out_rec->npix;
01426     if( h5io_mk_ds( gid, "Reflectance", H5T_STD_U16BE, 2, dim_siz,
01427       &( out_rec->bnd_dat_id[1][ibnd] ) ) != 0 )
01428       {
01429       printf( "%s, %d: Could not do h5io_mk_ds for Latitude\n", 
01430         __FILE__, __LINE__ );
01431       return 1;
01432       }
01433    /*
01434     *  ReflectanceFactors - 2 floats of scale and offset for all bands
01435     *  ref = <scale> * count + <offset>
01436     *  short of finding min, max in granule, could do
01437     *  <offset> = 0, <scale> = 1.5 / ( max_short - 10 )
01438     */
01439     dim_siz[0] = 2;
01440     /*  AGAIN as in RadianceFactors above, KEEP this, same caveats
01441     out_rec->refl_scale[ibnd] = 1.5 / ( float) ( SOUB_UINT16_FILL - 1 );
01442     out_rec->refl_offset[ibnd] = 0.;
01443     */
01444     out_rec->refl_scale[ibnd] = lcl_scale_ref[ibnd];
01445     out_rec->refl_offset[ibnd] = lcl_offset_ref[ibnd];
01446     refl_fac[0] = out_rec->refl_scale[ibnd];
01447     refl_fac[1] = out_rec->refl_offset[ibnd];
01448     if( h5io_mk_ds( gid, "ReflectanceFactors", H5T_IEEE_F32BE, 1, 
01449       dim_siz, &ds_id ) != 0 )
01450       {
01451       printf( "%s, %d: Could not do h5io_mk_ds for ReflectanceFactors\n", 
01452         __FILE__, __LINE__ );
01453       return 1;
01454       }
01455     if( h5io_wr_ds( &ds_id, (void *)refl_fac ) != 0 )
01456       {
01457       printf( "%s, %d: Could not write to ReflectanceFactors\n", 
01458         __FILE__, __LINE__ );
01459       return 1;
01460       }
01461     if( h5io_close( &ds_id ) != 0 )
01462       {
01463       printf( "%s, %d: Could not close ReflectanceFactors\n", 
01464         __FILE__, __LINE__ );
01465       return 1;
01466       }
01467     }
01468   else 
01469     {
01470    /*
01471     *  BBT, This is a scan-by-scan output item
01472     */
01473     dim_siz[0] = out_rec->nlin;
01474     dim_siz[1] = out_rec->npix;
01475    /*
01476     *  The BBT dataset is either unsigned short or float depending on
01477     *  the band number, so set up accordingly
01478     */
01479     if( out_rec->out_bnd_typ[ibnd] == 0 )
01480       iret = h5io_mk_ds( gid, "BrightnessTemperature", H5T_STD_U16BE, 2, 
01481         dim_siz, &( out_rec->bnd_dat_id[1][ibnd] ) );
01482     else
01483       iret = h5io_mk_ds( gid, "BrightnessTemperature", H5T_IEEE_F32BE, 2, 
01484       dim_siz, &( out_rec->bnd_dat_id[1][ibnd] ) );
01485     if( iret != 0 )
01486       {
01487       printf( "%s, %d: Could not do h5io_mk_ds for BrightnessTemperature\n", 
01488         __FILE__, __LINE__ );
01489       return 1;
01490       }
01491    /*
01492     *  BrightnessTemperatureFactors - 2 floats of scale and offset:
01493     *  only needed for scaled bands
01494     *  BBT = <scale> * count + <offset>
01495     *  short of finding min, max in granule, could do
01496     *  <offset> = 0, <scale> = 500. / ( max_short - 10 )
01497     *
01498     *  use the refl factor storage for the BBT scaling
01499     */
01500     dim_siz[0] = 2;
01501    /*
01502     *  The scaling is only set different from [1., 0.] for the scaled radiances
01503     */
01504     if( out_rec->out_bnd_typ[ibnd] == 0 )
01505       {
01506       /*  AGAIN as in RadianceFactors above, KEEP this, same caveats
01507       out_rec->refl_scale[ibnd] = 500. / ( ( float ) ( SOUB_UINT16_FILL - 1 ) );
01508       out_rec->refl_offset[ibnd] = 0.;
01509       */
01510       out_rec->refl_scale[ibnd] = lcl_scale_ref[ibnd];
01511       out_rec->refl_offset[ibnd] = lcl_offset_ref[ibnd];
01512       }
01513     else
01514       {
01515       out_rec->refl_scale[ibnd] = 1.;
01516       out_rec->refl_offset[ibnd] = 0.;
01517       }
01518     rad_fac[0] = out_rec->refl_scale[ibnd];
01519     rad_fac[1] = out_rec->refl_offset[ibnd];
01520     if( h5io_mk_ds( gid, "BrightnessTemperatureFactors", H5T_IEEE_F32BE, 
01521       1, dim_siz, &ds_id ) != 0 )
01522       {
01523       printf( 
01524         "%s, %d: Could not do h5io_mk_ds for BrightnessTemperatureFactors\n", 
01525         __FILE__, __LINE__ );
01526       return 1;
01527       }
01528     if( h5io_wr_ds( &ds_id, (void *)rad_fac ) != 0 )
01529       {
01530       printf( "%s, %d: Could not write to BrightnessTemperatureFactors\n", 
01531         __FILE__, __LINE__ );
01532       return 1;
01533       }
01534     if( h5io_close( &ds_id ) != 0 )
01535       {
01536       printf( "%s, %d: Could not close BrightnessTemperatureFactors\n", 
01537         __FILE__, __LINE__ );
01538       return 1;
01539       }
01540     }
01541   return 0;
01542   }
01543 
01544 
01545 int init_sdr_dpattr( int isdr, h5io_str *dat2_g_id, sdr_info_struc *sdr_info )
01546 /*-----------------------------------------------------------------------------
01547     Routine:   init_sdr_dpattr
01548 
01549     Description:  make the data product attributes for the sdr files
01550 
01551     Arguments:
01552         Type      Name         I/O   Description
01553         ----      ----         ---   -----------
01554         int       isdr          I    SDR file #
01555         h5io_str *  dat2_g_id   I    id for group to place attributes in
01556         sdr_info_struc*  sdr_info  I  structure to hold geolocation
01557                                      information
01558 
01559     Modification history:
01560 
01561     W. Robinson, SAIC  21 Oct 2008  Original development
01562 
01563 ----------------------------------------------------------------------------*/
01564   {
01565   int n_attr = 7, dims_1_1[] = { 1, 1 };
01566   int fsw_v = 0;
01567   char op_mode[] = "NPP Normal Operations, VIIRS Operational";
01568   int len_op_mode, len_domain;
01569 
01570   len_op_mode = strlen( op_mode );
01571   len_domain = strlen( sdr_info->domain );
01572   /* note that the attribute info is set up for the geo file and changes 
01573      are made for any band differences */
01574   h5attr_struc attrs[] = {
01575     { 1, 1, "Instrument_Short_name", H5T_NATIVE_CHAR, 6, 2, dims_1_1,
01576        (void *)"VIIRS" },
01577     { 1, 1, "N_Anc_Type_Tasked", H5T_NATIVE_CHAR, 9, 2,  dims_1_1,
01578        (void *)"Official" },
01579     { 1, 1, "N_Collection_Short_Name", H5T_NATIVE_CHAR, 17, 2,  dims_1_1,
01580        (void *)core_g_nm[isdr] },
01581     { 1, 1, "N_Dataset_Type_Tag", H5T_NATIVE_CHAR, 4, 2,  dims_1_1,
01582        (void *)"GEO" },
01583     { 0, 0, "N_Instrument_Flight_SW_Version", H5T_STD_I32BE, 0, 2, dims_1_1, 
01584        (void *)&fsw_v },
01585     { 1, 1, "N_Processing_Domain", H5T_NATIVE_CHAR, len_domain, 2,  dims_1_1,
01586        (void *)sdr_info->domain },
01587     { 1, 1, "Operation_Mode", H5T_NATIVE_CHAR, len_op_mode, 2,  dims_1_1,
01588        (void *)op_mode }
01589      };
01590  /*
01591   *  ATTRIB NOTES - hard coded except for domain and band specific for 
01592   *  N_Collection_Short_Name.  Some geo / band specific attrs
01593   */
01594   if( isdr > 0 )
01595     {
01596     /* the N_Anc_Type_Tasked needs to be repressed in the SDR */
01597     attrs[1].express = 0;
01598     /* the N_Dataset_Type_Tag is SDR for the band files */
01599     attrs[3].data = (void *)"SDR";
01600     /* the N_Instrument_Flight_SW_Version needs to be expressed in the SDR */
01601     attrs[4].express = 1;
01602     }
01603  /*
01604   *  output the attributes to the location
01605   */
01606   if( wr_attr_seq( dat2_g_id, n_attr, attrs ) != 0 )
01607     {
01608     printf( "%s, %d: Could not write data prod attributes\n", 
01609       __FILE__, __LINE__ );
01610     return 1;
01611     }
01612   return 0;
01613   }
01614 
01615 int init_sdr_agg( int isdr, h5io_str *gid, sdr_info_struc *sdr_info )
01616 /*-----------------------------------------------------------------------------
01617     Routine:   init_sdr_agg
01618 
01619     Description:  create the aggregation dataset and attributes 
01620       in the data products group for a SDR file
01621 
01622     Arguments:
01623         Type      Name         I/O   Description
01624         ----      ----         ---   -----------
01625         int       isdr          I    SDR file number
01626         h5io_str *  gid         I    id for group to place dataset and 
01627                                      attributes 
01628         sdr_info_struc *  sdr_info  I  structure to hold geolocation
01629                                      information
01630 
01631     Modification history:
01632 
01633     W. Robinson, SAIC  21 Oct 2008  Original development
01634 
01635 ----------------------------------------------------------------------------*/
01636   {
01637   int n_attr = 9, dims_1_1[] = { 1, 1 };
01638   char grp_name[100];
01639   uint64 abon = 14;
01640   int ang = 1;
01641   h5attr_struc attrs[] = {
01642     { 1, 1, "AggregateBeginningDate", H5T_NATIVE_CHAR, 9, 2, dims_1_1,
01643        (void *) sdr_info->st_date },
01644     { 1, 1, "AggregateBeginningGranuleID", H5T_NATIVE_CHAR, 16, 2, dims_1_1,
01645        (void *)"NPP001212012151" }, 
01646     { 1, 0, "AggregateBeginningOrbitNumber", H5T_STD_U64BE, 0, 2, dims_1_1,
01647        (void *)&abon },
01648     { 1, 1, "AggregateBeginningTime", H5T_NATIVE_CHAR, 15, 2, dims_1_1,
01649        (void *) sdr_info->st_time },
01650     { 1, 1, "AggregateEndingDate", H5T_NATIVE_CHAR, 9, 2, dims_1_1,
01651        (void *) sdr_info->en_date },
01652     { 1, 1, "AggregateEndingGranuleID", H5T_NATIVE_CHAR, 16, 2, dims_1_1,
01653        (void *)"NPP001212012151" },
01654     { 1, 0, "AggregateEndingOrbitNumber", H5T_STD_U64BE, 0, 2, dims_1_1,
01655        (void *)&abon },
01656     { 1, 1, "AggregateEndingTime", H5T_NATIVE_CHAR, 15, 2, dims_1_1,
01657        (void *) sdr_info->en_time },
01658     { 1, 0, "AggregateNumberGranules", H5T_STD_I32BE, 0, 2, dims_1_1,
01659        (void *)&ang }
01660      };
01661  /*
01662   *  ATTRIB NOTES - some values are hard-coded now
01663   */
01664   h5io_str ds_id;
01665   int dim_siz[2], *arr_int;
01666  /*
01667   *  the dataset is a reference dataset, so we'll forgo and just place an int
01668   */
01669   arr_int = (int *)malloc( sizeof( int ) );
01670   *arr_int = 666;
01671   dim_siz[0] = 1;
01672   sprintf( grp_name, "%s_Aggr", core_g_nm[isdr] );
01673   if( h5io_mk_ds( gid, grp_name, H5T_NATIVE_INT, 1, 
01674     dim_siz, &ds_id ) != 0 )
01675     {
01676     printf( "%s, %d: Could not do h5io_mk_ds for grp VIIRS-MOD-GEO-TC_Aggr\n", 
01677       __FILE__, __LINE__ );
01678     return 1;
01679     }
01680   if( h5io_wr_ds( &ds_id, (void *)arr_int ) != 0 )
01681     {
01682     printf( "%s, %d: Could not write to VIIRS-MOD-GEO-TC_Aggr\n", 
01683       __FILE__, __LINE__ );
01684     return 1;
01685     }
01686   free( arr_int );
01687  /*
01688   *  output the attributes to the location
01689   */
01690   if( wr_attr_seq( &ds_id, n_attr, attrs ) != 0 )
01691     {
01692     printf( 
01693       "%s, %d: Could not write top attributes for VIIRS-MOD-GEO-TC_Aggr\n", 
01694       __FILE__, __LINE__ );
01695     return 1;
01696     }
01697   if( h5io_close( &ds_id ) != 0 )
01698     {
01699     printf( "%s, %d: Could not close VIIRS-MOD-GEO-TC_Aggr\n", 
01700       __FILE__, __LINE__ );
01701     return 1;
01702     }
01703   return 0;
01704   }
01705 
01706 int init_sdr_gran( int isdr, h5io_str *gid, sdr_info_struc *sdr_info, out_rec_struc *out_rec )
01707 /*-----------------------------------------------------------------------------
01708     Routine:   init_geo_gran
01709 
01710     Description:  make the granule dataset and attributes under the data 
01711       products groups
01712 
01713     Arguments:
01714         Type      Name         I/O   Description
01715         ----      ----         ---   -----------
01716         int       isdr          I    SDR file number
01717         h5io_str *  dat2_g_id   I    id for group to place attributes in
01718         sdr_info_struc *  sdr_info  I  structure to hold geolocation
01719                                      information
01720         out_rec_struc * out_rec I    output record information
01721 
01722     Modification history:
01723 
01724     W. Robinson, SAIC  21 Oct 2008  Original development
01725     W. Robinson, SAIC  13 Oct 2011  change N_Granule_ID to be VYYYYMMDDHHMMSS
01726 
01727 ----------------------------------------------------------------------------*/
01728   {
01729   int n_attr = 49, dims_1_1[] = { 1, 1 }, len_str, i;
01730   int dims_8_1[] = { 8, 1 }, dims_9_1[] = { 9, 1 };
01731   int dims_2_1[] = { 2, 1 }, dims_anc[] = { 19, 1 }, dims_aux[] = { 5, 1 };
01732   int qual_sum_val[2];
01733   float g_ring_lat[8], g_ring_lon[8], gran_bdy[4], nadir_bdy[4];
01734   float fill = 0.;
01735   uint64 beg_orb = 14;
01736   char char33_9[33 * 9], band_id[4], char_100_49[100 * 49 ], grp_nam[100];
01737   char gran_vers[10] = "A1M", doc_ref[10] = "N/A";
01738   char *sw_vers = "viirs_sim_sdr_v0.0", gran_id[16];
01739   char qual_sum_name[ 26 * 2 ], char_anc[ 19 * 106 ], char_aux[ 5 * 106];
01740   unsigned char asc_dec = 0;
01741 
01742   len_str = strlen( sw_vers );
01743   sprintf( gran_id, "V%8.8s%6.6s", sdr_info->st_date, sdr_info->st_time );
01744   h5attr_struc attrs[] = {
01745     { 1, 0, "Ascending/Descending_Indicator", H5T_NATIVE_UCHAR, 0, 2, dims_1_1,
01746        (void *)&asc_dec },
01747     { 0, 1, "Band_ID", H5T_NATIVE_CHAR, 2, 2, dims_1_1,
01748        (void *)band_id },
01749     { 1, 1, "Beginning_Date", H5T_NATIVE_CHAR, 9, 2, dims_1_1,
01750        (void *) sdr_info->st_date }, 
01751     { 1, 1, "Beginning_Time", H5T_NATIVE_CHAR, 15, 2, dims_1_1,
01752        (void *) sdr_info->st_time },
01753     { 0, 0, "East_Bounding_Coordinate", H5T_IEEE_F32BE, 0, 2, dims_1_1,
01754        (void *)gran_bdy },
01755     { 1, 1, "Ending_Date", H5T_NATIVE_CHAR, 9, 2, dims_1_1,
01756        (void *) sdr_info->en_date },
01757     { 1, 1, "Ending_Time", H5T_NATIVE_CHAR, 15, 2, dims_1_1,
01758        (void *) sdr_info->en_time },
01759     { 1, 0, "G-Ring-Latitude", H5T_IEEE_F32BE, 0, 2, dims_8_1, 
01760       (void *)g_ring_lat },
01761     { 1, 0, "G-Ring-Longitude", H5T_IEEE_F32BE, 0, 2, dims_8_1, 
01762       (void *)g_ring_lon },
01763     { 1, 1, "N_Algorithm_Version", H5T_NATIVE_CHAR, 8, 2, dims_1_1,
01764        (void *) "Fill" },
01765     { 1, 1, "N_Anc_Filename", H5T_NATIVE_CHAR, 106, 2, dims_anc,
01766        (void *)char_anc },
01767     { 1, 1, "N_Aux_Filename", H5T_NATIVE_CHAR, 106, 2, dims_aux, 
01768        (void *)char_aux },
01769     { 1, 0, "N_Beginning_Orbit_Number", H5T_STD_U64BE, 0, 2, dims_1_1,
01770        (void *)&beg_orb },
01771     { 1, 0, "N_Beginning_Time_IET", H5T_STD_U64BE, 0, 1, dims_1_1,
01772        (void *)&( sdr_info->st_58_t ) },
01773     { 1, 1, "N_Creation_Date", H5T_NATIVE_CHAR, 9, 2, dims_1_1,
01774        (void *) sdr_info->cre_date },
01775     { 1, 1, "N_Creation_Time", H5T_NATIVE_CHAR, 15, 2, dims_1_1,
01776        (void *) sdr_info->cre_time },
01777     { 1, 0, "N_Ending_Time_IET", H5T_STD_U64BE, 0, 1, dims_1_1,
01778        (void *) &( sdr_info->en_58_t ) },
01779     { 0, 1, "N_Graceful_Degradation", H5T_NATIVE_CHAR, 3, 2, dims_1_1,
01780        (void *) "No" },
01781     { 1, 1, "N_Granule_ID", H5T_NATIVE_CHAR, 15, 2, dims_1_1,
01782        (void *) gran_id },
01783        /*  old val inserted: (void *)"NPP001212012151" }, */
01784     { 1, 1, "N_Granule_Status", H5T_NATIVE_CHAR, 5, 2, dims_1_1,
01785        (void *)"Fill" },
01786     { 1, 1, "N_Granule_Version", H5T_NATIVE_CHAR, 4, 2, dims_1_1,
01787        (void *)gran_vers }, 
01788     { 1, 1, "N_Input_Prod", H5T_NATIVE_CHAR, 33, 2, dims_9_1, 
01789        (void *)char33_9 },
01790     { 1, 1, "N_LEOA_Flag", H5T_NATIVE_CHAR, 4, 2, dims_1_1, 
01791        (void *)"Off" },
01792     { 1, 0, "N_Nadir_Latitude_Max", H5T_IEEE_F32BE, 0, 2, dims_1_1,
01793        (void *)( nadir_bdy + 2 ) },
01794     { 1, 0, "N_Nadir_Latitude_Min", H5T_IEEE_F32BE, 0, 2, dims_1_1,
01795        (void *)( nadir_bdy + 3 ) },
01796     { 1, 0, "N_Nadir_Longitude_Max", H5T_IEEE_F32BE, 0, 2, dims_1_1,
01797        (void *)nadir_bdy },
01798     { 1, 0, "N_Nadir_Longitude_Min", H5T_IEEE_F32BE, 0, 2, dims_1_1,
01799        (void *)( nadir_bdy + 1 ) },
01800     { 1, 1, "N_NPOES_Document_Ref", H5T_NATIVE_CHAR, 4, 2, dims_1_1,
01801        (void *)doc_ref },
01802     { 1, 0, "N_Number_Of_Scans", H5T_STD_I32BE, 0, 2, dims_1_1,
01803        (void *)&( out_rec->nscan ) },
01804     { 0, 0, "N_Percent_Erroneous_Data", H5T_IEEE_F32BE, 0, 2, dims_1_1,
01805        (void *)&fill },
01806     { 0, 0, "N_Percent_Missing_Data", H5T_IEEE_F32BE, 0, 2, dims_1_1,
01807        (void *)&fill },
01808     { 0, 0, "N_Percent_Not_Applicable_Data", H5T_IEEE_F32BE, 0, 2, dims_1_1,
01809        (void *)&fill },
01810     { 1, 1, "N_Quality_Summary_Names", H5T_NATIVE_CHAR, 26, 2, dims_2_1, 
01811        (void *) qual_sum_name },
01812     { 1, 0, "N_Quality_Summary_Values", H5T_STD_I32BE, 0, 2, dims_2_1,
01813        (void *) qual_sum_val },
01814     { 1, 1, "N_Reference_ID", H5T_NATIVE_CHAR, 10, 2, dims_1_1,
01815        (void *)"Who_Cares" },
01816     { 0, 0, "N_Satellite/Local_Azimuth_Angle_Max", H5T_IEEE_F32BE, 0, 2, 
01817        dims_1_1, (void *)&fill },
01818     { 0, 0, "N_Satellite/Local_Azimuth_Angle_Min", H5T_IEEE_F32BE, 0, 2,
01819        dims_1_1, (void *)&fill },
01820     { 0, 0, "N_Satellite/Local_Zenith_Angle_Max", H5T_IEEE_F32BE, 0, 2,
01821        dims_1_1, (void *)&fill },
01822     { 0, 0, "N_Satellite/Local_Zenith_Angle_Min", H5T_IEEE_F32BE, 0, 2,
01823        dims_1_1, (void *)&fill },
01824     { 1, 1, "N_Software_Version", H5T_NATIVE_CHAR, len_str, 2, dims_1_1,
01825        (void *) sw_vers },
01826     { 0, 0, "N_Solar_Azimuth_Angle_Max", H5T_IEEE_F32BE, 0, 2,
01827        dims_1_1, (void *)&fill },
01828     { 0, 0, "N_Solar_Azimuth_Angle_Min", H5T_IEEE_F32BE, 0, 2,
01829        dims_1_1, (void *)&fill },
01830     { 0, 0, "N_Solar_Zenith_Angle_Max", H5T_IEEE_F32BE, 0, 2,
01831        dims_1_1, (void *)&fill },
01832     { 0, 0, "N_Solar_Zenith_Angle_Min", H5T_IEEE_F32BE, 0, 2,
01833        dims_1_1, (void *)&fill },
01834     { 1, 1, "N_Spacecraft_Maneuver", H5T_NATIVE_CHAR, 18, 2, dims_1_1,
01835        (void *)"Normal Operations" },
01836     { 0, 0, "North_Bounding_Coordinate", H5T_IEEE_F32BE, 0, 2, dims_1_1,
01837        (void *)( gran_bdy + 2 ) },
01838     { 0, 0, "South_Bounding_Coordinate", H5T_IEEE_F32BE, 0, 2, dims_1_1,
01839        (void *)( gran_bdy + 3 ) },
01840     { 0, 0, "West_Bounding_Coordinate", H5T_IEEE_F32BE, 0, 2, dims_1_1,
01841        (void *)( gran_bdy + 1 ) },
01842     { 1, 1, "N_Day_Night_Flag", H5T_NATIVE_CHAR, 4, 2, dims_1_1,
01843        (void *)"Day" }
01844      };
01845  /*
01846   *  ATTRIB NOTES - many attrs are hard-coded now
01847   */
01848   h5io_str ds_id;
01849   int dim_siz[2], *arr_int;
01850  /*
01851   *  set the g_ring values here - coordinates of granule perimeter)
01852   */
01853   for( i = 0; i < 8; i++ )
01854     {
01855     *( g_ring_lat + i ) = (float) i * 2.5;
01856     *( g_ring_lon + i ) = (float) i * 25;
01857     }
01858  /*
01859   *  set something in the input prod strings demo
01860   */
01861   for( i = 0; i < 9; i++ )
01862     sprintf( ( char33_9 + ( i * 33 ) ), "Input_prod_#_%d", i );
01863  /*
01864   *  Modifications for the band files
01865   */
01866   if( isdr > 0 )
01867     {
01868     for( i = 0; i < n_attr; i++ )
01869       attrs[i].express = 1;
01870     sprintf( band_id, "M%d", isdr );
01871     }
01872   for( i = 0; i < 49; i++ )
01873     sprintf( ( char_100_49 + ( i * 100 ) ), "Aux file #%d", i );
01874   for( i = 0; i < 4; i++ )
01875     {
01876     *( gran_bdy + i ) = 0.;
01877     *( nadir_bdy + i ) = 0.;
01878     }
01879   strcpy( gran_vers, "A1" );
01880   strcpy( doc_ref, "TBD" );
01881  /*
01882   *  quality summary names fill
01883   */
01884   for( i = 0; i < 2; i++ )
01885     {
01886     sprintf( ( qual_sum_name + ( i * 26 ) ), "qual sum name %d", i );
01887     *( qual_sum_val + i ) = i;
01888     }
01889  /*
01890   * anc and aux fill
01891   */
01892   for( i = 0; i < 19; i++ )
01893     sprintf( ( char_anc + ( i * 106 ) ), "Anc file # %d", i );
01894   for( i = 0; i < 5; i++ )
01895     sprintf( ( char_aux + ( i * 106 ) ), "Aux file # %d", i );
01896  /*
01897   *  the dataset is a reference dataset, so we'll forgo and just place an int
01898   */
01899   arr_int = (int *)malloc( sizeof( int ) );
01900   *arr_int = 666;
01901   dim_siz[0] = 1;
01902   sprintf( grp_nam, "%s_Gran_0", core_g_nm[isdr] );
01903   if( h5io_mk_ds( gid, grp_nam, H5T_NATIVE_INT, 1, 
01904     dim_siz, &ds_id ) != 0 )
01905     {
01906     printf( "%s, %d: Could not do h5io_mk_ds for VIIRS-MOD-GEO-TC_Gran_0\n",
01907       __FILE__, __LINE__ );
01908     return 1;
01909     }
01910   if( h5io_wr_ds( &ds_id, (void *)arr_int ) != 0 )
01911     {
01912     printf( "%s, %d: Could not write to VIIRS-MOD-GEO-TC_Gran_0\n", 
01913       __FILE__, __LINE__ );
01914     return 1;
01915     }
01916   free( arr_int );
01917  /*
01918   *  output the attributes to the location
01919   */
01920   if( wr_attr_seq( &ds_id, n_attr, attrs ) != 0 )
01921     {
01922     printf( 
01923       "%s %d: Could not write top attributes for VIIRS-MOD-GEO-TC_Gran_0\n",
01924       __FILE__, __LINE__ );
01925     return 1;
01926     }
01927   if( h5io_close( &ds_id ) != 0 )
01928     {
01929     printf( "%s %d: Could not close VIIRS-MOD-GEO-TC_Gran_0\n", 
01930       __FILE__, __LINE__ );
01931     return 1;
01932     }
01933   return 0;
01934   }