Lemma is an Electromagnetics API
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

helper.h 8.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. /* This file is part of Lemma, a geophysical modelling and inversion API.
  2. * More information is available at http://lemmasoftware.org
  3. */
  4. /* This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  7. */
  8. /**
  9. * @file
  10. * @date 10/02/2014 02:49:55 PM
  11. * @version $Id$
  12. * @author Trevor Irons (ti)
  13. * @email Trevor.Irons@xri-geo.com
  14. * @copyright Copyright (c) 2014, XRI Geophysics, LLC
  15. * @copyright Copyright (c) 2014, Trevor Irons
  16. */
  17. #pragma once
  18. #ifndef HELPER_INC
  19. #define HELPER_INC
  20. #include "lemma.h"
  21. #include "yaml-cpp/yaml.h"
  22. namespace Lemma {
  23. /** \addtogroup LemmaCore
  24. * @{
  25. */
  26. /**
  27. * Convenience function for string conversion
  28. * @param[in] t input value to be converted to string
  29. * @return string representation of input value
  30. */
  31. template <class T>
  32. inline std::string to_string (const T& t) {
  33. std::stringstream ss;
  34. ss << t;
  35. return ss.str();
  36. }
  37. /// convert enums to string saves repeated code useful for YAML serializing
  38. std::string enum2String(const FREQUENCYUNITS& Units);
  39. /// convert enums to string saves repeated code useful for YAML serializing
  40. std::string enum2String(const TIMEUNITS& Units);
  41. /// convert enums to string saves repeated code useful for YAML serializing
  42. std::string enum2String(const MAGUNITS& Units);
  43. /// convert enums to string saves repeated code useful for YAML serializing
  44. std::string enum2String(const TEMPUNITS& Units);
  45. /// convert enums to string saves repeated code useful for YAML serializing
  46. std::string enum2String(const FEMCOILORIENTATION& Units);
  47. /// convert enums to string saves repeated code useful for YAML serializing
  48. std::string enum2String(const ORIENTATION& Units);
  49. /// convert enums to string saves repeated code useful for YAML serializing
  50. std::string enum2String(const FIELDCOMPONENT& Comp);
  51. /// convert enums to string saves repeated code useful for YAML serializing
  52. std::string enum2String(const HANKELTRANSFORMTYPE& Htype);
  53. /// convert enums to string saves repeated code useful for YAML serializing
  54. std::string enum2String(const FIELDCALCULATIONS& Htype);
  55. /// convert enums to string saves repeated code useful for YAML serializing
  56. std::string enum2String(const WINDOWTYPE& Wtype);
  57. // other way around is a template, where template argument lets us know
  58. // which specialisation to use.
  59. template <typename T>
  60. T string2Enum( const std::string& str );
  61. // Handy little class that indents a stream.
  62. // Based on solution provided here, todo may need to add to some managing class which keeps
  63. // track of nesting levels? But perhaps not. A Lemma class will contain pointers to other Lemma
  64. // classes. But those are not specifically listed out.
  65. // http://stackoverflow.com/questions/9599807/how-to-add-indention-to-the-stream-operator
  66. class IndentingOStreambuf : public std::streambuf {
  67. std::streambuf* myDest;
  68. bool myIsAtStartOfLine;
  69. std::string myIndent;
  70. std::ostream* myOwner;
  71. protected:
  72. virtual int overflow( int ch )
  73. {
  74. if ( myIsAtStartOfLine && ch != '\n' ) {
  75. myDest->sputn( myIndent.data(), myIndent.size() );
  76. }
  77. myIsAtStartOfLine = ch == '\n';
  78. return myDest->sputc( ch );
  79. }
  80. public:
  81. explicit IndentingOStreambuf(
  82. std::streambuf* dest, int indent = 4 )
  83. : myDest( dest )
  84. , myIsAtStartOfLine( true )
  85. , myIndent( indent, ' ' )
  86. , myOwner( NULL )
  87. {
  88. }
  89. explicit IndentingOStreambuf(
  90. std::ostream& dest, int indent = 4 )
  91. : myDest( dest.rdbuf() )
  92. , myIsAtStartOfLine( true )
  93. , myIndent( indent, ' ' )
  94. , myOwner( &dest )
  95. {
  96. myOwner->rdbuf( this );
  97. }
  98. virtual ~IndentingOStreambuf()
  99. {
  100. if ( myOwner != NULL ) {
  101. myOwner->rdbuf( myDest );
  102. }
  103. }
  104. };
  105. /** @}*/
  106. } // end namespace Lemma
  107. ///////////////////////////////////////////////////////
  108. // YAML Serializing helper functions. Can we move this into helper.h
  109. namespace YAML {
  110. template<>
  111. struct convert<Lemma::Complex> {
  112. static Node encode(const Lemma::Complex& rhs) {
  113. Node node;
  114. node["real"] = rhs.real();
  115. node["imag"] = rhs.imag();
  116. // No labels
  117. //node.push_back(rhs.real());
  118. //node.push_back(rhs.imag());
  119. node.SetTag( "Complex" ); // too verbose?
  120. return node;
  121. }
  122. static bool decode(const Node& node, Lemma::Complex& rhs) {
  123. // Disabled due to overly verbose output. Just believe...
  124. if( node.Tag() != "Complex" ) {
  125. return false;
  126. }
  127. rhs = Lemma::Complex( node["real"].as<Lemma::Real>(), node["imag"].as<Lemma::Real>() );
  128. // no label style
  129. //rhs = Lemma::Complex( node[0].as<Lemma::Real>(), node[1].as<Lemma::Real>() );
  130. return true;
  131. }
  132. };
  133. template<>
  134. struct convert<Lemma::Vector3Xr> {
  135. static Node encode(const Lemma::Vector3Xr& rhs) {
  136. Node node;
  137. node["size"] = rhs.cols();
  138. //node["rows"] = rhs.rows(); // == 3
  139. for (int ic=0; ic<rhs.cols(); ++ic) {
  140. node[ic].push_back( rhs(0, ic) );
  141. node[ic].push_back( rhs(1, ic) );
  142. node[ic].push_back( rhs(2, ic) );
  143. }
  144. node.SetTag( "Vector3Xr" );
  145. return node;
  146. }
  147. static bool decode(const Node& node, Lemma::Vector3Xr& rhs) {
  148. if( node.Tag() != "Vector3Xr" ) {
  149. return false;
  150. }
  151. rhs.resize( Eigen::NoChange, node["size"].as<int>() );
  152. for (unsigned int ic=0; ic<node.size(); ++ic) {
  153. int ir=0;
  154. for(YAML::const_iterator it=node[ic].begin();it!=node[ic].end();++it) {
  155. rhs(ir, ic) = it->as<Lemma::Real>();
  156. ++ir;
  157. }
  158. }
  159. return true;
  160. }
  161. };
  162. template<>
  163. struct convert<Lemma::VectorXr> {
  164. static Node encode(const Lemma::VectorXr& rhs) {
  165. Node node;
  166. node["size"] = rhs.size();
  167. for (int ic=0; ic<rhs.size(); ++ic) {
  168. node["data"].push_back( rhs(ic) );
  169. }
  170. node.SetTag( "VectorXr" );
  171. return node;
  172. }
  173. static bool decode(const Node& node, Lemma::VectorXr& rhs) {
  174. if( node.Tag() != "VectorXr" ) {
  175. return false;
  176. }
  177. rhs.resize( node["size"].as<int>() );
  178. int ir=0;
  179. for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
  180. rhs(ir) = it->as<Lemma::Real>();
  181. ++ir;
  182. }
  183. return true;
  184. }
  185. };
  186. template<>
  187. struct convert<Lemma::VectorXcr> {
  188. static Node encode(const Lemma::VectorXcr& rhs) {
  189. Node node;
  190. node["size"] = rhs.size();
  191. for (int ic=0; ic<rhs.size(); ++ic) {
  192. node["data"].push_back( rhs(ic) );
  193. }
  194. node.SetTag( "VectorXcr" );
  195. return node;
  196. }
  197. static bool decode(const Node& node, Lemma::VectorXcr& rhs) {
  198. if( node.Tag() != "VectorXcr" ) {
  199. return false;
  200. }
  201. rhs.resize( node["size"].as<int>() );
  202. int ir=0;
  203. for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
  204. rhs(ir) = it->as<Lemma::Complex>();
  205. ++ir;
  206. }
  207. return true;
  208. }
  209. };
  210. template<>
  211. struct convert<Lemma::VectorXi> {
  212. static Node encode(const Lemma::VectorXi& rhs) {
  213. Node node;
  214. node["size"] = rhs.size();
  215. for (int ic=0; ic<rhs.size(); ++ic) {
  216. node["data"].push_back( rhs(ic) );
  217. }
  218. node.SetTag( "VectorXi" );
  219. return node;
  220. }
  221. static bool decode(const Node& node, Lemma::VectorXi& rhs) {
  222. if( node.Tag() != "VectorXi" ) {
  223. return false;
  224. }
  225. rhs.resize( node["size"].as<int>() );
  226. int ir=0;
  227. for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
  228. rhs(ir) = it->as<int>();
  229. ++ir;
  230. }
  231. return true;
  232. }
  233. };
  234. template<>
  235. struct convert<Lemma::Vector3r> {
  236. static Node encode(const Lemma::Vector3r& rhs) {
  237. Node node;
  238. for (int ic=0; ic<rhs.size(); ++ic) {
  239. node[0].push_back( rhs(ic) );
  240. }
  241. node.SetTag( "Vector3r" );
  242. return node;
  243. }
  244. static bool decode(const Node& node, Lemma::Vector3r& rhs) {
  245. if( node.Tag() != "Vector3r" ) {
  246. return false;
  247. }
  248. int ir=0;
  249. for(YAML::const_iterator it=node[0].begin(); it!=node[0].end(); ++it) {
  250. rhs(ir) = it->as<Lemma::Real>();
  251. ++ir;
  252. }
  253. return true;
  254. }
  255. };
  256. }
  257. #endif // ----- #ifndef HELPER_INC -----