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 7.5KB

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