[seiscomp, scanloc] Install, add .gitignore
This commit is contained in:
552
include/seiscomp/datamodel/utils.h
Normal file
552
include/seiscomp/datamodel/utils.h
Normal file
@ -0,0 +1,552 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) gempa GmbH *
|
||||
* All rights reserved. *
|
||||
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
|
||||
* *
|
||||
* GNU Affero General Public License Usage *
|
||||
* This file may be used under the terms of the GNU Affero *
|
||||
* Public License version 3.0 as published by the Free Software Foundation *
|
||||
* and appearing in the file LICENSE included in the packaging of this *
|
||||
* file. Please review the following information to ensure the GNU Affero *
|
||||
* Public License version 3.0 requirements will be met: *
|
||||
* https://www.gnu.org/licenses/agpl-3.0.html. *
|
||||
* *
|
||||
* Other Usage *
|
||||
* Alternatively, this file may be used in accordance with the terms and *
|
||||
* conditions contained in a signed written agreement between you and *
|
||||
* gempa GmbH. *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef SEISCOMP_DATAMODEL_UTIL_H__
|
||||
#define SEISCOMP_DATAMODEL_UTIL_H__
|
||||
|
||||
#include <seiscomp/core/datetime.h>
|
||||
#include <seiscomp/core/exceptions.h>
|
||||
#include <seiscomp/core.h>
|
||||
#include <seiscomp/datamodel/notifier.h>
|
||||
#include <seiscomp/datamodel/object.h>
|
||||
#include <seiscomp/datamodel/types.h>
|
||||
#include <seiscomp/datamodel/creationinfo.h>
|
||||
#include <seiscomp/geo/coordinate.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace Seiscomp {
|
||||
namespace DataModel {
|
||||
|
||||
class Event;
|
||||
class Origin;
|
||||
class Pick;
|
||||
class Inventory;
|
||||
class Network;
|
||||
class Station;
|
||||
class SensorLocation;
|
||||
class Stream;
|
||||
class ConfigStation;
|
||||
class Setup;
|
||||
|
||||
|
||||
SC_SYSTEM_CORE_API std::string eventRegion(const DataModel::Event *);
|
||||
|
||||
|
||||
template <typename T>
|
||||
char objectEvaluationStatusToChar(const T *o) {
|
||||
try {
|
||||
switch ( o->evaluationStatus() ) {
|
||||
case PRELIMINARY:
|
||||
return 'P';
|
||||
case CONFIRMED:
|
||||
return 'C';
|
||||
case REVIEWED:
|
||||
return 'V';
|
||||
case FINAL:
|
||||
return 'F';
|
||||
case REJECTED:
|
||||
return 'X';
|
||||
case REPORTED:
|
||||
return 'R';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch ( ... ) {}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
char objectStatusToChar(const T *o) {
|
||||
char evalStat = objectEvaluationStatusToChar(o);
|
||||
if ( evalStat ) return evalStat;
|
||||
|
||||
try {
|
||||
if ( o->evaluationMode() == MANUAL )
|
||||
return 'M';
|
||||
}
|
||||
catch ( ... ) {}
|
||||
|
||||
return 'A';
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::string objectAgencyID(const T *o) {
|
||||
try {
|
||||
return o->creationInfo().agencyID();
|
||||
}
|
||||
catch ( Core::ValueException & ) {}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::string objectAuthor(const T *o) {
|
||||
try {
|
||||
return o->creationInfo().author();
|
||||
}
|
||||
catch ( Core::ValueException & ) {}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
double quantityUncertainty(const T &o) {
|
||||
try {
|
||||
return o.uncertainty();
|
||||
}
|
||||
catch ( Core::ValueException & ) {
|
||||
return (o.lowerUncertainty() + o.upperUncertainty()) * 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the creation time or modification time of an object.
|
||||
* If no creationInfo is set then it will create an empty
|
||||
* object and set the creation time. If a creationInfo is
|
||||
* present, it will set the modification time if the creation
|
||||
* time is not yet set. Otherwise it sets the creation time.
|
||||
*/
|
||||
template <typename T>
|
||||
void touch(T &o) {
|
||||
Core::Time now = Core::Time::GMT();
|
||||
|
||||
try {
|
||||
CreationInfo &ci = o.creationInfo();
|
||||
try {
|
||||
ci.modificationTime();
|
||||
ci.setModificationTime(now);
|
||||
}
|
||||
catch ( ... ) {
|
||||
// No modification time set
|
||||
try {
|
||||
ci.creationTime();
|
||||
ci.setModificationTime(now);
|
||||
}
|
||||
catch ( ... ) {
|
||||
// No creation time set
|
||||
ci.setCreationTime(now);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( ... ) {
|
||||
o.setCreationInfo(CreationInfo());
|
||||
o.creationInfo().setCreationTime(now);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void touch(T *o) {
|
||||
touch(*o);
|
||||
}
|
||||
|
||||
|
||||
MAKEENUM(
|
||||
InventoryError,
|
||||
EVALUES(
|
||||
NETWORK_CODE_NOT_FOUND,
|
||||
NETWORK_EPOCH_NOT_FOUND,
|
||||
STATION_CODE_NOT_FOUND,
|
||||
STATION_EPOCH_NOT_FOUND,
|
||||
SENSOR_CODE_NOT_FOUND,
|
||||
SENSOR_EPOCH_NOT_FOUND,
|
||||
STREAM_CODE_NOT_FOUND,
|
||||
STREAM_EPOCH_NOT_FOUND
|
||||
),
|
||||
ENAMES(
|
||||
"network code not found",
|
||||
"no matching network epoch found",
|
||||
"station code not found",
|
||||
"no matching station epoch found",
|
||||
"sensor location code not found",
|
||||
"no matching sensor location epoch found",
|
||||
"stream code not found",
|
||||
"no matching stream epoch found"
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
//! Returns the station for a network- and stationcode and
|
||||
//! a time. If the station has not been found nullptr will be returned.
|
||||
SC_SYSTEM_CORE_API
|
||||
Station* getStation(const Inventory *inventory,
|
||||
const std::string &networkCode,
|
||||
const std::string &stationCode,
|
||||
const Core::Time &, InventoryError *error = nullptr);
|
||||
|
||||
//! Returns the sensorlocation for a network-, station- and locationcode and
|
||||
//! a time. If the sensorlocation has not been found nullptr will be returned.
|
||||
SC_SYSTEM_CORE_API
|
||||
SensorLocation* getSensorLocation(const Inventory *inventory,
|
||||
const std::string &networkCode,
|
||||
const std::string &stationCode,
|
||||
const std::string &locationCode,
|
||||
const Core::Time &,
|
||||
InventoryError *error = nullptr);
|
||||
|
||||
//! Returns the stream for a network-, station-, location- and channelcode and
|
||||
//! a time. If the stream has not been found nullptr will be returned.
|
||||
SC_SYSTEM_CORE_API
|
||||
Stream* getStream(const Inventory *inventory,
|
||||
const std::string &networkCode,
|
||||
const std::string &stationCode,
|
||||
const std::string &locationCode,
|
||||
const std::string &channelCode,
|
||||
const Core::Time &,
|
||||
InventoryError *error = nullptr);
|
||||
|
||||
//! Returns the station used for a pick. If the station has not been found
|
||||
//! nullptr will be returned.
|
||||
SC_SYSTEM_CORE_API
|
||||
Station* getStation(const Inventory *inventory, const Pick *pick);
|
||||
|
||||
|
||||
//! Returns the sensor location used for a pick. If the sensor location has
|
||||
//! not been found nullptr will be returned.
|
||||
SC_SYSTEM_CORE_API
|
||||
SensorLocation* getSensorLocation(const Inventory *inventory,
|
||||
const Pick *pick);
|
||||
|
||||
|
||||
//! Returns the stream used for a pick. If the stream has
|
||||
//! not been found nullptr will be returned.
|
||||
Stream* getStream(const Inventory *inventory,
|
||||
const Pick *pick);
|
||||
|
||||
|
||||
struct ThreeComponents {
|
||||
enum Component {
|
||||
Vertical = 0, /* usually Z */
|
||||
FirstHorizontal = 1, /* usually N */
|
||||
SecondHorizontal = 2 /* usually E */
|
||||
};
|
||||
|
||||
Stream *vertical() const { return comps[Vertical]; }
|
||||
Stream *firstHorizontal() const { return comps[FirstHorizontal]; }
|
||||
Stream *secondHorizontal() const { return comps[SecondHorizontal]; }
|
||||
|
||||
ThreeComponents();
|
||||
|
||||
Stream *comps[3];
|
||||
};
|
||||
|
||||
|
||||
//! Returns the best matching stream for the vertical component having
|
||||
//! the stream code set to streamCode (without component code, first two letters).
|
||||
//! The method returns the component with the lowest horizontal dip. If several
|
||||
//! components share the same dip the first one found is returned, e.g. UVW or ABC
|
||||
//! orientations.
|
||||
SC_SYSTEM_CORE_API Stream *
|
||||
getVerticalComponent(const SensorLocation *loc, const char *streamCode, const Core::Time &time);
|
||||
|
||||
//! Returns the best matching streams for the vertical and horizontal components
|
||||
//! having the stream code set to streamCode (without component code, first two letters).
|
||||
//! Returns true if the resulting 3 components are forming an orthogonal system,
|
||||
//! false otherwise.
|
||||
//! The method tries to find 3 orthogonal components and select the first with
|
||||
//! the lowest dip (largest Z value) as vertical. The remaining two are returned
|
||||
//! as 1st horizontal (Y axis or North) and 2nd horizontal (X axis or East)
|
||||
//! respectively.
|
||||
//! NOTE: Each of the comps entries in res can be nullptr.
|
||||
SC_SYSTEM_CORE_API bool
|
||||
getThreeComponents(ThreeComponents &res, const SensorLocation *loc, const char *streamCode, const Core::Time &time);
|
||||
|
||||
//! Returns the number of components existing for a stream group (stream code
|
||||
//! without component code, first two letters) at a given time.
|
||||
SC_SYSTEM_CORE_API int
|
||||
numberOfComponents(const SensorLocation *loc, const char *streamCode, const Core::Time &time);
|
||||
|
||||
|
||||
/**
|
||||
* Looks for a setup which name is [setupName] (or "global" as fallback).
|
||||
* @param configStation The ConfigStation object with Setup's attached
|
||||
* @param setupName The name compared with Setup::name()
|
||||
* @param allowGlobal Defines if "global" is allowed as fallback setup
|
||||
* if setupName has not been found explicitely.
|
||||
* @return The setup if available, nullptr otherwise
|
||||
*/
|
||||
SC_SYSTEM_CORE_API Setup *
|
||||
findSetup(const ConfigStation *configStation, const std::string &setupName,
|
||||
bool allowGlobal = true);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a deep copy of an object including all child objects.
|
||||
*/
|
||||
SC_SYSTEM_CORE_API Object *copy(const Object* obj);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns the id of a network. This is essentially the network code.
|
||||
* @param net The network to get the id from.
|
||||
* @return The id
|
||||
*/
|
||||
SC_SYSTEM_CORE_API std::string id(const Network *net);
|
||||
|
||||
/**
|
||||
* @brief Returns the id of a station as networkCode + '.' + stationCode.
|
||||
*
|
||||
* @param sta The station to get the id from.
|
||||
* @return The id
|
||||
*/
|
||||
SC_SYSTEM_CORE_API std::string id(const Station *sta);
|
||||
|
||||
/**
|
||||
* @brief Returns the id of a sensor location as
|
||||
* networkCode + '.' + stationCode + '.' + locationCode.
|
||||
*
|
||||
* If any of the parent objects is not set then \p unsetCode is used for
|
||||
* the corresponding code.
|
||||
*
|
||||
* @param loc The sensor location to get the id from.
|
||||
* @param unsetCode The code used if a parent object is not set or if \p loc is null
|
||||
* @return The id
|
||||
*/
|
||||
SC_SYSTEM_CORE_API std::string id(const SensorLocation *loc,
|
||||
const char *unsetCode = "");
|
||||
|
||||
/**
|
||||
* @brief Returns the id of a stream as
|
||||
* networkCode + '.' + stationCode + '.' + locationCode + '.' + streamCode
|
||||
*
|
||||
* If any of the parent objects is not set then \p unsetCode is used for
|
||||
* the corresponding code.
|
||||
*
|
||||
* @param loc The stream to get the id from.
|
||||
* @param unsetCode The code used if a parent object is not set or if \p stream is null
|
||||
* @param includeComponent Whether to include the component code or not. The
|
||||
* component code is the last character of the stream
|
||||
* code.
|
||||
* @return The id
|
||||
*/
|
||||
SC_SYSTEM_CORE_API std::string id(const Stream *stream,
|
||||
const char *unsetCode = "",
|
||||
bool includeComponent = true);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Retrieves the geo coordinate (WGS84) from a station.
|
||||
*
|
||||
* This requires that the station has both latitude and longitude attributes
|
||||
* set. If any of the attributes is unset then an exception is thrown.
|
||||
*
|
||||
* @param sta The station to get the coordinate from
|
||||
* @return The geo coordinate of the station
|
||||
*/
|
||||
SC_SYSTEM_CORE_API Geo::GeoCoordinate getLocation(const Station *sta);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the geo coordinate (WGS84) from a sensor location.
|
||||
*
|
||||
* This requires that either the sensor location or the parent station has
|
||||
* the latitude as well as longitude set. If one attribute is not set in
|
||||
* the sensor location then the parent station will be lookup up.
|
||||
* If any of the attributes cannot be extracted then an exception is thrown.
|
||||
*
|
||||
* @param loc The sensor location to get the coordinate from
|
||||
* @return The geo coordinate of the sensor location
|
||||
*/
|
||||
SC_SYSTEM_CORE_API Geo::GeoCoordinate getLocation(const SensorLocation *loc);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the geo coordinate (WGS84) from a stream.
|
||||
*
|
||||
* This looks up the location of the parent sensor location which must be set.
|
||||
* If it is incomplete or unset then the parent station of the sensor location
|
||||
* will be lookup up.
|
||||
* If any of the attributes cannot be extracted then an exception is thrown.
|
||||
*
|
||||
* @param coord The output geo location
|
||||
* @param stream The stream to get the location from
|
||||
* @return Success flag
|
||||
*/
|
||||
SC_SYSTEM_CORE_API Geo::GeoCoordinate getLocation(const Stream *stream);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// DataModel Diff
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class SC_SYSTEM_CORE_API DiffMerge {
|
||||
public:
|
||||
DiffMerge();
|
||||
|
||||
|
||||
public:
|
||||
void setLoggingLevel(int level);
|
||||
void showLog(std::ostream &os = std::cerr, int padding = 0,
|
||||
int indent = 1, bool ignoreFirstPad = false);
|
||||
|
||||
/**
|
||||
* Scans a object tree for a particular node. Objects are compared on base of
|
||||
* their indexes, @see equalsIndex
|
||||
* @param tree object tree to scan
|
||||
* @param node item to search for
|
||||
* @return pointer to the item within the object tree or nullptr if the node was
|
||||
* not found
|
||||
*/
|
||||
Object *find(Object *tree, Object *node);
|
||||
|
||||
/**
|
||||
* Recursively compares two objects and collects all differences.
|
||||
* The root element of one of the objects must be included in the other object
|
||||
* tree, @see find(o1, o2)
|
||||
* @param o1 first object to compare
|
||||
* @param o2 second object to compare
|
||||
* @param diffList list to collect differences in
|
||||
* @return true if the diff could be performed, false if one object was null or
|
||||
* no common child object could be found
|
||||
* @throw TypeException if any type restriction is violated
|
||||
*/
|
||||
bool diff(Object *o1, Object *o2, std::vector<NotifierPtr> &diffList);
|
||||
|
||||
/**
|
||||
* Recursively compares two objects and collects all differences.
|
||||
* The root element of one of the objects must be included in the other object
|
||||
* tree, @see find(o1, o2)
|
||||
* @param o1 first object to compare
|
||||
* @param o2 second object to compare
|
||||
* @return A notifier message with all diff notifiers
|
||||
* @throw TypeException if any type restriction is violated
|
||||
*/
|
||||
NotifierMessage *diff2Message(Object *o1, Object *o2);
|
||||
|
||||
/**
|
||||
* Recursively merges the node object (and its children) into the tree object.
|
||||
* The node must be part of the tree, @ref find(o1, o2). Properties of the node
|
||||
* object override properties of the tree.
|
||||
* @param tree main object to merge the node into
|
||||
* @param node object to be merged into the tree
|
||||
* @param idMap map that keeps track of any publicID attribute changes applied
|
||||
* during the merge
|
||||
* @return true if the merge could be performed, false if the node was not found
|
||||
* in the tree
|
||||
* @throw TypeException if any type restriction is violated
|
||||
*/
|
||||
bool merge(Object *tree, Object *node, std::map<std::string, std::string> &idMap);
|
||||
|
||||
/**
|
||||
* Merges all all objects in the vector in order of their appearance into the
|
||||
* mergeResult object, @ref merge(Object*, Object*). The mergeResult object must
|
||||
* be not null and must serve as a parent for the objects being merged. In a
|
||||
* subsequent processing step changes to publicIDs are applied to references,
|
||||
* @ref mapReferences.
|
||||
* @param mergeResult object to merge the vector into
|
||||
* @param objects vector of objects to merge
|
||||
* @return true if all objects could be merged successfully, else false.
|
||||
*/
|
||||
bool merge(Object *mergeResult, const std::vector<Object*> &objects);
|
||||
|
||||
/**
|
||||
* Validates the internal publicID references of the specified object. In a
|
||||
* first step all publicIDs are collected, then the object is traversed top-down
|
||||
* and each reference's value is searched in the publicID set.
|
||||
* @param o object to validate
|
||||
* @return true if all references point to an existing publicID, else false
|
||||
*/
|
||||
bool validateReferences(Object *o);
|
||||
|
||||
/**
|
||||
* Maps publicID references of the specified object. While the object is
|
||||
* traversed top-down, a lookup for each reference in the publicID map is
|
||||
* performed. If a matching entry is found the reference's value is updated.
|
||||
* @param o object which references should be mapped
|
||||
* @param map publicIDMap of deprecated to current publicIDs
|
||||
* @return number of mappings performed
|
||||
*/
|
||||
size_t mapReferences(Object *o, const std::map<std::string, std::string> &publicIDMap);
|
||||
|
||||
bool compareObjects(const Object *o1, const Object *o2);
|
||||
|
||||
|
||||
private:
|
||||
std::string getPublicID(Object* o);
|
||||
void diffRecursive(Object *o1, Object *o2, const std::string &o1ParentID,
|
||||
std::vector<NotifierPtr> &diffList);
|
||||
|
||||
bool equalsIndex(Object *o1, Object *o2);
|
||||
bool compareNonArrayProperty(const Core::BaseObject *o1, const Core::BaseObject *o2);
|
||||
bool compareNonArrayProperty(const Core::MetaProperty* prop,
|
||||
const Core::BaseObject *o1, const Core::BaseObject *o2);
|
||||
void mergeRecursive(Object *o1, Object *o2,
|
||||
std::map<std::string, std::string> &idMap);
|
||||
|
||||
|
||||
private:
|
||||
DEFINE_SMARTPOINTER(LogNode);
|
||||
class LogNode: public Core::BaseObject {
|
||||
private:
|
||||
LogNode *_parent;
|
||||
std::string _title;
|
||||
|
||||
// Logging level
|
||||
// 2 Logs all (Default)
|
||||
// 1 Logs only differences
|
||||
// 0 Logs none - no messages are accepted
|
||||
int _level;
|
||||
std::vector<LogNodePtr> _childs;
|
||||
std::vector<std::string> _messages;
|
||||
|
||||
std::string o2t(const Object *o);
|
||||
void setParent(LogNode *n);
|
||||
void add(std::string s1, std::string n);
|
||||
|
||||
template <class T>
|
||||
std::string compare(T a, T b, bool quotes = false);
|
||||
|
||||
void reset ();
|
||||
|
||||
public:
|
||||
LogNode(const Object* o1, int level);
|
||||
LogNode(std::string title, int level);
|
||||
|
||||
public:
|
||||
template <class T>
|
||||
void add(std::string title, T a, T b);
|
||||
|
||||
void add(std::string title, bool status, std::string comment);
|
||||
void add(std::string title, const Object *o1);
|
||||
LogNodePtr add(LogNodePtr child);
|
||||
|
||||
void show(std::ostream &os, int padding = 0, int indent = 1,
|
||||
bool ignoreFirstPad = false);
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
LogNodePtr _currentNode;
|
||||
int _logLevel;
|
||||
};
|
||||
|
||||
|
||||
} // of ns DataModel
|
||||
} // of ns Seiscomp
|
||||
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user