/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/sed/sed_property_file.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_property_file.h"
00006 
00007 CLASS ( Sed_property_file_attr )
00008 {
00009    Sed_get_val_func get_val;
00010    double lower_clip;
00011    double upper_clip;
00012    double water_val;
00013    double rock_val;
00014    double x_res;
00015    double y_res;
00016    double z_res;
00017    double x_lim[2];
00018    double y_lim[2];
00019    double z_lim[2];
00020    Sed_data_type type;
00021    gpointer user_data;
00022 };
00023 
00024 CLASS ( Sed_property_file_header )
00025 {
00026    gssize n_rows;
00027    gssize n_x_cols;
00028    gssize n_y_cols;
00029    double cell_dx;
00030    double cell_dy;
00031    double cell_dz;
00032    double min_value, max_value;
00033    double water_value, rock_value;
00034    Sed_property property;
00035    double sea_level;
00036    double ref_x, ref_y, ref_z;
00037    int byte_order;
00038    int element_size;
00039 };
00040 
00041 CLASS ( Sed_property_file )
00042 {
00043    FILE*                    fp;
00044    Sed_property             p;
00045    Sed_property_file_header h;
00046    Sed_property_file_attr   attr;
00047    double**                 data;
00048 };
00049 
00050 Sed_property_file sed_property_file_new( const char* file , Sed_property p , Sed_property_file_attr a )
00051 {
00052    Sed_property_file f = NULL;
00053 
00054    eh_require( file );
00055    eh_require( p    );
00056 
00057    if ( file && p )
00058    {
00059       NEW_OBJECT( Sed_property_file , f );
00060       
00061       f->fp = fopen( file , "wb" );
00062       if ( !f->fp )
00063          eh_error( "Cound not open sedflux property file." );
00064 
00065       f->h = NULL;
00066       f->p = p;
00067 
00068       if ( a )
00069          f->attr = sed_property_file_attr_dup( a );
00070       else
00071          f->attr = sed_property_file_attr_new( );
00072 
00073       f->attr->get_val = NULL;
00074 
00075       f->data = NULL;
00076    }
00077 
00078    return f;
00079 }
00080 
00081 Sed_property_file sed_property_file_destroy( Sed_property_file f )
00082 {
00083    if ( f )
00084    {
00085       if ( f->data )
00086       {
00087          eh_free( f->data[0] );
00088          eh_free( f->data );
00089       }
00090 
00091       sed_property_file_attr_destroy( f->attr );
00092       sed_property_file_header_destroy( f->h );
00093 
00094       fclose( f->fp );
00095       eh_free( f );
00096    }
00097    return NULL;
00098 }
00099 
00100 Sed_property_file_attr sed_property_file_attr_new( )
00101 {
00102    Sed_property_file_attr a;
00103 
00104    NEW_OBJECT( Sed_property_file_attr , a );
00105 
00106    a->get_val = NULL;
00107    a->lower_clip = -G_MAXDOUBLE;
00108    a->upper_clip =  G_MAXDOUBLE;
00109    a->water_val  = -G_MAXDOUBLE;
00110    a->rock_val   =  G_MAXDOUBLE;
00111    a->x_res      =  0;
00112    a->y_res      =  0;
00113    a->z_res      =  0;
00114    a->x_lim[0]   = -G_MAXDOUBLE;
00115    a->x_lim[1]   =  G_MAXDOUBLE;
00116    a->y_lim[0]   = -G_MAXDOUBLE;
00117    a->y_lim[1]   =  G_MAXDOUBLE;
00118    a->z_lim[0]   = -G_MAXDOUBLE;
00119    a->z_lim[1]   =  G_MAXDOUBLE;
00120    a->type       = SED_TYPE_UINT8;
00121    a->user_data  = NULL;
00122 
00123    return a;
00124 }
00125 
00126 Sed_property_file_attr sed_property_file_attr_copy( Sed_property_file_attr dest , Sed_property_file_attr src )
00127 {
00128    if ( !dest )
00129       dest = sed_property_file_attr_new();
00130 
00131    g_memmove( dest , src , sizeof( Sed_property_file_attr ) );
00132 
00133    return dest;
00134 }
00135 
00136 Sed_property_file_attr sed_property_file_attr_dup( Sed_property_file_attr src )
00137 {
00138    return sed_property_file_attr_copy( NULL , src );
00139 }
00140 
00141 Sed_property_file_attr sed_property_file_attr_destroy( Sed_property_file_attr a )
00142 {
00143    if ( a )
00144    {
00145       eh_free( a );
00146    }
00147    return NULL;
00148 }
00149 
00150 Sed_property_file_header sed_property_file_header_destroy( Sed_property_file_header h )
00151 {
00152    if ( h )
00153    {
00154       sed_property_destroy( h->property );
00155       eh_free( h );
00156    }
00157    return NULL;
00158 }
00159 
00160 gssize sed_property_file_header_fprint( FILE *fp , Sed_property_file_header hdr );
00161 Sed_property_file_header sed_property_file_header_new( const Sed_cube p ,
00162                                                        Eh_ndgrid g      ,
00163                                                        Sed_property property );
00164 double sed_cube_min_height( Sed_cube p , gssize **col_id );
00165 double sed_cube_max_height( Sed_cube p , gssize **col_id );
00166 gssize *sed_cube_x_cols_between( Sed_cube p , double dx , double left , double right );
00167 gssize *sed_cube_y_cols_between( Sed_cube p , double dy , double bottom , double top );
00168 gssize sed_cube_n_rows_between( Sed_cube p , double dz , double lower , double upper , gssize *col_id );
00169 Eh_ndgrid sed_cube_property_subgrid( Sed_cube p            ,
00170                                      Sed_property property ,
00171                                      double lower_left[3]  ,
00172                                      double upper_right[3] ,
00173                                      double resolution[3] );
00174 
00175 gssize sed_property_file_write( Sed_property_file sed_fp , Sed_cube p )
00176 {
00177    gssize n = 0;
00178 
00179    eh_require( sed_fp );
00180    eh_require( p      );
00181 
00182    if ( sed_fp && p )
00183    {
00184       Eh_ndgrid g;
00185       double    lower_left[3];
00186       double    upper_right[3];
00187       double    resolution[3];
00188 
00189       lower_left[0]  = sed_fp->attr->x_lim[0];
00190       lower_left[1]  = sed_fp->attr->y_lim[0];
00191       lower_left[2]  = sed_fp->attr->z_lim[0];
00192       upper_right[0] = sed_fp->attr->x_lim[1];
00193       upper_right[1] = sed_fp->attr->y_lim[1];
00194       upper_right[2] = sed_fp->attr->z_lim[1];
00195       resolution[0]  = sed_fp->attr->x_res;
00196       resolution[1]  = sed_fp->attr->y_res;
00197       resolution[2]  = sed_fp->attr->z_res;
00198 
00199       g = sed_cube_property_subgrid( p           ,
00200                                      sed_fp->p   ,
00201                                      lower_left  ,
00202                                      upper_right ,
00203                                      resolution );
00204 
00205       sed_fp->h = sed_property_file_header_new( p , g , sed_fp->p );
00206 
00207       n += sed_property_file_header_fprint( sed_fp->fp , sed_fp->h );
00208       n += eh_ndgrid_write( sed_fp->fp , g );
00209 
00210       eh_ndgrid_destroy( g );
00211    }
00212 
00213    return n;
00214 }
00215 
00216 gssize sed_property_file_header_fprint( FILE *fp , Sed_property_file_header hdr )
00217 {
00218    gssize n = 0;
00219 
00220    eh_require( fp  );
00221    eh_require( hdr );
00222 
00223    if ( fp && hdr )
00224    {
00225       char* date_str    = eh_new( char , 2048 );
00226       char* program_str = eh_new( char , 2048 );
00227       char* property_name = sed_property_name( hdr->property );
00228       GDate *today = g_date_new( );
00229 
00230       g_date_set_time( today , time(NULL) );
00231       g_date_strftime( date_str , 2048 , "%A %e %B %Y %T %Z" , today );
00232 
00233       fflush( fp );
00234 
00235       n += fprintf( fp , "--- header ---\n" );
00236 
00237       g_snprintf( program_str , 2048 , "%s %s" ,
00238                   PROGRAM_NAME          ,
00239                   SED_VERSION_S );
00240 
00241       n += fprintf( fp , "SEDFLUX property file version: %s\n" , program_str );
00242       n += fprintf( fp , "Creation date: %s\n"                 , date_str );
00243       n += fprintf( fp , "Property: %s\n"                      , property_name );
00244       n += fprintf( fp , "Number of rows: %d\n"                , (gint)hdr->n_rows );
00245       n += fprintf( fp , "Number of x-columns: %d\n"           , (gint)hdr->n_x_cols );
00246       n += fprintf( fp , "Number of y-columns: %d\n"           , (gint)hdr->n_y_cols );
00247       n += fprintf( fp , "dx: %f\n"                            , hdr->cell_dx );
00248       n += fprintf( fp , "dy: %f\n"                            , hdr->cell_dy );
00249       n += fprintf( fp , "dz: %f\n"                            , hdr->cell_dz );
00250       n += fprintf( fp , "Sea level: %f\n"                     , hdr->sea_level );
00251       n += fprintf( fp , "Bottom-side coordinate: %f\n"        , hdr->ref_z );
00252       n += fprintf( fp , "North-side coordinate: %f\n"         , hdr->ref_x );
00253       n += fprintf( fp , "West-side coordinate: %f\n"          , hdr->ref_y );
00254       n += fprintf( fp , "Data type: %s\n"                     , "DOUBLE" );
00255       n += fprintf( fp , "Rock value: %g\n"                    , hdr->rock_value );
00256       n += fprintf( fp , "Water value: %g\n"                   , hdr->water_value );
00257       n += fprintf( fp , "Byte order: %d\n"                    , hdr->byte_order );
00258 
00259       n += fprintf( fp , "--- data ---\n" );
00260 
00261       fflush( fp );
00262 
00263       g_date_free( today );
00264       eh_free( property_name );
00265       eh_free( program_str );
00266       eh_free( date_str    );
00267    }
00268 
00269    return n;
00270 }
00271 
00272 Sed_property_file_header sed_property_file_header_new( const Sed_cube p ,
00273                                                        Eh_ndgrid g      ,
00274                                                        Sed_property property )
00275 {
00276    Sed_property_file_header hdr = NULL;
00277 
00278    eh_require( p );
00279    eh_require( g );
00280    eh_require( property );
00281 
00282    if ( p && g && property )
00283    {
00284       NEW_OBJECT( Sed_property_file_header , hdr );
00285 
00286       hdr->n_rows       = eh_ndgrid_n( g , 2 );
00287       hdr->n_y_cols     = eh_ndgrid_n( g , 1 );
00288       hdr->n_x_cols     = eh_ndgrid_n( g , 0 );
00289       hdr->cell_dx      = sed_cube_x_res( p );
00290       hdr->cell_dy      = sed_cube_y_res( p );
00291       hdr->cell_dz      = sed_cube_z_res( p );
00292       hdr->property     = property;
00293       hdr->sea_level    = sed_cube_sea_level( p );
00294       hdr->ref_z        = eh_ndgrid_x( g , 2 )[0];
00295       hdr->ref_y        = eh_ndgrid_x( g , 1 )[0];
00296       hdr->ref_x        = eh_ndgrid_x( g , 0 )[0];
00297       hdr->byte_order   = G_BYTE_ORDER;
00298       hdr->element_size = sizeof(double);
00299       hdr->rock_value   =  G_MAXDOUBLE;
00300       hdr->water_value  = -G_MAXDOUBLE;
00301    }
00302 
00303    return hdr;
00304 }
00305 
00306 Eh_ndgrid sed_cube_property_subgrid( Sed_cube p            ,
00307                                      Sed_property property ,
00308                                      double lower_left[3]  ,
00309                                      double upper_right[3] ,
00310                                      double resolution[3] )
00311 {
00312    gssize i, j, k, n, id;
00313    double bottom, top;
00314    double dx, dy, dz;
00315    double hydro_static;
00316    double *load;
00317    gssize sediment_rows, rock_rows, water_rows;
00318    gssize top_sed, bot_sed;
00319    Sed_column col_temp;
00320    Eh_dbl_grid g;
00321    Eh_ndgrid g_3;
00322    double lower_left_x, lower_left_y, lower_left_z;
00323    double upper_right_x, upper_right_y, upper_right_z;
00324    gssize *cols, *x_cols, *y_cols;
00325    gssize n_rows, n_x_cols, n_y_cols;
00326    gboolean with_load, excess_pressure;
00327 
00328    excess_pressure = sed_property_is_named( property , "EXCESS PRESSURE" );
00329    with_load = sed_property_is_named( property , "EXCESS PRESSURE" )
00330              | sed_property_is_named( property , "COHESION"        )
00331              | sed_property_is_named( property , "SHEAR STRENGTH"  );
00332 
00333    lower_left_x = sed_cube_col_x( p,0 );
00334    lower_left_y = sed_cube_col_y( p,0 );
00335    lower_left_z = sed_cube_min_height( p , NULL );
00336 
00337    if ( lower_left )
00338    {
00339       lower_left_x = eh_max( lower_left[0] , lower_left_x );
00340       lower_left_y = eh_max( lower_left[1] , lower_left_y );
00341       lower_left_z = eh_max( lower_left[2] , lower_left_z );
00342    }
00343 
00344    upper_right_x = sed_cube_col_x( p , sed_cube_size(p)-1 );
00345    upper_right_y = sed_cube_col_y( p , sed_cube_size(p)-1 );
00346    upper_right_z = sed_cube_max_height( p , NULL );
00347 
00348    if ( upper_right )
00349    {
00350       upper_right_x = eh_min( upper_right[0] , upper_right_x );
00351       upper_right_y = eh_min( upper_right[1] , upper_right_y );
00352       upper_right_z = eh_min( upper_right[2] , upper_right_z );
00353    }
00354 
00355    dx = sed_cube_x_res( p );
00356    dy = sed_cube_y_res( p );
00357    dz = sed_cube_z_res( p );
00358 
00359    if ( resolution )
00360    {
00361       dx = (resolution[0]>0)?resolution[0]:sed_cube_x_res( p );
00362       dy = (resolution[1]>0)?resolution[1]:sed_cube_y_res( p );
00363       dz = (resolution[2]>0)?resolution[2]:sed_cube_z_res( p );
00364    }
00365 
00366    x_cols = sed_cube_x_cols_between( p , dx , lower_left_x , upper_right_x );
00367    y_cols = sed_cube_y_cols_between( p , dy , lower_left_y , upper_right_y );
00368 
00369    for ( n_x_cols=0 ; x_cols[n_x_cols]>=0 ; n_x_cols++ );
00370    for ( n_y_cols=0 ; y_cols[n_y_cols]>=0 ; n_y_cols++ );
00371 
00372    cols = eh_new( gssize , n_x_cols*n_y_cols+1 );
00373    for ( i=0,n=0 ; i<n_x_cols ; i++ )
00374       for ( j=0 ; j<n_y_cols ; j++,n++ )
00375          cols[n] = sed_cube_id( p , x_cols[i] , y_cols[j] );
00376    cols[n] = -1;
00377 
00378    eh_free( x_cols );
00379    eh_free( y_cols );
00380 
00381    n_rows = sed_cube_n_rows_between( p , dz , lower_left_z , upper_right_z , cols );
00382    g_3    = eh_ndgrid_malloc( 3 , sizeof(double) , n_x_cols , n_y_cols , n_rows );
00383    g      = eh_ndgrid_to_grid( g_3 );
00384 
00385    eh_dbl_array_grid( eh_ndgrid_x(g_3,0) , eh_ndgrid_n(g_3,0) , lower_left_x , dx );
00386    eh_dbl_array_grid( eh_ndgrid_x(g_3,1) , eh_ndgrid_n(g_3,1) , lower_left_y , dy );
00387    eh_dbl_array_grid( eh_ndgrid_x(g_3,2) , eh_ndgrid_n(g_3,2) , lower_left_z , dz );
00388 
00389    col_temp = sed_column_dup( sed_cube_col(p,cols[0]) );
00390 
00391    top    = lower_left_z + n_rows*dz;
00392    bottom = lower_left_z;
00393    for ( i=0,id=cols[0],n=0 ; cols[n]>=0 ; i++,id=cols[++n] )
00394    {
00395       sed_column_copy( col_temp , sed_cube_col(p,id) );
00396 
00397       sed_column_set_z_res( col_temp , dz );
00398       sed_column_rebin( col_temp );
00399       sed_column_strip( col_temp , bottom , top );
00400 
00401       water_rows = eh_round( (   lower_left_z
00402                                + n_rows*dz
00403                                - sed_column_top_height( col_temp ) )
00404                              / dz ,
00405                              1. );
00406 
00407       if ( water_rows<0 )
00408          water_rows = 0;
00409       sediment_rows = sed_column_len( col_temp );
00410       rock_rows     = n_rows - sediment_rows - water_rows;
00411       top_sed       = sediment_rows-1;
00412       bot_sed       = 0;
00413 
00414       if ( rock_rows<0 )
00415       {
00416          rock_rows = 0;
00417          sediment_rows = n_rows - water_rows;
00418          bot_sed = top_sed - sediment_rows+1;
00419          if ( sediment_rows<=0 )
00420          {
00421             sediment_rows = 0;
00422             water_rows = n_rows;
00423             top_sed = -1; bot_sed = 0;
00424          }
00425       }
00426 
00427       if ( with_load )
00428          load = sed_column_load( col_temp , bot_sed , sediment_rows , NULL );
00429 
00430       if ( excess_pressure )
00431       {
00432          hydro_static = sed_column_water_pressure( col_temp );
00433          for ( j=top_sed ; j>=bot_sed ; j-- )
00434             load[j-bot_sed] = hydro_static;
00435       }
00436 
00437       for (j=0,k=0 ;j<water_rows;j++,k++)
00438          eh_dbl_grid_set_val( g , i , k , -G_MAXDOUBLE );
00439 
00440       for ( j=top_sed ; j>=bot_sed ; j--,k++)
00441          eh_dbl_grid_set_val( g , i , k , sed_property_measure( property ,
00442                                                                 sed_column_nth_cell( col_temp , j ) ,
00443                                                                 (with_load)?(load[j-bot_sed]):(-1) ) );
00444 
00445       for (j=0;j<rock_rows;j++,k++)
00446          eh_dbl_grid_set_val( g , i , k , G_MAXDOUBLE );
00447 
00448       if ( with_load )
00449          eh_free( load );
00450    }
00451 
00452    eh_free( cols );
00453    sed_column_destroy( col_temp );
00454    eh_grid_destroy( g , FALSE );
00455 
00456    return g_3;
00457 }
00458 
00459 double sed_cube_min_height( Sed_cube p , gssize **col_id )
00460 {
00461    double z = G_MAXDOUBLE;
00462 
00463    eh_require( p )
00464    {
00465       gssize id, len = sed_cube_size(p);
00466 
00467       for ( id=0 ; id<len ; id++ )
00468          z = eh_min( z , sed_cube_base_height(p,0,id) );
00469 
00470       if ( col_id )
00471       {
00472          gssize n;
00473 
00474          *col_id = NULL;
00475          for ( id=0,n=0 ; id<len ; id++ )
00476             if ( eh_compare_dbl( sed_cube_base_height(p,0,id) , z , 1e-12 ) )
00477             {
00478                *col_id        = g_renew( gssize , *col_id , ++n );
00479                (*col_id)[n-1] = id;
00480             }
00481          *col_id        = g_renew( gssize , *col_id , ++n );
00482          (*col_id)[n-1] = -1;
00483       }
00484    }
00485 
00486    return z;
00487 }
00488 
00489 double sed_cube_max_height( Sed_cube p , gssize **col_id )
00490 {
00491    double z = -G_MAXDOUBLE;
00492 
00493    if ( p )
00494    {
00495       gssize id, len = sed_cube_size(p);
00496 
00497       for ( id=0 ; id<len ; id++ )
00498          z = eh_max( z , sed_cube_top_height(p,0,id) );
00499 
00500       if ( col_id )
00501       {
00502          gssize n;
00503 
00504          *col_id = NULL;
00505          for ( id=0,n=0 ; id<len ; id++ )
00506             if ( eh_compare_dbl( sed_cube_top_height(p,0,id) , z , 1e-12 ) )
00507             {
00508                *col_id        = g_renew( gssize , *col_id , ++n );
00509                (*col_id)[n-1] = id;
00510             }
00511          *col_id        = g_renew( gssize , *col_id , ++n );
00512          (*col_id)[n-1] = -1;
00513       }
00514    }
00515 
00516    return z;
00517 }
00518 
00528 gssize *sed_cube_x_cols_between( Sed_cube p , double dx , double left , double right )
00529 {
00530    gssize *id=NULL;
00531 
00532    eh_return_val_if_fail( dx>=0 , NULL );
00533 
00534    eh_require( p )
00535    {
00536       gssize n=0;
00537       double x, y_0=sed_cube_col_y(p,0);
00538       Eh_ind_2 sub;
00539 
00540       eh_lower_bound( left  , sed_cube_col_x(p,0                 ) );
00541       eh_upper_bound( right , sed_cube_col_x(p,sed_cube_size(p)-1) );
00542 
00543       for ( x=left ; x<=right ; x+=dx )
00544       {
00545          id      = g_renew( gssize , id , ++n );
00546          id[n-1] = sed_cube_column_id( p , x , y_0 );
00547          sub     = sed_cube_sub( p , id[n-1] );
00548          id[n-1] = sub.i;
00549       }
00550       id      = g_renew( gssize , id , ++n );
00551       id[n-1] = -1;
00552    }
00553 
00554    return id;
00555 }
00556 
00566 gssize *sed_cube_y_cols_between( Sed_cube p , double dy , double bottom , double top )
00567 {
00568    gssize *id=NULL;
00569 
00570    eh_return_val_if_fail( dy>=0 , NULL );
00571 
00572    eh_require( p )
00573    {
00574       gssize n=0;
00575       double x_0=sed_cube_col_x(p,0), y;
00576       Eh_ind_2 sub;
00577 
00578       eh_lower_bound( bottom  , sed_cube_col_y( p,0                 ) );
00579       eh_upper_bound( top     , sed_cube_col_y( p,sed_cube_size(p)-1) );
00580 
00581       for ( y=bottom ; y<=top ; y+=dy )
00582       {
00583          id      = g_renew( gssize , id , ++n );
00584          id[n-1] = sed_cube_column_id( p , x_0 , y );
00585          sub     = sed_cube_sub( p , id[n-1] );
00586          id[n-1] = sub.j;
00587       }
00588       id      = g_renew( gssize , id , ++n );
00589       id[n-1] = -1;
00590    }
00591 
00592    return id;
00593 }
00594 
00595 gssize
00596 sed_cube_n_rows_between( Sed_cube p , double dz , double lower , double upper , gssize *col_id )
00597 {
00598    gssize n_rows = 0;
00599 
00600    eh_require( p )
00601    {
00602       gssize id, n;
00603       gssize row_0, row_1;
00604       gssize bottom_row    = G_MAXINT32;
00605       gssize top_row       = G_MININT32;
00606       double rows_per_cell = sed_cube_z_res(p)/dz;
00607 
00608       for ( id=col_id[0],n=0 ; col_id[n]>=0 ; id=col_id[++n] )
00609       {
00610          row_0 = (long)(sed_cube_base_height(p,0,id)/dz);
00611          row_1 = row_0 +    sed_column_len( sed_cube_col(p,id) )
00612                          * ( rows_per_cell ) + 1;
00613          eh_set_min( bottom_row , row_0 );
00614          eh_set_max( top_row    , row_1 );
00615       }
00616 
00617       eh_lower_bound( bottom_row , lower/dz );
00618       eh_upper_bound( top_row    , upper/dz );
00619 
00620       n_rows = top_row-bottom_row;
00621    }
00622 
00623    return n_rows;
00624 }
00625 

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