MsPASS C++ API  2.4.3.dev1+g61b06b96
Defines the C++ API for MsPASS
Loading...
Searching...
No Matches
Public Member Functions | List of all members
mspass::utility::AntelopePf Class Reference

C++ object version of a parameter file. More...

#include <AntelopePf.h>

Inheritance diagram for mspass::utility::AntelopePf:
Inheritance graph
[legend]
Collaboration diagram for mspass::utility::AntelopePf:
Collaboration graph
[legend]

Public Member Functions

 AntelopePf ()
 
 AntelopePf (std::string pfbase)
 Construct from a base pf name.
 
 AntelopePf (std::list< std::string > lines)
 Construct from a set of text lines.
 
 AntelopePf (const AntelopePf &parent)
 
std::list< std::string > get_tbl (const std::string key) const
 get a Tbl component by key.
 
AntelopePf get_branch (const std::string key) const
 used for subtrees (nested Arrs in antelope)
 
std::list< std::string > arr_keys () const
 
std::list< std::string > tbl_keys () const
 
Metadata ConvertToMetadata ()
 Return an object with only simple name:value pairs.
 
AntelopePfoperator= (const AntelopePf &parent)
 
void pfwrite (std::ostream &ofs)
 save result in a pf format.
 

Additional Inherited Members

Detailed Description

C++ object version of a parameter file.

This object encapsulates the Antelope concept of a parameter file in a single wrapper. The main constructor is actually act much like the Antelope pfread procedure. Internally this object does not use an antelope Pf at all directly, but it is a child of Metadata. Simple attributes (i.e. key-value pairs) are posted directly to the Metadata associative array (map) container. Note that the parser attempts to guess the type of each value given in the obvious ways (periods imply real numbers, e or E imply real numbers, etc.) but the algorithm used may not be foolproof. The get methods are from the Metadata object. Be warned like the Metadata object the type of an entry for a key can change and will be the last one set. An Antelope Tbl in a pf file is converted to an stl list container of stl::string's that contain the input lines. This is a strong divergence from the tbl interface of Antelope, but one I judged a reasonable modernization. Similarly, Arr's are converted to what I am here calling a "branch". Branches are map indexed containers with the key pointing to nested versions of this sampe object type. This is in keeping with the way Arr's are used in antelope, but with an object flavor instead of the pointer style of pfget_arr. Thus, get_branch returns a AntelopePf object instead of a pointer that has to be memory managed. A final note about this beast is that the entire thing was created with a tacit assumption the object itself is not huge. i.e. this implementation may not scale well if applied to very large (millions) line pf files. This is a job for something like MongoDB. View this as a convenient format for building a Metadata object. Note, a code fragment to use this to create lower level metadata would go like this: AntelopePf pfdata("example"); //parameter file constructor Metadata md(dynamic_cast<Metadata&>(pfdata);

Author
Gary L. Pavlis, Indiana University

This version for MsPASS is derived from a similar thing called a PfStyleMetadata object in antelope contrib.

Constructor & Destructor Documentation

◆ AntelopePf() [1/4]

mspass::utility::AntelopePf::AntelopePf ( )
inline

Default constructor - does nothing.

64: Metadata() {};
Metadata()
Definition Metadata.h:105

◆ AntelopePf() [2/4]

mspass::utility::AntelopePf::AntelopePf ( std::string  pfbase)

Construct from a base pf name.

This constructor acts like the antelope pfread function for parameter files constructed in plain C. A relative base name is first read from the MsPASS data directory when available: MSPASS_HOME/data when MSPASS_HOME is set, or the installed mspasspy package data after the Python extension registers it. A standalone caller without MSPASS_HOME instead starts with the directories defined by PFPATH; if PFPATH is not defined, that path defaults to ".". As with the antelope pfread procedure, the last file read takes precedence, so PFPATH or the current directory can override the MsPASS data file. Further if pfbase begins with a slash (i.e. "/") it is assumed to be the actual file name to read and the PFPATH feature is disabled.

Parameters
pfbaseis the base pf name. Relative names may include or omit the .pf suffix; it is added when absent.
Exceptions
-throws a MsPASSError object with an informative message if constuctor fails for any reason.
325 {
326 try {
328 const bool is_absolute = !pfbase.empty() && pfbase[0] == '/';
329 string pfname(pfbase);
330 if (!is_absolute && (pfname.size() < 3 ||
331 pfname.compare(pfname.size() - 3, 3, ".pf") != 0)) {
332 pfname += ".pf";
333 }
334 if (!is_absolute) {
335 try {
336 pffiles.push_back(data_directory() + "/pf/" + pfname);
337 } catch (const MsPASSError &) {
338 /* A standalone C++ caller without MSPASS_HOME has no package data
339 * directory. Preserve the existing PFPATH/current-directory search.
340 */
341 }
342 }
343 const string envname("PFPATH");
344 char *s = getenv(envname.c_str());
345 /* Test to see if pfbase is an absolute path - if so just use
346 * it and ignore the pfpath feature */
347 if (is_absolute) {
348 pffiles.push_back(pfbase);
349 } else if (s == NULL) {
350 pffiles.push_back(pfname);
351 } else {
352 list<string> pfpath_files = split_pfpath(pfname, s);
353 pffiles.splice(pffiles.end(), pfpath_files);
354 }
355 list<string>::iterator pfptr;
356 int nread;
357
358 for (nread = 0, pfptr = pffiles.begin(); pfptr != pffiles.end(); ++pfptr) {
359 // Skip pf files that do not exist
360 if (access(pfptr->c_str(), R_OK))
361 continue;
362 if (nread == 0) {
363 *this = pfread(*pfptr);
364 } else {
365 AntelopePf pfnext = pfread(*pfptr);
366 this->merge_pfmf(pfnext);
367 }
368 ++nread;
369 }
370 if (nread == 0) {
371 if (s == NULL) {
372 // This was necessary to avoid seg faults when s was a null pointer
373 // which happens when PFPATH is not set
374 throw MsPASSError(string("PFPATH is not defined and default pf=") +
375 pfbase + " was not found",
376 ErrorSeverity::Invalid);
377 } else {
378 throw MsPASSError(string("PFPATH=") + s + " had no pf files matching " +
379 pfbase,
380 ErrorSeverity::Invalid);
381 }
382 }
383 } catch (...) {
384 throw;
385 };
386}
AntelopePf()
Definition AntelopePf.h:64
T get(const std::string key) const
Definition Metadata.h:477

References mspass::utility::Metadata::get().

◆ AntelopePf() [3/4]

mspass::utility::AntelopePf::AntelopePf ( std::list< std::string >  lines)

Construct from a set of text lines.

This is a cruder constructor that could be used for small pf file. Read the contents of a pf file into a vector of lines with each line being one line from the pf. The constructor then sequentially parses this series of lines as it would if reading from a file.

Parameters
linesis the modified version of the text pf file.
192 : Metadata() {
193 const string base_error("AntelopePf constructor: ");
194 list<string>::iterator lptr, end_block;
196 string key, token2;
197 try {
198 for (lptr = alllines.begin(); lptr != alllines.end(); ++lptr) {
199 int i, ival;
201 /* This is redundant, but cost is low for long term stability*/
202 if (is_comment_line(*lptr))
203 continue;
204 /* Older version used a stringstream here but it would not
205 parse string attributes with embedded white space. This
206 revised algorithm will do that. returned pair has the
207 key as first and the string with the key trimmed in second. */
208 /*
209 istringstream is(*lptr);
210 is>>key;
211 is>>token2;
212 */
213 pair<string, string> sl = split_line(*lptr);
214 key = sl.first;
215 token2 = sl.second;
216 PfStyleInputType type_of_this_line = arg_type(token2);
217 switch (type_of_this_line) {
218 /* Note all simple type variables are duplicated in
219 as strings. This is a failsafe mechanism used
220 because Metadata will always fall back to string
221 map if the type specific versions fail. Realize
222 if Metadata changes this will be wasted effort. */
223 case PFMDSTRING:
224 this->put(key, token2);
225 break;
226 case PFMDREAL:
227 this->put(key, token2);
228 this->put(key, atof(token2.c_str()));
229 break;
230 case PFMDINT:
231 /* save ints as both string and int some string
232 values could be all digits. */
233 this->put(key, token2);
234 this->put(key, atoi(token2.c_str()));
235 break;
236 case PFMDBOOL:
237 ival = yesno(token2);
238 if (ival != 0)
239 this->put<bool>(key, true);
240 else
241 this->put<bool>(key, false);
242 break;
243 case PFMDTBL:
244 case PFMDARR:
245 lines_this_block = find_end_block(alllines, lptr);
246 block.clear();
247 /* Skips first and last lines in this loop. first with
248 if and last with termination condition. Note this
249 will cause problem if a curly back is not alone on
250 the last line */
251 for (i = 0; i < (lines_this_block - 1); ++i, ++lptr)
252 if (i > 0)
253 block.push_back(*lptr);
254 if (type_of_this_line == PFMDTBL)
255 pftbls.insert(pair<string, list<string>>(key, block));
256 else {
258 pfbranches.insert(pair<string, AntelopePf>(key, thispfarr));
259 }
260 break;
261 default:
262 throw AntelopePfError(base_error + "Error parsing this line->" + *lptr);
263 }
264 }
265 } catch (...) {
266 throw;
267 };
268}
void put(const std::string key, T val) noexcept
Definition Metadata.h:277

References mspass::utility::Metadata::get(), and mspass::utility::Metadata::put().

◆ AntelopePf() [4/4]

mspass::utility::AntelopePf::AntelopePf ( const AntelopePf parent)

Standard copy constructor.

388 : Metadata(parent) {
389 pftbls = parent.pftbls;
390 pfbranches = parent.pfbranches;
391}

References mspass::utility::Metadata::get().

Member Function Documentation

◆ arr_keys()

list< string > mspass::utility::AntelopePf::arr_keys ( ) const

Return a list of keys for branches (Arrs) in the pf file.

407 {
408 map<string, AntelopePf>::const_iterator iptr;
409 list<string> result;
410 for (iptr = pfbranches.begin(); iptr != pfbranches.end(); ++iptr)
411 result.push_back((*iptr).first);
412 return result;
413}

References mspass::utility::Metadata::get().

◆ ConvertToMetadata()

Metadata mspass::utility::AntelopePf::ConvertToMetadata ( )

Return an object with only simple name:value pairs.

The Metadata parent of this object only handles name:value pairs. The values can, however, be any object boost::any can handle. The documentation says that means it is copy constructable. For now this method returns an object containin the boost::any values. Any Arr and Tbl entries are pushed directly to the output Metadata using boost::any and the two keys defined as const strings at the top of this file (pftbl_key and pfarr_key).

Returns
Metadata sans any Arr and Tbl entries.
430 {
431 try {
432 Metadata result(dynamic_cast<Metadata &>(*this));
433 boost::any aTbl = this->pftbls;
434 // boost::any<map<string,list<string>> aTbl(this->pftbl);
435 boost::any aArr = this->pfbranches;
436 result.put<boost::any>(pftbl_key, aTbl);
437 result.put<boost::any>(pfarr_key, aArr);
438 return result;
439 } catch (...) {
440 throw;
441 };
442}

References mspass::utility::Metadata::get(), and mspass::utility::Metadata::put().

◆ get_branch()

AntelopePf mspass::utility::AntelopePf::get_branch ( const std::string  key) const

used for subtrees (nested Arrs in antelope)

This method is used for nested Arr constructs. This returns a copy of the branch defined by key attached to this object. The original from the parent is retained.

Parameters
keyis the key used to locate this branch.
Returns
a copy of the contents of the branch linked to key.
Exceptions
AntelopePfErrorwill be thrown if the key is not found.
399 {
400 map<string, AntelopePf>::const_iterator iptr;
401 iptr = pfbranches.find(key);
402 if (iptr == pfbranches.end())
403 throw AntelopePfError("get_branch failed trying to find data for key=" +
404 key);
405 return iptr->second;
406}

References mspass::utility::Metadata::get().

◆ get_tbl()

list< string > mspass::utility::AntelopePf::get_tbl ( const std::string  key) const

get a Tbl component by key.

Antelope has the idea of a tbl, which is a list of lines that are parsed independently. This is the get method to extract one of these by its key.

Parameters
keyis the key for the Tbl desired.
Exceptions
AntelopePfErrorwill be thrown if the key is not present.
392 {
394 iptr = pftbls.find(key);
395 if (iptr == pftbls.end())
396 throw AntelopePfError("get_tbl failed trying to find data for key=" + key);
397 return (iptr->second);
398}

References mspass::utility::Metadata::get().

◆ operator=()

Standard assignment operator,

421 {
422 if (this != &parent) {
423 /* This uses a trick to use operator = of the parent object */
425 pftbls = parent.pftbls;
426 pfbranches = parent.pfbranches;
427 }
428 return (*this);
429}
Metadata & operator=(const Metadata &mdold)
Definition Metadata.cc:460

References mspass::utility::Metadata::get(), and mspass::utility::Metadata::operator=().

◆ pfwrite()

void mspass::utility::AntelopePf::pfwrite ( std::ostream &  ofs)

save result in a pf format.

This is functionally equivalent to the Antelope pfwrite procedure, but is a member of this object. A feature of the current implementation is that all simply type parameters will usually be listed twice in the output file. The reason is that the constructor attempts to guess type, but to allow for mistakes all simple parameters are also treated as string variables so get methods are more robust.

Parameters
ofsis a std::ostream (e.g. cout) where the result will be written in pf style. Usually should end in ".pf".

◆ tbl_keys()

list< string > mspass::utility::AntelopePf::tbl_keys ( ) const

Return a list of keys for Tbls in the pf.

414 {
416 list<string> result;
417 for (iptr = pftbls.begin(); iptr != pftbls.end(); ++iptr)
418 result.push_back((*iptr).first);
419 return (result);
420}

References mspass::utility::Metadata::get().


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