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

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <glib.h>
00003 
00004 #include "sed_tripod.h"
00005 
00006 CLASS ( Sed_measurement )
00007 {
00008    char* name;
00009    Sed_tripod_func f;
00010 };
00011 
00012 typedef struct
00013 {
00014    char* name;
00015    Sed_tripod_func f;
00016 } Sed_measurement_static;
00017 
00018 
00019 CLASS ( Sed_tripod_header )
00020 {
00021    int byte_order;
00022    char *parameter;
00023    Sed_measurement x;
00024    gboolean from_river_mouth;
00025    gssize n_x_cols;
00026    gssize n_y_cols;
00027    gssize n_tripods;
00028    double bad_val;
00029    GArray *pos;
00030 };
00031 
00032 CLASS ( Sed_tripod_attr )
00033 {
00034    Sed_tripod_func get_val;
00035    double lower_clip;
00036    double upper_clip;
00037    double bad_val;
00038    Sed_data_type type;
00039    gpointer user_data;
00040 };
00041 
00042 CLASS ( Sed_tripod )
00043 {
00044    FILE* fp;
00045    Sed_measurement x;
00046    gboolean header_is_written;
00047    Sed_tripod_header h;
00048    Sed_tripod_attr attr;
00049 };
00050 
00051 static Sed_measurement_static all_measurements[17] = {
00052    { "SLOPE"        , &sed_measure_cube_slope } ,
00053    { "DEPTH"        , &sed_measure_cube_water_depth } ,
00054    { "ELEVATION"    , &sed_measure_cube_elevation } ,
00055    { "THICKNESS"    , &sed_measure_cube_thickness } ,
00056    { "GRAIN"        , &sed_measure_cube_grain_size } ,
00057    { "AGE"          , &sed_measure_cube_age } ,
00058    { "SAND"         , &sed_measure_cube_sand_fraction } ,
00059    { "SILT"         , &sed_measure_cube_silt_fraction } ,
00060    { "CLAY"         , &sed_measure_cube_clay_fraction } ,
00061    { "MUD"          , &sed_measure_cube_mud_fraction } ,
00062    { "FACIES"       , &sed_measure_cube_facies } ,
00063    { "DENSITY"      , &sed_measure_cube_density } ,
00064    { "POROSITY"     , &sed_measure_cube_porosity } ,
00065    { "PERMEABILITY" , &sed_measure_cube_permeability } ,
00066    { "BASEMENT"     , &sed_measure_cube_basement } ,
00067    { "RIVER MOUTH"  , &sed_measure_cube_river_mouth } ,
00068    { NULL , NULL }
00069 };
00070 
00071 Sed_tripod sed_tripod_new( const char* file , Sed_measurement x , Sed_tripod_attr attr )
00072 {
00073    Sed_tripod t;
00074 
00075    NEW_OBJECT( Sed_tripod , t );
00076 
00077    t->fp = fopen( file , "wb" );
00078    if ( !t->fp )
00079       eh_error( "Could not open tripod file" );
00080 
00081    t->h                 = sed_tripod_header_new( x );
00082    t->x                 = sed_measurement_dup( x );
00083    t->header_is_written = FALSE;
00084 
00085    if ( attr )
00086       t->attr = sed_tripod_attr_dup( attr );
00087    else
00088       t->attr = sed_tripod_attr_new( );
00089 
00090    if ( t->attr->get_val == NULL )
00091       t->attr->get_val = x->f;
00092 
00093    return t;
00094 }
00095 
00096 Sed_tripod sed_tripod_destroy( Sed_tripod t )
00097 {
00098    if ( t )
00099    {
00100       sed_tripod_attr_destroy( t->attr );
00101       sed_tripod_header_destroy( t->h );
00102       sed_measurement_destroy( t->x );
00103       fclose( t->fp );
00104       eh_free( t );
00105    }
00106 
00107    return t;
00108 }
00109 
00110 Sed_tripod_attr sed_tripod_attr_new( )
00111 {
00112    Sed_tripod_attr a;
00113 
00114    NEW_OBJECT( Sed_tripod_attr , a );
00115 
00116    a->get_val    = NULL;
00117    a->lower_clip = -G_MAXDOUBLE;
00118    a->upper_clip =  G_MAXDOUBLE;
00119    a->bad_val    = -G_MAXDOUBLE;
00120    a->type       = SED_TYPE_DOUBLE;
00121    a->user_data  = NULL;
00122 
00123    return a;
00124 }
00125 
00126 Sed_tripod_attr sed_tripod_attr_copy( Sed_tripod_attr dest , Sed_tripod_attr src )
00127 {
00128    eh_require( src );
00129 
00130    if ( src )
00131    {
00132       if ( !dest )
00133          dest = sed_tripod_attr_new();
00134 
00135       g_memmove( dest , src , sizeof( Sed_tripod_attr ) );
00136    }
00137    else
00138       dest = NULL;
00139 
00140    return dest;
00141 }
00142 
00143 Sed_tripod_attr sed_tripod_attr_dup( Sed_tripod_attr src )
00144 {
00145    return sed_tripod_attr_copy( NULL , src );
00146 }
00147 
00148 double* sed_tripod_measure( Sed_tripod t , Sed_cube c , Eh_pt_2* pos , double* data , gssize len )
00149 {
00150    eh_require( t );
00151    eh_require( c );
00152 
00153    if ( t && c )
00154    {
00155 
00156       eh_require( t->x    );
00157       eh_require( t->x->f );
00158 
00159       if ( pos )
00160       {
00161          gssize i, i_measure, j_measure;
00162          double x_0 = sed_cube_col_x(c,0);
00163          double y_0 = sed_cube_col_y(c,0);
00164 
00165          for ( i=0 ; i<len ; i++ )
00166          {
00167             i_measure = (gssize)((pos[i].x - x_0)/sed_cube_x_res( c ));
00168             j_measure = (gssize)((pos[i].y - y_0)/sed_cube_y_res( c ));
00169 
00170             if ( !sed_cube_is_in_domain( c , i_measure , j_measure ) )
00171             {
00172                eh_message( "OUT OF DOMAIN" );
00173                data[i] = eh_nan();
00174             }
00175             else
00176                data[i] = (t->x->f)( c , i_measure , j_measure );
00177          }
00178       }
00179       else
00180       {
00181          gssize id;
00182          for ( id=0 ; id<len ; id++ )
00183             data[id] = (t->x->f)( c , 0 , id );
00184       }
00185    }
00186    else
00187       data = NULL;
00188 
00189    return data;
00190 
00191 }
00192 
00193 Sed_tripod_attr sed_tripod_attr_destroy( Sed_tripod_attr a )
00194 {
00195    if ( a )
00196    {
00197       eh_free( a );
00198    }
00199    return NULL;
00200 }
00201 
00202 Sed_measurement
00203 sed_measurement_new( const char* name )
00204 {
00205    Sed_measurement m = NULL;
00206 
00207    if ( name )
00208    {
00209       gssize i;
00210       gboolean found = FALSE;
00211 
00212       NEW_OBJECT( Sed_measurement , m );
00213 
00214       m->name = g_strdup( name );
00215       m->f    = NULL;
00216 
00217       for ( i=0 ; !found && all_measurements[i].name ; i++ )
00218          if ( g_ascii_strcasecmp( all_measurements[i].name , name )==0 )
00219          {
00220             m->f = all_measurements[i].f;
00221             found = TRUE;
00222          }
00223 
00224       if ( !found )
00225       {
00226          eh_free( m->name );
00227          eh_free( m );
00228          m = NULL;
00229       }
00230    }
00231 
00232    return m;
00233 }
00234 
00235 Sed_measurement sed_measurement_copy( Sed_measurement dest , Sed_measurement src )
00236 {
00237    eh_require( src );
00238 
00239    if ( src )
00240    {
00241       if ( !dest )
00242          dest = sed_measurement_new( src->name );
00243 
00244       eh_free( dest->name );
00245 
00246       dest->name = g_strdup( src->name );
00247       dest->f    = src->f;
00248    }
00249    else
00250       dest = NULL;
00251 
00252    return dest;
00253 }
00254 
00255 Sed_measurement sed_measurement_dup( Sed_measurement src )
00256 {
00257    return sed_measurement_copy( NULL , src );
00258 }
00259 
00260 Sed_measurement sed_measurement_destroy( Sed_measurement m )
00261 {
00262    if ( m )
00263    {
00264       eh_free( m->name );
00265       eh_free( m );
00266    }
00267    return NULL;
00268 }
00269 
00270 char* sed_measurement_name( Sed_measurement m )
00271 {
00272    char* name;
00273 
00274    if ( m )
00275       name = g_strdup( m->name );
00276    else
00277       name = NULL;
00278 
00279    return name;
00280 }
00281 
00282 double sed_measure_cube_slope( Sed_cube p , gssize i , gssize j )
00283 {
00284    if ( sed_cube_is_in_domain(p,i,j) )
00285       return sed_cube_slope( p , i , j );
00286    else
00287       return eh_nan();
00288 }
00289 
00290 double sed_measure_cube_water_depth( Sed_cube p , gssize i , gssize j )
00291 {
00292    if ( sed_cube_is_in_domain(p,i,j) )
00293       return sed_cube_water_depth( p , i , j );
00294    else
00295       return eh_nan();
00296 }
00297 
00298 double sed_measure_cube_elevation( Sed_cube p , gssize i , gssize j )
00299 {
00300    if ( sed_cube_is_in_domain(p,i,j) )
00301       return sed_cube_top_height( p , i , j );
00302    else
00303       return eh_nan();
00304 }
00305 
00306 double sed_measure_cube_thickness( Sed_cube p , gssize i , gssize j )
00307 {
00308    if ( sed_cube_is_in_domain(p,i,j) )
00309       return sed_cube_thickness( p , i , j );
00310    else
00311       return eh_nan();
00312 }
00313 
00314 double sed_measure_cube_basement( Sed_cube p , gssize i , gssize j )
00315 {
00316    if ( sed_cube_is_in_domain(p,i,j) )
00317       return sed_cube_base_height( p , i , j );
00318    else
00319       return eh_nan();
00320 }
00321 
00322 double
00323 sed_measure_cube_grain_size( Sed_cube p , gssize i , gssize j )
00324 {
00325    if ( sed_cube_is_in_domain(p,i,j) && !sed_cube_col_is_empty(p,i,j) )
00326    {
00327       Sed_column col   = sed_cube_col_ij( p,i,j );
00328       gssize     i_top = sed_column_top_index( col );
00329 
00330       return sed_cell_grain_size_in_phi( sed_column_nth_cell( col , i_top ) );
00331    }
00332    else
00333       return eh_nan();
00334 
00335 }
00336 
00337 double sed_measure_cube_age( Sed_cube p , gssize i , gssize j )
00338 {
00339    if ( sed_cube_is_in_domain(p,i,j) && !sed_cube_col_is_empty(p,i,j) )
00340    {
00341       Sed_column col = sed_cube_col_ij( p,i,j );
00342       gssize i_top   = sed_column_top_index( col );
00343 
00344       return sed_cell_age( sed_column_nth_cell( col , i_top ) );
00345    }
00346    else
00347       return eh_nan();
00348 }
00349 
00350 double sed_measure_cube_sand_fraction( Sed_cube p , gssize i , gssize j )
00351 {
00352    if ( sed_cube_is_in_domain(p,i,j) && !sed_cube_col_is_empty(p,i,j) )
00353    {
00354       Sed_column col = sed_cube_col_ij( p,i,j );
00355       gssize i_top   = sed_column_top_index( col );
00356       return sed_cell_size_class_percent( sed_column_nth_cell( col , i_top ) , S_SED_TYPE_SAND );
00357    }
00358    else
00359       return eh_nan();
00360 }
00361 
00362 double sed_measure_cube_silt_fraction( Sed_cube p , gssize i , gssize j )
00363 {
00364    if ( sed_cube_is_in_domain(p,i,j) && !sed_cube_col_is_empty(p,i,j) )
00365    {
00366       Sed_column col = sed_cube_col_ij( p,i,j );
00367       gssize i_top   = sed_column_top_index( col );
00368       return sed_cell_size_class_percent( sed_column_nth_cell( col , i_top ) , S_SED_TYPE_SILT );
00369    }
00370    else
00371       return eh_nan();
00372 }
00373 
00374 double sed_measure_cube_clay_fraction( Sed_cube p , gssize i , gssize j )
00375 {
00376    if ( sed_cube_is_in_domain(p,i,j) && !sed_cube_col_is_empty(p,i,j) )
00377    {
00378       Sed_column col = sed_cube_col_ij( p,i,j );
00379       gssize i_top   = sed_column_top_index( col );
00380       return sed_cell_size_class_percent( sed_column_nth_cell( col , i_top ) , S_SED_TYPE_CLAY );
00381    }
00382    else
00383       return eh_nan();
00384 }
00385 
00386 double sed_measure_cube_mud_fraction( Sed_cube p , gssize i , gssize j )
00387 {
00388    if ( sed_cube_is_in_domain(p,i,j) && !sed_cube_col_is_empty(p,i,j) )
00389    {
00390       Sed_column col = sed_cube_col_ij( p,i,j );
00391       gssize i_top   = sed_column_top_index( col );
00392       return   sed_cell_size_class_percent( sed_column_nth_cell( col , i_top ) , S_SED_TYPE_SILT )
00393              + sed_cell_size_class_percent( sed_column_nth_cell( col , i_top ) , S_SED_TYPE_CLAY );
00394    }
00395    else
00396       return eh_nan();
00397 }
00398 
00399 double sed_measure_cube_density( Sed_cube p , gssize i , gssize j )
00400 {
00401    if ( sed_cube_is_in_domain(p,i,j) && !sed_cube_col_is_empty(p,i,j) )
00402    {
00403       Sed_column col = sed_cube_col_ij( p,i,j );
00404       gssize i_top   = sed_column_top_index( col );
00405       return sed_cell_density( sed_column_nth_cell( col , i_top ) );
00406    }
00407    else
00408       return eh_nan();
00409 }
00410 
00411 double sed_measure_cube_porosity( Sed_cube p , gssize i , gssize j )
00412 {
00413    if ( sed_cube_is_in_domain(p,i,j) && !sed_cube_col_is_empty(p,i,j) )
00414    {
00415       Sed_column col = sed_cube_col_ij( p,i,j );
00416       gssize i_top   = sed_column_top_index( col );
00417       return sed_cell_porosity( sed_column_nth_cell( col , i_top ) );
00418    }
00419    else
00420       return eh_nan();
00421 }
00422 
00423 double sed_measure_cube_permeability( Sed_cube p , gssize i , gssize j )
00424 {
00425    if ( sed_cube_is_in_domain(p,i,j) && !sed_cube_col_is_empty(p,i,j) )
00426    {
00427       Sed_column col = sed_cube_col_ij( p,i,j );
00428       gssize i_top   = sed_column_top_index( col );
00429       return sed_cell_permeability( sed_column_nth_cell( col , i_top ) );
00430    }
00431    else
00432       return eh_nan();
00433 }
00434 
00435 double sed_measure_cube_facies( Sed_cube p , gssize i , gssize j )
00436 {
00437    if ( sed_cube_is_in_domain(p,i,j) && !sed_cube_col_is_empty(p,i,j) )
00438    {
00439       Sed_column col = sed_cube_col_ij( p,i,j );
00440       gssize i_top   = sed_column_top_index( col );
00441       return (double)sed_cell_facies( sed_column_nth_cell( col , i_top ) );
00442    }
00443    else
00444       return eh_nan();
00445 }
00446 
00447 double sed_measure_cube_river_mouth( Sed_cube p , gssize i , gssize j )
00448 {
00449    if ( sed_cube_is_in_domain(p,i,j) )
00450    {
00451       gssize len = sed_cube_n_rivers( p );
00452       gssize n;
00453       Sed_riv this_river;
00454       gboolean found=FALSE;
00455 
00456       for ( n=0 ; n<len && !found ; n++ )
00457       {
00458          this_river = sed_cube_nth_river( p , n );
00459          if ( sed_river_mouth_is( this_river , i , j ) )
00460             found = TRUE;
00461       }
00462 
00463       return found?1:-1;
00464    }
00465    else
00466       return -1;
00467 }
00468 
00469 Sed_tripod_header sed_tripod_header_new( Sed_measurement x )
00470 {
00471    Sed_tripod_header h;
00472 
00473    NEW_OBJECT( Sed_tripod_header , h );
00474 
00475    h->bad_val          = eh_nan();
00476    h->n_tripods        = 0;
00477    h->n_x_cols         = 0;
00478    h->n_y_cols         = 0;
00479    h->byte_order       = G_BYTE_ORDER;
00480    h->x                = sed_measurement_dup( x );
00481    h->from_river_mouth = FALSE;
00482    h->pos              = g_array_new( FALSE , FALSE , sizeof(Eh_pt_2) );
00483    h->parameter        = NULL;
00484 
00485    return h;
00486 }
00487 
00488 Sed_tripod_header sed_tripod_header_destroy( Sed_tripod_header h )
00489 {
00490    if ( h )
00491    {
00492       eh_free( h->parameter );
00493       g_array_free( h->pos , TRUE );
00494       sed_measurement_destroy( h->x );
00495       eh_free( h );
00496    }
00497    return NULL;
00498 }
00499 
00500 gssize sed_tripod_header_fprint( FILE* fp , Sed_tripod_header h )
00501 {
00502    gssize n = 0;
00503 
00504    eh_require( fp );
00505    eh_require( h  );
00506    
00507    if ( fp && h )
00508    {
00509       char *date_str    = eh_new( char , 2048 );
00510       char *program_str = eh_new( char , 2048 );
00511       GDate *today      = g_date_new( );
00512       GArray *pos;
00513       char *property_str;
00514 
00515       g_date_set_time( today , time(NULL) );
00516       g_date_strftime( date_str , 2048 , "%A %e %B %Y %T %Z" , today );
00517       property_str = sed_measurement_name( h->x );
00518 
00519       fflush( fp );
00520 
00521       n += fprintf( fp , "--- header ---\n" );
00522 
00523       g_snprintf( program_str , 2048 , "%s %s.%s.%s" ,
00524                   PROGRAM_NAME          ,
00525                   SED_MAJOR_VERSION_S ,
00526                   SED_MINOR_VERSION_S ,
00527                   SED_MICRO_VERSION_S );
00528 
00529       n += fprintf( fp , "SEDFLUX tripod file version: %s\n"   , program_str );
00530       n += fprintf( fp , "Creation date: %s\n"                 , date_str );
00531       n += fprintf( fp , "Property: %s\n"                      , property_str );
00532       n += fprintf( fp , "Number of tripods: %d\n"             , (gint)h->n_tripods );
00533       n += fprintf( fp , "Number of x-columns: %d\n"           , (gint)h->n_x_cols );
00534       n += fprintf( fp , "Number of y-columns: %d\n"           , (gint)h->n_y_cols );
00535       n += fprintf( fp , "Data type: %s\n"                     , "DOUBLE" );
00536       n += fprintf( fp , "No data value: %g\n"                 , eh_nan() );
00537       n += fprintf( fp , "Byte order: %d\n"                    , h->byte_order );
00538 
00539       pos = h->pos;
00540       n += fprintf( fp , "Origin : " );
00541 
00542       if ( h->from_river_mouth )
00543          n += fprintf( fp , "RIVER MOUTH\n" );
00544       else
00545          n += fprintf( fp , "GRID\n" );
00546 
00547       n += fprintf( fp , "--- data ---\n" );
00548 
00549       fflush( fp );
00550 
00551       g_date_free( today );
00552       eh_free( program_str );
00553       eh_free( date_str    );
00554       eh_free( property_str );
00555    }
00556 
00557    return n;
00558 }
00559 
00560 gssize sed_tripod_write( Sed_tripod t , Sed_cube cube )
00561 {
00562    gssize n = 0;
00563 
00564    eh_require( t    );
00565    eh_require( cube );
00566 
00567    if ( t && cube )
00568    {
00569       gssize i;
00570       double time;
00571       double *measurement;
00572       Eh_pt_2 *location;
00573       int n_measurements;
00574       gint32 rec_len;
00575       Sed_tripod_header h = t->h;
00576 
00577       //---
00578       // Set up the positions where a measurement will be made.  The positions
00579       // are given in the pos array of the header.  If the pos array is empty
00580       // (its length is <= 0), it means make a measurement at every column
00581       // in the cube.
00582       //---
00583       if ( h->pos->len > 0 )
00584          n_measurements = h->pos->len;
00585       else
00586          n_measurements = sed_cube_size( cube );
00587 
00588       measurement = eh_new( double  , n_measurements );
00589       location    = eh_new( Eh_pt_2 , n_measurements );
00590 
00591       if ( h->pos->len > 0 )
00592          for ( i=0 ; i<n_measurements ; i++ )
00593             location[i] = g_array_index( h->pos , Eh_pt_2 , i );
00594       else
00595          for ( i=0 ; i<n_measurements ; i++ )
00596          {
00597             location[i].x = sed_cube_col_x( cube , i );
00598             location[i].y = sed_cube_col_y( cube , i );
00599          }
00600 
00601       //---
00602       // Make the measurement.
00603       //---
00604       sed_tripod_measure( t           ,
00605                           cube        ,
00606                           location    ,
00607                           measurement ,
00608                           n_measurements );
00609    
00610       //---
00611       // Write the header if it hasn't been written yet.  The header_is_written
00612       // member can be set to true upon the creation of the measurement file if
00613       // you would rather just have the data and no header.
00614       //---
00615       if ( !t->header_is_written )
00616       {
00617          n += sed_tripod_header_fprint( t->fp , t->h );
00618          rec_len = 3*n_measurements + 1;
00619          n += fwrite( &rec_len , sizeof(gint32) , 1 , t->fp );
00620          t->header_is_written = TRUE;
00621       }
00622 
00623       //---
00624       // Write the measurements.  First the time of the measurement is written,
00625       // then the x-y positions of the measurements, the the measuremnts
00626       // themselves.  The locations are written as x-y pairs of doubles.
00627       //---
00628       time = sed_cube_age_in_years( cube );
00629 
00630       n += fwrite( &time       , sizeof(double)  , 1              , t->fp );
00631       n += fwrite( location    , sizeof(Eh_pt_2) , n_measurements , t->fp );
00632       n += fwrite( measurement , sizeof(double)  , n_measurements , t->fp );
00633 
00634       fflush( t->fp );
00635 
00636       eh_free( measurement );
00637       eh_free( location    );
00638    }
00639 
00640    return n;
00641 }
00642 
00643 Sed_tripod sed_tripod_set_len( Sed_tripod t , gssize len )
00644 {
00645    if ( t )
00646    {
00647       t->h->n_tripods = len;
00648    }
00649 
00650    return t;
00651 }
00652 
00653 Sed_tripod sed_tripod_set_n_x( Sed_tripod t , gssize n_x )
00654 {
00655    if ( t )
00656    {
00657       t->h->n_x_cols = n_x;
00658    }
00659 
00660    return t;
00661 }
00662 
00663 Sed_tripod sed_tripod_set_n_y( Sed_tripod t , gssize n_y )
00664 {
00665    if ( t )
00666    {
00667       t->h->n_y_cols = n_y;
00668    }
00669 
00670    return t;
00671 }
00672 
00673 

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