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
00579
00580
00581
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
00603
00604 sed_tripod_measure( t ,
00605 cube ,
00606 location ,
00607 measurement ,
00608 n_measurements );
00609
00610
00611
00612
00613
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
00625
00626
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