version  0.0.1
Defines the C++ API for MsPASS
Public Member Functions | Protected Attributes | Friends | List of all members
mspass::utility::Metadata Class Reference
Inheritance diagram for mspass::utility::Metadata:
mspass::utility::BasicMetadata mspass::seismic::Ensemble< T > mspass::seismic::CoreSeismogram mspass::seismic::CoreTimeSeries mspass::seismic::Ensemble< Tdata > mspass::seismic::PowerSpectrum mspass::utility::AntelopePf mspass::seismic::LoggingEnsemble< T > mspass::seismic::Seismogram mspass::seismic::TimeSeries mspass::seismic::SeismogramWGaps mspass::seismic::TimeSeriesWGaps

Public Member Functions

 Metadata ()
 
 Metadata (std::ifstream &ifs, const std::string form=std::string("pf"))
 
 Metadata (const Metadata &mdold)
 
virtual ~Metadata ()
 
Metadataoperator= (const Metadata &mdold)
 
Metadataoperator+= (const Metadata &rhs) noexcept
 
const Metadata operator+ (const Metadata &other) const
 
double get_double (const std::string key) const override
 
int get_int (const std::string key) const override
 
long get_long (const std::string key) const
 
std::string get_string (const std::string key) const override
 
bool get_bool (const std::string key) const override
 
template<typename T >
get (const std::string key) const
 
template<typename T >
get (const char *key) const
 Generic get interface for C char array. More...
 
boost::any get_any (const std::string key) const
 
std::string type (const std::string key) const
 
template<typename T >
void put (const std::string key, T val) noexcept
 
template<typename T >
void put (const char *key, T val) noexcept
 
void put (const std::string key, const double val) override
 
void put (const std::string key, const int val) override
 
void put (const std::string key, const bool val) override
 
void put (const std::string key, const std::string val) override
 
void put (const char *key, const char *val)
 
void put (std::string key, const char *val)
 
void put_object (const std::string key, const pybind11::object val)
 
void put_int (const std::string key, const int val)
 
void put_string (const std::string key, const std::string val)
 
void put_bool (const std::string key, const bool val)
 
void put_double (const std::string key, const double val)
 
void put_long (const std::string key, const long val)
 
void append_chain (const std::string key, const std::string val, const std::string separator=std::string(":"))
 
std::set< std::string > modified () const
 
void clear_modified ()
 Mark all data as unmodified. More...
 
std::set< std::string > keys () const noexcept
 
bool is_defined (const std::string key) const noexcept
 
void erase (const std::string key)
 
std::size_t size () const noexcept
 
std::map< std::string, boost::any >::const_iterator begin () const noexcept
 
std::map< std::string, boost::any >::const_iterator end () const noexcept
 
void change_key (const std::string oldkey, const std::string newkey)
 Change the keyword to access an attribute. More...
 

Protected Attributes

std::map< std::string, boost::any > md
 
std::set< std::string > changed_or_set
 

Friends

pybind11::object serialize_metadata_py (const Metadata &md)
 
Metadata restore_serialized_metadata_py (const pybind11::object &sd)
 
std::ostringstream & operator<< (std::ostringstream &, const mspass::utility::Metadata &)
 

Constructor & Destructor Documentation

◆ Metadata() [1/3]

mspass::utility::Metadata::Metadata ( )
inline

Default constructor. Does nothing.

80 {};

◆ Metadata() [2/3]

mspass::utility::Metadata::Metadata ( std::ifstream &  ifs,
const std::string  form = std::string("pf") 
)

Construct from a file.

This simple file based constructor assumes the file contains only a set lines with this format: key value type where type must be one of: real, integer, bool, or string. Note int is actually always promoted to a long. The optional format variable is there to allow alternative formats in the future.

Parameters
ifs- ifstream from which to read data
format- optional format specification. Currently only default of "text" is accepted.
Exceptions
MsPASSErrorcan be thrown for a variety of conditions.

◆ Metadata() [3/3]

mspass::utility::Metadata::Metadata ( const Metadata mdold)

Standard copy constructor.

Parameters
mdold- parent object to be copied
70  : md(parent.md),changed_or_set(parent.changed_or_set)
71 {
72 }

◆ ~Metadata()

virtual mspass::utility::Metadata::~Metadata ( )
inlinevirtual

Destructor - has to be explicitly implemented and declared virtual for reasons found in textbooks and various web forums. A very subtle feature of C++ inheritance.

104 {};

Member Function Documentation

◆ append_chain()

void mspass::utility::Metadata::append_chain ( const std::string  key,
const std::string  val,
const std::string  separator = std::string(":") 
)

Create or append to a chained string.

A chain conceptually is identical to a list of string data. We implement it in Metadata because sometimes (e.g. MongoDB interaction and some constructs like the unix shell PATH variable) handling a full scale container like list<std::string> would be awkward. If more extensive capability like that is needed it would be better to add a class that inherits Metadata and does so. AntelopePf more or less does this, for example, handling Tbl sections. In any case, this usage is more for one word strings separated by a common separator: e.g. path=/usr/local/bin:/bin uses : as the separator. /usr/local/bin and /bin are the chain.

If the key related to the chain does not yet exist it is silently created. If it already exists and we append to it.

Parameters
keyis the key that defines the string.
valis the the new string to append to the chain
separatoris the string used for a separator (default ":")
Exceptions
MsPASSErrorwill be thrown if data is found in key and it is not of type string.
88 {
89  if(this->is_defined(key))
90  {
91  string typ=this->type(key);
92  if(typ.find("string")==string::npos)
93  throw MsPASSError("Metadata::append_chain: data for key="
94  + key + " is not string type but "+typ
95  + "\nMust be string type to define a valid chain",
96  ErrorSeverity::Invalid);
97  string sval=this->get_string(key);
98  sval += separator;
99  sval += val;
100  this->put(key,sval);
101  }
102  else
103  {
104  this->put(key,val);
105  }
106  changed_or_set.insert(key);
107 }
bool is_defined(const std::string key) const noexcept
Definition: Metadata.cc:73
std::string get_string(const std::string key) const override
Definition: Metadata.h:213

References is_defined().

◆ begin()

std::map< string, boost::any >::const_iterator mspass::utility::Metadata::begin ( ) const
noexcept

Return iterator to beginning of internal map container.

168 {
169  return md.begin();
170 }

◆ change_key()

void mspass::utility::Metadata::change_key ( const std::string  oldkey,
const std::string  newkey 
)

Change the keyword to access an attribute.

Sometimes it is useful to change the key used to access a particular piece of data. Doing so, for example, is one way to implement an alias (alternative name) for something. The entry for the old key is copied to a entry accessible by the new key. The entry for old is then deleted. This avoids downstream inconsistencies a the cost of possible failures from the translation. This method always returns and will silently do nothing if old is not defined. If the new key is already defined, its content will be replaced by the old's.

Parameters
oldkeyis the key to search for to be changed
newkeyis the new key to use for the replacement.
325 {
326  map<string,boost::any>::iterator mdptr;
327  mdptr=md.find(oldkey);
328  /* We silently do nothing if old is not found */
329  if(mdptr!=md.end())
330  {
331  md.insert_or_assign(newkey, mdptr->second);
332  md.erase(mdptr);
333  }
334 }

◆ clear_modified()

void mspass::utility::Metadata::clear_modified ( )
inline

Mark all data as unmodified.

There are situations where it is necessary to clear the data structure used to mark changed metadata. The best example know is when data objects interact with a database and try to do updates. Effort can be wasted in unnecessary updates if metadata are improperly marked as modified. This method clears the entire container that defines changed data.

402  {
403  changed_or_set.clear();
404  };

◆ end()

std::map< string, boost::any >::const_iterator mspass::utility::Metadata::end ( ) const
noexcept

Return iterator to end of internal map container.

172 {
173  return md.end();
174 }

◆ erase()

void mspass::utility::Metadata::erase ( const std::string  key)

Overload for C string

Clear data associated with a particular key.

152 {
153  map<string,boost::any>::iterator iptr;
154  iptr=md.find(key);
155  if(iptr!=md.end())
156  md.erase(iptr);
157  /* Also need to modify this set if the key is found there */
158  set<std::string>::iterator sptr;
159  sptr=changed_or_set.find(key);
160  if(sptr!=changed_or_set.end())
161  changed_or_set.erase(sptr);
162 }

◆ get() [1/2]

template<typename T >
T mspass::utility::Metadata::get ( const char *  key) const
inline

Generic get interface for C char array.

This is a generic interface most useful for template procedures
that need to get a Metadata component.   Since this object only
can contain simple types the type requested must be simple.
Currently supports only int, long, short, double, float, and string.
C char* is intentionally not supported. This is largely a wrapper
on the string key version of this same generic function.

\param key is the name tag of desired component.

\exception - will throw a MetadataGetError (child of MsPASSError) for
   type mismatch or in an overflow or underflow condition.
266  {
267  try{
268  T val;
269  val=get<T>(std::string(key));
270  return val;
271  }catch(...){throw;};
272  }

◆ get() [2/2]

template<typename T >
T mspass::utility::Metadata::get ( const std::string  key) const

Generic get interface.

This is a generic interface most useful for template procedures that need to get a Metadata component. Since this object only can contain simple types the type requested must be simple. Currently supports only int, long, short, double, float, and string. C char* is intentionally not supported. Calls to anything but the supported types will throw an exception.

Parameters
keyis the name tag of desired component.
Exceptions
-will throw a MetadataGetError (child of MsPASSError) for type mismatch or in an overflow or underflow condition.
473 {
474  T result;
475  std::map<std::string,boost::any>::const_iterator iptr;
476  iptr=md.find(key);
477  if(iptr==md.end())
478  {
479  throw MetadataGetError(key,typeid(T).name());
480  }
481  boost::any aval=iptr->second;
482  try{
483  result=boost::any_cast<T>(aval);
484  }catch(boost::bad_any_cast& err)
485  {
486  const std::type_info &ti = aval.type();
487  throw MetadataGetError(err.what(),key,typeid(T).name(),ti.name());
488  };
489  return result;
490 }

◆ get_any()

boost::any mspass::utility::Metadata::get_any ( const std::string  key) const
inline

Get the boost::any container from the Metadata object.

This method is mostly for Python bindings so that a generic get method can work in Python.

Parameters
keyis the name tag of desired component.
Exceptions
-MetadataGetError if requested parameter is not found.
283  {
284  std::map<std::string,boost::any>::const_iterator iptr;
285  iptr=md.find(key);
286  if(iptr==md.end())
287  {
288  throw MetadataGetError(key,typeid(boost::any).name());
289  }
290  return iptr->second;
291  };

◆ get_bool()

bool mspass::utility::Metadata::get_bool ( const std::string  key) const
inlineoverridevirtual

Get a boolean parameter from the Metadata object.

This method never throws an exception assuming that if the requested parameter is not found it is false.

Parameters
keykeyword associated with requested metadata member.

Implements mspass::utility::BasicMetadata.

228  {
229  try{
230  bool val;
231  val=get<bool>(key);
232  return val;
233  }catch(...){throw;};
234  };

◆ get_double()

double mspass::utility::Metadata::get_double ( const std::string  key) const
inlineoverridevirtual

Get a real number from the Metadata object.

Exceptions
MetadataGetErrorif requested parameter is not found or there is a type mismatch.
Parameters
keykeyword associated with requested metadata member.

Implements mspass::utility::BasicMetadata.

135  {
136  try{
137  double val;
138  val=get<double>(key);
139  return val;
140  }catch(MetadataGetError& merr)
141  {
142  /* Try a float if that failed */
143  try{
144  float fval;
145  fval=get<float>(key);
146  return fval;
147  }catch(MetadataGetError& merr)
148  {
149  throw merr;
150  }
151  }
152  };

◆ get_int()

int mspass::utility::Metadata::get_int ( const std::string  key) const
inlineoverridevirtual

Get an integer from the Metadata object.

Exceptions
MetadataGetErrorif requested parameter is not found or there is a type mismatch.
Parameters
keykeyword associated with requested metadata member.

Implements mspass::utility::BasicMetadata.

160  {
161  try{
162  int val;
163  val=get<int>(key);
164  return val;
165  }
166  catch(MetadataGetError& merr)
167  {
168  try{
169  long lval;
170  lval=get<long>(key);
171  return static_cast<int>(lval);
172  }catch(MetadataGetError& merr)
173  {
174  throw merr;
175  }
176  }
177  };

◆ get_long()

long mspass::utility::Metadata::get_long ( const std::string  key) const
inline

Get a long integer from the Metadata object.

Exceptions
MetadataGetErrorif requested parameter is not found or there is a type mismatch.
Parameters
keykeyword associated with requested metadata member.
185  {
186  try{
187  long val;
188  val=get<long>(key);
189  return val;
190  }
191  catch(MetadataGetError& merr)
192  {
193  try{
194  int ival;
195  ival=get<int>(key);
196  return static_cast<long>(ival);
197  }catch(MetadataGetError& merr)
198  {
199  throw merr;
200  }
201  }
202  };

◆ get_string()

std::string mspass::utility::Metadata::get_string ( const std::string  key) const
inlineoverridevirtual

Get a string from the Metadata object.

Note the string in this case can be quite large. If the string was parsed from an Antelope Pf nested Tbl and Arrs can be extracted this way and parsed with pf routines.

Exceptions
MetadataGetErrorif requested parameter is not found or there is a type mismatch.
Parameters
keykeyword associated with requested metadata member.

Implements mspass::utility::BasicMetadata.

213  {
214  try{
215  std::string val;
216  val=get<std::string>(key);
217  return val;
218  }catch(...){throw;};
219  };

◆ is_defined()

bool mspass::utility::Metadata::is_defined ( const std::string  key) const
noexcept

Test if a key has an associated value. Returns true if a value is defined.

74 {
75  map<string,boost::any>::const_iterator mptr;
76  mptr=md.find(key);
77  if(mptr!=md.end())
78  {
79  return true;
80  }
81  else
82  {
83  return false;
84  }
85 }

◆ keys()

set< string > mspass::utility::Metadata::keys ( ) const
noexcept

Return all keys without any type information.

141 {
142  set<string> result;
143  map<string,boost::any>::const_iterator mptr;
144  for(mptr=md.begin();mptr!=md.end();++mptr)
145  {
146  string key(mptr->first);\
147  result.insert(key);
148  }
149  return result;
150 }

◆ modified()

std::set<std::string> mspass::utility::Metadata::modified ( ) const
inline

Return the keys of all altered Metadata values.

388  {
389  return changed_or_set;
390  };

◆ operator+()

const Metadata mspass::utility::Metadata::operator+ ( const Metadata other) const

Add two Metadata objects. Uses operator+=

135 {
136  Metadata result(*this);
137  result += other;
138  return result;
139 }
Metadata()
Definition: Metadata.h:80

◆ operator+=()

Metadata & mspass::utility::Metadata::operator+= ( const Metadata rhs)
noexcept

Append additional metadata with replacement.

A plus operator implies addition, but this overloading does something very different. A simple way to describe the effect is that on completion the left hand side Metadata object will contain a duplicate of the right hand side plus any attributes in the rhs that were not present on the lhs. Another way to clarify this is to describe the algorithm. We take each attribute on the right and search for it in the lhs. If it is not in the lhs it will be added. If it is there already, the rhs value will replace the old value on the lhs. This is most useful when an algorithm creates a new set of attributes that we want to use in downstream processing but retain all the other attributes.

Parameters
rhsis the new metadata to be insert/replace on the lhs.
119 {
120  if(this!=(&rhs))
121  {
122  /* We depend here upon the map container replacing values associated with
123  existing keys. We mark all entries changes anyway. This is a vastly simpler
124  algorithm than the old SEISPP::Metadata. */
125  map<string,boost::any>::const_iterator rhsptr;
126  for(rhsptr=rhs.md.begin();rhsptr!=rhs.md.end();++rhsptr)
127  {
128  md[rhsptr->first]=rhsptr->second;
129  changed_or_set.insert(rhsptr->first);
130  }
131  }
132  return *this;
133 }

◆ operator=()

Metadata & mspass::utility::Metadata::operator= ( const Metadata mdold)

Standard assignment operator.

Parameters
mdold- parent object to copy
109 {
110  if(this!=(&parent))
111  {
112  md=parent.md;
113  changed_or_set=parent.changed_or_set;
114  }
115  return *this;
116 }

◆ put()

void mspass::utility::Metadata::put ( const char *  key,
const char *  val 
)
inline

Put a C string literal. Requires special handling because it is not copy constructable (see warning in boost docs: https://theboostcpplibraries.com/boost.any

328  {
329  std::string sval(val);
330  this->put<std::string>(key,val);
331  }

◆ size()

std::size_t mspass::utility::Metadata::size ( ) const
noexcept

Overload for C string

Return the size of the internal map container.

164 {
165  return md.size();
166 }

Friends And Related Function Documentation

◆ operator<<

std::ostringstream& operator<< ( std::ostringstream &  ,
const mspass::utility::Metadata  
)
friend

Standard operator for overloading output to a stringstream

◆ restore_serialized_metadata_py

Metadata restore_serialized_metadata_py ( const pybind11::object &  sd)
friend

Unpack serialized Metadata.

This function is the inverse of the serialize function. It recreates a Metadata object serialized previously with the serialize function.

Parameters
sdis the serialized data to be unpacked
Returns
Metadata derived from sd
303 {
304  pybind11::gil_scoped_acquire acquire;
305  try
306  {
307  pybind11::module pickle = pybind11::module::import("pickle");
308  pybind11::object loads = pickle.attr("loads");
309  pybind11::tuple md_dump = loads(s);
310  pybind11::dict md_dict = md_dump[0];
311  pybind11::object md_py = pybind11::module_::import("mspasspy.ccore.utility").attr("Metadata")(md_dict);
312  Metadata md = md_py.cast<Metadata>();
313  md.changed_or_set = md_dump[1].cast<std::set<std::string>>();
314  pybind11::gil_scoped_release release;
315  return md;
316  }
317  catch (...)
318  {
319  pybind11::gil_scoped_release release;
320  throw;
321  };
322 }

◆ serialize_metadata_py

pybind11::object serialize_metadata_py ( const Metadata md)
friend

Serialize Metadata to a python bytes object. This function is needed to support pickle in the python interface. It cast the C++ object to a Python dict and calls pickle against that dict directly to generate a Python bytes object. This may not be the most elegant approach, but it should be bombproof.

Parameters
mdis the Metadata object to be serialized
Returns
pickle serialized data object.
289 {
290  pybind11::gil_scoped_acquire acquire;
291  try{
292  pybind11::dict md_dict = pybind11::cast(md);
293  pybind11::set changed_or_set = pybind11::cast(md.changed_or_set);
294  pybind11::module pickle = pybind11::module::import("pickle");
295  pybind11::object dumps = pickle.attr("dumps");
296  pybind11::object md_dump = dumps(pybind11::make_tuple(md_dict, changed_or_set));
297  pybind11::gil_scoped_release release;
298  return md_dump;
299  }catch(...){pybind11::gil_scoped_release release;throw;};
300 }

The documentation for this class was generated from the following files: