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

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <glib.h>
00003 
00004 #include "utils/utils.h"
00005 #include "sed_hydrotrend.h"
00006 
00007 
00008 GQuark
00009 sed_hydrotrend_error_quark( void )
00010 {
00011    return g_quark_from_static_string( "sed-hydrorend-error-quark" );
00012 }
00013 
00014 // Functions to read/write a standard HydroTrend output file.
00021 Sed_hydrotrend_header*
00022 sed_hydrotrend_read_header( FILE *fp )
00023 {
00024    return sed_hydrotrend_read_header_from_byte_order( fp , G_BYTE_ORDER );
00025 }
00026 
00034 Sed_hydrotrend_header*
00035 sed_hydrotrend_read_header_from_byte_order( FILE *fp , gint order )
00036 {
00037    Sed_hydrotrend_header *hdr = NULL;
00038 
00039    if ( fp )
00040    {
00041       gint n;
00042       size_t (*fread_int)(void*,size_t,size_t,FILE*);
00043 
00044       if ( order==G_BYTE_ORDER ) fread_int = fread;
00045       else                       fread_int = eh_fread_int32_swap;
00046 
00047       if ( fread_int( &n , sizeof(gint32)  , 1 , fp )==1 && (n>=0 && n<2048 ) )
00048       {
00049          gchar* str = eh_new( gchar , n+1 );
00050 
00051          hdr = eh_new( Sed_hydrotrend_header , 1 );
00052 
00053          fread( str , sizeof(gchar) , n , fp );
00054          str[n] = '\0';
00055 
00056          hdr->comment = g_strescape( str , "\\" );
00057          eh_free( str );
00058 
00059          if (    fread_int( &(hdr->n_grains ) , sizeof(gint)  , 1 , fp )!=1 || hdr->n_grains <=0
00060               || fread_int( &(hdr->n_seasons) , sizeof(gint)  , 1 , fp )!=1 || hdr->n_seasons<=0
00061               || fread_int( &(hdr->n_samples) , sizeof(gint)  , 1 , fp )!=1 || hdr->n_samples<=0 )
00062          {
00063             hdr = sed_hydrotrend_header_destroy( hdr );
00064          }
00065       }
00066 
00067       if ( !hdr )
00068       {
00069          eh_debug( "Trouble reading hydrotrend header." );
00070          eh_debug( "Is the byte of the hydrotrend file the same as that" );
00071          eh_debug( "on the machine you are running sedflux?" );
00072          eh_debug( "The byte order of your system is %s" ,
00073                    (G_BYTE_ORDER==G_BIG_ENDIAN)?"big-endian":"little-endian" );
00074       }
00075    }
00076 
00077    return hdr;
00078 }
00079 
00080 Sed_hydrotrend_header*
00081 sed_hydrotrend_join_header_from_byte_order( FILE** fp_list , gint order , GError** err )
00082 {
00083    Sed_hydrotrend_header *hdr = NULL;
00084 
00085    eh_return_val_if_fail( err==NULL || *err==NULL , NULL );
00086 
00087    if ( fp_list && *fp_list )
00088    {
00089       FILE**                 fp;
00090       Sed_hydrotrend_header* h;
00091       GError*                tmp_err = NULL;
00092 
00093       hdr = sed_hydrotrend_read_header_from_byte_order( fp_list[0] , order );
00094       rewind( fp_list[0] );
00095 
00096       for ( fp=fp_list+1 ; *fp && !tmp_err ; fp++ )
00097       {
00098          h = sed_hydrotrend_read_header_from_byte_order( *fp , order );
00099          rewind( *fp );
00100 
00101          if ( h )
00102          {
00103             if ( h->n_grains != hdr->n_grains && !tmp_err )
00104                g_set_error( &tmp_err , SED_HYDROTREND_ERROR , SED_HYDROTREND_ERROR_BAD_HEADER ,
00105                             "Number of grain sizes in Hydrotrend files do not match (%d!=%d)" , hdr->n_grains , h->n_grains );
00106             if ( h->n_seasons != hdr->n_seasons && !tmp_err )
00107                g_set_error( &tmp_err , SED_HYDROTREND_ERROR , SED_HYDROTREND_ERROR_BAD_HEADER ,
00108                             "Number of seasons in Hydrotrend files do not match (%d!=%d)" , hdr->n_seasons , h->n_seasons );
00109 
00110             if ( !tmp_err )
00111             {
00112 //               gchar* tmp_str  = g_strdup( hdr->comment );
00113                gchar* tmp_str  = hdr->comment;
00114 
00115                hdr->comment    = g_strjoin( ";" , tmp_str , h->comment , NULL );
00116                hdr->n_samples += h->n_samples;
00117 
00118                eh_free( tmp_str );
00119             }
00120 
00121             eh_free( h->comment );
00122             eh_free( h          );
00123          }
00124       }
00125 
00126       if ( tmp_err )
00127       {
00128          g_propagate_error( err , tmp_err );
00129          eh_free( hdr->comment );
00130          eh_free( hdr          );
00131          hdr = NULL;
00132       }
00133    }
00134 
00135    return hdr;
00136 }
00137 
00138 Sed_hydrotrend_header*
00139 sed_hydrotrend_header_destroy( Sed_hydrotrend_header* h )
00140 {
00141    if ( h )
00142    {
00143       if ( h->comment ) eh_free( h->comment );
00144       eh_free( h );
00145    }
00146    return NULL;
00147 }
00148 
00149 gssize
00150 sed_hydrotrend_write_header_to_byte_order( FILE*  fp        ,
00151                                            gint   n_grains  ,
00152                                            gint   n_seasons ,
00153                                            gint   n_samples ,
00154                                            gchar* comment_s ,
00155                                            gint   order )
00156 {
00157    gssize n = 0;
00158 
00159    if ( fp )
00160    {
00161       gint len;
00162       gssize (*fwrite_int)(void*,size_t,size_t,FILE*);
00163 
00164       if ( !comment_s )
00165          comment_s = g_strdup( "No comment" );
00166 
00167       len = strlen( comment_s );
00168 
00169       if ( order==G_BYTE_ORDER ) fwrite_int = fwrite;
00170       else                       fwrite_int = eh_fwrite_int32_swap;
00171 
00172       n += fwrite_int( &len      , sizeof(int)  , 1   , fp );
00173       n += fwrite    ( comment_s , sizeof(char) , len , fp );
00174 
00175       n += fwrite_int( &n_grains  , sizeof(int)  , 1  , fp );
00176       n += fwrite_int( &n_seasons , sizeof(int)  , 1  , fp );
00177       n += fwrite_int( &n_samples , sizeof(int)  , 1  , fp );
00178    }
00179 
00180    return n;
00181 }
00182 
00193 gssize
00194 sed_hydrotrend_write_header( FILE* fp       ,
00195                              gint n_grains  ,
00196                              gint n_seasons ,
00197                              gint n_samples ,
00198                              gchar* comment_s )
00199 {
00200    gssize n = 0;
00201 
00202    if ( fp )
00203    {
00204       gint len;
00205 
00206       if ( !comment_s )
00207          comment_s = g_strdup( "No comment" );
00208 
00209       len = strlen( comment_s );
00210 
00211       n += fwrite( &len      , sizeof(int)  , 1   , fp );
00212       n += fwrite( comment_s , sizeof(char) , len , fp );
00213 
00214       n += fwrite( &n_grains  , sizeof(int)  , 1  , fp );
00215       n += fwrite( &n_seasons , sizeof(int)  , 1  , fp );
00216       n += fwrite( &n_samples , sizeof(int)  , 1  , fp );
00217    }
00218 
00219    return n;
00220 }
00221 
00222 gint
00223 sed_hydrotrend_byte_order( const gchar* file , GError** error )
00224 {
00225    gint order = 0;
00226 
00227    eh_require( error==NULL || *error==NULL );
00228 
00229    if ( file )
00230    {
00231       GError* tmp_err = NULL;
00232       FILE*   fp      = eh_fopen_error( file , "r" , &tmp_err );
00233 
00234       if ( !tmp_err )
00235       {
00236          Sed_hydrotrend_header* h = NULL;
00237 
00238          h = sed_hydrotrend_read_header_from_byte_order( fp , G_BIG_ENDIAN );
00239          if ( h )
00240             order = G_BIG_ENDIAN;
00241          else
00242          {
00243             rewind( fp );
00244             h = sed_hydrotrend_read_header_from_byte_order( fp , G_LITTLE_ENDIAN );
00245             order = G_LITTLE_ENDIAN;
00246          }
00247 
00248          if ( h )
00249          {
00250             eh_free( h->comment );
00251             eh_free( h          );
00252          }
00253 
00254          fclose( fp );
00255       }
00256    }
00257 
00258    return order;
00259 }
00260 
00261 gint
00262 sed_hydrotrend_guess_byte_order( FILE* fp )
00263 {
00264    gint byte_order = -1;
00265 
00266    if ( fp )
00267    {
00268       gint n;
00269       fread( &n , sizeof(gint)  , 1 , fp );
00270 
00271       if ( n>=0 || n<2048 )
00272          byte_order = G_BYTE_ORDER;
00273       else
00274       {
00275          rewind( fp );
00276          eh_fread_int32_swap( &n , sizeof(gint)  , 1 , fp );
00277 
00278          if ( n>=0 || n<2048 )
00279          {
00280             if ( G_BYTE_ORDER==G_BIG_ENDIAN ) byte_order = G_LITTLE_ENDIAN;
00281             else                              byte_order = G_BIG_ENDIAN;
00282          }
00283       }
00284 
00285       rewind( fp );
00286    }
00287 
00288    return byte_order;
00289 }
00290 
00298 Sed_hydro
00299 sed_hydrotrend_read_next_rec( FILE* fp , int n_grains )
00300 {
00301    return sed_hydrotrend_read_next_rec_from_byte_order( fp , n_grains , G_BYTE_ORDER );
00302 }
00303 
00304 
00313 Sed_hydro
00314 sed_hydrotrend_read_next_rec_from_byte_order( FILE *fp , int n_grains , gint order )
00315 {
00316    int n;
00317    float* fval = eh_new( float , 4+n_grains );
00318    Sed_hydro rec = NULL;
00319 
00320    if ( order==G_BYTE_ORDER ) n = fread            ( fval , sizeof(float) , 4+n_grains , fp );
00321    else                       n = eh_fread_flt_swap( fval , sizeof(float) , 4+n_grains , fp );
00322 
00323    if ( n==4+n_grains )
00324    {
00325       gint i;
00326 
00327       rec = sed_hydro_new( n_grains );
00328 
00329       sed_hydro_set_velocity( rec , fval[0] );
00330       sed_hydro_set_width   ( rec , fval[1] );
00331       sed_hydro_set_depth   ( rec , fval[2] );
00332       sed_hydro_set_bedload ( rec , fval[3] );
00333 
00334       for (i=0 ; i<n_grains ; i++)
00335          sed_hydro_set_nth_concentration( rec , i , fval[i+4] );
00336    }
00337    eh_free( fval );
00338 
00339    return rec;
00340 }
00341 
00352 Sed_hydro*
00353 sed_hydrotrend_read_recs( FILE* fp , gint rec_0 , gint n_recs , gint byte_order , GError** error )
00354 {
00355    Sed_hydro* rec_a = NULL;
00356 
00357    eh_require( rec_0  >= 0 );
00358 
00359    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00360 
00361    if ( fp || n_recs!=0 )
00362    {
00363       gint n;
00364       gint last     = sed_hydrotrend_fseek( fp , 0     , SEEK_END , byte_order );
00365       gint cur      = sed_hydrotrend_fseek( fp , rec_0 , SEEK_SET , byte_order );
00366       gint n_grains = sed_hydrotrend_n_grains( fp , byte_order , NULL );
00367 
00368       if ( last-cur < n_recs || n_recs<0 )
00369          n_recs = last - cur;
00370 
00371       rec_a = eh_new( Sed_hydro , n_recs+1 );
00372 
00373       for ( n=0 ; n<n_recs ; n++ )
00374          rec_a[n] = sed_hydrotrend_read_next_rec_from_byte_order( fp , n_grains , byte_order );
00375       rec_a[n] = NULL;
00376    }
00377 
00378    return rec_a;
00379 }
00380 
00388 gssize
00389 sed_hydrotrend_write_record( FILE *fp , Sed_hydro rec )
00390 {
00391    return sed_hydrotrend_write_record_to_byte_order( fp , rec , G_BYTE_ORDER );
00392 }
00393 
00402 gssize
00403 sed_hydrotrend_write_record_to_byte_order( FILE *fp , Sed_hydro rec , gint order )
00404 {
00405    gssize n;
00406 
00407    if ( rec )
00408    {
00409       gint   i;
00410       gint   n_grains = sed_hydro_size( rec );
00411       float* fval     = eh_new( float , 4+n_grains );
00412 
00413       fval[0] = sed_hydro_velocity( rec );
00414       fval[1] = sed_hydro_width   ( rec );
00415       fval[2] = sed_hydro_depth   ( rec );
00416       fval[3] = sed_hydro_bedload ( rec );
00417 
00418       for (i=0 ; i<n_grains ; i++)
00419          fval[4+i] = sed_hydro_nth_concentration( rec , i );
00420 
00421       if ( order==G_BYTE_ORDER )
00422          n = fwrite            ( fval , sizeof(float) , 4+n_grains , fp );
00423       else
00424          n = eh_fwrite_flt_swap( fval , sizeof(float) , 4+n_grains , fp );
00425 
00426       eh_free( fval );
00427    }
00428 
00429    return n;
00430 }
00431 
00441 gssize
00442 sed_hydrotrend_read_next_n_recs( FILE* fp , Sed_hydro* rec , int n_grains , int n_recs )
00443 {
00444    gssize n = 0;
00445    
00446    do
00447    {
00448       rec[n] = sed_hydrotrend_read_next_rec( fp , n_grains );
00449    }
00450    while ( rec[n] && (++n)<n_recs );
00451 
00452    return n;
00453 }
00454 
00455 Sed_hydro*
00456 sed_hydrotrend_read( const gchar* file , gint byte_order , int* n_seasons , GError** error )
00457 {
00458    return sed_hydrotrend_read_n_recs( file , -1 , byte_order , n_seasons , error );
00459 }
00460 
00461 Sed_hydro*
00462 sed_hydrotrend_read_n_recs( const gchar* file , gint n_recs , gint byte_order , int* n_seasons , GError** error )
00463 {
00464    Sed_hydro* arr = NULL;
00465 
00466    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00467 
00468    if ( file && n_recs!=0 )
00469    {
00470       GError* err    = NULL;
00471       FILE*   fp     = eh_fopen_error( file , "r" , &err );
00472 
00473       if ( !err )
00474       {
00475          Sed_hydrotrend_header* h = NULL;
00476 
00477          h = sed_hydrotrend_read_header_from_byte_order( fp , byte_order );
00478 
00479          if ( h )
00480          {
00481             if      ( n_recs<0            ) n_recs = h->n_samples;
00482             else if ( n_recs>h->n_samples ) n_recs = h->n_samples;
00483 
00484             arr = sed_hydrotrend_read_recs( fp , 0 , n_recs , byte_order , &err );
00485 
00486             if ( n_seasons ) *n_seasons = h->n_seasons;
00487 
00488             if ( !err )
00489             {
00490                gint n_read = g_strv_length( (gchar**)arr );
00491 
00492                if ( n_read != n_recs )
00493                {
00494                   eh_warning( "Number of items read does not match number of items in header" );
00495                   eh_debug( "Number of items in header : %d" , h->n_samples );
00496                   eh_debug( "Number of items read      : %d" , n_read       );
00497                }
00498             }
00499             else
00500                g_propagate_error( error , err );
00501 
00502             eh_free( h->comment );
00503             eh_free( h          );
00504          }
00505       }
00506       else
00507          g_propagate_error( error , err );
00508    }
00509 
00510    return arr;
00511 }
00512 
00523 gssize
00524 sed_hydrotrend_write( gchar* file , Sed_hydro* rec_a , gint n_seasons , gchar* comment_s , GError** error )
00525 {
00526    gssize n = 0;
00527 
00528    eh_return_val_if_fail( error==NULL || *error==NULL , 0 );
00529    eh_require( n_seasons>0 );
00530 
00531    if ( file && rec_a && *rec_a )
00532    {
00533       GError* err    = NULL;
00534       FILE* fp       = eh_fopen_error( file , "w" , &err );
00535       gint n_samples = g_strv_length( (gchar**)rec_a );
00536       gint n_grains  = sed_hydro_size(rec_a[0]);
00537 
00538       if ( !err )
00539       {
00540          sed_hydrotrend_write_header( fp , n_grains , n_seasons , n_samples , comment_s );
00541          sed_hydro_array_write_hydrotrend_records( fp , rec_a );
00542       }
00543       else
00544       {
00545          g_propagate_error( error , err );
00546          n = 0;
00547       }
00548    }
00549 
00550    return n;
00551 }
00552 
00553 gssize
00554 sed_hydro_array_write_hydrotrend_records_to_byte_order( FILE* fp , Sed_hydro* rec_a , gint order )
00555 {
00556    gssize n = 0;
00557 
00558    if ( fp && rec_a )
00559    {
00560       Sed_hydro* rec;
00561 
00562       for ( rec=rec_a ; *rec ; rec++ )
00563          sed_hydrotrend_write_record_to_byte_order( fp , *rec , order );
00564    }
00565 
00566    return n;
00567 }
00568 
00576 gssize
00577 sed_hydro_array_write_hydrotrend_records( FILE* fp , Sed_hydro* rec_a )
00578 {
00579    return sed_hydro_array_write_hydrotrend_records_to_byte_order( fp , rec_a , G_BYTE_ORDER );
00580 }
00581 
00608 gint
00609 sed_hydrotrend_fseek( FILE* fp , gint offset , gint whence , gint byte_order )
00610 {
00611    gint pos = -1;
00612 
00613    if ( fp )
00614    {
00615       gint rec_size   = sed_hydrotrend_record_size( fp , byte_order , NULL );
00616       gint data_start = sed_hydrotrend_data_start ( fp , byte_order , NULL );
00617 
00618       if ( whence == SEEK_SET )
00619          fseek( fp , rec_size*offset + data_start , SEEK_SET );
00620       else
00621          fseek( fp , rec_size*offset , whence );
00622 
00623       pos = ( ftell( fp ) - data_start ) / rec_size ;
00624    }
00625 
00626    return pos;
00627 }
00628 
00637 gint
00638 sed_hydrotrend_record_size( FILE* fp , gint byte_order , Sed_hydrotrend_header* h )
00639 {
00640    gint n = 0;
00641 
00642    if ( fp )
00643    {
00644       if ( h )
00645          n = ( h->n_grains + 4 )*sizeof(float);
00646       else
00647       {
00648          gint where = ftell( fp );
00649 
00650          rewind( fp );
00651 
00652          h = sed_hydrotrend_read_header_from_byte_order( fp , byte_order );
00653 
00654          eh_require( h );
00655 
00656          n = ( h->n_grains + 4 )*sizeof(float);
00657 
00658          fseek( fp , where , SEEK_SET );
00659 
00660          eh_free( h->comment );
00661          eh_free( h );
00662       }
00663    }
00664 
00665    return n;
00666 }
00667 
00676 gint
00677 sed_hydrotrend_n_grains( FILE* fp , gint byte_order , Sed_hydrotrend_header* h )
00678 {
00679    gint n = 0;
00680 
00681    if ( fp )
00682    {
00683       if ( h )
00684          n = h->n_grains;
00685       else
00686       {
00687          gint where = ftell( fp );
00688 
00689          rewind( fp );
00690 
00691          h = sed_hydrotrend_read_header_from_byte_order( fp , byte_order );
00692 
00693          eh_require( h );
00694 
00695          n = h->n_grains;
00696 
00697          fseek( fp , where , SEEK_SET );
00698 
00699          eh_free( h->comment );
00700          eh_free( h );
00701       }
00702    }
00703 
00704    return n;
00705 }
00706 
00716 gint
00717 sed_hydrotrend_data_start( FILE* fp , gint byte_order , Sed_hydrotrend_header* h )
00718 {
00719    gint n = 0;
00720 
00721    if ( fp )
00722    {
00723       if ( h )
00724          n = sizeof(gint) + strlen(h->comment) + 3*sizeof(gint);
00725       else
00726       {
00727          gint where = ftell( fp );
00728 
00729          rewind( fp );
00730 
00731          h = sed_hydrotrend_read_header_from_byte_order( fp , byte_order );
00732 
00733          eh_require( h );
00734 
00735          n = ftell( fp );
00736 
00737          fseek( fp , where , SEEK_SET );
00738 
00739          eh_free( h->comment );
00740          eh_free( h );
00741       }
00742    }
00743 
00744    return n;
00745 }
00746 

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