123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- /* This file is part of Lemma, a geophysical modelling and inversion API.
- * More information is available at http://lemmasoftware.org
- */
-
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
- /**
- * @file
- * @date 10/02/2014 02:49:55 PM
- * @version $Id$
- * @author Trevor Irons (ti)
- * @email Trevor.Irons@xri-geo.com
- * @copyright Copyright (c) 2017, University of Utah
- * @copyright Copyright (c) 2014, XRI Geophysics, LLC
- * @copyright Copyright (c) 2014, Trevor Irons
- */
-
- #pragma once
-
- #ifndef HELPER_INC
- #define HELPER_INC
-
- #include "lemma.h"
- #include "yaml-cpp/yaml.h"
-
- namespace Lemma {
-
- /** \addtogroup LemmaCore
- * @{
- */
-
- /**
- * Convenience function for string conversion
- * @param[in] t input value to be converted to string
- * @return string representation of input value
- */
- template <class T>
- inline std::string to_string (const T& t) {
- std::stringstream ss;
- ss << t;
- return ss.str();
- }
-
- /// convert enums to string saves repeated code useful for YAML serializing
- std::string enum2String(const FREQUENCYUNITS& Units);
- /// convert enums to string saves repeated code useful for YAML serializing
- std::string enum2String(const TIMEUNITS& Units);
- /// convert enums to string saves repeated code useful for YAML serializing
- std::string enum2String(const MAGUNITS& Units);
- /// convert enums to string saves repeated code useful for YAML serializing
- std::string enum2String(const TEMPUNITS& Units);
- /// convert enums to string saves repeated code useful for YAML serializing
- std::string enum2String(const FEMCOILORIENTATION& Units);
- /// convert enums to string saves repeated code useful for YAML serializing
- std::string enum2String(const ORIENTATION& Units);
- /// convert enums to string saves repeated code useful for YAML serializing
- std::string enum2String(const FIELDCOMPONENT& Comp);
- /// convert enums to string saves repeated code useful for YAML serializing
- std::string enum2String(const HANKELTRANSFORMTYPE& Htype);
- /// convert enums to string saves repeated code useful for YAML serializing
- std::string enum2String(const FIELDCALCULATIONS& Htype);
- /// convert enums to string saves repeated code useful for YAML serializing
- std::string enum2String(const WINDOWTYPE& Wtype);
-
- // other way around is a template, where template argument lets us know
- // which specialisation to use.
- template <typename T>
- T string2Enum( const std::string& str );
-
- // Handy little class that indents a stream.
- // Based on solution provided here, todo may need to add to some managing class which keeps
- // track of nesting levels? But perhaps not. A Lemma class will contain pointers to other Lemma
- // classes. But those are not specifically listed out.
- // http://stackoverflow.com/questions/9599807/how-to-add-indention-to-the-stream-operator
- class IndentingOStreambuf : public std::streambuf {
- std::streambuf* myDest;
- bool myIsAtStartOfLine;
- std::string myIndent;
- std::ostream* myOwner;
- protected:
- virtual int overflow( int ch )
- {
- if ( myIsAtStartOfLine && ch != '\n' ) {
- myDest->sputn( myIndent.data(), myIndent.size() );
- }
- myIsAtStartOfLine = ch == '\n';
- return myDest->sputc( ch );
- }
- public:
- explicit IndentingOStreambuf(
- std::streambuf* dest, int indent = 4 )
- : myDest( dest )
- , myIsAtStartOfLine( true )
- , myIndent( indent, ' ' )
- , myOwner( NULL )
- {
- }
- explicit IndentingOStreambuf(
- std::ostream& dest, int indent = 4 )
- : myDest( dest.rdbuf() )
- , myIsAtStartOfLine( true )
- , myIndent( indent, ' ' )
- , myOwner( &dest )
- {
- myOwner->rdbuf( this );
- }
- virtual ~IndentingOStreambuf()
- {
- if ( myOwner != NULL ) {
- myOwner->rdbuf( myDest );
- }
- }
- };
-
- /** @}*/
-
- } // end namespace Lemma
-
- ///////////////////////////////////////////////////////
- // YAML Serializing helper functions. Can we move this into helper.h
- namespace YAML {
-
- template<>
- struct convert<Lemma::Complex> {
- static Node encode(const Lemma::Complex& rhs) {
- Node node;
- node["real"] = rhs.real();
- node["imag"] = rhs.imag();
-
- // No labels
- //node.push_back(rhs.real());
- //node.push_back(rhs.imag());
-
- node.SetTag( "Complex" ); // too verbose?
- return node;
- }
-
- static bool decode(const Node& node, Lemma::Complex& rhs) {
- // Disabled due to overly verbose output. Just believe...
- if( node.Tag() != "Complex" ) {
- return false;
- }
- rhs = Lemma::Complex( node["real"].as<Lemma::Real>(), node["imag"].as<Lemma::Real>() );
- // no label style
- //rhs = Lemma::Complex( node[0].as<Lemma::Real>(), node[1].as<Lemma::Real>() );
- return true;
- }
-
- };
-
- template<>
- struct convert<Lemma::Vector3Xr> {
- static Node encode(const Lemma::Vector3Xr& rhs) {
- Node node;
- node["size"] = rhs.cols();
- //node["rows"] = rhs.rows(); // == 3
- for (int ic=0; ic<rhs.cols(); ++ic) {
- node[ic].push_back( rhs(0, ic) );
- node[ic].push_back( rhs(1, ic) );
- node[ic].push_back( rhs(2, ic) );
- }
- node.SetTag( "Vector3Xr" );
- return node;
- }
-
- static bool decode(const Node& node, Lemma::Vector3Xr& rhs) {
- if( node.Tag() != "Vector3Xr" ) {
- return false;
- }
- rhs.resize( Eigen::NoChange, node["size"].as<int>() );
- for (unsigned int ic=0; ic<node.size(); ++ic) {
- int ir=0;
- for(YAML::const_iterator it=node[ic].begin();it!=node[ic].end();++it) {
- rhs(ir, ic) = it->as<Lemma::Real>();
- ++ir;
- }
- }
- return true;
- }
- };
-
- template<>
- struct convert<Lemma::VectorXr> {
- static Node encode(const Lemma::VectorXr& rhs) {
- Node node;
- node["size"] = rhs.size();
- for (int ic=0; ic<rhs.size(); ++ic) {
- node["data"].push_back( rhs(ic) );
- }
- node.SetTag( "VectorXr" );
- return node;
- }
-
- static bool decode(const Node& node, Lemma::VectorXr& rhs) {
- if( node.Tag() != "VectorXr" ) {
- return false;
- }
- rhs.resize( node["size"].as<int>() );
- int ir=0;
- for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
- rhs(ir) = it->as<Lemma::Real>();
- ++ir;
- }
- return true;
- }
- };
-
- template<>
- struct convert<Lemma::VectorXcr> {
- static Node encode(const Lemma::VectorXcr& rhs) {
- Node node;
- node["size"] = rhs.size();
- for (int ic=0; ic<rhs.size(); ++ic) {
- node["data"].push_back( rhs(ic) );
- }
- node.SetTag( "VectorXcr" );
- return node;
- }
-
- static bool decode(const Node& node, Lemma::VectorXcr& rhs) {
- if( node.Tag() != "VectorXcr" ) {
- return false;
- }
- rhs.resize( node["size"].as<int>() );
- int ir=0;
- for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
- rhs(ir) = it->as<Lemma::Complex>();
- ++ir;
- }
- return true;
- }
- };
-
-
- template<>
- struct convert<Lemma::VectorXi> {
- static Node encode(const Lemma::VectorXi& rhs) {
- Node node;
- node["size"] = rhs.size();
- for (int ic=0; ic<rhs.size(); ++ic) {
- node["data"].push_back( rhs(ic) );
- }
- node.SetTag( "VectorXi" );
- return node;
- }
-
- static bool decode(const Node& node, Lemma::VectorXi& rhs) {
- if( node.Tag() != "VectorXi" ) {
- return false;
- }
- rhs.resize( node["size"].as<int>() );
- int ir=0;
- for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
- rhs(ir) = it->as<int>();
- ++ir;
- }
- return true;
- }
- };
-
- template<>
- struct convert<Lemma::Vector3r> {
- static Node encode(const Lemma::Vector3r& rhs) {
- Node node;
- for (int ic=0; ic<rhs.size(); ++ic) {
- node["data"].push_back( rhs(ic) );
- }
- node.SetTag( "Vector3r" );
- return node;
- }
-
- static bool decode(const Node& node, Lemma::Vector3r& rhs) {
- if( node.Tag() != "Vector3r" ) {
- return false;
- }
- int ir=0;
- for(YAML::const_iterator it=node["data"].begin(); it!=node["data"].end(); ++it) {
- rhs(ir) = it->as<Lemma::Real>();
- ++ir;
- }
- return true;
- }
- };
-
- template<>
- struct convert<Lemma::MatrixXr> {
- static Node encode(const Lemma::MatrixXr& rhs) {
- Node node;
- node["rows"] = rhs.rows();
- node["cols"] = rhs.cols();
- for (int ir=0; ir<rhs.rows(); ++ir) {
- for (int ic=0; ic<rhs.cols(); ++ic) {
- node["data"][ir][ic] = rhs(ir,ic);
- }
- node["data"][ir].SetStyle(YAML::EmitterStyle::Flow);
- }
- //node.SetStyle(YAML::EmitterStyle::Block);
- node.SetTag( "MatrixXr" );
- return node;
- }
-
- static bool decode(const Node& node, Lemma::MatrixXr& rhs) {
- if( node.Tag() != "MatrixXr" ) {
- return false;
- }
- int nc = node["cols"].as<int>();
- int nr = node["rows"].as<int>();
- rhs.resize(nr, nc);
- for (int ir=0; ir<nr; ++ir) {
- int ic=0;
- for(YAML::const_iterator it=node["data"][ir].begin(); it!=node["data"][ir].end(); ++it) {
- rhs(ir,ic) = it->as<Lemma::Real>();
- ++ic;
- }
- }
- return true;
- }
-
- };
-
- template<>
- struct convert<Lemma::MatrixXcr> {
- static Node encode(const Lemma::MatrixXcr& rhs) {
- Node node;
- node["rows"] = rhs.rows();
- node["cols"] = rhs.cols();
- for (int ir=0; ir<rhs.rows(); ++ir) {
- for (int ic=0; ic<rhs.cols(); ++ic) {
- node["data"][ir][ic] = rhs(ir,ic);
- }
- node["data"][ir].SetStyle(YAML::EmitterStyle::Flow);
- }
- //node.SetStyle(YAML::EmitterStyle::Block);
- node.SetTag( "MatrixXcr" );
- return node;
- }
-
- static bool decode(const Node& node, Lemma::MatrixXcr& rhs) {
- if( node.Tag() != "MatrixXcr" ) {
- return false;
- }
- int nc = node["cols"].as<int>();
- int nr = node["rows"].as<int>();
- rhs.resize(nr, nc);
- for (int ir=0; ir<nr; ++ir) {
- int ic=0;
- for(YAML::const_iterator it=node["data"][ir].begin(); it!=node["data"][ir].end(); ++it) {
- rhs(ir,ic) = it->as<Lemma::Complex>();
- ++ic;
- }
- }
- return true;
- }
-
- };
-
- }
-
- #endif // ----- #ifndef HELPER_INC -----
|