00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
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
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
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 )
00414 {
00415 arr = sed_hydro_scan_n_records( file , 10 , &tmp_err );
00416 if ( !tmp_err ) type = SED_HYDRO_INLINE;
00417 }
00418 else
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
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
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
01074 q = a->velocity*a->width*a->depth;
01075
01076 eh_require( q>0 );
01077
01078
01079
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
01085
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
01117 q = a->velocity*a->width*a->depth;
01118
01119 eh_require( q>0 );
01120
01121
01122
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
01129
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
01188 mean_rec->width = total_q/mean_rec->duration/(mean_rec->velocity*mean_rec->depth);
01189
01190
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
01282
01283
01284 Sed_hydro* r;
01285
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
01295
01296
01297
01298
01299
01300
01301
01302
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
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
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
01540 top_n = g_slist_sort( top_n , (GCompareFunc)cmp_hydro_sort_inds );
01541
01542 new_rec = g_ptr_array_new();
01543
01544
01545
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
01562 g_ptr_array_add( new_rec , mean_rec );
01563 }
01564
01565 real_rec = sed_hydro_dup( rec[ind] );
01566
01567
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
01577 g_ptr_array_add( new_rec , mean_rec );
01578 }
01579
01580
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
01674
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
01688
01689
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
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
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
01789
01790
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
01802 if ( !(fp->buf_set) )
01803 {
01804
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
01814 rec = sed_hydro_dup( *(fp->buf_cur) );
01815
01816
01817 fp->buf_cur++;
01818
01819
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
01841
01842
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
01862
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