/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sed/sed_hydro.c

Go to the documentation of this file.
00001 //---
00002 //
00003 // This file is part of sedflux.
00004 //
00005 // sedflux is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // sedflux is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with sedflux; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //
00019 //---
00020 
00021 #include <stdio.h>
00022 #include <glib.h>
00023 
00024 #include "utils/utils.h"
00025 #include "sed_hydro.h"
00026 #include "sed_hydrotrend.h"
00027 
00028 CLASS ( Sed_hydro )
00029 {
00030    double velocity;
00031    double width;
00032    double depth;
00033    double bedload;
00034    double *conc;
00035    gint32 n_grains;
00036    double duration;
00037    double t;
00038 };
00039 
00040 CLASS ( Sed_hydro_file )
00041 {
00042    FILE *fp;
00043    gchar* file;
00044    Sed_hydro_file_type type;
00045    gboolean wrap_is_on;
00046    Sed_hydro *buf_set;
00047    Sed_hydro *buf_cur;
00048    int buffer_len;
00049    int n_sig_values;
00050    size_t header_start;
00051    size_t data_start;
00052    size_t data_size;
00053    Sed_hydrotrend_header *hdr;
00054    Hydro_read_record_func read_record;
00055    Hydro_read_header_func read_hdr;
00056 };
00057 
00058 GQuark
00059 sed_hydro_error_quark( void )
00060 {
00061    return g_quark_from_static_string( "sed-hydro-error-quark" );
00062 }
00063 
00064 
00065 //Hydro_header* _hydro_read_inline_header           ( Sed_hydro_file fp );
00066 static Sed_hydro              _hydro_read_inline_record           ( Sed_hydro_file fp );
00067 static Sed_hydrotrend_header* _hydro_read_hydrotrend_header       ( Sed_hydro_file fp );
00068 static Sed_hydro              _hydro_read_hydrotrend_record       ( Sed_hydro_file fp );
00069 static Sed_hydro              _hydro_read_hydrotrend_record_buffer( Sed_hydro_file fp );
00070 
00071 void
00072 sed_hydro_fprint_default_inline_file( FILE *fp )
00073 {
00074    char *text[]=DEFAULT_HYDRO_INLINE_FILE;
00075    char **p;
00076    for ( p = text ; *p ; p++ )
00077       fprintf( fp , "%s\n" , *p );
00078 }
00079 
00080 gssize
00081 sed_hydro_array_fprint( FILE* fp , Sed_hydro* rec_a )
00082 {
00083    gssize n = 0;
00084 
00085    eh_return_val_if_fail( rec_a    , 0 );
00086    eh_return_val_if_fail( rec_a[0] , 0 );
00087 
00088    if ( fp && rec_a )
00089    {
00090       Sed_hydro* rec;
00091       gint       n_rec = 0;
00092 
00093       for ( rec=rec_a ; *rec ; rec++ )
00094       {
00095          n += fprintf( fp , "[ Record %d ]\n" , n_rec++ );
00096          n += sed_hydro_fprint( fp , *rec );
00097       }
00098    }
00099 
00100    return n;
00101 }
00102 
00103 gssize
00104 sed_hydro_fprint( FILE* fp , Sed_hydro rec )
00105 {
00106    gssize n = 0;
00107 
00108    eh_return_val_if_fail( rec , 0 );
00109 
00110    if ( fp && rec )
00111    {
00112       gssize i;
00113       n += fprintf( fp , "duration (day)         : %f\n" , rec->duration );
00114       n += fprintf( fp , "time                   : %f\n" , rec->t        );
00115       n += fprintf( fp , "velocity (m/s)         : %f\n" , rec->velocity );
00116       n += fprintf( fp , "width (m)              : %f\n" , rec->width    );
00117       n += fprintf( fp , "depth (m)              : %f\n" , rec->depth    );
00118       n += fprintf( fp , "bedload (kg/s)         : %f\n" , rec->bedload  );
00119       n += fprintf( fp , "concentration (kg/m^3) : " );
00120       for ( i=0 ; i<rec->n_grains-1 ; i++ )
00121          n += fprintf( fp , "%f, " , rec->conc[i] );
00122       n += fprintf( fp , "%f\n" , rec->conc[rec->n_grains-1] );
00123    }
00124 
00125    return n;
00126 }
00127 /*
00128 Sed_hydro
00129 sed_hydro_init( char *file )
00130 {
00131    char *name_used;
00132    FILE *fp;
00133    Sed_hydro record;
00134 
00135    if ( !file )
00136       name_used = g_strdup( SED_HYDRO_TEST_INLINE_FILE );
00137    else
00138       name_used = g_strdup( file );
00139 
00140    fp = fopen( name_used , "r" );
00141 
00142    record = sed_hydro_scan( fp );
00143 
00144    fclose( fp );
00145 
00146    eh_free( name_used );
00147 
00148    return record;
00149 }
00150 */
00151 
00159 Sed_hydro*
00160 sed_hydro_scan( const gchar* file , GError** error )
00161 {
00162    return sed_hydro_scan_n_records( file , -1 , error );
00163 }
00164 
00165 Sed_hydro*
00166 sed_hydro_scan_n_records( const gchar* file , gint n_recs , GError** error )
00167 {
00168    Sed_hydro* hydro_arr = NULL;
00169 
00170    eh_require( error==NULL || *error==NULL );
00171 
00172    if ( !file )
00173       file = SED_HYDRO_TEST_INLINE_FILE;
00174 
00175    if ( n_recs!=0 )
00176    {
00177       gchar*          name_used = g_strdup( file );
00178       GError*         tmp_err   = NULL;
00179       Eh_key_file     key_file  = NULL;
00180 
00181       key_file  = eh_key_file_scan( name_used , &tmp_err );
00182 
00183       if ( key_file )
00184       {
00185          gint            i;
00186          Eh_symbol_table group;
00187          const gint      len = eh_key_file_size( key_file );
00188 
00189          if      ( n_recs<0   ) n_recs = len;
00190          else if ( n_recs>len ) n_recs = len;
00191 
00192          hydro_arr = eh_new0( Sed_hydro , n_recs+1 );
00193 
00194          for ( group = eh_key_file_pop_group( key_file ), i=0 ;
00195                group && !tmp_err && i<n_recs ;
00196                group = eh_key_file_pop_group( key_file ), i++ )
00197          {
00198             hydro_arr[i] = sed_hydro_new_from_table( group , &tmp_err );
00199 
00200             if ( !tmp_err ) sed_hydro_check( hydro_arr[i] , &tmp_err );
00201 
00202             eh_symbol_table_destroy( group );
00203          }
00204          hydro_arr[i] = NULL;
00205 
00206          sed_hydro_array_set_time( hydro_arr , 0. );
00207 
00208          if ( tmp_err )
00209          {
00210             g_propagate_error( error , tmp_err );
00211 
00212             for ( i=0 ; hydro_arr[i] ; i++ )
00213                sed_hydro_destroy( hydro_arr[i] );
00214             eh_free( hydro_arr );
00215             hydro_arr = NULL;
00216          }
00217 
00218       }
00219       else
00220          g_propagate_error( error , tmp_err );
00221 
00222       eh_free            ( name_used );
00223       eh_key_file_destroy( key_file  );
00224    }
00225 
00226    return hydro_arr;
00227 }
00228 
00229 
00230 
00231 #define SED_HYDRO_LABEL_DURATION        "Duration"
00232 #define SED_HYDRO_LABEL_BEDLOAD         "Bedload"
00233 #define SED_HYDRO_LABEL_SUSPENDED_CONC  "Suspended load concentration"
00234 #define SED_HYDRO_LABEL_VELOCITY        "Velocity"
00235 #define SED_HYDRO_LABEL_WIDTH           "Width"
00236 #define SED_HYDRO_LABEL_DEPTH           "Depth"
00237 
00238 static gchar* required_labels[] =
00239 {
00240    SED_HYDRO_LABEL_DURATION         ,
00241    SED_HYDRO_LABEL_BEDLOAD          ,
00242    SED_HYDRO_LABEL_SUSPENDED_CONC   ,
00243    SED_HYDRO_LABEL_VELOCITY         ,
00244    SED_HYDRO_LABEL_WIDTH            ,
00245    SED_HYDRO_LABEL_DEPTH            ,
00246    NULL 
00247 };
00248 
00249 #include <string.h>
00250 
00258 Sed_hydro
00259 sed_hydro_new_from_table( Eh_symbol_table t , GError** error )
00260 {
00261    Sed_hydro r = NULL;
00262 
00263    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00264 
00265    if ( t )
00266    {
00267       GError* tmp_err = NULL;
00268 
00269       //if ( eh_symbol_table_has_labels( t , required_labels ) )
00270       if ( eh_symbol_table_require_labels( t , required_labels , &tmp_err ) )
00271       {
00272          gint    n_susp_grains;
00273          double* c = eh_symbol_table_dbl_array_value( t , SED_HYDRO_LABEL_SUSPENDED_CONC , &n_susp_grains , NULL );
00274 
00275          r = sed_hydro_new( n_susp_grains );
00276 
00277          r->conc      = memcpy( r->conc , c , sizeof(double)*n_susp_grains );
00278 
00279          r->duration  = eh_symbol_table_time_value( t , SED_HYDRO_LABEL_DURATION  );
00280          r->bedload   = eh_symbol_table_dbl_value ( t , SED_HYDRO_LABEL_BEDLOAD   );
00281          r->velocity  = eh_symbol_table_dbl_value ( t , SED_HYDRO_LABEL_VELOCITY  );
00282          r->width     = eh_symbol_table_dbl_value ( t , SED_HYDRO_LABEL_WIDTH     );
00283          r->depth     = eh_symbol_table_dbl_value ( t , SED_HYDRO_LABEL_DEPTH     );
00284       
00285          r->duration *= S_DAYS_PER_YEAR;
00286 
00287          r->t         = 0.;
00288 
00289          eh_free( c );
00290       }
00291 
00292       if ( tmp_err )
00293       {
00294          g_propagate_error( error , tmp_err );
00295          r = sed_hydro_destroy( r );
00296       }
00297    }
00298 
00299    return r;
00300 }
00301 
00302 gboolean
00303 sed_hydro_check( Sed_hydro a , GError** err )
00304 {
00305    gboolean is_ok = TRUE;
00306 
00307    eh_return_val_if_fail( err==NULL || *err==NULL , FALSE );
00308    eh_return_val_if_fail( a                       , TRUE  );
00309 
00310    if ( a )
00311    {
00312       gchar** err_s = NULL;
00313 
00314       eh_check_to_s( sed_hydro_width   (a)>0.  , "River width > 0"    , &err_s );
00315       eh_check_to_s( sed_hydro_depth   (a)>0.  , "River depth > 0"    , &err_s );
00316       eh_check_to_s( sed_hydro_velocity(a)>0.  , "River velocity > 0" , &err_s );
00317       eh_check_to_s( sed_hydro_bedload (a)>=0. , "Bedload flux > 0"   , &err_s );
00318       eh_check_to_s( sed_hydro_duration(a)>0.  , "Duration > 0"       , &err_s );
00319       eh_check_to_s( eh_dbl_array_each_ge( 0.  , a->conc , a->n_grains ) ,
00320                                                  "Suspended load concentration > 0" , &err_s );
00321 
00322       if ( err_s )
00323       {
00324          gchar* str = g_strjoinv( "\n" , err_s );
00325 
00326          is_ok = FALSE;
00327 
00328          g_set_error( err ,
00329                       SED_HYDRO_ERROR ,
00330                       SED_HYDRO_ERROR_BAD_PARAMETER ,
00331                       "%s" , str );
00332 
00333          eh_free( str );
00334          g_strfreev( err_s );
00335       }
00336 
00337    }
00338 
00339    return is_ok;
00340 }
00341 
00342 const gchar __hydro_unknown_type_s[]       = "Unknown";
00343 const gchar __hydro_inline_type_s[]        = "Inline";
00344 const gchar __hydro_hydrotrend_type_s[]    = "Hydrotrend";
00345 const gchar __hydro_hydrotrend_be_type_s[] = "Hydrotrend (big-endian)";
00346 const gchar __hydro_hydrotrend_le_type_s[] = "Hydrotrend (little-endian)";
00347 
00348 const gchar*
00349 sed_hydro_type_to_s( Sed_hydro_file_type t )
00350 {
00351    const gchar* s;
00352 
00353    switch ( t )
00354    {
00355       case SED_HYDRO_INLINE        : s = __hydro_inline_type_s ; break;
00356       case SED_HYDRO_HYDROTREND    : s = __hydro_hydrotrend_type_s ; break;
00357       case SED_HYDRO_HYDROTREND_BE : s = __hydro_hydrotrend_be_type_s ; break;
00358       case SED_HYDRO_HYDROTREND_LE : s = __hydro_hydrotrend_le_type_s ; break;
00359       default                      : s = __hydro_unknown_type_s;
00360    }
00361 
00362    return s;
00363 }
00364 
00365 Sed_hydro_file_type
00366 sed_hydro_str_to_type( const gchar* type_s )
00367 {
00368    Sed_hydro_file_type t = SED_HYDRO_UNKNOWN;
00369 
00370    if ( type_s )
00371    {
00372       if      (    g_ascii_strcasecmp( type_s , "SEASON" )==0
00373                 || g_ascii_strcasecmp( type_s , "INLINE" )==0 )
00374          t = SED_HYDRO_INLINE;
00375       else if (    g_ascii_strcasecmp( type_s , "HYDROTREND" )==0
00376                 || g_ascii_strcasecmp( type_s , "EVENT"      )==0
00377                 || g_ascii_strcasecmp( type_s , "BUFFER"     )==0 )
00378          t = SED_HYDRO_HYDROTREND;
00379    }
00380 
00381    return t;
00382 }
00383 
00384 Sed_hydro_file_type
00385 sed_hydro_file_guess_type( const gchar* file , GError** error )
00386 {
00387    Sed_hydro_file_type type = SED_HYDRO_UNKNOWN;
00388 
00389    eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00390 
00391    if ( file )
00392    {
00393       GError* tmp_err = NULL;
00394       FILE*   fp      = eh_fopen_error( file , "r" , &tmp_err );
00395 
00396       if ( !tmp_err )
00397       {
00398          gchar      str[1000];
00399          gboolean   is_ascii = TRUE;
00400          gint       n        = fread( str , sizeof(gchar) , 1000 , fp );
00401          Sed_hydro* arr      = NULL;
00402          gint       i;
00403 
00404          /* Look for binary characters */
00405          for ( i=0 ; i<n && is_ascii ; i++ )
00406          {
00407             if ( !g_ascii_isgraph(str[i]) && !g_ascii_isspace(str[i]) )
00408                is_ascii = FALSE;
00409          }
00410 
00411          fclose( fp );
00412 
00413          if ( is_ascii ) /* Try to read it as a key value file */
00414          {
00415             arr = sed_hydro_scan_n_records( file , 10 , &tmp_err );
00416             if ( !tmp_err ) type = SED_HYDRO_INLINE;
00417          }
00418          else /* Try to read it as a hydrotrend file */
00419          {
00420             arr = sed_hydrotrend_read_n_recs( file , 10 , G_BIG_ENDIAN , NULL , &tmp_err );
00421             if ( arr ) type = SED_HYDRO_HYDROTREND_BE;
00422             else
00423             {
00424                arr = sed_hydrotrend_read_n_recs( file , 10 , G_LITTLE_ENDIAN , NULL , &tmp_err );
00425                if ( arr ) type = SED_HYDRO_HYDROTREND_LE;
00426             }
00427          }
00428 
00429          sed_hydro_array_destroy( arr );
00430       }
00431    }
00432 
00433    return type;
00434 }
00435 
00436 /*
00437 Sed_hydro
00438 sed_hydro_scan( FILE *fp )
00439 {
00440    Sed_hydro river_data;
00441    int n_grains=9999;
00442    
00443    if ( read_int_vector(fp,&n_grains,1)!=1 )
00444       return NULL;
00445    
00446    eh_require( n_grains>=2 );
00447 
00448    river_data = sed_hydro_new( n_grains-1 );
00449    
00450    read_time_vector  ( fp , &river_data->duration , 1 );
00451    read_double_vector( fp , &river_data->bedload  , 1 );
00452    read_double_vector( fp ,  river_data->conc     , (int)(n_grains-1) );
00453    read_double_vector( fp , &river_data->velocity , 1 );
00454    read_double_vector( fp , &river_data->width    , 1 );
00455    read_double_vector( fp , &river_data->depth    , 1 );
00456 
00457    river_data->duration *= S_DAYS_PER_YEAR;
00458 
00459    return river_data;
00460 }
00461 */
00462 /*
00463 Hydro_header *sed_hydro_scan_inline_header( FILE *fp )
00464 {
00465    int where;
00466    Sed_hydro rec;
00467    Hydro_header *hdr=eh_new( Hydro_header , 1 );
00468 
00469    where = ftell(fp);
00470    rec = sed_hydro_scan( fp );
00471    fseek( fp , where , SEEK_SET );
00472    
00473    hdr->comment = NULL;
00474    hdr->n_grains  = rec->n_grains;
00475    hdr->n_seasons = -1;
00476    hdr->n_samples = -1;
00477 
00478    rec = sed_hydro_destroy( rec );
00479 
00480    return hdr;
00481 }
00482 */
00483 
00490 Sed_hydro
00491 sed_hydro_new( gint n_grains )
00492 {
00493    Sed_hydro rec;
00494 
00495    NEW_OBJECT( Sed_hydro , rec );
00496 
00497    if ( n_grains>0 ) rec->conc = eh_new0( double , n_grains );
00498    else              rec->conc = NULL;
00499 
00500    rec->duration = 1.;
00501    rec->t        = 0.;
00502    rec->n_grains = n_grains;
00503 
00504    rec->velocity = 0.;
00505    rec->width    = 0.;
00506    rec->depth    = 0.;
00507    rec->bedload  = 0.;
00508 
00509    return rec;
00510 }
00511 
00512 #include <string.h>
00513 
00514 Sed_hydro sed_hydro_copy( Sed_hydro dest , Sed_hydro src )
00515 {
00516    eh_return_val_if_fail( src , NULL );
00517 
00518    if ( !dest )
00519       dest = sed_hydro_new( src->n_grains );
00520 
00521    sed_hydro_resize( dest , sed_hydro_size(src) );
00522 
00523    dest->velocity = src->velocity;
00524    dest->width    = src->width;
00525    dest->depth    = src->depth;
00526    dest->bedload  = src->bedload;
00527    dest->n_grains = src->n_grains;
00528    dest->duration = src->duration;
00529    dest->t        = src->t;
00530 
00531    g_memmove( dest->conc , src->conc , sizeof(double)*src->n_grains );
00532 
00533    return dest;
00534 }
00535 
00536 Sed_hydro
00537 sed_hydro_dup( Sed_hydro src )
00538 {
00539    return sed_hydro_copy( NULL , src );
00540 }
00541 
00542 Sed_hydro*
00543 sed_hydro_array_dup( Sed_hydro* src )
00544 {
00545    Sed_hydro* dest = NULL;
00546 
00547    if ( src )
00548    {
00549       gint       i;
00550       gint       len = g_strv_length( (gchar**)src );
00551       Sed_hydro* p   = src;
00552 
00553       dest = eh_new( Sed_hydro , len+1 );
00554 
00555       for ( i=0 ; *p ; p++,i++ ) dest[i] = sed_hydro_dup( *p );
00556       dest[len] = NULL;
00557    }
00558 
00559    return dest;
00560 }
00561 
00571 gboolean
00572 sed_hydro_is_same( Sed_hydro a , Sed_hydro b )
00573 {
00574    eh_return_val_if_fail( a , FALSE );
00575    eh_return_val_if_fail( b , FALSE );
00576 
00577    return    a->n_grains == b->n_grains
00578           && eh_compare_dbl( a->bedload  , b->bedload  , 1e-12 )
00579           && eh_compare_dbl( a->width    , b->width    , 1e-12 )
00580           && eh_compare_dbl( a->depth    , b->depth    , 1e-12 )
00581           && eh_compare_dbl( a->velocity , b->velocity , 1e-12 )
00582           && eh_compare_dbl( a->duration , b->duration , 1e-12 );
00583 
00584 }
00585 
00586 Sed_hydro sed_hydro_resize( Sed_hydro a , gssize n )
00587 {
00588    if ( !a )
00589       a = sed_hydro_new( n );
00590    else
00591    {
00592       if ( n>0 )
00593       {
00594          a->conc = eh_renew( double , a->conc , n );
00595          a->n_grains = n;
00596       }
00597       else
00598          a = sed_hydro_destroy(a);
00599    }
00600 
00601    return a;
00602 }
00603 
00604 double
00605 sed_hydro_time( Sed_hydro a )
00606 {
00607    eh_require( a );
00608    return a->t;
00609 }
00610 
00611 gssize
00612 sed_hydro_size( Sed_hydro a )
00613 {
00614    eh_require( a );
00615    return a->n_grains;
00616 }
00617 
00618 Sed_hydro sed_hydro_destroy( Sed_hydro rec )
00619 {
00620    if ( rec )
00621    {
00622       eh_free(rec->conc);
00623       eh_free(rec);
00624    }
00625 
00626    return NULL;
00627 }
00628 
00629 Sed_hydro*
00630 sed_hydro_array_destroy( Sed_hydro* arr )
00631 {
00632    if ( arr )
00633    {
00634       Sed_hydro* p;
00635 
00636       for ( p=arr ; *p ; p++ )
00637          sed_hydro_destroy( *p );
00638       eh_free( arr );
00639    }
00640 
00641    return NULL;
00642 }
00643 
00644 gssize
00645 sed_hydro_write_to_byte_order( FILE *fp , Sed_hydro a , gint order )
00646 {
00647    gssize n = 0;
00648 
00649    if ( a && fp )
00650    {
00651       gint32 n_grains = a->n_grains;
00652 
00653       if ( order == G_BYTE_ORDER )
00654       {
00655          n += fwrite( &(a->velocity) , sizeof(double) , 1 , fp );
00656          n += fwrite( &(a->width   ) , sizeof(double) , 1 , fp );
00657          n += fwrite( &(a->depth   ) , sizeof(double) , 1 , fp );
00658          n += fwrite( &(a->bedload ) , sizeof(double) , 1 , fp );
00659          n += fwrite( &(n_grains)    , sizeof(gint32) , 1 , fp );
00660          n += fwrite(   a->conc      , sizeof(double) , a->n_grains , fp );
00661          n += fwrite( &(a->duration) , sizeof(double) , 1 , fp );
00662          n += fwrite( &(a->t)        , sizeof(double) , 1 , fp );
00663       }
00664       else
00665       {
00666          n += eh_fwrite_dbl_swap  ( &(a->velocity) , sizeof(double) , 1 , fp );
00667          n += eh_fwrite_dbl_swap  ( &(a->width   ) , sizeof(double) , 1 , fp );
00668          n += eh_fwrite_dbl_swap  ( &(a->depth   ) , sizeof(double) , 1 , fp );
00669          n += eh_fwrite_dbl_swap  ( &(a->bedload ) , sizeof(double) , 1 , fp );
00670          n += eh_fwrite_int32_swap( &(n_grains)    , sizeof(gint32) , 1 , fp );
00671          n += eh_fwrite_dbl_swap  (   a->conc      , sizeof(double) , a->n_grains , fp );
00672          n += eh_fwrite_dbl_swap  ( &(a->duration) , sizeof(double) , 1 , fp );
00673          n += eh_fwrite_dbl_swap  ( &(a->t)        , sizeof(double) , 1 , fp );
00674       }
00675    }
00676 
00677    return n;
00678 }
00679 
00680 gssize
00681 sed_hydro_write( FILE *fp , Sed_hydro a )
00682 {
00683    return sed_hydro_write_to_byte_order(fp,a,G_BYTE_ORDER);
00684 }
00685 
00686 gint
00687 sed_hydro_fprint_rec( FILE* fp , Sed_hydro rec , const gchar* label )
00688 {
00689    gssize n = 0;
00690 
00691    eh_return_val_if_fail( rec , 0 );
00692 
00693    if ( !fp    ) fp    = stdout;
00694 
00695    if ( rec )
00696    {
00697       gssize i;
00698       const gchar* l = label?label:"Hydro Record";
00699 
00700       n += fprintf( fp , "[ %s ]\n"                                      , l             );
00701       n += fprintf( fp , "Duration                              : %fd\n" , rec->duration );
00702       n += fprintf( fp , "Bedload (kg/s)                        : %f\n"  , rec->bedload  );
00703       n += fprintf( fp , "Suspended load concentration (kg/m^3) : " );
00704       for ( i=0 ; i<rec->n_grains-1 ; i++ )
00705          n += fprintf( fp , "%f, " , rec->conc[i] );
00706       n += fprintf( fp , "%f\n" , rec->conc[rec->n_grains-1] );
00707 
00708       n += fprintf( fp , "Width (m)                             : %f\n"  , rec->width    );
00709       n += fprintf( fp , "Depth (m)                             : %f\n"  , rec->depth    );
00710       n += fprintf( fp , "Velocity (m/s)                        : %f\n"  , rec->velocity );
00711    }
00712 
00713    return n;
00714 }
00715 
00716 Sed_hydro
00717 sed_hydro_read( FILE *fp )
00718 {
00719    Sed_hydro a = NULL;
00720 
00721    if ( fp )
00722    {
00723       gint32 len;
00724 
00725       a = sed_hydro_new( 1 );
00726 
00727       fread( &(a->velocity) , sizeof(double) , 1   , fp );
00728       fread( &(a->width)    , sizeof(double) , 1   , fp );
00729       fread( &(a->depth)    , sizeof(double) , 1   , fp );
00730       fread( &(a->bedload)  , sizeof(double) , 1   , fp );
00731       fread( &len           , sizeof(gint32) , 1   , fp );
00732 
00733       sed_hydro_resize( a , len );
00734 
00735       fread( a->conc        , sizeof(double) , len , fp );
00736       fread( &(a->duration) , sizeof(double) , 1   , fp );
00737       fread( &(a->t)        , sizeof(double) , 1   , fp );
00738    }
00739 
00740    return a;
00741 }
00742 
00750 double* sed_hydro_copy_concentration( double* dest , Sed_hydro a )
00751 {
00752    if ( !dest )
00753       dest = eh_new( double , a->n_grains );
00754    memcpy( dest , a->conc , sizeof(double)*a->n_grains );
00755 
00756    return dest;
00757 }
00758 
00759 double sed_hydro_nth_concentration( Sed_hydro a , gssize n )
00760 {
00761    eh_return_val_if_fail( a             , 0. );
00762    eh_return_val_if_fail( n>=0          , 0. );
00763    eh_return_val_if_fail( n<a->n_grains , 0. );
00764 
00765    return a->conc[n];
00766 }
00767 
00775 double
00776 sed_hydro_flow_density( Sed_hydro a , double rho )
00777 {
00778    return sed_hydro_suspended_concentration( a ) + rho;
00779 }
00780 
00781 gboolean
00782 sed_hydro_is_hyperpycnal( Sed_hydro a )
00783 {
00784    gboolean is_hyper = FALSE;
00785 
00786    eh_require( a );
00787 
00788    if ( sed_hydro_flow_density( a , sed_rho_fresh_water() ) > 1.01*sed_rho_sea_water() )
00789       is_hyper = TRUE;
00790    else
00791       is_hyper = FALSE;
00792 
00793    return is_hyper;
00794 }
00795 
00796 double*
00797 sed_hydro_fraction( Sed_hydro a )
00798 {
00799    double* f = NULL;
00800 
00801    eh_return_val_if_fail( a , NULL );
00802 
00803    if ( a )
00804    {
00805       double total_c = sed_hydro_suspended_concentration(a);
00806 
00807       f = sed_hydro_copy_concentration( NULL , a );
00808       if ( total_c > 0. )
00809          eh_dbl_array_mult( f , sed_hydro_size(a) , 1./total_c );
00810       else
00811          eh_dbl_array_mult( f , sed_hydro_size(a) , 0. );
00812    }
00813 
00814    return f;
00815 }
00816 
00817 double
00818 sed_hydro_nth_fraction( Sed_hydro a , gssize n )
00819 {
00820    eh_return_val_if_fail( a             , 0. );
00821    eh_return_val_if_fail( n>=0          , 0. );
00822    eh_return_val_if_fail( n<a->n_grains , 0. );
00823 
00824    return a->conc[n] / sed_hydro_suspended_concentration(a);
00825 }
00826 
00827 double sed_hydro_suspended_concentration( Sed_hydro a )
00828 {
00829    double total_conc=0;
00830 
00831    eh_return_val_if_fail( a , 0 );
00832 
00833    {
00834       gssize n;
00835       for ( n=0 ; n<a->n_grains ; n++ )
00836          total_conc += a->conc[n];
00837    }
00838 
00839    return total_conc;
00840 }
00841 
00848 double
00849 sed_hydro_suspended_flux( Sed_hydro a )
00850 {
00851    double total_mass_flux=0;
00852 
00853    eh_return_val_if_fail( a , 0 );
00854 
00855    {
00856       gssize n;
00857       for ( n=0 ; n<a->n_grains ; n++ )
00858          total_mass_flux += a->conc[n];
00859       total_mass_flux *= a->velocity * a->width * a->depth;
00860    }
00861 
00862    return total_mass_flux;
00863 }
00864 
00865 double sed_hydro_suspended_volume_flux( Sed_hydro a )
00866 {
00867    double total=0;
00868 
00869    eh_return_val_if_fail( a , 0 );
00870 
00871    {
00872       gssize n;
00873       Sed_sediment sed = sed_sediment_env();
00874 
00875       for ( n=0 ; n<a->n_grains ; n++ )
00876          total += a->conc[n]/sed_type_rho_sat( sed_sediment_type(sed,n+1) );
00877       total *= a->velocity * a->width * a->depth;
00878    }
00879 
00880    return total;
00881 }
00882 
00883 double sed_hydro_water_flux( Sed_hydro a )
00884 {
00885    eh_return_val_if_fail( a , 0 );
00886    return a->velocity * a->width * a->depth;
00887 }
00888 
00889 double
00890 sed_hydro_suspended_load( Sed_hydro a )
00891 {
00892    eh_return_val_if_fail( a , 0 );
00893    return sed_hydro_suspended_flux(a)*sed_hydro_duration_in_seconds(a);
00894 }
00895 
00896 double
00897 sed_hydro_total_load( Sed_hydro a )
00898 {
00899    eh_return_val_if_fail( a , 0 );
00900    return sed_hydro_suspended_load( a ) + a->bedload*sed_hydro_duration_in_seconds(a);
00901 }
00902 
00903 double
00904 sed_hydro_array_suspended_load( Sed_hydro* arr )
00905 {
00906    double load = 0.;
00907    if ( arr )
00908    {
00909       Sed_hydro* r;
00910       for ( r=arr ; *r ; r++ )
00911       {
00912          load += sed_hydro_suspended_load( *r );
00913       }
00914    }
00915    return load;
00916 }
00917 
00918 double
00919 sed_hydro_array_total_load( Sed_hydro* arr )
00920 {
00921    double load = 0.;
00922    if ( arr )
00923    {
00924       Sed_hydro* r;
00925       for ( r=arr ; *r ; r++ )
00926          load += sed_hydro_total_load( *r );
00927    }
00928    return load;
00929 }
00930 
00931 Sed_hydro sed_hydro_set_nth_concentration( Sed_hydro a , gssize n , double val )
00932 {
00933    eh_return_val_if_fail( a             , NULL );
00934    eh_return_val_if_fail( n>=0          , NULL );
00935    eh_return_val_if_fail( n<a->n_grains , NULL );
00936 
00937    a->conc[n] = val;
00938 
00939    return a;
00940 }
00941 
00942 Sed_hydro
00943 sed_hydro_adjust_mass( Sed_hydro a , double f )
00944 {
00945    if ( a )
00946    {
00947       gint n;
00948       gint len = sed_hydro_size(a);
00949       eh_lower_bound( f , 0. );
00950       for ( n=0 ; n<len ; n++ )
00951          a->conc[n] *= f;
00952       a->bedload *= f;
00953    }
00954    return a;
00955 }
00956 
00957 Sed_hydro sed_hydro_set_velocity( Sed_hydro a , double val )
00958 {
00959    a->velocity = val;
00960    return a;
00961 }
00962 
00963 Sed_hydro sed_hydro_set_width( Sed_hydro a , double val )
00964 {
00965    a->width = val;
00966    return a;
00967 }
00968 
00969 Sed_hydro sed_hydro_set_depth( Sed_hydro a , double val )
00970 {
00971    a->depth = val;
00972    return a;
00973 }
00974 
00975 Sed_hydro sed_hydro_set_bedload( Sed_hydro a , double val )
00976 {
00977    a->bedload = val;
00978    return a;
00979 }
00980 
00981 Sed_hydro
00982 sed_hydro_set_duration( Sed_hydro a , double val )
00983 {
00984    eh_require( a );
00985    a->duration = val;
00986    return a;
00987 }
00988 
00989 Sed_hydro
00990 sed_hydro_set_time( Sed_hydro a , double val )
00991 {
00992    eh_require( a );
00993    a->t = val;
00994    return a;
00995 }
00996 
00997 Sed_hydro*
00998 sed_hydro_array_set_time( Sed_hydro* arr , double t_0 )
00999 {
01000    if ( arr )
01001    {
01002       Sed_hydro* a = NULL;
01003       double     t = t_0;
01004 
01005       for ( a=arr ; *a ; a++ )
01006       {
01007          sed_hydro_set_time( *a , t );
01008 
01009          t += sed_hydro_duration( *a );
01010       }
01011    }
01012    return arr;
01013 }
01014 
01015 double sed_hydro_velocity( Sed_hydro a )
01016 {
01017    return a->velocity;
01018 }
01019 
01020 double sed_hydro_width( Sed_hydro a )
01021 {
01022    return a->width;
01023 }
01024 
01025 double sed_hydro_depth( Sed_hydro a )
01026 {
01027    return a->depth;
01028 }
01029 
01030 double sed_hydro_bedload( Sed_hydro a )
01031 {
01032    return a->bedload;
01033 }
01034 
01035 double
01036 sed_hydro_duration( Sed_hydro a )
01037 {
01038    return a->duration;
01039 }
01040 
01041 double
01042 sed_hydro_duration_in_seconds( Sed_hydro a )
01043 {
01044    return sed_hydro_duration(a)*S_SECONDS_PER_DAY;
01045 }
01046 
01057 Sed_hydro
01058 sed_hydro_add_cell( Sed_hydro a         ,
01059                     const Sed_cell s    )
01060 {
01061    eh_return_val_if_fail( a , NULL );
01062    eh_return_val_if_fail( s , a    );
01063 
01064    eh_require( (sed_hydro_size(a)+1)==sed_cell_n_types(s) );
01065 
01066    if ( sed_cell_size(s)>0 )
01067    {
01068       double       q;
01069       double       volume_in_m3 = sed_cell_size( s );
01070       Sed_sediment sed          = sed_sediment_env();
01071       double       dt_in_secs   = sed_hydro_duration_in_seconds(a);
01072 
01073       // calculate the water flux.
01074       q = a->velocity*a->width*a->depth;
01075 
01076       eh_require( q>0 );
01077 
01078       // calculate the bedload flux to add.  remember that the flux
01079       // is measured in kg/s.
01080       a->bedload += sed_cell_fraction(s,0)
01081                   * volume_in_m3
01082                   * sed_type_rho_sat( sed_sediment_type(sed,0) ) / dt_in_secs;
01083 
01084       // calculate the suspended load flux to add.  remember that
01085       // the concentrations are in kg/m^3.
01086       {
01087          gssize i;
01088          gssize len = sed_sediment_n_types(sed)-1;
01089          for ( i=0 ; i<len ; i++ )
01090             a->conc[i] += sed_cell_fraction(s,i+1)
01091                         * volume_in_m3
01092                         * sed_type_rho_sat( sed_sediment_type(sed , i+1) )
01093                         / ( q*dt_in_secs );
01094       }
01095    }
01096 
01097    return a;
01098 }
01099 
01100 Sed_hydro sed_hydro_subtract_cell( Sed_hydro a         ,
01101                                    const Sed_cell s    )
01102 {
01103 
01104    eh_return_val_if_fail( a , NULL );
01105    eh_return_val_if_fail( s , a    );
01106 
01107    eh_require( (sed_hydro_size(a)+1)==sed_cell_n_types(s) );
01108 
01109    if ( sed_cell_size(s)>0 )
01110    {
01111       double       q;
01112       double       volume_in_m3 = sed_cell_size( s );
01113       Sed_sediment sed          = sed_sediment_env();
01114       double       dt_in_secs   = sed_hydro_duration_in_seconds(a);
01115 
01116       // calculate the water flux.
01117       q = a->velocity*a->width*a->depth;
01118 
01119       eh_require( q>0 );
01120 
01121       // calculate the bedload flux to subtract.  remember that the flux
01122       // is measured in kg/s.
01123       a->bedload -= sed_cell_nth_fraction(s,0)
01124                   * volume_in_m3
01125                   * sed_type_rho_sat( sed_sediment_type(sed,0) ) / dt_in_secs;
01126       eh_lower_bound( a->bedload , 0 );
01127 
01128       // calculate the suspended load flux to subtract.  remember that
01129       // the concentrations are in kg/m^3.
01130       {
01131          gssize i;
01132          gssize len = sed_sediment_n_types(sed)-1;
01133          for ( i=0 ; i<len ; i++ )
01134          {
01135             a->conc[i] -= sed_cell_nth_fraction(s,i+1)
01136                         * volume_in_m3
01137                         * sed_type_rho_sat( sed_sediment_type(sed,i+1) )
01138                         / ( q*dt_in_secs );
01139             eh_lower_bound( a->conc[i] , 0 );
01140          }
01141       }
01142    }
01143 
01144    return a;
01145 }
01146 
01147 Sed_hydro sed_hydro_average_records( Sed_hydro* rec , gssize n_recs )
01148 {
01149    Sed_hydro mean_rec;
01150 
01151    eh_return_val_if_fail( rec      , NULL                  );
01152    eh_return_val_if_fail( rec[0]   , NULL                  );
01153    eh_return_val_if_fail( n_recs>0 , NULL                  );
01154    eh_return_val_if_fail( n_recs>1 , sed_hydro_dup(rec[0]) );
01155 
01156    mean_rec = sed_hydro_new( rec[0]->n_grains );
01157 
01158    {
01159       gssize i, j;
01160       double total_q=0;
01161       double *total_load;
01162 
01163       total_load = eh_new0( double , rec[0]->n_grains );
01164 
01165       mean_rec->duration = 0;
01166       for ( i=0 ; i<n_recs ; i++ )
01167       {
01168          mean_rec->velocity += rec[i]->velocity;
01169          mean_rec->width    += rec[i]->width;
01170          mean_rec->depth    += rec[i]->depth;
01171          mean_rec->bedload  += rec[i]->bedload;
01172          mean_rec->duration += rec[i]->duration;
01173          for ( j=0 ; j<mean_rec->n_grains; j++ )
01174          {
01175             mean_rec->conc[j] += rec[i]->conc[j];
01176             total_load[j]     += rec[i]->conc[j]*sed_hydro_water_flux(rec[i]);
01177          }
01178          total_q += sed_hydro_water_flux( rec[i] )*rec[i]->duration;
01179       }
01180       mean_rec->velocity /= (double)n_recs;
01181       mean_rec->width    /= (double)n_recs;
01182       mean_rec->depth    /= (double)n_recs;
01183       mean_rec->bedload  /= (double)n_recs;
01184       for ( j=0 ; j<mean_rec->n_grains ; j++ )
01185          mean_rec->conc[j] /= (double)n_recs;
01186 
01187       // adjust the mean width to conserve the amount of water.
01188       mean_rec->width  = total_q/mean_rec->duration/(mean_rec->velocity*mean_rec->depth);
01189 
01190       // adjust the concentrations to conserve the amount of each sediment type.
01191       for ( j=0 ; j<mean_rec->n_grains ; j++ )
01192          mean_rec->conc[j] = total_load[j]/total_q;
01193 
01194       eh_free( total_load );
01195    }
01196 
01197    return mean_rec;
01198 }
01199 
01200 double sed_hydro_sum_durations( Sed_hydro* rec , gssize n_recs )
01201 {
01202    double duration=0;
01203 
01204    eh_return_val_if_fail( rec      , 0 );
01205    eh_return_val_if_fail( n_recs>0 , 0 );
01206 
01207    {
01208       gssize i;
01209       for ( i=0 ; i<n_recs ; i++ )
01210          duration += rec[i]->duration;
01211    }
01212 
01213    return duration;
01214 }
01215 
01216 typedef struct
01217 {
01218    double val;
01219    int    ind;
01220 }
01221 Hydro_sort_st;
01222 
01223 gint cmp_hydro_sort_vals( Hydro_sort_st *a , Hydro_sort_st *b ) G_GNUC_INTERNAL;
01224 gint cmp_hydro_sort_inds( Hydro_sort_st *a , Hydro_sort_st *b ) G_GNUC_INTERNAL;
01225 
01233 Sed_hydro*
01234 sed_hydro_array_eventize_number( Sed_hydro* rec_a , gssize n_events )
01235 {
01236    Sed_hydro* event_a = NULL;
01237 
01238    if ( rec_a && n_events>=0 )
01239       event_a = sed_hydro_process_records( rec_a , g_strv_length( (gchar**)rec_a ) , n_events , TRUE );
01240 
01241    return event_a;
01242 }
01243 
01251 Sed_hydro*
01252 sed_hydro_array_eventize_fraction( Sed_hydro* rec_a , double fraction )
01253 {
01254    Sed_hydro* event_a = NULL;
01255 
01256    if ( rec_a && rec_a[0] && fraction>0 && fraction<=1 )
01257    {
01258       gssize len      = g_strv_length( (gchar**)rec_a);
01259       double dummy;
01260       gssize n_events = fraction*len;
01261       double fraction = modf( fraction*len , &dummy );
01262 
01263       if ( g_random_double_range( 0 , 1 ) < fraction )
01264          n_events++;
01265       
01266       event_a = sed_hydro_process_records( rec_a , len , n_events , TRUE );
01267    }
01268 
01269    return event_a;
01270 }
01271 
01272 Sed_hydro*
01273 sed_hydro_array_eventize_conc( Sed_hydro* rec_a , double c )
01274 {
01275    Sed_hydro* event_a = NULL;
01276 
01277    if ( rec_a && rec_a[0] && c>=0 )
01278    {
01279       {
01280          gssize     n_events  = 0;
01281 //         double     load      = sed_hydro_array_suspended_load( rec_a );
01282 //         double     threshold = load*f;
01283 //         Sed_hydro* sorted_a  = sed_hydro_array_sort_by_suspended_load( rec_a );
01284          Sed_hydro* r;
01285 //         double     sum;
01286 
01287 
01288          for ( r=rec_a ; *r ; r++ )
01289          {
01290             if ( sed_hydro_flow_density( *r , sed_rho_fresh_water() ) > c )
01291                n_events++;
01292          }
01293 /*
01294          eh_require( sorted_a );
01295 
01296          for ( r=sorted_a,sum=0. ; *r && sum<threshold ; r++ )
01297          {
01298             sum += sed_hydro_suspended_load( *r );
01299             n_events++;
01300          }
01301 
01302          eh_free( sorted_a );
01303 */
01304 
01305          event_a = sed_hydro_process_records( rec_a                         ,
01306                                               g_strv_length((gchar**)rec_a) ,
01307                                               n_events                      ,
01308                                               TRUE );
01309       }
01310    }
01311 
01312    return event_a;
01313 }
01314 
01323 Sed_hydro*
01324 sed_hydro_array_eventize( Sed_hydro* rec_a , double f , gboolean insert_mean_values )
01325 {
01326    Sed_hydro* event_a = NULL;
01327 
01328    if ( rec_a && rec_a[0] )
01329    {
01330       if ( eh_compare_dbl( f , 1. , 1e-12 ) )
01331          event_a = sed_hydro_array_dup( rec_a );
01332       else if ( f>0 )
01333       {
01334          gssize     n_events  = 0;
01335          double     load      = sed_hydro_array_suspended_load( rec_a );
01336          double     threshold = load*f;
01337          Sed_hydro* sorted_a  = sed_hydro_array_sort_by_suspended_load( rec_a );
01338          Sed_hydro* r;
01339          double     sum;
01340 
01341          eh_require( sorted_a );
01342 
01343          for ( r=sorted_a,sum=0. ; *r && sum<threshold ; r++ )
01344          {
01345             sum += sed_hydro_suspended_load( *r );
01346             n_events++;
01347          }
01348 
01349          eh_free( sorted_a );
01350 
01351          event_a = sed_hydro_process_records( rec_a                         ,
01352                                               g_strv_length((gchar**)rec_a) ,
01353                                               n_events                      ,
01354                                               insert_mean_values );
01355       }
01356    }
01357 
01358    return event_a;
01359 }
01360 
01361 gint
01362 sed_hydro_cmp_suspended_load( Sed_hydro* a , Sed_hydro* b )
01363 {
01364    gint cmp = 0;
01365 
01366    eh_require( a && *a );
01367    eh_require( b && *b );
01368 
01369    if ( *a && *b )
01370    {
01371       double a_load = sed_hydro_suspended_load( *a );
01372       double b_load = sed_hydro_suspended_load( *b );
01373 
01374       if      ( a_load < b_load )
01375          cmp = +1;
01376       else if ( a_load > b_load )
01377          cmp = -1;
01378       else
01379          cmp =  0;
01380    }
01381 
01382    return cmp;
01383 }
01384 
01385 gint
01386 sed_hydro_cmp_total_load( Sed_hydro* a , Sed_hydro* b )
01387 {
01388    gint cmp = 0;
01389 
01390    eh_require( a && *a );
01391    eh_require( b && *b );
01392 
01393    if ( *a && *b )
01394    {
01395       double a_load = sed_hydro_total_load( *a );
01396       double b_load = sed_hydro_total_load( *b );
01397 
01398       if      ( a_load < b_load )
01399          cmp = +1;
01400       else if ( a_load > b_load )
01401          cmp = -1;
01402       else
01403          cmp =  0;
01404    }
01405 
01406    return cmp;
01407 }
01408 
01409 gint
01410 sed_hydro_cmp_time( Sed_hydro *a , Sed_hydro *b )
01411 {
01412    gint cmp = 0;
01413 
01414    eh_require( a && *a );
01415    eh_require( b && *b );
01416 
01417    if ( *a && *b )
01418    {
01419       double a_t = sed_hydro_time( *a );
01420       double b_t = sed_hydro_time( *b );
01421 
01422       if      ( a_t < b_t )
01423          cmp = -1;
01424       else if ( a_t > b_t )
01425          cmp = +1;
01426       else
01427          cmp =  0;
01428    }
01429 
01430    return cmp;
01431 }
01432 
01433 Sed_hydro*
01434 sed_hydro_array_sort( Sed_hydro* rec_a , GCompareFunc f )
01435 {
01436    Sed_hydro* sorted_a = NULL;
01437 
01438    if ( rec_a )
01439    {
01440       gint       len           = g_strv_length( (gchar**)rec_a );
01441       GPtrArray* sorted_parray = g_ptr_array_sized_new( len+1 );
01442       Sed_hydro* r;
01443 
01444       for ( r=rec_a ; *r ; r++ )
01445       {
01446          g_ptr_array_add( sorted_parray , *r );
01447       }
01448 
01449       g_ptr_array_sort( sorted_parray , f    );
01450       g_ptr_array_add ( sorted_parray , NULL );
01451 
01452       sorted_a = (Sed_hydro*)g_ptr_array_free( sorted_parray , FALSE );
01453    }
01454 
01455    return sorted_a;
01456 }
01457 
01458 Sed_hydro*
01459 sed_hydro_array_sort_by_time( Sed_hydro* arr )
01460 {
01461    return sed_hydro_array_sort( arr , (GCompareFunc)sed_hydro_cmp_time );
01462 }
01463 
01464 Sed_hydro*
01465 sed_hydro_array_sort_by_suspended_load( Sed_hydro* arr )
01466 {
01467    return sed_hydro_array_sort( arr , (GCompareFunc)sed_hydro_cmp_suspended_load );
01468 }
01469 
01470 Sed_hydro*
01471 sed_hydro_array_sort_by_total_load( Sed_hydro* arr )
01472 {
01473    return sed_hydro_array_sort( arr , (GCompareFunc)sed_hydro_cmp_total_load );
01474 }
01475 
01476 Sed_hydro*
01477 sed_hydro_process_records( Sed_hydro* rec      ,
01478                            gssize n_recs       ,
01479                            gssize n_sig_values ,
01480                            gboolean insert_mean_values )
01481 {
01482    Sed_hydro* return_ptr = NULL;
01483 
01484    eh_return_val_if_fail( rec      , NULL   );
01485    eh_return_val_if_fail( rec[0]   , NULL   );
01486 
01487    if ( n_sig_values==0 && insert_mean_values )
01488    {
01489       Sed_hydro mean_rec = sed_hydro_average_records( rec , n_recs );
01490       eh_strv_append( (gchar***)&return_ptr , (gchar*)mean_rec );
01491    }
01492    else
01493    {
01494       GSList*    top_n   = NULL;
01495       GPtrArray* new_rec = NULL;
01496 
01497       // Create a list to record the top n events
01498       {
01499          Hydro_sort_st* new_val;
01500          gint           i;
01501 
01502          for ( i=0 ; i<n_sig_values ; i++ )
01503          {
01504             new_val      = eh_new( Hydro_sort_st , 1 );
01505             new_val->val = G_MINDOUBLE;
01506             new_val->ind = -1;
01507 
01508             top_n        = g_slist_append( top_n , new_val );
01509          }
01510       }
01511 
01512       // Insert to top n events into the list
01513       if ( n_sig_values!=0 )
01514       {
01515          Hydro_sort_st* lowest_val;
01516          Hydro_sort_st* new_val;
01517          gint           i;
01518          double         val;
01519 
01520          lowest_val = (Hydro_sort_st*)g_slist_nth_data( top_n , 0 );
01521          for ( i=0 ; i<n_recs ; i++ )
01522          {
01523             val = sed_hydro_suspended_flux(rec[i]);
01524             if ( val>lowest_val->val )
01525             {
01526                new_val = eh_new( Hydro_sort_st , 1 );
01527                new_val->val = val;
01528                new_val->ind = i;
01529                top_n = g_slist_insert_sorted( top_n ,
01530                                               new_val ,
01531                                               (GCompareFunc)cmp_hydro_sort_vals );
01532                top_n = g_slist_remove( top_n , lowest_val );
01533                eh_free( lowest_val );
01534                lowest_val = (Hydro_sort_st*)g_slist_nth_data( top_n , 0 );
01535             }
01536          }
01537       }
01538 
01539       // sort these records by time (or index)
01540       top_n = g_slist_sort( top_n , (GCompareFunc)cmp_hydro_sort_inds );
01541 
01542       new_rec = g_ptr_array_new();
01543 
01544       // Create the new list of records with mean values put in between the
01545       // largest events.
01546       {
01547          gint      j;
01548          gint      ind;
01549          gint      ind_last;
01550          Sed_hydro mean_rec;
01551          Sed_hydro real_rec;
01552 
01553          for ( j=0,ind=0,ind_last=-1 ; j<n_sig_values ; j++,ind_last=ind )
01554          {
01555             ind = ((Hydro_sort_st*)g_slist_nth_data( top_n , j ))->ind;
01556 
01557             if ( insert_mean_values && ind != ind_last+1 )
01558             {
01559                mean_rec = sed_hydro_average_records( &(rec[ind_last+1]) , ind-ind_last-1 );
01560 
01561                // Add the mean record.
01562                g_ptr_array_add( new_rec , mean_rec );
01563             }
01564 
01565             real_rec = sed_hydro_dup( rec[ind] );
01566 
01567             // Add the real record.
01568             g_ptr_array_add( new_rec , real_rec );
01569          }
01570 
01571          if ( insert_mean_values && ind<n_recs-1 )
01572          {
01573             ind = n_recs;
01574             mean_rec = sed_hydro_average_records( &(rec[ind_last+1]) , ind-ind_last-1 );
01575 
01576             // Add the mean record.
01577             g_ptr_array_add( new_rec , mean_rec );
01578          }
01579 
01580          // Create a NULL-terminated array
01581          g_ptr_array_add( new_rec , NULL );
01582       }
01583 
01584       return_ptr = (Sed_hydro*)g_ptr_array_free( new_rec , FALSE );
01585 
01586       g_slist_foreach( top_n , &eh_free_slist_data , NULL );
01587       g_slist_free   ( top_n );
01588    }
01589 
01590    return return_ptr;
01591 }
01592 
01593 gint cmp_hydro_sort_vals( Hydro_sort_st *a , Hydro_sort_st *b )
01594 {
01595    if ( a->val < b->val )
01596       return -1;
01597    else if ( a->val > b->val )
01598       return 1;
01599    else
01600       return 0;
01601 }
01602 
01603 gint cmp_hydro_sort_inds( Hydro_sort_st *a , Hydro_sort_st *b )
01604 {
01605    if ( a->ind < b->ind )
01606       return -1;
01607    else if ( a->ind > b->ind )
01608       return 1;
01609    else
01610       return 0;
01611 }
01612 
01613 Sed_hydro_file sed_hydro_file_set_wrap( Sed_hydro_file fp , gboolean wrap_is_on )
01614 {
01615    fp->wrap_is_on = wrap_is_on;
01616    return fp;
01617 }
01618 
01619 Sed_hydro_file sed_hydro_file_set_buffer_length( Sed_hydro_file fp , gssize len )
01620 {
01621    int whence = fp->buf_cur - fp->buf_set;
01622 
01623    fp->buf_set      = g_renew( Sed_hydro , fp->buf_set , len+1 );
01624    fp->buf_set[len] = NULL;
01625    fp->buf_cur      = fp->buf_set + whence;
01626    fp->buffer_len   = len;
01627 
01628    return fp;
01629 }
01630 
01631 Sed_hydro_file sed_hydro_file_set_sig_values( Sed_hydro_file fp , int n_sig_values )
01632 {
01633    fp->n_sig_values = n_sig_values;
01634    return fp;
01635 }
01636 
01637 Sed_hydrotrend_header *sed_hydro_file_header( Sed_hydro_file fp )
01638 {
01639    return fp->hdr;
01640 }
01641 
01642 Sed_hydro
01643 sed_hydro_file_read_record( Sed_hydro_file fp )
01644 {
01645    return (*(fp->read_record))( fp );
01646 }
01647 
01656 Sed_hydro_file
01657 sed_hydro_file_new( const char*         filename     ,
01658                     Sed_hydro_file_type type         ,
01659                     gboolean            buffer_is_on ,
01660                     gboolean            wrap_is_on   ,
01661                     GError** error )
01662 {
01663    Sed_hydro_file fp;
01664 
01665    eh_require( error==NULL || *error==NULL );
01666 
01667    if ( filename )
01668    {
01669       GError* tmp_err = NULL;
01670 
01671       NEW_OBJECT( Sed_hydro_file , fp );
01672 
01673       // the 'b' (binary) option for fopen is supposed to be ignored.  however,
01674       // on some windows machines, it seems to be necessary.
01675       if ( strcmp( filename , "-" )==0 )
01676          fp->fp = stdin;
01677       else
01678       {
01679          if ( type==SED_HYDRO_INLINE ) fp->fp = eh_fopen_error( filename , "r"  , &tmp_err );
01680          else                          fp->fp = eh_fopen_error( filename , "rb" , &tmp_err );
01681       }
01682 
01683       if ( !tmp_err )
01684       {
01685          fp->file = g_strdup( filename );
01686 
01687          // there are two types of river files (currently) - inline and hydrotrend.
01688          // if using a hydrotrend file, there are two methods for reading - buffered
01689          // or unbuffered.
01690          if ( type==SED_HYDRO_INLINE )
01691          {
01692             fp->type         = SED_HYDRO_INLINE;
01693             fp->buf_set      = NULL;
01694             fp->buf_cur      = NULL;
01695             fp->buffer_len   = 0;
01696             fp->n_sig_values = 0;
01697 //            fp->read_hdr     = (Hydro_read_header_func)&_hydro_read_inline_header;
01698             fp->read_hdr     = NULL;
01699             fp->read_record  = (Hydro_read_record_func)&_hydro_read_inline_record;
01700 
01701             fp->header_start = ftell(fp->fp);
01702             fp->hdr          = NULL;
01703             fp->data_start   = ftell(fp->fp);
01704          }
01705          else if (    type==SED_HYDRO_HYDROTREND 
01706                    || type==SED_HYDRO_HYDROTREND_BE
01707                    || type==SED_HYDRO_HYDROTREND_LE )
01708          {
01709             fp->type            = SED_HYDRO_HYDROTREND;
01710 
01711             if ( buffer_is_on )
01712             {
01713                fp->buf_set      = eh_new0( Sed_hydro , HYDRO_BUFFER_LEN+1 );
01714                fp->buf_cur      = fp->buf_set;
01715                fp->buffer_len   = HYDRO_BUFFER_LEN;
01716                fp->n_sig_values = HYDRO_N_SIG_VALUES;
01717                fp->read_hdr     = (Hydro_read_header_func)&_hydro_read_hydrotrend_header;
01718                fp->read_record  = (Hydro_read_record_func)&_hydro_read_hydrotrend_record_buffer;
01719             }
01720             else
01721             {
01722                fp->buf_set      = NULL;
01723                fp->buf_cur      = NULL;
01724                fp->buffer_len   = 0;
01725                fp->n_sig_values = 0;
01726                fp->read_hdr     = (Hydro_read_header_func)&_hydro_read_hydrotrend_header;
01727                fp->read_record  = (Hydro_read_record_func)&_hydro_read_hydrotrend_record;
01728             }
01729 
01730             fp->header_start = ftell(fp->fp);
01731             fp->hdr          = (*(fp->read_hdr))(fp);
01732             fp->data_start   = ftell(fp->fp);
01733 
01734          }
01735          else
01736             eh_require_not_reached();
01737 
01738          fp->data_size    = sizeof(float);
01739          fp->wrap_is_on   = wrap_is_on;
01740       }
01741 
01742       if ( tmp_err )
01743       {
01744          g_propagate_error( error , tmp_err );
01745          eh_free( fp );
01746          fp = NULL;
01747       }
01748    }
01749 
01750    return fp;
01751 }
01752 
01759 Sed_hydro_file sed_hydro_file_destroy( Sed_hydro_file fp )
01760 {
01761    eh_return_val_if_fail( fp , NULL );
01762 
01763    if ( fp )
01764    {
01765       fclose( fp->fp );
01766       eh_free( fp->file );
01767 
01768       if ( fp->buf_set )
01769       {
01770          gssize i;
01771          for ( i=0 ; i<fp->buffer_len ; i++ )
01772             fp->buf_set[i] = sed_hydro_destroy( fp->buf_set[i] );
01773          eh_free(fp->buf_set);
01774       }
01775 
01776       /* If the input file was of type 'inline', there is NULL */
01777       if ( fp->hdr )
01778       {
01779          eh_free( fp->hdr->comment );
01780          eh_free( fp->hdr );
01781       }
01782       eh_free( fp );
01783    }
01784 
01785    return NULL;
01786 }
01787 /*
01788 Hydro_header *_hydro_read_inline_header( Sed_hydro_file fp )
01789 {
01790    return sed_hydro_scan_inline_header( fp->fp );
01791 }
01792 */
01793 
01794 static Sed_hydro
01795 _hydro_read_inline_record( Sed_hydro_file fp )
01796 {
01797    Sed_hydro rec = NULL;
01798 
01799    eh_require( fp );
01800 
01801    /* If the buffer hasn't already been set */
01802    if ( !(fp->buf_set) )
01803    {
01804       /* Fill the buffer with all the records from the file */
01805       fp->buf_set = sed_hydro_scan( fp->file , NULL );
01806       fp->buf_cur = fp->buf_set;
01807    }
01808 
01809    eh_require( fp->buf_set );
01810 
01811    if ( fp->buf_cur )
01812    {
01813       /* Duplicate the record at the top of the queue */
01814       rec = sed_hydro_dup( *(fp->buf_cur) );
01815 
01816       /* Update the pointer to the current record */
01817       fp->buf_cur++;
01818 
01819       /* Rewind the buffer (the buffer is NULL-terminated) */
01820       if ( *(fp->buf_cur)==NULL )
01821       {
01822          if ( fp->wrap_is_on ) fp->buf_cur = fp->buf_set;
01823          else                  fp->buf_cur = NULL;
01824       }
01825    }
01826 
01827    return rec;
01828 }
01829 
01830 Sed_hydrotrend_header*
01831 _hydro_read_hydrotrend_header( Sed_hydro_file fp )
01832 {
01833    return sed_hydrotrend_read_header( fp->fp );
01834 }
01835 
01836 Sed_hydro _hydro_read_hydrotrend_record( Sed_hydro_file fp )
01837 {
01838    Sed_hydro rec;
01839    
01840    // read the record using the appropriate function.  if we encounter the end of
01841    // the file, start reading from the beginning of the data.  if wrap is off,
01842    // return with an error.
01843    rec = sed_hydrotrend_read_next_rec( fp->fp , fp->hdr->n_grains );
01844    if ( feof(fp->fp) )
01845    {
01846       if ( fp->wrap_is_on )
01847       {
01848          clearerr(fp->fp);
01849          fseek( fp->fp , fp->data_start , SEEK_SET );
01850          rec = (*(fp->read_record))( fp );
01851       }
01852       else
01853          eh_error( "Encountered end of file");
01854    }
01855 
01856    return rec;
01857 }
01858 
01859 Sed_hydro _hydro_read_hydrotrend_record_buffer( Sed_hydro_file fp )
01860 {
01861    // if we are at the end of the buffer we must create a new buffer.
01862    // otherwise just return the next record in the buffer.
01863    if ( *(fp->buf_cur)==NULL )
01864    {
01865       sed_hydro_file_fill_buffer( fp );
01866    }
01867    fp->buf_cur += 1;
01868 
01869    return sed_hydro_dup(fp->buf_cur[-1]);
01870 }
01871 
01872 Sed_hydro *sed_hydro_file_fill_buffer( Sed_hydro_file fp )
01873 {
01874    int i;
01875    int buffer_len         = fp->buffer_len;
01876    int n_sig_values       = fp->n_sig_values;
01877    Sed_hydro *temp_buffer = eh_new( Sed_hydro , buffer_len );
01878    Sed_hydro *buf_set;
01879 
01880    for ( i=0 ; i<buffer_len ; i++ )
01881    {
01882       fp->buf_set[i] = sed_hydro_destroy( fp->buf_set[i] );
01883    }
01884 
01885    for ( i=0 ; i<buffer_len ; i++ )
01886    {
01887       temp_buffer[i] = sed_hydrotrend_read_next_rec( fp->fp , fp->hdr->n_grains );
01888 
01889       if ( feof(fp->fp) )
01890       {
01891          if ( fp->wrap_is_on )
01892          {
01893             clearerr(fp->fp);
01894             fseek( fp->fp , fp->data_start , SEEK_SET );
01895             temp_buffer[i] = sed_hydrotrend_read_next_rec( fp->fp , fp->hdr->n_grains );
01896          }
01897          else
01898             eh_error( "Encountered end of the file");
01899       }
01900    }
01901 
01902    buf_set = sed_hydro_process_records( temp_buffer , buffer_len , n_sig_values , TRUE );
01903 
01904    for ( i=0 ; buf_set[i] ; i++ )
01905    {
01906       fp->buf_set[i] = buf_set[i];
01907    }
01908    fp->buf_set[i] = NULL;
01909 
01910    for ( i=0 ; i<buffer_len ; i++ )
01911       temp_buffer[i] = sed_hydro_destroy( temp_buffer[i] );
01912    eh_free(temp_buffer);
01913    eh_free(buf_set);
01914 
01915    fp->buf_cur = fp->buf_set;
01916 
01917    return fp->buf_set;
01918 }
01919 

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