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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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. // other way around is a template, where template argument lets us know
  56. // which specialisation to use.
  57. template <typename T>
  58. T string2Enum( const std::string& str );
  59. // Handy little class that indents a stream.
  60. // Based on solution provided here, todo may need to add to some managing class which keeps
  61. // track of nesting levels? But perhaps not. A Lemma class will contain pointers to other Lemma
  62. // classes. But those are not specifically listed out.
  63. // http://stackoverflow.com/questions/9599807/how-to-add-indention-to-the-stream-operator
  64. class IndentingOStreambuf : public std::streambuf {
  65. std::streambuf* myDest;
  66. bool myIsAtStartOfLine;
  67. std::string myIndent;
  68. std::ostream* myOwner;
  69. protected:
  70. virtual int overflow( int ch )
  71. {
  72. if ( myIsAtStartOfLine && ch != '\n' ) {
  73. myDest->sputn( myIndent.data(), myIndent.size() );
  74. }
  75. myIsAtStartOfLine = ch == '\n';
  76. return myDest->sputc( ch );
  77. }
  78. public:
  79. explicit IndentingOStreambuf(
  80. std::streambuf* dest, int indent = 4 )
  81. : myDest( dest )
  82. , myIsAtStartOfLine( true )
  83. , myIndent( indent, ' ' )
  84. , myOwner( NULL )
  85. {
  86. }
  87. explicit IndentingOStreambuf(
  88. std::ostream& dest, int indent = 4 )
  89. : myDest( dest.rdbuf() )
  90. , myIsAtStartOfLine( true )
  91. , myIndent( indent, ' ' )
  92. , myOwner( &dest )
  93. {
  94. myOwner->rdbuf( this );
  95. }
  96. virtual ~IndentingOStreambuf()
  97. {
  98. if ( myOwner != NULL ) {
  99. myOwner->rdbuf( myDest );
  100. }
  101. }
  102. };
  103. /** @}*/
  104. } // end namespace Lemma
  105. ///////////////////////////////////////////////////////
  106. // YAML Serializing helper functions. Can we move this into helper.h
  107. namespace YAML {
  108. template<>
  109. struct convert<Lemma::Complex> {
  110. static Node encode(const Lemma::Complex& rhs) {
  111. Node node;
  112. node["real"] = rhs.real();
  113. node["imag"] = rhs.imag();
  114. // No labels
  115. //node.push_back(rhs.real());
  116. //node.push_back(rhs.imag());
  117. node.SetTag( "Complex" ); // too verbose?
  118. return node;
  119. }
  120. static bool decode(const Node& node, Lemma::Complex& rhs) {
  121. // Disabled due to overly verbose output. Just believe...
  122. if( node.Tag() != "Complex" ) {
  123. return false;
  124. }
  125. rhs = Lemma::Complex( node["real"].as<Lemma::Real>(), node["imag"].as<Lemma::Real>() );
  126. // no label style
  127. //rhs = Lemma::Complex( node[0].as<Lemma::Real>(), node[1].as<Lemma::Real>() );
  128. return true;
  129. }
  130. };
  131. template<>
  132. struct convert<Lemma::Vector3Xr> {
  133. static Node encode(const Lemma::Vector3Xr& rhs) {
  134. Node node;
  135. node["size"] = rhs.cols();
  136. //node["rows"] = rhs.rows(); // == 3
  137. for (int ic=0; ic<rhs.cols(); ++ic) {
  138. node[ic].push_back( rhs(0, ic) );
  139. node[ic].push_back( rhs(1, ic) );
  140. node[ic].push_back( rhs(2, ic) );
  141. }
  142. node.SetTag( "Vector3Xr" );
  143. return node;
  144. }
  145. static bool decode(const Node& node, Lemma::Vector3Xr& rhs) {
  146. if( node.Tag() != "Vector3Xr" ) {
  147. return false;
  148. }
  149. rhs.resize( Eigen::NoChange, node["size"].as<int>() );
  150. for (unsigned int ic=0; ic<node.size(); ++ic) {
  151. int ir=0;
  152. for(YAML::const_iterator it=node[ic].begin();it!=node[ic].end();++it) {
  153. rhs(ir, ic) = it->as<Lemma::Real>();
  154. ++ir;
  155. }
  156. }
  157. return true;
  158. }
  159. };
  160. template<>
  161. struct convert<Lemma::VectorXr> {
  162. static Node encode(const Lemma::VectorXr& rhs) {
  163. Node node;
  164. node["size"] = rhs.size();
  165. for (int ic=0; ic<rhs.size(); ++ic) {
  166. node["data"].push_back( rhs(ic) );
  167. }
  168. node.SetTag( "VectorXr" );
  169. return node;
  170. }
  171. static bool decode(const Node& node, Lemma::VectorXr& rhs) {
  172. if( node.Tag() != "VectorXr" ) {
  173. return false;
  174. }
  175. rhs.resize( node["size"].as<int>() );
  176. int ir=0;
  177. for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
  178. rhs(ir) = it->as<Lemma::Real>();
  179. ++ir;
  180. }
  181. return true;
  182. }
  183. };
  184. template<>
  185. struct convert<Lemma::VectorXcr> {
  186. static Node encode(const Lemma::VectorXcr& rhs) {
  187. Node node;
  188. node["size"] = rhs.size();
  189. for (int ic=0; ic<rhs.size(); ++ic) {
  190. node["data"].push_back( rhs(ic) );
  191. }
  192. node.SetTag( "VectorXcr" );
  193. return node;
  194. }
  195. static bool decode(const Node& node, Lemma::VectorXcr& rhs) {
  196. if( node.Tag() != "VectorXcr" ) {
  197. return false;
  198. }
  199. rhs.resize( node["size"].as<int>() );
  200. int ir=0;
  201. for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
  202. rhs(ir) = it->as<Lemma::Complex>();
  203. ++ir;
  204. }
  205. return true;
  206. }
  207. };
  208. template<>
  209. struct convert<Lemma::VectorXi> {
  210. static Node encode(const Lemma::VectorXi& rhs) {
  211. Node node;
  212. node["size"] = rhs.size();
  213. for (int ic=0; ic<rhs.size(); ++ic) {
  214. node["data"].push_back( rhs(ic) );
  215. }
  216. node.SetTag( "VectorXi" );
  217. return node;
  218. }
  219. static bool decode(const Node& node, Lemma::VectorXi& rhs) {
  220. if( node.Tag() != "VectorXi" ) {
  221. return false;
  222. }
  223. rhs.resize( node["size"].as<int>() );
  224. int ir=0;
  225. for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
  226. rhs(ir) = it->as<int>();
  227. ++ir;
  228. }
  229. return true;
  230. }
  231. };
  232. template<>
  233. struct convert<Lemma::Vector3r> {
  234. static Node encode(const Lemma::Vector3r& rhs) {
  235. Node node;
  236. for (int ic=0; ic<rhs.size(); ++ic) {
  237. node[0].push_back( rhs(ic) );
  238. }
  239. node.SetTag( "Vector3r" );
  240. return node;
  241. }
  242. static bool decode(const Node& node, Lemma::Vector3r& rhs) {
  243. if( node.Tag() != "Vector3r" ) {
  244. return false;
  245. }
  246. int ir=0;
  247. for(YAML::const_iterator it=node[0].begin(); it!=node[0].end(); ++it) {
  248. rhs(ir) = it->as<Lemma::Real>();
  249. ++ir;
  250. }
  251. return true;
  252. }
  253. };
  254. }
  255. #endif // ----- #ifndef HELPER_INC -----