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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  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) 2017, University of Utah
  15. * @copyright Copyright (c) 2014, XRI Geophysics, LLC
  16. * @copyright Copyright (c) 2014, Trevor Irons
  17. */
  18. #pragma once
  19. #ifndef HELPER_INC
  20. #define HELPER_INC
  21. #include "lemma.h"
  22. #include "yaml-cpp/yaml.h"
  23. namespace Lemma {
  24. /** \addtogroup LemmaCore
  25. * @{
  26. */
  27. /**
  28. * Convenience function for string conversion
  29. * @param[in] t input value to be converted to string
  30. * @return string representation of input value
  31. */
  32. template <class T>
  33. inline std::string to_string (const T& t) {
  34. std::stringstream ss;
  35. ss << t;
  36. return ss.str();
  37. }
  38. /// convert enums to string saves repeated code useful for YAML serializing
  39. std::string enum2String(const FREQUENCYUNITS& Units);
  40. /// convert enums to string saves repeated code useful for YAML serializing
  41. std::string enum2String(const TIMEUNITS& Units);
  42. /// convert enums to string saves repeated code useful for YAML serializing
  43. std::string enum2String(const MAGUNITS& Units);
  44. /// convert enums to string saves repeated code useful for YAML serializing
  45. std::string enum2String(const TEMPUNITS& Units);
  46. /// convert enums to string saves repeated code useful for YAML serializing
  47. std::string enum2String(const FEMCOILORIENTATION& Units);
  48. /// convert enums to string saves repeated code useful for YAML serializing
  49. std::string enum2String(const ORIENTATION& Units);
  50. /// convert enums to string saves repeated code useful for YAML serializing
  51. std::string enum2String(const FIELDCOMPONENT& Comp);
  52. /// convert enums to string saves repeated code useful for YAML serializing
  53. std::string enum2String(const HANKELTRANSFORMTYPE& Htype);
  54. /// convert enums to string saves repeated code useful for YAML serializing
  55. std::string enum2String(const FIELDCALCULATIONS& Htype);
  56. /// convert enums to string saves repeated code useful for YAML serializing
  57. std::string enum2String(const WINDOWTYPE& Wtype);
  58. // other way around is a template, where template argument lets us know
  59. // which specialisation to use.
  60. template <typename T>
  61. T string2Enum( const std::string& str );
  62. // Handy little class that indents a stream.
  63. // Based on solution provided here, todo may need to add to some managing class which keeps
  64. // track of nesting levels? But perhaps not. A Lemma class will contain pointers to other Lemma
  65. // classes. But those are not specifically listed out.
  66. // http://stackoverflow.com/questions/9599807/how-to-add-indention-to-the-stream-operator
  67. class IndentingOStreambuf : public std::streambuf {
  68. std::streambuf* myDest;
  69. bool myIsAtStartOfLine;
  70. std::string myIndent;
  71. std::ostream* myOwner;
  72. protected:
  73. virtual int overflow( int ch )
  74. {
  75. if ( myIsAtStartOfLine && ch != '\n' ) {
  76. myDest->sputn( myIndent.data(), myIndent.size() );
  77. }
  78. myIsAtStartOfLine = ch == '\n';
  79. return myDest->sputc( ch );
  80. }
  81. public:
  82. explicit IndentingOStreambuf(
  83. std::streambuf* dest, int indent = 4 )
  84. : myDest( dest )
  85. , myIsAtStartOfLine( true )
  86. , myIndent( indent, ' ' )
  87. , myOwner( NULL )
  88. {
  89. }
  90. explicit IndentingOStreambuf(
  91. std::ostream& dest, int indent = 4 )
  92. : myDest( dest.rdbuf() )
  93. , myIsAtStartOfLine( true )
  94. , myIndent( indent, ' ' )
  95. , myOwner( &dest )
  96. {
  97. myOwner->rdbuf( this );
  98. }
  99. virtual ~IndentingOStreambuf()
  100. {
  101. if ( myOwner != NULL ) {
  102. myOwner->rdbuf( myDest );
  103. }
  104. }
  105. };
  106. /** @}*/
  107. } // end namespace Lemma
  108. ///////////////////////////////////////////////////////
  109. // YAML Serializing helper functions. Can we move this into helper.h
  110. namespace YAML {
  111. template<>
  112. struct convert<Lemma::Complex> {
  113. static Node encode(const Lemma::Complex& rhs) {
  114. Node node;
  115. node["real"] = rhs.real();
  116. node["imag"] = rhs.imag();
  117. // No labels
  118. //node.push_back(rhs.real());
  119. //node.push_back(rhs.imag());
  120. node.SetTag( "Complex" ); // too verbose?
  121. return node;
  122. }
  123. static bool decode(const Node& node, Lemma::Complex& rhs) {
  124. // Disabled due to overly verbose output. Just believe...
  125. if( node.Tag() != "Complex" ) {
  126. return false;
  127. }
  128. rhs = Lemma::Complex( node["real"].as<Lemma::Real>(), node["imag"].as<Lemma::Real>() );
  129. // no label style
  130. //rhs = Lemma::Complex( node[0].as<Lemma::Real>(), node[1].as<Lemma::Real>() );
  131. return true;
  132. }
  133. };
  134. template<>
  135. struct convert<Lemma::Vector3Xr> {
  136. static Node encode(const Lemma::Vector3Xr& rhs) {
  137. Node node;
  138. node["size"] = rhs.cols();
  139. //node["rows"] = rhs.rows(); // == 3
  140. for (int ic=0; ic<rhs.cols(); ++ic) {
  141. node[ic].push_back( rhs(0, ic) );
  142. node[ic].push_back( rhs(1, ic) );
  143. node[ic].push_back( rhs(2, ic) );
  144. }
  145. node.SetTag( "Vector3Xr" );
  146. return node;
  147. }
  148. static bool decode(const Node& node, Lemma::Vector3Xr& rhs) {
  149. if( node.Tag() != "Vector3Xr" ) {
  150. return false;
  151. }
  152. rhs.resize( Eigen::NoChange, node["size"].as<int>() );
  153. for (unsigned int ic=0; ic<node.size(); ++ic) {
  154. int ir=0;
  155. for(YAML::const_iterator it=node[ic].begin();it!=node[ic].end();++it) {
  156. rhs(ir, ic) = it->as<Lemma::Real>();
  157. ++ir;
  158. }
  159. }
  160. return true;
  161. }
  162. };
  163. template<>
  164. struct convert<Lemma::VectorXr> {
  165. static Node encode(const Lemma::VectorXr& rhs) {
  166. Node node;
  167. node["size"] = rhs.size();
  168. for (int ic=0; ic<rhs.size(); ++ic) {
  169. node["data"].push_back( rhs(ic) );
  170. }
  171. node.SetTag( "VectorXr" );
  172. return node;
  173. }
  174. static bool decode(const Node& node, Lemma::VectorXr& rhs) {
  175. if( node.Tag() != "VectorXr" ) {
  176. return false;
  177. }
  178. rhs.resize( node["size"].as<int>() );
  179. int ir=0;
  180. for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
  181. rhs(ir) = it->as<Lemma::Real>();
  182. ++ir;
  183. }
  184. return true;
  185. }
  186. };
  187. template<>
  188. struct convert<Lemma::VectorXcr> {
  189. static Node encode(const Lemma::VectorXcr& rhs) {
  190. Node node;
  191. node["size"] = rhs.size();
  192. for (int ic=0; ic<rhs.size(); ++ic) {
  193. node["data"].push_back( rhs(ic) );
  194. }
  195. node.SetTag( "VectorXcr" );
  196. return node;
  197. }
  198. static bool decode(const Node& node, Lemma::VectorXcr& rhs) {
  199. if( node.Tag() != "VectorXcr" ) {
  200. return false;
  201. }
  202. rhs.resize( node["size"].as<int>() );
  203. int ir=0;
  204. for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
  205. rhs(ir) = it->as<Lemma::Complex>();
  206. ++ir;
  207. }
  208. return true;
  209. }
  210. };
  211. template<>
  212. struct convert<Lemma::VectorXi> {
  213. static Node encode(const Lemma::VectorXi& rhs) {
  214. Node node;
  215. node["size"] = rhs.size();
  216. for (int ic=0; ic<rhs.size(); ++ic) {
  217. node["data"].push_back( rhs(ic) );
  218. }
  219. node.SetTag( "VectorXi" );
  220. return node;
  221. }
  222. static bool decode(const Node& node, Lemma::VectorXi& rhs) {
  223. if( node.Tag() != "VectorXi" ) {
  224. return false;
  225. }
  226. rhs.resize( node["size"].as<int>() );
  227. int ir=0;
  228. for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
  229. rhs(ir) = it->as<int>();
  230. ++ir;
  231. }
  232. return true;
  233. }
  234. };
  235. template<>
  236. struct convert<Lemma::Vector3r> {
  237. static Node encode(const Lemma::Vector3r& rhs) {
  238. Node node;
  239. for (int ic=0; ic<rhs.size(); ++ic) {
  240. node["data"].push_back( rhs(ic) );
  241. }
  242. node.SetTag( "Vector3r" );
  243. return node;
  244. }
  245. static bool decode(const Node& node, Lemma::Vector3r& rhs) {
  246. if( node.Tag() != "Vector3r" ) {
  247. return false;
  248. }
  249. int ir=0;
  250. for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
  251. rhs(ir) = it->as<Lemma::Real>();
  252. ++ir;
  253. }
  254. return true;
  255. }
  256. };
  257. template<>
  258. struct convert<Lemma::MatrixXr> {
  259. static Node encode(const Lemma::MatrixXr& rhs) {
  260. Node node;
  261. node["rows"] = rhs.rows();
  262. node["cols"] = rhs.cols();
  263. for (int ir=0; ir<rhs.rows(); ++ir) {
  264. for (int ic=0; ic<rhs.cols(); ++ic) {
  265. node["data"][ir][ic] = rhs(ir,ic);
  266. }
  267. node["data"][ir].SetStyle(YAML::EmitterStyle::Flow);
  268. }
  269. //node.SetStyle(YAML::EmitterStyle::Block);
  270. node.SetTag( "MatrixXr" );
  271. return node;
  272. }
  273. static bool decode(const Node& node, Lemma::MatrixXr& rhs) {
  274. if( node.Tag() != "MatrixXr" ) {
  275. return false;
  276. }
  277. int nc = node["cols"].as<int>();
  278. int nr = node["rows"].as<int>();
  279. rhs.resize(nr, nc);
  280. for (int ir=0; ir<nr; ++ir) {
  281. int ic=0;
  282. for(YAML::const_iterator it=node["data"][ir].begin(); it!=node["data"][ir].end(); ++it) {
  283. rhs(ir,ic) = it->as<Lemma::Real>();
  284. ++ic;
  285. }
  286. }
  287. return true;
  288. }
  289. };
  290. template<>
  291. struct convert<Lemma::MatrixXcr> {
  292. static Node encode(const Lemma::MatrixXcr& rhs) {
  293. Node node;
  294. node["rows"] = rhs.rows();
  295. node["cols"] = rhs.cols();
  296. for (int ir=0; ir<rhs.rows(); ++ir) {
  297. for (int ic=0; ic<rhs.cols(); ++ic) {
  298. node["data"][ir][ic] = rhs(ir,ic);
  299. }
  300. node["data"][ir].SetStyle(YAML::EmitterStyle::Flow);
  301. }
  302. //node.SetStyle(YAML::EmitterStyle::Block);
  303. node.SetTag( "MatrixXcr" );
  304. return node;
  305. }
  306. static bool decode(const Node& node, Lemma::MatrixXcr& rhs) {
  307. if( node.Tag() != "MatrixXcr" ) {
  308. return false;
  309. }
  310. int nc = node["cols"].as<int>();
  311. int nr = node["rows"].as<int>();
  312. rhs.resize(nr, nc);
  313. for (int ir=0; ir<nr; ++ir) {
  314. int ic=0;
  315. for(YAML::const_iterator it=node["data"][ir].begin(); it!=node["data"][ir].end(); ++it) {
  316. rhs(ir,ic) = it->as<Lemma::Complex>();
  317. ++ic;
  318. }
  319. }
  320. return true;
  321. }
  322. };
  323. }
  324. #endif // ----- #ifndef HELPER_INC -----