root/library/bdm/bdmroot.h @ 863

Revision 863, 6.9 kB (checked in by smidl, 14 years ago)

Correction to new log_level -- FIXME - wrong parsing of array<string> in LOG_LEVEL

  • Property svn:eol-style set to native
Line 
1
2/*!
3  \file
4  \brief Bayesian Models (bm) that use Bayes rule to learn from observations
5  \author Vaclav Smidl.
6
7  -----------------------------------
8  BDM++ - C++ library for Bayesian Decision Making under Uncertainty
9
10  Using IT++ for numerical operations
11  -----------------------------------
12*/
13
14#ifndef root_H
15#define root_H
16
17#include <string>
18#include <bitset>
19
20#include "itpp_ext.h"
21#include "bdmerror.h"
22
23#ifdef MEX
24        #include "base/libconfig/lib/libconfig.h++"     
25        // TODO DODELAT A NAHRADIT #include "base/libconfig_mex.h"
26#else
27        #include "base/libconfig/lib/libconfig.h++"
28#endif
29
30
31using namespace libconfig;
32using namespace itpp;
33using namespace std;
34
35namespace bdm {
36       
37//! auxiliary function for debugging
38void UI_DBG (const Setting &S, const string &spc, ostream &out );
39       
40//! level of details that will be logged to a logger
41// DULEZITE TODO - zde musi respektovat aktualne ulozene hodnoty, tj. nacist je, pak pridat
42// ty co se maji v tomto kroku ulozit a pak vse ulozit.. protoze to delame kompozici a ne dedenim  DODELAT
43// ALE HOUBY, TAKHLE TO NEJDE, musime nechat jako samostatny objekt, kazda uroven tedy zvlast,
44// jednoznacne jmeno atd..
45//
46//! information about connection to a logger
47template<class T> class logged_options {
48private:
49        friend class UI;
50
51        //! boolean flags related indicating which details will be logged to a logger
52        bitset<32> values;
53
54        const Array<string> &names() const
55        {
56                return T::option_names();
57        }
58
59public:
60       
61        bool any() const
62        {
63                return values.any();
64        }
65
66        bool operator [] (const enum T::possible_options &option ) const
67        {
68                return values[option];
69        }
70
71        bitset<32>::reference operator [] (const enum T::possible_options &option )
72        {
73                return values[option];
74        }
75};
76
77// MUZEME INTERNE POUZIVAT ENUMY, A KLIDNE MENIT JEJICH PORADI, DIKY TOMUHLE MAKRU SE VZDY NAMAPUJI NA TY SPRAVNE STRINGY
78#define LOG_LEVEL(CLASSNAME,...) private: friend class logged_options<CLASSNAME>; static const Array<string> &__option_names() { static const Array<string> option_names( "{"#__VA_ARGS__" }" ); return option_names; }; public: enum possible_options { __VA_ARGS__ }; logged_options<CLASSNAME> log_level;
79
80//forward declaration
81class logger;
82
83//! information about connection to a logger
84class log_record {
85public:
86        //!remember which logger is registered
87        logger &L;
88        //! vector of log IDs - one element for each entry
89        ivec ids;
90
91        //!default constructor
92        log_record ( logger &L0 ) : L ( L0 ), ids ( 0 ) {}
93};
94
95//! Root class of BDM objects
96class root {
97private:
98        //! It is necessary to allow calling of from_setting and to_setting within the UI class ++ i log_options
99        friend class UI;
100
101        // TODO okomentovat
102        static const Array<string> &option_names() 
103        { 
104                static const Array<string> option_names; 
105                return option_names; 
106        }; 
107
108protected:
109        //! record of connections to the logger
110        log_record* logrec;
111
112        /*!     
113        \brief Read instance properties according the data stored in the Setting structure.
114        It has to be called only through UI class, therefore it is protected
115
116        At the begining of this method, it is obligatory to call
117        the corresponding base::from_setting method. Sometimes, there can be
118        an exception from this rule. If so, the programmer is encouraged
119        to describe the reasons for this exception in the documentation in detail.
120       
121        Then, all the configuration     components should be read through the UI mechanism.
122        Those with UI::SettingPresence set to optional shoud have their defaults fulfilled
123        within the body of this method.
124
125        For instance, declaring a class \c trunk derived from our #root class,
126        the implementation of the from_setting method should look like this
127
128        \code
129
130        public trunk : public root {
131
132                anytype xxx, yyy;
133
134                virtual void from_setting ( const Setting &set ) {
135                        root::from_setting( set );
136                       
137                        UI::get ( xxx, set, "xxx", UI::compulsory );
138
139                        if ( !UI::get ( yyy, set, "yyy", UI::optional ) ) {
140                                ... // here, it is necessary to set the default of attribute yyy                                               
141                        }
142
143                        ... // another stuff related to trunk class
144                }
145
146                ... // other members of this class
147        };
148
149        \endcode
150        */
151        virtual void from_setting ( const Setting &set ) {
152        }
153
154        /*!     
155        \brief  Save all the instance properties into the Setting structure.
156        It has to be called only through UI class, therefore it is protected
157
158        The only obligatory rule concerning the body of this method is to call
159        the corresponding base::to_setting method first.        Sometimes, there can
160        be an exception from this rule. If so, the programmer is encouraged
161        to describe the reasons for this exception in the documentation in detail.
162       
163        For instance, declaring
164        a class \c trunk derived from our #root class, the implementation of
165        the to_setting method should look like this
166
167        \code
168        public trunk : public root {
169
170                anytype xxx;
171
172                virtual void to_setting ( const Setting &set ) {
173                        root::to_setting( set );
174
175                        UI::save ( xxx, set, "xxx" );
176                       
177                        ... // another stuff related directly to trunk class
178
179                }
180
181                ... // other members of this class
182
183        };
184
185        \endcode
186        */
187        virtual void to_setting ( Setting &set ) const {
188        }
189
190public:
191        // TODO okomentovat
192        enum possible_options { };
193
194        //!default constructor
195        root() : logrec ( NULL ) {};
196
197        //! make sure this is a virtual object
198        virtual ~root() {
199                if ( logrec ) delete logrec;
200        }
201
202        //! Returns basic textual info about the current instance
203        virtual string to_string() const {
204                Config C;
205                Setting &set=C.getRoot();
206                this->to_setting(set);
207                ostringstream os;
208                UI_DBG(set, "", os);
209                return os.str();
210        }
211        //! Register itself in a logger, i.e. allocate space for data from this class
212        //! The level of details (parameter \c level ) is individual for each class.
213        virtual void log_register ( logger &L, const string &prefix ) {
214                logrec = new log_record ( L );
215        }
216
217        //! Write current information into the given logger
218        virtual void log_write() const {
219        }
220
221        /*!     
222        \brief  This method checks that all internal structures has been set up correctly.
223
224        It is called automatically after the call of the #from_setting method by the mechanism of the UI class.
225        However, it can be called in any other situation to assure the correctness of an instance.
226       
227        The only obligatory rule concerning the body of this method is to call
228        the corresponding base::validate method first. Sometimes, there can be
229        an exception from this rule. If so, the programmer is encouraged
230        to describe the reasons for this exception in the documentation in detail.     
231       
232        Then, only those checks which are not implemented in the base method
233        are implemented here. For instance, declaring a class \c trunk derived from our
234        #root class, the implementation of the method validate should
235        look like this
236
237        \code
238        public trunk : public root {
239
240                virtual void validate ( ) {
241                        root::validate( );
242
243                        ... // checks related directly to trunk class
244                }
245
246                ... // other members of this class
247
248        };
249
250        \endcode
251
252        */
253        virtual void validate() {
254        }
255
256        //! Virtual method providing deep copy of instances
257        virtual root* _copy() const NOT_IMPLEMENTED(NULL);
258       
259};
260
261}; //namespace
262#endif // root_H
Note: See TracBrowser for help on using the browser.