00001 #include <eh_utils.h>
00002
00003 CLASS ( Eh_data_record )
00004 {
00005 Eh_symbol_table t;
00006 Eh_dbl_grid g;
00007 };
00008
00009 Eh_data_record eh_data_record_new()
00010 {
00011 Eh_data_record p;
00012
00013 NEW_OBJECT( Eh_data_record , p );
00014
00015 p->t = eh_symbol_table_new();
00016 p->g = eh_grid_new( double , 0 , 0 );
00017
00018 return p;
00019 }
00020
00021 Eh_data_record eh_data_record_destroy( Eh_data_record p )
00022 {
00023 if ( p )
00024 {
00025 eh_symbol_table_destroy( p->t );
00026 eh_grid_destroy( p->g , TRUE );
00027 eh_free( p );
00028 }
00029
00030 return NULL;
00031 }
00032
00033 void eh_data_record_print( Eh_data_record p ,
00034 char *rec_name ,
00035 char *delim ,
00036 gboolean row_major ,
00037 gboolean with_header ,
00038 FILE *fp )
00039 {
00040 if ( with_header )
00041 {
00042 fprintf( fp , "--- %s ---\n" , rec_name );
00043 eh_symbol_table_print_aligned( p->t , fp );
00044 fprintf(fp,"--- data ---\n");
00045 }
00046
00047 {
00048 gchar* format = g_strconcat( "%f" , delim , " " , NULL );
00049
00050 if ( row_major )
00051 eh_dbl_grid_fprintf( fp , format , p->g );
00052 else
00053 {
00054 eh_dbl_grid_fprintf( fp , format , eh_grid_transpose(p->g) );
00055 eh_grid_transpose( p->g );
00056 }
00057
00058 eh_free( format );
00059 }
00060 }
00061
00062 int eh_data_record_size( Eh_data_record p , int dim )
00063 {
00064 if ( p && p->g && (dim==0||dim==1) )
00065 {
00066 if ( dim==0 )
00067 return eh_grid_n_x(p->g);
00068 else if ( dim==1 )
00069 return eh_grid_n_y(p->g);
00070 }
00071
00072 return 0;
00073 }
00074
00075 Eh_symbol_table eh_data_record_table( Eh_data_record p )
00076 {
00077 return p->t;
00078 }
00079
00080 double* eh_data_record_row( Eh_data_record p , gssize row )
00081 {
00082 if ( p && row < eh_grid_n_x(p->g) && row >=0 )
00083 return eh_grid_row(p->g,row);
00084
00085 return NULL;
00086 }
00087
00088 double* eh_data_record_dup_row( Eh_data_record p , gssize row )
00089 {
00090 return g_memdup( eh_data_record_row(p,row) , eh_data_record_size(p,1)*sizeof(double) );
00091
00092 }
00093
00094 void eh_data_record_set_row( Eh_data_record p , int row , double* a )
00095 {
00096 if ( p && row<eh_grid_n_x(p->g) && a )
00097 g_memmove( eh_data_record_row(p,row) , a , eh_grid_el_size(p->g)*eh_grid_n_y(p->g) );
00098 }
00099
00100 void eh_data_record_add_row( Eh_data_record p , double* a )
00101 {
00102 eh_grid_add_row( p->g , a );
00103 }
00104
00105 void eh_data_record_add_column( Eh_data_record p , double* a )
00106 {
00107 eh_grid_add_column( p->g , a );
00108 }
00109
00110 void eh_data_record_add_label( Eh_data_record p , char *label , char *value )
00111 {
00112 eh_symbol_table_insert( p->t , label , value );
00113 }
00114
00115 void eh_data_record_interpolate_rows( Eh_data_record p , gssize row , double* y , gssize new_len )
00116 {
00117 eh_require( p );
00118 eh_require( row>=0 );
00119 eh_require( row<eh_grid_n_x(p->g) );
00120 eh_require( y );
00121 eh_require( new_len>0 );
00122
00123 if ( p )
00124 {
00125 gssize i;
00126 double* y_0 = eh_data_record_row( p , row );
00127 Eh_dbl_grid new_grid = eh_grid_new( double , eh_grid_n_x(p->g) , new_len );
00128
00129 for ( i=0 ; i<eh_grid_n_x(p->g) ; i++ )
00130 {
00131 if ( i!=row )
00132 interpolate( y_0 , eh_grid_row(p->g,i) , eh_grid_n_y(p->g) ,
00133 y , eh_grid_row(new_grid,i) , new_len );
00134 }
00135
00136 eh_grid_destroy( p->g , TRUE );
00137 p->g = new_grid;
00138 }
00139 }
00140
00141 Eh_data_record*
00142 eh_data_record_scan_file( const char* file , const char* delim , int fast_dim , gboolean with_header , GError** error )
00143 {
00144 Eh_data_record* all_records = NULL;
00145 GError* tmp_err = NULL;
00146 GScanner* s = NULL;
00147
00148 eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00149
00150 s = eh_open_scanner( file , &tmp_err );
00151
00152 if ( s )
00153 {
00154 gssize n_recs = 0;
00155 Eh_data_record next_record = eh_data_record_scan( s , delim , fast_dim , with_header );
00156
00157 while ( next_record )
00158 {
00159 n_recs++;
00160 all_records = eh_renew( Eh_data_record , all_records , n_recs+1 );
00161 all_records[n_recs-1] = next_record;
00162 next_record = eh_data_record_scan( s , delim , fast_dim , with_header );
00163 }
00164 if ( all_records )
00165 all_records[n_recs] = NULL;
00166 }
00167 else
00168 g_propagate_error( error , tmp_err );
00169
00170 eh_close_scanner( s );
00171
00172 return all_records;
00173 }
00174
00175 Eh_data_record eh_data_record_scan( GScanner* s , const char* delim , int fast_dim , gboolean with_header )
00176 {
00177 Eh_data_record ans;
00178
00179 if ( !g_scanner_scope_lookup_symbol(s,0,"---") )
00180 g_scanner_scope_add_symbol(s,0,"---",g_strdup("---") );
00181
00182 ans = eh_data_record_new();
00183
00184 if ( with_header )
00185 {
00186 char *record_name = eh_scan_next_record( s , ans->t );
00187 if ( !record_name )
00188 return eh_data_record_destroy( ans );
00189 eh_free( record_name );
00190 }
00191
00192 eh_debug( "Find the next record" );
00193 {
00194 char *record_name = eh_seek_record_start(s);
00195 if ( !record_name )
00196 return eh_data_record_destroy( ans );
00197 eh_free( record_name );
00198 }
00199
00200 eh_debug( "Read the input file line by line" );
00201 {
00202 gssize n_cols;
00203 double* row = eh_scan_ascii_data_line_dbl( s , delim , &n_cols );
00204
00205 eh_grid_resize( ans->g , 0 , n_cols );
00206
00207 while ( row )
00208 {
00209 eh_grid_add_row( ans->g , row );
00210 eh_free( row );
00211
00212 row = eh_scan_ascii_data_line_dbl( s , delim , &n_cols );
00213 }
00214 }
00215
00216 eh_debug( "Switch rows and columns if necessary" );
00217 if ( fast_dim==EH_FAST_DIM_COL )
00218 eh_grid_transpose( ans->g );
00219
00220 return ans;
00221 }
00222