Lemma is an Electromagnetics API
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

helper.h 11KB

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