/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sedutils/sedflux-read-hydro.c

Go to the documentation of this file.
00001 //
00002 // This file is part of sedflux.
00003 //
00004 // sedflux is free software; you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation; either version 2 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // sedflux is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with sedflux; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 //
00018 //---
00019 
00020 #include <stdio.h>
00021 #include <utils/utils.h>
00022 #include <sed/sed_sedflux.h>
00023 
00024 static gchar**  in_file    = NULL;
00025 static gchar*   out_file   = NULL;
00026 static gint     in_type    = 0;
00027 static gint     out_type   = 0;
00028 static double   dt         = 365.;
00029 static double   fraction   = 1.;
00030 static gint     n_recs     = -1;
00031 static gint     buf_len    = 365;
00032 static gint     events     = 5;
00033 static gint     start      = 0;
00034 static gboolean just_events = FALSE;
00035 static gboolean version    = FALSE;
00036 static gint     verbosity  = 5;
00037 static gboolean debug      = FALSE;
00038 static gboolean info       = FALSE;
00039 static gint     to         = G_BYTE_ORDER;
00040 static gint     from       = G_BYTE_ORDER;
00041 
00042 static gboolean parse_file_list ( const gchar* name , const gchar* value , gpointer data , GError** error );
00043 static gboolean parse_file_type ( const gchar* name , const gchar* value , gpointer data , GError** error );
00044 static gboolean parse_byte_order( const gchar* name , const gchar* value , gpointer data , GError** error );
00045 
00046 static void     write_data( FILE* fp , Sed_hydro* a , gint type , gint order );
00047 
00048 GOptionEntry entries[] =
00049 {
00050    { "in-file"     , 'i' , 0 , G_OPTION_ARG_CALLBACK , parse_file_list  , "Input file"               , "<file>" } ,
00051    { "in-type"     ,  0  , 0 , G_OPTION_ARG_CALLBACK , &parse_file_type , "Input file type"          , "TYPE" } ,
00052    { "out-type"    ,  0  , 0 , G_OPTION_ARG_CALLBACK , &parse_file_type , "Output file type"         , "TYPE" } ,
00053    { "dt"          , 'T' , 0 , G_OPTION_ARG_DOUBLE   , &dt              , "Duration (days)"          , "TIME" } ,
00054    { "fraction"    , 'f' , 0 , G_OPTION_ARG_DOUBLE   , &fraction        , "Fraction of sediment"     , "FRAC" } ,
00055    { "n-recs"      , 'N' , 0 , G_OPTION_ARG_INT      , &n_recs          , "Number of records"        , "N" } ,
00056    { "buffer"      , 'l' , 0 , G_OPTION_ARG_INT      , &buf_len         , "Buffer length"            , "LEN" } ,
00057    { "events"      , 'n' , 0 , G_OPTION_ARG_INT      , &events          , "Number of events"         , "N" } ,
00058    { "start-rec"   , 's' , 0 , G_OPTION_ARG_INT      , &start           , "Start record"             , "N" } ,
00059    { "just-events" , 'e' , 0 , G_OPTION_ARG_NONE     , &just_events     , "Don't include non-floods" , NULL } ,
00060    { "verbose"     , 'V' , 0 , G_OPTION_ARG_INT      , &verbosity       , "Verbosity level"          , "n" } ,
00061    { "version"     , 'v' , 0 , G_OPTION_ARG_NONE     , &version         , "Version number"           , NULL } ,
00062    { "debug"       , 'd' , 0 , G_OPTION_ARG_NONE     , &debug           , "Write debug messages"     , NULL } ,
00063    { "info"        ,  0  , 0 , G_OPTION_ARG_NONE     , &info            , "Print file info"          , NULL } ,
00064    { "swap"        ,  0  , 0 , G_OPTION_ARG_CALLBACK , parse_byte_order , "Swap byte order"          , NULL } ,
00065    { "to"          ,  0  , 0 , G_OPTION_ARG_CALLBACK , parse_byte_order , "Destination byte order"   , "[big|little]" } ,
00066    { "from"        ,  0  , 0 , G_OPTION_ARG_CALLBACK , parse_byte_order , "Source byte order"        , "[big|little]" } ,
00067    { "join"        ,  0  , 0 , G_OPTION_ARG_CALLBACK , parse_file_list  , "Files to join"            , "file1[,file2[,file3]]" },
00068    { NULL }
00069 };
00070 
00071 gboolean
00072 parse_file_list( const gchar* name , const gchar* value , gpointer data , GError** error )
00073 {
00074    gboolean success = FALSE;
00075 
00076    eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00077 
00078    if ( name && value )
00079    {
00080       GError* tmp_err   = NULL;
00081 
00082       in_file  = g_strsplit(value,",",0);
00083 
00084       if ( !in_file )
00085       {
00086          g_set_error( &tmp_err ,
00087                       G_OPTION_ERROR ,
00088                       G_OPTION_ERROR_FAILED ,
00089                       "Failed to parse comma-separated list of files to concatenate" );
00090       }
00091 
00092       if ( tmp_err )
00093       {
00094          g_propagate_error( error , tmp_err );
00095          success = FALSE;
00096       }
00097       else
00098          success = TRUE;
00099    }
00100 
00101    return success;
00102 }
00103 
00104 gboolean
00105 parse_file_type( const gchar* name , const gchar* value , gpointer data , GError** error )
00106 {
00107    gboolean success = FALSE;
00108 
00109    eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00110 
00111    if ( name && value )
00112    {
00113       GError* tmp_err = NULL;
00114       gint    format  = -1;
00115 
00116       if      ( g_ascii_strcasecmp( value , "hydrotrend"  )==0 ) format  = 0;
00117       else if ( g_ascii_strcasecmp( value , "ascii"       )==0 ) format  = 1;
00118       else if ( g_ascii_strcasecmp( value , "hyperpycnal" )==0 ) format  = 2;
00119       else if ( g_ascii_strcasecmp( value , "hypopycnal"  )==0 ) format  = 3;
00120       else
00121       {
00122          g_set_error( &tmp_err ,
00123                       G_OPTION_ERROR ,
00124                       G_OPTION_ERROR_BAD_VALUE ,
00125                       "Unknown file format (%s): must be either HYDROTREND or ASCII" , value );
00126       }
00127 
00128       if      ( g_ascii_strcasecmp( name , "--in-type" )==0  ) in_type  = format;
00129       else if ( g_ascii_strcasecmp( name , "--out-type" )==0 ) out_type = format;
00130       else
00131       {
00132          g_set_error( &tmp_err ,
00133                       G_OPTION_ERROR ,
00134                       G_OPTION_ERROR_FAILED , 
00135                       "Invalid option name (%s)" , name );
00136       }
00137 
00138       if ( tmp_err )
00139       {
00140          g_propagate_error( error , tmp_err );
00141          success = FALSE;
00142       }
00143       else
00144          success = TRUE;
00145    }
00146 
00147    return success;
00148 }
00149 
00150 gboolean
00151 parse_byte_order( const gchar* name , const gchar* value , gpointer data , GError** error )
00152 {
00153    gboolean success = FALSE;
00154 
00155    eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00156 
00157    if ( name && value )
00158    {
00159       GError* tmp_err = NULL;
00160       gint*   byte_order;
00161 
00162       if (    g_ascii_strcasecmp( name , "--SWAP" )!=0
00163            && g_ascii_strcasecmp( name , "--TO"   )!=0
00164            && g_ascii_strcasecmp( name , "--FROM" )!=0 )
00165       {
00166             success = FALSE;
00167             g_set_error( &tmp_err ,
00168                          G_OPTION_ERROR ,
00169                          G_OPTION_ERROR_FAILED , 
00170                          "Invalid option name (%s)" , name );
00171       }
00172       else if ( g_ascii_strcasecmp( name , "--SWAP" )==0 )
00173       {
00174          from = G_BYTE_ORDER;
00175 
00176          if ( G_BYTE_ORDER==G_BIG_ENDIAN ) to = G_LITTLE_ENDIAN;
00177          else                              to = G_BIG_ENDIAN;
00178       }
00179       else
00180       {
00181          if      ( g_ascii_strcasecmp( name , "--TO"   )==0 )
00182             byte_order = &to;
00183          else if ( g_ascii_strcasecmp( name , "--FROM" )==0 )
00184             byte_order = &from;
00185 
00186          if      (    g_ascii_strcasecmp( value , "BIG"        )==0
00187                    || g_ascii_strcasecmp( value , "BIG-ENDIAN" )==0 )
00188          {
00189             success = TRUE;
00190             *byte_order = G_BIG_ENDIAN;
00191          }
00192          else if (    g_ascii_strcasecmp( value , "LITTLE"        )==0
00193                    || g_ascii_strcasecmp( value , "LITTLE-ENDIAN" )==0 )
00194          {
00195             success = TRUE;
00196             *byte_order = G_LITTLE_ENDIAN;
00197          }
00198          else
00199          {
00200             success = FALSE;
00201             g_set_error( &tmp_err ,
00202                          G_OPTION_ERROR ,
00203                          G_OPTION_ERROR_BAD_VALUE , 
00204                          "Unknown byte order (%s): must be either BIG-ENDIAN or LITTLE-ENDIAN" , value );
00205          }
00206       }
00207 
00208       if ( tmp_err )
00209          g_propagate_error( error , tmp_err );
00210    }
00211 
00212    return success;
00213 }
00214 
00215 #define byte_order_s( o ) ( (o==G_BIG_ENDIAN)?"big endian":"little endian" )
00216 
00217 gint
00218 main( gint argc , gchar *argv[] )
00219 {
00220    GError*         error   = NULL;
00221    FILE*           fp_out  = stdout;
00222    FILE**          fp_in   = NULL;
00223 
00224    { /* Parse command line options.  Exit if there is an error. */
00225       GOptionContext* context = g_option_context_new( "Read a HydroTrend river file" );
00226 
00227       //g_thread_init( NULL );
00228       eh_init_glib();
00229       g_log_set_handler( NULL , G_LOG_LEVEL_MASK|G_LOG_FLAG_FATAL , &eh_logger , NULL );
00230 
00231       g_option_context_add_main_entries( context , entries , NULL );
00232 
00233       if ( !g_option_context_parse( context , &argc , &argv , &error ) )
00234          eh_error( "Error parsing command line arguments: %s" , error->message );
00235    }
00236 
00237    if ( version ) eh_fprint_version_info( stdout , "sedflux-read-hydro" , 0 , 1 , 0 ), exit(0);
00238    if ( debug   ) g_setenv( "SEDFLUX_READ_HYDRO" , "TRUE" , TRUE );
00239 
00240    eh_set_verbosity_level( verbosity );
00241 
00242    if ( in_file )
00243    { /* Open all of the input files.  Exit if there is an error. */
00244       gchar** file;
00245       FILE*   fp;
00246 
00247       for ( file=in_file ; *file ; file++ )
00248       {
00249          fp = eh_fopen_error( *file , "r" , &error );
00250 
00251          if ( fp ) eh_strv_append( (gchar***)&fp_in , (gchar*)fp );
00252          else      eh_exit_on_error( error , "sedflux-read-hydro" );
00253       }
00254    }
00255    else
00256    {
00257       fp_in    = eh_new0( FILE* , 2 );
00258       fp_in[0] = stdin;
00259    }
00260 
00261    if ( info )
00262    { /* Print some info about the input file(s) and exit. */
00263       Sed_hydrotrend_header* h         = sed_hydrotrend_join_header_from_byte_order( fp_in , from , &error );
00264       gchar*                 file_list = g_strjoinv( ";" , in_file );
00265 
00266       eh_info( "File name             : %s" , file_list                         );
00267       eh_info( "Number of grain sizes : %d" , h->n_grains                       );
00268       eh_info( "Number of seasons     : %d" , h->n_seasons                      );
00269       eh_info( "Number of records     : %d" , h->n_samples                      );
00270       eh_info( "Number of years       : %f" , h->n_samples/(double)h->n_seasons );
00271       eh_info( "Comment               : %s" , h->comment                        );
00272       eh_info( "Byte order            : %s" , byte_order_s(from)                );
00273 
00274       eh_free( file_list );
00275 
00276       return EXIT_SUCCESS;
00277    }
00278 
00279    if ( out_file )
00280    { /* Open the output file.  Exit if there is an error. */
00281       fp_out = eh_fopen_error( out_file , "w" , &error );
00282       eh_exit_on_error( error , "sedflux-read-hydro" );
00283    }
00284 
00285    eh_info( "First record           : %d" , start    );
00286    eh_info( "Number of records      : %d" , n_recs   );
00287    eh_info( "Buffer length          : %d" , buf_len  );
00288    eh_info( "Fraction of load       : %f" , fraction );
00289    eh_info( "Source byte order      : %s" , byte_order_s(from) );
00290    eh_info( "Destination byte order : %s" , byte_order_s(to  ) );
00291 
00292 eh_watch_int( out_type );
00293 
00294    { /* Operate on the hydro file. */
00295       FILE**                 fp       = NULL;
00296       GError*                error    = NULL;
00297       Sed_hydrotrend_header* h        = sed_hydrotrend_join_header_from_byte_order( fp_in , from , &error );
00298       gint                   tot_recs = n_recs;
00299 eh_watch_ptr( h );
00300       eh_exit_on_error( error , "sedflux-read-hydro" );
00301 
00302       if ( n_recs<=0   ) tot_recs = h->n_samples - start;
00303       if ( out_type==0 ) sed_hydrotrend_write_header_to_byte_order( fp_out , h->n_grains , h->n_seasons , tot_recs , h->comment , to );
00304 eh_watch_int( tot_recs );
00305 
00306       h = sed_hydrotrend_header_destroy( h );
00307 
00308       for ( fp=fp_in ; *fp ; fp++ )
00309       { /* If the header is valid, go to work. */
00310          gint       i;
00311          Sed_hydro* all_recs  = NULL;
00312          Sed_hydro* big_recs  = NULL;
00313          gint       top_rec   = 0;
00314          gint       top_block = 0;
00315 eh_watch_ptr( fp );
00316          tot_recs = n_recs;
00317 eh_watch_int( tot_recs );
00318 
00319          h = sed_hydrotrend_read_header_from_byte_order( *fp , from );
00320 eh_watch_ptr( h );
00321 eh_watch_int( h->n_grains );
00322 eh_watch_int( h->n_seasons );
00323 eh_watch_int( h->n_samples );
00324 eh_watch_str( h->comment );
00325 
00326          if ( n_recs<=0   ) tot_recs = h->n_samples - start;
00327 //         if ( out_type==0 ) sed_hydrotrend_write_header_to_byte_order( fp_out , h->n_grains , h->n_seasons , n_recs , h->comment , to );
00328 
00329 eh_watch_int( tot_recs );
00330          //top_rec   = start + tot_recs*buf_len;
00331          top_rec   = start + tot_recs;
00332 eh_watch_int( top_rec );
00333 eh_watch_int( buf_len );
00334 eh_watch_int( start );
00335          top_block = (top_rec+1) / buf_len;
00336 eh_watch_int( top_block );
00337 
00338          //for ( i=start ; i<top_block ; i+=buf_len )
00339          for ( i=start ; i<top_rec ; i+=buf_len )
00340          { /* Write hydro records in blocks. */
00341 eh_watch_int( i );
00342 eh_watch_int( top_block );
00343 eh_watch_int( top_rec );
00344             all_recs = sed_hydrotrend_read_recs( *fp , i , buf_len , from , &error );
00345 eh_watch_ptr( all_recs );
00346             //big_recs = sed_hydro_array_eventize( all_recs , fraction , !just_events );
00347             big_recs = sed_hydro_array_eventize_conc( all_recs , 1045. );
00348 eh_watch_ptr( big_recs );
00349 //eh_watch_int( g_strv_length( all_recs ) );
00350 //eh_watch_int( g_strv_length( big_recs ) );
00351 
00352             write_data( fp_out , big_recs , out_type , to );
00353             //write_data( fp_out , all_recs , out_type , to );
00354 
00355             //eh_info( "Block start            : %d" , i                                        );
00356             //eh_info( "Total load             : %f" , sed_hydro_array_suspended_load(all_recs) );
00357             //eh_info( "Modeled load           : %f" , sed_hydro_array_suspended_load(big_recs) );
00358             //eh_info( "Number of events       : %d" , g_strv_length( (gchar**)big_recs )       );
00359 
00360             all_recs = sed_hydro_array_destroy( all_recs );
00361             big_recs = sed_hydro_array_destroy( big_recs );
00362          }
00363 
00364          fclose( *fp );
00365       }
00366    }
00367 
00368    eh_free( fp_in  );
00369    fclose ( fp_out );
00370 
00371    return EXIT_SUCCESS;
00372 }
00373 
00374 void
00375 write_data( FILE* fp , Sed_hydro* a , gint type , gint order )
00376 {
00377    if ( a )
00378    {
00379       if      ( type==0 )
00380          sed_hydro_array_write_hydrotrend_records_to_byte_order( fp , a , order );
00381       else if ( type==1 )
00382       {
00383          Sed_hydro* r;
00384          double     t;
00385          for ( r=a ; *r ; r++ )
00386             for ( t=0 ; t<sed_hydro_duration(*r) ; t++ )
00387                fprintf( fp , "%f\n" , sed_hydro_water_flux(*r) );
00388                //fprintf( fp , "%f\n" , sed_hydro_suspended_load(*r)/sed_hydro_duration(*r) );
00389       }
00390       else if ( type==2 )
00391       {
00392          Sed_hydro* r;
00393          for ( r=a ; *r ; r++ )
00394             if ( sed_hydro_is_hyperpycnal(*r) )
00395                sed_hydro_fprint_rec( fp , *r , NULL );
00396       }
00397       else if ( type==3 )
00398       {
00399          Sed_hydro* r;
00400          for ( r=a ; *r ; r++ )
00401             if ( !sed_hydro_is_hyperpycnal(*r) )
00402                sed_hydro_fprint_rec( fp , *r , NULL );
00403       }
00404       else
00405          eh_require_not_reached();
00406    }
00407    return;
00408 }
00409 
00410 #ifdef IGNORE_THIS
00411 
00412 int main(int argc,char *argv[])
00413 {
00414    char *prop_vals[] = { "q" , "qs" , "v" , "w" , "d" , "bed" , NULL };
00415    int j;
00416    int n_recs, buf_len, n_sig;
00417    int start;
00418    int type;
00419    double time, total_time;
00420    int prop;
00421    gboolean verbose, use_buf;
00422    char *infile;
00423    Eh_args *args;
00424    Hydro_get_val_func get_val;
00425    Sed_hydro_file fp;
00426    Sed_hydro rec;
00427    GPtrArray *rec_array;
00428 
00429    args = eh_opts_init(argc,argv);
00430    if ( eh_check_opts( args , NULL , NULL , help_msg )!=0 )
00431       eh_exit(-1);
00432 
00433    total_time = eh_get_opt_dbl ( args , "dt" , 365.    );
00434    n_recs  = eh_get_opt_int ( args , "nrecs" , 10    );
00435    buf_len = eh_get_opt_int ( args , "len"   , 365   );
00436    n_sig   = eh_get_opt_int ( args , "nsig"  , 5     );
00437    start   = eh_get_opt_int ( args , "start" , 0     );
00438    verbose = eh_get_opt_bool( args , "v"     , FALSE );
00439    use_buf = eh_get_opt_bool( args , "buf"   , FALSE );
00440    infile  = eh_get_opt_str ( args , "in"    , "-"   );
00441    prop    = eh_get_opt_key ( args , "prop"  , 0 , prop_vals );
00442    
00443    switch ( prop )
00444    {
00445       case 0:
00446          get_val = &sed_hydro_water_flux;
00447          break;
00448       case 1:
00449          get_val = &sed_hydro_suspended_flux;
00450          break;
00451       case 2:
00452          get_val = &sed_hydro_velocity;
00453          break;
00454       case 3:
00455          get_val = &sed_hydro_width;
00456          break;
00457       case 4:
00458          get_val = &sed_hydro_depth;
00459          break;
00460       case 5:
00461          get_val = &sed_hydro_bedload;
00462          break;
00463    }
00464    
00465    if ( use_buf )
00466       type = HYDRO_HYDROTREND|HYDRO_USE_BUFFER;
00467    else
00468       type = HYDRO_HYDROTREND;
00469 
00470    if ( verbose )
00471    {
00472       fprintf(stderr,"--- head ---\n");
00473       fprintf(stderr,"total time (days) : %f\n",total_time);
00474       fprintf(stderr,"n records    : %d\n",n_recs);
00475       fprintf(stderr,"buf length   : %d\n",buf_len);
00476       fprintf(stderr,"n sig events : %d\n",n_sig);
00477       fprintf(stderr,"start        : %d\n",start);
00478       fprintf(stderr,"property     : %s\n",prop_vals[prop]);
00479       fprintf(stderr,"buffer       : %d\n",use_buf);
00480    }
00481 
00482    fp = sed_hydro_file_new( infile , type , TRUE );
00483    sed_hydro_file_set_sig_values( fp , n_sig );
00484    sed_hydro_file_set_buffer_length( fp , buf_len );
00485 
00486    rec_array = g_ptr_array_new( );
00487    fprintf(stdout,"%s\n",prop_vals[prop]);
00488    for ( time=0 ; time<total_time ; )
00489    {
00490       rec = sed_hydro_file_read_record( fp );
00491       if ( sed_hydro_duration(rec) + time > total_time )
00492          sed_hydro_set_duration( rec , total_time-time );
00493       for ( j=0 ; j<sed_hydro_duration(rec) ; j++ )
00494          fprintf(stdout,"%f\n",(*get_val)( rec ));
00495       time += sed_hydro_duration(rec);
00496       g_ptr_array_add( rec_array , rec );
00497    }
00498    
00499    if ( verbose )
00500    {
00501       double total = 0, total_qs = 0;
00502 
00503       for ( j=0 ; j<rec_array->len ; j++ )
00504       {
00505          rec       = g_ptr_array_index( rec_array , j );
00506          total    += (*get_val)( rec )*sed_hydro_duration(rec);
00507          total_qs += sed_hydro_suspended_load( rec );
00508       }
00509 
00510       fprintf(stderr,"--- tail ---\n");
00511       fprintf(stderr,"n events         : %d\n",rec_array->len);
00512       fprintf(stderr,"total            : %f\n",total);
00513       fprintf(stderr,"total qs         : %f\n",total_qs);
00514    }
00515 
00516    g_ptr_array_free( rec_array , FALSE );
00517 
00518    sed_hydro_file_destroy( fp );
00519 
00520    return 0;
00521 }
00522 
00523 #endif
00524 

Generated on Fri Jan 4 18:04:16 2008 for sedflux by  doxygen 1.5.2