outputmodule.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. ///////////////////////////////////////////////////////////////////////////////////////
  2. /// \file outputmodule.h
  3. /// \brief Base class for output modules and a container class for output modules
  4. ///
  5. /// \author Joe Siltberg
  6. /// $Date: 2018-02-02 18:01:35 +0100 (ven, 02 fév 2018) $
  7. ///
  8. ///////////////////////////////////////////////////////////////////////////////////////
  9. #ifndef LPJ_GUESS_OUTPUT_MODULE_H
  10. #define LPJ_GUESS_OUTPUT_MODULE_H
  11. #include <vector>
  12. #include <string>
  13. #include <map>
  14. #include "outputchannel.h"
  15. class Gridcell;
  16. namespace GuessOutput {
  17. /// Base class for output modules
  18. /**
  19. * An output module should inherit from this class and implement
  20. * the pure virtual functions.
  21. *
  22. * In order for the output module to be used by the framework,
  23. * it must be registered with the REGISTER_OUTPUT_MODULE macro
  24. * (defined and documented below).
  25. */
  26. class OutputModule {
  27. public:
  28. virtual ~OutputModule() {};
  29. /// Called after the instruction file has been read
  30. /**
  31. * If an output module needs to declare its own instruction
  32. * file parameters, it should declare them in its constructor
  33. * (which will be called before the instrction file is read).
  34. *
  35. * Typically, some of the output module's initialization
  36. * can't be done until the instruction file parameters are
  37. * available, and is therefore done in this init function.
  38. */
  39. virtual void init() = 0;
  40. /// Called by the framework at the end of the last day of each simulation year
  41. /** The function should generate simulation results for the year, typically
  42. * by getting values from the gridcell, doing various calculations, and
  43. * sending the results along to the output channel (\see OutputChannel) */
  44. virtual void outannual(Gridcell& gridcell) = 0;
  45. /// Called by the framework at the end of each simulation day
  46. /** Similar to outannual but called every day */
  47. virtual void outdaily(Gridcell& gridcell) = 0;
  48. protected:
  49. /// Help function to define_output_tables, creates one output table
  50. void create_output_table(Table& table,
  51. const char* file,
  52. const ColumnDescriptors& columns);
  53. void close_output_table(Table& table);
  54. };
  55. /// Manages a list of output modules
  56. /**
  57. * Apart from simply storing the output modules,
  58. * this class is also a place for things used by all output
  59. * modules (for instance creating the OutputChannel or
  60. * declaring the 'outputdirectory' parameter).
  61. */
  62. class OutputModuleContainer {
  63. public:
  64. OutputModuleContainer();
  65. ~OutputModuleContainer();
  66. /// Adds an output module to the container
  67. /** The container will deallocate the module when
  68. * the container is destructed.
  69. */
  70. void add(OutputModule* output_module);
  71. /// Calls init on all output modules
  72. /** Should be called after the instruction file has been read */
  73. void init();
  74. /// Calls outannual on all output modules
  75. void outannual(Gridcell& gridcell);
  76. /// Calls outdaily on all output modules
  77. void outdaily(Gridcell& gridcell);
  78. private:
  79. /// The output modules
  80. std::vector<OutputModule*> modules;
  81. /// Instruction file parameter deciding where to create output files
  82. std::string outputdirectory;
  83. /// Instruction file parameter deciding precision of coordinates in output
  84. /** The parameter controls the number of digits after the decimal point */
  85. int coordinates_precision;
  86. };
  87. /// Keeps track of registered output modules
  88. /** Output modules are registered with the REGISTER_OUTPUT_MODULE
  89. * macro defined below. The framework can then use the registry
  90. * to create output modules.
  91. *
  92. * The OutputModuleRegistry is a singleton, meaning there's only
  93. * one instance of this class, which is retrieved with the
  94. * get_instance() member function.
  95. */
  96. class OutputModuleRegistry {
  97. public:
  98. /// Function pointer type
  99. /** For each registered output module, we have a function which
  100. * creates an instance of that output module. The function is
  101. * created by the REGISTER_OUTPUT_MODULE macro below.
  102. */
  103. typedef OutputModule* (*OutputModuleCreator)();
  104. /// Returns the one and only output module registry
  105. static OutputModuleRegistry& get_instance();
  106. /// Registers an output module
  107. /** This function shouldn't be called directly, use the REGISTER_OUTPUT_MODULE
  108. * macro below instead.
  109. */
  110. void register_output_module(const char* name, OutputModuleCreator omc);
  111. /// Creates one instance of each registered module and adds it to a container
  112. void create_all_modules(OutputModuleContainer& container) const;
  113. private:
  114. /// Private constructor to make sure we only have one instance
  115. OutputModuleRegistry() {}
  116. /// Also private to prevent copying
  117. OutputModuleRegistry(const OutputModuleRegistry&);
  118. /// The modules and their names
  119. std::map<std::string, OutputModuleCreator> modules;
  120. };
  121. /// A macro used to register output modules
  122. /** Each output module should use this macro somewhere in their
  123. * cpp file. For instance:
  124. *
  125. * REGISTER_OUTPUT_MODULE("euroflux", EurofluxOutput)
  126. *
  127. * where "euroflux" is the name of the module, and EurofluxOutput is the
  128. * class to associate with that name. The names are currently not used,
  129. * all registered output modules are always used by the framework.
  130. */
  131. #define REGISTER_OUTPUT_MODULE(name, class_name) \
  132. namespace class_name##_registration { \
  133. \
  134. GuessOutput::OutputModule* class_name##_creator() { \
  135. return new class_name();\
  136. }\
  137. \
  138. int dummy() {\
  139. GuessOutput::OutputModuleRegistry::get_instance().register_output_module(name, class_name##_creator); \
  140. return 0;\
  141. }\
  142. \
  143. int x = dummy();\
  144. }
  145. /// The output channel through which all output is sent
  146. /** Currently a global for legacy reasons (in order to not break
  147. * existing outannual functions). Should be a member of
  148. * OutputModuleContainer, which is already responsible for
  149. * creating and destroying the output_channel.
  150. */
  151. extern OutputChannel* output_channel;
  152. }
  153. #endif // LPJ_GUESS_OUTPUT_MODULE_H