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

Go to the documentation of this file.
00001 //---
00002 //
00003 // This file is part of sedflux.
00004 //
00005 // sedflux is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // sedflux is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with sedflux; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //
00019 //---
00020 
00021 #include <stdio.h>
00022 #include <glib.h>
00023 #include "utils/utils.h"
00024 
00025 #include "sed_epoch.h"
00026 #include "sed_signal.h"
00027 
00028 CLASS( Sed_epoch )
00029 {
00030    char*             name;        //< Name that identifies the epoch
00031    double            number;      //< ID that identifies the epoch
00032 
00033    double            start;       //< Start time for the epoch
00034    double            duration;    //< Duration of the epoch
00035    double            time_step;   //< Time step of the epoch
00036 
00037    char*             filename;    //< Initialization file
00038    Sed_process_queue proc_q;      //< List of processes to run during the epoch
00039 };
00040 
00041 CLASS( Sed_epoch_queue )
00042 {
00043    GList* l; //< A list of Sed_epoch
00044 };
00045 
00046 GQuark
00047 sed_epoch_error_quark( void )
00048 {
00049    return g_quark_from_static_string( "sed-epoch-error-quark" );
00050 }
00051 
00052 Sed_epoch
00053 sed_epoch_new( void )
00054 {
00055    Sed_epoch e;
00056 
00057    NEW_OBJECT( Sed_epoch , e );
00058 
00059    e->name      = NULL;
00060    e->number    = -1;
00061 
00062    e->start     =  0;
00063    e->duration  =  0;
00064    e->time_step =  0;
00065 
00066    e->filename  = NULL;
00067    e->proc_q    = NULL;
00068 
00069    return e;
00070 }
00071 
00072 Sed_epoch
00073 sed_epoch_copy( Sed_epoch d , const Sed_epoch s )
00074 {
00075    if ( s )
00076    {
00077       if ( !d )
00078          d = sed_epoch_new( );
00079 
00080       d->name      = g_strdup( s->name );
00081       d->number    = s->number;
00082 
00083       d->start     = s->start;
00084       d->duration  = s->duration;
00085       d->time_step = s->time_step;
00086 
00087       d->filename  = g_strdup( s->filename );
00088 
00089       if ( d->proc_q )
00090          sed_process_queue_destroy( d->proc_q );
00091 
00092       d->proc_q = sed_process_queue_dup( s->proc_q );
00093    }
00094 
00095    return d;
00096 }
00097 
00098 Sed_epoch
00099 sed_epoch_dup( const Sed_epoch s )
00100 {
00101    Sed_epoch d = NULL;
00102 
00103    if ( s ) d = sed_epoch_copy( NULL , s );
00104 
00105    return d;
00106 }
00107 
00108 #define SED_KEY_EPOCH_NUMBER       "number"
00109 #define SED_KEY_EPOCH_DURATION     "duration"
00110 #define SED_KEY_EPOCH_ACTIVE       "active"
00111 #define SED_KEY_EPOCH_TIME_STEP    "time step"
00112 #define SED_KEY_EPOCH_FILE         "process file"
00113 
00114 static gchar* old_required_labels[] =
00115 {
00116    SED_KEY_EPOCH_NUMBER       ,
00117    SED_KEY_EPOCH_DURATION     ,
00118    SED_KEY_EPOCH_TIME_STEP    ,
00119    SED_KEY_EPOCH_FILE         ,
00120    NULL
00121 };
00122 
00123 static gchar* required_labels[] =
00124 {
00125    SED_KEY_EPOCH_ACTIVE       ,
00126    SED_KEY_EPOCH_TIME_STEP    ,
00127    SED_KEY_EPOCH_FILE         ,
00128    NULL
00129 };
00130 
00131 Sed_epoch_queue
00132 sed_epoch_new_from_table( Eh_symbol_table t , GError** error )
00133 {
00134    Sed_epoch_queue q = NULL;
00135 
00136    eh_require( t );
00137    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00138 
00139    if ( t )
00140    {
00141       GError* tmp_err     = NULL;
00142       gchar*  time_s      = eh_symbol_table_value( t , SED_KEY_EPOCH_ACTIVE    );
00143       gchar*  number_s    = eh_symbol_table_value( t , SED_KEY_EPOCH_NUMBER    );
00144       gchar*  duration_s  = eh_symbol_table_value( t , SED_KEY_EPOCH_DURATION  );
00145       gchar*  file_s      = eh_symbol_table_value( t , SED_KEY_EPOCH_FILE      );
00146       gchar*  time_step_s = eh_symbol_table_value( t , SED_KEY_EPOCH_TIME_STEP );
00147 
00148       /* Still support the old way of specifying epoch durations and times */
00149       if (    !eh_symbol_table_has_labels( t , required_labels     )
00150            && !eh_symbol_table_has_labels( t , old_required_labels ) )
00151       {
00152          gchar* err_s;
00153          eh_symbol_table_require_labels( t , required_labels , &tmp_err );
00154 
00155          err_s = tmp_err->message;
00156          tmp_err->message = g_strconcat( "Missing required labels in epoch group\n" , err_s , NULL );
00157          eh_free( err_s );
00158          /*
00159          g_set_error( &tmp_err ,
00160                       SED_EPOCH_ERROR ,
00161                       SED_EPOCH_ERROR_MISSING_LABEL ,
00162                       "Missing required labels in epoch group" );
00163          */
00164       }
00165 
00166       /* Scan the active times the new way */
00167       if ( !tmp_err && time_s   ) q = sed_epoch_queue_new_sscan    ( time_s   , time_step_s , file_s , &tmp_err );
00168       if ( !tmp_err && number_s ) q = sed_epoch_queue_new_sscan_old( number_s , time_step_s , file_s , duration_s , &tmp_err );
00169 
00170       if ( tmp_err )
00171       {
00172          g_propagate_error( error , tmp_err );
00173          q = sed_epoch_queue_destroy( q );
00174       }
00175 
00176       eh_free( number_s    );
00177       eh_free( duration_s  );
00178       eh_free( time_s      );
00179       eh_free( file_s      );
00180       eh_free( time_step_s );
00181    }
00182 
00183    return q;
00184 }
00185 
00186 Sed_epoch_queue
00187 sed_epoch_queue_new_sscan_old( const gchar* number_s    ,
00188                                const gchar* time_step_s ,
00189                                const gchar* file_s      ,
00190                                const gchar* duration_s  ,
00191                                GError** error )
00192 {
00193    Sed_epoch_queue q = NULL;
00194 
00195    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00196 
00197    {
00198       GError*   tmp_err = NULL;
00199       Sed_epoch e       = sed_epoch_new();
00200 
00201       if ( !tmp_err ) sed_epoch_sscan_number   ( e , number_s    , &tmp_err );
00202       if ( !tmp_err ) sed_epoch_sscan_duration ( e , duration_s  , &tmp_err );
00203       if ( !tmp_err ) sed_epoch_sscan_time_step( e , time_step_s , &tmp_err );
00204       if ( !tmp_err ) sed_epoch_sscan_filename ( e , file_s      , &tmp_err );
00205       if ( !tmp_err )
00206       {
00207          NEW_OBJECT( Sed_epoch_queue , q );
00208          q->l = NULL;
00209 
00210          sed_epoch_queue_push_tail( q , e );
00211       }
00212       
00213       if ( tmp_err )
00214       {
00215          g_propagate_error( error , tmp_err );
00216          q = NULL;
00217       }
00218    }
00219 
00220    return q;
00221 }
00222 
00223 Sed_epoch_queue
00224 sed_epoch_queue_new_sscan( const gchar* time_s      ,
00225                            const gchar* time_step_s ,
00226                            const gchar* file_s      ,
00227                            GError** error )
00228 {
00229    Sed_epoch_queue q = NULL;
00230 
00231    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00232 
00233    if ( time_s && time_step_s && file_s )
00234    {
00235       GError*   tmp_err   = NULL;
00236       gchar**   time_str  = g_strsplit   ( time_s      , ";" , 0 );
00237       gchar**   dt_str    = g_strsplit   ( time_step_s , ";" , 0 );
00238       gint      len_time  = g_strv_length( time_str );
00239       gint      len_dt    = g_strv_length( dt_str   );
00240       gint      i;
00241       Sed_epoch e;
00242 
00243       NEW_OBJECT( Sed_epoch_queue , q );
00244       q->l = NULL;
00245 
00246       if ( len_time==len_dt )
00247       {
00248          for ( i=0 ; !tmp_err && i<len_time ; i++ )
00249          {
00250             e = sed_epoch_new();
00251 
00252             if ( !tmp_err ) sed_epoch_sscan_time      ( e , time_str[i] , &tmp_err );
00253             if ( !tmp_err ) sed_epoch_sscan_time_step ( e , dt_str[i]   , &tmp_err );
00254             if ( !tmp_err ) sed_epoch_sscan_filename  ( e , file_s      , &tmp_err );
00255 
00256             sed_epoch_queue_push_tail( q , e );
00257             
00258          }
00259       }
00260       else if ( len_dt==1 )
00261       {
00262          for ( i=0 ; !tmp_err && i<len_time ; i++ )
00263          {
00264             e = sed_epoch_new();
00265 
00266             if ( !tmp_err ) sed_epoch_sscan_time      ( e , time_str[i] , &tmp_err );
00267             if ( !tmp_err ) sed_epoch_sscan_time_step ( e , dt_str[0]   , &tmp_err );
00268             if ( !tmp_err ) sed_epoch_sscan_filename  ( e , file_s      , &tmp_err );
00269 
00270             sed_epoch_queue_push_tail( q , e );
00271          }
00272       }
00273       else
00274          g_set_error( &tmp_err ,
00275                       SED_EPOCH_ERROR ,
00276                       SED_EPOCH_ERROR_BAD_TIME_STEP ,
00277                       "Number of time steps does not match active periods (or scalar)" );
00278 
00279       g_strfreev( time_str );
00280       g_strfreev( dt_str   );
00281 
00282       if ( tmp_err )
00283       {
00284          g_propagate_error( error , tmp_err );
00285          q = sed_epoch_queue_destroy( q );
00286       }
00287    }
00288 
00289    return q;
00290 }
00291 
00292 Sed_epoch_queue
00293 sed_epoch_queue_new( const gchar* file , GError** error )
00294 {
00295    Sed_epoch_queue q = NULL;
00296 
00297    eh_require( file );
00298    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00299 
00300    if ( file )
00301    {
00302       GError*     tmp_err  = NULL;
00303       Eh_key_file key_file = NULL;
00304 
00305       key_file = eh_key_file_scan( file , &tmp_err );
00306 
00307       if ( key_file )
00308       {
00309          Eh_symbol_table* tables     = eh_key_file_get_symbol_tables( key_file , "epoch" );
00310          Eh_symbol_table* this_table;
00311          Sed_epoch_queue  new_q;
00312 
00313          NEW_OBJECT( Sed_epoch_queue , q );
00314          q->l = NULL;
00315 
00316          for ( this_table=tables ; !tmp_err && *this_table ; this_table++ )
00317          {
00318             new_q = sed_epoch_new_from_table( *this_table , &tmp_err );
00319 
00320             q = sed_epoch_queue_concat( q , new_q );
00321 
00322             sed_epoch_queue_destroy( new_q );
00323          }
00324 
00325          sed_epoch_queue_order( q );
00326 
00327          for ( this_table=tables ; *this_table ; this_table++ )
00328             eh_symbol_table_destroy( *this_table );
00329          eh_free( tables );
00330       }
00331 
00332       if ( tmp_err )
00333       {
00334          g_propagate_error( error , tmp_err );
00335          q = sed_epoch_queue_destroy( q );
00336       }
00337 
00338       eh_key_file_destroy( key_file );
00339    }
00340 
00341    return q;
00342 }
00343 
00344 Sed_epoch_queue
00345 sed_epoch_queue_new_full( const gchar*       file          ,
00346                           Sed_process_init_t proc_defs[]   ,
00347                           Sed_process_family proc_family[] ,
00348                           Sed_process_check  proc_checks[] ,
00349                           GError**           error )
00350 {
00351    Sed_epoch_queue q = NULL;
00352 
00353    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00354 
00355    if ( file )
00356    {
00357       GError* tmp_err = NULL;
00358 
00359       q = sed_epoch_queue_new( file , &tmp_err );
00360 
00361       if ( !tmp_err ) sed_epoch_queue_set_processes( q , proc_defs , proc_family , proc_checks , &tmp_err );
00362       if (  tmp_err ) g_propagate_error( error , tmp_err );
00363    }
00364 
00365    return q;
00366 }
00367 
00368 Sed_epoch_queue
00369 sed_epoch_queue_dup( const Sed_epoch_queue s )
00370 {
00371    Sed_epoch_queue d = NULL;
00372 
00373    if ( s )
00374    {
00375       GList* l;
00376 
00377       NEW_OBJECT( Sed_epoch_queue , d );
00378       d->l = NULL;
00379 
00380       for ( l=s->l ; l ; l=l->next )
00381          d->l = g_list_prepend( d->l , sed_epoch_dup( l->data ) );
00382       d->l = g_list_reverse( d->l );
00383    }
00384 
00385    return d;
00386 }
00387 
00388 Sed_epoch_queue
00389 sed_epoch_queue_concat( Sed_epoch_queue q_1 , Sed_epoch_queue q_2 )
00390 {
00391    if ( q_1 && q_2 )
00392    {
00393       GList* l;
00394       GList* new_l = NULL;
00395 
00396       for ( l=q_2->l ; l ; l=l->next )
00397          new_l = g_list_prepend( new_l , sed_epoch_dup( l->data ) );
00398       q_1->l = g_list_concat( q_1->l , g_list_reverse(new_l) );
00399    }
00400    else if ( !q_1       )
00401    {
00402       q_1 = sed_epoch_queue_dup( q_2 );
00403    }
00404 
00405    return q_1;
00406 }
00407 
00408 gint
00409 sed_epoch_start_cmp( Sed_epoch a , Sed_epoch b )
00410 {
00411    gint val = 0;
00412 
00413    if ( a && b )
00414    {
00415       if ( a->start > b->start )
00416          val =  1;
00417       else if ( a->start < b->start )
00418          val = -1;
00419    }
00420 
00421    return val;
00422 }
00423 
00424 gint
00425 sed_epoch_number_cmp( Sed_epoch a , Sed_epoch b )
00426 {
00427    gint val = 0;
00428 
00429    if ( a && b )
00430    {
00431       if ( a->number > b->number )
00432          val =  1;
00433       else if ( a->number < b->number )
00434          val = -1;
00435    }
00436 
00437    return val;
00438 }
00439 
00440 Sed_epoch
00441 sed_epoch_destroy( Sed_epoch e )
00442 {
00443    if ( e )
00444    {
00445       sed_process_queue_destroy( e->proc_q );
00446 
00447       eh_free( e->name      );
00448       eh_free( e->filename  );
00449       eh_free( e            );
00450    }
00451    return NULL;
00452 }
00453 
00454 Sed_epoch_queue
00455 sed_epoch_queue_destroy( Sed_epoch_queue list )
00456 {
00457    if ( list )
00458    {
00459       GList* link;
00460 
00461       for ( link=list->l ; link ; link = link->next )
00462          sed_epoch_destroy( link->data );
00463 
00464       g_list_free( list->l );
00465       eh_free( list );
00466    }
00467 
00468    return NULL;
00469 }
00470 
00471 Sed_epoch
00472 epoch_set_name( Sed_epoch e , const gchar* name )
00473 {
00474    if ( e )
00475    {
00476       if ( e->name ) eh_free( e->name );
00477 
00478       e->name = g_strdup( name );
00479    }
00480 
00481    return e;
00482 }
00483 
00484 Sed_epoch
00485 sed_epoch_set_number( Sed_epoch e , gssize n )
00486 {
00487    eh_require( n>=0 );
00488 
00489    if ( e )
00490    {
00491       e->number = n;
00492    }
00493 
00494    return e;
00495 }
00496 
00497 Sed_epoch
00498 sed_epoch_sscan_filename( Sed_epoch e , const gchar* file_s , GError** error )
00499 {
00500    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00501 
00502    if ( e )
00503    {
00504       GError* tmp_err = NULL;
00505 
00506       if ( !eh_try_open( file_s ) )
00507       {
00508          g_set_error( &tmp_err ,
00509                       SED_EPOCH_ERROR ,
00510                       SED_EPOCH_ERROR_OPEN_FILE ,
00511                       "Could not open epoch file: %s" , file_s );
00512       }
00513       else
00514          sed_epoch_set_filename( e , file_s );
00515    }
00516 
00517    return e;
00518 }
00519 
00520 Sed_epoch
00521 sed_epoch_sscan_number( Sed_epoch e , const gchar* number_s , GError** error )
00522 {
00523    eh_require( number_s );
00524    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00525 
00526    if ( e )
00527    {
00528       GError* tmp_err = NULL;
00529       double  id = -1;
00530 
00531       id = eh_str_to_dbl( number_s , &tmp_err );
00532 
00533       if ( !tmp_err ) sed_epoch_set_number( e , id );
00534 
00535       if ( tmp_err )
00536       {
00537          g_propagate_error( error , tmp_err );
00538          e = NULL;
00539       }
00540    }
00541 
00542    return e;
00543 }
00544 
00545 Sed_epoch
00546 sed_epoch_sscan_time( Sed_epoch e , const gchar* time_s , GError** error )
00547 {
00548    eh_require( time_s );
00549    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00550 
00551    if ( e )
00552    {
00553       GError* tmp_err = NULL;
00554       double* time    = NULL;
00555 
00556       time = eh_str_to_time_range( time_s , &tmp_err );
00557 
00558       if ( !tmp_err ) sed_epoch_set_active_time( e , time );
00559 
00560       if ( tmp_err )
00561       {
00562          g_propagate_error( error , tmp_err );
00563          e = NULL;
00564       }
00565 
00566       eh_free( time );
00567    }
00568 
00569    return e;
00570 }
00571 
00572 Sed_epoch
00573 sed_epoch_sscan_duration( Sed_epoch e , const gchar* duration_s , GError** error )
00574 {
00575    eh_require( duration_s );
00576    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00577 
00578    if ( e )
00579    {
00580       GError* tmp_err = NULL;
00581       double  duration;
00582 
00583       duration = eh_str_to_time_in_years( duration_s , &tmp_err );
00584 
00585       /* Look for negative duration */
00586       if ( !tmp_err && duration < 0 )
00587          g_set_error( &tmp_err , 
00588                       SED_EPOCH_ERROR ,
00589                       SED_EPOCH_ERROR_NEGATIVE_DURATION ,
00590                       "Negative time step" );
00591 
00592       if ( !tmp_err ) sed_epoch_set_duration( e , duration );
00593 
00594       if ( tmp_err )
00595       {
00596          g_propagate_error( error , tmp_err );
00597          e = NULL;
00598       }
00599    }
00600 
00601    return e;
00602 }
00603 
00604 Sed_epoch
00605 sed_epoch_sscan_time_step( Sed_epoch e , const gchar* dt_s , GError** error )
00606 {
00607    eh_require( dt_s );
00608    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00609 
00610    if ( e )
00611    {
00612       GError* tmp_err = NULL;
00613       double  dt;
00614 
00615       dt = eh_str_to_time_in_years( dt_s , &tmp_err );
00616 
00617       /* Look for negative time step */
00618       if ( !tmp_err && dt < 0 )
00619          g_set_error( &tmp_err , 
00620                       SED_EPOCH_ERROR ,
00621                       SED_EPOCH_ERROR_NEGATIVE_TIME_STEP ,
00622                       "Negative time step" );
00623 
00624       if ( !tmp_err ) sed_epoch_set_time_step( e , dt );
00625 
00626       if ( tmp_err )
00627       {
00628          g_propagate_error( error , tmp_err );
00629          e = NULL;
00630       }
00631    }
00632 
00633    return e;
00634 }
00635 
00636 Sed_epoch
00637 sed_epoch_set_active_time( Sed_epoch e , double* time )
00638 {
00639    eh_require( e    );
00640    eh_require( time );
00641 
00642    if ( e && time )
00643    {
00644       e->start     = time[0];
00645       e->duration  = time[1] - time[0];
00646    }
00647 
00648    return e;
00649 }
00650 
00651 Sed_epoch
00652 sed_epoch_set_duration( Sed_epoch e , double duration )
00653 {
00654    if ( e )
00655    {
00656       e->duration = duration;
00657    }
00658 
00659    return e;
00660 }
00661 
00662 Sed_epoch
00663 sed_epoch_set_time_step( Sed_epoch e , double time_step )
00664 {
00665    if ( e )
00666       e->time_step = time_step;
00667    return e;
00668 }
00669 
00670 Sed_epoch
00671 sed_epoch_set_filename( Sed_epoch e , const gchar* filename )
00672 {
00673    if ( e )
00674    {
00675       if ( e->filename ) eh_free( e->filename );
00676 
00677       e->filename = g_strdup( filename );
00678    }
00679 
00680    return e;
00681 }
00682 
00683 const gchar*
00684 sed_epoch_name( Sed_epoch e )
00685 {
00686    eh_return_val_if_fail( e , NULL );
00687 
00688    return e->name;
00689 }
00690 
00691 gssize
00692 sed_epoch_number( Sed_epoch e )
00693 {
00694    eh_return_val_if_fail( e , G_MAXINT );
00695 
00696    return e->number;
00697 }
00698 
00699 double
00700 sed_epoch_start( Sed_epoch e )
00701 {
00702    eh_return_val_if_fail( e , G_MAXDOUBLE );
00703 
00704    return e->start;
00705 }
00706 
00707 double
00708 sed_epoch_end( Sed_epoch e )
00709 {
00710    eh_return_val_if_fail( e , G_MAXDOUBLE );
00711 
00712    return e->start + e->duration;
00713 }
00714 
00715 double
00716 sed_epoch_duration( Sed_epoch e )
00717 {
00718    eh_return_val_if_fail( e , 0 );
00719 
00720    return e->duration;
00721 }
00722 
00723 double
00724 sed_epoch_time_step( Sed_epoch e )
00725 {
00726    eh_return_val_if_fail( e , 0 );
00727 
00728    return e->time_step;
00729 }
00730 
00731 const gchar*
00732 sed_epoch_filename( Sed_epoch e )
00733 {
00734    eh_return_val_if_fail( e , NULL );
00735 
00736    return e->filename;
00737 }
00738 
00739 Sed_process_queue
00740 sed_epoch_proc_queue( Sed_epoch e )
00741 {
00742    eh_return_val_if_fail( e , NULL );
00743 
00744    return e->proc_q;
00745 }
00746 
00747 gssize
00748 sed_epoch_queue_length( Sed_epoch_queue q )
00749 {
00750    eh_return_val_if_fail( q , 0 );
00751 
00752    return g_list_length( q->l );
00753 }
00754 
00755 Sed_epoch_queue
00756 sed_epoch_queue_order( Sed_epoch_queue q )
00757 {
00758    if ( q )
00759    {
00760       /* If the first epoch was given in the new format, sort by start time */
00761       if ( q->l && sed_epoch_number( q->l->data ) < 0 )
00762          q->l = g_list_sort( q->l , (GCompareFunc)sed_epoch_start_cmp );
00763       else
00764          q->l = g_list_sort( q->l , (GCompareFunc)sed_epoch_number_cmp );
00765    }
00766    return q;
00767 }
00768 
00769 Sed_epoch_queue
00770 sed_epoch_queue_push_tail( Sed_epoch_queue q , Sed_epoch e )
00771 {
00772    if ( q && e )
00773       q->l = g_list_append( q->l , e );
00774 
00775    return q;
00776 }
00777 
00778 Sed_epoch
00779 sed_epoch_queue_pop( Sed_epoch_queue q )
00780 {
00781    Sed_epoch e = NULL;
00782 
00783    if ( q && q->l )
00784    {
00785       e = (q->l)->data;
00786 
00787       q->l = g_list_delete_link( q->l , q->l );
00788    }
00789 
00790    return e;
00791 }
00792 
00793 Sed_epoch
00794 sed_epoch_queue_nth( Sed_epoch_queue q , gssize n )
00795 {
00796    Sed_epoch e;
00797 
00798    if ( q && q->l )
00799    {
00800       e = g_list_nth_data( q->l , n );
00801    }
00802 
00803    return e;
00804 }
00805 
00806 gint
00807 sed_epoch_is_in_range( Sed_epoch e , double* t )
00808 {
00809    gint is_in_range = 1;
00810    if ( e && t )
00811    {
00812       if ( (*t) < sed_epoch_end(e) && (*t) >= sed_epoch_start(e) )
00813          is_in_range = 0;
00814    }
00815    return is_in_range;
00816 }
00817 
00818 Sed_epoch
00819 sed_epoch_queue_find( Sed_epoch_queue q , double t )
00820 {
00821    Sed_epoch e = NULL;
00822 
00823    if ( q )
00824    {
00825       GList* l = g_list_find_custom( q->l , &t , (GCompareFunc)sed_epoch_is_in_range );
00826 
00827       if ( l )
00828          e = l->data;
00829    }
00830 
00831    return e;
00832 }
00833 
00834 gssize
00835 sed_epoch_fprint( FILE* fp , Sed_epoch e )
00836 {
00837    gssize n = 0;
00838 
00839    if ( e )
00840    {
00841       gchar* file = (e->filename)?e->filename:"(null)";
00842 
00843       n += fprintf( fp , "[Epoch Info]\n" );
00844 
00845       n += fprintf( fp , "Id           = %f\n" , e->number    );
00846       n += fprintf( fp , "Start        = %f\n" , e->start     );
00847       n += fprintf( fp , "Duration     = %f\n" , e->duration  );
00848 
00849       n += fprintf( fp , "Time step    = %f  " , e->time_step );
00850       n += fprintf( fp , "# NOTE: A river file may override this time step!\n" );
00851 
00852       n += fprintf( fp , "Process file = %s\n" , file         );
00853 
00854 
00855    }
00856    return n;
00857 }
00858 
00859 gssize
00860 sed_epoch_queue_fprint( FILE* fp , Sed_epoch_queue q )
00861 {
00862    gssize n = 0;
00863 
00864    if ( q )
00865    {
00866       GList* link;
00867 
00868       for ( link=q->l ; link ; link=link->next )
00869       {
00870          n += sed_epoch_fprint( fp , link->data );
00871       }
00872 
00873    }
00874 
00875    return n;
00876 }
00877 
00878 Sed_epoch
00879 sed_epoch_scan_proc_queue( Sed_epoch          e          ,
00880                            Sed_process_init_t p_list[]   ,
00881                            Sed_process_family p_family[] ,
00882                            Sed_process_check  p_check[]  ,
00883                            GError** error )
00884 {
00885    eh_require( e );
00886 
00887    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00888 
00889    if ( e )
00890    {
00891       GError* tmp_err = NULL;
00892 
00893       e->proc_q  = sed_process_queue_init( sed_epoch_filename(e) , p_list , p_family , p_check , &tmp_err );
00894       if ( tmp_err )
00895          g_propagate_error( error , tmp_err );
00896    }
00897 
00898    return e;
00899 }
00900 
00901 Sed_epoch_queue
00902 sed_epoch_queue_set_processes( Sed_epoch_queue    q          ,
00903                                Sed_process_init_t p_list[]   ,
00904                                Sed_process_family p_family[] ,
00905                                Sed_process_check  p_check[]  ,
00906                                GError** error )
00907 {
00908    eh_require( q );
00909    eh_return_val_if_fail( error==NULL || *error==NULL , NULL );
00910 
00911    if ( q )
00912    {
00913       GList* l;
00914       GError* tmp_err = NULL;
00915 
00916       for ( l=q->l ; !tmp_err && l ; l=l->next )
00917          sed_epoch_scan_proc_queue( l->data , p_list , p_family , p_check , &tmp_err );
00918 
00919       if ( tmp_err ) g_propagate_error( error , tmp_err );
00920    } 
00921    return q;
00922 }
00923 
00924 gboolean
00925 sed_epoch_queue_test_run( const Sed_epoch_queue q          ,
00926                           Sed_process_init_t    p_list[]   ,
00927                           Sed_process_family    p_family[] ,
00928                           Sed_process_check     p_check[]  ,
00929                           GError**              error )
00930 {
00931    gboolean is_ok = FALSE;
00932 
00933    eh_require( q      );
00934    eh_require( p_list );
00935    eh_return_val_if_fail( error==NULL || *error==NULL , FALSE );
00936 
00937    if ( q && p_list )
00938    {
00939       GError*           tmp_err = NULL;
00940       Sed_epoch_queue   epoch_q = sed_epoch_queue_dup( q );
00941       Sed_process_queue proc_q;
00942       Sed_epoch         epoch;
00943 
00944       for ( epoch = sed_epoch_queue_pop( epoch_q ) ;
00945             epoch && !tmp_err ;
00946             epoch = sed_epoch_queue_pop( epoch_q ) )
00947          proc_q  = sed_process_queue_init( sed_epoch_filename(epoch) , p_list , p_family , p_check , &tmp_err );
00948 
00949       if ( tmp_err )
00950       {
00951          g_propagate_error( error , tmp_err );
00952          is_ok = FALSE;
00953       }
00954       else
00955          is_ok = TRUE;
00956 
00957       sed_epoch_queue_destroy( epoch_q );
00958    }
00959 
00960    return is_ok;
00961 }
00962 
00963 Sed_epoch_queue
00964 sed_epoch_queue_run( Sed_epoch_queue q , Sed_cube p )
00965 {
00966    eh_require( q );
00967    eh_require( p );
00968 
00969    if ( q && p )
00970    {
00971       Sed_process_queue proc_q;
00972       Sed_epoch         epoch;
00973 
00974       for ( epoch = sed_epoch_queue_pop( q ) ;
00975             epoch && !sed_signal_is_pending( SED_SIG_QUIT ) ;
00976             epoch = sed_epoch_queue_pop( q ) )
00977       {
00978          proc_q = sed_epoch_proc_queue( epoch );
00979 
00980          if ( proc_q )
00981          {
00982             sed_cube_set_time_step( p , sed_epoch_time_step( epoch ) );
00983 
00984             sed_process_queue_run_until ( proc_q , p , sed_epoch_end( epoch ) );
00985             sed_process_queue_run_at_end( proc_q , p );
00986 
00987             sed_process_queue_summary( stdout , proc_q );
00988 
00989             sed_epoch_destroy        ( epoch  );
00990 //            sed_cube_free_river      ( p      );
00991          }
00992          else
00993             eh_require_not_reached();
00994       }
00995    }
00996 
00997    return q;
00998 }
00999 
01000 Sed_epoch_queue
01001 sed_epoch_queue_tic( Sed_epoch_queue   epoch_q ,
01002                      Sed_cube          p       )
01003 {
01004    eh_require( epoch_q );
01005    eh_require( p       );
01006 
01007    if ( epoch_q && p )
01008    {
01009       double            t_start = sed_cube_age( p );
01010       Sed_epoch         epoch   = sed_epoch_queue_find( epoch_q , t_start );
01011       Sed_process_queue proc_q  = sed_epoch_proc_queue( epoch );
01012       double            t_stop  = t_start + sed_epoch_duration( epoch );
01013 
01014       sed_cube_set_time_step( p , sed_epoch_time_step( epoch ) );
01015 
01016       sed_process_queue_run_until( proc_q , p , t_stop );
01017 
01018       if ( t_stop > sed_epoch_end( epoch ) )
01019       {
01020          sed_process_queue_run_at_end( proc_q , p );
01021 
01022          sed_process_queue_summary( stdout , proc_q );
01023 
01024 //         sed_cube_free_river      ( p      );
01025       }
01026    }
01027 
01028    return epoch_q;
01029 }
01030 

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