Show
Ignore:
Timestamp:
04/19/10 12:44:57 (14 years ago)
Author:
mido
Message:

LOG LEVEL improved and hopefully finished

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • library/bdm/base/bdmbase.h

    r896 r907  
    8686        //! Internal global variable storing names of RVs 
    8787        static Array<string> NAMES; 
    88  
    8988        //! TODO 
    9089        const static int BUFFER_STEP; 
    91  
    9290        //! TODO 
    9391        static str2int_map MAP; 
     
    141139        RV() : dsize ( 0 ), len ( 0 ), ids ( 0 ), times ( 0 ) {} 
    142140 
    143         //! Constructor of a single RV with given id 
     141        //! Constructor of a single RV  
    144142        RV ( string name, int sz, int tm = 0 ); 
     143 
     144        //! Constructor of a single nameless RV  
     145        RV ( int sz, int tm = 0 ); 
    145146 
    146147        // compiler-generated copy constructor is used 
     
    295296RV concat ( const RV &rv1, const RV &rv2 ); 
    296297 
     298 
     299//! This class stores a details that will be logged to a logger 
     300template<class T> class log_level_template : public log_level_base { 
     301        //! this is necessary to allow logger to set ids vector appropriately and also to set registered_logger 
     302        friend class logger;  
     303 
     304        //! vector of log IDs - one element for each entry 
     305        ivec ids; 
     306 
     307        //! internal pointer to the logger to which this log_level is registered 
     308        //!  
     309        //! it is set to NULL at the beginning 
     310        logger * registered_logger; 
     311 
     312public: 
     313        //! default constructor 
     314        log_level_template() { 
     315                registered_logger = NULL; 
     316                ids.set_size(  T::log_level_names().length() ); 
     317                ids = -1; 
     318        } 
     319 
     320        //! This method stores a vector to the proper place in registered logger  
     321        void store( const enum T::log_level_enums log_level_enum, const vec &vect ) const 
     322        { 
     323                bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! Use root::log_register(...) method."); 
     324                bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular vector was not added to logger! Use logger::add_vector(...) method."); 
     325                registered_logger->log_vector( ids( log_level_enum ), vect ); 
     326        } 
     327 
     328        //! This method stores a double to the proper place in registered logger  
     329        void store( const enum T::log_level_enums log_level_enum, const double &dbl ) const 
     330        { 
     331                bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method."); 
     332                bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular double was not added to logger! Use logger::add_vector(...) method."); 
     333                registered_logger->log_double( ids( log_level_enum ), dbl ); 
     334        } 
     335 
     336        //! This method stores a Setting obtained by call of UI::save( data, .. ) to the proper place in registered logger  
     337        template<class U> void store( const enum T::log_level_enums log_level_enum, const U data ) const 
     338        {                        
     339                bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method."); 
     340                bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular vector was not added to logger! Use logger::add_setting(...) method."); 
     341                registered_logger->log_setting( ids( log_level_enum ), data); 
     342        } 
     343 
     344 
     345        //! string equivalents of the used enumerations which are filled with a help of #LOG_LEVEL macro within class T 
     346        const Array<string> &names() const 
     347        { 
     348                return T::log_level_names(); 
     349        } 
     350 
     351        //! read only operator for testing  individual fields of log_level 
     352        //! 
     353        //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe 
     354        bool operator [] (const enum T::log_level_enums &log_level_enum ) const 
     355        { 
     356                return values[log_level_enum]; 
     357        } 
     358 
     359        //! operator for setting an individual field of log_level  
     360        //! 
     361        //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe 
     362        bitset<32>::reference operator [] (const enum T::log_level_enums &log_level_enum ) 
     363        { 
     364                return values[log_level_enum]; 
     365        } 
     366}; 
     367 
     368/*! 
     369  \def LOG_LEVEL(classname,...) 
     370  \brief Macro for defining a log_level attribute with a specific set of enumerations related to a specific class  
     371 
     372  This macro has to be called within a class declaration. Its argument \a classname has to correspond to that wrapping class. 
     373  This macro defines a log_level instance which can be modified either directly or by the means of #UI class. 
     374 
     375  One of the main purposes of this macro is to allow variability in using enumerations. By relating them to their names through 
     376  an array of strings, we are no more dependant on their precise ordering. What is more, we can add or remove any without harming  
     377  any applications which are using this library. 
     378 
     379  \todo Write a more detailed explanation including also examples 
     380 
     381  \ref ui 
     382*/ 
     383#define LOG_LEVEL(classname,...) public: enum log_level_enums { __VA_ARGS__ }; log_level_template<classname> log_level; private: friend class log_level_template<classname>; static const Array<string> &log_level_names() { static const Array<string> log_level_names = log_level_base::string2Array( #__VA_ARGS__ ); return log_level_names; } 
     384 
     385 
    297386/*! 
    298387@brief Class for storing results (and semi-results) of an experiment 
     
    301390*/ 
    302391class logger : public root { 
     392private: 
     393        //! this method removes a "log" prefix from a string, i.e., it transforms "logevidence" to "evidence" 
     394        //! 
     395        //! for other cases, it keeps string unchanged 
     396        static string remove_log_prefix_if_possible( string name_with_prefix ); 
    303397protected: 
    304398        //! RVs of all logged variables. 
     
    310404        //! list of Settings for specific ids 
    311405        Array<Setting*> settings; 
    312 public: 
    313         //!Default constructor 
    314         logger ( const string separator0 ) : entries ( 0 ), names ( 0 ), separator ( separator0 ) {} 
    315  
     406 
     407        //! log this instance to Setting 
     408        //! 
     409        //! this method has to be called only through \c log_level class to assure the validity of the passed id 
     410        template<class U> void log_setting ( int id, const U data ) { 
     411                UI::save(data, *settings ( id ) ); 
     412        } 
     413 
     414        //! log this vector  
     415        //! 
     416        //! this method has to be called only through \c log_level class to assure the validity of the passed id 
     417        virtual void log_vector ( int id, const vec &v ) NOT_IMPLEMENTED_VOID; 
     418 
     419        //! log this double 
     420        //! 
     421        //! this method has to be called only through \c log_level class to assure the validity of the passed id 
     422        virtual void log_double ( int id, const double &d ) NOT_IMPLEMENTED_VOID; 
     423 
     424        //! it is necessary to allow log_levels to call log_setting, log_vector and log_double methods 
     425        template<class T> friend class log_level_template; 
     426public: 
    316427        //!separator of prefixes of entries 
    317428        //! 
     
    319430        const string separator; 
    320431 
    321  
    322         //! returns an identifier which will be later needed for calling the \c logit() function 
    323         //! For empty RV it returns -1, this entry will be ignored by \c logit(). 
    324         virtual int add_vector ( const RV &rv, const string &prefix, const string &name = "" ); 
    325  
    326         virtual int add_setting ( const string &prefix ); 
    327  
    328         //! log this vector 
    329         virtual void log_vector ( int id, const vec &v ) = 0; 
    330  
    331         virtual Setting & log_to_setting ( int id ) { 
    332                 return settings ( id )->add ( Setting::TypeGroup ); 
    333         } 
    334         //! log this double 
    335         virtual void logit ( int id, const double &d ) = 0; 
     432        //!Default constructor 
     433        logger ( const string separator ) : entries ( 0 ), names ( 0 ), separator ( separator ) {} 
     434 
     435        //!Destructor calls the finalize method 
     436        ~logger() { 
     437                finalize();  
     438        } 
     439 
     440        //! sets up the ids identifier in the passed log_level instance to permit future calls of the log_level_template<T>::store(...) method 
     441        //! 
     442        //! It also sets a pointer to logger or justify it is correctly assigned from previous call to this procedure  
     443        //! Entries with empty RV will be ignored  
     444        template<class T> void add_vector ( log_level_template<T> &log_level, enum T::log_level_enums const log_level_enum, const RV &rv, const string &prefix ) 
     445        { 
     446                if( !log_level.registered_logger ) 
     447                        log_level.registered_logger = this; 
     448                else 
     449                        bdm_assert_debug ( log_level.registered_logger == this, "This log_level is already registered to another logger!"); 
     450 
     451 
     452                if ( rv._dsize() == 0 )  
     453                        return; 
     454                 
     455                int id = entries.length(); 
     456                string adjusted_name = remove_log_prefix_if_possible( log_level.names()(log_level_enum) ); 
     457                names = concat ( names, prefix + separator + adjusted_name ); // diff 
     458                entries.set_length ( id + 1, true ); 
     459                entries ( id ) = rv; 
     460                log_level.ids(log_level_enum) = id;  
     461        } 
     462 
     463        //! sets up the ids identifier in the passed log_level instance to permit future calls of the log_level_template<T>::store(...) method 
     464        //! 
     465        //! It also sets a pointer to logger or justify it is correctly assigned from previous call to this procedure  
     466        template<class T> void add_setting ( log_level_template<T> &log_level, enum T::log_level_enums const log_level_enum,  const string &prefix ) { 
     467                if( !log_level.registered_logger ) 
     468                        log_level.registered_logger = this; 
     469                else 
     470                        bdm_assert_debug ( log_level.registered_logger == this, "This log_level is already registered to another logger!"); 
     471 
     472                Setting &root = setting_conf.getRoot();  
     473                int id = root.getLength(); //root must be group!! 
     474                settings.set_length ( id + 1, true );                    
     475                string adjusted_name = remove_log_prefix_if_possible( log_level.names()(log_level_enum) ); 
     476                settings ( id ) = &root.add ( prefix + separator + adjusted_name, Setting::TypeList );           
     477                log_level.ids(log_level_enum) = id;  
     478        } 
    336479 
    337480        //! Shifts storage position for another time step. 
     
    339482 
    340483        //! Finalize storing information 
     484        //! 
     485        //! This method is called either directly or via destructor ~logger(), therefore it has to permit repetitive calls for the case it is called twice 
    341486        virtual void finalize() {}; 
    342487 
     
    344489        virtual void init() {}; 
    345490}; 
    346  
    347  
    348491 
    349492//! Class representing function \f$f(x)\f$ of variable \f$x\f$ represented by \c rv 
     
    9071050 
    9081051class DS : public root { 
    909         //! \var log_level_enums dt 
     1052        //! \var log_level_enums logdt 
    9101053        //! TODO DOPLNIT 
    911         LOG_LEVEL(DS, dt); 
     1054 
     1055        //! \var log_level_enums logut  
     1056        //! TODO DOPLNIT 
     1057        LOG_LEVEL(DS,logdt,logut); 
    9121058 
    9131059protected: 
     
    9231069        //! default constructors 
    9241070        DS() : dtsize ( 0 ), utsize ( 0 ), Drv(), Urv(){ 
    925                 log_level[dt] = true; 
     1071                log_level[logdt] = true; 
     1072                log_level[logut] = true; 
    9261073        }; 
    9271074 
     
    9671114                Urv = urv; 
    9681115        } 
     1116 
     1117        void from_setting ( const Setting &set ); 
     1118 
     1119        void validate(); 
    9691120}; 
    9701121