IMP  2.0.1
The Integrative Modeling Platform
kernel/optimizer_state_macros.h
Go to the documentation of this file.
1 /**
2  * \file IMP/kernel/optimizer_state_macros.h
3  * \brief Various general useful macros for IMP.
4  *
5  * Copyright 2007-2013 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_OPTIMIZER_STATE_MACROS_H
10 #define IMPKERNEL_OPTIMIZER_STATE_MACROS_H
11 #include <IMP/kernel/kernel_config.h>
12 #include <IMP/base/value_macros.h>
14 #include "internal/utility.h"
15 #include "OptimizerState.h"
16 
17 
18 //! Define the basics needed for an OptimizerState
19 /** In addition to the methods done by IMP_OBJECT, it declares
20  - IMP::OptimizerState::update()
21 */
22 #define IMP_OPTIMIZER_STATE(Name) \
23  virtual void update(); \
24  IMP_OBJECT(Name)
25 
26 //! Define the basics needed for an OptimizerState which acts every n steps
27 /** Please use IMP::core::PeriodicOptimizerState instead.
28 */
29 #define IMP_PERIODIC_OPTIMIZER_STATE(Name) \
30  virtual void update() { \
31  IMP_OBJECT_LOG; \
32  ++call_number_; \
33  if (call_number_%(skip_+1) ==0) { \
34  do_update(update_number_); \
35  ++update_number_; \
36  } \
37  } \
38  IMP_PROTECTED_METHOD(void, do_update,(unsigned int call_number),,); \
39 public: \
40 /** Called when an optimization begins. It resets the current call number
41  as well as making sure that the last frame is written.*/ \
42  void set_is_optimizing(bool tf) { \
43  if (!tf) { \
44  do_update(update_number_); \
45  ++update_number_; \
46  } \
47  else call_number_=0; \
48  } \
49  IMP_NO_DOXYGEN(void set_skip_steps(unsigned int k) {set_period(k+1);}); \
50  void set_period(unsigned int p) { \
51  IMP_USAGE_CHECK(p>0, "Period must be positive."); \
52  skip_=p-1; call_number_=0; \
53  } \
54  unsigned int get_period() const { \
55  return skip_+1; \
56  } \
57  void reset() { \
58  call_number_=0; \
59  update_number_=0; \
60  } \
61  IMP_OBJECT(Name); \
62  private: \
63  ::IMP::kernel::internal::Counter skip_, call_number_, update_number_ \
64 
65 
66 
67 
68 //! Define a pair of classes to handle saving the model
69 /** This macro defines a class:
70  - NameOptimizerState
71  to handling saving the model in the specified way during
72  optimization and on failures, respectively.
73  \param[in] Name The name to prefix the class names
74  \param[in] args The parentesized arguments to the constructor. The
75  last one should be a string called file_name.
76  \param[in] vars The needed member variables.
77  \param[in] constr The body of the constructor.
78  \param[in] functs Any functions (declaration and definition) to
79  go in the class bodies.
80  \param[in] save_action The action to take to perform the save. The
81  name to save to is know as file_name
82  */
83 #define IMP_MODEL_SAVE(Name, args, vars, constr, functs, save_action) \
84  class Name##OptimizerState: public OptimizerState { \
85  ::IMP::kernel::internal::Counter skip_steps_, call_number_, \
86  update_number_; \
87  std::string file_name_; \
88  vars \
89  IMP_IMPLEMENT_INLINE(virtual void update(), { \
90  if (call_number_%(skip_steps_+1) ==0) { \
91  std::ostringstream oss; \
92  bool formatted=false; \
93  try { \
94  oss << boost::format(file_name_) % update_number_; \
95  formatted=true; \
96  } catch(...){ \
97  } \
98  if (formatted) { \
99  write(oss.str(), false); \
100  } else { \
101  write(file_name_, update_number_!=0); \
102  } \
103  ++update_number_; \
104  } \
105  ++call_number_; \
106  }); \
107  public: \
108 /** Write to a file generated from the passed filename every
109 skip_steps steps. The file_name constructor argument should contain
110 "%1%" if you don't want to write the same file each time.
111 */ \
112  Name##OptimizerState args : \
113  OptimizerState(std::string("Writer to ")+file_name), \
114  file_name_(file_name) {constr} \
115  functs \
116  IMP_NO_DOXYGEN(void set_skip_steps(unsigned int k) {set_period(k+1);}); \
117  void set_period(unsigned int p) { \
118  skip_steps_=p-1; \
119  call_number_=0; \
120  } \
121 void write(std::string file_name, unsigned int call=0, \
122  bool append=false) const { \
123  IMP_UNUSED(call); IMP_UNUSED(append); \
124  save_action \
125  } \
126  private: \
127 IMP_IMPLEMENT(void do_update(unsigned int call_number)); \
128 IMP_OBJECT_METHODS(Name##OptimizerState); \
129  }; \
130 IMP_OBJECTS(Name##OptimizerState, Name##OptimizerStates);
131 
132 
133 #endif /* IMPKERNEL_OPTIMIZER_STATE_MACROS_H */