diff --git a/config/src/config.cpp b/config/src/config.cpp index fe210a41..d8dfe15c 100644 --- a/config/src/config.cpp +++ b/config/src/config.cpp @@ -70,9 +70,6 @@ void Config::loadConfigfile() { configline += currentline; } - logger::log("debug", - "config::load_configfile: read from configfile: " + configline); - // set the whole config line as our current config if (setConfigString(configline) == true) logger::log( diff --git a/doc/GlassConfiguration.md b/doc/GlassConfiguration.md index 0c251453..02d46002 100644 --- a/doc/GlassConfiguration.md +++ b/doc/GlassConfiguration.md @@ -9,7 +9,6 @@ An example `glass_init.d` configuration file: "PickMax": 10000, "SitePickMax": 30, "CorrelationMax": 1000, - "Track": false, "PickDuplicateWindow": 2.5, "NumNucleationThreads": 5, "NumHypoThreads": 5, @@ -90,16 +89,15 @@ detection performance. maximum size is reached, glass will start expiring the oldest correlations from this list as new correlations are received. This value is used for computational performance tuning. -* **Track** - A mostly depreciated flag controlling whether tracking debug -statements are logged. * **PickDuplicateWindow** - The time window (+/-) within which to consider a pick a duplicate of an existing pick from the same station. * **NumNucleationThreads** - The number of nucleation/detection threads to run in glass. This value should always be at least one. The upper limit depends -on local machine capabilities. +on local machine capabilities. This value is used for computational performance +tuning. * **NumHypoThreads** - The number of hypocenter location threads to run in glass. In general this value should be equal to **NumNucleationThreads** to -avoid race conditions. +avoid race conditions. This value is used for computational performance tuning. * **WebBackgroundUpdate** - A flag indicating whether to process station updates to grids on a background thread. If station updates are not processed on a background thread, glass will halt while the updates are processed. diff --git a/glass-app/CMakeLists.txt b/glass-app/CMakeLists.txt index 3361950a..c2978e2c 100644 --- a/glass-app/CMakeLists.txt +++ b/glass-app/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.4) # ----- PROJECT VERSION NUMBER ----- # set (glass-app_VERSION_MAJOR 0) -set (glass-app_VERSION_MINOR 4) +set (glass-app_VERSION_MINOR 5) set (glass-app_VERSION_PATCH 0) # ----- PROJECT ----- # diff --git a/glass-app/input/input.cpp b/glass-app/input/input.cpp index b5122988..4eb1b766 100644 --- a/glass-app/input/input.cpp +++ b/glass-app/input/input.cpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace glass { // Construction/Destruction @@ -240,7 +241,9 @@ bool input::setup(json::Object *config) { "input::setup(): Defaulting to 30 for ShutdownWait"); } else { m_iShutdownWait = (*config)["ShutdownWait"].ToInt(); - logger::log("info", "input::setup(): Using ShutdownWait: " + logger::log( + "info", + "input::setup(): Using ShutdownWait: " + std::to_string(m_iShutdownWait)); } @@ -304,7 +307,7 @@ void input::clear() { } // get next data from input -json::Object* input::getData() { +std::shared_ptr input::getData() { // just get the value from the queue return (m_DataQueue->getDataFromQueue()); } @@ -444,7 +447,7 @@ bool input::readFiles(std::string extension, const std::string &inputdir, continue; // parse the line - json::Object * newdata = parse(extension, line); + std::shared_ptr newdata = parse(extension, line); // validate the data if (validate(extension, newdata) == true) { @@ -493,7 +496,8 @@ bool input::readFiles(std::string extension, const std::string &inputdir, } // parse a json object from an input string -json::Object* input::parse(std::string extension, std::string input) { +std::shared_ptr input::parse(std::string extension, + std::string input) { // choose the parser based on the extension // global pick if (((extension == GPICK_EXTENSION) || (extension == GPICKS_EXTENSION)) @@ -511,7 +515,8 @@ json::Object* input::parse(std::string extension, std::string input) { } // validate a json object -bool input::validate(std::string extension, json::Object* input) { +bool input::validate(std::string extension, + std::shared_ptr input) { // choose the validator based on the extension // global pick if (((extension == GPICK_EXTENSION) || (extension == GPICKS_EXTENSION)) diff --git a/glass-app/input/input.h b/glass-app/input/input.h index 19f68c75..39a0abea 100644 --- a/glass-app/input/input.h +++ b/glass-app/input/input.h @@ -23,6 +23,7 @@ #include #include #include +#include #define GPICK_EXTENSION "gpick" #define GPICKS_EXTENSION "gpicks" @@ -111,7 +112,7 @@ class input : public util::iInput, public util::ThreadBaseClass { * * \return Returns a pointer to a json::Object containing the data. */ - json::Object* getData() override; + std::shared_ptr getData() override; /** * \brief input data count function @@ -261,7 +262,8 @@ class input : public util::iInput, public util::ThreadBaseClass { * \param extension - A std::string containing the extension to parse * \return returns a pointer to a json::Object containing the parsed data */ - virtual json::Object* parse(std::string extension, std::string input); + virtual std::shared_ptr parse(std::string extension, + std::string input); /** * \brief validate data function @@ -272,7 +274,8 @@ class input : public util::iInput, public util::ThreadBaseClass { * \param input - A json::Object containing the data to validate * \return returns true if valid, false otherwise */ - virtual bool validate(std::string extension, json::Object* input); + virtual bool validate(std::string extension, + std::shared_ptr input); /** * \brief cleanup file function diff --git a/glass-app/tests/input_unittest.cpp b/glass-app/tests/input_unittest.cpp index ca937a74..86fd408a 100644 --- a/glass-app/tests/input_unittest.cpp +++ b/glass-app/tests/input_unittest.cpp @@ -4,6 +4,7 @@ #include #include +#include #define CONFIGFILENAME "inputtest.d" #define TESTPATH "testdata" @@ -246,7 +247,7 @@ TEST_F(InputTest, Run) { ASSERT_TRUE(std::ifstream(jsonorigfile).good()) << "jsonorigfile archived"; ASSERT_TRUE(std::ifstream(badfile).good()) << "badfile errored"; - json::Object* data = InputThread->getData(); + std::shared_ptr data = InputThread->getData(); // assert input data ok ASSERT_TRUE(data != NULL) << "input data is not null"; diff --git a/glass-app/tests/output_unittest.cpp b/glass-app/tests/output_unittest.cpp index d55be68c..f0b0271c 100644 --- a/glass-app/tests/output_unittest.cpp +++ b/glass-app/tests/output_unittest.cpp @@ -40,7 +40,7 @@ #define OUTPUT3FILE "0BB39FF59826AA4BA63AAA07FFFE713F.jsondetect" #define RETRACT3FILE "0BB39FF59826AA4BA63AAA07FFFE713F.jsonrtct" -json::Object* GetDataFromFile(std::string filename) { +std::shared_ptr GetDataFromFile(std::string filename) { std::ifstream infile; if (std::ifstream(filename).good() != true) { return (NULL); @@ -64,7 +64,8 @@ json::Object* GetDataFromFile(std::string filename) { // make sure we got valid json if (deserializedJSON.GetType() != json::ValueType::NULLVal) { // convert our resulting value to a json object - json::Object *newdata = new json::Object(deserializedJSON.ToObject()); + std::shared_ptr newdata = std::make_shared( + json::Object(deserializedJSON.ToObject())); return (newdata); } @@ -92,7 +93,7 @@ class AssociatorStub : public util::iAssociator { virtual ~AssociatorStub() { } - void sendToAssociator(json::Object* message) override { + void sendToAssociator(std::shared_ptr &message) override { if (message == NULL) { return; } @@ -110,17 +111,23 @@ class AssociatorStub : public util::iAssociator { } if (id == OUTPUTID) { - Output->sendToOutput(GetDataFromFile(hypofile)); + std::shared_ptr hypo = GetDataFromFile(hypofile); + Output->sendToOutput(hypo); } else if (id == OUTPUT2ID) { if (sentone == false) { - Output->sendToOutput(GetDataFromFile(hypo2file)); + std::shared_ptr hypo2 = GetDataFromFile( + hypo2file); + Output->sendToOutput(hypo2); sentone = true; } else { - Output->sendToOutput(GetDataFromFile(hypo2updatefile)); + std::shared_ptr hypo2Update = GetDataFromFile( + hypo2updatefile); + Output->sendToOutput(hypo2Update); } } else if (id == OUTPUT3ID) { - Output->sendToOutput(GetDataFromFile(hypo3file)); + std::shared_ptr hypo3 = GetDataFromFile(hypo3file); + Output->sendToOutput(hypo3); } } bool sentone; @@ -215,20 +222,24 @@ class OutputTest : public ::testing::Test { bool configurefail2() { // configure fail - return (OutputThread->setup(new json::Object(json::Deserialize(CONFIGFAIL1)))); + return (OutputThread->setup( + new json::Object(json::Deserialize(CONFIGFAIL1)))); } bool configurefail3() { // configure fail - return (OutputThread->setup(new json::Object(json::Deserialize(CONFIGFAIL2)))); + return (OutputThread->setup( + new json::Object(json::Deserialize(CONFIGFAIL2)))); } bool emptyconfig() { // configure empty - return (OutputThread->setup(new json::Object(json::Deserialize(EMPTYCONFIG)))); + return (OutputThread->setup( + new json::Object(json::Deserialize(EMPTYCONFIG)))); } - void CheckData(json::Object * dataone, json::Object * datatwo) { + void CheckData(std::shared_ptr dataone, + std::shared_ptr datatwo) { if (dataone == NULL) { return; } @@ -416,7 +427,7 @@ TEST_F(OutputTest, Output) { // start input thread OutputThread->start(); - json::Object * outputevent = GetDataFromFile(eventfile); + std::shared_ptr outputevent = GetDataFromFile(eventfile); (*outputevent)["CreateTime"] = glassutil::CDate::encodeISO8601Time( glassutil::CDate::now()); (*outputevent)["ReportTime"] = glassutil::CDate::encodeISO8601Time( @@ -432,8 +443,8 @@ TEST_F(OutputTest, Output) { ASSERT_TRUE(std::ifstream(outputfile).good()) << "hypo output file created"; // get the data - json::Object * senthypo = GetDataFromFile(hypofile); - json::Object * outputorigin = GetDataFromFile(outputfile); + std::shared_ptr senthypo = GetDataFromFile(hypofile); + std::shared_ptr outputorigin = GetDataFromFile(outputfile); // check the output data against the input CheckData(senthypo, outputorigin); @@ -446,7 +457,7 @@ TEST_F(OutputTest, Update) { // start input thread OutputThread->start(); - json::Object * outputevent = GetDataFromFile(event2file); + std::shared_ptr outputevent = GetDataFromFile(event2file); (*outputevent)["CreateTime"] = glassutil::CDate::encodeISO8601Time( glassutil::CDate::now()); (*outputevent)["ReportTime"] = glassutil::CDate::encodeISO8601Time( @@ -463,8 +474,8 @@ TEST_F(OutputTest, Update) { << "hypo output file created"; // get the data - json::Object * senthypo2 = GetDataFromFile(hypo2file); - json::Object * output2origin = GetDataFromFile(output2file); + std::shared_ptr senthypo2 = GetDataFromFile(hypo2file); + std::shared_ptr output2origin = GetDataFromFile(output2file); // check the output data against the update CheckData(senthypo2, output2origin); @@ -472,7 +483,7 @@ TEST_F(OutputTest, Update) { //remove output for update std::remove(output2file.c_str()); - json::Object * updateevent = GetDataFromFile(event2updatefile); + std::shared_ptr updateevent = GetDataFromFile(event2updatefile); (*updateevent)["CreateTime"] = glassutil::CDate::encodeISO8601Time( glassutil::CDate::now()); (*updateevent)["ReportTime"] = glassutil::CDate::encodeISO8601Time( @@ -489,8 +500,8 @@ TEST_F(OutputTest, Update) { << "hypo update file created"; // get the data - json::Object * sentupdatehypo2 = GetDataFromFile(hypo2updatefile); - json::Object * output2origin2 = GetDataFromFile(output2file); + std::shared_ptr sentupdatehypo2 = GetDataFromFile(hypo2updatefile); + std::shared_ptr output2origin2 = GetDataFromFile(output2file); // check the output data against the update CheckData(sentupdatehypo2, output2origin2); @@ -503,13 +514,13 @@ TEST_F(OutputTest, Cancel) { // start input thread OutputThread->start(); - json::Object * outputevent = GetDataFromFile(event3file); + std::shared_ptr outputevent = GetDataFromFile(event3file); (*outputevent)["CreateTime"] = glassutil::CDate::encodeISO8601Time( glassutil::CDate::now()); (*outputevent)["ReportTime"] = glassutil::CDate::encodeISO8601Time( glassutil::CDate::now()); - json::Object * cancelmessage = GetDataFromFile(cancel3file); + std::shared_ptr cancelmessage = GetDataFromFile(cancel3file); // add data to output OutputThread->sendToOutput(outputevent); @@ -534,7 +545,7 @@ TEST_F(OutputTest, Retract) { // start input thread OutputThread->start(); - json::Object * outputevent = GetDataFromFile(event3file); + std::shared_ptr outputevent = GetDataFromFile(event3file); (*outputevent)["CreateTime"] = glassutil::CDate::encodeISO8601Time( glassutil::CDate::now()); (*outputevent)["ReportTime"] = glassutil::CDate::encodeISO8601Time( @@ -550,7 +561,7 @@ TEST_F(OutputTest, Retract) { ASSERT_TRUE(std::ifstream(output3file).good()) << "output file created"; - json::Object * cancelmessage = GetDataFromFile(cancel3file); + std::shared_ptr cancelmessage = GetDataFromFile(cancel3file); // send cancel to output OutputThread->sendToOutput(cancelmessage); diff --git a/glass-broker-app/CMakeLists.txt b/glass-broker-app/CMakeLists.txt index 178a12f3..fa8cd68a 100644 --- a/glass-broker-app/CMakeLists.txt +++ b/glass-broker-app/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.4) # ----- PROJECT VERSION NUMBER ----- # set (glass-broker-app_VERSION_MAJOR 0) -set (glass-broker-app_VERSION_MINOR 4) +set (glass-broker-app_VERSION_MINOR 5) set (glass-broker-app_VERSION_PATCH 0) # ----- PROJECT ----- # diff --git a/glass-broker-app/input/input.cpp b/glass-broker-app/input/input.cpp index 5bff6ec7..a18f96ef 100644 --- a/glass-broker-app/input/input.cpp +++ b/glass-broker-app/input/input.cpp @@ -253,7 +253,7 @@ void input::clear() { } // get next data from input -json::Object* input::getData() { +std::shared_ptr input::getData() { // just get the value from the queue return (m_DataQueue->getDataFromQueue()); } @@ -275,7 +275,7 @@ bool input::work() { if (message != "") { logger::log("trace", "input::work(): Got message: " + message); - json::Object* newdata = NULL; + std::shared_ptr newdata; try { newdata = m_JSONParser->parse(message); } catch (const std::exception &e) { diff --git a/glass-broker-app/input/input.h b/glass-broker-app/input/input.h index 146f88ec..a3aa3383 100644 --- a/glass-broker-app/input/input.h +++ b/glass-broker-app/input/input.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace glass { /** @@ -101,7 +102,7 @@ class input : public util::iInput, public util::ThreadBaseClass { * * \return Returns a pointer to a json::Object containing the data. */ - json::Object* getData() override; + std::shared_ptr getData() override; /** * \brief input data count function diff --git a/glasscore/CMakeLists.txt b/glasscore/CMakeLists.txt index 0a59db94..04a1fe19 100644 --- a/glasscore/CMakeLists.txt +++ b/glasscore/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.4) # ----- PROJECT VERSION NUMBER ----- # set (glasscore_VERSION_MAJOR 0) -set (glasscore_VERSION_MINOR 4) +set (glasscore_VERSION_MINOR 5) set (glasscore_VERSION_PATCH 0) # ----- PROJECT ----- # diff --git a/glasscore/glasslib/include/Correlation.h b/glasscore/glasslib/include/Correlation.h index a8e3977f..4a4b099c 100644 --- a/glasscore/glasslib/include/Correlation.h +++ b/glasscore/glasslib/include/Correlation.h @@ -84,7 +84,7 @@ class CCorrelation { * \param correlationId - An integer containing the correlation id to use. * \param pSiteList - A pointer to the CSiteList class */ - CCorrelation(json::Object *correlation, int correlationId, + CCorrelation(std::shared_ptr correlation, int correlationId, CSiteList *pSiteList); /** @@ -142,8 +142,6 @@ class CCorrelation { void addHypo(std::shared_ptr hyp, std::string ass = "", bool force = false); - void setAss(std::string ass); - /** * \brief Remove hypo reference to this correlation * @@ -161,7 +159,97 @@ class CCorrelation { void clearHypo(); - // Local Attributes + /** + * \brief Correlation value getter + * \return the correlation value + */ + double getCorrelation() const; + + /** + * \brief Latitude getter + * \return the latitude + */ + double getLat() const; + + /** + * \brief Longitude getter + * \return the longitude + */ + double getLon() const; + + /** + * \brief Depth getter + * \return the depth + */ + double getZ() const; + + /** + * \brief Origin time getter + * \return the origin time + */ + double getTOrg() const; + + /** + * \brief Correlation id getter + * \return the correlation id + */ + int getIdCorrelation() const; + + /** + * \brief Json correlation getter + * \return the json correlation + */ + const std::shared_ptr& getJCorrelation() const; + + /** + * \brief Hypo getter + * \return the hypo + */ + const std::shared_ptr getHypo() const; + + /** + * \brief Site getter + * \return the site + */ + const std::shared_ptr& getSite() const; + + /** + * \brief Association string getter + * \return the association string + */ + const std::string& getAss() const; + + /** + * \brief Association string setter + * \param ass - the association string + */ + void setAss(std::string ass); + + /** + * \brief Phase getter + * \return the phase + */ + const std::string& getPhs() const; + + /** + * \brief Pid getter + * \return the pid + */ + const std::string& getPid() const; + + /** + * \brief Correlation time getter + * \return the correlation time + */ + double getTCorrelation() const; + + /** + * \brief Creation time getter + * \return the creation time + */ + double getTGlassCreate() const; + + private: /** * \brief A std::shared_ptr to a CSite object * representing the link between this correlation and the site it was @@ -170,10 +258,10 @@ class CCorrelation { std::shared_ptr pSite; /** - * \brief A std::vector of std::shared_ptr's to CHypo objects + * \brief A std::weak_ptr to a CHypo object * representing the links between this correlation and associated hypocenter */ - std::shared_ptr pHypo; + std::weak_ptr wpHypo; /** * \brief A std::string containing a character representing the action @@ -241,7 +329,14 @@ class CCorrelation { */ std::shared_ptr jCorrelation; - std::mutex correlationMutex; + /** + * \brief A recursive_mutex to control threading access to CCorrelation. + * NOTE: recursive mutexes are frowned upon, so maybe redesign around it + * see: http://www.codingstandard.com/rule/18-3-3-do-not-use-stdrecursive_mutex/ + * However a recursive_mutex allows us to maintain the original class + * design as delivered by the contractor. + */ + mutable std::recursive_mutex correlationMutex; }; } // namespace glasscore #endif // CORRELATION_H diff --git a/glasscore/glasslib/include/CorrelationList.h b/glasscore/glasslib/include/CorrelationList.h index 43e59f17..127f4dc0 100644 --- a/glasscore/glasslib/include/CorrelationList.h +++ b/glasscore/glasslib/include/CorrelationList.h @@ -81,7 +81,7 @@ class CCorrelationList { * \return Returns true if the communication was handled by CCorrelationList, * false otherwise */ - bool dispatch(json::Object *com); + bool dispatch(std::shared_ptr com); /** * \brief CCorrelationList add correlation function @@ -103,7 +103,7 @@ class CCorrelationList { * \return Returns true if the correlation was usable and added by CCorrelationList, * false otherwise */ - bool addCorrelation(json::Object *com); + bool addCorrelation(std::shared_ptr com); /** * \brief CCorrelationList get correlation function @@ -181,6 +181,60 @@ class CCorrelationList { double tOrg, double tDuration = 2.5); + /** + * \brief CGlass getter + * \return the CGlass pointer + */ + const CGlass* getGlass() const; + + /** + * \brief CGlass setter + * \param glass - the CGlass pointer + */ + void setGlass(CGlass* glass); + + /** + * \brief CSiteList getter + * \return the CSiteList pointer + */ + const CSiteList* getSiteList() const; + + /** + * \brief CSiteList setter + * \param siteList - the CSiteList pointer + */ + void setSiteList(CSiteList* siteList); + + /** + * \brief nCorrelation getter + * \return the nCorrelation + */ + int getNCorrelation() const; + + /** + * \brief nCorrelationMax getter + * \return the nCorrelationMax + */ + int getNCorrelationMax() const; + + /** + * \brief nCorrelationMax Setter + * \param correlationMax - the nCorrelationMax + */ + void setNCorrelationMax(int correlationMax); + + /** + * \brief nCorrelationTotal getter + * \return the nCorrelationTotal + */ + int getNCorrelationTotal() const; + + /** + * \brief Get the current size of the correlation list + */ + int getVCorrelationSize() const; + + private: /** * \brief A pointer to the parent CGlass class, used to send output, * look up site information, encode/decode time, get configuration values, @@ -233,7 +287,16 @@ class CCorrelationList { * However a recursive_mutex allows us to maintain the original class * design as delivered by the contractor. */ - std::recursive_mutex m_vCorrelationMutex; + mutable std::recursive_mutex m_vCorrelationMutex; + + /** + * \brief A recursive_mutex to control threading access to CCorrelationList. + * NOTE: recursive mutexes are frowned upon, so maybe redesign around it + * see: http://www.codingstandard.com/rule/18-3-3-do-not-use-stdrecursive_mutex/ + * However a recursive_mutex allows us to maintain the original class + * design as delivered by the contractor. + */ + mutable std::recursive_mutex m_CorrelationListMutex; }; } // namespace glasscore #endif // CORRELATIONLIST_H diff --git a/glasscore/glasslib/include/Detection.h b/glasscore/glasslib/include/Detection.h index 38e6f35a..6e67ccc8 100644 --- a/glasscore/glasslib/include/Detection.h +++ b/glasscore/glasslib/include/Detection.h @@ -69,7 +69,7 @@ class CDetection { * \return Returns true if the communication was handled by CDetection, * false otherwise */ - bool dispatch(json::Object *com); + bool dispatch(std::shared_ptr com); /** * \brief Process detection message @@ -89,15 +89,36 @@ class CDetection { * \param com - A pointer to a json::object containing the incoming * 'Detection' message */ - bool process(json::Object *com); + bool process(std::shared_ptr com); - // Local Attributes + /** + * \brief CGlass getter + * \return the CGlass pointer + */ + const CGlass* getGlass() const; + + /** + * \brief CGlass setter + * \param glass - the CGlass pointer + */ + void setGlass(CGlass* glass); + + private: /** * \brief A pointer to the parent CGlass class, used to send output, * look up site information, encode/decode time, get configuration * values, call association functions, and debug flags */ CGlass *pGlass; + + /** + * \brief A recursive_mutex to control threading access to CDetection. + * NOTE: recursive mutexes are frowned upon, so maybe redesign around it + * see: http://www.codingstandard.com/rule/18-3-3-do-not-use-stdrecursive_mutex/ + * However a recursive_mutex allows us to maintain the original class + * design as delivered by the contractor. + */ + mutable std::recursive_mutex detectionMutex; }; } // namespace glasscore #endif // DETECTION_H diff --git a/glasscore/glasslib/include/Glass.h b/glasscore/glasslib/include/Glass.h index 63b010f2..4d464228 100644 --- a/glasscore/glasslib/include/Glass.h +++ b/glasscore/glasslib/include/Glass.h @@ -81,7 +81,7 @@ class CGlass { * \return Returns true if the communication was handled by CGlass, * false otherwise */ - bool dispatch(json::Object *com); + bool dispatch(std::shared_ptr com); /** * \brief CGlass communication sending function @@ -95,7 +95,7 @@ class CGlass { * \return Returns true if the communication was sent via * a valid IGlassSend interface pointer, false otherwise */ - bool send(json::Object *com); + bool send(std::shared_ptr com); /** * \brief CGlass initialization function @@ -112,7 +112,7 @@ class CGlass { * \return Returns true if the initialization was successful, * false otherwise */ - bool initialize(json::Object *com); + bool initialize(std::shared_ptr com); /** * \brief CGlass clear function @@ -120,19 +120,6 @@ class CGlass { */ void clear(); - /** - * \brief CGlass input synchronization confirmation function - * - * The function used by CGlass to confirm that glasscore has processed - * all previously sent input data. Once glasscore has completed - * processing all input, a confirmation "pong" message is sent. - * - * \param com - A pointer to a json::object containing the - * confirmation query. - * \return Always returns true - */ - bool ping(json::Object *com); - /** * \brief CGlass earth model test function * @@ -189,26 +176,61 @@ class CGlass { */ double sig_laplace_pdf(double tdif, double sig); + /** + * \brief An IGlassSend interface pointer used to send communication + * (such as output data), to outside the glasscore library + */ + glasscore::IGlassSend *piSend; + /** * \brief check to see if each thread is still functional * * Checks each thread to see if it is still responsive. */ bool statusCheck(); - - // Local Attributes - /** - * \brief A std::string used in debugging to keep track of the id of the - * last pick added to glass. - */ - std::string sTrack; - - /** - * \brief A boolean set to true to turn on process tracking using - * printf strings (saved in sTrack) - */ - bool bTrack; - + double getAvgDelta() const; + double getAvgSigma() const; + double getBeamMatchingAzimuthWindow() const; + double getBeamMatchingDistanceWindow() const; + int getCorrelationCancelAge() const; + double getCorrelationMatchingTWindow() const; + double getCorrelationMatchingXWindow() const; + double getCutFactor() const; + double getCutMin() const; + double getCutPercentage() const; + double getReportThresh() const; + double getThresh() const; + double getExpAffinity() const; + bool getGraphicsOut() const; + const std::string& getGraphicsOutFolder() const; + double getGraphicsStepKm() const; + int getGraphicsSteps() const; + int getCycleLimit() const; + bool getMinimizeTtLocator() const; + int getCorrelationMax() const; + int getCount() const; + int getDetect() const; + int getHypoMax() const; + int getNucleate() const; + int getPickMax() const; + double getReportCut() const; + int getSitePickMax() const; + CCorrelationList*& getCorrelationList(); + CDetection*& getDetection(); + CHypoList*& getHypoList(); + double getPickDuplicateWindow() const; + CPickList*& getPickList(); + CSiteList*& getSiteList(); + std::shared_ptr& getTrvDefault(); + std::shared_ptr& getTTT(); + CWebList*& getWebList(); + double getSdAssociate() const; + double getSdPrune() const; + const std::string& getWeb() const; + bool getTestLocator() const; + bool getTestTimes() const; + + private: /** * \brief A double value containing the default number of picks that * that need to be gathered to trigger the nucleation of an event. @@ -282,12 +304,6 @@ class CGlass { */ double dCutMin; - /** - * \brief An IGlassSend interface pointer used to send communication - * (such as output data), to outside the glasscore library - */ - glasscore::IGlassSend *piSend; - /** * \brief A pointer to a CWeb object containing the detection web */ @@ -303,12 +319,12 @@ class CGlass { * \brief A pointer to a CTTT object containing the travel * time phases and branches used by glasscore for association */ - traveltime::CTTT *pTTT; + std::shared_ptr pTTT; /** * \brief the std::mutex for traveltimes */ - std::mutex m_TTTMutex; + mutable std::mutex m_TTTMutex; /** * \brief A pointer to a CSiteList object containing all the sites @@ -365,36 +381,6 @@ class CGlass { */ int nHypoMax; - /** - * \brief An integer containing the count of the number of times - * Hypo::iterate is called. Used for debugging. - */ - int nIterate; - - /** - * \brief An integer containing the count of the number of times - * Hypo::localize is called. Used for debugging. - */ - int nLocate; - - /** - * \brief A string containing the most recent nucleated web. Used for - * debugging. - */ - std::string sWeb; - - /** - * \brief An integer containing the count of supporting stations for the most - * recently nucleated node. Used for debugging. - */ - int nCount; - - /** - * \brief A double containing the Bayesian sum for the most recently - * nucleated node. Used for debugging. - */ - double dSum; - /** * \brief Window to check for 'duplicate' picks at same station. If new pick is * within window, it isn't added to pick list. diff --git a/glasscore/glasslib/include/Hypo.h b/glasscore/glasslib/include/Hypo.h index eda42fbf..349925fa 100644 --- a/glasscore/glasslib/include/Hypo.h +++ b/glasscore/glasslib/include/Hypo.h @@ -21,7 +21,7 @@ namespace glasscore { class CGlass; class CPick; class CCorrelation; -class CNode; +class CTrigger; /** * \brief glasscore hypocenter class @@ -79,9 +79,9 @@ class CHypo { */ CHypo(double lat, double lon, double z, double time, std::string pid, std::string web, double bayes, double thresh, int cut, - traveltime::CTravelTime* firstTrav, - traveltime::CTravelTime* secondTrav, traveltime::CTTT *ttt, - double resolution = 100); + std::shared_ptr firstTrav, + std::shared_ptr secondTrav, + std::shared_ptr ttt, double resolution = 100); /** * \brief CHypo alternate constructor @@ -92,7 +92,8 @@ class CHypo { * \param node - A shared pointer to a CNode object containing the node to * construct this hypo from. */ - explicit CHypo(std::shared_ptr node, traveltime::CTTT *ttt); + explicit CHypo(std::shared_ptr trigger, + std::shared_ptr ttt); /** * \brief CHypo alternate constructor @@ -104,8 +105,9 @@ class CHypo { * correlation to construct this hypo from. */ explicit CHypo(std::shared_ptr corr, - traveltime::CTravelTime* firstTrav, - traveltime::CTravelTime* secondTrav, traveltime::CTTT *ttt); + std::shared_ptr firstTrav, + std::shared_ptr secondTrav, + std::shared_ptr ttt); /** * \brief CHypo destructor @@ -142,9 +144,11 @@ class CHypo { */ bool initialize(double lat, double lon, double z, double time, std::string pid, std::string web, double bayes, - double thresh, int cut, traveltime::CTravelTime* firstTrav, - traveltime::CTravelTime* secondTrav, traveltime::CTTT *ttt, - double resolution = 100); + double thresh, int cut, + std::shared_ptr firstTrav, + std::shared_ptr secondTrav, + std::shared_ptr ttt, double resolution = + 100); /** * \brief Add pick reference to this hypo @@ -246,7 +250,7 @@ class CHypo { * * \return Returns the generated json object. */ - json::Object hypo(); + std::shared_ptr hypo(); /** * \brief Generate Event message @@ -472,6 +476,8 @@ class CHypo { double getBayes(double xlat, double xlon, double xZ, double oT, int nucleate); + double getResidual(std::string sPhase, double tObs, double tCal); + /** * Get the sum of the absolute residuals at a location * @@ -491,13 +497,6 @@ class CHypo { */ void graphicsOutput(); - /** - * \brief Sets the processing cycle count - * - * \param newCycle - An integer value containing the new cycle count - */ - void setCycle(int newCycle); - /** * \brief Calculate station weights * @@ -518,8 +517,245 @@ class CHypo { */ void trap(); - void incrementProcessCount(); + /** + * \brief Latitude getter + * \return the latitude + */ + double getLat() const; + + /** + * \brief Longitude getter + * \return the longitude + */ + double getLon() const; + + /** + * \brief Depth getter + * \return the depth + */ + double getZ() const; + + /** + * \brief Origin time getter + * \return the origin time + */ + double getTOrg() const; + + /** + * \brief Bayes value getter + * \return the bayes value + */ + double getBayes() const; + + /** + * \brief Correlation added flag getter + * \return the correlation added flag + */ + bool getCorrAdded() const; + + /** + * \brief Correlation added flag setter + * \param corrAdded - the correlation added flag + */ + void setCorrAdded(bool corrAdded); + + /** + * \brief Event reported flag getter + * \return the event reported flag + */ + bool getEvent() const; + + /** + * \brief Fixed flag getter + * \return the fixed flag + */ + bool getFixed() const; + + /** + * \brief Fixed flag setter + * \param fixed - the fixed flag + */ + void setFixed(bool fixed); + + /** + * \brief Bayes initial value getter + * \return the intial bayes value + */ + double getBayesInitial() const; + /** + * \brief Cut factor getter + * \return the cut factor value + */ + double getCutFactor() const; + + /** + * \brief Cut factor setter + * \param cutFactor - the cut factor + */ + void setCutFactor(double cutFactor); + + /** + * \brief Cut min getter + * \return the cut min value + */ + double getCutMin() const; + + /** + * \brief Cut min setter + * \param cutMin - the cut min value + */ + void setCutMin(double cutMin); + + /** + * \brief Cut percentage getter + * \return the cut percentage value + */ + double getCutPercentage() const; + + /** + * \brief Cut factor setter + * \param cutPercentage - the cut percentage value + */ + void setCutPercentage(double cutPercentage); + + /** + * \brief Cut getter + * \return the cut value + */ + int getCut() const; + + /** + * \brief Cut setter + * \param cut - the cut value + */ + void setCut(double cut); + + /** + * \brief Thresh getter + * \return the thresh value + */ + double getThresh() const; + + /** + * \brief Thresh setter + * \param thresh - the thresh value + */ + void setThresh(double thresh); + + /** + * \brief Gap getter + * \return the gap value + */ + double getGap() const; + + /** + * \brief Kurtosis getter + * \return the kurtosis value + */ + double getKrt() const; + + /** + * \brief Med distance getter + * \return the med distance value + */ + double getMed() const; + + /** + * \brief Min distance getter + * \return the min distance value + */ + double getMin() const; + + /** + * \brief Residual getter + * \return the residual value + */ + double getRes() const; + + /** + * \brief Sig getter + * \return the sig value + */ + double getSig() const; + + /** + * \brief Cycle getter + * \return the cycle value + */ + int getCycle() const; + + /** + * \brief Cycle setter + * \param newCycle - the cycle value + */ + int setCycle(int newCycle); + + /** + * \brief Process count getter + * \return the process count value + */ + int getProcessCount() const; + + /** + * \brief Process count incrementer + * \return the process count value + */ + int incrementProcessCount(); + + /** + * \brief CGlass getter + * \return the CGlass pointer + */ + const CGlass* getGlass() const; + + /** + * \brief CGlass setter + * \param glass - the CGlass pointer + */ + void setGlass(CGlass* glass); + + /** + * \brief Pid getter + * \return the Pid + */ + const std::string& getPid() const; + + /** + * \brief Web Name getter + * \return the Web Name + */ + const std::string& getWebName() const; + + /** + * \brief Pick vector size getter + * \return the pick vector size + */ + int getVPickSize() const; + + /** + * \brief Correlation vector size getter + * \return the correlation vector size + */ + int getVCorrSize() const; + + /** + * \brief Creation time getter + * \return the creation time + */ + double getTCreate() const; + + /** + * \brief Report count getter + * \return the report count + */ + int getReportCount() const; + + bool isLockedForProcessing(); + void lockForProcessing(); + void unlockAfterProcessing(); + + private: /** * \brief A pointer to the main CGlass class, used to send output, * look up travel times, encode/decode time, and call significance @@ -531,7 +767,7 @@ class CHypo { * \brief A std::string with the name of the initiating subnet trigger * used during the nucleation process */ - std::string sWeb; + std::string sWebName; /** * \brief An integer containing the number of stations needed to maintain @@ -576,16 +812,6 @@ class CHypo { */ double dZ; - /** - * \brief A boolean indicating whether this hypo needs to be refined. - */ - bool bRefine; - - /** - * \brief A boolean indicating if a Quake message was sent for this hypo. - */ - bool bQuake; - /** * \brief A boolean indicating if an Event message was sent for this hypo. */ @@ -747,19 +973,19 @@ class CHypo { * \brief A pointer to a CTravelTime object containing * travel times for the first phase used to nucleate this hypo */ - traveltime::CTravelTime* pTrv1; + std::shared_ptr pTrv1; /** * \brief A pointer to a CTravelTime object containing * travel times for the second phase used to nucleate this hypo */ - traveltime::CTravelTime* pTrv2; + std::shared_ptr pTrv2; /** * \brief A pointer to a CTTT object containing the travel * time phases and branches used for association and location */ - traveltime::CTTT *pTTT; + std::shared_ptr pTTT; /** * \brief A recursive_mutex to control threading access to CHypo. @@ -768,7 +994,12 @@ class CHypo { * However a recursive_mutex allows us to maintain the original class * design as delivered by the contractor. */ - std::recursive_mutex hypoMutex; + mutable std::recursive_mutex hypoMutex; + + /** + * \brief A mutex to control processing access to CHypo. + */ + std::mutex processingMutex; /** * \brief A random engine used to generate random numbers diff --git a/glasscore/glasslib/include/HypoList.h b/glasscore/glasslib/include/HypoList.h index 05fbb878..5a4a1001 100644 --- a/glasscore/glasslib/include/HypoList.h +++ b/glasscore/glasslib/include/HypoList.h @@ -95,7 +95,7 @@ class CHypoList { * \return Returns true if the communication was handled by CGlass, * false otherwise */ - bool dispatch(json::Object *com); + bool dispatch(std::shared_ptr com); /** * \brief Get insertion index for hypo @@ -272,15 +272,62 @@ class CHypoList { * \param com - A pointer to a json::object containing the id of the * hypocenter to use */ - bool reqHypo(json::Object *com); + bool reqHypo(std::shared_ptr com); /** \brief Merge event **/ - bool merge(std::shared_ptr hyp); + // bool merge(std::shared_ptr hyp); + /** + * \brief check to see if each thread is still functional + * + * Checks each thread to see if it is still responsive. + */ + bool statusCheck(); /** - * \brief HypoList sort function + * \brief CGlass getter + * \return the CGlass pointer + */ + const CGlass* getGlass() const; + + /** + * \brief CGlass setter + * \param glass - the CGlass pointer */ + void setGlass(CGlass* glass); + /** + * \brief nHypo getter + * \return the nHypo + */ + int getNHypo() const; + + /** + * \brief nHypoMax getter + * \return the nHypoMax + */ + int getNHypoMax() const; + + /** + * \brief nHypoMax Setter + * \param hypoMax - the nHypoMax + */ + void setNHypoMax(int hypoMax); + + /** + * \brief nHypoTotal getter + * \return the nHypoTotal + */ + int getNHypoTotal() const; + + /** + * \brief Get the current size of the hypocenter list + */ + int getVHypoSize() const; + + private: + /** + * \brief HypoList sort function + */ void sort(); /** @@ -297,13 +344,6 @@ class CHypoList { */ void jobSleep(); - /** - * \brief check to see if each thread is still functional - * - * Checks each thread to see if it is still responsive. - */ - bool statusCheck(); - /** * \brief thread status update function * @@ -369,12 +409,16 @@ class CHypoList { * However a recursive_mutex allows us to maintain the original class * design as delivered by the contractor. */ - std::recursive_mutex m_vHypoMutex; + mutable std::recursive_mutex m_vHypoMutex; /** - * \brief A boolean indicating whether to send Event json messages. + * \brief A recursive_mutex to control threading access to CHypoList. + * NOTE: recursive mutexes are frowned upon, so maybe redesign around it + * see: http://www.codingstandard.com/rule/18-3-3-do-not-use-stdrecursive_mutex/ + * However a recursive_mutex allows us to maintain the original class + * design as delivered by the contractor. */ - bool bSendEvent; + mutable std::recursive_mutex m_HypoListMutex; /** * \brief the std::vector of std::threads diff --git a/glasscore/glasslib/include/IGlassSend.h b/glasscore/glasslib/include/IGlassSend.h index 3c58c1de..0670fabe 100644 --- a/glasscore/glasslib/include/IGlassSend.h +++ b/glasscore/glasslib/include/IGlassSend.h @@ -8,6 +8,7 @@ #define IGLASSSEND_H #include +#include namespace glasscore { @@ -30,7 +31,7 @@ struct IGlassSend { * \param com - A pointer to a json::object containing the data * to send to glasscore. */ - virtual void Send(json::Object *com) = 0; + virtual void Send(std::shared_ptr com) = 0; }; } // namespace glasscore #endif // IGLASSSEND_H diff --git a/glasscore/glasslib/include/Link.h b/glasscore/glasslib/include/Link.h index 820db7f8..e8db663d 100644 --- a/glasscore/glasslib/include/Link.h +++ b/glasscore/glasslib/include/Link.h @@ -22,9 +22,10 @@ class CSite; #define LINK_TT2 2 // Second travel time /** - * \brief Typedef to simplify use of a site-node link + * \brief Typedef to simplify use of a site-node link uses weak_ptr to + * prevent a cyclical reference */ -typedef std::tuple, double, double> NodeLink; +typedef std::tuple, double, double> NodeLink; /** * \brief Typedef to simplify use of a node-site link diff --git a/glasscore/glasslib/include/Node.h b/glasscore/glasslib/include/Node.h index d47e7352..e84191ee 100644 --- a/glasscore/glasslib/include/Node.h +++ b/glasscore/glasslib/include/Node.h @@ -22,6 +22,7 @@ namespace glasscore { class CPick; class CSite; class CWeb; +class CTrigger; /** * \brief glasscore detection node class @@ -138,7 +139,7 @@ class CNode { * picks used in calculation * \return Returns true if the node nucleated an event, false otherwise */ - bool nucleate(double tOrigin, bool bList = false); + std::shared_ptr nucleate(double tOrigin); /** * \brief CNode significance function @@ -164,14 +165,96 @@ class CNode { */ std::shared_ptr getSite(std::string sScnl); + /** + * \brief CNode get last site function + * + * Get the last site linked to the node + * + * \return Returns a shared pointer to the last CSite object if found, null + * otherwise + */ std::shared_ptr getLastSite(); + /** + * \brief CNode site link sort function + * + * Sort the list of sites linked to this node + */ void sortSiteLinks(); + /** + * \brief Sites string getter + * \return the sites string + */ std::string getSitesString(); - int getSiteLinksCount(); + /** + * \brief Site links count getter + * \return the site links count + */ + int getSiteLinksCount() const; + + /** + * \brief Enabled flag getter + * \return the enabled flag + */ + bool getEnabled() const; + /** + * \brief Enabled flag setter + * \param enable - the enabled flag + */ + void setEnabled(bool enabled); + + /** + * \brief Latitude getter + * \return the latitude + */ + double getLat() const; + + /** + * \brief Longitude getter + * \return the longitude + */ + double getLon() const; + + /** + * \brief Depth getter + * \return the Depth + */ + double getZ() const; + + /** + * \brief Resolution getter + * \return the Resolution + */ + double getResolution() const; + + /** + * \brief CWeb pointer getter + * \return the CWeb pointer + */ + CWeb* getWeb() const; + + /** + * \brief CWeb pointer setter + * \param web - the CWeb pointer + */ + void setWeb(CWeb* web); + + /** + * \brief Name getter + * \return the name + */ + const std::string& getName() const; + + /** + * \brief Pid getter + * \return the pid + */ + const std::string& getPid() const; + + private: /** * \brief A pointer to the parent CWeb class, used get configuration, * values, perform significance calculations, and debug flags @@ -212,37 +295,11 @@ class CNode { double dResolution; /** - * \brief A std::vector of std::shared_ptr's to CPick objects - * used in calculating the likelihood of a hypocenter - * centered on this node during the last call to nucleate() + * \brief A boolean flag indicating whether this node is enabled for + * nucleation */ - std::vector> vPick; - - /** - * \brief A double value that accumulates the Bayesian - * sum when evaluating the agoric at each node in a web. - * It is compared to the threshold value set for the - * web which owns this node. - */ - double dSum; - - /** - * \brief A integer value that tallies the number of sites - * that are included in this solution. This value is - * compared against the Nucleation parameter in the - * parameters for the web for which this node is a memeber - */ - int nCount; - - /** - * \brief A double value with the origin time calculated the last time - * this node was nucleated. - */ - double tOrg; - bool bEnabled; - private: /** * \brief A std::vector of tuples linking node to site * {shared site pointer, travel time 1, travel time 2} @@ -252,7 +309,16 @@ class CNode { /** * \brief A mutex to control threading access to vSite. */ - std::mutex vSiteMutex; + mutable std::mutex vSiteMutex; + + /** + * \brief A recursive_mutex to control threading access to CNode. + * NOTE: recursive mutexes are frowned upon, so maybe redesign around it + * see: http://www.codingstandard.com/rule/18-3-3-do-not-use-stdrecursive_mutex/ + * However a recursive_mutex allows us to maintain the original class + * design as delivered by the contractor. + */ + mutable std::recursive_mutex nodeMutex; }; } // namespace glasscore #endif // NODE_H diff --git a/glasscore/glasslib/include/Pick.h b/glasscore/glasslib/include/Pick.h index 68fec135..ce496b50 100644 --- a/glasscore/glasslib/include/Pick.h +++ b/glasscore/glasslib/include/Pick.h @@ -76,7 +76,7 @@ class CPick { * \param pickId - An integer containing the pick id to use. * \param pSiteList - A pointer to the CSiteList class */ - CPick(json::Object *pick, int pickId, CSiteList *pSiteList); + CPick(std::shared_ptr pick, int pickId, CSiteList *pSiteList); /** * \brief CPick destructor @@ -122,8 +122,6 @@ class CPick { void addHypo(std::shared_ptr hyp, std::string ass = "", bool force = false); - void setAss(std::string ass); - /** * \brief Remove hypo reference to this pick * @@ -138,6 +136,9 @@ class CPick { */ void remHypo(std::shared_ptr hyp); + /** + * \brief Clear any hypo reference to this pick + */ void clearHypo(); /** @@ -151,7 +152,73 @@ class CPick { */ bool nucleate(); - // Local Attributes + /** + * \brief Back azimuth getter + * \return the back azimuth + */ + double getBackAzimuth() const; + + /** + * \brief Slowness getter + * \return the slowness + */ + double getSlowness() const; + + /** + * \brief Pick id getter + * \return the pick id + */ + int getIdPick() const; + + /** + * \brief Json pick getter + * \return the json pick + */ + const std::shared_ptr& getJPick() const; + + /** + * \brief Hypo getter + * \return the hypo + */ + const std::shared_ptr getHypo() const; + + /** + * \brief Site getter + * \return the site + */ + const std::shared_ptr& getSite() const; + + /** + * \brief Association string getter + * \return the association string + */ + const std::string& getAss() const; + + /** + * \brief Association string setter + * \param ass - the association string + */ + void setAss(std::string ass); + + /** + * \brief Phase getter + * \return the phase + */ + const std::string& getPhs() const; + + /** + * \brief Pid getter + * \return the pid + */ + const std::string& getPid() const; + + /** + * \brief Pick time getter + * \return the pick time + */ + double getTPick() const; + + private: /** * \brief A std::shared_ptr to a CSite object * representing the link between this pick and the site it was @@ -160,10 +227,12 @@ class CPick { std::shared_ptr pSite; /** - * \brief A std::vector of std::shared_ptr's to CHypo objects - * representing the links between this pick and associated hypocenter + * \brief A std::weak_ptr to a CHypo object + * representing the links between this pick and associated hypocenter. + * A weak_ptr is used here instead of a shared_ptr to prevent a cyclical + * reference between CPick and CHypo. */ - std::shared_ptr pHypo; + std::weak_ptr wpHypo; /** * \brief A std::string containing a character representing the action @@ -208,7 +277,14 @@ class CPick { */ std::shared_ptr jPick; - std::recursive_mutex pickMutex; + /** + * \brief A recursive_mutex to control threading access to CPick. + * NOTE: recursive mutexes are frowned upon, so maybe redesign around it + * see: http://www.codingstandard.com/rule/18-3-3-do-not-use-stdrecursive_mutex/ + * However a recursive_mutex allows us to maintain the original class + * design as delivered by the contractor. + */ + mutable std::recursive_mutex pickMutex; }; } // namespace glasscore #endif // PICK_H diff --git a/glasscore/glasslib/include/PickList.h b/glasscore/glasslib/include/PickList.h index 7dccca16..f21a134b 100644 --- a/glasscore/glasslib/include/PickList.h +++ b/glasscore/glasslib/include/PickList.h @@ -91,7 +91,7 @@ class CPickList { * \return Returns true if the communication was handled by CPickList, * false otherwise */ - bool dispatch(json::Object *com); + bool dispatch(std::shared_ptr com); /** * \brief CPickList add pick function @@ -114,7 +114,7 @@ class CPickList { * \return Returns true if the pick was usable and added by CPickList, * false otherwise */ - bool addPick(json::Object *pick); + bool addPick(std::shared_ptr pick); /** * \brief CPickList get pick function @@ -192,6 +192,67 @@ class CPickList { std::vector> rogues(std::string pidHyp, double tOrg, double tDuration = 2400.0); + /** + * \brief check to see if each thread is still functional + * + * Checks each thread to see if it is still responsive. + */ + bool statusCheck(); + + /** + * \brief CGlass getter + * \return the CGlass pointer + */ + const CGlass* getGlass() const; + + /** + * \brief CGlass setter + * \param glass - the CGlass pointer + */ + void setGlass(CGlass* glass); + + /** + * \brief CSiteList getter + * \return the CSiteList pointer + */ + const CSiteList* getSiteList() const; + + /** + * \brief CSiteList setter + * \param siteList - the CSiteList pointer + */ + void setSiteList(CSiteList* siteList); + + /** + * \brief nPick getter + * \return the nPick + */ + int getNPick() const; + + /** + * \brief nPickMax getter + * \return the nPickMax + */ + int getNPickMax() const; + + /** + * \brief nPickMax Setter + * \param correlationMax - the nPickMax + */ + void setNPickMax(int picknMax); + + /** + * \brief nPickTotal getter + * \return the nPickTotal + */ + int getNPickTotal() const; + + /** + * \brief Get the current size of the pick list + */ + int getVPickSize() const; + + private: /** * \brief Process the next pick on the queue * @@ -206,13 +267,6 @@ class CPickList { */ void jobSleep(); - /** - * \brief check to see if each thread is still functional - * - * Checks each thread to see if it is still responsive. - */ - bool statusCheck(); - /** * \brief thread status update function * @@ -329,7 +383,16 @@ class CPickList { * However a recursive_mutex allows us to maintain the original class * design as delivered by the contractor. */ - std::recursive_mutex m_vPickMutex; + mutable std::recursive_mutex m_vPickMutex; + + /** + * \brief A recursive_mutex to control threading access to CPickList. + * NOTE: recursive mutexes are frowned upon, so maybe redesign around it + * see: http://www.codingstandard.com/rule/18-3-3-do-not-use-stdrecursive_mutex/ + * However a recursive_mutex allows us to maintain the original class + * design as delivered by the contractor. + */ + mutable std::recursive_mutex m_PickListMutex; }; } // namespace glasscore #endif // PICKLIST_H diff --git a/glasscore/glasslib/include/Site.h b/glasscore/glasslib/include/Site.h index 92de9011..8d537df8 100644 --- a/glasscore/glasslib/include/Site.h +++ b/glasscore/glasslib/include/Site.h @@ -23,6 +23,7 @@ namespace glasscore { class CPick; class CNode; class CGlass; +class CTrigger; /** * \brief glasscore site (station) class @@ -80,7 +81,7 @@ class CSite { * \param com - A pointer to a json::Object to construct the site from * \param glassPtr - A pointer to the CGlass class */ - CSite(json::Object *com, CGlass *glassPtr); + CSite(std::shared_ptr site, CGlass *glassPtr); /** * \brief CSite destructor @@ -92,6 +93,8 @@ class CSite { */ void clear(); + void clearVPick(); + /** * \brief CSite update function * @@ -205,40 +208,123 @@ class CSite { * \param tpick - A double value containing the pick time to nucleate with * in julian seconds */ - void nucleate(double tpick); + std::vector> nucleate(double tpick); /** * \brief Add triggering node to triggered node list if value exceeds * current value of if named node's web is not yet present. */ - void addTrigger(std::shared_ptr node); + void addTrigger(std::vector> *vTrigger, + std::shared_ptr trigger); + + /** + * \brief Node link count getter + * \return the node link count + */ + int getNodeLinksCount() const; + + /** + * \brief Use flag getter + * \return the use flag + */ + bool getUse() const; - int getNodeLinksCount(); + /** + * \brief Use flag setter + * \param use - the use flag + */ + void setUse(bool use); + + /** + * \brief Use for teleseismic flag getter + * \return the use for teleseismic flag + */ + bool getUseForTele() const; + + /** + * \brief Use for teleseismic flag setter + * \param useForTele - the use for teleseismic flag + */ + void setUseForTele(bool useForTele); + + /** + * \brief Quality getter + * \return the quality + */ + double getQual() const; + + /** + * \brief Quality setter + * \param qual - the quality + */ + void setQual(double qual); + + /** + * \brief CGeo getter + * \return the CGeo + */ + glassutil::CGeo& getGeo(); + + /** + * \brief Max picks for site getter + * \return the max picks for site + */ + int getSitePickMax() const; /** - * \brief A std::vector of std::shared_ptr's to the picks mad at this this - * CSite + * \brief CGlass getter + * \return the CGlass pointer */ - std::vector> vPick; + CGlass* getGlass() const; /** - * \brief A std::shared_ptr to the node with the best PDF the last time - * nucleate() was called that exceeded web specific thresholds. + * \brief SCNL getter + * \return the SCNL */ - std::shared_ptr pNode; + const std::string& getScnl() const; /** - * \brief A std::shared_ptr to the node with the best PDF the last time - * nucleate() was called with the largest value for the current pick. + * \brief Site getter + * \return the site */ - std::shared_ptr qNode; + const std::string& getSite() const; /** - * \brief A double value containing the P travel time - * between the node with the best PDF the last time - * nucleate() was called and the site in seconds + * \brief Comp getter + * \return the comp */ - double dTrav; + const std::string& getComp() const; + + /** + * \brief Net getter + * \return the net + */ + const std::string& getNet() const; + + /** + * \brief Loc getter + * \return the loc + */ + const std::string& getLoc() const; + + /** + * \brief vPick getter + * \return the vPick + */ + const std::vector> getVPick() const; + + private: + /** + * \brief A mutex to control threading access to vPick. + */ + mutable std::mutex vPickMutex; + + /** + * \brief A std::vector of std::weak_ptr's to the picks made at this this + * CSite. A weak_ptr is used here instead of a shared_ptr to prevent a + * cyclical reference between CPick and CSite. + */ + std::vector> vPick; /** * \brief A pointer to the main CGlass class used encode/decode time and @@ -305,25 +391,11 @@ class CSite { */ int nSitePickMax; - /* - * /brief A std::vector of shared node pointers that contain a list - * of nodes that triggered for an input pick. It supports the concept - * that each node can generate trigger event independently from other - * webs. It is set by the method 'addTrigger'. - */ - std::vector> vTrigger; - /** - * \brief A mutex to control threading access to vPick. - */ - std::mutex vPickMutex; - - /** - * \brief A mutex to control threading access to vTrigger. + * \brief A mutex to control threading access to vNode. */ - std::mutex vTriggerMutex; + mutable std::mutex vNodeMutex; - private: /** * \brief A std::vector of tuples linking site to node * {shared node pointer, travel-time 1, travel-time 2} @@ -331,9 +403,13 @@ class CSite { std::vector vNode; /** - * \brief A mutex to control threading access to vNode. + * \brief A recursive_mutex to control threading access to CSite. + * NOTE: recursive mutexes are frowned upon, so maybe redesign around it + * see: http://www.codingstandard.com/rule/18-3-3-do-not-use-stdrecursive_mutex/ + * However a recursive_mutex allows us to maintain the original class + * design as delivered by the contractor. */ - std::mutex vNodeMutex; + mutable std::recursive_mutex siteMutex; }; } // namespace glasscore #endif // SITE_H diff --git a/glasscore/glasslib/include/SiteList.h b/glasscore/glasslib/include/SiteList.h index ef74a61b..13da3df2 100644 --- a/glasscore/glasslib/include/SiteList.h +++ b/glasscore/glasslib/include/SiteList.h @@ -78,7 +78,7 @@ class CSiteList { * \return Returns true if the communication was handled by CSiteList, * false otherwise */ - bool dispatch(json::Object *com); + bool dispatch(std::shared_ptr com); /** * \brief CSiteList add/update site function @@ -91,7 +91,7 @@ class CSiteList { * \return Returns true if the site was complete and added by CSiteList, * false otherwise */ - bool addSite(json::Object *com); + bool addSite(std::shared_ptr com); /** * \brief CSiteList add list of sites function @@ -103,7 +103,7 @@ class CSiteList { * \return Returns true if the site was complete and added by CSiteList, * false otherwise */ - bool addSiteList(json::Object *com); + bool addSiteList(std::shared_ptr com); /** * \brief CSiteList add/update site function @@ -198,6 +198,24 @@ class CSiteList { */ bool reqSiteList(); + /** + * \brief CGlass getter + * \return the CGlass pointer + */ + const CGlass* getGlass() const; + + /** + * \brief CGlass setter + * \param glass - the CGlass pointer + */ + void setGlass(CGlass* glass); + + /** + * \brief Get the current size of the site list + */ + int getVSiteSize() const; + + private: /** * \brief A pointer to the main CGlass class, used to pass this information * to sites added to CSiteList @@ -207,7 +225,7 @@ class CSiteList { /** * \brief A mutex to control threading access to vSite. */ - std::mutex vSiteMutex; + mutable std::mutex vSiteMutex; /** * \brief A std::vector of all the sites in CSiteList. @@ -219,6 +237,15 @@ class CSiteList { * in CSiteList indexed by the std::string scnl id. */ std::map> mSite; + + /** + * \brief A recursive_mutex to control threading access to CSiteList. + * NOTE: recursive mutexes are frowned upon, so maybe redesign around it + * see: http://www.codingstandard.com/rule/18-3-3-do-not-use-stdrecursive_mutex/ + * However a recursive_mutex allows us to maintain the original class + * design as delivered by the contractor. + */ + mutable std::recursive_mutex m_SiteListMutex; }; } // namespace glasscore #endif // SITELIST_H diff --git a/glasscore/glasslib/include/Trigger.h b/glasscore/glasslib/include/Trigger.h new file mode 100644 index 00000000..d53f366e --- /dev/null +++ b/glasscore/glasslib/include/Trigger.h @@ -0,0 +1,214 @@ +/***************************************** + * This file is documented for Doxygen. + * If you modify this file please update + * the comments so that Doxygen will still + * be able to work. + ****************************************/ +#ifndef TRIGGER_H +#define TRIGGER_H + +#include +#include +#include +#include +#include +#include +#include "Geo.h" +#include "Link.h" + +namespace glasscore { + +// forward declarations +class CPick; +class CWeb; + +/** + * \brief glasscore detection trigger class + * + * The CTrigger class represents a single detection trigger from the + * detection graph database. A CTrigger consists of the location (latitude, + * longitude, and depth) of the triggering node, the spatial resolution of the + * triggering node, and a list of picks that made the trigger + * + * CTrigger uses smart pointers (std::shared_ptr). + */ +class CTrigger { + public: + /** + * \brief CTrigger constructor + */ + CTrigger(); + + /** + * \brief CTrigger advanced constructor + * + * Construct a trigger using the provided data + * + * \param lat - A double value containing the latitude to use + * for this trigger in degrees + * \param lon - A double value containing the longitude to use + * for this trigger in degrees + * \param z - A double value containing the depth to use + * for this trigger in kilometers + * \param ot - A double value containing the time to use + * for this trigger in seconds + * \param resolution - A double value containing the inter-node resolution + * in kilometer + * \param sum - A double value containing the bayesian sum for this trigger + * \param count - An integer value containing the site count for this + * trigger + * \param picks - A std::vector containing the picks + * for this trigger + * \param web - A pointer to the creating node's CWeb + */ + CTrigger(double lat, double lon, double z, double ot, double resolution, + double sum, int count, + std::vector> picks, CWeb *web); + + /** + * \brief CTrigger destructor + */ + ~CTrigger(); + + /** + * \brief CTrigger initialization function + * + * Initialize a trigger using the provided data + * + * \param lat - A double value containing the latitude to use + * for this trigger in degrees + * \param lon - A double value containing the longitude to use + * for this trigger in degrees + * \param z - A double value containing the depth to use + * for this trigger in kilometers + * \param ot - A double value containing the time to use + * for this trigger in seconds + * \param resolution - A double value containing the inter-node resolution + * in kilometer + * \param sum - A double value containing the bayesian sum for this trigger + * \param count - An integer value containing the site count for this + * trigger + * \param picks - A std::vector containing the picks + * for this trigger + * \param web - A pointer to the creating node's web + */ + bool initialize(double lat, double lon, double z, double ot, + double resolution, double sum, int count, + std::vector> picks, CWeb *web); + + /** + * \brief CTrigger clear function + */ + void clear(); + + /** + * \brief Latitude getter + * \return the latitude + */ + double getLat() const; + + /** + * \brief Longitude getter + * \return the longitude + */ + double getLon() const; + + /** + * \brief Depth getter + * \return the depth + */ + double getZ() const; + + /** + * \brief Origin time getter + * \return the origin time + */ + double getTOrg() const; + + /** + * \brief Resolution getter + * \return the resolution + */ + double getResolution() const; + + /** + * \brief Sum getter + * \return the sum + */ + double getSum() const; + + /** + * \brief Count getter + * \return the count + */ + int getCount() const; + + /** + * \brief Web pointer getter + * \return the CWeb pointer + */ + const CWeb* getWeb() const; + + /** + * \brief vPick getter + * \return the vPick + */ + const std::vector> getVPick() const; + + private: + /** + * \brief A double value containing latitude of this triggerin degrees. + */ + double dLat; + + /** + * \brief A double value containing longitude of this triggerin degrees. + */ + double dLon; + + /** + * \brief A double value containing the depth of this trigger in kilometers. + */ + double dZ; + + /** + * \brief A double value with the origin time of this trigger in seconds + */ + double tOrg; + + /** + * \brief A double value containing the spatial resolution + * (between nodes) in kilometers. + */ + double dResolution; + + /** + * \brief A double value that accumulates the Bayesian + * sum of this trigger + */ + double dSum; + + /** + * \brief A integer value that tallies the number of sites + * that are included in this trigger + */ + int nCount; + + /** + * \brief A std::vector of std::shared_ptr's to CPick objects + * used in creating this trigger + */ + std::vector> vPick; + + /** + * \brief A pointer to the node CWeb class, used get travel times + */ + CWeb *pWeb; + + /** + * \brief A recursive mutex to control threading access to this trigger. + */ + mutable std::recursive_mutex triggerMutex; +}; +} // namespace glasscore +#endif // TRIGGER_H diff --git a/glasscore/glasslib/include/Web.h b/glasscore/glasslib/include/Web.h index 7d2fe743..048f75f7 100644 --- a/glasscore/glasslib/include/Web.h +++ b/glasscore/glasslib/include/Web.h @@ -43,7 +43,7 @@ class CWeb { * The constructor for the CWeb class. * \param createBackgroundThread - A boolean flag indicating whether * to create a background thread for web updates. If set to false, glass will - * halt until the web update is completed. Default true. + * halt until the web update is completed. Default true. * \param sleepTime - An integer containing the amount of * time to sleep in milliseconds between jobs. Default 10 * \param checkInterval - An integer containing the amount of time in @@ -78,9 +78,9 @@ class CWeb { * use for travel time lookups. * \param secondTrav - A shared pointer to the second CTravelTime object to * use for travel time lookups. - * \param createBackgroundThread - A boolean flag indicating whether - * to create a background thread for web updates. If set to false, glass will - * halt until the web update is completed. Default true. + * \param createBackgroundThread - A boolean flag indicating whether + * to create a background thread for web updates. If set to false, glass will + * halt until the web update is completed. Default true. * \param sleepTime - An integer containing the amount of * time to sleep in milliseconds between jobs. Default 10 * \param checkInterval - An integer containing the amount of time in @@ -124,7 +124,7 @@ class CWeb { * \return Returns true if the communication was handled by CWeb, * false otherwise */ - bool dispatch(json::Object *com); + bool dispatch(std::shared_ptr com); /** * \brief CWeb initialization function @@ -168,7 +168,7 @@ class CWeb { * configuration * \return Returns true if successful, false if a grid was not created. */ - bool grid(json::Object *com); + bool grid(std::shared_ptr com); /** * \brief Generate a detection grid with explicit nodes @@ -179,7 +179,7 @@ class CWeb { * configuration * \return Returns true if successful, false if a grid was not created. */ - bool grid_explicit(json::Object *com); + bool grid_explicit(std::shared_ptr com); /** * \brief Generate a global detection grid @@ -191,7 +191,7 @@ class CWeb { * configuration * \return Always returns true */ - bool global(json::Object *com); + bool global(std::shared_ptr com); /** * \brief Load the travel times for this web @@ -212,7 +212,7 @@ class CWeb { * \param com - A pointer to a json::object containing the web configuration * \return Returns true if successful, false otherwise. */ - bool genSiteFilters(json::Object *com); + bool genSiteFilters(std::shared_ptr com); /** * \brief Generate node site list @@ -327,6 +327,55 @@ class CWeb { */ bool statusCheck(); + /** + * \brief add a job + * + * Adds a job to the queue of jobs to be run by the background + * thread + * \param newjob - A std::function bound to the function + * containing the job to run + */ + void addJob(std::function newjob); + + /** + * \brief CGlass getter + * \return the CGlass pointer + */ + CGlass* getGlass() const; + + /** + * \brief CGlass setter + * \param glass - the CGlass pointer + */ + void setGlass(CGlass* glass); + + /** + * \brief CSiteList getter + * \return the CSiteList pointer + */ + const CSiteList* getSiteList() const; + + /** + * \brief CSiteList setter + * \param siteList - the CSiteList pointer + */ + void setSiteList(CSiteList* siteList); + bool getUpdate() const; + double getResolution() const; + double getThresh() const; + int getCol() const; + int getDetect() const; + int getNucleate() const; + int getRow() const; + int getZ() const; + const std::string& getName() const; + const std::shared_ptr& getTrv1() const; + const std::shared_ptr& getTrv2() const; + int getVNetFilterSize() const; + int getVSitesFilterSize() const; + int getVNodeSize() const; + + private: /** * \brief the job sleep * @@ -342,7 +391,6 @@ class CWeb { */ void setStatus(bool status); - // Local Attributes /** * \brief A pointer to the main CGlass class, used to send output, * get default values, encode/decode time, and get debug flags @@ -383,6 +431,11 @@ class CWeb { */ std::vector> vNode; + /** + * \brief the std::mutex for m_QueueMutex + */ + mutable std::mutex m_vNodeMutex; + /** * \brief String name of web used in tuning */ @@ -454,7 +507,7 @@ class CWeb { /** * \brief the std::mutex for traveltimes */ - std::mutex m_TrvMutex; + mutable std::mutex m_TrvMutex; /** * \brief A mutex to control threading access to vSite. @@ -517,14 +570,13 @@ class CWeb { bool m_bUseBackgroundThread; /** - * \brief add a job - * - * Adds a job to the queue of jobs to be run by the background - * thread - * \param newjob - A std::function bound to the function - * containing the job to run + * \brief A recursive_mutex to control threading access to CWeb. + * NOTE: recursive mutexes are frowned upon, so maybe redesign around it + * see: http://www.codingstandard.com/rule/18-3-3-do-not-use-stdrecursive_mutex/ + * However a recursive_mutex allows us to maintain the original class + * design as delivered by the contractor. */ - void addJob(std::function newjob); + mutable std::recursive_mutex m_WebMutex; }; } // namespace glasscore #endif // WEB_H diff --git a/glasscore/glasslib/include/WebList.h b/glasscore/glasslib/include/WebList.h index b20cba00..6ce02c40 100644 --- a/glasscore/glasslib/include/WebList.h +++ b/glasscore/glasslib/include/WebList.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace glasscore { @@ -65,7 +66,7 @@ class CWebList { * \return Returns true if the communication was handled by CWeb, * false otherwise */ - bool dispatch(json::Object *com); + bool dispatch(std::shared_ptr com); /** * \brief Add subnet web ('Grid', etc) from detection fabric @@ -79,7 +80,7 @@ class CWebList { * * \return Always returns true */ - bool addWeb(json::Object *com); + bool addWeb(std::shared_ptr com); /** * \brief Remove subnet compoent ('Grid', etc) from detection fabric @@ -94,7 +95,7 @@ class CWebList { * * \return Always returns true */ - bool removeWeb(json::Object *com); + bool removeWeb(std::shared_ptr com); /** * \brief Add a site to the webs @@ -130,6 +131,36 @@ class CWebList { */ bool statusCheck(); + /** + * \brief CGlass getter + * \return the CGlass pointer + */ + const CGlass* getGlass() const; + + /** + * \brief CGlass setter + * \param glass - the CGlass pointer + */ + void setGlass(CGlass* glass); + + /** + * \brief CSiteList getter + * \return the CSiteList pointer + */ + const CSiteList* getSiteList() const; + + /** + * \brief CSiteList setter + * \param siteList - the CSiteList pointer + */ + void setSiteList(CSiteList* siteList); + + /** + * \brief Get the current size of the web list + */ + int getVWebSize() const; + + private: /** * \brief A pointer to the main CGlass class, used to send output, * get sites (stations), encode/decode time, and get debug flags @@ -152,6 +183,15 @@ class CWebList { * a background thread. */ bool m_bUseBackgroundThreads; + + /** + * \brief A recursive_mutex to control threading access to CCorrelationList. + * NOTE: recursive mutexes are frowned upon, so maybe redesign around it + * see: http://www.codingstandard.com/rule/18-3-3-do-not-use-stdrecursive_mutex/ + * However a recursive_mutex allows us to maintain the original class + * design as delivered by the contractor. + */ + mutable std::recursive_mutex m_WebListMutex; }; } // namespace glasscore #endif // WEBLIST_H diff --git a/glasscore/glasslib/src/Correlation.cpp b/glasscore/glasslib/src/Correlation.cpp index 47ceec4f..178509e7 100644 --- a/glasscore/glasslib/src/Correlation.cpp +++ b/glasscore/glasslib/src/Correlation.cpp @@ -41,8 +41,8 @@ CCorrelation::CCorrelation(std::shared_ptr correlationSite, } // ---------------------------------------------------------CCorrelation -CCorrelation::CCorrelation(json::Object *correlation, int correlationId, - CSiteList *pSiteList) { +CCorrelation::CCorrelation(std::shared_ptr correlation, + int correlationId, CSiteList *pSiteList) { clear(); // null check json @@ -114,6 +114,7 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::CLogit::log( glassutil::log_level::error, "CCorrelation::CCorrelation: Missing required Station Key."); + return; } @@ -133,6 +134,7 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::CLogit::log( glassutil::log_level::error, "CCorrelation::CCorrelation: Missing required Network Key."); + return; } @@ -148,6 +150,7 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::CLogit::log( glassutil::log_level::error, "CCorrelation::CCorrelation: Missing required Site Key."); + return; } @@ -160,11 +163,12 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, if (site == NULL) { glassutil::CLogit::log(glassutil::log_level::warn, "CCorrelation::CCorrelation: site is null."); + return; } // check to see if we're using this site - if (!site->bUse) { + if (!site->getUse()) { return; } @@ -179,6 +183,7 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::CLogit::log( glassutil::log_level::error, "CCorrelation::CCorrelation: Missing required Time Key."); + return; } @@ -191,6 +196,7 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::CLogit::log( glassutil::log_level::warn, "CCorrelation::CCorrelation: Missing required ID Key."); + return; } @@ -202,6 +208,7 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::CLogit::log( glassutil::log_level::error, "CCorrelation::CCorrelation: Missing required Phase Key."); + return; } @@ -222,6 +229,7 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::log_level::error, "CCorrelation::CCorrelation: Missing required Hypocenter" " Latitude Key."); + return; } @@ -234,6 +242,7 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::log_level::error, "CCorrelation::CCorrelation: Missing required Hypocenter" " Longitude Key."); + return; } @@ -246,6 +255,7 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::log_level::error, "CCorrelation::CCorrelation: Missing required Hypocenter" " Depth Key."); + return; } @@ -262,6 +272,7 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::log_level::error, "CCorrelation::CCorrelation: Missing required Hypocenter" " Time Key."); + return; } @@ -270,6 +281,7 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::CLogit::log( glassutil::log_level::error, "CCorrelation::CCorrelation: Missing required Hypocenter Key."); + return; } @@ -282,6 +294,7 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::CLogit::log( glassutil::log_level::warn, "CCorrelation::CCorrelation: Missing required Correlation Key."); + return; } @@ -291,15 +304,16 @@ CCorrelation::CCorrelation(json::Object *correlation, int correlationId, glassutil::CLogit::log( glassutil::log_level::error, "CCorrelation::CCorrelation: Failed to initialize correlation."); + return; } - std::lock_guard guard(correlationMutex); + std::lock_guard guard(correlationMutex); // remember input json for hypo message generation // note move to init? - std::shared_ptr jcorr(new json::Object(*correlation)); - jCorrelation = jcorr; + // std::shared_ptr jcorr(new json::Object(*correlation)); + jCorrelation = correlation; } // ---------------------------------------------------------~CCorrelation @@ -309,11 +323,12 @@ CCorrelation::~CCorrelation() { // ---------------------------------------------------------clear void CCorrelation::clear() { - std::lock_guard guard(correlationMutex); + std::lock_guard guard(correlationMutex); + + pSite.reset(); + wpHypo.reset(); + jCorrelation.reset(); - pSite = NULL; - pHypo = NULL; - jCorrelation = NULL; sAss = ""; sPhs = ""; sPid = ""; @@ -341,7 +356,7 @@ bool CCorrelation::initialize(std::shared_ptr correlationSite, return (false); } - std::lock_guard guard(correlationMutex); + std::lock_guard guard(correlationMutex); pSite = correlationSite; sPhs = phase; @@ -359,7 +374,7 @@ bool CCorrelation::initialize(std::shared_ptr correlationSite, glassutil::CLogit::log( glassutil::log_level::debug, - "CCorrelation::initialize: pSite:" + pSite->sScnl + "CCorrelation::initialize: pSite:" + pSite->getScnl() + "; tCorrelation:" + std::to_string(tCorrelation) + "; idCorrelation:" + std::to_string(idCorrelation) + "; sPid:" + sPid + "; sPhs:" + sPhs + "; tOrg:" @@ -374,6 +389,8 @@ bool CCorrelation::initialize(std::shared_ptr correlationSite, // ---------------------------------------------------------addHypo void CCorrelation::addHypo(std::shared_ptr hyp, std::string ass, bool force) { + std::lock_guard guard(correlationMutex); + // nullcheck if (hyp == NULL) { glassutil::CLogit::log( @@ -382,20 +399,20 @@ void CCorrelation::addHypo(std::shared_ptr hyp, std::string ass, return; } - std::lock_guard guard(correlationMutex); - - // Add hypo data reference to this correlation + // Add hypo data reference to this pick if (force == true) { - pHypo = hyp; + wpHypo = hyp; sAss = ass; - } else if (!pHypo) { - pHypo = hyp; + } else if (wpHypo.expired() == true) { + wpHypo = hyp; sAss = ass; } } // ---------------------------------------------------------remHypo void CCorrelation::remHypo(std::shared_ptr hyp) { + std::lock_guard guard(correlationMutex); + // nullcheck if (hyp == NULL) { glassutil::CLogit::log(glassutil::log_level::error, @@ -403,25 +420,86 @@ void CCorrelation::remHypo(std::shared_ptr hyp) { return; } - std::lock_guard guard(correlationMutex); - - // Remove hypo reference from this corrleation - if (pHypo->sPid == hyp->sPid) { - pHypo = NULL; + // is the pointer still valid + if (auto pHypo = wpHypo.lock()) { + // Remove hypo reference from this pick + if (pHypo->getPid() == hyp->getPid()) { + clearHypo(); + } + } else { + // remove invalid pointer + clearHypo(); } } void CCorrelation::clearHypo() { - std::lock_guard guard(correlationMutex); - pHypo = NULL; + std::lock_guard guard(correlationMutex); + wpHypo.reset(); } -void CCorrelation::setAss(std::string ass) { - std::lock_guard guard(correlationMutex); +double CCorrelation::getCorrelation() const { + return (dCorrelation); +} + +double CCorrelation::getLat() const { + return (dLat); +} +double CCorrelation::getLon() const { + return (dLon); +} + +double CCorrelation::getZ() const { + return (dZ); +} + +int CCorrelation::getIdCorrelation() const { + return (idCorrelation); +} + +const std::shared_ptr& CCorrelation::getJCorrelation() const { + return (jCorrelation); +} + +const std::shared_ptr CCorrelation::getHypo() const { + std::lock_guard guard(correlationMutex); + return (wpHypo.lock()); +} + +const std::shared_ptr& CCorrelation::getSite() const { + return (pSite); +} + +const std::string& CCorrelation::getAss() const { + std::lock_guard guard(correlationMutex); + return (sAss); +} + +void CCorrelation::setAss(std::string ass) { + std::lock_guard guard(correlationMutex); sAss = ass; } +const std::string& CCorrelation::getPhs() const { + return (sPhs); +} + +const std::string& CCorrelation::getPid() const { + return (sPid); +} + +double CCorrelation::getTCorrelation() const { + return (tCorrelation); +} + +double CCorrelation::getTGlassCreate() const { + return (tGlassCreate); +} + +double CCorrelation::getTOrg() const { + return (tOrg); +} + } // namespace glasscore /* diff --git a/glasscore/glasslib/src/CorrelationList.cpp b/glasscore/glasslib/src/CorrelationList.cpp index 9b3ba9a8..ff13e28c 100644 --- a/glasscore/glasslib/src/CorrelationList.cpp +++ b/glasscore/glasslib/src/CorrelationList.cpp @@ -32,7 +32,7 @@ CCorrelationList::~CCorrelationList() { // ---------------------------------------------------------clear void CCorrelationList::clear() { - std::lock_guard listGuard(m_vCorrelationMutex); + std::lock_guard corrListGuard(m_CorrelationListMutex); pGlass = NULL; pSiteList = NULL; @@ -56,7 +56,7 @@ void CCorrelationList::clearCorrelations() { } // ---------------------------------------------------------dispatch -bool CCorrelationList::dispatch(json::Object *com) { +bool CCorrelationList::dispatch(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log( @@ -97,7 +97,8 @@ bool CCorrelationList::dispatch(json::Object *com) { } // ---------------------------------------------------------addCorrelation -bool CCorrelationList::addCorrelation(json::Object *correlation) { +bool CCorrelationList::addCorrelation( + std::shared_ptr correlation) { std::lock_guard listGuard(m_vCorrelationMutex); // null check json @@ -142,18 +143,20 @@ bool CCorrelationList::addCorrelation(json::Object *correlation) { pSiteList); // check to see if we got a valid correlation - if ((newCorrelation->pSite == NULL) || (newCorrelation->tCorrelation == 0) - || (newCorrelation->sPid == "")) { + if ((newCorrelation->getSite() == NULL) + || (newCorrelation->getTCorrelation() == 0) + || (newCorrelation->getPid() == "")) { // cleanup delete (newCorrelation); - return (false); + // message was processed + return (true); } // check if correlation is duplicate, if pGlass exists if (pGlass) { - bool duplicate = checkDuplicate(newCorrelation, - pGlass->correlationMatchingTWindow, - pGlass->correlationMatchingXWindow); + bool duplicate = checkDuplicate( + newCorrelation, pGlass->getCorrelationMatchingTWindow(), + pGlass->getCorrelationMatchingXWindow()); // it is a duplicate, log and don't add correlation if (duplicate) { @@ -162,7 +165,8 @@ bool CCorrelationList::addCorrelation(json::Object *correlation) { "CCorrelationList::addCorrelation: Duplicate correlation " "not passed in."); delete (newCorrelation); - return (false); + // message was processed + return (true); } } @@ -185,11 +189,11 @@ bool CCorrelationList::addCorrelation(json::Object *correlation) { // get maximum number of correlations // use max correlations from pGlass if we have it if (pGlass) { - nCorrelationMax = pGlass->nCorrelationMax; + nCorrelationMax = pGlass->getCorrelationMax(); } // create pair for insertion - std::pair p(corr->tCorrelation, nCorrelation); + std::pair p(corr->getTCorrelation(), nCorrelation); // check to see if we're at the correlation limit if (vCorrelation.size() == nCorrelationMax) { @@ -207,7 +211,7 @@ bool CCorrelationList::addCorrelation(json::Object *correlation) { // Insert new correlation in proper time sequence into correlation vector // get the index of the new correlation - int iCorrelation = indexCorrelation(corr->tCorrelation); + int iCorrelation = indexCorrelation(corr->getTCorrelation()); switch (iCorrelation) { case -2: // Empty vector, just add it @@ -236,29 +240,28 @@ bool CCorrelationList::addCorrelation(json::Object *correlation) { mCorrelation[nCorrelation] = corr; // make sure we have a pGlass and pGlass->pHypoList - if ((pGlass) && (pGlass->pHypoList)) { + if ((pGlass) && (pGlass->getHypoList())) { // Attempt association of the new correlation. If that fails create a // new hypo from the correlation - if (!pGlass->pHypoList->associate(corr)) { + if (!pGlass->getHypoList()->associate(corr)) { // not associated, we need to create a new hypo // NOTE: maybe move below to CCorrelation function to match pick? // correlations don't have a second travel time - traveltime::CTravelTime* nullTrav = NULL; + std::shared_ptr nullTrav; // create new hypo - pGlass->m_TTTMutex.lock(); std::shared_ptr hypo = std::make_shared( - corr, pGlass->pTrvDefault.get(), nullTrav, pGlass->pTTT); - pGlass->m_TTTMutex.unlock(); + corr, pGlass->getTrvDefault(), nullTrav, + pGlass->getTTT()); // set hypo glass pointer and such - hypo->pGlass = pGlass; - hypo->dCutFactor = pGlass->dCutFactor; - hypo->dCutPercentage = pGlass->dCutPercentage; - hypo->dCutMin = pGlass->dCutMin; - hypo->nCut = pGlass->nNucleate; - hypo->dThresh = pGlass->dThresh; + hypo->setGlass(pGlass); + hypo->setCutFactor(pGlass->getCutFactor()); + hypo->setCutPercentage(pGlass->getCutPercentage()); + hypo->setCutMin(pGlass->getCutMin()); + hypo->setCut(pGlass->getNucleate()); + hypo->setThresh(pGlass->getThresh()); // add correlation to hypo hypo->addCorrelation(corr); @@ -270,26 +273,26 @@ bool CCorrelationList::addCorrelation(json::Object *correlation) { // Search for any associable picks that match hypo in the pick list // choosing to not localize after because we trust the correlation // location for this step - pGlass->pPickList->scavenge(hypo); + pGlass->getPickList()->scavenge(hypo); // search for any associable correlations that match hypo in the // correlation list choosing to not localize after because we trust // the correlation location for this step - pGlass->pCorrelationList->scavenge(hypo); + scavenge(hypo); // ensure all data scavanged belong to hypo choosing to not localize // after because we trust the correlation location for this step - pGlass->pHypoList->resolve(hypo); + pGlass->getHypoList()->resolve(hypo); // add hypo to hypo list - pGlass->pHypoList->addHypo(hypo); + pGlass->getHypoList()->addHypo(hypo); // schedule it for processing - pGlass->pHypoList->pushFifo(hypo); + pGlass->getHypoList()->pushFifo(hypo); } } - // we're done + // we're done, message was processed return (true); } @@ -384,10 +387,10 @@ bool CCorrelationList::checkDuplicate(CCorrelation * newCorrelation, } // get the index of the earliest possible match - int it1 = indexCorrelation(newCorrelation->tCorrelation - tWindow); + int it1 = indexCorrelation(newCorrelation->getTCorrelation() - tWindow); // get index of the latest possible correlation - int it2 = indexCorrelation(newCorrelation->tCorrelation + tWindow); + int it2 = indexCorrelation(newCorrelation->getTCorrelation() + tWindow); // index can't be negative, it1/2 negative if correlation before first in // list @@ -409,15 +412,17 @@ bool CCorrelationList::checkDuplicate(CCorrelation * newCorrelation, std::shared_ptr cor = mCorrelation[q.second]; // check if time difference is within window - if (std::abs(newCorrelation->tCorrelation - cor->tCorrelation) + if (std::abs(newCorrelation->getTCorrelation() - cor->getTCorrelation()) < tWindow) { // check if sites match - if (newCorrelation->pSite->sScnl == cor->pSite->sScnl) { + if (newCorrelation->getSite()->getScnl() + == cor->getSite()->getScnl()) { glassutil::CGeo geo1; - geo1.setGeographic(newCorrelation->dLat, newCorrelation->dLon, - newCorrelation->dZ); + geo1.setGeographic(newCorrelation->getLat(), + newCorrelation->getLon(), + newCorrelation->getZ()); glassutil::CGeo geo2; - geo2.setGeographic(cor->dLat, cor->dLon, cor->dZ); + geo2.setGeographic(cor->getLat(), cor->getLon(), cor->getZ()); double delta = RAD2DEG * geo1.delta(&geo2); // check if distance difference is within window @@ -428,12 +433,13 @@ bool CCorrelationList::checkDuplicate(CCorrelation * newCorrelation, "CCorrelationList::checkDuplicate: Duplicate " "(tWindow = " + std::to_string(tWindow) + ", xWindow = " + std::to_string(xWindow) - + ") : old:" + cor->pSite->sScnl + " " - + std::to_string(cor->tCorrelation) + + ") : old:" + cor->getSite()->getScnl() + + " " + + std::to_string(cor->getTCorrelation()) + " new(del):" - + newCorrelation->pSite->sScnl + " " + + newCorrelation->getSite()->getScnl() + " " + std::to_string( - newCorrelation->tCorrelation)); + newCorrelation->getTCorrelation())); return (true); } } @@ -468,15 +474,15 @@ bool CCorrelationList::scavenge(std::shared_ptr hyp, double tDuration) { } glassutil::CLogit::log(glassutil::log_level::debug, - "CCorrelationList::scavenge. " + hyp->sPid); + "CCorrelationList::scavenge. " + hyp->getPid()); // get the index of the correlation to start with // based on the hypo origin time - int it1 = indexCorrelation(hyp->tOrg - tDuration); + int it1 = indexCorrelation(hyp->getTOrg() - tDuration); // get the index of the correlation to end with by using the hypo // origin time plus the provided duration - int it2 = indexCorrelation(hyp->tOrg + tDuration); + int it2 = indexCorrelation(hyp->getTOrg() + tDuration); // index can't be negative // Primarily occurs if origin time is before first correlation @@ -498,7 +504,7 @@ bool CCorrelationList::scavenge(std::shared_ptr hyp, double tDuration) { // get the correlation from the vector auto q = vCorrelation[it]; std::shared_ptr corr = mCorrelation[q.second]; - std::shared_ptr corrHyp = corr->pHypo; + std::shared_ptr corrHyp = corr->getHypo(); // check to see if this correlation is already in this hypo if (hyp->hasCorrelation(corr)) { @@ -507,8 +513,8 @@ bool CCorrelationList::scavenge(std::shared_ptr hyp, double tDuration) { } // check to see if this correlation can be associated with this hypo - if (!hyp->associate(corr, pGlass->correlationMatchingTWindow, - pGlass->correlationMatchingXWindow)) { + if (!hyp->associate(corr, pGlass->getCorrelationMatchingTWindow(), + pGlass->getCorrelationMatchingXWindow())) { // it can't, skip it continue; } @@ -521,19 +527,6 @@ bool CCorrelationList::scavenge(std::shared_ptr hyp, double tDuration) { // add correlation to this hypo hyp->addCorrelation(corr); - if (pGlass->bTrack) { - char sLog[1024]; - snprintf( - sLog, - sizeof(sLog), - "C-WAF %s %s %s (%d)\n", - hyp->sPid.substr(0, 4).c_str(), - glassutil::CDate::encodeDateTime(corr->tCorrelation) - .c_str(), - corr->pSite->sScnl.c_str(), - static_cast(hyp->vCorr.size())); - glassutil::CLogit::Out(sLog); - } // we've associated a correlation bAss = true; @@ -600,10 +593,10 @@ std::vector> CCorrelationList::rogues( // get the current pick from the vector auto q = vCorrelation[it]; std::shared_ptr corr = mCorrelation[q.second]; - std::shared_ptr corrHyp = corr->pHypo; + std::shared_ptr corrHyp = corr->getHypo(); // if the current pick is associated to this event - if ((corrHyp != NULL) && (corrHyp->sPid == pidHyp)) { + if ((corrHyp != NULL) && (corrHyp->getPid() == pidHyp)) { // skip to next pick continue; } @@ -614,4 +607,53 @@ std::vector> CCorrelationList::rogues( return (vRogue); } + +const CSiteList* CCorrelationList::getSiteList() const { + std::lock_guard corrListGuard(m_CorrelationListMutex); + return (pSiteList); +} + +void CCorrelationList::setSiteList(CSiteList* siteList) { + std::lock_guard corrListGuard(m_CorrelationListMutex); + pSiteList = siteList; +} + +const CGlass* CCorrelationList::getGlass() const { + std::lock_guard corrListGuard(m_CorrelationListMutex); + return (pGlass); +} + +void CCorrelationList::setGlass(CGlass* glass) { + std::lock_guard corrListGuard(m_CorrelationListMutex); + pGlass = glass; +} + +int CCorrelationList::getNCorrelation() const { + std::lock_guard vCorrelationGuard( + m_vCorrelationMutex); + return (nCorrelation); +} + +int CCorrelationList::getNCorrelationMax() const { + std::lock_guard corrListGuard(m_CorrelationListMutex); + return (nCorrelationMax); +} + +void CCorrelationList::setNCorrelationMax(int correlationMax) { + std::lock_guard corrListGuard(m_CorrelationListMutex); + nCorrelationMax = correlationMax; +} + +int CCorrelationList::getNCorrelationTotal() const { + std::lock_guard vCorrelationGuard( + m_vCorrelationMutex); + return (nCorrelationTotal); +} + +int CCorrelationList::getVCorrelationSize() const { + std::lock_guard vCorrelationGuard( + m_vCorrelationMutex); + return (vCorrelation.size()); +} + } // namespace glasscore diff --git a/glasscore/glasslib/src/Detection.cpp b/glasscore/glasslib/src/Detection.cpp index de7907e2..4dcd94d0 100644 --- a/glasscore/glasslib/src/Detection.cpp +++ b/glasscore/glasslib/src/Detection.cpp @@ -28,11 +28,12 @@ CDetection::~CDetection() { // ---------------------------------------------------------clear void CDetection::clear() { + std::lock_guard detectionGuard(detectionMutex); pGlass = NULL; } // ---------------------------------------------------------Dispatch -bool CDetection::dispatch(json::Object *com) { +bool CDetection::dispatch(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log( @@ -73,7 +74,7 @@ bool CDetection::dispatch(json::Object *com) { } // ---------------------------------------------------------process -bool CDetection::process(json::Object *com) { +bool CDetection::process(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log( @@ -84,9 +85,12 @@ bool CDetection::process(json::Object *com) { if (pGlass == NULL) { glassutil::CLogit::log(glassutil::log_level::error, "CDetection::process: NULL pGlass."); + return (false); } + std::lock_guard detectionGuard(detectionMutex); + // detection definition variables double torg = 0; double lat = 0; @@ -111,6 +115,7 @@ bool CDetection::process(json::Object *com) { glassutil::CLogit::log( glassutil::log_level::error, "CDetection::process: Missing required Hypocenter Time Key."); + return (false); } @@ -125,6 +130,7 @@ bool CDetection::process(json::Object *com) { glassutil::log_level::error, "CDetection::process: Missing required Hypocenter Latitude" " Key."); + return (false); } @@ -138,6 +144,7 @@ bool CDetection::process(json::Object *com) { glassutil::log_level::error, "CDetection::process: Missing required Hypocenter Longitude" " Key."); + return (false); } @@ -150,27 +157,27 @@ bool CDetection::process(json::Object *com) { glassutil::log_level::error, "CDetection::process: Missing required Hypocenter Depth" " Key."); + return (false); } } else { glassutil::CLogit::log( glassutil::log_level::error, "CDetection::process: Missing required Hypocenter Key."); + return (false); } // Check to see if hypo already exists. We could also // check location at this point, but it seems unlikely // that would add much value - auto hypolist = pGlass->pHypoList; - // define a three minute search window // NOTE: Hard coded. double t1 = torg - 90.0; double t2 = torg + 90.0; // search for the first hypocenter in the window - std::shared_ptr hypo = hypolist->findHypo(t1, t2); + std::shared_ptr hypo = pGlass->getHypoList()->findHypo(t1, t2); // check to see if we found a hypo if (hypo != NULL) { @@ -179,43 +186,51 @@ bool CDetection::process(json::Object *com) { glassutil::CGeo geo1; geo1.setGeographic(lat, lon, z); glassutil::CGeo geo2; - geo2.setGeographic(hypo->dLat, hypo->dLon, hypo->dZ); + geo2.setGeographic(hypo->getLat(), hypo->getLon(), hypo->getZ()); double delta = RAD2DEG * geo1.delta(&geo2); // if the detection is more than 5 degrees away, it isn't a match // NOTE: Hard coded. if (delta > 5.0) { // detections don't have a second travel time - traveltime::CTravelTime* nullTrav = NULL; + std::shared_ptr nullTrav; // create new hypo - pGlass->m_TTTMutex.lock(); hypo = std::make_shared(lat, lon, z, torg, glassutil::CPid::pid(), "Detection", 0.0, 0.0, 0, - pGlass->pTrvDefault.get(), nullTrav, - pGlass->pTTT); - pGlass->m_TTTMutex.unlock(); + pGlass->getTrvDefault(), + nullTrav, pGlass->getTTT()); // set hypo glass pointer and such - hypo->pGlass = pGlass; - hypo->dCutFactor = pGlass->dCutFactor; - hypo->dCutPercentage = pGlass->dCutPercentage; - hypo->dCutMin = pGlass->dCutMin; + hypo->setGlass(pGlass); + hypo->setCutFactor(pGlass->getCutFactor()); + hypo->setCutPercentage(pGlass->getCutPercentage()); + hypo->setCutMin(pGlass->getCutMin()); // process hypo using evolve - if (pGlass->pHypoList->evolve(hypo, 1)) { + if (pGlass->getHypoList()->evolve(hypo, 1)) { // add to hypo list - hypolist->addHypo(hypo); + pGlass->getHypoList()->addHypo(hypo); } } else { // existing hypo, now hwat? // schedule hypo for processing? - hypolist->pushFifo(hypo); + pGlass->getHypoList()->pushFifo(hypo); } } // done return (true); } + +const CGlass* CDetection::getGlass() const { + std::lock_guard detectionGuard(detectionMutex); + return (pGlass); +} + +void CDetection::setGlass(CGlass* glass) { + std::lock_guard detectionGuard(detectionMutex); + pGlass = glass; +} } // namespace glasscore diff --git a/glasscore/glasslib/src/Glass.cpp b/glasscore/glasslib/src/Glass.cpp index ddfc4bef..5358a239 100644 --- a/glasscore/glasslib/src/Glass.cpp +++ b/glasscore/glasslib/src/Glass.cpp @@ -38,10 +38,6 @@ CGlass::CGlass() { nCorrelationMax = 1000; nSitePickMax = 200; nHypoMax = 100; - bTrack = false; - sWeb = "Nada"; - nCount = 0; - dSum = 0.0; graphicsOut = false; graphicsOutFolder = "./"; graphicsStepKM = 1.; @@ -76,7 +72,7 @@ CGlass::~CGlass() { } // ---------------------------------------------------------dispatch -bool CGlass::dispatch(json::Object *com) { +bool CGlass::dispatch(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log(glassutil::log_level::error, @@ -91,30 +87,23 @@ bool CGlass::dispatch(json::Object *com) { json::Value v = (*com)["Cmd"].ToString(); // log cmd if it isn't one of the common ones - if ((v != "Site") && (v != "Ping") && (v != "Pick")) { + if ((v != "Site") && (v != "ReqHypo") && (v != "Correlation") + && (v != "Pick")) { glassutil::CLogit::log(glassutil::log_level::debug, "CGlass::dispatch: Cmd:" + v.ToString()); } - if (v == "Ping") { - return (ping(com)); - } - - // reset debugging values - nIterate = 0; - nLocate = 0; - // generate travel time file // NOTE: Move to stand alone program // if (v == "GenTrv") { - // return (genTrv(com)); + // return((genTrv(com)); // } // test travel time classes // NOTE: Move to unit tests. // if (v == "TestTTT") { // testTTT(com); - // return (true); + // return(true); // } // Initialize glass @@ -183,7 +172,7 @@ bool CGlass::dispatch(json::Object *com) { } // ---------------------------------------------------------send -bool CGlass::send(json::Object *com) { +bool CGlass::send(std::shared_ptr com) { // make sure we have something to send to if (piSend) { // send the communication @@ -230,7 +219,7 @@ void CGlass::clear() { } // ---------------------------------------------------------Initialize -bool CGlass::initialize(json::Object *com) { +bool CGlass::initialize(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log(glassutil::log_level::error, @@ -324,7 +313,7 @@ bool CGlass::initialize(json::Object *com) { json::Array phases = (*com)["AssociationPhases"].ToArray(); // create and initialize travel time list - pTTT = new traveltime::CTTT(); + pTTT = std::make_shared(); // for each phase in the array for (auto val : phases) { @@ -838,20 +827,6 @@ bool CGlass::initialize(json::Object *com) { "parameters"); } - // bTrack - if ((com->HasKey("Track")) - && ((*com)["Track"].GetType() == json::ValueType::BoolVal)) { - bTrack = (*com)["Track"].ToBool(); - - if (bTrack) { - glassutil::CLogit::log(glassutil::log_level::info, - "CGlass::initialize: Track set to true"); - } else { - glassutil::CLogit::log(glassutil::log_level::info, - "CGlass::initialize: Track set to false"); - } - } - // Test Locator if ((com->HasKey("TestLocator")) && ((*com)["TestLocator"].GetType() == json::ValueType::BoolVal)) { @@ -1018,7 +993,7 @@ bool CGlass::initialize(json::Object *com) { // create site list pSiteList = new CSiteList(); - pSiteList->pGlass = this; + pSiteList->setGlass(this); // clean out old web list if any if (pWebList) { @@ -1027,8 +1002,8 @@ bool CGlass::initialize(json::Object *com) { // create detection web list pWebList = new CWebList(webBackgroundUpdate); - pWebList->pGlass = this; - pWebList->pSiteList = pSiteList; + pWebList->setGlass(this); + pWebList->setSiteList(pSiteList); // clean out old pick list if any if (pPickList) { @@ -1037,8 +1012,8 @@ bool CGlass::initialize(json::Object *com) { // create pick list pPickList = new CPickList(numNucleationThreads); - pPickList->pGlass = this; - pPickList->pSiteList = pSiteList; + pPickList->setGlass(this); + pPickList->setSiteList(pSiteList); // clean out old correlation list if any if (pCorrelationList) { @@ -1047,8 +1022,8 @@ bool CGlass::initialize(json::Object *com) { // create correlation list pCorrelationList = new CCorrelationList(); - pCorrelationList->pGlass = this; - pCorrelationList->pSiteList = pSiteList; + pCorrelationList->setGlass(this); + pCorrelationList->setSiteList(pSiteList); // clean out old hypo list if any if (pHypoList) { @@ -1057,67 +1032,15 @@ bool CGlass::initialize(json::Object *com) { // create hypo list pHypoList = new CHypoList(numHypoThreads); - pHypoList->pGlass = this; - - // configure output format - if ((com->HasKey("OutputFormat")) - && ((*com)["OutputFormat"].GetType() == json::ValueType::StringVal)) { - // get the output format - std::string outputformat = (*com)["OutputFormat"].ToString(); - - // set up based on output format - if (outputformat == "Event") { - pHypoList->bSendEvent = true; - - glassutil::CLogit::log( - glassutil::log_level::info, - "CGlass::initialize: Using output format Event"); - } else { - pHypoList->bSendEvent = false; - - glassutil::CLogit::log( - glassutil::log_level::info, - "CGlass::initialize: Using default output format Event"); - } - } else { - // default to sending quake messages - pHypoList->bSendEvent = false; - - glassutil::CLogit::log( - glassutil::log_level::info, - "CGlass::initialize: Using default output format Quake"); - } + pHypoList->setGlass(this); // create detection processor pDetection = new CDetection(); - pDetection->pGlass = this; + pDetection->setGlass(this); return (true); } -// ---------------------------------------------------------Ping -bool CGlass::ping(json::Object *com) { - // NOTE: This function only had relevance for Caryl, consider removing - json::Object pong; - pong["Cmd"] = "Pong"; - int npicks = 0; - int nquakes = 0; - if (pPickList) { - npicks = pPickList->vPick.size(); - } - if (pHypoList) { - nquakes = pHypoList->vHypo.size(); - } - pong["nPicks"] = npicks; - pong["nQuakes"] = nquakes; - pong["nLoc"] = nLocate; - pong["nIter"] = nIterate; - pong["Web"] = sWeb; - pong["Sum"] = dSum; - pong["Count"] = nCount; - send(&pong); - return true; -} /* NOTE: Leave these in place as examples for Travel Time unit tests. * // ---------------------------------------------------------Test @@ -1133,7 +1056,7 @@ bool CGlass::ping(json::Object *com) { bool bload = terra->load(mdl.c_str()); if (!bload) - return false; + return(false; printf("Terra nLayer:%ld dRadius:%.2f\n", terra->nLayer, terra->dRadius); double r = terra->dRadius; @@ -1152,7 +1075,7 @@ bool CGlass::ping(json::Object *com) { printf("T %6.2f %6.2f %6.2f %6.2f\n", deg, t1, t2, t2 - t1); } - return true; + return(true; } // ---------------------------------------------------------GenTrv @@ -1163,7 +1086,7 @@ bool CGlass::ping(json::Object *com) { gentrv = new CGenTrv(); bool bres = gentrv->Generate(com); delete gentrv; - return bres; + return(bres; } // ---------------------------------------------------------TestTTT @@ -1213,7 +1136,7 @@ bool CGlass::ping(json::Object *com) { // It is used for pruning and association, and is roughly // analogous to residual pruning in least squares approaches double CGlass::sig(double x, double sigma) { - return exp(-0.5 * x * x / sigma / sigma); + return (exp(-0.5 * x * x / sigma / sigma)); } // ---------------------------------------------------------Sig // Calculate the laplacian significance function, which is just @@ -1221,9 +1144,9 @@ double CGlass::sig(double x, double sigma) { // analogous to residual pruning in L1 approach. double CGlass::sig_laplace_pdf(double x, double sigma) { if (x > 0) { - return (1. / (2. * sigma)) * exp(-1. * x / sigma); + return ((1. / (2. * sigma)) * exp(-1. * x / sigma)); } else { - return (1. / (2. * sigma)) * exp(x / sigma); + return ((1. / (2. * sigma)) * exp(x / sigma)); } } @@ -1252,4 +1175,163 @@ bool CGlass::statusCheck() { // all is well return (true); } + +double CGlass::getAvgDelta() const { + return (avgDelta); +} + +double CGlass::getAvgSigma() const { + return (avgSigma); +} + +double CGlass::getBeamMatchingAzimuthWindow() const { + return (beamMatchingAzimuthWindow); +} + +double CGlass::getBeamMatchingDistanceWindow() const { + return (beamMatchingDistanceWindow); +} + +int CGlass::getCorrelationCancelAge() const { + return (correlationCancelAge); +} + +double CGlass::getCorrelationMatchingTWindow() const { + return (correlationMatchingTWindow); +} + +double CGlass::getCorrelationMatchingXWindow() const { + return (correlationMatchingXWindow); +} + +double CGlass::getCutFactor() const { + return (dCutFactor); +} + +double CGlass::getCutMin() const { + return (dCutMin); +} + +double CGlass::getCutPercentage() const { + return (dCutPercentage); +} + +double CGlass::getReportThresh() const { + return (dReportThresh); +} + +double CGlass::getThresh() const { + return (dThresh); +} + +double CGlass::getExpAffinity() const { + return (expAffinity); +} + +bool CGlass::getGraphicsOut() const { + return (graphicsOut); +} + +const std::string& CGlass::getGraphicsOutFolder() const { + return (graphicsOutFolder); +} + +double CGlass::getGraphicsStepKm() const { + return (graphicsStepKM); +} + +int CGlass::getGraphicsSteps() const { + return (graphicsSteps); +} + +int CGlass::getCycleLimit() const { + return (iCycleLimit); +} + +bool CGlass::getMinimizeTtLocator() const { + return (minimizeTTLocator); +} + +int CGlass::getCorrelationMax() const { + return (nCorrelationMax); +} + +int CGlass::getDetect() const { + return (nDetect); +} + +int CGlass::getHypoMax() const { + return (nHypoMax); +} + +int CGlass::getNucleate() const { + return (nNucleate); +} + +int CGlass::getPickMax() const { + return (nPickMax); +} + +double CGlass::getReportCut() const { + return (nReportCut); +} + +int CGlass::getSitePickMax() const { + return (nSitePickMax); +} + +CCorrelationList*& CGlass::getCorrelationList() { + return (pCorrelationList); +} + +CDetection*& CGlass::getDetection() { + return (pDetection); +} + +CHypoList*& CGlass::getHypoList() { + return (pHypoList); +} + +double CGlass::getPickDuplicateWindow() const { + return (pickDuplicateWindow); +} + +CPickList*& CGlass::getPickList() { + return (pPickList); +} + +CSiteList*& CGlass::getSiteList() { + return (pSiteList); +} + +std::shared_ptr& CGlass::getTrvDefault() { + std::lock_guard ttGuard(m_TTTMutex); + return (pTrvDefault); +} + +std::shared_ptr& CGlass::getTTT() { + std::lock_guard ttGuard(m_TTTMutex); + return (pTTT); +} + +CWebList*& CGlass::getWebList() { + return (pWebList); +} + +double CGlass::getSdAssociate() const { + return (sdAssociate); +} + +double CGlass::getSdPrune() const { + return (sdPrune); +} + +bool CGlass::getTestLocator() const { + return (testLocator); +} + +bool CGlass::getTestTimes() const { + return (testTimes); +} + } // namespace glasscore diff --git a/glasscore/glasslib/src/Hypo.cpp b/glasscore/glasslib/src/Hypo.cpp index 1e09e3ed..9c8e18b5 100644 --- a/glasscore/glasslib/src/Hypo.cpp +++ b/glasscore/glasslib/src/Hypo.cpp @@ -15,7 +15,7 @@ #include "HypoList.h" #include "Pick.h" #include "Correlation.h" -#include "Node.h" +#include "Trigger.h" #include "Web.h" #include "Glass.h" #include "Logit.h" @@ -28,7 +28,7 @@ namespace glasscore { * \brief Pick sorting function used by CHypo, sorts by pick time */ static bool sortPick(std::shared_ptr pck1, std::shared_ptr pck2) { - if (pck2->tPick > pck1->tPick) { + if (pck2->getTPick() > pck1->getTPick()) { return (true); } @@ -40,9 +40,6 @@ CHypo::CHypo() { // seed the random number generator std::random_device randomDevice; m_RandomGenerator.seed(randomDevice()); - pTTT = NULL; - pTrv1 = NULL; - pTrv2 = NULL; clear(); } @@ -50,15 +47,12 @@ CHypo::CHypo() { // ---------------------------------------------------------CHypo CHypo::CHypo(double lat, double lon, double z, double time, std::string pid, std::string web, double bayes, double thresh, int cut, - traveltime::CTravelTime* firstTrav, - traveltime::CTravelTime* secondTrav, traveltime::CTTT *ttt, - double resolution) { + std::shared_ptr firstTrav, + std::shared_ptr secondTrav, + std::shared_ptr ttt, double resolution) { // seed the random number generator std::random_device randomDevice; m_RandomGenerator.seed(randomDevice()); - pTTT = NULL; - pTrv1 = NULL; - pTrv2 = NULL; if (!initialize(lat, lon, z, time, pid, web, bayes, thresh, cut, firstTrav, secondTrav, ttt, resolution)) { @@ -67,16 +61,14 @@ CHypo::CHypo(double lat, double lon, double z, double time, std::string pid, } // ---------------------------------------------------------CHypo -CHypo::CHypo(std::shared_ptr node, traveltime::CTTT *ttt) { +CHypo::CHypo(std::shared_ptr trigger, + std::shared_ptr ttt) { // seed the random number generator std::random_device randomDevice; m_RandomGenerator.seed(randomDevice()); - pTTT = NULL; - pTrv1 = NULL; - pTrv2 = NULL; // null checks - if (node == NULL) { + if (trigger == NULL) { glassutil::CLogit::log(glassutil::log_level::error, "CHypo::CHypo: NULL node."); @@ -84,30 +76,30 @@ CHypo::CHypo(std::shared_ptr node, traveltime::CTTT *ttt) { return; } - if (node->pWeb == NULL) { + if (trigger->getWeb() == NULL) { glassutil::CLogit::log(glassutil::log_level::error, - "CHypo::CHypo: NULL node->pWeb."); + "CHypo::CHypo: NULL trigger->getWeb()."); clear(); return; } - // lock for trv copying - std::lock_guard < std::mutex > ttGuard(node->pWeb->m_TrvMutex); - - if (!initialize(node->dLat, node->dLon, node->dZ, node->tOrg, - glassutil::CPid::pid(), node->pWeb->sName, 0.0, - node->pWeb->dThresh, node->pWeb->nNucleate, - node->pWeb->pTrv1.get(), node->pWeb->pTrv2.get(), ttt, - node->dResolution)) { + if (!initialize(trigger->getLat(), trigger->getLon(), trigger->getZ(), + trigger->getTOrg(), glassutil::CPid::pid(), + trigger->getWeb()->getName(), trigger->getSum(), + trigger->getWeb()->getThresh(), + trigger->getWeb()->getNucleate(), + trigger->getWeb()->getTrv1(), trigger->getWeb()->getTrv2(), + ttt, trigger->getResolution())) { clear(); } } // ---------------------------------------------------------CHypo CHypo::CHypo(std::shared_ptr corr, - traveltime::CTravelTime* firstTrav, - traveltime::CTravelTime* secondTrav, traveltime::CTTT *ttt) { + std::shared_ptr firstTrav, + std::shared_ptr secondTrav, + std::shared_ptr ttt) { // seed the random number generator std::random_device randomDevice; m_RandomGenerator.seed(randomDevice()); @@ -124,9 +116,9 @@ CHypo::CHypo(std::shared_ptr corr, return; } - if (!initialize(corr->dLat, corr->dLon, corr->dZ, corr->tOrg, - glassutil::CPid::pid(), "Correlation", 0.0, 0.0, 0.0, - firstTrav, secondTrav, ttt, 0.0)) { + if (!initialize(corr->getLat(), corr->getLon(), corr->getZ(), + corr->getTOrg(), glassutil::CPid::pid(), "Correlation", 0.0, + 0.0, 0.0, firstTrav, secondTrav, ttt, 0.0)) { clear(); } } @@ -139,7 +131,7 @@ CHypo::~CHypo() { // ---------------------------------------------------------clear void CHypo::clear() { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); dLat = 0.0; dLon = 0.0; @@ -152,7 +144,7 @@ void CHypo::clear() { dBayesInitial = 0.0; iCycle = 0; nWts = 0; - sWeb = ""; + sWebName = ""; dMed = 0; dMin = 0; dGap = 0; @@ -165,26 +157,13 @@ void CHypo::clear() { dCutMin = 30.0; bFixed = false; - bRefine = false; - bQuake = false; bEvent = false; pGlass = NULL; - if (pTrv1) { - delete (pTrv1); - } - pTrv1 = NULL; - - if (pTrv2) { - delete (pTrv2); - } - pTrv2 = NULL; - - if (pTTT) { - delete (pTTT); - } - pTTT = NULL; + pTTT.reset(); + pTrv1.reset(); + pTrv2.reset(); bCorrAdded = false; @@ -200,11 +179,12 @@ void CHypo::clear() { bool CHypo::initialize(double lat, double lon, double z, double time, std::string pid, std::string web, double bayes, double thresh, int cut, - traveltime::CTravelTime* firstTrav, - traveltime::CTravelTime* secondTrav, - traveltime::CTTT *ttt, double resolution) { + std::shared_ptr firstTrav, + std::shared_ptr secondTrav, + std::shared_ptr ttt, + double resolution) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); clear(); @@ -213,7 +193,7 @@ bool CHypo::initialize(double lat, double lon, double z, double time, dZ = z; tOrg = time; sPid = pid; - sWeb = web; + sWebName = web; dBayes = bayes; dBayesInitial = bayes; @@ -229,23 +209,26 @@ bool CHypo::initialize(double lat, double lon, double z, double time, "CHypo::initialize: lat:" + std::to_string(dLat) + "; lon:" + std::to_string(dLon) + "; z:" + std::to_string(dZ) + "; t:" + std::to_string(tOrg) + "; sPid:" + sPid - + "; web:" + sWeb + "; bayes:" + std::to_string(dBayes) + + "; web:" + sWebName + "; bayes:" + std::to_string(dBayes) + "; thresh:" + std::to_string(dThresh) + "; cut:" + std::to_string(nCut) + "; resolution:" + std::to_string(dRes)); + // make local copies of the travel times so that we don't + // have cross-thread contention for them between hypos if (firstTrav != NULL) { - pTrv1 = new traveltime::CTravelTime(*firstTrav); + pTrv1 = std::make_shared( + traveltime::CTravelTime(*firstTrav)); } - if (secondTrav) { - pTrv2 = new traveltime::CTravelTime(*secondTrav); + if (secondTrav != NULL) { + pTrv2 = std::make_shared( + traveltime::CTravelTime(*secondTrav)); } if (ttt != NULL) { - pTTT = new traveltime::CTTT(*ttt); + pTTT = std::make_shared(traveltime::CTTT(*ttt)); } - tCreate = glassutil::CDate::now(); return (true); @@ -254,7 +237,7 @@ bool CHypo::initialize(double lat, double lon, double z, double time, // ---------------------------------------------------------addPick void CHypo::addPick(std::shared_ptr pck) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // null check if (pck == NULL) { @@ -268,10 +251,10 @@ void CHypo::addPick(std::shared_ptr pck) { // see if we have this same pick // NOTE: this only checks by ID, need to improve this to // an ID/Source check - if (q->sPid == pck->sPid) { + if (q->getPid() == pck->getPid()) { char sLog[1024]; snprintf(sLog, sizeof(sLog), "CHypo::addPick: ** Duplicate pick %s", - pck->pSite->sScnl.c_str()); + pck->getSite()->getScnl().c_str()); glassutil::CLogit::log(sLog); // NOTE: shouldn't we not add this duplicate pick? @@ -282,17 +265,10 @@ void CHypo::addPick(std::shared_ptr pck) { vPick.push_back(pck); } -void CHypo::incrementProcessCount() { - // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); - - processCount++; -} - // ---------------------------------------------------------remPick void CHypo::remPick(std::shared_ptr pck) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // null check if (pck == NULL) { @@ -302,7 +278,7 @@ void CHypo::remPick(std::shared_ptr pck) { } // get the pick id - std::string pid = pck->sPid; + std::string pid = pck->getPid(); // for each pick in the vector for (int i = 0; i < vPick.size(); i++) { @@ -310,7 +286,7 @@ void CHypo::remPick(std::shared_ptr pck) { auto pick = vPick[i]; // is this pick a match? - if (pick->sPid == pid) { + if (pick->getPid() == pid) { // remove pick from vector vPick.erase(vPick.cbegin() + i); @@ -321,7 +297,7 @@ void CHypo::remPick(std::shared_ptr pck) { bool CHypo::hasPick(std::shared_ptr pck) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // null check if (pck == NULL) { @@ -333,7 +309,7 @@ bool CHypo::hasPick(std::shared_ptr pck) { // for each pick in the vector for (const auto &q : vPick) { // is this pick a match? - if (q->sPid == pck->sPid) { + if (q->getPid() == pck->getPid()) { return (true); } } @@ -343,7 +319,7 @@ bool CHypo::hasPick(std::shared_ptr pck) { void CHypo::clearPicks() { // lock the hypo since we're iterating through it's lists - std::lock_guard < std::recursive_mutex > hypoGuard(hypoMutex); + std::lock_guard hypoGuard(hypoMutex); // go through all the picks linked to this hypo for (auto pck : vPick) { @@ -352,9 +328,9 @@ void CHypo::clearPicks() { } // if the current pick is linked to this hypo - if ((pck->pHypo != NULL) && (sPid == pck->pHypo->sPid)) { + if ((pck->getHypo() != NULL) && (sPid == pck->getHypo()->getPid())) { // remove hypo link from this pick - pck->pHypo = NULL; + pck->clearHypo(); } } @@ -365,7 +341,7 @@ void CHypo::clearPicks() { // ---------------------------------------------------------addPick void CHypo::addCorrelation(std::shared_ptr corr) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // null check if (corr == NULL) { @@ -379,11 +355,11 @@ void CHypo::addCorrelation(std::shared_ptr corr) { // see if we have this same correlation // NOTE: this only checks by ID, need to improve this to // an ID/Source check - if (q->sPid == corr->sPid) { + if (q->getPid() == corr->getPid()) { char sLog[1024]; snprintf(sLog, sizeof(sLog), "CHypo::addCorrelation: ** Duplicate correlation %s", - corr->pSite->sScnl.c_str()); + corr->getSite()->getScnl().c_str()); glassutil::CLogit::log(sLog); return; @@ -398,7 +374,7 @@ void CHypo::addCorrelation(std::shared_ptr corr) { // ---------------------------------------------------------remPick void CHypo::remCorrelation(std::shared_ptr corr) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // null check if (corr == NULL) { @@ -408,7 +384,7 @@ void CHypo::remCorrelation(std::shared_ptr corr) { } // get the correlation id - std::string pid = corr->sPid; + std::string pid = corr->getPid(); // for each correlation in the vector for (int i = 0; i < vCorr.size(); i++) { @@ -416,7 +392,7 @@ void CHypo::remCorrelation(std::shared_ptr corr) { auto correlation = vCorr[i]; // is this correlation a match? - if (correlation->sPid == pid) { + if (correlation->getPid() == pid) { // remove correlation from vector vCorr.erase(vCorr.cbegin() + i); return; @@ -426,7 +402,7 @@ void CHypo::remCorrelation(std::shared_ptr corr) { bool CHypo::hasCorrelation(std::shared_ptr corr) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // null check if (corr == NULL) { @@ -438,7 +414,7 @@ bool CHypo::hasCorrelation(std::shared_ptr corr) { // for each corr in the vector for (const auto &q : vCorr) { // is this corr a match? - if (q->sPid == corr->sPid) { + if (q->getPid() == corr->getPid()) { return (true); } } @@ -448,7 +424,7 @@ bool CHypo::hasCorrelation(std::shared_ptr corr) { void CHypo::clearCorrelations() { // lock the hypo since we're iterating through it's lists - std::lock_guard < std::recursive_mutex > hypoGuard(hypoMutex); + std::lock_guard hypoGuard(hypoMutex); // go through all the picks linked to this hypo for (auto corr : vCorr) { @@ -457,9 +433,9 @@ void CHypo::clearCorrelations() { } // if the current pick is linked to this hypo - if ((corr->pHypo != NULL) && (sPid == corr->pHypo->sPid)) { + if ((corr->getHypo() != NULL) && (sPid == corr->getHypo()->getPid())) { // remove hypo link from this pick - corr->pHypo = NULL; + corr->clearHypo(); } } @@ -499,11 +475,13 @@ double CHypo::Rand(double x, double y) { } // ---------------------------------------------------------Hypo -json::Object CHypo::hypo() { +std::shared_ptr CHypo::hypo() { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); + + std::shared_ptr hypo = std::make_shared( + json::Object()); - json::Object hypo; // null check if (pGlass == NULL) { glassutil::CLogit::log(glassutil::log_level::warn, @@ -526,8 +504,8 @@ json::Object CHypo::hypo() { glassutil::CLogit::log( glassutil::log_level::debug, - "CHypo::Hypo: generating hypo message for sPid:" + sPid + " sWeb:" - + sWeb); + "CHypo::Hypo: generating hypo message for sPid:" + sPid + + " sWebName:" + sWebName); // NOTE: Need to think about this format, currently it *almost* // creates a detection formats json, but doesn't use the library @@ -535,9 +513,9 @@ json::Object CHypo::hypo() { // the quake format? // basic info - hypo["Cmd"] = "Hypo"; - hypo["Type"] = "Hypo"; - hypo["ID"] = sPid; + (*hypo)["Cmd"] = "Hypo"; + (*hypo)["Type"] = "Hypo"; + (*hypo)["ID"] = sPid; // source // NOTE: THIS NEEDS TO BE NOT HARDCODED EVENTUALLY @@ -545,23 +523,23 @@ json::Object CHypo::hypo() { json::Object src; src["AgencyID"] = "US"; src["Author"] = "glass"; - hypo["Source"] = src; + (*hypo)["Source"] = src; // time - hypo["T"] = glassutil::CDate::encodeDateTime(tOrg); - hypo["Time"] = glassutil::CDate::encodeISO8601Time(tOrg); + (*hypo)["T"] = glassutil::CDate::encodeDateTime(tOrg); + (*hypo)["Time"] = glassutil::CDate::encodeISO8601Time(tOrg); // location - hypo["Latitude"] = dLat; - hypo["Longitude"] = dLon; - hypo["Depth"] = dZ; + (*hypo)["Latitude"] = dLat; + (*hypo)["Longitude"] = dLon; + (*hypo)["Depth"] = dZ; // supplementary info - hypo["MinimumDistance"] = dMin; - hypo["Gap"] = dGap; - hypo["Bayes"] = dBayes; - hypo["InitialBayes"] = dBayesInitial; - hypo["Web"] = sWeb; + (*hypo)["MinimumDistance"] = dMin; + (*hypo)["Gap"] = dGap; + (*hypo)["Bayes"] = dBayes; + (*hypo)["InitialBayes"] = dBayesInitial; + (*hypo)["Web"] = sWebName; // generate data array for this hypo // set up traveltime object @@ -577,36 +555,38 @@ json::Object CHypo::hypo() { // for each pick for (auto pick : vPick) { // get basic pick values - std::shared_ptr site = pick->pSite; - double tobs = pick->tPick - tOrg; - double tcal = pTTT->T(&site->geo, tobs); + std::shared_ptr site = pick->getSite(); + double tobs = pick->getTPick() - tOrg; + double tcal = pTTT->T(&site->getGeo(), tobs); double tres = tobs - tcal; // should this be changed? double sig = pGlass->sig(tres, 1.0); // if we have it, use the shared pointer json::Object pickObj; - if (pick->jPick) { + std::shared_ptr jPick = pick->getJPick(); + if (jPick) { // start with a copy of json pick // which has the site, source, time, etc - pickObj = json::Object(*pick->jPick.get()); + pickObj = json::Object(*jPick.get()); // add the association info json::Object assocobj; assocobj["Phase"] = pTTT->sPhase; - assocobj["Distance"] = geo.delta(&site->geo) / DEG2RAD; - assocobj["Azimuth"] = geo.azimuth(&site->geo) / DEG2RAD; + assocobj["Distance"] = geo.delta(&site->getGeo()) / DEG2RAD; + assocobj["Azimuth"] = geo.azimuth(&site->getGeo()) / DEG2RAD; assocobj["Residual"] = tres; assocobj["Sigma"] = sig; pickObj["AssociationInfo"] = assocobj; } else { // we don't have a jpick, so fill in what we know - pickObj["Site"] = site->sScnl; - pickObj["Pid"] = pick->sPid; - pickObj["T"] = glassutil::CDate::encodeDateTime(pick->tPick); - pickObj["Time"] = glassutil::CDate::encodeISO8601Time(pick->tPick); - pickObj["Distance"] = geo.delta(&site->geo) / DEG2RAD; - pickObj["Azimuth"] = geo.azimuth(&site->geo) / DEG2RAD; + pickObj["Site"] = site->getScnl(); + pickObj["Pid"] = pick->getPid(); + pickObj["T"] = glassutil::CDate::encodeDateTime(pick->getTPick()); + pickObj["Time"] = glassutil::CDate::encodeISO8601Time( + pick->getTPick()); + pickObj["Distance"] = geo.delta(&site->getGeo()) / DEG2RAD; + pickObj["Azimuth"] = geo.azimuth(&site->getGeo()) / DEG2RAD; pickObj["Residual"] = tres; } @@ -617,41 +597,43 @@ json::Object CHypo::hypo() { // for each correlation for (auto correlation : vCorr) { // get basic pick values - std::shared_ptr site = correlation->pSite; - double tobs = correlation->tCorrelation - tOrg; - double tcal = pTTT->T(&site->geo, tobs); + std::shared_ptr site = correlation->getSite(); + double tobs = correlation->getTCorrelation() - tOrg; + double tcal = pTTT->T(&site->getGeo(), tobs); double tres = tobs - tcal; // should this be changed? double sig = pGlass->sig(tres, 1.0); // if we have it, use the shared pointer json::Object correlationObj; - if (correlation->jCorrelation) { + std::shared_ptr jCorrelation = correlation + ->getJCorrelation(); + if (jCorrelation) { // start with a copy of json pick // which has the site, source, time, etc - correlationObj = json::Object(*correlation->jCorrelation.get()); + correlationObj = json::Object(*jCorrelation.get()); // add the association info json::Object assocobj; assocobj["Phase"] = pTTT->sPhase; - assocobj["Distance"] = geo.delta(&site->geo) / DEG2RAD; - assocobj["Azimuth"] = geo.azimuth(&site->geo) / DEG2RAD; + assocobj["Distance"] = geo.delta(&site->getGeo()) / DEG2RAD; + assocobj["Azimuth"] = geo.azimuth(&site->getGeo()) / DEG2RAD; assocobj["Residual"] = tres; assocobj["Sigma"] = sig; correlationObj["AssociationInfo"] = assocobj; } else { // we don't have a jCorrelation, so fill in what we know - correlationObj["Site"] = site->sScnl; - correlationObj["Pid"] = correlation->sPid; + correlationObj["Site"] = site->getScnl(); + correlationObj["Pid"] = correlation->getPid(); correlationObj["Time"] = glassutil::CDate::encodeISO8601Time( - correlation->tCorrelation); - correlationObj["Latitude"] = correlation->dLat; - correlationObj["Longitude"] = correlation->dLon; - correlationObj["Depth"] = correlation->dZ; - correlationObj["Distance"] = geo.delta(&site->geo) / DEG2RAD; - correlationObj["Azimuth"] = geo.azimuth(&site->geo) / DEG2RAD; + correlation->getTCorrelation()); + correlationObj["Latitude"] = correlation->getLat(); + correlationObj["Longitude"] = correlation->getLon(); + correlationObj["Depth"] = correlation->getZ(); + correlationObj["Distance"] = geo.delta(&site->getGeo()) / DEG2RAD; + correlationObj["Azimuth"] = geo.azimuth(&site->getGeo()) / DEG2RAD; correlationObj["Residual"] = tres; - correlationObj["Correlation"] = correlation->dCorrelation; + correlationObj["Correlation"] = correlation->getCorrelation(); } // add new pick to list @@ -659,10 +641,10 @@ json::Object CHypo::hypo() { } // add data array to object - hypo["Data"] = data; + (*hypo)["Data"] = data; if (pGlass) { - pGlass->send(&hypo); + pGlass->send(hypo); } // done @@ -672,32 +654,33 @@ json::Object CHypo::hypo() { // ---------------------------------------------------------Event void CHypo::event() { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); bEvent = true; reportCount++; - json::Object evt; + std::shared_ptr event = std::make_shared( + json::Object()); // fill in Event command from current hypocenter - evt["Cmd"] = "Event"; - evt["Pid"] = sPid; - evt["CreateTime"] = glassutil::CDate::encodeISO8601Time(tCreate); - evt["ReportTime"] = glassutil::CDate::encodeISO8601Time( + (*event)["Cmd"] = "Event"; + (*event)["Pid"] = sPid; + (*event)["CreateTime"] = glassutil::CDate::encodeISO8601Time(tCreate); + (*event)["ReportTime"] = glassutil::CDate::encodeISO8601Time( glassutil::CDate::now()); - evt["Version"] = reportCount; + (*event)["Version"] = reportCount; // basic hypo information - evt["Latitude"] = dLat; - evt["Longitude"] = dLon; - evt["Depth"] = dZ; - evt["Time"] = glassutil::CDate::encodeISO8601Time(tOrg); - evt["Bayes"] = dBayes; - evt["Ndata"] = static_cast(vPick.size()) + (*event)["Latitude"] = dLat; + (*event)["Longitude"] = dLon; + (*event)["Depth"] = dZ; + (*event)["Time"] = glassutil::CDate::encodeISO8601Time(tOrg); + (*event)["Bayes"] = dBayes; + (*event)["Ndata"] = static_cast(vPick.size()) + static_cast(vCorr.size()); // send it if (pGlass) { - pGlass->send(&evt); + pGlass->send(event); } } @@ -705,7 +688,7 @@ void CHypo::event() { bool CHypo::associate(std::shared_ptr pick, double sigma, double sdassoc) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // null check if (pick == NULL) { @@ -724,8 +707,8 @@ bool CHypo::associate(std::shared_ptr pick, double sigma, return (false); } - double dAzimuthRange = pGlass->beamMatchingAzimuthWindow; - // double dDistanceRange = pGlass->beamMatchingDistanceWindow; + double dAzimuthRange = pGlass->getBeamMatchingAzimuthWindow(); + // double dDistanceRange = pGlass->getBeamMatchingDistanceWindow(); // set up a geographic object for this hypo glassutil::CGeo hypoGeo; @@ -735,10 +718,10 @@ bool CHypo::associate(std::shared_ptr pick, double sigma, pTTT->setOrigin(dLat, dLon, dZ); // get site - std::shared_ptr site = pick->pSite; + std::shared_ptr site = pick->getSite(); // compute distance - double siteDistance = hypoGeo.delta(&site->geo) / DEG2RAD; + double siteDistance = hypoGeo.delta(&site->getGeo()) / DEG2RAD; // check if distance is beyond cutoff if (siteDistance > dCut) { @@ -747,10 +730,10 @@ bool CHypo::associate(std::shared_ptr pick, double sigma, } // compute observed traveltime - double tObs = pick->tPick - tOrg; + double tObs = pick->getTPick() - tOrg; // get expected travel time - double tCal = pTTT->T(&site->geo, tObs); + double tCal = pTTT->T(&site->getGeo(), tObs); // Check if pick has an invalid travel time, if (tCal < 0.0) { @@ -759,14 +742,14 @@ bool CHypo::associate(std::shared_ptr pick, double sigma, } // check backazimuth if present - if (pick->dBackAzimuth > 0) { + if (pick->getBackAzimuth() > 0) { // compute azimith from the site to the node - double siteAzimuth = site->geo.azimuth(&hypoGeo); + double siteAzimuth = site->getGeo().azimuth(&hypoGeo); // check to see if pick's backazimuth is within the // valid range - if ((pick->dBackAzimuth < (siteAzimuth - dAzimuthRange)) - || (pick->dBackAzimuth > (siteAzimuth + dAzimuthRange))) { + if ((pick->getBackAzimuth() < (siteAzimuth - dAzimuthRange)) + || (pick->getBackAzimuth() > (siteAzimuth + dAzimuthRange))) { // it is not, do not associate return (false); } @@ -810,8 +793,8 @@ bool CHypo::associate(std::shared_ptr pick, double sigma, "CHypo::associate: NOASSOC Hypo:%s Time:%s Station:%s Pick:%s" " stdev:%.2f>sdassoc:%.2f)", sPid.c_str(), - glassutil::CDate::encodeDateTime(pick->tPick).c_str(), - pick->pSite->sScnl.c_str(), pick->sPid.c_str(), stdev, sdassoc); + glassutil::CDate::encodeDateTime(pick->getTPick()).c_str(), + pick->getSite()->getScnl().c_str(), pick->getPid().c_str(), stdev, sdassoc); glassutil::CLogit::log(sLog); */ @@ -823,8 +806,8 @@ bool CHypo::associate(std::shared_ptr pick, double sigma, "CHypo::associate: ASSOC Hypo:%s Time:%s Station:%s Pick:%s" " stdev:%.2f>sdassoc:%.2f)", sPid.c_str(), - glassutil::CDate::encodeDateTime(pick->tPick).c_str(), - pick->pSite->sScnl.c_str(), pick->sPid.c_str(), stdev, sdassoc); + glassutil::CDate::encodeDateTime(pick->getTPick()).c_str(), + pick->getSite()->getScnl().c_str(), pick->getPid().c_str(), stdev, sdassoc); glassutil::CLogit::log(sLog); */ @@ -836,7 +819,7 @@ bool CHypo::associate(std::shared_ptr pick, double sigma, bool CHypo::associate(std::shared_ptr corr, double tWindow, double xWindow) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // NOTE: this is a simple time/distance check for association // wiser heads than mine may come up with a more robust approach JMP @@ -858,12 +841,13 @@ bool CHypo::associate(std::shared_ptr corr, double tWindow, double xDist = 0; // check if time difference is within window - tDist = std::abs(tOrg - corr->tCorrelation); + tDist = std::abs(tOrg - corr->getTCorrelation()); if (tDist < tWindow) { glassutil::CGeo geo1; geo1.setGeographic(dLat, dLon, 6371.0 - dZ); glassutil::CGeo geo2; - geo2.setGeographic(corr->dLat, corr->dLon, 6371.0 - corr->dZ); + geo2.setGeographic(corr->getLat(), corr->getLon(), + 6371.0 - corr->getZ()); xDist = RAD2DEG * geo1.delta(&geo2); // check if distance difference is within window @@ -875,9 +859,10 @@ bool CHypo::associate(std::shared_ptr corr, double tWindow, " Corr:%s tDist:%.2fxWindow:%.2f)", sPid.c_str(), - glassutil::CDate::encodeDateTime(corr->tCorrelation).c_str(), - corr->pSite->sScnl.c_str(), corr->sPid.c_str(), tDist, - tWindow, xDist, xWindow); + glassutil::CDate::encodeDateTime(corr->getTCorrelation()) + .c_str(), + corr->getSite()->getScnl().c_str(), corr->getPid().c_str(), + tDist, tWindow, xDist, xWindow); glassutil::CLogit::log(sLog); return (true); @@ -886,21 +871,24 @@ bool CHypo::associate(std::shared_ptr corr, double tWindow, if (xDist == 0) { snprintf( - sLog, sizeof(sLog), + sLog, + sizeof(sLog), "CHypo::associate: C-NOASSOC Hypo:%s Time:%s Station:%s Corr:%s" " tDist:%.2f>tWindow:%.2f", sPid.c_str(), - glassutil::CDate::encodeDateTime(corr->tCorrelation).c_str(), - corr->pSite->sScnl.c_str(), corr->sPid.c_str(), tDist, tWindow); + glassutil::CDate::encodeDateTime(corr->getTCorrelation()).c_str(), + corr->getSite()->getScnl().c_str(), corr->getPid().c_str(), + tDist, tWindow); } else { snprintf( - sLog, sizeof(sLog), + sLog, + sizeof(sLog), "CHypo::associate: C-NOASSOC Hypo:%s Time:%s Station:%s Corr:%s" " tDist:%.2fxWindow:%.2f)", sPid.c_str(), - glassutil::CDate::encodeDateTime(corr->tCorrelation).c_str(), - corr->pSite->sScnl.c_str(), corr->sPid.c_str(), tDist, tWindow, - xDist, xWindow); + glassutil::CDate::encodeDateTime(corr->getTCorrelation()).c_str(), + corr->getSite()->getScnl().c_str(), corr->getPid().c_str(), + tDist, tWindow, xDist, xWindow); } glassutil::CLogit::log(sLog); @@ -911,7 +899,7 @@ bool CHypo::associate(std::shared_ptr corr, double tWindow, // ---------------------------------------------------------affinity double CHypo::affinity(std::shared_ptr pck) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // null checks if (pck == NULL) { @@ -922,14 +910,14 @@ double CHypo::affinity(std::shared_ptr pck) { } // get the site from the pick - std::shared_ptr site = pck->pSite; + std::shared_ptr site = pck->getSite(); // get various global parameters from the glass pointer // get the standard deviation allowed for association - double sdassoc = pGlass->sdAssociate; + double sdassoc = pGlass->getSdAssociate(); // get the affinity factor - double expaff = pGlass->expAffinity; + double expaff = pGlass->getExpAffinity(); // check to see if this pick can associate with this hypo using // the given association standard deviation @@ -962,7 +950,7 @@ double CHypo::affinity(std::shared_ptr pck) { // ---------------------------------------------------------affinity double CHypo::affinity(std::shared_ptr corr) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // NOTE: I'm just combining time/distance into a made up affinity // wiser heads than mine may come up with a more robust approach JMP @@ -975,8 +963,8 @@ double CHypo::affinity(std::shared_ptr corr) { } // get various global parameters from the glass pointer - double tWindow = pGlass->correlationMatchingTWindow; - double xWindow = pGlass->correlationMatchingXWindow; + double tWindow = pGlass->getCorrelationMatchingTWindow(); + double xWindow = pGlass->getCorrelationMatchingXWindow(); // check to see if this correlation can associate with this hypo if (!associate(corr, tWindow, xWindow)) { @@ -986,7 +974,7 @@ double CHypo::affinity(std::shared_ptr corr) { // compute time factor, multiply by 10 to make time factor // have equal weight to the distance factor - double tFactor = std::abs(tOrg - corr->tCorrelation) * 10; + double tFactor = std::abs(tOrg - corr->getTCorrelation()) * 10; // hypo is in geographic coordinates glassutil::CGeo geo1; @@ -994,7 +982,7 @@ double CHypo::affinity(std::shared_ptr corr) { // correlation is in geographic coordinates glassutil::CGeo geo2; - geo2.setGeographic(corr->dLat, corr->dLon, 6371.0 - corr->dZ); + geo2.setGeographic(corr->getLat(), corr->getLon(), 6371.0 - corr->getZ()); // compute distance factor double xFactor = RAD2DEG * geo1.delta(&geo2); @@ -1012,7 +1000,7 @@ double CHypo::affinity(std::shared_ptr corr) { // ---------------------------------------------------------prune bool CHypo::prune() { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // nullcheck if (pGlass == NULL) { @@ -1027,14 +1015,14 @@ bool CHypo::prune() { "CHypo::prune. " + sPid); // set up local vector to track picks to remove - std::vector < std::shared_ptr < CPick >> vremove; + std::vector> vremove; // set up a geographic object for this hypo glassutil::CGeo geo; geo.setGeographic(dLat, dLon, 6371.0); // get the standard deviation allowed for pruning - double sdprune = pGlass->sdPrune; + double sdprune = pGlass->getSdPrune(); // for each pick in this hypo for (auto pck : vPick) { @@ -1042,12 +1030,12 @@ bool CHypo::prune() { if (!associate(pck, 1.0, sdprune)) { // pick no longer associates, add to remove list vremove.push_back(pck); - // if (pGlass->bTrack) { - snprintf(sLog, sizeof(sLog), "CHypo::prune: CUL %s %s (%.2f)", - glassutil::CDate::encodeDateTime(pck->tPick).c_str(), - pck->pSite->sScnl.c_str(), sdprune); + + snprintf( + sLog, sizeof(sLog), "CHypo::prune: CUL %s %s (%.2f)", + glassutil::CDate::encodeDateTime(pck->getTPick()).c_str(), + pck->getSite()->getScnl().c_str(), sdprune); glassutil::CLogit::log(sLog); - // } // on to the next pick continue; @@ -1055,14 +1043,14 @@ bool CHypo::prune() { // Trim whiskers // compute delta between site and hypo - double delta = geo.delta(&pck->pSite->geo); + double delta = geo.delta(&pck->getSite()->getGeo()); // check if delta is beyond distance limit if (delta > dCut) { - snprintf(sLog, sizeof(sLog), - "CHypo::prune: CUL %s %s (%.2f > %.2f)", - glassutil::CDate::encodeDateTime(pck->tPick).c_str(), - pck->pSite->sScnl.c_str(), delta, dCut); + snprintf( + sLog, sizeof(sLog), "CHypo::prune: CUL %s %s (%.2f > %.2f)", + glassutil::CDate::encodeDateTime(pck->getTPick()).c_str(), + pck->getSite()->getScnl().c_str(), delta, dCut); glassutil::CLogit::log(sLog); // add pick to remove list @@ -1085,11 +1073,11 @@ bool CHypo::prune() { "CHypo::prune pick pruneCount:" + std::to_string(pruneCount)); // set up local vector to track correlations to remove - std::vector < std::shared_ptr < CCorrelation >> vcremove; + std::vector> vcremove; // get the correlation windows - double tWindow = pGlass->correlationMatchingTWindow; - double xWindow = pGlass->correlationMatchingXWindow; + double tWindow = pGlass->getCorrelationMatchingTWindow(); + double xWindow = pGlass->getCorrelationMatchingXWindow(); // for each correlation in this hypo for (auto cor : vCorr) { @@ -1097,13 +1085,15 @@ bool CHypo::prune() { if (!associate(cor, tWindow, xWindow)) { // correlation no longer associates, add to remove list vcremove.push_back(cor); - // if (pGlass->bTrack) { + snprintf( - sLog, sizeof(sLog), "CHypo::prune: C-CUL %s %s", - glassutil::CDate::encodeDateTime(cor->tCorrelation).c_str(), - cor->pSite->sScnl.c_str()); + sLog, + sizeof(sLog), + "CHypo::prune: C-CUL %s %s", + glassutil::CDate::encodeDateTime(cor->getTCorrelation()) + .c_str(), + cor->getSite()->getScnl().c_str()); glassutil::CLogit::log(sLog); - // } // on to the next correlation continue; @@ -1128,7 +1118,7 @@ bool CHypo::prune() { // ---------------------------------------------------------cancel bool CHypo::cancel() { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // nullcheck if (pGlass == NULL) { @@ -1148,9 +1138,10 @@ bool CHypo::cancel() { char sHypo[1024]; glassutil::CDate dt = glassutil::CDate(tOrg); - snprintf(sHypo, sizeof(sHypo), "%s %s%9.4f%10.4f%6.1f %d", sPid.c_str(), - dt.dateTime().c_str(), dLat, dLon, dZ, - static_cast(vPick.size())); + snprintf(sHypo, sizeof(sHypo), "CHypo::cancel: %s tOrg:%s; dLat:%9.4f; " + "dLon:%10.4f; dZ:%6.1f; bayes:%.2f; nPick:%d; nCorr:%d", + sPid.c_str(), dt.dateTime().c_str(), dLat, dLon, dZ, dBayes, + static_cast(vPick.size()), static_cast(vCorr.size())); // check to see if there is enough supporting data for this hypocenter // NOTE, in Node, ncut is used as a threshold for the number of @@ -1163,18 +1154,19 @@ bool CHypo::cancel() { if (vCorr.size() > 0) { // get the current time double now = glassutil::CDate::now(); + int cancelAge = pGlass->getCorrelationCancelAge(); // check correlations int expireCount = 0; for (auto cor : vCorr) { // count correlation as expired if it's creation time is older than // the cancel age - if ((cor->tGlassCreate + pGlass->correlationCancelAge) < now) { + if ((cor->getTGlassCreate() + cancelAge) < now) { snprintf(sLog, sizeof(sLog), "CHypo::cancel: Correlation:%s created: %f " "limit:%d now:%f", - sPid.c_str(), cor->tGlassCreate, - pGlass->correlationCancelAge, now); + sPid.c_str(), cor->getTGlassCreate(), cancelAge, + now); glassutil::CLogit::log(sLog); expireCount++; } @@ -1187,7 +1179,7 @@ bool CHypo::cancel() { "correlations (%d) older than %d seconds", sPid.c_str(), (static_cast(vCorr.size()) - expireCount), - pGlass->correlationCancelAge); + cancelAge); glassutil::CLogit::log(sLog); } else { snprintf(sLog, sizeof(sLog), @@ -1195,7 +1187,7 @@ bool CHypo::cancel() { "correlations (%d) younger than %d seconds", sPid.c_str(), (static_cast(vCorr.size()) - expireCount), - pGlass->correlationCancelAge); + cancelAge); glassutil::CLogit::log(sLog); // Hypo is still viable, for now... @@ -1252,7 +1244,7 @@ bool CHypo::cancel() { // ---------------------------------------------------------cancel bool CHypo::reportCheck() { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // nullcheck if (pGlass == NULL) { @@ -1269,7 +1261,7 @@ bool CHypo::reportCheck() { dt.dateTime().c_str(), dLat, dLon, dZ, static_cast(vPick.size())); - int nReportCut = pGlass->nReportCut; + int nReportCut = pGlass->getReportCut(); // check data count if ((vPick.size() + vCorr.size()) < nReportCut) { @@ -1288,7 +1280,7 @@ bool CHypo::reportCheck() { // rms check? other checks? // baysian threshold check - double dReportThresh = pGlass->dReportThresh; + double dReportThresh = pGlass->getReportThresh(); if (dBayes < dReportThresh) { // failure snprintf( @@ -1309,7 +1301,7 @@ bool CHypo::reportCheck() { // ---------------------------------------------------------stats void CHypo::stats() { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // Calculate the statistical distribution of distance // histogram for culling purposes. The actual values are @@ -1337,16 +1329,16 @@ void CHypo::stats() { std::vector azm; for (auto pick : vPick) { // get the site - std::shared_ptr site = pick->pSite; + std::shared_ptr site = pick->getSite(); // compute the distance delta - double delta = geo.delta(&site->geo) / DEG2RAD; + double delta = geo.delta(&site->getGeo()) / DEG2RAD; // add to distance vactor dis.push_back(delta); // compute the azimuth - double azimuth = geo.azimuth(&site->geo) / DEG2RAD; + double azimuth = geo.azimuth(&site->getGeo()) / DEG2RAD; // add to azimuth vector azm.push_back(azimuth); @@ -1423,14 +1415,14 @@ void CHypo::summary() { snprintf(sLog, sizeof(sLog), "CHypo::summary: %s%7.2f%8.2f%6.1f%6.1f%6.1f%5d (%5.1f) %s", sorg.c_str(), dLat, dLon, dZ, dMin, dGap, - static_cast(vPick.size()), dBayes, sWeb.c_str()); + static_cast(vPick.size()), dBayes, sWebName.c_str()); glassutil::CLogit::log(sLog); } // ---------------------------------------------------------list void CHypo::list(std::string src) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); if (pGlass == NULL) { glassutil::CLogit::log(glassutil::log_level::error, @@ -1468,7 +1460,7 @@ void CHypo::list(std::string src) { "CHypo::list: ** %s **\\nPid:%s\nGap:%.1f Dmin:%.1f Dmedian:%.1f" "\nSigma:%.2f Kurtosis:%.2f\nWeb:%s", sorg.c_str(), sPid.c_str(), dGap, dMin, dMed, dSig, dKrt, - sWeb.c_str()); + sWebName.c_str()); glassutil::CLogit::log(sLog); // setup traveltime interface for this hypo @@ -1479,7 +1471,7 @@ void CHypo::list(std::string src) { geo.setGeographic(dLat, dLon, 6371.0 - dZ); // create local pick vector - std::vector < std::shared_ptr < CPick >> vpick; + std::vector> vpick; // copy picks to the local pick vector for (auto pick : vPick) { @@ -1487,7 +1479,7 @@ void CHypo::list(std::string src) { } // generate list of rogue picks - std::vector < std::shared_ptr < CPick >> pickRogues = pGlass->pPickList + std::vector> pickRogues = pGlass->getPickList() ->rogues(sPid, tOrg); // add rogue picks to the local pick vector @@ -1504,13 +1496,13 @@ void CHypo::list(std::string src) { auto pick = vPick[ipk]; // get the site - std::shared_ptr site = pick->pSite; + std::shared_ptr site = pick->getSite(); // compute observed traveltime - double tobs = pick->tPick - tOrg; + double tobs = pick->getTPick() - tOrg; // get expected travel time - double tcal = pTTT->T(&site->geo, tobs); + double tcal = pTTT->T(&site->getGeo(), tobs); // compute residual double tres = tobs - tcal; @@ -1522,16 +1514,16 @@ void CHypo::list(std::string src) { } // compute distance - double dis = geo.delta(&site->geo) / DEG2RAD; + double dis = geo.delta(&site->getGeo()) / DEG2RAD; // compute azimuth - double azm = geo.azimuth(&site->geo) / DEG2RAD; + double azm = geo.azimuth(&site->getGeo()) / DEG2RAD; // get the association string - std::string sass = pick->sAss; + std::string sass = pick->getAss(); // if the hypo link is valid - if ((pick->pHypo != NULL) && (pick->pHypo->sPid != sPid)) { + if ((pick->getHypo() != NULL) && (pick->getHypo()->getPid() != sPid)) { // set association string sass = "*"; } else { @@ -1544,8 +1536,8 @@ void CHypo::list(std::string src) { "CHypo::list: ** %s **\nPid:%s\n%s %s %s %.2f Dis:%.1f" " Azm:%.1f Wt:NA", sorg.c_str(), sPid.c_str(), sass.c_str(), - site->sScnl.c_str(), pTTT->sPhase.c_str(), tres, dis, - azm); + site->getScnl().c_str(), pTTT->sPhase.c_str(), tres, + dis, azm); glassutil::CLogit::log(sLog); } else { @@ -1553,8 +1545,8 @@ void CHypo::list(std::string src) { "CHypo::list: ** %s **\nPid:%s\n%s %s %s %.2f Dis:%.1f" " Azm:%.1f Wt:%.2f", sorg.c_str(), sPid.c_str(), sass.c_str(), - site->sScnl.c_str(), pTTT->sPhase.c_str(), tres, dis, - azm, vWts[ipk]); + site->getScnl().c_str(), pTTT->sPhase.c_str(), tres, + dis, azm, vWts[ipk]); glassutil::CLogit::log(sLog); } } @@ -1564,7 +1556,7 @@ void CHypo::list(std::string src) { double CHypo::anneal(int nIter, double dStart, double dStop, double tStart, double tStop) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // This is essentially a faster algorithmic implementation of iterate // nullcheck @@ -1578,7 +1570,7 @@ double CHypo::anneal(int nIter, double dStart, double dStop, double tStart, "CHypo::anneal. " + sPid); // locate using new function - if (pGlass->minimizeTTLocator == false) { + if (pGlass->getMinimizeTtLocator() == false) { annealingLocate(nIter, dStart, dStop, tStart, tStop, 1); } else { annealingLocateResidual(nIter, dStart, dStop, tStart, tStop, 1); @@ -1591,7 +1583,7 @@ double CHypo::anneal(int nIter, double dStart, double dStop, double tStart, stats(); // create pick delete vector - std::vector < std::shared_ptr < CPick >> vkill; + std::vector> vkill; // set the traveltime for the current hypo if (pTrv1 != NULL) { @@ -1612,21 +1604,21 @@ double CHypo::anneal(int nIter, double dStart, double dStop, double tStart, // calculate the travel times double tCal1 = -1; if (pTrv1 != NULL) { - tCal1 = pTrv1->T(&pick->pSite->geo); + tCal1 = pTrv1->T(&pick->getSite()->getGeo()); } double tCal2 = -1; if (pTrv2 != NULL) { - tCal2 = pTrv2->T(&pick->pSite->geo); + tCal2 = pTrv2->T(&pick->getSite()->getGeo()); } // calculate absolute residuals double tRes1 = 0; if (tCal1 > 0) { - tRes1 = std::abs(pick->tPick - tCal1 - tOrg); + tRes1 = std::abs(pick->getTPick() - tCal1 - tOrg); } double tRes2 = 0; if (tCal2 > 0) { - tRes2 = std::abs(pick->tPick - tCal2 - tOrg); + tRes2 = std::abs(pick->getTPick() - tCal2 - tOrg); } // get best (smallest) residual @@ -1666,7 +1658,7 @@ double CHypo::anneal(int nIter, double dStart, double dStop, double tStart, // ---------------------------------------------------------localize double CHypo::localize() { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // Localize this hypo // nullcheck @@ -1687,10 +1679,6 @@ double CHypo::localize() { return dBayes; } - // increment location count for debugging? - // Note: Not sure what the purpose of keeping this count is - pGlass->nLocate++; - // get the number of picks int npick = vPick.size(); @@ -1710,7 +1698,7 @@ double CHypo::localize() { double searchR = (dRes / 4. + taper.Val(vPick.size()) * .75 * dRes) / 4.; // This should be the default - if (pGlass->minimizeTTLocator == false) { + if (pGlass->getMinimizeTtLocator() == false) { if (npick < 50) { annealingLocate(5000, searchR, 1., searchR / 30.0, .1); } else if (npick < 150 && (npick % 10) == 0) { @@ -1748,11 +1736,6 @@ double CHypo::localize() { static_cast(vPick.size())); glassutil::CLogit::log(sLog); - if (pGlass->bTrack) { - // call list to output the current data - list("Localize"); - } - // return the final maximum bayesian fit return (dBayes); } @@ -1761,7 +1744,7 @@ double CHypo::localize() { void CHypo::annealingLocate(int nIter, double dStart, double dStop, double tStart, double tStop, int nucleate) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // don't locate if the location is fixed if (bFixed) { @@ -1778,7 +1761,7 @@ void CHypo::annealingLocate(int nIter, double dStart, double dStop, // if testing locator, setup output file std::ofstream outfile; - if (pGlass->testLocator) { + if (pGlass->getTestLocator()) { std::string filename = "./locatorTest/" + sPid + ".txt"; outfile.open(filename, std::ios::out | std::ios::app); outfile << std::to_string(dLat) << " " << std::to_string(dLon) << " " @@ -1787,11 +1770,6 @@ void CHypo::annealingLocate(int nIter, double dStart, double dStop, << std::to_string(valStart) << " 0 0 0 \n"; } - snprintf(sLog, sizeof(sLog), "CHypo::annealingLocate: old bayes value " - "%.4f sPid:%s", - valStart, sPid.c_str()); - glassutil::CLogit::log(sLog); - // set the starting location as the current best stack value valBest = valStart; @@ -1847,7 +1825,7 @@ void CHypo::annealingLocate(int nIter, double dStart, double dStop, double val = getBayes(xlat, xlon, xz, oT, nucleate); // if testing locator print iteration - if (pGlass->testLocator) { + if (pGlass->getTestLocator()) { outfile << std::to_string(xlat) << " " << std::to_string(xlon) << " " << std::to_string(xz) << " " << std::to_string(oT) << " " << std::to_string(vPick.size()) << " " @@ -1882,23 +1860,22 @@ void CHypo::annealingLocate(int nIter, double dStart, double dStop, if (nucleate == 1) { dBayesInitial = valBest; } - snprintf(sLog, sizeof(sLog), - "CHypo::annealingLocate: total movement (%.4f,%.4f,%.4f,%.4f)" - " (%.4f,%.4f,%.4f,%.4f) sPid:%s", - dLat, dLon, dZ, tOrg, ddx, ddy, ddz, ddt, sPid.c_str()); - glassutil::CLogit::log(sLog); - snprintf(sLog, sizeof(sLog), "CHypo::annealingLocate: new bayes value " - "%.4f sPid:%s", - valBest, sPid.c_str()); + snprintf( + sLog, sizeof(sLog), + "CHypo::annealingLocate: total movement (%.4f,%.4f,%.4f,%.4f)" + " (%.4f,%.4f,%.4f,%.4f) sPid:%s; new bayes value:%.4f; old bayes" + " value:%.4f", + dLat, dLon, dZ, tOrg, ddx, ddy, ddz, ddt, sPid.c_str(), valBest, + valStart); glassutil::CLogit::log(sLog); - if (pGlass->graphicsOut == true) { + if (pGlass->getGraphicsOut() == true) { graphicsOutput(); } // if testing the locator close the file - if (pGlass->testLocator) { + if (pGlass->getTestLocator()) { outfile.close(); } @@ -1909,9 +1886,15 @@ void CHypo::annealingLocate(int nIter, double dStart, double dStop, double CHypo::getBayes(double xlat, double xlon, double xZ, double oT, int nucleate) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); - if (pTTT == NULL) { + if ((!pTrv1) && (!pTrv2)) { + glassutil::CLogit::log(glassutil::log_level::error, + "CHypo::getBayes: NULL pTrv1 and pTrv2."); + return (0); + } + + if (!pTTT) { glassutil::CLogit::log(glassutil::log_level::error, "CHypo::getBayes: NULL pTTT."); return (0); @@ -1931,10 +1914,10 @@ double CHypo::getBayes(double xlat, double xlon, double xZ, double oT, geo.setGeographic(xlat, xlon, 6371.0 - xZ); // This sets the travel-time look up location - if (pTrv1 != NULL) { + if (pTrv1) { pTrv1->setOrigin(xlat, xlon, xZ); } - if (pTrv2 != NULL) { + if (pTrv2) { pTrv2->setOrigin(xlat, xlon, xZ); } @@ -1951,35 +1934,52 @@ double CHypo::getBayes(double xlat, double xlon, double xZ, double oT, double resi = 99999999; // calculate residual - double tobs = pick->tPick - oT; - std::shared_ptr site = pick->pSite; - - // only use nucleation phase if on nucleation branch - if (nucleate == 1 && pTrv2 == NULL) { - tcal = pTrv1->T(&site->geo); - resi = tobs - tcal; - } else if (nucleate == 1 && pTrv1 == NULL) { - tcal = pTrv2->T(&site->geo); - resi = tobs - tcal; - } else { - // take whichever has the smallest residual, P or S - tcal = pTTT->T(&site->geo, tobs); - if (pTTT->sPhase == "P") { - resi = tobs - tcal; - } else if (pTTT->sPhase == "S") { - resi = (tobs - tcal) * 2.; // Effectively halving the weight of S - // this value was selected by testing specific - // events with issues - } else { - resi = (tobs - tcal) * 10.; // Down weighting all other phases - // Value was chosen so that other phases would - // still contribute (reducing instabilities) - // but remain insignificant + double tobs = pick->getTPick() - oT; + std::shared_ptr site = pick->getSite(); + glassutil::CGeo siteGeo = site->getGeo(); + + // only use nucleation phases if on nucleation branch + if (nucleate == 1) { + if ((pTrv1) && (pTrv2)) { + // we have both nucleation phases + // first nucleation phase + // calculate the residual using the phase name + double tcal1 = pTrv1->T(&siteGeo); + double resi1 = getResidual(pTrv1->sPhase, tobs, tcal1); + + // second nucleation phase + // calculate the residual using the phase name + double tcal2 = pTrv2->T(&siteGeo); + double resi2 = getResidual(pTrv2->sPhase, tobs, tcal2); + + // use the smallest residual + if (resi1 < resi2) { + tcal = tcal1; + resi = resi1; + } else { + tcal = tcal2; + resi = resi2; + } + } else if ((pTrv1) && (!pTrv2)) { + // we have just the first nucleation phase + tcal = pTrv1->T(&siteGeo); + resi = getResidual(pTrv1->sPhase, tobs, tcal); + } else if ((!pTrv1) && (pTrv2)) { + // we have just the second ducleation phase + tcal = pTrv2->T(&siteGeo); + resi = getResidual(pTrv2->sPhase, tobs, tcal); } + } else { + // use all available association phases + // take whichever phase has the smallest residual + tcal = pTTT->T(&siteGeo, tobs); + + // calculate the residual using the phase name + resi = getResidual(pTTT->sPhase, tobs, tcal); } // calculate distance to station to get sigma - double delta = RAD2DEG * geo.delta(&site->geo); + double delta = RAD2DEG * geo.delta(&site->getGeo()); double sigma = (tap.Val(delta) * 2.25) + 0.75; // calculate and add to the stack @@ -1988,11 +1988,31 @@ double CHypo::getBayes(double xlat, double xlon, double xZ, double oT, return value; } +// ---------------------------------------------------------getResidual +double CHypo::getResidual(std::string sPhase, double tObs, double tCal) { + if (sPhase == "P") { + return (tObs - tCal); + } else if (sPhase == "S") { + // Effectively halving the weight of S + // this value was selected by testing specific + // events with issues + // NOTE: Hard Coded + return ((tObs - tCal) * 2.0); + } else { + // Down weighting all other phases + // Value was chosen so that other phases would + // still contribute (reducing instabilities) + // but remain insignificant + // NOTE: Hard Coded + return ((tObs - tCal) * 10.0); + } +} + // ---------------------------------------------------------annealingLocate void CHypo::annealingLocateResidual(int nIter, double dStart, double dStop, double tStart, double tStop, int nucleate) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); if (pTTT == NULL) { glassutil::CLogit::log(glassutil::log_level::error, @@ -2109,7 +2129,7 @@ void CHypo::annealingLocateResidual(int nIter, double dStart, double dStop, "CHypo::annealingLocate: new sum abs residual %.4f", valBest); glassutil::CLogit::log(sLog); - if (pGlass->graphicsOut == true) { + if (pGlass->getGraphicsOut() == true) { graphicsOutput(); } @@ -2120,7 +2140,7 @@ void CHypo::annealingLocateResidual(int nIter, double dStart, double dStop, double CHypo::getSumAbsResidual(double xlat, double xlon, double xZ, double oT, int nucleate) { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); if (pTTT == NULL) { glassutil::CLogit::log(glassutil::log_level::error, @@ -2154,20 +2174,20 @@ double CHypo::getSumAbsResidual(double xlat, double xlon, double xZ, double oT, double resi = 99999999; // calculate residual - double tobs = pick->tPick - oT; + double tobs = pick->getTPick() - oT; double tcal; - std::shared_ptr site = pick->pSite; + std::shared_ptr site = pick->getSite(); // only use nucleation phase if on nucleation branch if (nucleate == 1 && pTrv2 == NULL) { - tcal = pTrv1->T(&site->geo); + tcal = pTrv1->T(&site->getGeo()); resi = tobs - tcal; } else if (nucleate == 1 && pTrv1 == NULL) { - tcal = pTrv2->T(&site->geo); + tcal = pTrv2->T(&site->getGeo()); resi = tobs - tcal; } else { // take whichever has the smallest residual, P or S - tcal = pTTT->T(&site->geo, tobs); + tcal = pTTT->T(&site->getGeo(), tobs); if (pTTT->sPhase == "P" || pTTT->sPhase == "S") { resi = tobs - tcal; } @@ -2184,7 +2204,7 @@ double CHypo::getSumAbsResidual(double xlat, double xlon, double xZ, double oT, // ---------------------------------------------------graphicsOutput void CHypo::graphicsOutput() { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); if (pTTT == NULL) { glassutil::CLogit::log(glassutil::log_level::error, @@ -2193,7 +2213,7 @@ void CHypo::graphicsOutput() { } std::ofstream outfile; - std::string filename = pGlass->graphicsOutFolder + sPid + ".txt"; + std::string filename = pGlass->getGraphicsOutFolder() + sPid + ".txt"; outfile.open(filename, std::ios::out); outfile << "hypocenter: " << std::to_string(dLat) << " " << std::to_string(dLon) << " " << std::to_string(dZ) << " " @@ -2204,21 +2224,22 @@ void CHypo::graphicsOutput() { double sigma = 0; glassutil::CGeo geo; int npick = vPick.size(); - for (int y = -1 * pGlass->graphicsSteps; y <= pGlass->graphicsSteps; y++) { - double xlat = dLat + (y * pGlass->graphicsStepKM) / 111.1; - for (int x = -1 * pGlass->graphicsSteps; x <= pGlass->graphicsSteps; - x++) { + for (int y = -1 * pGlass->getGraphicsSteps(); + y <= pGlass->getGraphicsSteps(); y++) { + double xlat = dLat + (y * pGlass->getGraphicsStepKm()) / 111.1; + for (int x = -1 * pGlass->getGraphicsSteps(); + x <= pGlass->getGraphicsSteps(); x++) { double xlon = dLon - + cos(DEG2RAD * xlat) * (x * pGlass->graphicsStepKM) + + cos(DEG2RAD * xlat) * (x * pGlass->getGraphicsStepKm()) / 111.1; pTTT->setOrigin(xlat, xlon, dZ); stack = 0; for (int ipick = 0; ipick < npick; ipick++) { auto pick = vPick[ipick]; - double tobs = pick->tPick - tOrg; - std::shared_ptr site = pick->pSite; - tcal = pTTT->T(&site->geo, tobs); - delta = RAD2DEG * geo.delta(&site->geo); + double tobs = pick->getTPick() - tOrg; + std::shared_ptr site = pick->getSite(); + tcal = pTTT->T(&site->getGeo(), tobs); + delta = RAD2DEG * geo.delta(&site->getGeo()); // This should be a function. if (delta < 1.5) { @@ -2241,7 +2262,7 @@ void CHypo::graphicsOutput() { // ---------------------------------------------------------trap void CHypo::trap() { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); char sLog[1024]; @@ -2252,26 +2273,26 @@ void CHypo::trap() { } // get the pick's hypo pointer - std::shared_ptr hyp = q->pHypo; + std::shared_ptr hyp = q->getHypo(); // check pointer if (hyp == NULL) { // bad hypo pointer snprintf(sLog, sizeof(sLog), "CHypo::trap: sPid %s Pick %s has no back link to hypo", - sPid.c_str(), q->sPid.c_str()); + sPid.c_str(), q->getPid().c_str()); glassutil::CLogit::log(glassutil::log_level::warn, sLog); continue; } // check sPid - if (hyp->sPid != sPid) { + if (hyp->getPid() != sPid) { // sPid is for a different hypo snprintf( sLog, sizeof(sLog), "CHypo::trap: sPid %s Pick: %s linked to another hypo: %s", - sPid.c_str(), q->sPid.c_str(), hyp->sPid.c_str()); + sPid.c_str(), q->getPid().c_str(), hyp->getPid().c_str()); glassutil::CLogit::log(glassutil::log_level::warn, sLog); } } @@ -2280,7 +2301,7 @@ void CHypo::trap() { // ---------------------------------------------------------weights bool CHypo::weights() { // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); + std::lock_guard guard(hypoMutex); // Calculate station weight from distance and nearby stations // to reduce biases induced by network density @@ -2292,8 +2313,8 @@ bool CHypo::weights() { } // get average delta and sigma from glass - double avgDelta = pGlass->avgDelta; - double avgSigma = pGlass->avgSigma; + double avgDelta = pGlass->getAvgDelta(); + double avgSigma = pGlass->getAvgSigma(); // create taper glassutil::CTaper tap; @@ -2317,14 +2338,14 @@ bool CHypo::weights() { auto pick = vPick[ipick]; // get the site - std::shared_ptr site = pick->pSite; + std::shared_ptr site = pick->getSite(); // set up a geo object for this hypo glassutil::CGeo geo; geo.setGeographic(dLat, dLon, 6371.0 - dZ); // get distance between this pick and the hypo - double del = RAD2DEG * geo.delta(&site->geo); + double del = RAD2DEG * geo.delta(&site->getGeo()); // compute sigma for this pick-hypo distance from the average sigma and // the distance to this site using the taper @@ -2338,10 +2359,10 @@ bool CHypo::weights() { auto pickj = vPick[j]; // get the site - std::shared_ptr sitej = pickj->pSite; + std::shared_ptr sitej = pickj->getSite(); // get the distance between this pick and the pick being weighted - double delj = RAD2DEG * site->getDelta(&sitej->geo); + double delj = RAD2DEG * site->getDelta(&sitej->getGeo()); // if the distance is within 6 sig if (delj < (6.0 * sig)) { @@ -2360,21 +2381,9 @@ bool CHypo::weights() { return (true); } -void CHypo::setCycle(int newCycle) { - // lock mutex for this scope - std::lock_guard < std::recursive_mutex > guard(hypoMutex); - - iCycle = newCycle; - - glassutil::CLogit::log( - glassutil::log_level::debug, - "CHypo::setCycle sPid:" + sPid + " cycle: " - + std::to_string(iCycle)); -} - bool CHypo::resolve(std::shared_ptr hyp) { // lock the hypo since we're iterating through it's lists - std::lock_guard < std::recursive_mutex > hypoGuard(hypoMutex); + std::lock_guard hypoGuard(hypoMutex); // nullchecks if (pGlass == NULL) { @@ -2382,7 +2391,7 @@ bool CHypo::resolve(std::shared_ptr hyp) { "CHypo::resolve: NULL pGlass."); return (false); } - if (pGlass->pHypoList == NULL) { + if (pGlass->getHypoList() == NULL) { glassutil::CLogit::log(glassutil::log_level::error, "CHypo::resolve: NULL pGlass pHypoList."); return (false); @@ -2407,7 +2416,7 @@ bool CHypo::resolve(std::shared_ptr hyp) { std::shared_ptr pck = vPick[iPck]; // get the pick's hypo pointer - std::shared_ptr pickHyp = pck->pHypo; + std::shared_ptr pickHyp = pck->getHypo(); // if this pick isn't linked to a hypo if (pickHyp == NULL) { @@ -2417,7 +2426,7 @@ bool CHypo::resolve(std::shared_ptr hyp) { continue; } - std::string sOtherPid = pickHyp->sPid; + std::string sOtherPid = pickHyp->getPid(); // if this pick is linked to this hypo if (sOtherPid == sPid) { @@ -2434,23 +2443,13 @@ bool CHypo::resolve(std::shared_ptr hyp) { snprintf(sLog, sizeof(sLog), "CHypo::resolve: SCV COMPARE %s %s %s %s (%.2f, %.2f)", sPid.c_str(), sOtherPid.c_str(), - glassutil::CDate::encodeDateTime(pck->tPick).c_str(), - pck->pSite->sScnl.c_str(), aff1, aff2); + glassutil::CDate::encodeDateTime(pck->getTPick()).c_str(), + pck->getSite()->getScnl().c_str(), aff1, aff2); glassutil::CLogit::log(sLog); // check which affinity is better if (aff1 > aff2) { // this pick has a higher affinity with the provided hypo - if (pGlass->bTrack) { - snprintf( - sLog, sizeof(sLog), - "CHypo::resolve: SCV %s %s %s %s (%.2f)", sPid.c_str(), - sOtherPid.c_str(), - glassutil::CDate::encodeDateTime(pck->tPick).c_str(), - pck->pSite->sScnl.c_str(), aff1); - glassutil::CLogit::log(sLog); - } - // remove the pick from it's original hypo pickHyp->remPick(pck); @@ -2463,10 +2462,10 @@ bool CHypo::resolve(std::shared_ptr hyp) { // just stealing it back, which is why we do it here // NOTE: why add it at all? we're gonna locate before we finish // is it to see if we can get more next time - pGlass->pHypoList->pushFifo(hyp); + pGlass->getHypoList()->pushFifo(hyp); // add the original hypo the pick was linked to the processing queue - pGlass->pHypoList->pushFifo(pickHyp); + pGlass->getHypoList()->pushFifo(pickHyp); // we've made a change to the hypo (grabbed a pick) bAss = true; @@ -2497,7 +2496,7 @@ bool CHypo::resolve(std::shared_ptr hyp) { auto corr = vCorr[iCorr]; // get the correlation's hypo pointer - std::shared_ptr corrHyp = corr->pHypo; + std::shared_ptr corrHyp = corr->getHypo(); // if this correlation isn't linked to a hypo if (corrHyp == NULL) { @@ -2506,7 +2505,7 @@ bool CHypo::resolve(std::shared_ptr hyp) { continue; } - std::string sOtherPid = corrHyp->sPid; + std::string sOtherPid = corrHyp->getPid(); // if this corr is linked to this hypo if (sOtherPid == sPid) { @@ -2519,29 +2518,18 @@ bool CHypo::resolve(std::shared_ptr hyp) { double aff2 = corrHyp->affinity(corr); snprintf( - sLog, sizeof(sLog), + sLog, + sizeof(sLog), "CHypo::resolve: C SCV COMPARE %s %s %s %s (%.2f, %.2f )", - sPid.c_str(), sOtherPid.c_str(), - glassutil::CDate::encodeDateTime(corr->tCorrelation).c_str(), - corr->pSite->sScnl.c_str(), aff1, aff2); + sPid.c_str(), + sOtherPid.c_str(), + glassutil::CDate::encodeDateTime(corr->getTCorrelation()).c_str(), + corr->getSite()->getScnl().c_str(), aff1, aff2); glassutil::CLogit::log(sLog); // check which affinity is better if (aff1 > aff2) { - // this pick has a higher affinity with the provided hypo - if (pGlass->bTrack) { - snprintf( - sLog, - sizeof(sLog), - "CHypo::resolve: C SCV %s %s %s %s (%.2f)\n", - sPid.c_str(), - sOtherPid.c_str(), - glassutil::CDate::encodeDateTime(corr->tCorrelation) - .c_str(), - corr->pSite->sScnl.c_str(), aff1); - glassutil::CLogit::log(sLog); - } - + // this correlation has a higher affinity with the provided hypo // remove the correlation from it's original hypo corrHyp->remCorrelation(corr); @@ -2552,10 +2540,10 @@ bool CHypo::resolve(std::shared_ptr hyp) { // NOTE: this puts provided hypo before original hypo in FIFO, // we want this hypo to keep this pick, rather than the original // just stealing it back, which is why we do it here - pGlass->pHypoList->pushFifo(hyp); + pGlass->getHypoList()->pushFifo(hyp); // add the original hypo the pick was linked to the processing queue - pGlass->pHypoList->pushFifo(corrHyp); + pGlass->getHypoList()->pushFifo(corrHyp); // we've made a change to the hypo (grabbed a pick) bAss = true; @@ -2571,4 +2559,221 @@ bool CHypo::resolve(std::shared_ptr hyp) { return (bAss); } + +double CHypo::getLat() const { + std::lock_guard hypoGuard(hypoMutex); + return (dLat); +} + +double CHypo::getLon() const { + std::lock_guard hypoGuard(hypoMutex); + return (dLon); +} + +double CHypo::getZ() const { + std::lock_guard hypoGuard(hypoMutex); + return (dZ); +} + +double CHypo::getTOrg() const { + std::lock_guard hypoGuard(hypoMutex); + return (tOrg); +} + +double CHypo::getBayes() const { + std::lock_guard hypoGuard(hypoMutex); + return (dBayes); +} + +bool CHypo::getCorrAdded() const { + std::lock_guard hypoGuard(hypoMutex); + return (bCorrAdded); +} + +void CHypo::setCorrAdded(bool corrAdded) { + std::lock_guard hypoGuard(hypoMutex); + bCorrAdded = corrAdded; +} + +bool CHypo::getEvent() const { + std::lock_guard hypoGuard(hypoMutex); + return (bEvent); +} + +bool CHypo::getFixed() const { + std::lock_guard hypoGuard(hypoMutex); + return (bFixed); +} + +void CHypo::setFixed(bool fixed) { + std::lock_guard hypoGuard(hypoMutex); + bFixed = fixed; +} + +double CHypo::getBayesInitial() const { + std::lock_guard hypoGuard(hypoMutex); + return (dBayesInitial); +} + +double CHypo::getCutFactor() const { + std::lock_guard hypoGuard(hypoMutex); + return (dCutFactor); +} + +void CHypo::setCutFactor(double cutFactor) { + std::lock_guard hypoGuard(hypoMutex); + dCutFactor = cutFactor; +} + +double CHypo::getCutMin() const { + std::lock_guard hypoGuard(hypoMutex); + return (dCutMin); +} + +void CHypo::setCutMin(double cutMin) { + std::lock_guard hypoGuard(hypoMutex); + dCutMin = cutMin; +} + +double CHypo::getCutPercentage() const { + std::lock_guard hypoGuard(hypoMutex); + return (dCutPercentage); +} + +void CHypo::setCutPercentage(double cutPercentage) { + std::lock_guard hypoGuard(hypoMutex); + dCutPercentage = cutPercentage; +} + +double CHypo::getGap() const { + std::lock_guard hypoGuard(hypoMutex); + return (dGap); +} + +double CHypo::getKrt() const { + std::lock_guard hypoGuard(hypoMutex); + return (dKrt); +} + +double CHypo::getMed() const { + std::lock_guard hypoGuard(hypoMutex); + return (dMed); +} + +double CHypo::getMin() const { + std::lock_guard hypoGuard(hypoMutex); + return (dMin); +} + +double CHypo::getRes() const { + std::lock_guard hypoGuard(hypoMutex); + return (dRes); +} + +double CHypo::getSig() const { + std::lock_guard hypoGuard(hypoMutex); + return (dSig); +} + +double CHypo::getThresh() const { + std::lock_guard hypoGuard(hypoMutex); + return (dThresh); +} + +void CHypo::setThresh(double thresh) { + std::lock_guard hypoGuard(hypoMutex); + dThresh = thresh; +} + +int CHypo::getCycle() const { + std::lock_guard hypoGuard(hypoMutex); + return (iCycle); +} + +int CHypo::setCycle(int newCycle) { + // lock mutex for this scope + std::lock_guard guard(hypoMutex); + + iCycle = newCycle; + + return (iCycle); +} + +int CHypo::getCut() const { + std::lock_guard hypoGuard(hypoMutex); + return (nCut); +} + +void CHypo::setCut(double cut) { + std::lock_guard hypoGuard(hypoMutex); + nCut = cut; +} + +const CGlass* CHypo::getGlass() const { + std::lock_guard hypoGuard(hypoMutex); + return (pGlass); +} + +void CHypo::setGlass(CGlass* glass) { + std::lock_guard hypoGuard(hypoMutex); + pGlass = glass; +} + +int CHypo::getProcessCount() const { + std::lock_guard guard(hypoMutex); + return (processCount); +} + +int CHypo::incrementProcessCount() { + // lock mutex for this scope + std::lock_guard guard(hypoMutex); + + processCount++; + + return (processCount); +} + +const std::string& CHypo::getPid() const { + return (sPid); +} + +const std::string& CHypo::getWebName() const { + return (sWebName); +} + +int CHypo::getVPickSize() const { + std::lock_guard hypoGuard(hypoMutex); + return (vPick.size()); +} +int CHypo::getVCorrSize() const { + std::lock_guard hypoGuard(hypoMutex); + return (vCorr.size()); +} + +double CHypo::getTCreate() const { + return (tCreate); +} + +int CHypo::getReportCount() const { + std::lock_guard hypoGuard(hypoMutex); + return (reportCount); +} + +bool CHypo::isLockedForProcessing() { + if (processingMutex.try_lock() == false) { + return (true); + } + + processingMutex.unlock(); + return (false); +} + +void CHypo::lockForProcessing() { + processingMutex.lock(); +} + +void CHypo::unlockAfterProcessing() { + processingMutex.unlock(); +} + } // namespace glasscore diff --git a/glasscore/glasslib/src/HypoList.cpp b/glasscore/glasslib/src/HypoList.cpp index 315d5fc5..aedcae8c 100644 --- a/glasscore/glasslib/src/HypoList.cpp +++ b/glasscore/glasslib/src/HypoList.cpp @@ -77,9 +77,9 @@ CHypoList::~CHypoList() { // ---------------------------------------------------------clear void CHypoList::clear() { - clearHypos(); - bSendEvent = false; + std::lock_guard hypoListGuard(m_HypoListMutex); + clearHypos(); pGlass = NULL; } @@ -99,7 +99,7 @@ void CHypoList::clearHypos() { } // ---------------------------------------------------------Dispatch -bool CHypoList::dispatch(json::Object *com) { +bool CHypoList::dispatch(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log( @@ -216,7 +216,7 @@ int CHypoList::pushFifo(std::shared_ptr hyp) { } // get this hypo's id - std::string pid = hyp->sPid; + std::string pid = hyp->getPid(); // is this id already on the queue? if (std::find(qFifo.begin(), qFifo.end(), pid) == qFifo.end()) { @@ -289,10 +289,10 @@ bool CHypoList::addHypo(std::shared_ptr hypo, bool scheduleProcessing) { // set some basic hypo values from pGlass if we have it if (pGlass) { - hypo->pGlass = pGlass; - hypo->dCutFactor = pGlass->dCutFactor; - hypo->dCutPercentage = pGlass->dCutPercentage; - hypo->dCutMin = pGlass->dCutMin; + hypo->setGlass(pGlass); + hypo->setCutFactor(pGlass->getCutFactor()); + hypo->setCutPercentage(pGlass->getCutPercentage()); + hypo->setCutMin(pGlass->getCutMin()); } // Add hypo to cache (mHypo) and time sorted @@ -306,11 +306,11 @@ bool CHypoList::addHypo(std::shared_ptr hypo, bool scheduleProcessing) { // get maximum number of hypos // use max picks from pGlass if we have it if (pGlass) { - nHypoMax = pGlass->nHypoMax; + nHypoMax = pGlass->getHypoMax(); } // create pair for insertion - std::pair p(hypo->tOrg, hypo->sPid); + std::pair p(hypo->getTOrg(), hypo->getPid()); // remove oldest hypo if this new one // pushes us over the limit @@ -331,19 +331,20 @@ bool CHypoList::addHypo(std::shared_ptr hypo, bool scheduleProcessing) { + " Removing Hypo: " + pdx.second); // create expiration message - json::Object expire; - expire["Cmd"] = "Expire"; - expire["Pid"] = pdx.second; + std::shared_ptr expire = std::make_shared( + json::Object()); + (*expire)["Cmd"] = "Expire"; + (*expire)["Pid"] = pdx.second; // send message if (pGlass) { - pGlass->send(&expire); + pGlass->send(expire); } } // Insert new hypo in proper time sequence into hypo vector // get the index of the new hypo - int ihypo = indexHypo(hypo->tOrg); + int ihypo = indexHypo(hypo->getTOrg()); switch (ihypo) { case -2: // Empty vector, just add it @@ -368,7 +369,7 @@ bool CHypoList::addHypo(std::shared_ptr hypo, bool scheduleProcessing) { break; } // add to hypo map - mHypo[hypo->sPid] = hypo; + mHypo[hypo->getPid()] = hypo; // Schedule this hypo for refinement. Note that this // hypo will be the first one in the queue, and will be the @@ -395,7 +396,7 @@ void CHypoList::remHypo(std::shared_ptr hypo, bool reportCancel) { } // get the id - std::string pid = hypo->sPid; + std::string pid = hypo->getPid(); // unlink all the hypo's data hypo->clearPicks(); @@ -423,18 +424,19 @@ void CHypoList::remHypo(std::shared_ptr hypo, bool reportCancel) { m_vHypoMutex.unlock(); - // Send cancellation message for this hypo if we're sending quake or event - // messages + // Send cancellation message for this hypo if we've sent an event + // message if (reportCancel == true) { - if ((hypo->bQuake) || (hypo->bEvent)) { + if (hypo->getEvent()) { // create cancellation message - json::Object can; - can["Cmd"] = "Cancel"; - can["Pid"] = pid; + std::shared_ptr cancel = + std::make_shared(json::Object()); + (*cancel)["Cmd"] = "Cancel"; + (*cancel)["Pid"] = pid; // send message if (pGlass) { - pGlass->send(&can); + pGlass->send(cancel); } } } @@ -507,14 +509,14 @@ bool CHypoList::associate(std::shared_ptr pk) { // are there any hypos to associate with? if (vHypo.size() < 1) { + glassutil::CLogit::log( + glassutil::log_level::debug, + "CHypoList::associate NOASSOC idPick:" + + std::to_string(pk->getIdPick()) + "; No Hypos"); // nope return (false); } - glassutil::CLogit::log( - glassutil::log_level::debug, - "CHypoList::associate idPick:" + std::to_string(pk->idPick)); - std::string pid; std::vector> viper; @@ -522,7 +524,7 @@ bool CHypoList::associate(std::shared_ptr pk) { // (a potential hypo must be before the pick we're associating) // use the pick time minus 2400 seconds to compute the starting index // NOTE: Hard coded time delta - int it1 = indexHypo(pk->tPick - 2400.0); + int it1 = indexHypo(pk->getTPick() - 2400.0); // check to see the index indicates that the time is before the // start of the hypo list @@ -533,10 +535,10 @@ bool CHypoList::associate(std::shared_ptr pk) { // get the ending index based on the pick time (a potential hypo can't // be after the pick we're associating) - int it2 = indexHypo(pk->tPick); + int it2 = indexHypo(pk->getTPick()); std::string pidmax; - double sdassoc = pGlass->sdAssociate; + double sdassoc = pGlass->getSdAssociate(); // for each hypo in the list within the // time range @@ -555,12 +557,17 @@ bool CHypoList::associate(std::shared_ptr pk) { viper.push_back(hyp); // remember this id for later - pidmax = hyp->sPid; + pidmax = hyp->getPid(); } } // there were no hypos that the pick associated with if (viper.size() < 1) { + glassutil::CLogit::log( + glassutil::log_level::debug, + "CHypoList::associate NOASSOC idPick:" + + std::to_string(pk->getIdPick())); + return (false); } @@ -570,15 +577,16 @@ bool CHypoList::associate(std::shared_ptr pk) { std::shared_ptr hyp = mHypo[pidmax]; // log - if (pGlass->bTrack) { - char sLog[1024]; - snprintf(sLog, sizeof(sLog), "ASS %s %s %s (%d)\n", - hyp->sPid.c_str(), - glassutil::CDate::encodeDateTime(pk->tPick).c_str(), - pk->pSite->sScnl.c_str(), - static_cast(hyp->vPick.size())); - glassutil::CLogit::Out(sLog); - } + /* + char sLog[1024]; + snprintf( + sLog, sizeof(sLog), "ASS %s %s %s (%d)\n", + hyp->getPid().c_str(), + glassutil::CDate::encodeDateTime(pk->getTPick()).c_str(), + pk->getSite()->getScnl().c_str(), + static_cast(hyp->getVPickSize())); + glassutil::CLogit::Out(sLog); + */ // link the pick to the hypo pk->addHypo(hyp, "", true); @@ -588,7 +596,7 @@ bool CHypoList::associate(std::shared_ptr pk) { glassutil::CLogit::log( glassutil::log_level::debug, - "CHypoList::associate (pick) sPid:" + hyp->sPid + "CHypoList::associate (pick) sPid:" + hyp->getPid() + " resetting cycle count due to new association"); // reset the cycle count @@ -597,6 +605,11 @@ bool CHypoList::associate(std::shared_ptr pk) { // add to the processing queue pushFifo(hyp); + glassutil::CLogit::log( + glassutil::log_level::debug, + "CHypoList::associate ASSOC idPick:" + + std::to_string(pk->getIdPick()) + "; numHypos:1"); + // the pick was associated return (true); } @@ -605,7 +618,7 @@ bool CHypoList::associate(std::shared_ptr pk) { for (auto q : viper) { glassutil::CLogit::log( glassutil::log_level::debug, - "CHypoList::associate (pick) sPid:" + q->sPid + "CHypoList::associate (pick) sPid:" + q->getPid() + " resetting cycle count due to new association"); // reset the cycle count @@ -616,6 +629,12 @@ bool CHypoList::associate(std::shared_ptr pk) { pushFifo(q); } + glassutil::CLogit::log( + glassutil::log_level::debug, + "CHypoList::associate ASSOC idPick:" + + std::to_string(pk->getIdPick()) + "; numHypos:" + + std::to_string(viper.size())); + // the pick was associated return (true); } @@ -661,7 +680,7 @@ bool CHypoList::associate(std::shared_ptr corr) { // *could* be issues here, but has no idea how significant they are. // Could affect association to splits with similar origin times. int it1 = indexHypo( - corr->tCorrelation - pGlass->correlationMatchingTWindow); + corr->getTCorrelation() - pGlass->getCorrelationMatchingTWindow()); // check to see the index indicates that the time is before the // start of the hypo list @@ -673,7 +692,7 @@ bool CHypoList::associate(std::shared_ptr corr) { // get the ending index based on the correlation time plus // correlationMatchingTWindow int it2 = indexHypo( - corr->tCorrelation + pGlass->correlationMatchingTWindow); + corr->getTCorrelation() + pGlass->getCorrelationMatchingTWindow()); std::string pidmax; @@ -688,13 +707,13 @@ bool CHypoList::associate(std::shared_ptr corr) { // check to see if the correlation will associate with // this hypo - if (hyp->associate(corr, pGlass->correlationMatchingTWindow, - pGlass->correlationMatchingXWindow)) { + if (hyp->associate(corr, pGlass->getCorrelationMatchingTWindow(), + pGlass->getCorrelationMatchingXWindow())) { // add to the list of hypos this correlation can associate with viper.push_back(hyp); // remember this id for later - pidmax = hyp->sPid; + pidmax = hyp->getPid(); } } @@ -709,18 +728,19 @@ bool CHypoList::associate(std::shared_ptr corr) { hyp = mHypo[pidmax]; // log - if (pGlass->bTrack) { - char sLog[1024]; - snprintf( - sLog, - sizeof(sLog), - "C-ASS %s %s %s (%d)\n", - hyp->sPid.substr(0, 4).c_str(), - glassutil::CDate::encodeDateTime(corr->tCorrelation).c_str(), - corr->pSite->sScnl.c_str(), - static_cast(hyp->vCorr.size())); - glassutil::CLogit::Out(sLog); - } + /* + char sLog[1024]; + snprintf( + sLog, + sizeof(sLog), + "C-ASS %s %s %s (%d)\n", + hyp->getPid().substr(0, 4).c_str(), + glassutil::CDate::encodeDateTime(corr->getTCorrelation()) + .c_str(), + corr->getSite()->getScnl().c_str(), + static_cast(hyp->getVCorrSize())); + glassutil::CLogit::Out(sLog); + */ // link the correlation to the hypo corr->addHypo(hyp, "", true); @@ -730,7 +750,7 @@ bool CHypoList::associate(std::shared_ptr corr) { glassutil::CLogit::log( glassutil::log_level::debug, - "CHypoList::associate (correlation) sPid:" + hyp->sPid + "CHypoList::associate (correlation) sPid:" + hyp->getPid() + " resetting cycle count due to new association"); // reset the cycle count @@ -747,7 +767,7 @@ bool CHypoList::associate(std::shared_ptr corr) { for (auto q : viper) { glassutil::CLogit::log( glassutil::log_level::debug, - "CHypoList::associate (correlation) sPid:" + q->sPid + "CHypoList::associate (correlation) sPid:" + q->getPid() + " resetting cycle count due to new association"); // reset the cycle count @@ -810,50 +830,70 @@ void CHypoList::darwin() { return; } - // log the hypo we're working on - glassutil::CLogit::log( - glassutil::log_level::debug, - "CHypoList::darwin Processing Hypo sPid:" + hyp->sPid + " Cycle:" - + std::to_string(hyp->iCycle) + " Fifo Size:" - + std::to_string(getFifoSize())); + // only allow one thread to process a hypo at at time + hyp->lockForProcessing(); - // check to see if this hypo is viable. - if (hyp->cancel()) { - // this hypo is no longer viable - // log + try { + // log the hypo we're working on glassutil::CLogit::log( glassutil::log_level::debug, - "CHypoList::darwin canceling sPid:" + hyp->sPid - + " processCount:" + std::to_string(hyp->processCount)); + "CHypoList::darwin Processing Hypo sPid:" + hyp->getPid() + + " Cycle:" + std::to_string(hyp->getCycle()) + + " Fifo Size:" + std::to_string(getFifoSize())); - // remove hypo from the hypo list - remHypo(hyp); + // check to see if this hypo is viable. + if (hyp->cancel()) { + hyp->unlockAfterProcessing(); - sort(); + // this hypo is no longer viable + // log + glassutil::CLogit::log( + glassutil::log_level::debug, + "CHypoList::darwin canceling sPid:" + hyp->getPid() + + " processCount:" + + std::to_string(hyp->getProcessCount())); - // done with processing - return; - } + // remove hypo from the hypo list + remHypo(hyp); - // check to see if we've hit the iCycle Limit for this - // hypo - if (hyp->iCycle >= pGlass->iCycleLimit) { - // log - glassutil::CLogit::log( - glassutil::log_level::debug, - "CHypoList::darwin skipping sPid:" + hyp->sPid - + " at cycle limit:" + std::to_string(hyp->iCycle) - + +" processCount:" - + std::to_string(hyp->processCount)); - return; - } + sort(); + + // done with processing + return; + } + + // check to see if we've hit the iCycle Limit for this + // hypo + if (hyp->getCycle() >= pGlass->getCycleLimit()) { + hyp->unlockAfterProcessing(); + // log + glassutil::CLogit::log( + glassutil::log_level::debug, + "CHypoList::darwin skipping sPid:" + hyp->getPid() + + " at cycle limit:" + + std::to_string(hyp->getCycle()) + + +" processCount:" + + std::to_string(hyp->getProcessCount())); + + return; + } - // process this hypocenter - evolve(hyp); + // process this hypocenter + evolve(hyp); - // resort the hypocenter list to maintain - // time order - sort(); + hyp->unlockAfterProcessing(); + + // resort the hypocenter list to maintain + // time order + sort(); + } catch (...) { + // ensure the hypo is unlocked + if (hyp->isLockedForProcessing()) { + hyp->unlockAfterProcessing(); + } + + throw; + } } // ---------------------------------------------------------evolve @@ -870,14 +910,13 @@ bool CHypoList::evolve(std::shared_ptr hyp, int announce) { return (false); } - hyp->incrementProcessCount(); - hyp->setCycle(hyp->iCycle + 1); + std::string pid = hyp->getPid(); - glassutil::CLogit::log( - glassutil::log_level::debug, - "CHypoList::evolve sPid:" + hyp->sPid + " cycle:" - + std::to_string(hyp->iCycle) + " processCount:" - + std::to_string(hyp->processCount)); + std::chrono::high_resolution_clock::time_point tEvolveStartTime = + std::chrono::high_resolution_clock::now(); + + hyp->incrementProcessCount(); + hyp->setCycle(hyp->getCycle() + 1); // initialize breport, gets set to true later if event isn't cancelled. // otherwise, in some cases events will not be reported. @@ -886,9 +925,15 @@ bool CHypoList::evolve(std::shared_ptr hyp, int announce) { // locate the hypo hyp->localize(); + std::chrono::high_resolution_clock::time_point tLocalizeEndTime = + std::chrono::high_resolution_clock::now(); + double localizeTime = std::chrono::duration_cast< + std::chrono::duration>(tLocalizeEndTime - tEvolveStartTime) + .count(); + // Search for any associable picks that match hypo in the pick list // NOTE: This uses the hard coded 2400 second scavenge duration default - if (pGlass->pPickList->scavenge(hyp)) { + if (pGlass->getPickList()->scavenge(hyp)) { // we should report this hypo since it has changed breport = true; @@ -898,7 +943,7 @@ bool CHypoList::evolve(std::shared_ptr hyp, int announce) { // search for any associable correlations that match hypo in the correlation // list - if (pGlass->pCorrelationList->scavenge(hyp)) { + if (pGlass->getCorrelationList()->scavenge(hyp)) { // we should report this hypo since it has changed breport = true; @@ -906,6 +951,12 @@ bool CHypoList::evolve(std::shared_ptr hyp, int announce) { hyp->localize(); } + std::chrono::high_resolution_clock::time_point tScavengeEndTime = + std::chrono::high_resolution_clock::now(); + double scavengeTime = std::chrono::duration_cast< + std::chrono::duration>(tScavengeEndTime - tLocalizeEndTime) + .count(); + // Ensure all data belong to hypo if (resolve(hyp)) { // we should report this hypo since it has changed @@ -915,6 +966,12 @@ bool CHypoList::evolve(std::shared_ptr hyp, int announce) { hyp->localize(); } + std::chrono::high_resolution_clock::time_point tResolveEndTime = + std::chrono::high_resolution_clock::now(); + double resolveTime = std::chrono::duration_cast< + std::chrono::duration>(tResolveEndTime - tScavengeEndTime) + .count(); + // Remove data that no longer fit hypo's association criteria if (hyp->prune()) { // we should report this hypo since it has changed @@ -924,6 +981,12 @@ bool CHypoList::evolve(std::shared_ptr hyp, int announce) { hyp->localize(); } + std::chrono::high_resolution_clock::time_point tPruneEndTime = + std::chrono::high_resolution_clock::now(); + double pruneTime = + std::chrono::duration_cast>( + tPruneEndTime - tResolveEndTime).count(); + /*// Check to see if event can be merged into another if (merge(hyp)) { @@ -933,16 +996,48 @@ bool CHypoList::evolve(std::shared_ptr hyp, int announce) { // check to see if this hypo is viable. if (hyp->cancel()) { + std::chrono::high_resolution_clock::time_point tCancelEndTime = + std::chrono::high_resolution_clock::now(); + double cancelTime = std::chrono::duration_cast< + std::chrono::duration>(tCancelEndTime - tPruneEndTime) + .count(); + + remHypo(hyp); + + std::chrono::high_resolution_clock::time_point tRemoveEndTime = + std::chrono::high_resolution_clock::now(); + double removeTime = std::chrono::duration_cast< + std::chrono::duration>(tRemoveEndTime - tCancelEndTime) + .count(); + + double evolveTime = std::chrono::duration_cast< + std::chrono::duration>( + tRemoveEndTime - tEvolveStartTime).count(); + glassutil::CLogit::log( glassutil::log_level::debug, - "CHypoList::evolve canceling sPid:" + hyp->sPid - + " processCount:" + std::to_string(hyp->processCount)); - remHypo(hyp); + "CHypoList::evolve: Canceled sPid:" + pid + " cycle:" + + std::to_string(hyp->getCycle()) + " processCount:" + + std::to_string(hyp->getProcessCount()) + + " Evolve Timing: localizeTime:" + + std::to_string(localizeTime) + " scavengeTime:" + + std::to_string(scavengeTime) + " resolveTime:" + + std::to_string(resolveTime) + " pruneTime:" + + std::to_string(pruneTime) + " cancelTime:" + + std::to_string(cancelTime) + " removeTime:" + + std::to_string(removeTime) + " evolveTime:" + + std::to_string(evolveTime)); // return false since the hypo was canceled. return (false); } + std::chrono::high_resolution_clock::time_point tCancelEndTime = + std::chrono::high_resolution_clock::now(); + double cancelTime = + std::chrono::duration_cast>( + tCancelEndTime - tPruneEndTime).count(); + // report if asked // NOTE: why? if (announce == 1) { @@ -951,11 +1046,12 @@ bool CHypoList::evolve(std::shared_ptr hyp, int announce) { // announce if a correlation has been added to an existing event // NOTE: Is there a better way to do this? - if ((hyp->bCorrAdded == true) && (hyp->vPick.size() >= hyp->nCut)) { + if ((hyp->getCorrAdded() == true) + && (hyp->getVPickSize() >= hyp->getCut())) { breport = true; - hyp->bCorrAdded = false; + hyp->setCorrAdded(false); } else { - hyp->bCorrAdded = false; + hyp->setCorrAdded(false); } // if we're supposed to report @@ -967,197 +1063,221 @@ bool CHypoList::evolve(std::shared_ptr hyp, int announce) { } } + std::chrono::high_resolution_clock::time_point tReportEndTime = + std::chrono::high_resolution_clock::now(); + double reportTime = + std::chrono::duration_cast>( + tReportEndTime - tCancelEndTime).count(); + // check for and log any miss-linked picks hyp->trap(); - // the hypo survived, so return true - return (true); -} - -// ---------------------------------------------------------merge -bool CHypoList::merge(std::shared_ptr hypo) { - std::lock_guard listGuard(m_vHypoMutex); - - if (pGlass == NULL) { - glassutil::CLogit::log(glassutil::log_level::error, - "CHypoList::merge: NULL pGlass."); - return (false); - } - - // are there any hypos to associate with? - if (vHypo.size() < 1) { - // nope - return (false); - } - - char sLog[1024]; - double distanceCut = 2.; - double timeCut = 60.; - double delta; - glassutil::CGeo geo; - geo.setGeographic(hypo->dLat, hypo->dLon, 6371.0); - std::shared_ptr hypo2; - int itHypo = indexHypo(hypo->tOrg); - - int it1 = indexHypo(hypo->tOrg - timeCut); + std::chrono::high_resolution_clock::time_point tTrapEndTime = + std::chrono::high_resolution_clock::now(); + double trapTime = std::chrono::duration_cast>( + tTrapEndTime - tReportEndTime).count(); - // check to see the index indicates that the time is before the - // start of the hypo list - if (it1 < 0) { - // set the starting index to the beginning of the hypo list - it1 = 0; - } - - // get the ending index based on the pick time (a potential hypo can't - // be after the pick we're associating) - int it2 = indexHypo(hypo->tOrg + timeCut); - - std::string pidmax; + double evolveTime = + std::chrono::duration_cast>( + tTrapEndTime - tEvolveStartTime).count(); - // for each hypo in the list within the - // time range - for (int it = it1; it <= it2; it++) { - if (it != itHypo) { - // get this hypo id - std::string pid = vHypo[it].second; - // get this hypo based on the id - hypo2 = mHypo[pid]; - glassutil::CGeo geo2; - geo2.setGeographic(hypo2->dLat, hypo2->dLon, 6371.0); - - // check distance between events - delta = geo.delta(&geo2); - if (delta < distanceCut - && (hypo->vPick.size() <= hypo2->vPick.size()) - && hypo->sPid != hypo2->sPid) { - snprintf( - sLog, sizeof(sLog), - "CHypoList::merge: Potentially Merging %s into %s\n", - hypo->sPid.c_str(), hypo2->sPid.c_str()); - glassutil::CLogit::log(sLog); - - std::shared_ptr hypo3 = std::make_shared( - (hypo2->dLat + hypo->dLat) / 2., - (hypo2->dLon + hypo->dLon) / 2., - (hypo2->dZ + hypo->dZ) / 2., - (hypo2->tOrg + hypo->tOrg) / 2., glassutil::CPid::pid(), - hypo2->sWeb, hypo2->dBayes, hypo2->dThresh, hypo2->nCut, - hypo2->pTrv1, hypo2->pTrv2, pGlass->pTTT); - - // set hypo glass pointer and such - hypo3->pGlass = pGlass; - hypo3->dCutFactor = pGlass->dCutFactor; - hypo3->dCutPercentage = pGlass->dCutPercentage; - hypo3->dCutMin = pGlass->dCutMin; - - // add all picks for other two events - for (auto pick : hypo->vPick) { - // they're not associated yet, just potentially - pick->sAss = "N"; - hypo3->addPick(pick); - } - - for (auto pick : hypo2->vPick) { - // they're not associated yet, just potentially - pick->sAss = "N"; - hypo3->addPick(pick); - } - - // First localization attempt after nucleation - // make 3 passes - - // hypo3->anneal(); need to flush out - hypo3->localize(); - - if (pGlass->pPickList->scavenge(hypo3)) { - // relocate the hypo - hypo3->localize(); - } - - /* - // Don't Resolve because the small events will always be a local minimum - if (resolve(hypo3)) { - // relocate the hypo - hypo3->localize(); - } - */ - // Remove picks that no longer fit hypo's association criteria - if (hypo3->prune()) { - // relocate the hypo - hypo3->localize(); - } - - int npick = hypo3->vPick.size(); - - /* - for (int ipass = 0; ipass < 3; ipass++) { - - // get an initial location via synthetic annealing, - // which also prunes out any poorly fitting picks - hypo3->localize(500, 100.0, 1.0); - - // get the number of picks we have now - npick = hypo3->vPick.size(); - - snprintf(sLog, sizeof(sLog), "CHypoList::merge: -- New Potential Event Passed %d %d/%d", ipass, npick, - ncut); - glassutil::CLogit::log(sLog); - } - */ - // check that it held onto picks delete other two events - if (npick > 0.6 * (hypo->vPick.size() + hypo2->vPick.size())) { - snprintf( - sLog, - sizeof(sLog), - "CHypoList::merge: -- keeping new event %s which" - " associated %d picks of %d potential picks", - hypo3->sPid.c_str(), - npick, - (static_cast(hypo->vPick.size()) - + static_cast(hypo2->vPick.size()))); - glassutil::CLogit::log(sLog); - - snprintf(sLog, sizeof(sLog), - " ** Canceling merged event %s\n", - hypo->sPid.c_str()); - glassutil::CLogit::Out(sLog); - remHypo(hypo); - - // check for and log any miss-linked picks - hypo->trap(); - - snprintf(sLog, sizeof(sLog), - " ** Canceling merged event %s\n", - hypo2->sPid.c_str()); - glassutil::CLogit::Out(sLog); - remHypo(hypo2); - - // check for and log any miss-linked picks - hypo2->trap(); - return true; - } else { - // else delete potential new events - snprintf( - sLog, - sizeof(sLog), - "CHypoList::merge: -- cancelling potential new" - " event %s which associated %d picks of %d" - " potential picks", - hypo3->sPid.c_str(), - npick, - (static_cast(hypo->vPick.size()) - + static_cast(hypo2->vPick.size()))); - glassutil::CLogit::log(sLog); - } - } - } - } + glassutil::CLogit::log( + glassutil::log_level::debug, + "CHypoList::evolve: Finished sPid:" + pid + " cycle:" + + std::to_string(hyp->getCycle()) + " processCount:" + + std::to_string(hyp->getProcessCount()) + + " Evolve Timing: localizeTime:" + + std::to_string(localizeTime) + " scavengeTime:" + + std::to_string(scavengeTime) + " resolveTime:" + + std::to_string(resolveTime) + " pruneTime:" + + std::to_string(pruneTime) + " cancelTime:" + + std::to_string(cancelTime) + " reportTime:" + + std::to_string(reportTime) + " trapTime:" + + std::to_string(trapTime) + " evolveTime:" + + std::to_string(evolveTime)); - return (false); + // the hypo survived, so return true + return (true); } - +/* + // ---------------------------------------------------------merge + bool CHypoList::merge(std::shared_ptr hypo) { + std::lock_guard listGuard(m_vHypoMutex); + + if (pGlass == NULL) { + glassutil::CLogit::log(glassutil::log_level::error, + "CHypoList::merge: NULL pGlass."); + return (false); + } + + // are there any hypos to associate with? + if (vHypo.size() < 1) { + // nope + return (false); + } + + char sLog[1024]; + double distanceCut = 2.; + double timeCut = 60.; + double delta; + glassutil::CGeo geo; + geo.setGeographic(hypo->getLat(), hypo->getLon(), 6371.0); + std::shared_ptr hypo2; + int itHypo = indexHypo(hypo->getTOrg()); + + int it1 = indexHypo(hypo->getTOrg() - timeCut); + + // check to see the index indicates that the time is before the + // start of the hypo list + if (it1 < 0) { + // set the starting index to the beginning of the hypo list + it1 = 0; + } + + // get the ending index based on the pick time (a potential hypo can't + // be after the pick we're associating) + int it2 = indexHypo(hypo->getTOrg() + timeCut); + + std::string pidmax; + + // for each hypo in the list within the + // time range + for (int it = it1; it <= it2; it++) { + if (it != itHypo) { + // get this hypo id + std::string pid = vHypo[it].second; + // get this hypo based on the id + hypo2 = mHypo[pid]; + glassutil::CGeo geo2; + geo2.setGeographic(hypo2->getLat(), hypo2->getLon(), 6371.0); + + // check distance between events + delta = geo.delta(&geo2); + if (delta < distanceCut + && (hypo->vPick.size() <= hypo2->vPick.size()) + && hypo->getPid() != hypo2->getPid()) { + snprintf( + sLog, sizeof(sLog), + "CHypoList::merge: Potentially Merging %s into %s\n", + hypo->getPid().c_str(), hypo2->getPid().c_str()); + glassutil::CLogit::log(sLog); + + std::shared_ptr hypo3 = std::make_shared( + (hypo2->getLat() + hypo->getLat()) / 2., + (hypo2->getLon() + hypo->getLon()) / 2., + (hypo2->getZ() + hypo->getZ()) / 2., + (hypo2->getTOrg() + hypo->getTOrg()) / 2., + glassutil::CPid::pid(), hypo2->sWeb, hypo2->getBayes(), + hypo2->dThresh, hypo2->nCut, hypo2->pTrv1, hypo2->pTrv2, + pGlass->pTTT); + + // set hypo glass pointer and such + hypo3->pGlass = pGlass; + hypo3->dCutFactor = pGlass->dCutFactor; + hypo3->dCutPercentage = pGlass->dCutPercentage; + hypo3->dCutMin = pGlass->dCutMin; + + // add all picks for other two events + for (auto pick : hypo->vPick) { + // they're not associated yet, just potentially + pick->setAss("N"); + hypo3->addPick(pick); + } + + for (auto pick : hypo2->vPick) { + // they're not associated yet, just potentially + pick->setAss("N"); + hypo3->addPick(pick); + } + + // First localization attempt after nucleation + // make 3 passes + + // hypo3->anneal(); need to flush out + hypo3->localize(); + + if (pGlass->pPickList->scavenge(hypo3)) { + // relocate the hypo + hypo3->localize(); + } + + // Remove picks that no longer fit hypo's association criteria + if (hypo3->prune()) { + // relocate the hypo + hypo3->localize(); + } + + int npick = hypo3->vPick.size(); + + + for (int ipass = 0; ipass < 3; ipass++) { + + // get an initial location via synthetic annealing, + // which also prunes out any poorly fitting picks + hypo3->localize(500, 100.0, 1.0); + + // get the number of picks we have now + npick = hypo3->vPick.size(); + + snprintf(sLog, sizeof(sLog), "CHypoList::merge: -- New Potential Event Passed %d %d/%d", ipass, npick, + ncut); + glassutil::CLogit::log(sLog); + } + + // check that it held onto picks delete other two events + if (npick > 0.6 * (hypo->vPick.size() + hypo2->vPick.size())) { + snprintf( + sLog, + sizeof(sLog), + "CHypoList::merge: -- keeping new event %s which" + " associated %d picks of %d potential picks", + hypo3->getPid().c_str(), + npick, + (static_cast(hypo->vPick.size()) + + static_cast(hypo2->vPick.size()))); + glassutil::CLogit::log(sLog); + + snprintf(sLog, sizeof(sLog), + " ** Canceling merged event %s\n", + hypo->getPid().c_str()); + glassutil::CLogit::Out(sLog); + remHypo(hypo); + + // check for and log any miss-linked picks + hypo->trap(); + + snprintf(sLog, sizeof(sLog), + " ** Canceling merged event %s\n", + hypo2->getPid().c_str()); + glassutil::CLogit::Out(sLog); + remHypo(hypo2); + + // check for and log any miss-linked picks + hypo2->trap(); + return true; + } else { + // else delete potential new events + snprintf( + sLog, + sizeof(sLog), + "CHypoList::merge: -- cancelling potential new" + " event %s which associated %d picks of %d" + " potential picks", + hypo3->getPid().c_str(), + npick, + (static_cast(hypo->vPick.size()) + + static_cast(hypo2->vPick.size()))); + glassutil::CLogit::log(sLog); + } + } + } + } + + return (false); + } + */ // ---------------------------------------------------------ReqHypo -bool CHypoList::reqHypo(json::Object *com) { +bool CHypoList::reqHypo(std::shared_ptr com) { std::lock_guard listGuard(m_vHypoMutex); // null check json @@ -1206,17 +1326,12 @@ bool CHypoList::reqHypo(json::Object *com) { return (false); } - // log - char sLog[1024]; - snprintf(sLog, sizeof(sLog), "ReqHypo %s\n", sPid.c_str()); - glassutil::CLogit::Out(sLog); - // get the hypo std::shared_ptr hyp = mHypo[sPid]; // check the hypo if (!hyp) { - return (false); + return (true); } // generate the hypo message @@ -1339,4 +1454,39 @@ bool CHypoList::statusCheck() { // everything is awesome return (true); } + +const CGlass* CHypoList::getGlass() const { + std::lock_guard hypoListGuard(m_HypoListMutex); + return (pGlass); +} + +void CHypoList::setGlass(CGlass* glass) { + std::lock_guard hypoListGuard(m_HypoListMutex); + pGlass = glass; +} + +int CHypoList::getNHypo() const { + std::lock_guard vHypoGuard(m_vHypoMutex); + return (nHypo); +} + +int CHypoList::getNHypoMax() const { + std::lock_guard hypoListGuard(m_HypoListMutex); + return (nHypoMax); +} + +void CHypoList::setNHypoMax(int hypoMax) { + std::lock_guard hypoListGuard(m_HypoListMutex); + nHypoMax = hypoMax; +} + +int CHypoList::getNHypoTotal() const { + std::lock_guard vHypoGuard(m_vHypoMutex); + return (nHypoTotal); +} + +int CHypoList::getVHypoSize() const { + std::lock_guard vHypoGuard(m_vHypoMutex); + return (vHypo.size()); +} } // namespace glasscore diff --git a/glasscore/glasslib/src/Node.cpp b/glasscore/glasslib/src/Node.cpp index ad31dd2f..b0e5c88e 100644 --- a/glasscore/glasslib/src/Node.cpp +++ b/glasscore/glasslib/src/Node.cpp @@ -5,9 +5,11 @@ #include #include #include +#include #include "Node.h" #include "Glass.h" #include "Web.h" +#include "Trigger.h" #include "Site.h" #include "Pick.h" #include "Date.h" @@ -18,14 +20,14 @@ namespace glasscore { // site Link sorting function // Compares site links using travel times bool sortSiteLink(const SiteLink &lhs, const SiteLink &rhs) { - double travelTime1 = std::get < LINK_TT1 > (lhs); + double travelTime1 = std::get< LINK_TT1>(lhs); if (travelTime1 < 0) { - travelTime1 = std::get < LINK_TT2 > (lhs); + travelTime1 = std::get< LINK_TT2>(lhs); } - double travelTime2 = std::get < LINK_TT1 > (rhs); + double travelTime2 = std::get< LINK_TT1>(rhs); if (travelTime2 < 0) { - travelTime2 = std::get < LINK_TT2 > (rhs); + travelTime2 = std::get< LINK_TT2>(rhs); } // compare @@ -57,6 +59,8 @@ CNode::~CNode() { // ---------------------------------------------------------clear void CNode::clear() { + std::lock_guard nodeGuard(nodeMutex); + clearSiteLinks(); sName = "Nemo"; @@ -65,10 +69,6 @@ void CNode::clear() { dLon = 0; dZ = 0; dResolution = 0; - tOrg = 0; - nCount = 0; - dSum = 0; - nCount = 0; sPid = ""; bEnabled = false; } @@ -79,11 +79,11 @@ void CNode::clearSiteLinks() { } // lock mutex for this scope - std::lock_guard < std::mutex > guard(vSiteMutex); + std::lock_guard guard(vSiteMutex); // remove any links that sites have TO this node for (auto &link : vSite) { - std::shared_ptr aSite = std::get < LINK_PTR > (link); + std::shared_ptr aSite = std::get< LINK_PTR>(link); aSite->remNode(sPid); } @@ -93,6 +93,8 @@ void CNode::clearSiteLinks() { bool CNode::initialize(std::string name, double lat, double lon, double z, double resolution, std::string nodeID) { + std::lock_guard nodeGuard(nodeMutex); + clear(); sName = name; @@ -123,7 +125,7 @@ bool CNode::linkSite(std::shared_ptr site, std::shared_ptr node, } // lock mutex for this scope - std::lock_guard < std::mutex > guard(vSiteMutex); + std::lock_guard guard(vSiteMutex); // Link node to site using traveltime // NOTE: No validation on travel times @@ -157,11 +159,11 @@ bool CNode::unlinkSite(std::shared_ptr site) { std::shared_ptr foundSite; for (const auto &link : vSite) { // get the site - std::shared_ptr currentSite = std::get < LINK_PTR > (link); + std::shared_ptr currentSite = std::get< LINK_PTR>(link); // if the new station would be before // the current station - if (currentSite->sScnl == site->sScnl) { + if (currentSite->getScnl() == site->getScnl()) { found = true; foundLink = link; foundSite = currentSite; @@ -209,7 +211,7 @@ bool CNode::unlinkLastSite() { lastSite->remNode(sPid); // lock mutex for this scope - std::lock_guard < std::mutex > guard(vSiteMutex); + std::lock_guard guard(vSiteMutex); // unlink last site from node vSite.pop_back(); @@ -221,48 +223,45 @@ bool CNode::unlinkLastSite() { } // ---------------------------------------------------------Nucleate -bool CNode::nucleate(double tOrigin, bool bList) { +std::shared_ptr CNode::nucleate(double tOrigin) { + std::lock_guard nodeGuard(nodeMutex); + // nullchecks // check web if (pWeb == NULL) { glassutil::CLogit::log(glassutil::log_level::error, "CNode::nucleate: NULL web pointer."); - return (false); + return (NULL); } // check web pGlass - if (pWeb->pGlass == NULL) { + if (pWeb->getGlass() == NULL) { glassutil::CLogit::log(glassutil::log_level::error, "CNode::nucleate: NULL web glass pointer."); - return (false); + return (NULL); } // don't nucleate if this node is disabled if (bEnabled == false) { - return (false); + return (NULL); } - tOrg = 0.0; - // get the cut and threshold from our // parent web - int nCut = pWeb->nNucleate; - double dThresh = pWeb->dThresh; - double dAzimuthRange = pWeb->pGlass->beamMatchingAzimuthWindow; + int nCut = pWeb->getNucleate(); + double dThresh = pWeb->getThresh(); + double dAzimuthRange = pWeb->getGlass()->getBeamMatchingAzimuthWindow(); // commented out because slowness matching of beams is not yet implemented // but is scheduled to be soon - // double dDistanceRange = pWeb->pGlass->beamMatchingDistanceWindow; + // double dDistanceRange = pWeb->pGlass->getBeamMatchingDistanceWindow(); // init overall significance sum and node site count // to 0 - dSum = 0.0; - nCount = 0; + double dSum = 0.0; + int nCount = 0; - // clear the pick vector - if (bList) { - vPick.clear(); - } + std::vector> vPick; // lock mutex for this scope - std::lock_guard < std::mutex > guard(vSiteMutex); + std::lock_guard guard(vSiteMutex); // the best nucleating pick std::shared_ptr pickBest; @@ -273,21 +272,22 @@ bool CNode::nucleate(double tOrigin, bool bList) { double dSigBest = -1.0; // get shared pointer to site - std::shared_ptr site = std::get < LINK_PTR > (link); + std::shared_ptr site = std::get< LINK_PTR>(link); // Ignore if station out of service - if (!site->bUse) { + if (!site->getUse()) { continue; } - site->vPickMutex.lock(); + std::vector> vSitePicks = site->getVPick(); + // search through each pick at this site - for (const auto &pick : site->vPick) { + for (const auto &pick : vSitePicks) { // get the pick's arrival time - double tPick = pick->tPick; + double tPick = pick->getTPick(); // get the picks back azimuth - double backAzimuth = pick->dBackAzimuth; + double backAzimuth = pick->getBackAzimuth(); // compute observed travel time from the pick time and // the provided origin time @@ -307,7 +307,8 @@ bool CNode::nucleate(double tOrigin, bool bList) { nodeGeo.setGeographic(dLat, dLon, 6371.0 - dZ); // compute azimith from the site to the node - double siteAzimuth = pick->pSite->geo.azimuth(&nodeGeo); + double siteAzimuth = pick->getSite()->getGeo().azimuth( + &nodeGeo); // check to see if pick's backazimuth is within the // valid range @@ -324,7 +325,7 @@ bool CNode::nucleate(double tOrigin, bool bList) { // azimuth check /*if (pick->dSlowness > 0) { // compute distance from the site to the node - double siteDistance = pick->pSite->geo.delta(&nodeGeo); + double siteDistance = pick->pSite->getGeo().delta(&nodeGeo); // compute observed distance from slowness (1/velocity) // and tObs (distance = velocity * time) @@ -354,12 +355,9 @@ bool CNode::nucleate(double tOrigin, bool bList) { } } - site->vPickMutex.unlock(); - // check to see if the pick with the highest significance at this site // should be added to the overall sum from this site // NOTE: This significance threshold is hard coded. - if (dSigBest >= 0.1) { // count this site nCount++; @@ -369,9 +367,7 @@ bool CNode::nucleate(double tOrigin, bool bList) { dSum += dSigBest; // add the pick to the pick vector - if (bList) { - vPick.push_back(pickBest); - } + vPick.push_back(pickBest); } } @@ -385,42 +381,31 @@ bool CNode::nucleate(double tOrigin, bool bList) { // exceeds the nucleation threshold if (nCount < nCut) { // the node did not nucleate an event - return (false); + return (NULL); } // make sure the total node significance exceeds the // significance threshold if (dSum < dThresh) { // the node did not nucleate an event - return (false); - } - - // Log nucleation statistics - if (bList) { - // convert time to human readable - glassutil::CDate dt = glassutil::CDate(tOrigin); - std::string sOrg = dt.dateTime(); - char sLog[1024]; - snprintf(sLog, sizeof(sLog), - "**Nucleate %s Web:%s Cut:%d Thresh:%.2f\n", sOrg.c_str(), - pWeb->sName.c_str(), nCut, dSum); - glassutil::CLogit::Out(sLog); + return (NULL); } - // remember tOrigin, it will be used when a hypocenter is created - // from this node - tOrg = tOrigin; + // create trigger + std::shared_ptr trigger( + new CTrigger(dLat, dLon, dZ, tOrigin, dResolution, dSum, nCount, + vPick, pWeb)); // the node nucleated an event - return (true); + return (trigger); } double CNode::getBestSig(double tObservedTT, SiteLink link) { // get traveltime1 to site - double travelTime1 = std::get < LINK_TT1 > (link); + double travelTime1 = std::get< LINK_TT1>(link); // get traveltime2 to site - double travelTime2 = std::get < LINK_TT2 > (link); + double travelTime2 = std::get< LINK_TT2>(link); // use observed travel time, travel times to site, and a dT/dKm of // 0.1 s/km to calculate distance residuals @@ -447,11 +432,11 @@ double CNode::getBestSig(double tObservedTT, SiteLink link) { // and detection grid resolution double dSig1 = 0; if (dRes1 > 0) { - dSig1 = pWeb->pGlass->sig(dRes1, dResolution); + dSig1 = pWeb->getGlass()->sig(dRes1, dResolution); } double dSig2 = 0; if (dRes2 > 0) { - dSig2 = pWeb->pGlass->sig(dRes2, dResolution); + dSig2 = pWeb->getGlass()->sig(dRes2, dResolution); } // return the higher of the two significances @@ -468,16 +453,16 @@ std::shared_ptr CNode::getSite(std::string sScnl) { } // lock mutex for this scope - std::lock_guard < std::mutex > guard(vSiteMutex); + std::lock_guard guard(vSiteMutex); // NOTE: could be made more efficient (faster) // if we had a std::map // for all sites for (const auto &link : vSite) { // get the site - auto aSite = std::get < LINK_PTR > (link); + auto aSite = std::get< LINK_PTR>(link); - if (aSite->sScnl == sScnl) { + if (aSite->getScnl() == sScnl) { // found return (aSite); } @@ -493,10 +478,10 @@ std::shared_ptr CNode::getLastSite() { } // lock mutex for this scope - std::lock_guard < std::mutex > guard(vSiteMutex); + std::lock_guard guard(vSiteMutex); SiteLink lastLink = vSite[vSite.size() - 1]; - std::shared_ptr lastSite = std::get < LINK_PTR > (lastLink); + std::shared_ptr lastSite = std::get< LINK_PTR>(lastLink); // found return (lastSite); @@ -504,7 +489,7 @@ std::shared_ptr CNode::getLastSite() { void CNode::sortSiteLinks() { // lock mutex for this scope - std::lock_guard < std::mutex > guard(vSiteMutex); + std::lock_guard guard(vSiteMutex); // sort sites sort(vSite.begin(), vSite.end(), sortSiteLink); @@ -512,28 +497,70 @@ void CNode::sortSiteLinks() { std::string CNode::getSitesString() { // lock mutex for this scope - std::lock_guard < std::mutex > guard(vSiteMutex); + std::lock_guard guard(vSiteMutex); std::string siteString = ""; // write to station file for (const auto &link : vSite) { // get the site - std::shared_ptr currentSite = std::get < LINK_PTR > (link); + std::shared_ptr currentSite = std::get< LINK_PTR>(link); - siteString += sPid + "," + currentSite->sScnl + "," - + std::to_string(currentSite->geo.dLat) + ";" - + std::to_string(currentSite->geo.dLon) + ";" - + std::to_string(currentSite->geo.dRad) + "\n"; + siteString += sPid + "," + currentSite->getScnl() + "," + + std::to_string(currentSite->getGeo().dLat) + ";" + + std::to_string(currentSite->getGeo().dLon) + ";" + + std::to_string(currentSite->getGeo().dRad) + "\n"; } return (siteString); } -int CNode::getSiteLinksCount() { +int CNode::getSiteLinksCount() const { // lock mutex for this scope - std::lock_guard < std::mutex > guard(vSiteMutex); - int size = vSite.size(); + std::lock_guard guard(vSiteMutex); + return (vSite.size()); +} + +bool CNode::getEnabled() const { + std::lock_guard nodeGuard(nodeMutex); + return (bEnabled); +} + +void CNode::setEnabled(bool enabled) { + std::lock_guard nodeGuard(nodeMutex); + bEnabled = enabled; +} + +double CNode::getLat() const { + return (dLat); +} + +double CNode::getLon() const { + return (dLon); +} + +double CNode::getResolution() const { + return (dResolution); +} + +double CNode::getZ() const { + return (dZ); +} + +CWeb* CNode::getWeb() const { + std::lock_guard nodeGuard(nodeMutex); + return (pWeb); +} + +void CNode::setWeb(CWeb* web) { + std::lock_guard nodeGuard(nodeMutex); + pWeb = web; +} + +const std::string& CNode::getName() const { + return (sName); +} - return (size); +const std::string& CNode::getPid() const { + return (sPid); } } // namespace glasscore diff --git a/glasscore/glasslib/src/Pick.cpp b/glasscore/glasslib/src/Pick.cpp index 39964714..b1c69be6 100644 --- a/glasscore/glasslib/src/Pick.cpp +++ b/glasscore/glasslib/src/Pick.cpp @@ -1,8 +1,10 @@ #include #include #include +#include #include "Pid.h" #include "Web.h" +#include "Trigger.h" #include "Node.h" #include "PickList.h" #include "HypoList.h" @@ -33,7 +35,8 @@ CPick::CPick(std::shared_ptr pickSite, double pickTime, int pickId, } // ---------------------------------------------------------CPick -CPick::CPick(json::Object *pick, int pickId, CSiteList *pSiteList) { +CPick::CPick(std::shared_ptr pick, int pickId, + CSiteList *pSiteList) { clear(); // null check json @@ -100,6 +103,7 @@ CPick::CPick(json::Object *pick, int pickId, CSiteList *pSiteList) { glassutil::CLogit::log( glassutil::log_level::error, "CPick::CPick: Missing required Station Key."); + return; } @@ -119,6 +123,7 @@ CPick::CPick(json::Object *pick, int pickId, CSiteList *pSiteList) { glassutil::CLogit::log( glassutil::log_level::error, "CPick::CPick: Missing required Network Key."); + return; } @@ -133,6 +138,7 @@ CPick::CPick(json::Object *pick, int pickId, CSiteList *pSiteList) { // no site key glassutil::CLogit::log(glassutil::log_level::error, "CPick::CPick: Missing required Site Key."); + return; } @@ -145,11 +151,12 @@ CPick::CPick(json::Object *pick, int pickId, CSiteList *pSiteList) { if (site == NULL) { glassutil::CLogit::log(glassutil::log_level::warn, "CPick::CPick: site is null."); + return; } // check to see if we're using this site - if (!site->bUse) { + if (!site->getUse()) { return; } @@ -171,6 +178,7 @@ CPick::CPick(json::Object *pick, int pickId, CSiteList *pSiteList) { glassutil::CLogit::log( glassutil::log_level::error, "CPick::CPick: Missing required Time or T Key."); + return; } @@ -186,6 +194,7 @@ CPick::CPick(json::Object *pick, int pickId, CSiteList *pSiteList) { glassutil::CLogit::log( glassutil::log_level::warn, "CPick::CPick: Missing required ID or Pid Key."); + return; } @@ -225,12 +234,11 @@ CPick::CPick(json::Object *pick, int pickId, CSiteList *pSiteList) { return; } - std::lock_guard < std::recursive_mutex > guard(pickMutex); + std::lock_guard guard(pickMutex); // remember input json for hypo message generation // note, move to init? - std::shared_ptr jpck(new json::Object(*pick)); - jPick = jpck; + jPick = pick; } // ---------------------------------------------------------~CPick @@ -240,11 +248,11 @@ CPick::~CPick() { // ---------------------------------------------------------~clear void CPick::clear() { - std::lock_guard < std::recursive_mutex > guard(pickMutex); + std::lock_guard guard(pickMutex); - pSite = NULL; - pHypo = NULL; - jPick = NULL; + pSite.reset(); + wpHypo.reset(); + jPick.reset(); sAss = ""; sPhs = ""; @@ -258,9 +266,9 @@ void CPick::clear() { bool CPick::initialize(std::shared_ptr pickSite, double pickTime, int pickId, std::string pickIdString, double backAzimuth, double slowness) { + std::lock_guard guard(pickMutex); + clear(); - // lock after clear to avoid deadlock - std::lock_guard < std::recursive_mutex > guard(pickMutex); // nullcheck if (pickSite == NULL) { @@ -274,18 +282,19 @@ bool CPick::initialize(std::shared_ptr pickSite, double pickTime, dBackAzimuth = backAzimuth; dSlowness = slowness; - glassutil::CLogit::log( - glassutil::log_level::debug, - "CPick::initialize: site:" + pSite->sScnl + "; tPick:" - + std::to_string(tPick) + "; idPick:" - + std::to_string(idPick) + "; sPid:" + sPid); + /* glassutil::CLogit::log( + glassutil::log_level::debug, + "CPick::initialize: site:" + pSite->getScnl() + "; tPick:" + + std::to_string(tPick) + "; idPick:" + + std::to_string(idPick) + "; sPid:" + sPid); + */ return (true); } // ---------------------------------------------------------addHypo void CPick::addHypo(std::shared_ptr hyp, std::string ass, bool force) { - std::lock_guard < std::recursive_mutex > guard(pickMutex); + std::lock_guard guard(pickMutex); // nullcheck if (hyp == NULL) { @@ -296,17 +305,17 @@ void CPick::addHypo(std::shared_ptr hyp, std::string ass, bool force) { // Add hypo data reference to this pick if (force == true) { - pHypo = hyp; + wpHypo = hyp; sAss = ass; - } else if (!pHypo) { - pHypo = hyp; + } else if (wpHypo.expired() == true) { + wpHypo = hyp; sAss = ass; } } // ---------------------------------------------------------remHypo void CPick::remHypo(std::shared_ptr hyp) { - std::lock_guard < std::recursive_mutex > guard(pickMutex); + std::lock_guard guard(pickMutex); // nullcheck if (hyp == NULL) { @@ -315,19 +324,25 @@ void CPick::remHypo(std::shared_ptr hyp) { return; } - // Remove hypo reference from this pick - if (pHypo->sPid == hyp->sPid) { - pHypo = NULL; + // is the pointer still valid + if (auto pHypo = wpHypo.lock()) { + // Remove hypo reference from this pick + if (pHypo->getPid() == hyp->getPid()) { + clearHypo(); + } + } else { + // remove invalid pointer + clearHypo(); } } void CPick::clearHypo() { - std::lock_guard < std::recursive_mutex > guard(pickMutex); - pHypo = NULL; + std::lock_guard guard(pickMutex); + wpHypo.reset(); } void CPick::setAss(std::string ass) { - std::lock_guard < std::recursive_mutex > guard(pickMutex); + std::lock_guard guard(pickMutex); sAss = ass; } @@ -335,7 +350,7 @@ void CPick::setAss(std::string ass) { // ---------------------------------------------------------Nucleate bool CPick::nucleate() { // get CGlass pointer from site - CGlass *pGlass = pSite->pGlass; + CGlass *pGlass = pSite->getGlass(); // nullcheck if (pGlass == NULL) { @@ -344,31 +359,30 @@ bool CPick::nucleate() { return (false); } + std::string pt = glassutil::CDate::encodeDateTime(tPick); char sLog[1024]; // Use site nucleate to scan all nodes // linked to this pick's site and calculate // the stacked agoric at each node. If the threshold // is exceeded, the node is added to the site's trigger list - pSite->nucleate(tPick); - - // Set glass values for debugging - pGlass->sWeb = ""; - pGlass->nCount = 0; - pGlass->dSum = 0.0; - - // for each node that triggered linked to this - // pick's site - pSite->vTriggerMutex.lock(); - for (auto node : pSite->vTrigger) { - // Set glass values for debugging - pGlass->sWeb = node->pWeb->sName; - pGlass->nCount = node->nCount; - pGlass->dSum = node->dSum; - - snprintf(sLog, sizeof(sLog), "CPick::nucleate: %s %d %.2f", - pGlass->sWeb.c_str(), pGlass->nCount, pGlass->dSum); - glassutil::CLogit::log(sLog); + std::vector> vTrigger = pSite->nucleate(tPick); + + // if there were no triggers, we're done + if (vTrigger.size() == 0) { + glassutil::CLogit::log( + glassutil::log_level::debug, + "CPick::nucleate: NOTRG site:" + pSite->getScnl() + "; tPick:" + + pt + "; idPick:" + std::to_string(idPick) + "; sPid:" + + sPid); + + return (false); + } + + for (const auto &trigger : vTrigger) { + if (trigger->getWeb() == NULL) { + continue; + } // nucleate at the node to build the // list of picks that support this node @@ -376,41 +390,34 @@ bool CPick::nucleate() { // NOTE: this did not used to check the nucleate return here // it seems that this should improve computational performance // but MIGHT have unintended consequences. - if (!node->nucleate(node->tOrg, true)) { - // didn't nucleate anything - continue; - } + // if (!node->nucleate(node->getTOrg(), true)) { + // didn't nucleate anything + // continue; + // } // create the hypo using the node - pGlass->m_TTTMutex.lock(); - std::shared_ptr hypo = std::make_shared < CHypo - > (node, pGlass->pTTT); - pGlass->m_TTTMutex.unlock(); + std::shared_ptr hypo = std::make_shared( + trigger, pGlass->getTTT()); // set hypo glass pointer and such - hypo->pGlass = pGlass; - hypo->dCutFactor = pGlass->dCutFactor; - hypo->dCutPercentage = pGlass->dCutPercentage; - hypo->dCutMin = pGlass->dCutMin; + hypo->setGlass(pGlass); + hypo->setCutFactor(pGlass->getCutFactor()); + hypo->setCutPercentage(pGlass->getCutPercentage()); + hypo->setCutMin(pGlass->getCutMin()); // add links to all the picks that support the hypo - for (auto pick : node->vPick) { + std::vector> vTriggerPicks = trigger->getVPick(); + + for (auto pick : vTriggerPicks) { // they're not associated yet, just potentially pick->setAss("N"); hypo->addPick(pick); - - // debug logging - if (pGlass->bTrack) { - snprintf(sLog, sizeof(sLog), - "CPick::nucleate: Adding to hyp %s\n", - pick->pSite->sScnl.c_str()); - glassutil::CLogit::log(sLog); - } } // use the hypo's nucleation threshold, which is really the // web's nucleation threshold - int ncut = hypo->nCut; + int ncut = hypo->getCut(); + double thresh = hypo->getThresh(); bool bad = false; // First localization attempt after nucleation @@ -422,17 +429,35 @@ bool CPick::nucleate() { // far out the ot can change without losing the initial pick // this all assumes that the closest grid triggers // values derived from testing global event association - - hypo->anneal(10000, node->dResolution / 2., node->dResolution / 10., - node->dResolution / 10.0, .1); + double bayes = hypo->anneal(10000, trigger->getResolution() / 2., + trigger->getResolution() / 10., + trigger->getResolution() / 10.0, .1); // get the number of picks we have now - int npick = hypo->vPick.size(); + int npick = hypo->getVPickSize(); - snprintf(sLog, sizeof(sLog), "CPick::nucleate: -- Pass %d %d/%d %s", - ipass, npick, ncut, hypo->sPid.c_str()); + snprintf(sLog, sizeof(sLog), "CPick::nucleate: -- Pass:%d; nPick:%d" + "/nCut:%d; bayes:%f/thresh:%f; %s", + ipass, npick, ncut, bayes, thresh, + hypo->getPid().c_str()); glassutil::CLogit::log(sLog); + // check to see if we still have a high enough bayes value for this + // hypo to survive. + if (bayes < thresh) { + // it isn't + snprintf(sLog, sizeof(sLog), + "CPick::nucleate: -- Abandoning solution %s " + "due to low bayes value " + "(bayes:%f/thresh:%f)", + hypo->getPid().c_str(), bayes, thresh); + glassutil::CLogit::log(sLog); + + // don't bother making additional passes + bad = true; + break; + } + // check to see if we still have enough picks for this hypo to // survive. // NOTE, in Node, ncut is used as a threshold for the number of @@ -441,8 +466,10 @@ bool CPick::nucleate() { if (npick < ncut) { // we don't snprintf(sLog, sizeof(sLog), - "CPick::nucleate: -- Abandoning this solution %s", - hypo->sPid.c_str()); + "CPick::nucleate: -- Abandoning solution %s " + "due to lack of picks " + "(npick:%d/ncut:%d)", + hypo->getPid().c_str(), npick, ncut); glassutil::CLogit::log(sLog); // don't bother making additional passes @@ -459,20 +486,20 @@ bool CPick::nucleate() { // if we got this far, the hypo has enough supporting data to // merit looking at it closer. Process it using evolve - if (pGlass->pHypoList->evolve(hypo, 1)) { + if (pGlass->getHypoList()->evolve(hypo, 1)) { // the hypo survived evolve, // log the hypo - std::string st = glassutil::CDate::encodeDateTime(hypo->tOrg); - snprintf(sLog, sizeof(sLog), - "CPick::nucleate: TRG hypo:%s %s %9.4f %10.4f %6.1f %d", - hypo->sPid.c_str(), st.c_str(), hypo->dLat, hypo->dLon, - hypo->dZ, static_cast(hypo->vPick.size())); - glassutil::CLogit::log(sLog); + std::string st = glassutil::CDate::encodeDateTime(hypo->getTOrg()); - // log the triggering web - snprintf(sLog, sizeof(sLog), "CPick::nucleate: WEB %s\n", - node->sName.c_str()); - glassutil::CLogit::log(sLog); + glassutil::CLogit::log( + glassutil::log_level::debug, + "CPick::nucleate: TRG site:" + pSite->getScnl() + "; tPick:" + + pt + "; idPick:" + std::to_string(idPick) + + "; sPid:" + sPid + " => web:" + hypo->getWebName() + + "; hyp: " + hypo->getPid() + "; lat:" + + std::to_string(hypo->getLat()) + "; lon:" + + std::to_string(hypo->getLon()) + "; z:" + + std::to_string(hypo->getZ()) + "; tOrg:" + st); // add a link to the hypo for each pick // NOTE: Why is this done? Shouldn't evolve have already @@ -487,23 +514,54 @@ bool CPick::nucleate() { }*/ // add new hypo to hypo list - pGlass->pHypoList->addHypo(hypo); + pGlass->getHypoList()->addHypo(hypo); } } - int triggerCount = pSite->vTrigger.size(); - pSite->vTriggerMutex.unlock(); + // done + return (true); +} - // If any webs triggered, return true to prevent further association - if (triggerCount > 0) { - return (true); - } +double CPick::getBackAzimuth() const { + return (dBackAzimuth); +} - snprintf(sLog, sizeof(sLog), "CPick::nucleate: NOTRG idPick:%d sPid:%s", - idPick, sPid.c_str()); - glassutil::CLogit::log(sLog); +double CPick::getSlowness() const { + return (dSlowness); +} - // done - return (false); +int CPick::getIdPick() const { + return (idPick); } + +const std::shared_ptr& CPick::getJPick() const { + return (jPick); +} + +const std::shared_ptr CPick::getHypo() const { + std::lock_guard pickGuard(pickMutex); + return (wpHypo.lock()); +} + +const std::shared_ptr& CPick::getSite() const { + return (pSite); +} + +const std::string& CPick::getAss() const { + std::lock_guard pickGuard(pickMutex); + return (sAss); +} + +const std::string& CPick::getPhs() const { + return (sPhs); +} + +const std::string& CPick::getPid() const { + return (sPid); +} + +double CPick::getTPick() const { + return (tPick); +} + } // namespace glasscore diff --git a/glasscore/glasslib/src/PickList.cpp b/glasscore/glasslib/src/PickList.cpp index c596730d..c59f61f7 100644 --- a/glasscore/glasslib/src/PickList.cpp +++ b/glasscore/glasslib/src/PickList.cpp @@ -76,7 +76,7 @@ CPickList::~CPickList() { // ---------------------------------------------------------~clear void CPickList::clear() { - std::lock_guard listGuard(m_vPickMutex); + std::lock_guard pickListGuard(m_PickListMutex); pGlass = NULL; pSiteList = NULL; @@ -106,7 +106,7 @@ void CPickList::clearPicks() { } // ---------------------------------------------------------Dispatch -bool CPickList::dispatch(json::Object *com) { +bool CPickList::dispatch(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log( @@ -154,7 +154,7 @@ bool CPickList::dispatch(json::Object *com) { } // ---------------------------------------------------------addPick -bool CPickList::addPick(json::Object *pick) { +bool CPickList::addPick(std::shared_ptr pick) { // null check json if (pick == NULL) { glassutil::CLogit::log(glassutil::log_level::error, @@ -202,16 +202,18 @@ bool CPickList::addPick(json::Object *pick) { CPick * newPick = new CPick(pick, nPick + 1, pSiteList); // check to see if we got a valid pick - if ((newPick->pSite == NULL) || (newPick->tPick == 0) - || (newPick->sPid == "")) { + if ((newPick->getSite() == NULL) || (newPick->getTPick() == 0) + || (newPick->getPid() == "")) { // cleanup delete (newPick); - return (false); + // message was processed + return (true); } // check if pick is duplicate, if pGlass exists if (pGlass) { - bool duplicate = checkDuplicate(newPick, pGlass->pickDuplicateWindow); + bool duplicate = checkDuplicate(newPick, + pGlass->getPickDuplicateWindow()); // it is a duplicate, log and don't add pick if (duplicate) { @@ -219,7 +221,8 @@ bool CPickList::addPick(json::Object *pick) { glassutil::log_level::warn, "CPickList::addPick: Duplicate pick not passed in."); delete (newPick); - return (false); + // message was processed + return (true); } } @@ -244,11 +247,11 @@ bool CPickList::addPick(json::Object *pick) { // get maximum number of picks // use max picks from pGlass if we have it if (pGlass) { - nPickMax = pGlass->nPickMax; + nPickMax = pGlass->getPickMax(); } // create pair for insertion - std::pair p(pck->tPick, nPick); + std::pair p(pck->getTPick(), nPick); // check to see if we're at the pick limit if (vPick.size() == nPickMax) { @@ -258,7 +261,7 @@ bool CPickList::addPick(json::Object *pick) { auto pos = mPick.find(pdx.second); // remove pick from per site pick list - pos->second->pSite->remPick(pos->second); + pos->second->getSite()->remPick(pos->second); // erase from map mPick.erase(pos); @@ -269,7 +272,7 @@ bool CPickList::addPick(json::Object *pick) { // Insert new pick in proper time sequence into pick vector // get the index of the new pick - int iPick = indexPick(pck->tPick); + int iPick = indexPick(pck->getTPick()); switch (iPick) { case -2: // Empty vector, just add it @@ -298,7 +301,7 @@ bool CPickList::addPick(json::Object *pick) { mPick[nPick] = pck; // add to site specific pick list - pck->pSite->addPick(pck); + pck->getSite()->addPick(pck); m_vPickMutex.unlock(); @@ -310,7 +313,7 @@ bool CPickList::addPick(json::Object *pick) { // wait until there's space in the queue // we don't want to build up a huge queue of unprocessed // picks - if ((pGlass) && (pGlass->pHypoList)) { + if ((pGlass) && (pGlass->getHypoList())) { while (queueSize >= (m_iNumThreads)) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); @@ -326,7 +329,7 @@ bool CPickList::addPick(json::Object *pick) { m_qProcessMutex.unlock(); } - // we're done + // we're done, message was processed return (true); } @@ -432,10 +435,10 @@ bool CPickList::checkDuplicate(CPick *newPick, double window) { bool matched = false; // get the index of the earliest possible match - int it1 = indexPick(newPick->tPick - window); + int it1 = indexPick(newPick->getTPick() - window); // get index of the latest possible pick - int it2 = indexPick(newPick->tPick + window); + int it2 = indexPick(newPick->getTPick() + window); // index can't be negative, it1/2 negative if pick before first in list if (it1 < 0) { @@ -456,19 +459,19 @@ bool CPickList::checkDuplicate(CPick *newPick, double window) { std::shared_ptr pck = mPick[q.second]; // check if time difference is within window - if (std::abs(newPick->tPick - pck->tPick) < window) { + if (std::abs(newPick->getTPick() - pck->getTPick()) < window) { // check if sites match - if (newPick->pSite->sScnl == pck->pSite->sScnl) { + if (newPick->getSite()->getScnl() == pck->getSite()->getScnl()) { // if match is found, set to true, log, and break out of loop matched = true; glassutil::CLogit::log( glassutil::log_level::warn, "CPickList::checkDuplicat: Duplicate (window = " + std::to_string(window) + ") : old:" - + pck->pSite->sScnl + " " - + std::to_string(pck->tPick) + " new(del):" - + newPick->pSite->sScnl + " " - + std::to_string(newPick->tPick)); + + pck->getSite()->getScnl() + " " + + std::to_string(pck->getTPick()) + " new(del):" + + newPick->getSite()->getScnl() + " " + + std::to_string(newPick->getTPick())); break; } } @@ -502,14 +505,14 @@ bool CPickList::scavenge(std::shared_ptr hyp, double tDuration) { char sLog[1024]; glassutil::CLogit::log(glassutil::log_level::debug, - "CPickList::scavenge. " + hyp->sPid); + "CPickList::scavenge. " + hyp->getPid()); // Calculate range for possible associations - double sdassoc = pGlass->sdAssociate; + double sdassoc = pGlass->getSdAssociate(); // get the index of the pick to start with // based on the hypo origin time - int it1 = indexPick(hyp->tOrg); + int it1 = indexPick(hyp->getTOrg()); // index can't be negative // Primarily occurs if origin time is before first pick @@ -519,7 +522,7 @@ bool CPickList::scavenge(std::shared_ptr hyp, double tDuration) { // get the index of the pick to end with by using the hypo // origin time plus the provided duration - int it2 = indexPick(hyp->tOrg + tDuration); + int it2 = indexPick(hyp->getTOrg() + tDuration); // don't bother if there's no picks if (it1 == it2) { @@ -534,7 +537,7 @@ bool CPickList::scavenge(std::shared_ptr hyp, double tDuration) { // get the pick from the vector auto q = vPick[it]; std::shared_ptr pck = mPick[q.second]; - std::shared_ptr pickHyp = pck->pHypo; + std::shared_ptr pickHyp = pck->getHypo(); // check to see if this pick is already in this hypo if (hyp->hasPick(pck)) { @@ -556,15 +559,6 @@ bool CPickList::scavenge(std::shared_ptr hyp, double tDuration) { // add pick to this hypo hyp->addPick(pck); - if (pGlass->bTrack) { - snprintf( - sLog, sizeof(sLog), "WAF %s %s %s (%d)\n", - hyp->sPid.substr(0, 4).c_str(), - glassutil::CDate::encodeDateTime(pck->tPick).c_str(), - pck->pSite->sScnl.c_str(), - static_cast(hyp->vPick.size())); - glassutil::CLogit::Out(sLog); - } // we've associated a pick bAss = true; @@ -583,7 +577,7 @@ bool CPickList::scavenge(std::shared_ptr hyp, double tDuration) { glassutil::CLogit::log( glassutil::log_level::debug, - "CPickList::scavenge " + hyp->sPid + " added:" + "CPickList::scavenge " + hyp->getPid() + " added:" + std::to_string(addCount)); // return whether we've associated at least one pick @@ -637,10 +631,10 @@ std::vector> CPickList::rogues(std::string pidHyp, // get the current pick from the vector auto q = vPick[it]; std::shared_ptr pck = mPick[q.second]; - std::shared_ptr pickHyp = pck->pHypo; + std::shared_ptr pickHyp = pck->getHypo(); // if the current pick is associated to this event - if ((pickHyp != NULL) && (pickHyp->sPid == pidHyp)) { + if ((pickHyp != NULL) && (pickHyp->getPid() == pidHyp)) { // skip to next pick continue; } @@ -669,7 +663,7 @@ void CPickList::processPick() { // on to the next loop continue; } - if (pGlass->pHypoList == NULL) { + if (pGlass->getHypoList() == NULL) { // give up some time at the end of the loop jobSleep(); @@ -710,7 +704,7 @@ void CPickList::processPick() { // Attempt both association and nucleation of the new pick. // If both succeed, the mess is sorted out in darwin/evolve // associate - pGlass->pHypoList->associate(pck); + pGlass->getHypoList()->associate(pck); // nucleate pck->nucleate(); @@ -797,4 +791,50 @@ bool CPickList::statusCheck() { // everything is awesome return (true); } + +const CSiteList* CPickList::getSiteList() const { + std::lock_guard pickListGuard(m_PickListMutex); + return (pSiteList); +} + +void CPickList::setSiteList(CSiteList* siteList) { + std::lock_guard pickListGuard(m_PickListMutex); + pSiteList = siteList; +} + +const CGlass* CPickList::getGlass() const { + std::lock_guard pickListGuard(m_PickListMutex); + return (pGlass); +} + +void CPickList::setGlass(CGlass* glass) { + std::lock_guard pickListGuard(m_PickListMutex); + pGlass = glass; +} + +int CPickList::getNPick() const { + std::lock_guard vPickGuard(m_vPickMutex); + return (nPick); +} + +int CPickList::getNPickMax() const { + std::lock_guard pickListGuard(m_PickListMutex); + return (nPickMax); +} + +void CPickList::setNPickMax(int picknMax) { + std::lock_guard pickListGuard(m_PickListMutex); + nPickMax = picknMax; +} + +int CPickList::getNPickTotal() const { + std::lock_guard vPickGuard(m_vPickMutex); + return (nPickTotal); +} + +int CPickList::getVPickSize() const { + std::lock_guard vPickGuard(m_vPickMutex); + return (vPick.size()); +} + } // namespace glasscore diff --git a/glasscore/glasslib/src/Site.cpp b/glasscore/glasslib/src/Site.cpp index 80738e2f..44eb976a 100644 --- a/glasscore/glasslib/src/Site.cpp +++ b/glasscore/glasslib/src/Site.cpp @@ -13,6 +13,7 @@ #include "Site.h" #include "Logit.h" #include "Node.h" +#include "Trigger.h" #include "Web.h" namespace glasscore { @@ -34,7 +35,7 @@ std::vector &split(const std::string &s, char delim, } std::vector split(const std::string &s, char delim) { - std::vector < std::string > elems; + std::vector elems; // split using string and delimiter split(s, delim, elems); @@ -58,20 +59,20 @@ CSite::CSite(std::string sta, std::string comp, std::string net, } // ---------------------------------------------------------CSite -CSite::CSite(json::Object *com, CGlass *glassPtr) { +CSite::CSite(std::shared_ptr site, CGlass *glassPtr) { clear(); // null check json - if (com == NULL) { + if (site == NULL) { glassutil::CLogit::log(glassutil::log_level::error, - "CSite::CSite: NULL json communication."); + "CSite::CSite: NULL json site."); return; } // check type - if (com->HasKey("Type") - && ((*com)["Type"].GetType() == json::ValueType::StringVal)) { - std::string type = (*com)["Type"].ToString(); + if (site->HasKey("Type") + && ((*site)["Type"].GetType() == json::ValueType::StringVal)) { + std::string type = (*site)["Type"].ToString(); if (type != "StationInfo") { glassutil::CLogit::log( @@ -101,9 +102,9 @@ CSite::CSite(json::Object *com, CGlass *glassPtr) { // get site information from json // scnl - if (((*com).HasKey("Site")) - && ((*com)["Site"].GetType() == json::ValueType::ObjectVal)) { - json::Object siteobj = (*com)["Site"].ToObject(); + if (((*site).HasKey("Site")) + && ((*site)["Site"].GetType() == json::ValueType::ObjectVal)) { + json::Object siteobj = (*site)["Site"].ToObject(); // station if (siteobj.HasKey("Station") @@ -113,6 +114,7 @@ CSite::CSite(json::Object *com, CGlass *glassPtr) { glassutil::CLogit::log( glassutil::log_level::error, "CSite::CSite: Missing required Station Key."); + return; } @@ -132,6 +134,7 @@ CSite::CSite(json::Object *com, CGlass *glassPtr) { glassutil::CLogit::log( glassutil::log_level::error, "CSite::CSite: Missing required Network Key."); + return; } @@ -151,62 +154,66 @@ CSite::CSite(json::Object *com, CGlass *glassPtr) { } else { glassutil::CLogit::log(glassutil::log_level::error, "CSite::CSite: Missing required Site Object."); + return; } // latitude for this site - if (((*com).HasKey("Latitude")) - && ((*com)["Latitude"].GetType() == json::ValueType::DoubleVal)) { - latitude = (*com)["Latitude"].ToDouble(); + if (((*site).HasKey("Latitude")) + && ((*site)["Latitude"].GetType() == json::ValueType::DoubleVal)) { + latitude = (*site)["Latitude"].ToDouble(); } else { glassutil::CLogit::log(glassutil::log_level::error, "CSite::CSite: Missing required Latitude Key."); + return; } // longitude for this site - if (((*com).HasKey("Longitude")) - && ((*com)["Longitude"].GetType() == json::ValueType::DoubleVal)) { - longitude = (*com)["Longitude"].ToDouble(); + if (((*site).HasKey("Longitude")) + && ((*site)["Longitude"].GetType() == json::ValueType::DoubleVal)) { + longitude = (*site)["Longitude"].ToDouble(); } else { glassutil::CLogit::log( glassutil::log_level::error, "CSite::CSite: Missing required Longitude Key."); + return; } // elevation for this site - if (((*com).HasKey("Elevation")) - && ((*com)["Elevation"].GetType() == json::ValueType::DoubleVal)) { - elevation = (*com)["Elevation"].ToDouble(); + if (((*site).HasKey("Elevation")) + && ((*site)["Elevation"].GetType() == json::ValueType::DoubleVal)) { + elevation = (*site)["Elevation"].ToDouble(); } else { glassutil::CLogit::log( glassutil::log_level::error, "CSite::CSite: Missing required Elevation Key."); + return; } // quality for this site (if present) - if (((*com).HasKey("Quality")) - && ((*com)["Quality"].GetType() == json::ValueType::DoubleVal)) { - quality = (*com)["Quality"].ToDouble(); + if (((*site).HasKey("Quality")) + && ((*site)["Quality"].GetType() == json::ValueType::DoubleVal)) { + quality = (*site)["Quality"].ToDouble(); } else { quality = 1.0; } // enable for this site (if present) - if (((*com).HasKey("Enable")) - && ((*com)["Enable"].GetType() == json::ValueType::BoolVal)) { - enable = (*com)["Enable"].ToBool(); + if (((*site).HasKey("Enable")) + && ((*site)["Enable"].GetType() == json::ValueType::BoolVal)) { + enable = (*site)["Enable"].ToBool(); } else { enable = true; } // enable for this site (if present) - if (((*com).HasKey("UseForTeleseismic")) - && ((*com)["UseForTeleseismic"].GetType() + if (((*site).HasKey("UseForTeleseismic")) + && ((*site)["UseForTeleseismic"].GetType() == json::ValueType::BoolVal)) { - useForTelesiesmic = (*com)["UseForTeleseismic"].ToBool(); + useForTelesiesmic = (*site)["UseForTeleseismic"].ToBool(); } else { useForTelesiesmic = true; } @@ -223,6 +230,8 @@ bool CSite::initialize(std::string sta, std::string comp, std::string net, CGlass *glassPtr) { clear(); + std::lock_guard guard(siteMutex); + // generate scnl sScnl = ""; @@ -274,20 +283,9 @@ bool CSite::initialize(std::string sta, std::string comp, std::string net, pGlass = glassPtr; if (pGlass) { - nSitePickMax = pGlass->nSitePickMax; + nSitePickMax = pGlass->getSitePickMax(); } - glassutil::CLogit::log( - glassutil::log_level::debug, - "CSite::initialize: sScnl:" + sScnl + "; sSite:" + sSite - + "; sComp:" + sComp + "; sNet:" + sNet + "; sLoc:" + sLoc - + "; dLat:" + std::to_string(geo.dLat) + "; dLon:" - + std::to_string(geo.dLon) + "; dZ:" - + std::to_string(geo.dZ) + "; dQual:" - + std::to_string(dQual) + "; bUse:" + std::to_string(bUse) - + "; bUseForTele:" + std::to_string(bUseForTele) - + "; nSitePickMax:" + std::to_string(nSitePickMax)); - return (true); } @@ -297,6 +295,7 @@ CSite::~CSite() { } void CSite::clear() { + std::lock_guard guard(siteMutex); // clear scnl sScnl = ""; sSite = ""; @@ -307,11 +306,8 @@ void CSite::clear() { bUse = true; bUseForTele = true; dQual = 1.0; - dTrav = 0.0; pGlass = NULL; - pNode = NULL; - qNode = NULL; // clear geographic geo = glassutil::CGeo(); @@ -324,19 +320,20 @@ void CSite::clear() { vNode.clear(); vNodeMutex.unlock(); - vPickMutex.lock(); - vPick.clear(); - vPickMutex.unlock(); - - vTriggerMutex.lock(); - vTrigger.clear(); - vTriggerMutex.unlock(); + clearVPick(); // reset max picks nSitePickMax = 200; } +void CSite::clearVPick() { + vPickMutex.lock(); + vPick.clear(); + vPickMutex.unlock(); +} + void CSite::update(CSite *site) { + std::lock_guard guard(siteMutex); // scnl check if (sScnl != site->sScnl) { return; @@ -358,6 +355,7 @@ void CSite::update(CSite *site) { // ---------------------------------------------------------setLocation void CSite::setLocation(double lat, double lon, double z) { + std::lock_guard guard(siteMutex); // construct unit vector in cartesian earth coordinates double rxy = cos(DEG2RAD * lat); dVec[0] = rxy * cos(DEG2RAD * lon); @@ -406,7 +404,7 @@ double CSite::getDistance(std::shared_ptr site) { // ---------------------------------------------------------addPick void CSite::addPick(std::shared_ptr pck) { // lock for editing - std::lock_guard < std::mutex > guard(vPickMutex); + std::lock_guard guard(vPickMutex); // nullcheck if (pck == NULL) { @@ -416,11 +414,11 @@ void CSite::addPick(std::shared_ptr pck) { } // ensure this pick is for this site - if (pck->pSite->sScnl != sScnl) { + if (pck->getSite()->sScnl != sScnl) { glassutil::CLogit::log( glassutil::log_level::warn, "CSite::addPick: CPick for different site: (" + sScnl + "!=" - + pck->pSite->sScnl + ")"); + + pck->getSite()->sScnl + ")"); return; } @@ -432,13 +430,14 @@ void CSite::addPick(std::shared_ptr pck) { // add pick to site pick vector // NOTE: Need to add duplicate pick protection - vPick.push_back(pck); + std::weak_ptr wpPck = pck; + vPick.push_back(wpPck); } // ---------------------------------------------------------remPick void CSite::remPick(std::shared_ptr pck) { // lock for editing - std::lock_guard < std::mutex > guard(vPickMutex); + std::lock_guard guard(vPickMutex); // nullcheck if (pck == NULL) { @@ -448,9 +447,20 @@ void CSite::remPick(std::shared_ptr pck) { } // remove pick from site pick vector - auto it = std::find(vPick.begin(), vPick.end(), pck); - if (it != vPick.end()) { - vPick.erase(it); + for (auto it = vPick.begin(); it != vPick.end();) { + if ((*it).expired() == true) { + // clean up expired pointers + it = vPick.erase(it); + } else if (auto aPck = (*it).lock()) { + // erase target pick + if (aPck->getPid() == pck->getPid()) { + it = vPick.erase(it); + } else { + ++it; + } + } else { + ++it; + } } } @@ -458,7 +468,7 @@ void CSite::remPick(std::shared_ptr pck) { void CSite::addNode(std::shared_ptr node, double travelTime1, double travelTime2) { // lock for editing - std::lock_guard < std::mutex > guard(vNodeMutex); + std::lock_guard guard(vNodeMutex); // nullcheck if (node == NULL) { @@ -485,7 +495,7 @@ void CSite::addNode(std::shared_ptr node, double travelTime1, // ---------------------------------------------------------remNode void CSite::remNode(std::string nodeID) { // lock for editing - std::lock_guard < std::mutex > guard(vNodeMutex); + std::lock_guard guard(vNodeMutex); // nullcheck if (nodeID == "") { @@ -494,55 +504,56 @@ void CSite::remNode(std::string nodeID) { return; } - NodeLink nodeLinkToDelete; - - // remove the node identified by the id - for (const auto &link : vNode) { - // third is shared pointer to node - std::shared_ptr aNode = std::get < LINK_PTR > (link); - - // nullcheck - if (aNode == NULL) { - continue; - } - - // check to see if we have a match - if (aNode->sPid == nodeID) { - // remember which one to delete - nodeLinkToDelete = link; - - // we're done - break; + // clean up expired pointers + for (auto it = vNode.begin(); it != vNode.end();) { + if (std::get(*it).expired() == true) { + it = vNode.erase(it); + } else { + ++it; } } - // remove link from vector - auto it = std::find(vNode.begin(), vNode.end(), nodeLinkToDelete); - if (it != vNode.end()) { - vNode.erase(it); + for (auto it = vNode.begin(); it != vNode.end();) { + if (auto aNode = std::get(*it).lock()) { + // erase target pick + if (aNode->getPid() == nodeID) { + it = vNode.erase(it); + return; + } else { + ++it; + } + } else { + ++it; + } } } // ---------------------------------------------------------Nucleate -void CSite::nucleate(double tPick) { - std::lock_guard < std::mutex > guard(vNodeMutex); +std::vector> CSite::nucleate(double tPick) { + std::lock_guard guard(vNodeMutex); - // clear any previous triggering nodes - vTriggerMutex.lock(); - vTrigger.clear(); - vTriggerMutex.unlock(); + // create trigger vector + std::vector> vTrigger; // for each node linked to this site for (const auto &link : vNode) { // compute potential origin time from tpick and traveltime to node // first get traveltime1 to node - double travelTime1 = std::get < LINK_TT1 > (link); + double travelTime1 = std::get< LINK_TT1>(link); // second get traveltime2 to node - double travelTime2 = std::get < LINK_TT2 > (link); + double travelTime2 = std::get< LINK_TT2>(link); // third get shared pointer to node - std::shared_ptr node = std::get < LINK_PTR > (link); + std::shared_ptr node = std::get(link).lock(); + + if (node == NULL) { + continue; + } + + if (node->getEnabled() == false) { + continue; + } // compute first origin time double tOrigin1 = -1; @@ -558,70 +569,155 @@ void CSite::nucleate(double tPick) { // attempt to nucleate an event located // at the current node with the potential origin times + bool primarySuccessful = false; if (tOrigin1 > 0) { - if (node->nucleate(tOrigin1)) { + std::shared_ptr trigger1 = node->nucleate(tOrigin1); + + if (trigger1 != NULL) { // if node triggered, add to triggered vector - addTrigger(node); + addTrigger(&vTrigger, trigger1); + primarySuccessful = true; } - } else if (tOrigin2 > 0) { - if (node->nucleate(tOrigin2)) { + } + + // only attempt secondary phase nucleation if primary nucleation + // was unsuccessful + if ((primarySuccessful == false) && (tOrigin2 > 0)) { + std::shared_ptr trigger2 = node->nucleate(tOrigin2); + + if (trigger2 != NULL) { // if node triggered, add to triggered vector - addTrigger(node); + addTrigger(&vTrigger, trigger2); } - } else { + } + + if ((tOrigin1 < 0) && (tOrigin2 < 0)) { glassutil::CLogit::log( glassutil::log_level::warn, "CSite::nucleate: " + sScnl + " No valid travel times. (" + std::to_string(travelTime1) + ", " + std::to_string(travelTime2) + ") web: " - + node->pWeb->sName); + + node->getWeb()->getName()); } } + + return (vTrigger); } // ---------------------------------------------------------addTrigger -void CSite::addTrigger(std::shared_ptr node) { - std::lock_guard < std::mutex > guard(vTriggerMutex); - - // for each known triggering node - for (int iq = 0; iq < vTrigger.size(); iq++) { - // get current triggered node - auto q = vTrigger[iq]; - - // if current triggered node is part of latest node's web - if (node->pWeb->sName == q->pWeb->sName) { - // if latest node's sum is greater than current triggered node's - // sum, replace it - - // glassutil::CLogit::log( - // glassutil::log_level::debug, - // "CSite::addTrigger Node 1:" - // + std::to_string(node->dLat) + ", " - // + std::to_string(node->dLon) + ", " - // + std::to_string(node->dZ) + ", " - // + std::to_string(node->dSum) + ", Node 2:" - // + std::to_string(q->dLat) + ", " - // + std::to_string(q->dLon) + ", " - // + std::to_string(q->dZ) + ", " - // + std::to_string(q->dSum)); - - if (node->dSum > q->dSum) { - vTrigger[iq] = node; +void CSite::addTrigger(std::vector> *vTrigger, + std::shared_ptr trigger) { + if (trigger == NULL) { + return; + } + if (trigger->getWeb() == NULL) { + return; + } + + // clean up expired pointers + for (auto it = vTrigger->begin(); it != vTrigger->end();) { + std::shared_ptr aTrigger = (*it); + + // if current trigger is part of latest trigger's web + if (trigger->getWeb()->getName() == aTrigger->getWeb()->getName()) { + // if current trigger's sum is less than latest trigger's sum + if (trigger->getSum() > aTrigger->getSum()) { + it = vTrigger->erase(it); + it = vTrigger->insert(it, trigger); } // we're done return; + } else { + ++it; } } // add triggering node to vector of triggered nodes - vTrigger.push_back(node); + vTrigger->push_back(trigger); } -int CSite::getNodeLinksCount() { - std::lock_guard < std::mutex > guard(vNodeMutex); +int CSite::getNodeLinksCount() const { + std::lock_guard guard(vNodeMutex); int size = vNode.size(); return (size); } + +bool CSite::getUse() const { + std::lock_guard guard(siteMutex); + return (bUse); +} + +void CSite::setUse(bool use) { + std::lock_guard guard(siteMutex); + bUse = use; +} + +bool CSite::getUseForTele() const { + std::lock_guard guard(siteMutex); + return (bUseForTele); +} + +void CSite::setUseForTele(bool useForTele) { + std::lock_guard guard(siteMutex); + bUseForTele = useForTele; +} + +double CSite::getQual() const { + std::lock_guard guard(siteMutex); + return (dQual); +} + +void CSite::setQual(double qual) { + std::lock_guard guard(siteMutex); + dQual = qual; +} + +glassutil::CGeo& CSite::getGeo() { + return (geo); +} + +int CSite::getSitePickMax() const { + return (nSitePickMax); +} + +CGlass* CSite::getGlass() const { + return (pGlass); +} + +const std::string& CSite::getComp() const { + return (sComp); +} + +const std::string& CSite::getLoc() const { + return (sLoc); +} + +const std::string& CSite::getNet() const { + return (sNet); +} + +const std::string& CSite::getScnl() const { + return (sScnl); +} + +const std::string& CSite::getSite() const { + return (sSite); +} + +const std::vector > CSite::getVPick() const { + std::lock_guard guard(vPickMutex); + + std::vector> picks; + for (auto awpPck : vPick) { + std::shared_ptr aPck = awpPck.lock(); + + if (aPck != NULL) { + picks.push_back(aPck); + } + } + + return (picks); +} } // namespace glasscore diff --git a/glasscore/glasslib/src/SiteList.cpp b/glasscore/glasslib/src/SiteList.cpp index bf171ac1..ae0a7032 100644 --- a/glasscore/glasslib/src/SiteList.cpp +++ b/glasscore/glasslib/src/SiteList.cpp @@ -25,6 +25,7 @@ CSiteList::~CSiteList() { // ---------------------------------------------------------clear void CSiteList::clear() { + std::lock_guard siteListGuard(m_SiteListMutex); pGlass = NULL; // clear sites @@ -36,7 +37,7 @@ void CSiteList::clearSites() { std::lock_guard guard(vSiteMutex); // remove all picks from sites for (auto site : vSite) { - site->vPick.clear(); + site->clearVPick(); } // clear the vector and map @@ -45,7 +46,7 @@ void CSiteList::clearSites() { } // ---------------------------------------------------------dispatch -bool CSiteList::dispatch(json::Object *com) { +bool CSiteList::dispatch(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log( @@ -97,7 +98,7 @@ bool CSiteList::dispatch(json::Object *com) { } // ---------------------------------------------------------addSite -bool CSiteList::addSite(json::Object *com) { +bool CSiteList::addSite(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log(glassutil::log_level::error, @@ -126,7 +127,7 @@ bool CSiteList::addSite(json::Object *com) { CSite * site = new CSite(com, pGlass); // make sure a site was actually created - if (site->sScnl == "") { + if (site->getScnl() == "") { glassutil::CLogit::log(glassutil::log_level::warn, "CSiteList::addSite: Site not created."); delete (site); @@ -140,7 +141,7 @@ bool CSiteList::addSite(json::Object *com) { } // ---------------------------------------------------------addSiteList -bool CSiteList::addSiteList(json::Object *com) { +bool CSiteList::addSiteList(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log( @@ -175,13 +176,14 @@ bool CSiteList::addSiteList(json::Object *com) { for (auto v : stationList) { if (v.GetType() == json::ValueType::ObjectVal) { // convert object to json pointer - json::Object siteObj = v.ToObject(); + std::shared_ptr siteObj = std::make_shared< + json::Object>(v.ToObject()); // create a new a site from the station json; - CSite * site = new CSite(&siteObj, pGlass); + CSite * site = new CSite(siteObj, pGlass); // make sure a site was actually created - if (site->sScnl == "") { + if (site->getScnl() == "") { glassutil::CLogit::log( glassutil::log_level::warn, "CSiteList::addSiteList: Site not created."); @@ -216,7 +218,7 @@ bool CSiteList::addSite(std::shared_ptr site) { } // check to see if we have an existing site - std::shared_ptr oldSite = getSite(site->sScnl); + std::shared_ptr oldSite = getSite(site->getScnl()); std::lock_guard guard(vSiteMutex); @@ -227,19 +229,19 @@ bool CSiteList::addSite(std::shared_ptr site) { // pass updated site to webs if (pGlass) { - if (pGlass->pWebList) { - pGlass->pWebList->addSite(oldSite); + if (pGlass->getWebList()) { + pGlass->getWebList()->addSite(oldSite); } } } else { // add new site to list and map vSite.push_back(site); - mSite[site->sScnl] = site; + mSite[site->getScnl()] = site; // pass new site to webs if (pGlass) { - if (pGlass->pWebList) { - pGlass->pWebList->addSite(site); + if (pGlass->getWebList()) { + pGlass->getWebList()->addSite(site); } } } @@ -343,23 +345,22 @@ std::shared_ptr CSiteList::getSite(std::string site, std::string comp, if (lookup) { if (pGlass) { // construct request json message - json::Object obj; - obj["Type"] = "SiteLookup"; - obj["Site"] = site; - obj["Comp"] = comp; - obj["Net"] = net; - obj["Loc"] = loc; + std::shared_ptr request = std::make_shared< + json::Object>(json::Object()); + (*request)["Type"] = "SiteLookup"; + (*request)["Site"] = site; + (*request)["Comp"] = comp; + (*request)["Net"] = net; + (*request)["Loc"] = loc; // send request - pGlass->send(&obj); + pGlass->send(request); char sLog[1024]; - snprintf( - sLog, - sizeof(sLog), - "CSiteList::getSite: SCNL:%s not on station list, " - "requesting information.", - scnl.c_str()); + snprintf(sLog, sizeof(sLog), + "CSiteList::getSite: SCNL:%s not on station list, " + "requesting information.", + scnl.c_str()); glassutil::CLogit::log(sLog); } } @@ -370,8 +371,9 @@ std::shared_ptr CSiteList::getSite(std::string site, std::string comp, // ---------------------------------------------------------getSiteList bool CSiteList::reqSiteList() { // construct request json message - json::Object sitelistObj; - sitelistObj["Cmd"] = "SiteList"; + std::shared_ptr sitelistObj = std::make_shared( + json::Object()); + (*sitelistObj)["Cmd"] = "SiteList"; // array to hold data json::Array stationList; @@ -386,7 +388,7 @@ bool CSiteList::reqSiteList() { double z; // convert to geographic coordinates - site->geo.getGeographic(&lat, &lon, &z); + site->getGeo().getGeographic(&lat, &lon, &z); // convert from earth radius to elevation double elv = (z - 6317.0) * -1000.0; @@ -395,29 +397,45 @@ bool CSiteList::reqSiteList() { stationObj["Lat"] = lat; stationObj["Lon"] = lon; stationObj["Z"] = elv; - stationObj["Qual"] = site->dQual; - stationObj["Use"] = site->bUse; - stationObj["UseForTele"] = site->bUseForTele; + stationObj["Qual"] = site->getQual(); + stationObj["Use"] = site->getUse(); + stationObj["UseForTele"] = site->getUseForTele(); - stationObj["Sta"] = site->sSite; - if (site->sComp != "") { - stationObj["Comp"] = site->sComp; + stationObj["Sta"] = site->getSite(); + if (site->getComp() != "") { + stationObj["Comp"] = site->getComp(); } - stationObj["Net"] = site->sNet; - if (site->sLoc != "") { - stationObj["Loc"] = site->sLoc; + stationObj["Net"] = site->getNet(); + if (site->getLoc() != "") { + stationObj["Loc"] = site->getLoc(); } // add to station list stationList.push_back(stationObj); } - sitelistObj["SiteList"] = stationList; + (*sitelistObj)["SiteList"] = stationList; if (pGlass) { - pGlass->send(&sitelistObj); + pGlass->send(sitelistObj); } return (true); } + +const CGlass* CSiteList::getGlass() const { + std::lock_guard siteListGuard(m_SiteListMutex); + return (pGlass); +} + +void CSiteList::setGlass(CGlass* glass) { + std::lock_guard siteListGuard(m_SiteListMutex); + pGlass = glass; +} + +int CSiteList::getVSiteSize() const { + std::lock_guard vSiteGuard(vSiteMutex); + return (vSite.size()); +} + } // namespace glasscore diff --git a/glasscore/glasslib/src/Trigger.cpp b/glasscore/glasslib/src/Trigger.cpp new file mode 100644 index 00000000..cb4ffdbd --- /dev/null +++ b/glasscore/glasslib/src/Trigger.cpp @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include +#include +#include "Trigger.h" +#include "Pick.h" +#include "Logit.h" + +namespace glasscore { + +// ---------------------------------------------------------CTrigger +CTrigger::CTrigger() { + clear(); +} + +// ---------------------------------------------------------CNode +CTrigger::CTrigger(double lat, double lon, double z, double ot, + double resolution, double sum, int count, + std::vector> picks, CWeb *web) { + if (!initialize(lat, lon, z, ot, resolution, sum, count, picks, web)) { + clear(); + } +} + +// ---------------------------------------------------------~CTrigger +CTrigger::~CTrigger() { + clear(); +} + +// ---------------------------------------------------------clear +void CTrigger::clear() { + std::lock_guard guard(triggerMutex); + + dLat = 0; + dLon = 0; + dZ = 0; + tOrg = 0; + dResolution = 0; + dSum = 0; + nCount = 0; + pWeb = NULL; + + vPick.clear(); +} + +bool CTrigger::initialize(double lat, double lon, double z, double ot, + double resolution, double sum, int count, + std::vector> picks, + CWeb *web) { + clear(); + + std::lock_guard guard(triggerMutex); + + dLat = lat; + dLon = lon; + dZ = z; + tOrg = ot; + dResolution = resolution; + dSum = sum; + nCount = count; + pWeb = web; + + for (auto aPick : picks) { + vPick.push_back(aPick); + } + +/* glassutil::CLogit::log( + glassutil::log_level::debug, + "CTrigger::initialize: dLat:" + std::to_string(dLat) + "; dLon:" + + std::to_string(dLon) + "; dZ:" + std::to_string(dZ) + + "; tOrg:" + std::to_string(tOrg) + "; dResolution:" + + std::to_string(dResolution) + "; dSum:" + + std::to_string(dSum) + "; nCount:" + + std::to_string(nCount) + "; vPick Size:" + + std::to_string(vPick.size()));*/ + + return (true); +} + +double CTrigger::getLat() const { + return (dLat); +} + +double CTrigger::getLon() const { + return (dLon); +} + +double CTrigger::getZ() const { + return (dZ); +} + +double CTrigger::getTOrg() const { + return (tOrg); +} + +double CTrigger::getResolution() const { + return (dResolution); +} + +double CTrigger::getSum() const { + return (dSum); +} + +int CTrigger::getCount() const { + return (nCount); +} + +const CWeb* CTrigger::getWeb() const { + return (pWeb); +} + +const std::vector > CTrigger::getVPick() const { + std::lock_guard guard(triggerMutex); + return (vPick); +} + +} // namespace glasscore diff --git a/glasscore/glasslib/src/Web.cpp b/glasscore/glasslib/src/Web.cpp index f61ca3db..095c14a3 100644 --- a/glasscore/glasslib/src/Web.cpp +++ b/glasscore/glasslib/src/Web.cpp @@ -94,6 +94,7 @@ CWeb::CWeb(std::string name, double thresh, int numDetect, int numNucleate, // ---------------------------------------------------------~CWeb CWeb::~CWeb() { glassutil::CLogit::log("CWeb::~CWeb"); + std::lock_guard webGuard(m_WebMutex); clear(); @@ -112,6 +113,7 @@ CWeb::~CWeb() { // ---------------------------------------------------------clear void CWeb::clear() { + std::lock_guard webGuard(m_WebMutex); nRow = 0; nCol = 0; nZ = 0; @@ -125,17 +127,35 @@ void CWeb::clear() { bUpdate = false; // clear out all the nodes in the web - for (auto &node : vNode) { - node->clear(); + try { + m_vNodeMutex.lock(); + for (auto &node : vNode) { + node->clear(); + } + vNode.clear(); + } catch (...) { + // ensure the vNode mutex is unlocked + m_vNodeMutex.unlock(); + + throw; } - vNode.clear(); + m_vNodeMutex.unlock(); // clear the network and site filters vNetFilter.clear(); vSitesFilter.clear(); // clear sites - vSite.clear(); + try { + vSiteMutex.lock(); + vSite.clear(); + } catch (...) { + // ensure the vSite mutex is unlocked + vSiteMutex.unlock(); + + throw; + } + vSiteMutex.unlock(); pTrv1 = NULL; pTrv2 = NULL; @@ -147,6 +167,8 @@ bool CWeb::initialize(std::string name, double thresh, int numDetect, int numCols, int numZ, bool update, std::shared_ptr firstTrav, std::shared_ptr secondTrav) { + std::lock_guard webGuard(m_WebMutex); + sName = name; dThresh = thresh; nDetect = numDetect; @@ -164,7 +186,7 @@ bool CWeb::initialize(std::string name, double thresh, int numDetect, } // ---------------------------------------------------------Dispatch -bool CWeb::dispatch(json::Object *com) { +bool CWeb::dispatch(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log(glassutil::log_level::error, @@ -199,7 +221,7 @@ bool CWeb::dispatch(json::Object *com) { } // ---------------------------------------------------------Global -bool CWeb::global(json::Object*com) { +bool CWeb::global(std::shared_ptr com) { glassutil::CLogit::log(glassutil::log_level::debug, "CWeb::global"); // nullchecks @@ -220,9 +242,9 @@ bool CWeb::global(json::Object*com) { // check pGlass if (pGlass != NULL) { - detect = pGlass->nDetect; - nucleate = pGlass->nNucleate; - thresh = pGlass->dThresh; + detect = pGlass->getDetect(); + nucleate = pGlass->getNucleate(); + thresh = pGlass->getThresh(); } double resol = 100; @@ -402,7 +424,7 @@ bool CWeb::global(json::Object*com) { // write node to grid file if (saveGrid) { - outfile << sName << "," << node->sPid << "," + outfile << sName << "," << node->getPid() << "," << std::to_string(aLat) << "," << std::to_string(aLon) << "," << std::to_string(z) << "\n"; @@ -444,7 +466,7 @@ bool CWeb::global(json::Object*com) { } // ---------------------------------------------------------Grid -bool CWeb::grid(json::Object *com) { +bool CWeb::grid(std::shared_ptr com) { glassutil::CLogit::log(glassutil::log_level::debug, "CWeb::grid"); // nullchecks // check json @@ -464,9 +486,9 @@ bool CWeb::grid(json::Object *com) { // check pGlass if (pGlass != NULL) { - detect = pGlass->nDetect; - nucleate = pGlass->nNucleate; - thresh = pGlass->dThresh; + detect = pGlass->getDetect(); + nucleate = pGlass->getNucleate(); + thresh = pGlass->getThresh(); } double resol = 0; @@ -699,7 +721,7 @@ bool CWeb::grid(json::Object *com) { // write node to grid file if (saveGrid) { - outfile << sName << "," << node->sPid << "," + outfile << sName << "," << node->getPid() << "," << std::to_string(latrow) << "," << std::to_string(loncol) << "," << std::to_string(z) << "\n"; @@ -744,7 +766,7 @@ bool CWeb::grid(json::Object *com) { } // ---------------------------------------------Grid w/ explicit nodes -bool CWeb::grid_explicit(json::Object *com) { +bool CWeb::grid_explicit(std::shared_ptr com) { glassutil::CLogit::log(glassutil::log_level::debug, "CWeb::grid_explicit"); // nullchecks @@ -766,9 +788,9 @@ bool CWeb::grid_explicit(json::Object *com) { // check pGlass if (pGlass != NULL) { - detect = pGlass->nDetect; - nucleate = pGlass->nNucleate; - thresh = pGlass->dThresh; + detect = pGlass->getDetect(); + nucleate = pGlass->getNucleate(); + thresh = pGlass->getThresh(); } int nN = 0; @@ -992,8 +1014,8 @@ bool CWeb::loadTravelTimes(json::Object *com) { pTrv1.reset(); // use overall glass default if available - if ((pGlass != NULL) && (pGlass->pTrvDefault != NULL)) { - pTrv1 = pGlass->pTrvDefault; + if ((pGlass != NULL) && (pGlass->getTrvDefault() != NULL)) { + pTrv1 = pGlass->getTrvDefault(); } else { // create new traveltime pTrv1 = std::make_shared(); @@ -1047,11 +1069,10 @@ bool CWeb::loadTravelTimes(json::Object *com) { // set up the first phase travel time if (pTrv1->setup(phs, file) == false) { glassutil::CLogit::log( - glassutil::log_level::error, - "CWeb::loadTravelTimes: Failed to load file " - "location " + file + " for first phase: " - + phs); - return(false); + glassutil::log_level::error, + "CWeb::loadTravelTimes: Failed to load file " + "location " + file + " for first phase: " + phs); + return (false); } } else { @@ -1059,8 +1080,8 @@ bool CWeb::loadTravelTimes(json::Object *com) { pTrv1.reset(); // use overall glass default if available - if (pGlass->pTrvDefault != NULL) { - pTrv1 = pGlass->pTrvDefault; + if (pGlass->getTrvDefault() != NULL) { + pTrv1 = pGlass->getTrvDefault(); } else { // create new traveltime pTrv1 = std::make_shared(); @@ -1112,11 +1133,10 @@ bool CWeb::loadTravelTimes(json::Object *com) { // set up the second phase travel time if (pTrv2->setup(phs, file) == false) { glassutil::CLogit::log( - glassutil::log_level::error, - "CWeb::loadTravelTimes: Failed to load file " - "location " + file + " for second phase: " - + phs); - return(false); + glassutil::log_level::error, + "CWeb::loadTravelTimes: Failed to load file " + "location " + file + " for second phase: " + phs); + return (false); } } else { // no second phase @@ -1132,7 +1152,7 @@ bool CWeb::loadTravelTimes(json::Object *com) { } // ---------------------------------------------------------genSiteFilters -bool CWeb::genSiteFilters(json::Object *com) { +bool CWeb::genSiteFilters(std::shared_ptr com) { // nullchecks // check json if (com == NULL) { @@ -1141,6 +1161,8 @@ bool CWeb::genSiteFilters(json::Object *com) { return (false); } + std::lock_guard webGuard(m_WebMutex); + // Get the network names to be included in this web. if ((*com).HasKey("Nets") && ((*com)["Nets"].GetType() == json::ValueType::ArrayVal)) { @@ -1216,14 +1238,14 @@ bool CWeb::isSiteAllowed(std::shared_ptr site) { // if we have a network filter, make sure network is allowed before adding if ((vNetFilter.size() > 0) - && (find(vNetFilter.begin(), vNetFilter.end(), site->sNet) + && (find(vNetFilter.begin(), vNetFilter.end(), site->getNet()) != vNetFilter.end())) { return (true); } // if we have a site filter, make sure site is allowed before adding if ((vSitesFilter.size() > 0) - && (find(vSitesFilter.begin(), vSitesFilter.end(), site->sScnl) + && (find(vSitesFilter.begin(), vSitesFilter.end(), site->getScnl()) != vSitesFilter.end())) { return (true); } @@ -1266,7 +1288,7 @@ bool CWeb::genSiteList() { // get site from the overall site list std::shared_ptr site = pSiteList->getSite(isite); - if (site->bUse == false) { + if (site->getUse() == false) { continue; } @@ -1325,7 +1347,7 @@ std::shared_ptr CWeb::genNode(double lat, double lon, double z, new CNode(sName, lat, lon, z, resol, glassutil::CPid::pid())); // set parent web - node->pWeb = this; + node->setWeb(this); // return empty node if we don't // have any sites @@ -1346,6 +1368,7 @@ bool CWeb::addNode(std::shared_ptr node) { if (node == NULL) { return (false); } + std::lock_guard vNodeGuard(m_vNodeMutex); vNode.push_back(node); @@ -1368,29 +1391,38 @@ std::shared_ptr CWeb::genNodeSites(std::shared_ptr node) { } // check sites if (vSite.size() == 0) { + glassutil::CLogit::log(glassutil::log_level::error, + "CWeb::genNodeSites: No sites."); return (node); } // check nDetect if (nDetect == 0) { + glassutil::CLogit::log(glassutil::log_level::error, + "CWeb::genNodeSites: nDetect is 0."); return (node); } + + int sitesAllowed = nDetect; if (vSite.size() < nDetect) { - return (node); + glassutil::CLogit::log(glassutil::log_level::warn, + "CWeb::genNodeSites: nDetect is greater " + "than the number of sites."); + sitesAllowed = vSite.size(); } // setup traveltimes for this node if (pTrv1 != NULL) { - pTrv1->setOrigin(node->dLat, node->dLon, node->dZ); + pTrv1->setOrigin(node->getLat(), node->getLon(), node->getZ()); } if (pTrv2 != NULL) { - pTrv2->setOrigin(node->dLat, node->dLon, node->dZ); + pTrv2->setOrigin(node->getLat(), node->getLon(), node->getZ()); } // clear node of any existing sites node->clearSiteLinks(); // for the number of allowed sites per node - for (int i = 0; i < nDetect; i++) { + for (int i = 0; i < sitesAllowed; i++) { // get each site auto aSite = vSite[i]; std::shared_ptr site = aSite.second; @@ -1409,6 +1441,11 @@ std::shared_ptr CWeb::genNodeSites(std::shared_ptr node) { travelTime2 = pTrv2->T(delta); } + // skip site if there are no valid times + if ((travelTime1 < 0) && (travelTime2 < 0)) { + continue; + } + // Link node to site using traveltimes node->linkSite(site, node, travelTime1, travelTime2); } @@ -1427,25 +1464,27 @@ void CWeb::addSite(std::shared_ptr site) { } // if this is a remove, send to remSite - if (site->bUse == false) { + if (site->getUse() == false) { remSite(site); return; } glassutil::CLogit::log( glassutil::log_level::debug, - "CWeb::addSite: New potential station " + site->sScnl + " for web: " - + sName + "."); + "CWeb::addSite: New potential station " + site->getScnl() + + " for web: " + sName + "."); // don't bother if this site isn't allowed if (isSiteAllowed(site) == false) { glassutil::CLogit::log( glassutil::log_level::debug, - "CWeb::addSite: Station " + site->sScnl + " not allowed in web " - + sName + "."); + "CWeb::addSite: Station " + site->getScnl() + + " not allowed in web " + sName + "."); return; } + std::lock_guard vNodeGuard(m_vNodeMutex); + int nodeModCount = 0; int nodeCount = 0; int totalNodes = vNode.size(); @@ -1454,10 +1493,12 @@ void CWeb::addSite(std::shared_ptr site) { for (auto &node : vNode) { nodeCount++; + node->setEnabled(false); + if (nodeCount % 1000 == 0) { glassutil::CLogit::log( glassutil::log_level::debug, - "CWeb::addSite: Station " + site->sScnl + " processed " + "CWeb::addSite: Station " + site->getScnl() + " processed " + std::to_string(nodeCount) + " out of " + std::to_string(totalNodes) + " nodes in web: " + sName + ". Modified " @@ -1465,22 +1506,23 @@ void CWeb::addSite(std::shared_ptr site) { } // check to see if we have this site - std::shared_ptr foundSite = node->getSite(site->sScnl); + std::shared_ptr foundSite = node->getSite(site->getScnl()); // update? if (foundSite != NULL) { // NOTE: what to do here?! anything? only would // matter if the site location changed or (future) quality changed + node->setEnabled(true); continue; } // set to node geographic location // NOTE: node depth is ignored here glassutil::CGeo geo; - geo.setGeographic(node->dLat, node->dLon, 6371.0); + geo.setGeographic(node->getLat(), node->getLon(), 6371.0); // compute delta distance between site and node - double newDistance = RAD2DEG * site->geo.delta(&geo); + double newDistance = RAD2DEG * site->getGeo().delta(&geo); // get site in node list // NOTE: this assumes that the node site list is sorted @@ -1488,20 +1530,21 @@ void CWeb::addSite(std::shared_ptr site) { std::shared_ptr furthestSite = node->getLastSite(); // compute distance to farthest site - double maxDistance = RAD2DEG * geo.delta(&furthestSite->geo); + double maxDistance = RAD2DEG * geo.delta(&furthestSite->getGeo()); // Ignore if new site is farther than last linked site - if (newDistance > maxDistance) { - node->bEnabled = true; + if ((node->getSiteLinksCount() >= nDetect) + && (newDistance > maxDistance)) { + node->setEnabled(true); continue; } // setup traveltimes for this node if (pTrv1 != NULL) { - pTrv1->setOrigin(node->dLat, node->dLon, node->dZ); + pTrv1->setOrigin(node->getLat(), node->getLon(), node->getZ()); } if (pTrv2 != NULL) { - pTrv2->setOrigin(node->dLat, node->dLon, node->dZ); + pTrv2->setOrigin(node->getLat(), node->getLon(), node->getZ()); } // compute traveltimes between site and node @@ -1514,13 +1557,20 @@ void CWeb::addSite(std::shared_ptr site) { travelTime2 = pTrv2->T(newDistance); } - // remove last site - // This assumes that the node site list is sorted - // on distance/traveltime - node->unlinkLastSite(); + // check to see if we're at the limit + if (node->getSiteLinksCount() < nDetect) { + // Link node to site using traveltimes + node->linkSite(site, node, travelTime1, travelTime2); - // Link node to site using traveltimes - node->linkSite(site, node, travelTime1, travelTime2); + } else { + // remove last site + // This assumes that the node site list is sorted + // on distance/traveltime + node->unlinkLastSite(); + + // Link node to site using traveltimes + node->linkSite(site, node, travelTime1, travelTime2); + } // resort site links node->sortSiteLinks(); @@ -1528,6 +1578,8 @@ void CWeb::addSite(std::shared_ptr site) { // we've added a site nodeModCount++; + node->setEnabled(true); + // update thread status setStatus(true); } @@ -1537,13 +1589,14 @@ void CWeb::addSite(std::shared_ptr site) { char sLog[1024]; snprintf(sLog, sizeof(sLog), "CWeb::addSite: Added site: %s to %d " "node(s) in web: %s", - site->sScnl.c_str(), nodeModCount, sName.c_str()); + site->getScnl().c_str(), nodeModCount, sName.c_str()); glassutil::CLogit::log(glassutil::log_level::info, sLog); } else { glassutil::CLogit::log( glassutil::log_level::debug, - "CWeb::addSite: Station " + site->sScnl + " not added to any " - "nodes in web: " + sName + "."); + "CWeb::addSite: Station " + site->getScnl() + + " not added to any " + "nodes in web: " + sName + "."); } } @@ -1558,14 +1611,14 @@ void CWeb::remSite(std::shared_ptr site) { if (isSiteAllowed(site) == false) { glassutil::CLogit::log( glassutil::log_level::debug, - "CWeb::remSite: Station " + site->sScnl + " not allowed in web " - + sName + "."); + "CWeb::remSite: Station " + site->getScnl() + + " not allowed in web " + sName + "."); return; } glassutil::CLogit::log( glassutil::log_level::debug, - "CWeb::remSite: Trying to remove station " + site->sScnl + "CWeb::remSite: Trying to remove station " + site->getScnl() + " from web " + sName + "."); // init flag to check to see if we've generated a site list for this web @@ -1573,16 +1626,19 @@ void CWeb::remSite(std::shared_ptr site) { bool bSiteList = false; int nodeCount = 0; + std::lock_guard vNodeGuard(m_vNodeMutex); + // for each node in web for (auto &node : vNode) { // search through each site linked to this node, see if we have it - std::shared_ptr foundSite = node->getSite(site->sScnl); + std::shared_ptr foundSite = node->getSite(site->getScnl()); // don't bother if this node doesn't have this site if (foundSite == NULL) { continue; } + node->setEnabled(false); std::lock_guard guard(vSiteMutex); // generate the site list for this web if this is the first @@ -1594,13 +1650,13 @@ void CWeb::remSite(std::shared_ptr site) { // make sure we've got enough sites for a node if (vSite.size() < nDetect) { - node->bEnabled = true; + node->setEnabled(true); return; } } // sort overall list of sites for this node - sortSiteList(node->dLat, node->dLon); + sortSiteList(node->getLat(), node->getLon()); // remove site link if (node->unlinkSite(foundSite) == true) { @@ -1626,8 +1682,9 @@ void CWeb::remSite(std::shared_ptr site) { == false) { glassutil::CLogit::log( glassutil::log_level::error, - "CWeb::remSite: Failed to add station " + newSite->sScnl - + " to web " + sName + "."); + "CWeb::remSite: Failed to add station " + + newSite->getScnl() + " to web " + sName + + "."); } // resort site links @@ -1638,10 +1695,12 @@ void CWeb::remSite(std::shared_ptr site) { } else { glassutil::CLogit::log( glassutil::log_level::error, - "CWeb::remSite: Failed to remove station " + site->sScnl + "CWeb::remSite: Failed to remove station " + site->getScnl() + " from web " + sName + "."); } + node->setEnabled(true); + // update thread status setStatus(true); } @@ -1652,12 +1711,12 @@ void CWeb::remSite(std::shared_ptr site) { snprintf( sLog, sizeof(sLog), "CWeb::remSite: Removed site: %s from %d node(s) in web: %s", - site->sScnl.c_str(), nodeCount, sName.c_str()); + site->getScnl().c_str(), nodeCount, sName.c_str()); glassutil::CLogit::log(glassutil::log_level::info, sLog); } else { glassutil::CLogit::log( glassutil::log_level::debug, - "CWeb::remSite: Station " + site->sScnl + "CWeb::remSite: Station " + site->getScnl() + " not removed from any nodes in web: " + sName + "."); } } @@ -1814,15 +1873,100 @@ bool CWeb::hasSite(std::shared_ptr site) { return (false); } + std::lock_guard vNodeGuard(m_vNodeMutex); + // for each node in web for (auto &node : vNode) { // check to see if we have this site - if (node->getSite(site->sScnl) != NULL) { - return(true); + if (node->getSite(site->getScnl()) != NULL) { + return (true); } } // site not found - return(false); + return (false); +} + +const CSiteList* CWeb::getSiteList() const { + std::lock_guard webGuard(m_WebMutex); + return (pSiteList); +} + +void CWeb::setSiteList(CSiteList* siteList) { + std::lock_guard webGuard(m_WebMutex); + pSiteList = siteList; +} + +CGlass* CWeb::getGlass() const { + std::lock_guard webGuard(m_WebMutex); + return (pGlass); +} + +void CWeb::setGlass(CGlass* glass) { + std::lock_guard webGuard(m_WebMutex); + pGlass = glass; +} + +bool CWeb::getUpdate() const { + return (bUpdate); +} + +double CWeb::getResolution() const { + return (dResolution); } + +double CWeb::getThresh() const { + return (dThresh); +} + +int CWeb::getCol() const { + return (nCol); +} + +int CWeb::getDetect() const { + return (nDetect); +} + +int CWeb::getNucleate() const { + return (nNucleate); +} + +int CWeb::getRow() const { + return (nRow); +} + +int CWeb::getZ() const { + return (nZ); +} + +const std::string& CWeb::getName() const { + return (sName); +} + +const std::shared_ptr& CWeb::getTrv1() const { + std::lock_guard webGuard(m_TrvMutex); + return (pTrv1); +} + +const std::shared_ptr& CWeb::getTrv2() const { + std::lock_guard webGuard(m_TrvMutex); + return (pTrv2); +} + +int CWeb::getVNetFilterSize() const { + std::lock_guard webGuard(m_WebMutex); + return (vNetFilter.size()); +} + +int CWeb::getVSitesFilterSize() const { + std::lock_guard webGuard(m_WebMutex); + return (vSitesFilter.size()); +} + +int CWeb::getVNodeSize() const { + std::lock_guard vNodeGuard(m_vNodeMutex); + return (vNode.size()); +} + } // namespace glasscore + diff --git a/glasscore/glasslib/src/WebList.cpp b/glasscore/glasslib/src/WebList.cpp index 3d7fd34f..0dd223a6 100644 --- a/glasscore/glasslib/src/WebList.cpp +++ b/glasscore/glasslib/src/WebList.cpp @@ -25,6 +25,8 @@ CWebList::~CWebList() { // ---------------------------------------------------------clear void CWebList::clear() { + std::lock_guard webListGuard(m_WebListMutex); + pGlass = NULL; pSiteList = NULL; @@ -36,7 +38,7 @@ void CWebList::clear() { } // ---------------------------------------------------------Dispatch -bool CWebList::dispatch(json::Object *com) { +bool CWebList::dispatch(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log(glassutil::log_level::error, @@ -66,7 +68,7 @@ bool CWebList::dispatch(json::Object *com) { } // ---------------------------------------------------------AddWeb -bool CWebList::addWeb(json::Object *com) { +bool CWebList::addWeb(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log(glassutil::log_level::error, @@ -87,7 +89,7 @@ bool CWebList::addWeb(json::Object *com) { std::shared_ptr web = vWeb[i]; // look for name match - if (web->sName == name) { + if (web->getName() == name) { glassutil::CLogit::log( glassutil::log_level::warn, "CWebList::addWeb: Already have a web with the name " + name @@ -99,10 +101,10 @@ bool CWebList::addWeb(json::Object *com) { // Create a new web object std::shared_ptr web(new CWeb(m_bUseBackgroundThreads)); if (pGlass != NULL) { - web->pGlass = pGlass; + web->setGlass(pGlass); } if (pSiteList != NULL) { - web->pSiteList = pSiteList; + web->setSiteList(pSiteList); } // send the config to web so that it can generate itself @@ -118,7 +120,7 @@ bool CWebList::addWeb(json::Object *com) { } // ---------------------------------------------------------RemoveWeb -bool CWebList::removeWeb(json::Object *com) { +bool CWebList::removeWeb(std::shared_ptr com) { // null check json if (com == NULL) { glassutil::CLogit::log( @@ -147,7 +149,7 @@ bool CWebList::removeWeb(json::Object *com) { for (int i = 0; i < vWeb.size(); i++) { std::shared_ptr web = vWeb[i]; - if (web->sName == name) { + if (web->getName() == name) { // clear the web and remove it web->clear(); vWeb.erase(vWeb.begin() + i); @@ -168,12 +170,12 @@ void CWebList::addSite(std::shared_ptr site) { glassutil::CLogit::log( glassutil::log_level::debug, - "CWebList::addSite: Adding station " + site->sScnl + "."); + "CWebList::addSite: Adding station " + site->getScnl() + "."); // Update all web node site lists that might be changed // by the addition of this site for (auto &web : vWeb) { - if (web->bUpdate == true) { + if (web->getUpdate() == true) { if (web->isSiteAllowed(site) == true) { web->addJob(std::bind(&CWeb::addSite, web, site)); } @@ -190,12 +192,12 @@ void CWebList::remSite(std::shared_ptr site) { glassutil::CLogit::log( glassutil::log_level::debug, - "CWebList::addSite: Removing station " + site->sScnl + "."); + "CWebList::addSite: Removing station " + site->getScnl() + "."); // Remove site from all web nodes that link to it and restructure // node site lists for (auto &web : vWeb) { - if (web->bUpdate == true) { + if (web->getUpdate() == true) { if (web->isSiteAllowed(site) == true) { web->addJob(std::bind(&CWeb::remSite, web, site)); } @@ -247,4 +249,29 @@ bool CWebList::statusCheck() { // all's well return (true); } + +const CSiteList* CWebList::getSiteList() const { + std::lock_guard webListGuard(m_WebListMutex); + return (pSiteList); +} + +void CWebList::setSiteList(CSiteList* siteList) { + std::lock_guard webListGuard(m_WebListMutex); + pSiteList = siteList; +} + +const CGlass* CWebList::getGlass() const { + std::lock_guard webListGuard(m_WebListMutex); + return (pGlass); +} + +void CWebList::setGlass(CGlass* glass) { + std::lock_guard webListGuard(m_WebListMutex); + pGlass = glass; +} + +int CWebList::getVWebSize() const { + std::lock_guard webListGuard(m_WebListMutex); + return(vWeb.size()); +} } // namespace glasscore diff --git a/glasscore/tests/correlation_unittest.cpp b/glasscore/tests/correlation_unittest.cpp index e43999e6..a2ec4844 100644 --- a/glasscore/tests/correlation_unittest.cpp +++ b/glasscore/tests/correlation_unittest.cpp @@ -27,74 +27,74 @@ // check site data for validity void checkdata(glasscore::CCorrelation * corrleationobject, - const std::string &testinfo) { + const std::string &testinfo) { // check scnl - std::string sitescnl = corrleationobject->pSite->sScnl; + std::string sitescnl = corrleationobject->getSite()->getScnl(); std::string expectedscnl = std::string(SCNL); ASSERT_STREQ(sitescnl.c_str(), expectedscnl.c_str()); // check site - std::string sitesite = corrleationobject->pSite->sSite; + std::string sitesite = corrleationobject->getSite()->getSite(); std::string expectedsite = std::string(SITE); ASSERT_STREQ(sitesite.c_str(), expectedsite.c_str()); // check comp - std::string sitecomp = corrleationobject->pSite->sComp; + std::string sitecomp = corrleationobject->getSite()->getComp(); std::string expectedcomp = std::string(COMP); ASSERT_STREQ(sitecomp.c_str(), expectedcomp.c_str()); // check net - std::string sitenet = corrleationobject->pSite->sNet; + std::string sitenet = corrleationobject->getSite()->getNet(); std::string expectednet = std::string(NET); ASSERT_STREQ(sitenet.c_str(), expectednet.c_str()); // check loc - std::string siteloc = corrleationobject->pSite->sLoc; + std::string siteloc = corrleationobject->getSite()->getLoc(); std::string expectedloc = std::string(LOC); ASSERT_STREQ(siteloc.c_str(), expectedloc.c_str()); // check time - double correlationtime = corrleationobject->tCorrelation; + double correlationtime = corrleationobject->getTCorrelation(); double expectedcorrelationtime = CORRELATIONTIME; ASSERT_NEAR(correlationtime, expectedcorrelationtime, 0.0001); // check id - int id = corrleationobject->idCorrelation; + int id = corrleationobject->getIdCorrelation(); int expectedid = CORRELATIONID; ASSERT_EQ(id, expectedid); // check string id - std::string stringid = corrleationobject->sPid; + std::string stringid = corrleationobject->getPid(); std::string expectedstringid = std::string(CORRELATIONIDSTRING); ASSERT_STREQ(stringid.c_str(), expectedstringid.c_str()); // check origin time - double origintime = corrleationobject->tOrg; + double origintime = corrleationobject->getTOrg(); double expectedorigintime = ORIGINTIME; ASSERT_NEAR(origintime, expectedorigintime, 0.0001); // check lat - double lat = corrleationobject->dLat; + double lat = corrleationobject->getLat(); double expectedlat = LAT; ASSERT_NEAR(lat, expectedlat, 0.0001); // check lon - double lon = corrleationobject->dLon; + double lon = corrleationobject->getLon(); double expectedlon = LON; ASSERT_NEAR(lon, expectedlon, 0.0001); // check rad - double z = corrleationobject->dZ; + double z = corrleationobject->getZ(); double expectedz = Z; ASSERT_NEAR(z, expectedz, 0.0001); // check correlation - double correlation = corrleationobject->dCorrelation; + double correlation = corrleationobject->getCorrelation(); double expectedcorrelation = CORRELATION; ASSERT_NEAR(correlation, expectedcorrelation, 0.0001); // check phase - std::string stringphase = corrleationobject->sPhs; + std::string stringphase = corrleationobject->getPhs(); std::string expectedstringphase = std::string(PHASE); ASSERT_STREQ(stringphase.c_str(), expectedstringphase.c_str()); } @@ -107,27 +107,28 @@ TEST(CorrelationTest, Construction) { glasscore::CCorrelation * testCorrelation = new glasscore::CCorrelation(); // assert default values - ASSERT_EQ(0, testCorrelation->tCorrelation)<< "time is zero"; - ASSERT_EQ(0, testCorrelation->idCorrelation)<< "id is zero"; - ASSERT_EQ(0, testCorrelation->tOrg)<< "origin time is zero"; - ASSERT_EQ(0, testCorrelation->dLat)<< "lat is zero"; - ASSERT_EQ(0, testCorrelation->dLon)<< "lon is zero"; - ASSERT_EQ(0, testCorrelation->dZ)<< "z is zero"; - ASSERT_EQ(0, testCorrelation->dCorrelation)<< "correlation is zero"; - - ASSERT_STREQ("", testCorrelation->sAss.c_str()); - ASSERT_STREQ("", testCorrelation->sPhs.c_str()); - ASSERT_STREQ("", testCorrelation->sPid.c_str()); + ASSERT_EQ(0, testCorrelation->getTCorrelation())<< "time is zero"; + ASSERT_EQ(0, testCorrelation->getIdCorrelation())<< "id is zero"; + ASSERT_EQ(0, testCorrelation->getTOrg())<< "origin time is zero"; + ASSERT_EQ(0, testCorrelation->getLat())<< "lat is zero"; + ASSERT_EQ(0, testCorrelation->getLon())<< "lon is zero"; + ASSERT_EQ(0, testCorrelation->getZ())<< "z is zero"; + ASSERT_EQ(0, testCorrelation->getCorrelation())<< "correlation is zero"; + + ASSERT_STREQ("", testCorrelation->getAss().c_str()); + ASSERT_STREQ("", testCorrelation->getPhs().c_str()); + ASSERT_STREQ("", testCorrelation->getPid().c_str()); // pointers - ASSERT_TRUE(testCorrelation->pSite == NULL)<< "pSite null"; - ASSERT_TRUE(testCorrelation->pHypo == NULL)<< "pHypo null"; - ASSERT_TRUE(testCorrelation->jCorrelation == NULL)<< "jCorrelation null"; + ASSERT_TRUE(testCorrelation->getSite() == NULL)<< "pSite null"; + ASSERT_TRUE(testCorrelation->getHypo() == NULL)<< "pHypo null"; + ASSERT_TRUE(testCorrelation->getJCorrelation() == NULL)<< "jCorrelation null"; // create shared pointer to the site - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); std::shared_ptr sharedTestSite( - new glasscore::CSite(&siteJSON, NULL)); + new glasscore::CSite(siteJSON, NULL)); // now init testCorrelation->initialize(sharedTestSite, CORRELATIONTIME, CORRELATIONID, @@ -148,21 +149,22 @@ TEST(CorrelationTest, JSONConstruction) { glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); // create json objects from the strings - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); // add site to site list - testSiteList->addSite(&siteJSON); + testSiteList->addSite(siteJSON); // construct a correlation using a JSON object - json::Object correlationJSON = json::Deserialize( - std::string(CORRELATIONJSON)); + std::shared_ptr correlationJSON = std::make_shared( + json::Object(json::Deserialize(std::string(CORRELATIONJSON)))); glasscore::CCorrelation * testCorrelation = new glasscore::CCorrelation( - &correlationJSON, CORRELATIONID, testSiteList); + correlationJSON, CORRELATIONID, testSiteList); // check results checkdata(testCorrelation, "json construction check"); - delete(testCorrelation); + delete (testCorrelation); } // tests correlation hypo operations @@ -170,9 +172,10 @@ TEST(CorrelationTest, HypoOperations) { glassutil::CLogit::disable(); // create shared pointer to the site - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); std::shared_ptr sharedTestSite( - new glasscore::CSite(&siteJSON, NULL)); + new glasscore::CSite(siteJSON, NULL)); // create correlation glasscore::CCorrelation *testCorrelation = new glasscore::CCorrelation( @@ -182,11 +185,12 @@ TEST(CorrelationTest, HypoOperations) { LON, Z, CORRELATION); // create a hypo - traveltime::CTravelTime* nullTrav = NULL; + std::shared_ptr nullTrav; + std::shared_ptr nullTTT; glasscore::CHypo * testHypo = new glasscore::CHypo(0.0, 0.0, 0.0, 0.0, "1", "test", 0.0, 0.0, 0, nullTrav, nullTrav, - NULL); + nullTTT); // create new shared pointer to the hypo std::shared_ptr sharedHypo(testHypo); @@ -195,11 +199,11 @@ TEST(CorrelationTest, HypoOperations) { testCorrelation->addHypo(sharedHypo); // check hypo - ASSERT_TRUE(testCorrelation->pHypo != NULL)<< "pHypo not null"; + ASSERT_TRUE(testCorrelation->getHypo() != NULL)<< "pHypo not null"; // remove hypo from correlation testCorrelation->remHypo(sharedHypo); // check hypo - ASSERT_TRUE(testCorrelation->pHypo == NULL)<< "pHypo null"; + ASSERT_TRUE(testCorrelation->getHypo() == NULL)<< "pHypo null"; } diff --git a/glasscore/tests/correlationlist_unittest.cpp b/glasscore/tests/correlationlist_unittest.cpp index 258dc08f..14b6d94a 100644 --- a/glasscore/tests/correlationlist_unittest.cpp +++ b/glasscore/tests/correlationlist_unittest.cpp @@ -41,18 +41,17 @@ TEST(CorrelationListTest, Construction) { new glasscore::CCorrelationList(); // assert default values - ASSERT_EQ(-1, testCorrelationList->nCorrelationTotal)<< - "nCorrelationTotal is 0"; - ASSERT_EQ(0, testCorrelationList->nCorrelation)<< "nCorrelation is 0"; + ASSERT_EQ(-1, testCorrelationList->getNCorrelationTotal())<< + "nCorrelationTotal is 0"; + ASSERT_EQ(0, testCorrelationList->getNCorrelation())<< "nCorrelation is 0"; // lists - ASSERT_EQ(0, testCorrelationList->vCorrelation.size())<< - "vCorrelation.size() is 0"; - ASSERT_EQ(0, testCorrelationList->mCorrelation.size())<< - "mCorrelation.size() is 0"; + ASSERT_EQ(0, testCorrelationList->getVCorrelationSize())<< + "vCorrelation.size() is 0"; // pointers - ASSERT_EQ(NULL, testCorrelationList->pGlass)<< "pGlass null"; + ASSERT_EQ(NULL, testCorrelationList->getGlass())<< "pGlass null"; + ASSERT_EQ(NULL, testCorrelationList->getSiteList())<< "pSiteList null"; // cleanup delete (testCorrelationList); @@ -63,47 +62,56 @@ TEST(CorrelationListTest, CorrelationOperations) { glassutil::CLogit::disable(); // create json objects from the strings - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); - json::Object site2JSON = json::Deserialize(std::string(SITE2JSON)); - json::Object site3JSON = json::Deserialize(std::string(SITE3JSON)); - - json::Object correlationJSON = json::Deserialize( - std::string(CORRELATIONJSON)); - json::Object correlation2JSON = json::Deserialize( - std::string(CORRELATION2JSON)); - json::Object correlation3JSON = json::Deserialize( - std::string(CORRELATION3JSON)); - json::Object correlation4JSON = json::Deserialize( - std::string(CORRELATION4JSON)); - json::Object correlation5JSON = json::Deserialize( - std::string(CORRELATION5JSON)); - json::Object correlation6JSON = json::Deserialize( - std::string(CORRELATION6JSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); + std::shared_ptr site2JSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITE2JSON)))); + std::shared_ptr site3JSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITE3JSON)))); + + std::shared_ptr correlationJSON = std::make_shared< + json::Object>( + json::Object(json::Deserialize(std::string(CORRELATIONJSON)))); + std::shared_ptr correlation2JSON = std::make_shared< + json::Object>( + json::Object(json::Deserialize(std::string(CORRELATION2JSON)))); + std::shared_ptr correlation3JSON = std::make_shared< + json::Object>( + json::Object(json::Deserialize(std::string(CORRELATION3JSON)))); + std::shared_ptr correlation4JSON = std::make_shared< + json::Object>( + json::Object(json::Deserialize(std::string(CORRELATION4JSON)))); + std::shared_ptr correlation5JSON = std::make_shared< + json::Object>( + json::Object(json::Deserialize(std::string(CORRELATION5JSON)))); + std::shared_ptr correlation6JSON = std::make_shared< + json::Object>( + json::Object(json::Deserialize(std::string(CORRELATION6JSON)))); // construct a sitelist glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); // add sites to site list - testSiteList->addSite(&siteJSON); - testSiteList->addSite(&site2JSON); - testSiteList->addSite(&site3JSON); + testSiteList->addSite(siteJSON); + testSiteList->addSite(site2JSON); + testSiteList->addSite(site3JSON); // construct a correlationlist glasscore::CCorrelationList * testCorrelationList = new glasscore::CCorrelationList(); - testCorrelationList->pSiteList = testSiteList; - testCorrelationList->nCorrelationMax = MAXNCORRELATION; + testCorrelationList->setSiteList(testSiteList); + testCorrelationList->setNCorrelationMax(MAXNCORRELATION); // test indexcorrelation when empty ASSERT_EQ(-2, testCorrelationList->indexCorrelation(0))<< - "test indexcorrelation when empty"; + "test indexcorrelation when empty"; // test adding correlations by addCorrelation and dispatch - testCorrelationList->addCorrelation(&correlationJSON); - testCorrelationList->dispatch(&correlation3JSON); + testCorrelationList->addCorrelation(correlationJSON); + testCorrelationList->dispatch(correlation3JSON); int expectedSize = 2; - ASSERT_EQ(expectedSize, testCorrelationList->nCorrelation)<< - "Added Correlations"; + ASSERT_EQ(expectedSize, testCorrelationList->getNCorrelation())<< + "Added Correlations"; // test getting a correlation (first correlation, id 1) std::shared_ptr testCorrelation = @@ -111,45 +119,45 @@ TEST(CorrelationListTest, CorrelationOperations) { // check testcorrelation ASSERT_TRUE(testCorrelation != NULL)<< "testCorrelation not null"; // check scnl - std::string sitescnl = testCorrelation->pSite->sScnl; + std::string sitescnl = testCorrelation->getSite()->getScnl(); std::string expectedscnl = std::string(SCNL); ASSERT_STREQ(sitescnl.c_str(), expectedscnl.c_str())<< - "testCorrelation has right scnl"; + "testCorrelation has right scnl"; // test indexcorrelation ASSERT_EQ(-1, testCorrelationList->indexCorrelation(TCORRELATION))<< - "test indexcorrelation with time before"; + "test indexcorrelation with time before"; ASSERT_EQ(1, testCorrelationList->indexCorrelation(TCORRELATION2))<< - "test indexcorrelation with time after"; + "test indexcorrelation with time after"; ASSERT_EQ(0, testCorrelationList->indexCorrelation(TCORRELATION3))<< - "test indexcorrelation with time within"; + "test indexcorrelation with time within"; // add more correlations - testCorrelationList->addCorrelation(&correlation2JSON); - testCorrelationList->addCorrelation(&correlation4JSON); - testCorrelationList->addCorrelation(&correlation5JSON); - testCorrelationList->addCorrelation(&correlation6JSON); + testCorrelationList->addCorrelation(correlation2JSON); + testCorrelationList->addCorrelation(correlation4JSON); + testCorrelationList->addCorrelation(correlation5JSON); + testCorrelationList->addCorrelation(correlation6JSON); // check to make sure the size isn't any larger than our max expectedSize = MAXNCORRELATION; - ASSERT_EQ(expectedSize, testCorrelationList->vCorrelation.size())<< - "testCorrelationList not larger than max"; + ASSERT_EQ(expectedSize, testCorrelationList->getVCorrelationSize())<< + "testCorrelationList not larger than max"; // get first correlation, which is now id 2 std::shared_ptr test2Correlation = testCorrelationList->getCorrelation(2); // check scnl - sitescnl = test2Correlation->pSite->sScnl; + sitescnl = test2Correlation->getSite()->getScnl(); expectedscnl = std::string(SCNL2); ASSERT_STREQ(sitescnl.c_str(), expectedscnl.c_str())<< - "test2Correlation has right scnl"; + "test2Correlation has right scnl"; // test clearing correlations testCorrelationList->clearCorrelations(); expectedSize = 0; - ASSERT_EQ(expectedSize, testCorrelationList->nCorrelation)<< - "Cleared Correlations"; + ASSERT_EQ(expectedSize, testCorrelationList->getNCorrelation())<< + "Cleared Correlations"; // cleanup delete (testCorrelationList); diff --git a/glasscore/tests/hypo_unittest.cpp b/glasscore/tests/hypo_unittest.cpp index 10ade2c8..bc8e3d31 100644 --- a/glasscore/tests/hypo_unittest.cpp +++ b/glasscore/tests/hypo_unittest.cpp @@ -35,47 +35,47 @@ // check site data for validity void checkdata(glasscore::CHypo *hypoobject, const std::string &testinfo) { // check lat - double latitude = hypoobject->dLat; + double latitude = hypoobject->getLat(); double expectedLatitude = LATITUDE; ASSERT_NEAR(latitude, expectedLatitude, 0.0001); // check lon - double longitude = hypoobject->dLon; + double longitude = hypoobject->getLon(); double expectedLongitude = LONGITUDE; ASSERT_NEAR(longitude, expectedLongitude, 0.0001); // check depth - double depth = hypoobject->dZ; + double depth = hypoobject->getZ(); double expectedDepth = DEPTH; ASSERT_NEAR(depth, expectedDepth, 0.0001); // check time - double time = hypoobject->tOrg; + double time = hypoobject->getTOrg(); double expectedTime = TIME; ASSERT_NEAR(time, expectedTime, 0.0001); // check id - std::string id = hypoobject->sPid; + std::string id = hypoobject->getPid(); std::string expectedId = ID; ASSERT_STREQ(id.c_str(), expectedId.c_str()); // check web - std::string web = hypoobject->sWeb; + std::string web = hypoobject->getWebName(); std::string expectedWeb = std::string(WEB); ASSERT_STREQ(web.c_str(), expectedWeb.c_str()); // check bayes - double bayes = hypoobject->dBayes; + double bayes = hypoobject->getBayes(); double expectedBayes = BAYES; ASSERT_NEAR(bayes, expectedBayes, 0.0001); // check bayes - double thresh = hypoobject->dThresh; + double thresh = hypoobject->getThresh(); double expectedThresh = THRESH; ASSERT_NEAR(thresh, expectedThresh, 0.0001); // check cut - int cut = hypoobject->nCut; + int cut = hypoobject->getCut(); int expectedCut = CUT; ASSERT_EQ(cut, expectedCut); } @@ -88,38 +88,35 @@ TEST(HypoTest, Construction) { glasscore::CHypo * testHypo = new glasscore::CHypo(); // assert default values - ASSERT_EQ(0, testHypo->dLat)<< "dLat is zero"; - ASSERT_EQ(0, testHypo->dLon)<< "dLon is zero"; - ASSERT_EQ(0, testHypo->dZ)<< "dZ is zero"; - ASSERT_EQ(0, testHypo->tOrg)<< "tOrg is zero"; - ASSERT_STREQ("", testHypo->sPid.c_str())<< "sPid is empty"; - ASSERT_STREQ("", testHypo->sWeb.c_str())<< "sWeb is empty"; - ASSERT_EQ(0, testHypo->dBayes)<< "dBayes is zero"; - ASSERT_EQ(0, testHypo->dThresh)<< "dThresh is zero"; - ASSERT_EQ(0, testHypo->nCut)<< "nCut is zero"; - ASSERT_EQ(0, testHypo->iCycle)<< "iCycle is zero"; - ASSERT_EQ(0, testHypo->nWts)<< "nWts is zero"; - ASSERT_EQ(0, testHypo->dMed)<< "dMed is zero"; - ASSERT_EQ(0, testHypo->dMin)<< "dMin is zero"; - ASSERT_EQ(0, testHypo->dGap)<< "dGap is zero"; - ASSERT_EQ(0, testHypo->dSig)<< "dSig is zero"; - ASSERT_EQ(0, testHypo->dKrt)<< "dKrt is zero"; - ASSERT_FALSE(testHypo->bFixed)<< "bFixed is false"; - ASSERT_FALSE(testHypo->bRefine)<< "bRefine is false"; - ASSERT_FALSE(testHypo->bQuake)<< "bQuake is false"; - ASSERT_FALSE(testHypo->bEvent)<< "bEvent is false"; - - ASSERT_EQ(0, testHypo->vPick.size())<< "vPick size is zero"; - ASSERT_EQ(0, testHypo->vWts.size())<< "vWts size is zero"; + ASSERT_EQ(0, testHypo->getLat())<< "dLat is zero"; + ASSERT_EQ(0, testHypo->getLon())<< "dLon is zero"; + ASSERT_EQ(0, testHypo->getZ())<< "dZ is zero"; + ASSERT_EQ(0, testHypo->getTOrg())<< "tOrg is zero"; + ASSERT_STREQ("", testHypo->getPid().c_str())<< "sPid is empty"; + ASSERT_STREQ("", testHypo->getWebName().c_str())<< "sWeb is empty"; + ASSERT_EQ(0, testHypo->getBayes())<< "dBayes is zero"; + ASSERT_EQ(0, testHypo->getThresh())<< "dThresh is zero"; + ASSERT_EQ(0, testHypo->getCut())<< "nCut is zero"; + ASSERT_EQ(0, testHypo->getCycle())<< "iCycle is zero"; + ASSERT_EQ(0, testHypo->getMed())<< "dMed is zero"; + ASSERT_EQ(0, testHypo->getMin())<< "dMin is zero"; + ASSERT_EQ(0, testHypo->getGap())<< "dGap is zero"; + ASSERT_EQ(0, testHypo->getSig())<< "dSig is zero"; + ASSERT_EQ(0, testHypo->getKrt())<< "dKrt is zero"; + ASSERT_FALSE(testHypo->getFixed())<< "bFixed is false"; + ASSERT_FALSE(testHypo->getEvent())<< "bEvent is false"; + + ASSERT_EQ(0, testHypo->getVPickSize())<< "vPick size is zero"; // pointers - ASSERT_TRUE(testHypo->pGlass == NULL)<< "pGlass null"; + ASSERT_TRUE(testHypo->getGlass() == NULL)<< "pGlass null"; // now init - traveltime::CTravelTime* nullTrav = NULL; + std::shared_ptr nullTrav; + std::shared_ptr nullTTT; testHypo->initialize(LATITUDE, LONGITUDE, DEPTH, TIME, std::string(ID), std::string(WEB), BAYES, THRESH, CUT, nullTrav, - nullTrav, NULL); + nullTrav, nullTTT); // check results checkdata(testHypo, "initialize check"); @@ -130,38 +127,45 @@ TEST(HypoTest, PickOperations) { glassutil::CLogit::disable(); // construct a hypo - traveltime::CTravelTime* nullTrav = NULL; + std::shared_ptr nullTrav; + std::shared_ptr nullTTT; glasscore::CHypo * testHypo = new glasscore::CHypo(LATITUDE, LONGITUDE, DEPTH, TIME, std::string(ID), std::string(WEB), BAYES, THRESH, - CUT, nullTrav, - nullTrav, NULL); + CUT, nullTrav, nullTrav, + nullTTT); // create json objects from the strings - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); - json::Object site2JSON = json::Deserialize(std::string(SITE2JSON)); - json::Object site3JSON = json::Deserialize(std::string(SITE3JSON)); - - json::Object pickJSON = json::Deserialize(std::string(PICKJSON)); - json::Object pick2JSON = json::Deserialize(std::string(PICK2JSON)); - json::Object pick3JSON = json::Deserialize(std::string(PICK3JSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); + std::shared_ptr site2JSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITE2JSON)))); + std::shared_ptr site3JSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITE3JSON)))); + + std::shared_ptr pickJSON = std::make_shared( + json::Object(json::Deserialize(std::string(PICKJSON)))); + std::shared_ptr pick2JSON = std::make_shared( + json::Object(json::Deserialize(std::string(PICK2JSON)))); + std::shared_ptr pick3JSON = std::make_shared( + json::Object(json::Deserialize(std::string(PICK3JSON)))); // construct a sitelist glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); // add sites to site list - testSiteList->addSite(&siteJSON); - testSiteList->addSite(&site2JSON); - testSiteList->addSite(&site3JSON); + testSiteList->addSite(siteJSON); + testSiteList->addSite(site2JSON); + testSiteList->addSite(site3JSON); // create picks - glasscore::CPick * testPick = new glasscore::CPick(&pickJSON, 1, + glasscore::CPick * testPick = new glasscore::CPick(pickJSON, 1, testSiteList); - glasscore::CPick * testPick2 = new glasscore::CPick(&pick2JSON, 2, + glasscore::CPick * testPick2 = new glasscore::CPick(pick2JSON, 2, testSiteList); - glasscore::CPick * testPick3 = new glasscore::CPick(&pick3JSON, 3, + glasscore::CPick * testPick3 = new glasscore::CPick(pick3JSON, 3, testSiteList); // create new shared pointers to the picks @@ -176,7 +180,7 @@ TEST(HypoTest, PickOperations) { // check to make sure the size isn't any larger than our max int expectedSize = MAXNPICK; - ASSERT_EQ(expectedSize, testHypo->vPick.size())<< + ASSERT_EQ(expectedSize, testHypo->getVPickSize())<< "hypo vPick not larger than max"; // remove picks from hypo @@ -185,5 +189,5 @@ TEST(HypoTest, PickOperations) { // check to see that only one pick remains expectedSize = 1; - ASSERT_EQ(expectedSize, testHypo->vPick.size())<< "hypo has only one pick"; + ASSERT_EQ(expectedSize, testHypo->getVPickSize())<< "hypo has only one pick"; } diff --git a/glasscore/tests/hypolist_unittest.cpp b/glasscore/tests/hypolist_unittest.cpp index 83c0bcb3..13186f4f 100644 --- a/glasscore/tests/hypolist_unittest.cpp +++ b/glasscore/tests/hypolist_unittest.cpp @@ -32,16 +32,15 @@ TEST(HypoListTest, Construction) { glasscore::CHypoList * testHypoList = new glasscore::CHypoList(); // assert default values - ASSERT_EQ(-1, testHypoList->nHypoTotal)<< "nPickTotal is 0"; - ASSERT_EQ(0, testHypoList->nHypo)<< "nHypo is 0"; + ASSERT_EQ(-1, testHypoList->getNHypoTotal())<< "nPickTotal is 0"; + ASSERT_EQ(0, testHypoList->getNHypo())<< "nHypo is 0"; // lists - ASSERT_EQ(0, testHypoList->vHypo.size())<< "vHypo.size() is 0"; - ASSERT_EQ(0, testHypoList->mHypo.size())<< "mHypo.size() is 0"; - ASSERT_EQ(0, testHypoList->qFifo.size())<< "qFifo.size() is 0"; + ASSERT_EQ(0, testHypoList->getVHypoSize())<< "vHypo.size() is 0"; + ASSERT_EQ(0, testHypoList->getFifoSize())<< "qFifo.size() is 0"; // pointers - ASSERT_EQ(NULL, testHypoList->pGlass)<< "pGlass null"; + ASSERT_EQ(NULL, testHypoList->getGlass())<< "pGlass null"; // cleanup delete (testHypoList); @@ -51,45 +50,44 @@ TEST(HypoListTest, Construction) { TEST(HypoListTest, HypoOperations) { glassutil::CLogit::disable(); - traveltime::CTTT * nullTTT = NULL; - // create hypo objects - traveltime::CTravelTime* nullTrav = NULL; + std::shared_ptr nullTrav; + std::shared_ptr nullTTT; std::shared_ptr hypo1 = std::make_shared(-21.84, 170.03, 10.0, 3648585210.926340, "1", "Test", - 0.0, 0.5, 6, nullTrav, - nullTrav, nullTTT); + 0.0, 0.5, 6, nullTrav, nullTrav, + nullTTT); std::shared_ptr hypo2 = std::make_shared(22.84, 70.03, 12.0, 3648585208.926340, "2", "Test", - 0.0, 0.5, 6, nullTrav, - nullTrav, nullTTT); + 0.0, 0.5, 6, nullTrav, nullTrav, + nullTTT); std::shared_ptr hypo3 = std::make_shared(41.84, -120.03, 8.0, 3648585222.926340, "3", "Test", - 0.0, 0.5, 6, nullTrav, - nullTrav, nullTTT); + 0.0, 0.5, 6, nullTrav, nullTrav, + nullTTT); std::shared_ptr hypo4 = std::make_shared(-1.84, 10.03, 100.0, 3648585250.926340, "4", "Test", - 0.0, 0.5, 6, nullTrav, - nullTrav, nullTTT); + 0.0, 0.5, 6, nullTrav, nullTrav, + nullTTT); std::shared_ptr hypo5 = std::make_shared(1.84, -170.03, 67.0, 3648585233.926340, "5", "Test", - 0.0, 0.5, 6, nullTrav, - nullTrav, nullTTT); + 0.0, 0.5, 6, nullTrav, nullTrav, + nullTTT); std::shared_ptr hypo6 = std::make_shared(46.84, 135.03, 42.0, 3648585211.926340, "6", "Test", - 0.0, 0.5, 6, nullTrav, - nullTrav, nullTTT); + 0.0, 0.5, 6, nullTrav, nullTrav, + nullTTT); // construct a hypolist glasscore::CHypoList * testHypoList = new glasscore::CHypoList(); - testHypoList->nHypoMax = MAXNHYPO; + testHypoList->setNHypoMax(MAXNHYPO); // test indexpick when empty ASSERT_EQ(-2, testHypoList->indexHypo(0))<< "test indexHypo when empty"; @@ -98,7 +96,7 @@ TEST(HypoListTest, HypoOperations) { testHypoList->addHypo(hypo1, false); testHypoList->addHypo(hypo2, false); int expectedSize = 2; - ASSERT_EQ(expectedSize, testHypoList->nHypo)<< "Added Hypos"; + ASSERT_EQ(expectedSize, testHypoList->getNHypo())<< "Added Hypos"; // test indexHypo ASSERT_EQ(-1, testHypoList->indexHypo(TORG))<< @@ -116,7 +114,7 @@ TEST(HypoListTest, HypoOperations) { // check to make sure the size isn't any larger than our max expectedSize = MAXNHYPO; - ASSERT_EQ(expectedSize, (int)testHypoList->vHypo.size())<< + ASSERT_EQ(expectedSize, (int)testHypoList->getVHypoSize())<< "testHypoList not larger than max"; // test getting a hypo @@ -127,7 +125,7 @@ TEST(HypoListTest, HypoOperations) { ASSERT_TRUE(testHypo != NULL)<< "testHypo not null"; // check id - std::string hypoId = testHypo->sPid; + std::string hypoId = testHypo->getPid(); std::string expectedId = std::string(TESTHYPOID); ASSERT_STREQ(hypoId.c_str(), expectedId.c_str())<< "testHypo has right id"; @@ -136,13 +134,13 @@ TEST(HypoListTest, HypoOperations) { // check to make sure the size is now one less expectedSize = MAXNHYPO - 1; - ASSERT_EQ(expectedSize, (int)testHypoList->vHypo.size())<< + ASSERT_EQ(expectedSize, (int)testHypoList->getVHypoSize())<< "testHypoList is one smaller"; // test clearing hypos testHypoList->clearHypos(); expectedSize = 0; - ASSERT_EQ(expectedSize, (int)testHypoList->nHypo)<< "Cleared Hypos"; + ASSERT_EQ(expectedSize, (int)testHypoList->getNHypo())<< "Cleared Hypos"; // cleanup delete (testHypoList); diff --git a/glasscore/tests/node_unittest.cpp b/glasscore/tests/node_unittest.cpp index e25e9233..58eb037a 100644 --- a/glasscore/tests/node_unittest.cpp +++ b/glasscore/tests/node_unittest.cpp @@ -32,23 +32,23 @@ TEST(NodeTest, Construction) { std::string(NODEID)); // name - ASSERT_STREQ(std::string(NAME).c_str(), testNode->sName.c_str())<< + ASSERT_STREQ(std::string(NAME).c_str(), testNode->getName().c_str())<< "Node Name Matches"; // latitude - ASSERT_EQ(LATITUDE, testNode->dLat)<< "Node Latitude Check"; + ASSERT_EQ(LATITUDE, testNode->getLat())<< "Node Latitude Check"; // longitude - ASSERT_EQ(LONGITUDE, testNode->dLon)<< "Node Longitude Check"; + ASSERT_EQ(LONGITUDE, testNode->getLon())<< "Node Longitude Check"; // depth - ASSERT_EQ(DEPTH, testNode->dZ)<< "Node Depth Check"; + ASSERT_EQ(DEPTH, testNode->getZ())<< "Node Depth Check"; // resolution - ASSERT_EQ(RESOLUTION, testNode->dResolution)<< "Node Resolution Check"; + ASSERT_EQ(RESOLUTION, testNode->getResolution())<< "Node Resolution Check"; // id - ASSERT_STREQ(std::string(NODEID).c_str(), testNode->sPid.c_str())<< + ASSERT_STREQ(std::string(NODEID).c_str(), testNode->getPid().c_str())<< "Node ID Matches"; // site list @@ -68,10 +68,11 @@ TEST(NodeTest, SiteOperations) { std::string(NODEID)); // create json object from the string - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); // construct sites using JSON objects - glasscore::CSite * testSite = new glasscore::CSite(&siteJSON, NULL); + glasscore::CSite * testSite = new glasscore::CSite(siteJSON, NULL); // create new shared pointer to the node std::shared_ptr sharedTestNode(testNode); diff --git a/glasscore/tests/pick_unittest.cpp b/glasscore/tests/pick_unittest.cpp index a9a46d77..e1cd9539 100644 --- a/glasscore/tests/pick_unittest.cpp +++ b/glasscore/tests/pick_unittest.cpp @@ -28,52 +28,52 @@ // check site data for validity void checkdata(glasscore::CPick * pickobject, const std::string &testinfo) { // check scnl - std::string sitescnl = pickobject->pSite->sScnl; + std::string sitescnl = pickobject->getSite()->getScnl(); std::string expectedscnl = std::string(SCNL); ASSERT_STREQ(sitescnl.c_str(), expectedscnl.c_str()); // check site - std::string sitesite = pickobject->pSite->sSite; + std::string sitesite = pickobject->getSite()->getSite(); std::string expectedsite = std::string(SITE); ASSERT_STREQ(sitesite.c_str(), expectedsite.c_str()); // check comp - std::string sitecomp = pickobject->pSite->sComp; + std::string sitecomp = pickobject->getSite()->getComp(); std::string expectedcomp = std::string(COMP); ASSERT_STREQ(sitecomp.c_str(), expectedcomp.c_str()); // check net - std::string sitenet = pickobject->pSite->sNet; + std::string sitenet = pickobject->getSite()->getNet(); std::string expectednet = std::string(NET); ASSERT_STREQ(sitenet.c_str(), expectednet.c_str()); // check loc - std::string siteloc = pickobject->pSite->sLoc; + std::string siteloc = pickobject->getSite()->getLoc(); std::string expectedloc = std::string(LOC); ASSERT_STREQ(siteloc.c_str(), expectedloc.c_str()); // check time - double picktime = pickobject->tPick; + double picktime = pickobject->getTPick(); double expectedtime = PICKTIME; ASSERT_NEAR(picktime, expectedtime, 0.0001); // check backazimuth - double beambackazimuth = pickobject->dBackAzimuth; + double beambackazimuth = pickobject->getBackAzimuth(); double expectedbackazimuth = BACKAZIMUTH; ASSERT_EQ(beambackazimuth, expectedbackazimuth); // check slowness - double beamslowness = pickobject->dSlowness; + double beamslowness = pickobject->getSlowness(); double expectedslowness = SLOWNESS; ASSERT_EQ(beamslowness, expectedslowness); // check id - int pickid = pickobject->idPick; + int pickid = pickobject->getIdPick(); double expectedpickid = PICKID; ASSERT_EQ(pickid, expectedpickid); // check string id - std::string pickstringid = pickobject->sPid; + std::string pickstringid = pickobject->getPid(); std::string expectedstringid = std::string(PICKIDSTRING); ASSERT_STREQ(pickstringid.c_str(), expectedstringid.c_str()); } @@ -86,23 +86,24 @@ TEST(PickTest, Construction) { glasscore::CPick * testPick = new glasscore::CPick(); // assert default values - ASSERT_EQ(0, testPick->tPick)<< "time is zero"; - ASSERT_EQ(-1, testPick->dBackAzimuth)<< "backazimuth is -1"; - ASSERT_EQ(-1, testPick->dSlowness)<< "slowness is -1"; - ASSERT_EQ(0, testPick->idPick)<< "id is zero"; - ASSERT_STREQ("", testPick->sAss.c_str()); - ASSERT_STREQ("", testPick->sPhs.c_str()); - ASSERT_STREQ("", testPick->sPid.c_str()); + ASSERT_EQ(0, testPick->getTPick())<< "time is zero"; + ASSERT_EQ(-1, testPick->getBackAzimuth())<< "backazimuth is -1"; + ASSERT_EQ(-1, testPick->getSlowness())<< "slowness is -1"; + ASSERT_EQ(0, testPick->getIdPick())<< "id is zero"; + ASSERT_STREQ("", testPick->getAss().c_str()); + ASSERT_STREQ("", testPick->getPhs().c_str()); + ASSERT_STREQ("", testPick->getPid().c_str()); // pointers - ASSERT_TRUE(testPick->pSite == NULL)<< "pSite null"; - ASSERT_TRUE(testPick->pHypo == NULL)<< "pHypo null"; - ASSERT_TRUE(testPick->jPick == NULL)<< "jPick null"; + ASSERT_TRUE(testPick->getSite() == NULL)<< "pSite null"; + ASSERT_TRUE(testPick->getHypo() == NULL)<< "pHypo null"; + ASSERT_TRUE(testPick->getJPick() == NULL)<< "jPick null"; // create shared pointer to the site - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); std::shared_ptr sharedTestSite( - new glasscore::CSite(&siteJSON, NULL)); + new glasscore::CSite(siteJSON, NULL)); // now init testPick->initialize(sharedTestSite, PICKTIME, PICKID, @@ -111,7 +112,7 @@ TEST(PickTest, Construction) { // check results checkdata(testPick, "initialize check"); - delete(testPick); + delete (testPick); } // tests to see if the pick can be constructed from JSON @@ -122,14 +123,17 @@ TEST(PickTest, JSONConstruction) { glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); // create json objects from the strings - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); // add site to site list - testSiteList->addSite(&siteJSON); + testSiteList->addSite(siteJSON); // construct a pick using a JSON object - json::Object pickJSON = json::Deserialize(std::string(PICKJSON)); - glasscore::CPick * testPick = new glasscore::CPick(&pickJSON, PICKID, + std::shared_ptr pickJSON = std::make_shared( + json::Object(json::Deserialize(std::string(PICKJSON)))); + + glasscore::CPick * testPick = new glasscore::CPick(pickJSON, PICKID, testSiteList); // check results @@ -141,9 +145,10 @@ TEST(PickTest, HypoOperations) { glassutil::CLogit::disable(); // create shared pointer to the site - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); std::shared_ptr sharedTestSite( - new glasscore::CSite(&siteJSON, NULL)); + new glasscore::CSite(siteJSON, NULL)); // create pick glasscore::CPick * testPick = new glasscore::CPick( @@ -152,11 +157,12 @@ TEST(PickTest, HypoOperations) { std::string(PICKIDSTRING), BACKAZIMUTH, SLOWNESS); // create a hypo - traveltime::CTravelTime* nullTrav = NULL; + std::shared_ptr nullTrav; + std::shared_ptr nullTTT; glasscore::CHypo * testHypo = new glasscore::CHypo(0.0, 0.0, 0.0, 0.0, "1", "test", 0.0, 0.0, 0, nullTrav, nullTrav, - NULL); + nullTTT); // create new shared pointer to the hypo std::shared_ptr sharedHypo(testHypo); @@ -165,11 +171,11 @@ TEST(PickTest, HypoOperations) { testPick->addHypo(sharedHypo); // check hypo - ASSERT_TRUE(testPick->pHypo != NULL)<< "pHypo not null"; + ASSERT_TRUE(testPick->getHypo() != NULL)<< "pHypo not null"; // remove hypo from pick testPick->remHypo(sharedHypo); // check hypo - ASSERT_TRUE(testPick->pHypo == NULL)<< "pHypo null"; + ASSERT_TRUE(testPick->getHypo() == NULL)<< "pHypo null"; } diff --git a/glasscore/tests/picklist_unittest.cpp b/glasscore/tests/picklist_unittest.cpp index 61f03850..cca7fb20 100644 --- a/glasscore/tests/picklist_unittest.cpp +++ b/glasscore/tests/picklist_unittest.cpp @@ -40,15 +40,15 @@ TEST(PickListTest, Construction) { glasscore::CPickList * testPickList = new glasscore::CPickList(); // assert default values - ASSERT_EQ(-1, testPickList->nPickTotal)<< "nPickTotal is 0"; - ASSERT_EQ(0, testPickList->nPick)<< "nPick is 0"; + ASSERT_EQ(-1, testPickList->getNPickTotal())<< "nPickTotal is 0"; + ASSERT_EQ(0, testPickList->getNPick())<< "nPick is 0"; // lists - ASSERT_EQ(0, testPickList->vPick.size())<< "vPick.size() is 0"; - ASSERT_EQ(0, testPickList->mPick.size())<< "mPick.size() is 0"; + ASSERT_EQ(0, testPickList->getVPickSize())<< "getVPickSize() is 0"; // pointers - ASSERT_EQ(NULL, testPickList->pGlass)<< "pGlass null"; + ASSERT_EQ(NULL, testPickList->getGlass())<< "pGlass null"; + ASSERT_EQ(NULL, testPickList->getSiteList())<< "pSiteList null"; // cleanup delete (testPickList); @@ -59,81 +59,90 @@ TEST(PickListTest, PickOperations) { glassutil::CLogit::disable(); // create json objects from the strings - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); - json::Object site2JSON = json::Deserialize(std::string(SITE2JSON)); - json::Object site3JSON = json::Deserialize(std::string(SITE3JSON)); - - json::Object pickJSON = json::Deserialize(std::string(PICKJSON)); - json::Object pick2JSON = json::Deserialize(std::string(PICK2JSON)); - json::Object pick3JSON = json::Deserialize(std::string(PICK3JSON)); - json::Object pick4JSON = json::Deserialize(std::string(PICK4JSON)); - json::Object pick5JSON = json::Deserialize(std::string(PICK5JSON)); - json::Object pick6JSON = json::Deserialize(std::string(PICK6JSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); + std::shared_ptr site2JSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITE2JSON)))); + std::shared_ptr site3JSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITE3JSON)))); + + std::shared_ptr pickJSON = std::make_shared( + json::Object(json::Deserialize(std::string(PICKJSON)))); + std::shared_ptr pick2JSON = std::make_shared( + json::Object(json::Deserialize(std::string(PICK2JSON)))); + std::shared_ptr pick3JSON = std::make_shared( + json::Object(json::Deserialize(std::string(PICK3JSON)))); + std::shared_ptr pick4JSON = std::make_shared( + json::Object(json::Deserialize(std::string(PICK4JSON)))); + std::shared_ptr pick5JSON = std::make_shared( + json::Object(json::Deserialize(std::string(PICK5JSON)))); + std::shared_ptr pick6JSON = std::make_shared( + json::Object(json::Deserialize(std::string(PICK6JSON)))); // construct a sitelist glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); // add sites to site list - testSiteList->addSite(&siteJSON); - testSiteList->addSite(&site2JSON); - testSiteList->addSite(&site3JSON); + testSiteList->addSite(siteJSON); + testSiteList->addSite(site2JSON); + testSiteList->addSite(site3JSON); // construct a picklist glasscore::CPickList * testPickList = new glasscore::CPickList(); - testPickList->pSiteList = testSiteList; - testPickList->nPickMax = MAXNPICK; + testPickList->setSiteList(testSiteList); + testPickList->setNPickMax(MAXNPICK); // test indexpick when empty ASSERT_EQ(-2, testPickList->indexPick(0))<< "test indexpick when empty"; // test adding picks by addPick and dispatch - testPickList->addPick(&pickJSON); - testPickList->dispatch(&pick3JSON); + testPickList->addPick(pickJSON); + testPickList->dispatch(pick3JSON); int expectedSize = 2; - ASSERT_EQ(expectedSize, testPickList->nPick)<< "Added Picks"; + ASSERT_EQ(expectedSize, testPickList->getNPick())<< "Added Picks"; // test getting a pick (first pick, id 1) std::shared_ptr testPick = testPickList->getPick(1); // check testpick ASSERT_TRUE(testPick != NULL)<< "testPick not null"; // check scnl - std::string sitescnl = testPick->pSite->sScnl; + std::string sitescnl = testPick->getSite()->getScnl(); std::string expectedscnl = std::string(SCNL); ASSERT_STREQ(sitescnl.c_str(), expectedscnl.c_str())<< - "testPick has right scnl"; + "testPick has right scnl"; // test indexpick ASSERT_EQ(-1, testPickList->indexPick(TPICK))<< - "test indexpick with time before"; + "test indexpick with time before"; ASSERT_EQ(1, testPickList->indexPick(TPICK2))<< - "test indexpick with time after"; + "test indexpick with time after"; ASSERT_EQ(0, testPickList->indexPick(TPICK3))<< - "test indexpick with time within"; + "test indexpick with time within"; // add more picks - testPickList->addPick(&pick2JSON); - testPickList->addPick(&pick4JSON); - testPickList->addPick(&pick5JSON); - testPickList->addPick(&pick6JSON); + testPickList->addPick(pick2JSON); + testPickList->addPick(pick4JSON); + testPickList->addPick(pick5JSON); + testPickList->addPick(pick6JSON); // check to make sure the size isn't any larger than our max expectedSize = MAXNPICK; - ASSERT_EQ(expectedSize, testPickList->vPick.size())<< - "testPickList not larger than max"; + ASSERT_EQ(expectedSize, testPickList->getVPickSize())<< + "testPickList not larger than max"; // get first pick, which is now id 2 std::shared_ptr test2Pick = testPickList->getPick(2); // check scnl - sitescnl = test2Pick->pSite->sScnl; + sitescnl = test2Pick->getSite()->getScnl(); expectedscnl = std::string(SCNL2); ASSERT_STREQ(sitescnl.c_str(), expectedscnl.c_str())<< - "test2Pick has right scnl"; + "test2Pick has right scnl"; // test clearing picks testPickList->clearPicks(); expectedSize = 0; - ASSERT_EQ(expectedSize, testPickList->nPick)<< "Cleared Picks"; + ASSERT_EQ(expectedSize, testPickList->getNPick())<< "Cleared Picks"; // cleanup delete (testPickList); diff --git a/glasscore/tests/site_unittest.cpp b/glasscore/tests/site_unittest.cpp index 0e8937d9..a16ba8c6 100644 --- a/glasscore/tests/site_unittest.cpp +++ b/glasscore/tests/site_unittest.cpp @@ -33,61 +33,61 @@ // check site data for validity void checkdata(glasscore::CSite * siteobject, const std::string &testinfo) { // check scnl - std::string sitescnl = siteobject->sScnl; + std::string sitescnl = siteobject->getScnl(); std::string expectedscnl = std::string(SCNL); ASSERT_STREQ(sitescnl.c_str(), expectedscnl.c_str()); // check site - std::string sitesite = siteobject->sSite; + std::string sitesite = siteobject->getSite(); std::string expectedsite = std::string(SITE); ASSERT_STREQ(sitesite.c_str(), expectedsite.c_str()); // check comp - std::string sitecomp = siteobject->sComp; + std::string sitecomp = siteobject->getComp(); std::string expectedcomp = std::string(COMP); ASSERT_STREQ(sitecomp.c_str(), expectedcomp.c_str()); // check net - std::string sitenet = siteobject->sNet; + std::string sitenet = siteobject->getNet(); std::string expectednet = std::string(NET); ASSERT_STREQ(sitenet.c_str(), expectednet.c_str()); // check loc - std::string siteloc = siteobject->sLoc; + std::string siteloc = siteobject->getLoc(); std::string expectedloc = std::string(LOC); ASSERT_STREQ(siteloc.c_str(), expectedloc.c_str()); // check latitude - double sitelatitude = siteobject->geo.dLat; + double sitelatitude = siteobject->getGeo().dLat; // NOTE: expected latitude is in geocentric coordinates double expectedlatitude = GEOCENTRIC_LATITUDE; ASSERT_NEAR(sitelatitude, expectedlatitude, 0.000001); // check longitude - double sitelongitude = siteobject->geo.dLon; + double sitelongitude = siteobject->getGeo().dLon; // NOTE: expected longitude is the same in geocentric and geographic // coordinates double expectedlongitude = LONGITUDE; ASSERT_NEAR(sitelongitude, expectedlongitude, 0.000001); // check elevation - double siteelevation = siteobject->geo.dZ; + double siteelevation = siteobject->getGeo().dZ; // NOTE: expected elevation is in geocentric coordinates double expectedelevation = GEOCENTRID_ELEVATION; ASSERT_NEAR(siteelevation, expectedelevation, 0.000001); // check use - bool siteuse = siteobject->bUse; + bool siteuse = siteobject->getUse(); bool expecteduse = USE; ASSERT_EQ(siteuse, expecteduse); // check useforTele - bool siteusefortele = siteobject->bUseForTele; + bool siteusefortele = siteobject->getUseForTele(); bool expectedusefortele = USEFORTELE; ASSERT_EQ(siteusefortele, expectedusefortele); // check qual - double sitequal = siteobject->dQual; + double sitequal = siteobject->getQual(); double expectedqual = QUALITY; ASSERT_NEAR(sitequal, expectedqual, 0.000001); } @@ -101,34 +101,27 @@ TEST(SiteTest, Construction) { // assert default values // scnl - ASSERT_STREQ("", testSite->sScnl.c_str())<< "sScnl Empty"; - ASSERT_STREQ("", testSite->sSite.c_str())<< "sSite Empty"; - ASSERT_STREQ("", testSite->sComp.c_str())<< "sComp Empty"; - ASSERT_STREQ("", testSite->sNet.c_str())<< "sNet Empty"; - ASSERT_STREQ("", testSite->sLoc.c_str())<< "sLoc Empty"; + ASSERT_STREQ("", testSite->getScnl().c_str())<< "sScnl Empty"; + ASSERT_STREQ("", testSite->getSite().c_str())<< "sSite Empty"; + ASSERT_STREQ("", testSite->getComp().c_str())<< "sComp Empty"; + ASSERT_STREQ("", testSite->getNet().c_str())<< "sNet Empty"; + ASSERT_STREQ("", testSite->getLoc().c_str())<< "sLoc Empty"; - ASSERT_EQ(true, testSite->bUse)<< "bUse false"; - ASSERT_EQ(true, testSite->bUseForTele)<< "bUseForTele false"; - ASSERT_EQ(0, testSite->dTrav)<< "dTrav zero"; - ASSERT_EQ(1, testSite->dQual)<< "dQual one"; + ASSERT_EQ(true, testSite->getUse())<< "bUse false"; + ASSERT_EQ(true, testSite->getUseForTele())<< "bUseForTele false"; + ASSERT_EQ(1, testSite->getQual())<< "dQual one"; // pointers - ASSERT_EQ(NULL, testSite->pGlass)<< "pGlass null"; - ASSERT_EQ(NULL, testSite->pNode.get())<< "pNode null"; - ASSERT_EQ(NULL, testSite->qNode.get())<< "qNode null"; + ASSERT_EQ(NULL, testSite->getGlass())<< "pGlass null"; // geographic - ASSERT_EQ(0, testSite->geo.dLat)<< "geo.dLat 0"; - ASSERT_EQ(0, testSite->geo.dLon)<< "geo.dLon 0"; - ASSERT_EQ(0, testSite->geo.dZ)<< "geo.dZ 0"; - ASSERT_EQ(0, testSite->dVec[0])<< "dVec[0] 0"; - ASSERT_EQ(0, testSite->dVec[1])<< "dVec[1] 0"; - ASSERT_EQ(0, testSite->dVec[2])<< "dVec[2] 0"; + ASSERT_EQ(0, testSite->getGeo().dLat)<< "geo.dLat 0"; + ASSERT_EQ(0, testSite->getGeo().dLon)<< "geo.dLon 0"; + ASSERT_EQ(0, testSite->getGeo().dZ)<< "geo.dZ 0"; // lists ASSERT_EQ(0, testSite->getNodeLinksCount())<< "vNode.size() 0"; - ASSERT_EQ(0, testSite->vPick.size())<< "vPick.size() 0"; - ASSERT_EQ(0, testSite->vTrigger.size())<< "vTrigger.size() 0"; + ASSERT_EQ(0, testSite->getVPick().size())<< "vPick.size() 0"; // now init testSite->initialize(std::string(SITE), std::string(COMP), std::string(NET), @@ -150,10 +143,11 @@ TEST(SiteTest, JSONConstruction) { glassutil::CLogit::disable(); // create a json object from the string - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); // construct a site using a JSON object - glasscore::CSite * testSite = new glasscore::CSite(&siteJSON, NULL); + glasscore::CSite * testSite = new glasscore::CSite(siteJSON, NULL); // check results checkdata(testSite, "json construction check"); @@ -167,12 +161,14 @@ TEST(SiteTest, Distance) { glassutil::CLogit::disable(); // create json objects from the strings - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); - json::Object site2JSON = json::Deserialize(std::string(SITE2JSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); + std::shared_ptr site2JSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITE2JSON)))); // construct sites using JSON objects - glasscore::CSite * testSite = new glasscore::CSite(&siteJSON, NULL); - glasscore::CSite * testSite2 = new glasscore::CSite(&site2JSON, NULL); + glasscore::CSite * testSite = new glasscore::CSite(siteJSON, NULL); + glasscore::CSite * testSite2 = new glasscore::CSite(site2JSON, NULL); // create new shared pointer to the site std::shared_ptr sharedTestSite2(testSite2); @@ -183,7 +179,7 @@ TEST(SiteTest, Distance) { // test getDelta double expectedDelta = SITE2DELTA; - ASSERT_DOUBLE_EQ(expectedDelta, testSite->getDelta(&testSite2->geo)); + ASSERT_DOUBLE_EQ(expectedDelta, testSite->getDelta(&testSite2->getGeo())); } // tests to see if picks can be added to and removed from the site @@ -191,16 +187,17 @@ TEST(SiteTest, PickOperations) { glassutil::CLogit::disable(); // create a json object from the string - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); - json::Object site2JSON = json::Deserialize(std::string(SITE2JSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); + std::shared_ptr site2JSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITE2JSON)))); // construct a site using a JSON object - glasscore::CSite * testSite = new glasscore::CSite(&siteJSON, NULL); - glasscore::CSite * testSite2 = new glasscore::CSite(&site2JSON, NULL); - - // create new shared pointers to the sites - std::shared_ptr sharedTestSite(testSite); - std::shared_ptr sharedTestSite2(testSite2); + glasscore::CSite * testSite = new glasscore::CSite(siteJSON, NULL); + std::shared_ptr sharedTestSite( + new glasscore::CSite(siteJSON, NULL)); + std::shared_ptr sharedTestSite2( + new glasscore::CSite(site2JSON, NULL)); // create pick objects glasscore::CPick * testPick = new glasscore::CPick(sharedTestSite, 10.0, 1, @@ -215,17 +212,17 @@ TEST(SiteTest, PickOperations) { // test adding pick to site testSite->addPick(sharedTestPick); int expectedSize = 1; - ASSERT_EQ(expectedSize, testSite->vPick.size())<< "Added Pick"; + ASSERT_EQ(expectedSize, testSite->getVPick().size())<< "Added Pick"; // test adding pick from different station testSite->addPick(sharedTestPick2); - ASSERT_EQ(expectedSize, testSite->vPick.size())<< - "Added pick from different station"; + ASSERT_EQ(expectedSize, testSite->getVPick().size())<< + "Added pick from different station"; // test removing pick testSite->remPick(sharedTestPick); expectedSize = 0; - ASSERT_EQ(expectedSize, testSite->vPick.size())<< "Removed pick"; + ASSERT_EQ(expectedSize, testSite->getVPick().size())<< "Removed pick"; } // tests to see if nodes can be added to and removed from the site @@ -233,10 +230,11 @@ TEST(SiteTest, NodeOperations) { glassutil::CLogit::disable(); // create a json object from the string - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); // construct a site using a JSON object - glasscore::CSite * testSite = new glasscore::CSite(&siteJSON, NULL); + glasscore::CSite * testSite = new glasscore::CSite(siteJSON, NULL); // create node objects glasscore::CNode * testNode = new glasscore::CNode("test", 0.0, 0.0, 10, @@ -255,7 +253,7 @@ TEST(SiteTest, NodeOperations) { ASSERT_EQ(expectedSize, testSite->getNodeLinksCount())<< "Added Nodes"; // test removing nodes from site - testSite->remNode(testNode->sPid); + testSite->remNode(testNode->getPid()); expectedSize = 1; ASSERT_EQ(expectedSize, testSite->getNodeLinksCount())<< "Removed Node"; } diff --git a/glasscore/tests/sitelist_unittest.cpp b/glasscore/tests/sitelist_unittest.cpp index 49026eb8..5ca8fad4 100644 --- a/glasscore/tests/sitelist_unittest.cpp +++ b/glasscore/tests/sitelist_unittest.cpp @@ -20,11 +20,10 @@ TEST(SiteListTest, Construction) { // assert default values // lists - ASSERT_EQ(0, testSiteList->vSite.size())<< "vSite is empty"; - ASSERT_EQ(0, testSiteList->mSite.size())<< "mSite.size() 0"; + ASSERT_EQ(0, testSiteList->getVSiteSize())<< "vSite is empty"; // pointers - ASSERT_EQ(NULL, testSiteList->pGlass)<< "pGlass null"; + ASSERT_EQ(NULL, testSiteList->getGlass())<< "pGlass null"; // cleanup delete (testSiteList); @@ -38,36 +37,38 @@ TEST(SiteListTest, SiteOperations) { glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); // create json objects from the strings - json::Object siteJSON = json::Deserialize(std::string(SITEJSON)); - json::Object site2JSON = json::Deserialize(std::string(SITE2JSON)); - json::Object site3JSON = json::Deserialize(std::string(SITE3JSON)); - json::Object site4JSON = json::Deserialize(std::string(SITE4JSON)); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); + std::shared_ptr site2JSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITE2JSON)))); + std::shared_ptr site3JSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITE3JSON)))); + std::shared_ptr site4JSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITE4JSON)))); // construct sites using JSON objects - glasscore::CSite * testSite = new glasscore::CSite(&siteJSON, NULL); - glasscore::CSite * testSite2 = new glasscore::CSite(&site2JSON, NULL); - glasscore::CSite * testSite3 = new glasscore::CSite(&site3JSON, NULL); - glasscore::CSite * testSite4 = new glasscore::CSite(&site4JSON, NULL); + glasscore::CSite * testSite = new glasscore::CSite(siteJSON, NULL); + glasscore::CSite * testSite4 = new glasscore::CSite(site4JSON, NULL); + // create new shared pointer to the sites std::shared_ptr sharedTestSite(testSite); - std::shared_ptr sharedTestSite2(testSite2); - std::shared_ptr sharedTestSite3(testSite3); std::shared_ptr sharedTestSite4(testSite4); // test adding sites to site list via all three methods // shared_ptr, json, and dispatch (also json) testSiteList->addSite(sharedTestSite); - testSiteList->addSite(&site2JSON); - testSiteList->dispatch(&site3JSON); + testSiteList->addSite(site2JSON); + testSiteList->dispatch(site3JSON); int expectedSize = 3; ASSERT_EQ(expectedSize, testSiteList->getSiteCount())<< "Added Sites"; + // test updating a site, and get site testSiteList->addSite(sharedTestSite4); std::shared_ptr updatedSite = testSiteList->getSite( - sharedTestSite4->sScnl); - ASSERT_FALSE(updatedSite->bUse)<< "Updated site"; + sharedTestSite4->getScnl()); + ASSERT_FALSE(updatedSite->getUse())<< "Updated site"; // cleanup delete (testSiteList); diff --git a/glasscore/tests/trigger_unittest.cpp b/glasscore/tests/trigger_unittest.cpp new file mode 100644 index 00000000..30a8385d --- /dev/null +++ b/glasscore/tests/trigger_unittest.cpp @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include "Trigger.h" +#include "Web.h" +#include "Pick.h" +#include "Site.h" +#include "SiteList.h" +#include "Logit.h" + +#define LATITUDE -21.849968 +#define LONGITUDE 170.034750 +#define DEPTH 10.000000 +#define TIME 3648585210.926340 +#define SUM 3.5 +#define COUNT 1 + +#define SITEJSON "{\"Type\":\"StationInfo\",\"Elevation\":2326.000000,\"Latitude\":45.822170,\"Longitude\":-112.451000,\"Site\":{\"Station\":\"LRM\",\"Channel\":\"EHZ\",\"Network\":\"MB\",\"Location\":\"\"},\"Enable\":true,\"Quality\":1.0,\"UseForTeleseismic\":true}" // NOLINT + +#define PICKJSON "{\"ID\":\"20682831\",\"Phase\":\"P\",\"Polarity\":\"up\",\"Site\":{\"Channel\":\"EHZ\",\"Location\":\"\",\"Network\":\"MB\",\"Station\":\"LRM\"},\"Source\":{\"AgencyID\":\"228041013\",\"Author\":\"228041013\"},\"Time\":\"2014-12-23T00:01:43.599Z\",\"Type\":\"Pick\"}" // NOLINT + +#define NAME "TestWeb" +#define THRESH 1.4 +#define NUMDETECT 5 +#define NUMNUCLEATE 4 +#define RESOLUTION 100.0 +#define NUMROWS 3 +#define NUMCOLS 4 +#define NUMZ 1 +#define UPDATE true + +// tests to see if the node can be constructed +TEST(TriggerTest, Construction) { + glassutil::CLogit::disable(); + + // construct a web + std::shared_ptr nullTrav; + glasscore::CWeb * testWeb = new glasscore::CWeb(std::string(NAME), + THRESH, + NUMDETECT, + NUMNUCLEATE, + RESOLUTION, + NUMROWS, + NUMCOLS, NUMZ, + UPDATE, + nullTrav, nullTrav); + + // create shared pointer to the site + // create json objects from the strings + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(SITEJSON)))); + std::shared_ptr pickJSON = std::make_shared( + json::Object(json::Deserialize(std::string(PICKJSON)))); + + // construct a sitelist + glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); + + // add sites to site list + testSiteList->addSite(siteJSON); + + // create pick + glasscore::CPick * testPick = new glasscore::CPick(pickJSON, 1, + testSiteList); + + std::shared_ptr sharedPick(testPick); + + // create pick vector + std::vector> picks; + picks.push_back(sharedPick); + + // construct a trigger + glasscore::CTrigger * testTrigger = new glasscore::CTrigger(); + + // latitude + ASSERT_EQ(0, testTrigger->getLat())<< "Trigger Latitude 0"; + + // longitude + ASSERT_EQ(0, testTrigger->getLon())<< "Trigger Longitude 0"; + + // depth + ASSERT_EQ(0, testTrigger->getZ())<< "Trigger Depth 0"; + + // time + ASSERT_EQ(0, testTrigger->getTOrg())<< "Trigger Time 0"; + + // resolution + ASSERT_EQ(0, testTrigger->getResolution())<< "Trigger Resolution 0"; + + // Sum + ASSERT_EQ(0, testTrigger->getSum())<< "Trigger Sum 0"; + + // Count + ASSERT_EQ(0, testTrigger->getCount())<< "Trigger Count 0"; + + // web + ASSERT_TRUE(testTrigger->getWeb() == NULL)<< "PWeb null"; + + // pick list + ASSERT_EQ(0, testTrigger->getVPick().size())<< "Trigger pick Count 0"; + + // init + testTrigger->initialize(LATITUDE, + LONGITUDE, + DEPTH, + TIME, + RESOLUTION, + SUM, + COUNT, picks, testWeb); + + // latitude + ASSERT_EQ(LATITUDE, testTrigger->getLat())<< "Trigger Latitude Check"; + + // longitude + ASSERT_EQ(LONGITUDE, testTrigger->getLon())<< "Trigger Longitude Check"; + + // depth + ASSERT_EQ(DEPTH, testTrigger->getZ())<< "Trigger Depth Check"; + + // time + ASSERT_EQ(TIME, testTrigger->getTOrg())<< "Trigger Time Check"; + + // resolution + ASSERT_EQ(RESOLUTION, testTrigger->getResolution())<< "Trigger Resolution " + "Check"; + + // Sum + ASSERT_EQ(SUM, testTrigger->getSum())<< "Trigger Sum Check"; + + // Count + ASSERT_EQ(COUNT, testTrigger->getCount())<< "Trigger Count Check"; + + // web + ASSERT_STREQ(std::string(NAME).c_str(), + testTrigger->getWeb()->getName().c_str())<< + "Trigger Web Name Matches"; + + // pick list + ASSERT_EQ(COUNT, testTrigger->getVPick().size())<< "Trigger pick Count " + "Check"; + + // clear + testTrigger->clear(); + + // latitude + ASSERT_EQ(0, testTrigger->getLat())<< "Trigger Latitude 0"; + + // longitude + ASSERT_EQ(0, testTrigger->getLon())<< "Trigger Longitude 0"; + + // depth + ASSERT_EQ(0, testTrigger->getZ())<< "Trigger Depth 0"; + + // time + ASSERT_EQ(0, testTrigger->getTOrg())<< "Trigger Time 0"; + + // resolution + ASSERT_EQ(0, testTrigger->getResolution())<< "Trigger Resolution 0"; + + // Sum + ASSERT_EQ(0, testTrigger->getSum())<< "Trigger Sum 0"; + + // Count + ASSERT_EQ(0, testTrigger->getCount())<< "Trigger Count 0"; + + // web + ASSERT_TRUE(testTrigger->getWeb() == NULL)<< "PWeb null"; + + // pick list + ASSERT_EQ(0, testTrigger->getVPick().size())<< "Trigger pick Count 0"; +} diff --git a/glasscore/tests/web_unittest.cpp b/glasscore/tests/web_unittest.cpp index f7ea26dd..5cd67c43 100644 --- a/glasscore/tests/web_unittest.cpp +++ b/glasscore/tests/web_unittest.cpp @@ -92,43 +92,43 @@ TEST(WebTest, Construction) { nullTrav, nullTrav); // name - ASSERT_STREQ(std::string(NAME).c_str(), testWeb->sName.c_str())<< - "Web sName Matches"; + ASSERT_STREQ(std::string(NAME).c_str(), testWeb->getName().c_str())<< + "Web getName() Matches"; // threshold - ASSERT_EQ(THRESH, testWeb->dThresh)<< "Web dThresh Check"; + ASSERT_EQ(THRESH, testWeb->getThresh())<< "Web getThresh() Check"; - // nDetect - ASSERT_EQ(NUMDETECT, testWeb->nDetect)<< "Web nDetect Check"; + // getDetect() + ASSERT_EQ(NUMDETECT, testWeb->getDetect())<< "Web getDetect() Check"; - // nNucleate - ASSERT_EQ(NUMNUCLEATE, testWeb->nNucleate)<< "Web nNucleate Check"; + // getNucleate() + ASSERT_EQ(NUMNUCLEATE, testWeb->getNucleate())<< "Web getNucleate() Check"; // resolution - ASSERT_EQ(RESOLUTION, testWeb->dResolution)<< "Web resolution Check"; + ASSERT_EQ(RESOLUTION, testWeb->getResolution())<< "Web resolution Check"; - // nRow - ASSERT_EQ(NUMROWS, testWeb->nRow)<< "Web nRow Check"; + // getRow() + ASSERT_EQ(NUMROWS, testWeb->getRow())<< "Web getRow() Check"; - // nCol - ASSERT_EQ(NUMCOLS, testWeb->nCol)<< "Web nCol Check"; + // getCol() + ASSERT_EQ(NUMCOLS, testWeb->getCol())<< "Web getCol() Check"; - // nZ - ASSERT_EQ(NUMZ, testWeb->nZ)<< "Web nZ Check"; + // getZ() + ASSERT_EQ(NUMZ, testWeb->getZ())<< "Web getZ() Check"; - // bUpdate - ASSERT_EQ(UPDATE, testWeb->bUpdate)<< "Web bUpdate Check"; + // getUpdate() + ASSERT_EQ(UPDATE, testWeb->getUpdate())<< "Web getUpdate() Check"; // lists int expectedSize = 0; - ASSERT_EQ(expectedSize, (int)testWeb->vNode.size())<< "node list empty"; - ASSERT_EQ(expectedSize, (int)testWeb->vSitesFilter.size())<< + ASSERT_EQ(expectedSize, (int)testWeb->getVNodeSize())<< "node list empty"; + ASSERT_EQ(expectedSize, (int)testWeb->getVSitesFilterSize())<< "site filter list empty"; - ASSERT_EQ(expectedSize, (int)testWeb->vNetFilter.size())<< + ASSERT_EQ(expectedSize, (int)testWeb->getVNetFilterSize())<< "net filter list empty"; // pointers - ASSERT_EQ(NULL, testWeb->pGlass)<< "pGlass null"; + ASSERT_EQ(NULL, testWeb->getGlass())<< "getGlass() null"; // construct a web glasscore::CWeb * testWeb2 = new glasscore::CWeb(std::string(NAME), @@ -142,42 +142,42 @@ TEST(WebTest, Construction) { nullTrav, nullTrav); // name - ASSERT_STREQ(std::string(NAME).c_str(), testWeb2->sName.c_str())<< - "Web sName Matches"; + ASSERT_STREQ(std::string(NAME).c_str(), testWeb2->getName().c_str())<< + "Web getName() Matches"; // threshold - ASSERT_EQ(THRESH, testWeb2->dThresh)<< "Web dThresh Check"; + ASSERT_EQ(THRESH, testWeb2->getThresh())<< "Web getThresh() Check"; - // nDetect - ASSERT_EQ(NUMDETECT, testWeb2->nDetect)<< "Web nDetect Check"; + // getDetect() + ASSERT_EQ(NUMDETECT, testWeb2->getDetect())<< "Web getDetect() Check"; - // nNucleate - ASSERT_EQ(NUMNUCLEATE, testWeb2->nNucleate)<< "Web nNucleate Check"; + // getNucleate() + ASSERT_EQ(NUMNUCLEATE, testWeb2->getNucleate())<< "Web getNucleate() Check"; // resolution - ASSERT_EQ(RESOLUTION, testWeb2->dResolution)<< "Web resolution Check"; + ASSERT_EQ(RESOLUTION, testWeb2->getResolution())<< "Web resolution Check"; - // nRow - ASSERT_EQ(NUMROWS, testWeb2->nRow)<< "Web nRow Check"; + // getRow() + ASSERT_EQ(NUMROWS, testWeb2->getRow())<< "Web getRow() Check"; - // nCol - ASSERT_EQ(NUMCOLS, testWeb2->nCol)<< "Web nCol Check"; + // getCol() + ASSERT_EQ(NUMCOLS, testWeb2->getCol())<< "Web getCol() Check"; - // nZ - ASSERT_EQ(NUMZ, testWeb2->nZ)<< "Web nZ Check"; + // getZ() + ASSERT_EQ(NUMZ, testWeb2->getZ())<< "Web getZ() Check"; - // bUpdate - ASSERT_EQ(NOUPDATE, testWeb2->bUpdate)<< "Web bUpdate Check"; + // getUpdate() + ASSERT_EQ(NOUPDATE, testWeb2->getUpdate())<< "Web getUpdate() Check"; // lists - ASSERT_EQ(expectedSize, (int)testWeb2->vNode.size())<< "node list empty"; - ASSERT_EQ(expectedSize, (int)testWeb2->vSitesFilter.size())<< + ASSERT_EQ(expectedSize, (int)testWeb2->getVNodeSize())<< "node list empty"; + ASSERT_EQ(expectedSize, (int)testWeb2->getVSitesFilterSize())<< "site filter list empty"; - ASSERT_EQ(expectedSize, (int)testWeb2->vNetFilter.size())<< + ASSERT_EQ(expectedSize, (int)testWeb2->getVNetFilterSize())<< "net filter list empty"; // pointers - ASSERT_EQ(NULL, testWeb2->pGlass)<< "pGlass null"; + ASSERT_EQ(NULL, testWeb2->getGlass())<< "getGlass() null"; delete (testWeb); delete (testWeb2); @@ -202,39 +202,39 @@ TEST(WebTest, Initialize) { nullTrav, nullTrav); // name - ASSERT_STREQ(std::string(NAME).c_str(), testWeb.sName.c_str())<< - "Web sName Matches"; + ASSERT_STREQ(std::string(NAME).c_str(), testWeb.getName().c_str())<< + "Web getName() Matches"; // threshold - ASSERT_EQ(THRESH, testWeb.dThresh)<< "Web dThresh Check"; + ASSERT_EQ(THRESH, testWeb.getThresh())<< "Web getThresh() Check"; - // nDetect - ASSERT_EQ(NUMDETECT, testWeb.nDetect)<< "Web nDetect Check"; + // getDetect() + ASSERT_EQ(NUMDETECT, testWeb.getDetect())<< "Web getDetect() Check"; - // nNucleate - ASSERT_EQ(NUMNUCLEATE, testWeb.nNucleate)<< "Web nNucleate Check"; + // getNucleate() + ASSERT_EQ(NUMNUCLEATE, testWeb.getNucleate())<< "Web getNucleate() Check"; // resolution - ASSERT_EQ(RESOLUTION, testWeb.dResolution)<< "Web resolution Check"; + ASSERT_EQ(RESOLUTION, testWeb.getResolution())<< "Web resolution Check"; - // nRow - ASSERT_EQ(NUMROWS, testWeb.nRow)<< "Web nRow Check"; + // getRow() + ASSERT_EQ(NUMROWS, testWeb.getRow())<< "Web getRow() Check"; - // nCol - ASSERT_EQ(NUMCOLS, testWeb.nCol)<< "Web nCol Check"; + // getCol() + ASSERT_EQ(NUMCOLS, testWeb.getCol())<< "Web getCol() Check"; - // nZ - ASSERT_EQ(NUMZ, testWeb.nZ)<< "Web nZ Check"; + // getZ() + ASSERT_EQ(NUMZ, testWeb.getZ())<< "Web getZ() Check"; - // bUpdate - ASSERT_EQ(UPDATE, testWeb.bUpdate)<< "Web bUpdate Check"; + // getUpdate() + ASSERT_EQ(UPDATE, testWeb.getUpdate())<< "Web getUpdate() Check"; // lists int expectedSize = 0; - ASSERT_EQ(expectedSize, (int)testWeb.vNode.size())<< "node list empty"; - ASSERT_EQ(expectedSize, (int)testWeb.vSitesFilter.size())<< + ASSERT_EQ(expectedSize, (int)testWeb.getVNodeSize())<< "node list empty"; + ASSERT_EQ(expectedSize, (int)testWeb.getVSitesFilterSize())<< "site filter list empty"; - ASSERT_EQ(expectedSize, (int)testWeb.vNetFilter.size())<< + ASSERT_EQ(expectedSize, (int)testWeb.getVNetFilterSize())<< "net filter list empty"; ASSERT_TRUE(testWeb.statusCheck())<< "status check"; @@ -266,64 +266,70 @@ TEST(WebTest, GlobalTest) { std::getline(globalFile, globalLine); globalFile.close(); - json::Object siteList = json::Deserialize(stationLine); - json::Object globalConfig = json::Deserialize(globalLine); + std::shared_ptr siteList = std::make_shared( + json::Deserialize(stationLine)); + std::shared_ptr globalConfig = std::make_shared( + json::Deserialize(globalLine)); // construct a sitelist glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); - testSiteList->dispatch(&siteList); + testSiteList->dispatch(siteList); // construct a web glasscore::CWeb testGlobalWeb(UPDATE); - testGlobalWeb.pSiteList = testSiteList; - testGlobalWeb.dispatch(&globalConfig); + testGlobalWeb.setSiteList(testSiteList); + testGlobalWeb.dispatch(globalConfig); // name - ASSERT_STREQ(std::string(GLOBALNAME).c_str(), testGlobalWeb.sName.c_str())<< - "Web sName Matches"; + ASSERT_STREQ(std::string(GLOBALNAME).c_str(), + testGlobalWeb.getName().c_str())<< + "Web getName() Matches"; // threshold - ASSERT_EQ(GLOBALTHRESH, testGlobalWeb.dThresh)<< "Web dThresh Check"; + ASSERT_EQ(GLOBALTHRESH, testGlobalWeb.getThresh())<< + "Web getThresh() Check"; - // nDetect - ASSERT_EQ(GLOBALNUMDETECT, testGlobalWeb.nDetect)<< "Web nDetect Check"; + // getDetect() + ASSERT_EQ(GLOBALNUMDETECT, testGlobalWeb.getDetect())<< + "Web getDetect() Check"; - // nNucleate - ASSERT_EQ(GLOBALNUMNUCLEATE, testGlobalWeb.nNucleate)<< "Web nNucleate Check"; + // getNucleate() + ASSERT_EQ(GLOBALNUMNUCLEATE, testGlobalWeb.getNucleate())<< + "Web getNucleate() Check"; - // dResolution - ASSERT_EQ(GLOBALRESOLUTION, testGlobalWeb.dResolution)<< "Web dResolution " - "Check"; + // getResolution() + ASSERT_EQ(GLOBALRESOLUTION, testGlobalWeb.getResolution())<< + "Web getResolution() Check"; - // nRow - ASSERT_EQ(0, testGlobalWeb.nRow)<< "Web nRow Check"; + // getRow() + ASSERT_EQ(0, testGlobalWeb.getRow())<< "Web getRow() Check"; - // nCol - ASSERT_EQ(0, testGlobalWeb.nCol)<< "Web nCol Check"; + // getCol() + ASSERT_EQ(0, testGlobalWeb.getCol())<< "Web getCol() Check"; - // nCol - ASSERT_EQ(GLOBALNUMZ, testGlobalWeb.nZ)<< "Web nZ Check"; + // getCol() + ASSERT_EQ(GLOBALNUMZ, testGlobalWeb.getZ())<< "Web getZ() Check"; - // bUpdate - ASSERT_EQ(UPDATE, testGlobalWeb.bUpdate)<< "Web bUpdate Check"; + // getUpdate() + ASSERT_EQ(UPDATE, testGlobalWeb.getUpdate())<< "Web getUpdate() Check"; // lists - ASSERT_EQ(GLOBALNUMNODES, (int)testGlobalWeb.vNode.size())<< "node list"; - ASSERT_EQ(0, (int)testGlobalWeb.vSitesFilter.size())<< + ASSERT_EQ(GLOBALNUMNODES, (int)testGlobalWeb.getVNodeSize())<< "node list"; + ASSERT_EQ(0, (int)testGlobalWeb.getVSitesFilterSize())<< "site filter list empty"; - ASSERT_EQ(GLOBALNUMNETEXLUDE, (int)testGlobalWeb.vNetFilter.size())<< + ASSERT_EQ(GLOBALNUMNETEXLUDE, (int)testGlobalWeb.getVNetFilterSize())<< "net filter list empty"; // pointers - ASSERT_EQ(NULL, testGlobalWeb.pGlass)<< "pGlass null"; - ASSERT_TRUE(NULL != testGlobalWeb.pTrv1)<< "pTrv1 not null"; - ASSERT_TRUE(NULL != testGlobalWeb.pTrv2)<< "pTrv2 not null"; + ASSERT_EQ(NULL, testGlobalWeb.getGlass())<< "getGlass() null"; + ASSERT_TRUE(NULL != testGlobalWeb.getTrv1())<< "getTrv1() not null"; + ASSERT_TRUE(NULL != testGlobalWeb.getTrv2())<< "getTrv2() not null"; // phase name - ASSERT_STREQ(testGlobalWeb.pTrv1->sPhase.c_str(), phasename1.c_str()); + ASSERT_STREQ(testGlobalWeb.getTrv1()->sPhase.c_str(), phasename1.c_str()); // phase name - ASSERT_STREQ(testGlobalWeb.pTrv2->sPhase.c_str(), phasename2.c_str()); + ASSERT_STREQ(testGlobalWeb.getTrv2()->sPhase.c_str(), phasename2.c_str()); // cleanup delete (testSiteList); @@ -356,64 +362,67 @@ TEST(WebTest, GridTest) { std::getline(gridFile, gridLine); gridFile.close(); - json::Object siteList = json::Deserialize(stationLine); - json::Object gridConfig = json::Deserialize(gridLine); + std::shared_ptr siteList = std::make_shared( + json::Deserialize(stationLine)); + std::shared_ptr gridConfig = std::make_shared( + json::Deserialize(gridLine)); // construct a sitelist glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); - testSiteList->dispatch(&siteList); + testSiteList->dispatch(siteList); // construct a web glasscore::CWeb testGridWeb(UPDATE); - testGridWeb.pSiteList = testSiteList; - testGridWeb.dispatch(&gridConfig); + testGridWeb.setSiteList(testSiteList); + testGridWeb.dispatch(gridConfig); // name - ASSERT_STREQ(std::string(GRIDNAME).c_str(), testGridWeb.sName.c_str())<< - "Web sName Matches"; + ASSERT_STREQ(std::string(GRIDNAME).c_str(), testGridWeb.getName().c_str())<< + "Web getName() Matches"; // threshold - ASSERT_EQ(GRIDTHRESH, testGridWeb.dThresh)<< "Web dThresh Check"; + ASSERT_EQ(GRIDTHRESH, testGridWeb.getThresh())<< "Web getThresh() Check"; - // nDetect - ASSERT_EQ(GRIDNUMDETECT, testGridWeb.nDetect)<< "Web nDetect Check"; + // getDetect() + ASSERT_EQ(GRIDNUMDETECT, testGridWeb.getDetect())<< "Web getDetect() Check"; - // nNucleate - ASSERT_EQ(GRIDNUMNUCLEATE, testGridWeb.nNucleate)<< "Web nNucleate Check"; + // getNucleate() + ASSERT_EQ(GRIDNUMNUCLEATE, testGridWeb.getNucleate())<< + "Web getNucleate() Check"; - // dResolution - ASSERT_EQ(GRIDRESOLUTION, testGridWeb.dResolution)<< "Web dResolution " - "Check"; + // getResolution() + ASSERT_EQ(GRIDRESOLUTION, testGridWeb.getResolution())<< + "Web getResolution() Check"; - // nRow - ASSERT_EQ(GRIDNUMROWS, testGridWeb.nRow)<< "Web nRow Check"; + // getRow() + ASSERT_EQ(GRIDNUMROWS, testGridWeb.getRow())<< "Web getRow() Check"; - // nCol - ASSERT_EQ(GRIDNUMROWS, testGridWeb.nCol)<< "Web nCol Check"; + // getCol() + ASSERT_EQ(GRIDNUMROWS, testGridWeb.getCol())<< "Web getCol() Check"; - // nCol - ASSERT_EQ(GRIDNUMZ, testGridWeb.nZ)<< "Web nZ Check"; + // getCol() + ASSERT_EQ(GRIDNUMZ, testGridWeb.getZ())<< "Web getZ() Check"; - // bUpdate - ASSERT_EQ(UPDATE, testGridWeb.bUpdate)<< "Web bUpdate Check"; + // getUpdate() + ASSERT_EQ(UPDATE, testGridWeb.getUpdate())<< "Web getUpdate() Check"; // lists - ASSERT_EQ(GRIDNUMNODES, (int)testGridWeb.vNode.size())<< "node list"; - ASSERT_EQ(0, (int)testGridWeb.vSitesFilter.size())<< + ASSERT_EQ(GRIDNUMNODES, (int)testGridWeb.getVNodeSize())<< "node list"; + ASSERT_EQ(0, (int)testGridWeb.getVSitesFilterSize())<< "site filter list empty"; - ASSERT_EQ(0, (int)testGridWeb.vNetFilter.size())<< + ASSERT_EQ(0, (int)testGridWeb.getVNetFilterSize())<< "net filter list empty"; // pointers - ASSERT_EQ(NULL, testGridWeb.pGlass)<< "pGlass null"; - ASSERT_TRUE(NULL != testGridWeb.pTrv1)<< "pTrv1 not null"; - ASSERT_TRUE(NULL != testGridWeb.pTrv2)<< "pTrv2 not null"; + ASSERT_EQ(NULL, testGridWeb.getGlass())<< "getGlass() null"; + ASSERT_TRUE(NULL != testGridWeb.getTrv1())<< "getTrv1() not null"; + ASSERT_TRUE(NULL != testGridWeb.getTrv2())<< "getTrv2() not null"; // phase name - ASSERT_STREQ(testGridWeb.pTrv1->sPhase.c_str(), phasename1.c_str()); + ASSERT_STREQ(testGridWeb.getTrv1()->sPhase.c_str(), phasename1.c_str()); // phase name - ASSERT_STREQ(testGridWeb.pTrv2->sPhase.c_str(), phasename2.c_str()); + ASSERT_STREQ(testGridWeb.getTrv2()->sPhase.c_str(), phasename2.c_str()); // cleanup delete (testSiteList); @@ -445,64 +454,66 @@ TEST(WebTest, GridExplicitTest) { std::getline(gridFile, gridLine); gridFile.close(); - json::Object siteList = json::Deserialize(stationLine); - json::Object gridConfig = json::Deserialize(gridLine); + std::shared_ptr siteList = std::make_shared( + json::Deserialize(stationLine)); + std::shared_ptr gridConfig = std::make_shared( + json::Deserialize(gridLine)); // construct a sitelist glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); - testSiteList->dispatch(&siteList); + testSiteList->dispatch(siteList); // construct a web glasscore::CWeb testGridWeb(UPDATE); - testGridWeb.pSiteList = testSiteList; - testGridWeb.dispatch(&gridConfig); + testGridWeb.setSiteList(testSiteList); + testGridWeb.dispatch(gridConfig); // name ASSERT_STREQ(std::string(GRIDEXPLICITNAME).c_str(), - testGridWeb.sName.c_str())<< "Web sName Matches"; + testGridWeb.getName().c_str())<< "Web getName() Matches"; // threshold ASSERT_EQ(GRIDEXPLICITTHRESH, - testGridWeb.dThresh)<< "Web dThresh Check"; + testGridWeb.getThresh())<< "Web getThresh() Check"; - // nDetect + // getDetect() ASSERT_EQ(GRIDEXPLICITNUMDETECT, - testGridWeb.nDetect)<< "Web nDetect Check"; + testGridWeb.getDetect())<< "Web getDetect() Check"; - // nNucleate + // getNucleate() ASSERT_EQ(GRIDEXPLICITNUMNUCLEATE, - testGridWeb.nNucleate)<< "Web nNucleate Check"; + testGridWeb.getNucleate())<< "Web getNucleate() Check"; - // dResolution + // getResolution() ASSERT_EQ(GRIDEXPLICITRESOLUTION, - testGridWeb.dResolution)<< "Web dResolution Check"; + testGridWeb.getResolution())<< "Web getResolution() Check"; - // nRow - ASSERT_EQ(0, testGridWeb.nRow)<< "Web nRow Check"; + // getRow() + ASSERT_EQ(0, testGridWeb.getRow())<< "Web getRow() Check"; - // nCol - ASSERT_EQ(0, testGridWeb.nCol)<< "Web nCol Check"; + // getCol() + ASSERT_EQ(0, testGridWeb.getCol())<< "Web getCol() Check"; - // nCol - ASSERT_EQ(0, testGridWeb.nZ)<< "Web nZ Check"; + // getCol() + ASSERT_EQ(0, testGridWeb.getZ())<< "Web getZ() Check"; - // bUpdate - ASSERT_EQ(NOUPDATE, testGridWeb.bUpdate)<< "Web bUpdate Check"; + // getUpdate() + ASSERT_EQ(NOUPDATE, testGridWeb.getUpdate())<< "Web getUpdate() Check"; // lists - ASSERT_EQ(GRIDEXPLICITNUMNODES, (int)testGridWeb.vNode.size())<< "node list"; - ASSERT_EQ(0, (int)testGridWeb.vSitesFilter.size())<< + ASSERT_EQ(GRIDEXPLICITNUMNODES, (int)testGridWeb.getVNodeSize())<< "node list"; + ASSERT_EQ(0, (int)testGridWeb.getVSitesFilterSize())<< "site filter list empty"; - ASSERT_EQ(0, (int)testGridWeb.vNetFilter.size())<< + ASSERT_EQ(0, (int)testGridWeb.getVNetFilterSize())<< "net filter list empty"; // pointers - ASSERT_EQ(NULL, testGridWeb.pGlass)<< "pGlass null"; - ASSERT_TRUE(NULL != testGridWeb.pTrv1)<< "pTrv1 not null"; - ASSERT_TRUE(NULL == testGridWeb.pTrv2)<< "pTrv2 null"; + ASSERT_EQ(NULL, testGridWeb.getGlass())<< "getGlass() null"; + ASSERT_TRUE(NULL != testGridWeb.getTrv1())<< "getTrv1() not null"; + ASSERT_TRUE(NULL == testGridWeb.getTrv2())<< "getTrv2() null"; // phase name - ASSERT_STREQ(testGridWeb.pTrv1->sPhase.c_str(), phasename1.c_str()); + ASSERT_STREQ(testGridWeb.getTrv1()->sPhase.c_str(), phasename1.c_str()); // cleanup delete (testSiteList); @@ -531,21 +542,24 @@ TEST(WebTest, AddTest) { std::getline(gridFile, gridLine); gridFile.close(); - json::Object siteList = json::Deserialize(stationLine); - json::Object gridConfig = json::Deserialize(gridLine); + std::shared_ptr siteList = std::make_shared( + json::Deserialize(stationLine)); + std::shared_ptr gridConfig = std::make_shared( + json::Deserialize(gridLine)); // construct a sitelist glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); - testSiteList->dispatch(&siteList); + testSiteList->dispatch(siteList); // construct a web glasscore::CWeb testGridWeb(UPDATE); - testGridWeb.pSiteList = testSiteList; - testGridWeb.dispatch(&gridConfig); + testGridWeb.setSiteList(testSiteList); + testGridWeb.dispatch(gridConfig); // create site to add - json::Object siteJSON = json::Deserialize(std::string(ADDSITE)); - glasscore::CSite * addSite = new glasscore::CSite(&siteJSON, NULL); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(ADDSITE)))); + glasscore::CSite * addSite = new glasscore::CSite(siteJSON, NULL); std::shared_ptr sharedAddSite(addSite); // add to site list @@ -587,21 +601,24 @@ TEST(WebTest, RemoveTest) { std::getline(gridFile, gridLine); gridFile.close(); - json::Object siteList = json::Deserialize(stationLine); - json::Object gridConfig = json::Deserialize(gridLine); + std::shared_ptr siteList = std::make_shared( + json::Deserialize(stationLine)); + std::shared_ptr gridConfig = std::make_shared( + json::Deserialize(gridLine)); // construct a sitelist glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); - testSiteList->dispatch(&siteList); + testSiteList->dispatch(siteList); // construct a web glasscore::CWeb testGridWeb(UPDATE); - testGridWeb.pSiteList = testSiteList; - testGridWeb.dispatch(&gridConfig); + testGridWeb.setSiteList(testSiteList); + testGridWeb.dispatch(gridConfig); // create site to remove - json::Object siteJSON = json::Deserialize(std::string(REMOVESITE)); - glasscore::CSite * removeSite = new glasscore::CSite(&siteJSON, NULL); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(REMOVESITE)))); + glasscore::CSite * removeSite = new glasscore::CSite(siteJSON, NULL); std::shared_ptr sharedRemoveSite(removeSite); // update in site list @@ -644,7 +661,6 @@ TEST(WebTest, FailTests) { // grid fails std::ifstream badGridFile; std::string badGridLine = ""; - json::Object badGridConfig; // global // bad tt @@ -655,8 +671,9 @@ TEST(WebTest, FailTests) { std::getline(badGridFile, badGridLine); badGridFile.close(); - badGridConfig = json::Deserialize(badGridLine); - ASSERT_FALSE(aWeb.global(&badGridConfig))<< "bad global1 false"; + std::shared_ptr badGridConfig = std::make_shared( + json::Deserialize(badGridLine)); + ASSERT_FALSE(aWeb.global(badGridConfig))<< "bad global1 false"; // no resolution badGridFile.open( @@ -666,8 +683,9 @@ TEST(WebTest, FailTests) { std::getline(badGridFile, badGridLine); badGridFile.close(); - badGridConfig = json::Deserialize(badGridLine); - ASSERT_FALSE(aWeb.global(&badGridConfig))<< "bad global2 false"; + std::shared_ptr badGridConfig2 = std::make_shared( + json::Deserialize(badGridLine)); + ASSERT_FALSE(aWeb.global(badGridConfig2))<< "bad global2 false"; // no depths badGridFile.open( @@ -677,8 +695,9 @@ TEST(WebTest, FailTests) { std::getline(badGridFile, badGridLine); badGridFile.close(); - badGridConfig = json::Deserialize(badGridLine); - ASSERT_FALSE(aWeb.global(&badGridConfig))<< "bad global4 false"; + std::shared_ptr badGridConfig3 = std::make_shared( + json::Deserialize(badGridLine)); + ASSERT_FALSE(aWeb.global(badGridConfig3))<< "bad global4 false"; // grid // bad tt @@ -688,8 +707,9 @@ TEST(WebTest, FailTests) { std::getline(badGridFile, badGridLine); badGridFile.close(); - badGridConfig = json::Deserialize(badGridLine); - ASSERT_FALSE(aWeb.global(&badGridConfig))<< "bad grid1 false"; + std::shared_ptr badGridConfig4 = std::make_shared( + json::Deserialize(badGridLine)); + ASSERT_FALSE(aWeb.global(badGridConfig4))<< "bad grid1 false"; // no resolution badGridFile.open( @@ -698,8 +718,9 @@ TEST(WebTest, FailTests) { std::getline(badGridFile, badGridLine); badGridFile.close(); - badGridConfig = json::Deserialize(badGridLine); - ASSERT_FALSE(aWeb.global(&badGridConfig))<< "bad grid2 false"; + std::shared_ptr badGridConfig5 = std::make_shared( + json::Deserialize(badGridLine)); + ASSERT_FALSE(aWeb.global(badGridConfig5))<< "bad grid2 false"; // no depths badGridFile.open( @@ -708,8 +729,9 @@ TEST(WebTest, FailTests) { std::getline(badGridFile, badGridLine); badGridFile.close(); - badGridConfig = json::Deserialize(badGridLine); - ASSERT_FALSE(aWeb.global(&badGridConfig))<< "bad grid3 false"; + std::shared_ptr badGridConfig6 = std::make_shared( + json::Deserialize(badGridLine)); + ASSERT_FALSE(aWeb.global(badGridConfig6))<< "bad grid3 false"; // explicit // bad tt @@ -720,8 +742,9 @@ TEST(WebTest, FailTests) { std::getline(badGridFile, badGridLine); badGridFile.close(); - badGridConfig = json::Deserialize(badGridLine); - ASSERT_FALSE(aWeb.global(&badGridConfig))<< "bad grid1 false"; + std::shared_ptr badGridConfig7 = std::make_shared( + json::Deserialize(badGridLine)); + ASSERT_FALSE(aWeb.global(badGridConfig7))<< "bad grid1 false"; // no resolution badGridFile.open( @@ -731,6 +754,7 @@ TEST(WebTest, FailTests) { std::getline(badGridFile, badGridLine); badGridFile.close(); - badGridConfig = json::Deserialize(badGridLine); - ASSERT_FALSE(aWeb.global(&badGridConfig))<< "bad grid2 false"; + std::shared_ptr badGridConfig8 = std::make_shared( + json::Deserialize(badGridLine)); + ASSERT_FALSE(aWeb.global(badGridConfig8))<< "bad grid2 false"; } diff --git a/glasscore/tests/weblist_unittest.cpp b/glasscore/tests/weblist_unittest.cpp index 240c8cbd..38f56e4a 100644 --- a/glasscore/tests/weblist_unittest.cpp +++ b/glasscore/tests/weblist_unittest.cpp @@ -29,10 +29,10 @@ TEST(WebListTest, Construction) { glasscore::CWebList * testWebList = new glasscore::CWebList(); // lists - ASSERT_EQ(0, (int)testWebList->vWeb.size())<< "web list empty"; + ASSERT_EQ(0, (int)testWebList->getVWebSize())<< "web list empty"; // pointers - ASSERT_EQ(NULL, testWebList->pGlass)<< "pGlass null"; + ASSERT_EQ(NULL, testWebList->getGlass())<< "getGlass() null"; ASSERT_TRUE(testWebList->statusCheck())<< "status check"; @@ -62,25 +62,27 @@ TEST(WebListTest, AddWeb) { std::getline(gridFile, gridLine); gridFile.close(); - json::Object siteList = json::Deserialize(stationLine); - json::Object gridConfig = json::Deserialize(gridLine); + std::shared_ptr siteList = std::make_shared( + json::Deserialize(stationLine)); + std::shared_ptr gridConfig = std::make_shared( + json::Deserialize(gridLine)); // construct a sitelist glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); - testSiteList->dispatch(&siteList); + testSiteList->dispatch(siteList); // construct a WebList glasscore::CWebList * testWebList = new glasscore::CWebList(); - testWebList->pSiteList = testSiteList; + testWebList->setSiteList(testSiteList); // web list - ASSERT_EQ(0, (int)testWebList->vWeb.size())<< "web list empty"; + ASSERT_EQ(0, (int)testWebList->getVWebSize())<< "web list empty"; // add a web - testWebList->dispatch(&gridConfig); + testWebList->dispatch(gridConfig); // web list - ASSERT_EQ(1, (int)testWebList->vWeb.size())<< "web list added"; + ASSERT_EQ(1, (int)testWebList->getVWebSize())<< "web list added"; ASSERT_TRUE(testWebList->statusCheck())<< "status check"; @@ -111,33 +113,37 @@ TEST(WebListTest, RemWeb) { std::getline(gridFile, gridLine); gridFile.close(); - json::Object siteList = json::Deserialize(stationLine); - json::Object gridConfig = json::Deserialize(gridLine); + std::shared_ptr siteList = std::make_shared( + json::Deserialize(stationLine)); + std::shared_ptr gridConfig = std::make_shared( + json::Deserialize(gridLine)); // construct a sitelist glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); - testSiteList->dispatch(&siteList); + testSiteList->dispatch(siteList); // construct a WebList glasscore::CWebList * testWebList = new glasscore::CWebList(); - testWebList->pSiteList = testSiteList; + testWebList->setSiteList(testSiteList); // web list - ASSERT_EQ(0, (int)testWebList->vWeb.size())<< "web list empty"; + ASSERT_EQ(0, (int)testWebList->getVWebSize())<< "web list empty"; // add a web - testWebList->dispatch(&gridConfig); + testWebList->dispatch(gridConfig); // web list - ASSERT_EQ(1, (int)testWebList->vWeb.size())<< "web list added"; + ASSERT_EQ(1, (int)testWebList->getVWebSize())<< "web list added"; - json::Object remGridConfig = json::Deserialize(std::string(REMWEB)); + std::shared_ptr remGridConfig = + std::make_shared( + json::Deserialize(std::string(REMWEB))); // remove a web - testWebList->dispatch(&remGridConfig); + testWebList->dispatch(remGridConfig); // web list - ASSERT_EQ(0, (int)testWebList->vWeb.size())<< "web list removed"; + ASSERT_EQ(0, (int)testWebList->getVWebSize())<< "web list removed"; delete (testSiteList); delete (testWebList); @@ -166,29 +172,32 @@ TEST(WebListTest, SiteOperations) { std::getline(gridFile, gridLine); gridFile.close(); - json::Object siteList = json::Deserialize(stationLine); - json::Object gridConfig = json::Deserialize(gridLine); + std::shared_ptr siteList = std::make_shared( + json::Deserialize(stationLine)); + std::shared_ptr gridConfig = std::make_shared( + json::Deserialize(gridLine)); // construct a sitelist glasscore::CSiteList * testSiteList = new glasscore::CSiteList(); - testSiteList->dispatch(&siteList); + testSiteList->dispatch(siteList); // construct a WebList glasscore::CWebList * testWebList = new glasscore::CWebList(); - testWebList->pSiteList = testSiteList; + testWebList->setSiteList(testSiteList); // web list - ASSERT_EQ(0, (int)testWebList->vWeb.size())<< "web list empty"; + ASSERT_EQ(0, (int)testWebList->getVWebSize())<< "web list empty"; // add a web - testWebList->dispatch(&gridConfig); + testWebList->dispatch(gridConfig); // web list - ASSERT_EQ(1, (int)testWebList->vWeb.size())<< "web list added"; + ASSERT_EQ(1, (int)testWebList->getVWebSize())<< "web list added"; // create site to add - json::Object siteJSON = json::Deserialize(std::string(ADDSITE)); - glasscore::CSite * addSite = new glasscore::CSite(&siteJSON, NULL); + std::shared_ptr siteJSON = std::make_shared( + json::Object(json::Deserialize(std::string(ADDSITE)))); + glasscore::CSite * addSite = new glasscore::CSite(siteJSON, NULL); std::shared_ptr sharedAddSite(addSite); // add to site list @@ -202,8 +211,9 @@ TEST(WebListTest, SiteOperations) { ASSERT_TRUE(testWebList->hasSite(sharedAddSite))<< "site added"; // create site to remove - json::Object siteJSON2 = json::Deserialize(std::string(REMOVESITE)); - glasscore::CSite * removeSite = new glasscore::CSite(&siteJSON2, NULL); + std::shared_ptr siteJSON2 = std::make_shared( + json::Object(json::Deserialize(std::string(REMOVESITE)))); + glasscore::CSite * removeSite = new glasscore::CSite(siteJSON2, NULL); std::shared_ptr sharedRemoveSite(removeSite); // update in site list diff --git a/output/include/output.h b/output/include/output.h index cd5b1411..91b8a388 100644 --- a/output/include/output.h +++ b/output/include/output.h @@ -23,6 +23,7 @@ #include #include #include +#include namespace glass { /** @@ -81,7 +82,7 @@ class output : public util::iOutput, public util::ThreadBaseClass { * * \param message - A json::Object containing the message to send to output. */ - void sendToOutput(json::Object* message) override; + void sendToOutput(std::shared_ptr &message) override; /** * \brief thread pool check function @@ -144,9 +145,9 @@ class output : public util::iOutput, public util::ThreadBaseClass { * \param data - A pointer to a json::Object containing the detection data. * \return Returns true if successful, false otherwise */ - bool addTrackingData(json::Object* data); + bool addTrackingData(std::shared_ptr data); - json::Object * getTrackingData(std::string id); + std::shared_ptr getTrackingData(std::string id); /** * \brief get data from the output tracking cache @@ -157,7 +158,7 @@ class output : public util::iOutput, public util::ThreadBaseClass { * \return Returns a pointer to the json::Object containing the detection * data ready for output, NULL if no data found that is ready. */ - json::Object * getNextTrackingData(); + std::shared_ptr getNextTrackingData(); /** * \brief check if data is in output tracking cache @@ -168,7 +169,7 @@ class output : public util::iOutput, public util::ThreadBaseClass { * \param data - A pointer to a json::Object containing the detection data. * \return Returns true if the data is in the cache, false otherwise */ - bool haveTrackingData(json::Object* data); + bool haveTrackingData(std::shared_ptr data); bool haveTrackingData(std::string ID); /** @@ -179,7 +180,7 @@ class output : public util::iOutput, public util::ThreadBaseClass { * \param data - A pointer to a json::Object containing the detection data. * \return Returns true if successful, false otherwise */ - bool removeTrackingData(json::Object* data); + bool removeTrackingData(std::shared_ptr data); bool removeTrackingData(std::string ID); /** @@ -198,9 +199,10 @@ class output : public util::iOutput, public util::ThreadBaseClass { * data to check * \return Returns true if the data is ready, false if not. */ - bool isDataReady(json::Object *data); - bool isDataChanged(json::Object *data); - bool isDataPublished(json::Object *data, bool ignoreVersion = true); + bool isDataReady(std::shared_ptr data); + bool isDataChanged(std::shared_ptr data); + bool isDataPublished(std::shared_ptr data, + bool ignoreVersion = true); protected: /** @@ -220,7 +222,7 @@ class output : public util::iOutput, public util::ThreadBaseClass { * \param data - A pointer to a json::Object containing the data to be * output. */ - void writeOutput(json::Object *data); + void writeOutput(std::shared_ptr data); virtual void sendOutput(const std::string &type, const std::string &id, const std::string &message) = 0; diff --git a/output/src/output.cpp b/output/src/output.cpp index ff156bea..a87a9793 100644 --- a/output/src/output.cpp +++ b/output/src/output.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace glass { @@ -212,7 +213,11 @@ void output::clear() { util::BaseClass::clear(); } -void output::sendToOutput(json::Object* message) { +void output::sendToOutput(std::shared_ptr &message) { + if (message == NULL) { + return; + } + if (m_MessageQueue != NULL) { m_MessageQueue->addDataToQueue(message); } @@ -232,7 +237,7 @@ bool output::check() { } // add data to output cache -bool output::addTrackingData(json::Object* data) { +bool output::addTrackingData(std::shared_ptr data) { if (data == NULL) { logger::log("error", "output::addtrackingdata(): Bad json object passed in."); @@ -258,16 +263,14 @@ bool output::addTrackingData(json::Object* data) { return (false); } - // make a new copy to add - json::Object * newData = new json::Object(*data); - logger::log( "debug", "output::addTrackingData(): New tracking data: " - + json::Serialize(*newData)); + + json::Serialize(*data)); // check to see if this event is already being tracked - json::Object* existingdata = m_TrackingCache->getFromCache(id); + std::shared_ptr existingdata = m_TrackingCache->getFromCache( + id); if (existingdata != NULL) { // it is, copy the pub log for an existing event if (!(*existingdata).HasKey("PubLog")) { @@ -276,11 +279,10 @@ bool output::addTrackingData(json::Object* data) { "output::addtrackingdata(): existing event missing pub log! :" + json::Serialize(*existingdata)); - delete (newData); return (false); } else { json::Array pubLog = (*existingdata)["PubLog"].ToArray(); - (*newData)["PubLog"] = pubLog; + (*data)["PubLog"] = pubLog; } } else { // it isn't generate the pub log for a new event @@ -291,15 +293,15 @@ bool output::addTrackingData(json::Object* data) { // generate a pub log entry pubLog.push_back(0); } - (*newData)["PubLog"] = pubLog; + (*data)["PubLog"] = pubLog; } // add, cache handles updates - return (m_TrackingCache->addToCache(newData, id)); + return (m_TrackingCache->addToCache(data, id)); } // remove data from output cache -bool output::removeTrackingData(json::Object* data) { +bool output::removeTrackingData(std::shared_ptr data) { if (data == NULL) { logger::log("error", "output::removetrackingdata(): Bad json object passed in."); @@ -315,6 +317,7 @@ bool output::removeTrackingData(json::Object* data) { logger::log( "error", "output::removetrackingdata(): Bad json hypo object passed in."); + return (false); } @@ -335,14 +338,15 @@ bool output::removeTrackingData(std::string ID) { return (false); } -json::Object * output::getTrackingData(std::string id) { +std::shared_ptr output::getTrackingData(std::string id) { // return the value return (m_TrackingCache->getFromCache(id)); } -json::Object * output::getNextTrackingData() { +std::shared_ptr output::getNextTrackingData() { // get the data - json::Object* data = m_TrackingCache->getNextFromCache(true); + std::shared_ptr data = m_TrackingCache->getNextFromCache( + true); // loop until we hit the end of the list while (data != NULL) { @@ -361,7 +365,7 @@ json::Object * output::getNextTrackingData() { } // check if data in output cache -bool output::haveTrackingData(json::Object* data) { +bool output::haveTrackingData(std::shared_ptr data) { if (data == NULL) { logger::log("error", "output::havetrackingdata(): Bad json object passed in."); @@ -412,7 +416,7 @@ bool output::work() { // first see what we're supposed to do with a new message // see if there's anything in the message queue - json::Object* message = m_MessageQueue->getDataFromQueue(); + std::shared_ptr message = m_MessageQueue->getDataFromQueue(); // if we got something if (message != NULL) { @@ -447,7 +451,8 @@ bool output::work() { // glass has a hypo it wants us to send if (messagetype == "Hypo") { - json::Object * trackingData = getTrackingData(messageid); + std::shared_ptr trackingData = getTrackingData( + messageid); if (trackingData == NULL) { return (false); @@ -489,14 +494,10 @@ bool output::work() { // add the event to the tracking cache addTrackingData(message); - // cleanup - // cppcheck-suppress nullPointerRedundantCheck - if (message != NULL) { - delete (message); - } m_iEventCounter++; } else if (messagetype == "Cancel") { - json::Object * trackingData = getTrackingData(messageid); + std::shared_ptr trackingData = getTrackingData( + messageid); // see if we've tracked this event if (trackingData != NULL) { // we have @@ -526,7 +527,8 @@ bool output::work() { } m_iCancelCounter++; } else if (messagetype == "Expire") { - json::Object * trackingData = getTrackingData(messageid); + std::shared_ptr trackingData = getTrackingData( + messageid); // see if we've tracked this event if (trackingData != NULL) { // we have @@ -554,9 +556,6 @@ bool output::work() { "warning", "output::work(): Unknown message from glasslib: " + json::Serialize(*message) + "."); - - // cleanup - delete (message); } // reporting @@ -609,7 +608,7 @@ bool output::work() { } // see if there's anything in the tracking cache - json::Object * data = getNextTrackingData(); + std::shared_ptr data = getNextTrackingData(); // got something if (data != NULL) { @@ -652,7 +651,8 @@ bool output::work() { // Request the hypo from associator if (Associator != NULL) { // build the request - json::Object * datarequest = new json::Object(); + std::shared_ptr datarequest = std::make_shared< + json::Object>(json::Object()); (*datarequest)["Cmd"] = "ReqHypo"; (*datarequest)["Pid"] = id; @@ -673,7 +673,8 @@ bool output::work() { // Request the sitelist from associator if (Associator != NULL) { // build the request - json::Object * datarequest = new json::Object(); + std::shared_ptr datarequest = std::make_shared< + json::Object>(json::Object()); (*datarequest)["Cmd"] = "ReqSiteList"; // send the request @@ -690,7 +691,7 @@ bool output::work() { } // handle output -void output::writeOutput(json::Object *data) { +void output::writeOutput(std::shared_ptr data) { if (data == NULL) { logger::log("error", "output::writeoutput(): Null json object passed in."); @@ -745,7 +746,7 @@ void output::writeOutput(json::Object *data) { } // filter -bool output::isDataReady(json::Object *data) { +bool output::isDataReady(std::shared_ptr data) { if (data == NULL) { logger::log("error", "output::isdataready(): Null tracking object passed in."); @@ -847,7 +848,7 @@ bool output::isDataReady(json::Object *data) { return (false); } -bool output::isDataChanged(json::Object *data) { +bool output::isDataChanged(std::shared_ptr data) { if (data == NULL) { logger::log("error", "output::isDataChanged(): Null tracking object passed in."); @@ -888,7 +889,8 @@ bool output::isDataChanged(json::Object *data) { return (true); } -bool output::isDataPublished(json::Object *data, bool ignoreVersion) { +bool output::isDataPublished(std::shared_ptr data, + bool ignoreVersion) { if (data == NULL) { logger::log( "error", diff --git a/output/tests/output_unittest.cpp b/output/tests/output_unittest.cpp index 54c0b356..61ad9aba 100644 --- a/output/tests/output_unittest.cpp +++ b/output/tests/output_unittest.cpp @@ -6,6 +6,7 @@ #include #include +#include #define EMPTYCONFIG "{\"Cmd\":\"GlassOutput\"}" #define CONFIGFAIL1 "{\"PublicationTimes\":[3, 6]}" @@ -39,6 +40,7 @@ class OutputStub : public glass::output { TEST(Output, TrackingTests) { // create output stub OutputStub outputThread; + std::shared_ptr nullTrack; time_t tNow; std::time(&tNow); @@ -50,17 +52,20 @@ TEST(Output, TrackingTests) { ASSERT_TRUE( outputThread.setup(new json::Object(json::Deserialize(EMPTYCONFIG)))); // NOLINT - json::Object *tracking1 = new json::Object(json::Deserialize(TRACKING1)); + std::shared_ptr tracking1 = std::make_shared( + json::Object(json::Deserialize(TRACKING1))); (*tracking1)["CreateTime"] = util::convertEpochTimeToISO8601(tNow); (*tracking1)["ReportTime"] = util::convertEpochTimeToISO8601(tNow); - json::Object *tracking2 = new json::Object(json::Deserialize(TRACKING2)); + std::shared_ptr tracking2 = std::make_shared( + json::Object(json::Deserialize(TRACKING2))); (*tracking2)["CreateTime"] = util::convertEpochTimeToISO8601(tNow); (*tracking2)["ReportTime"] = util::convertEpochTimeToISO8601(tNow); - json::Object *tracking3 = new json::Object(json::Deserialize(TRACKING3)); + std::shared_ptr tracking3 = std::make_shared( + json::Object(json::Deserialize(TRACKING3))); (*tracking3)["CreateTime"] = util::convertEpochTimeToISO8601(tNow); (*tracking3)["ReportTime"] = util::convertEpochTimeToISO8601(tNow); @@ -73,25 +78,34 @@ TEST(Output, TrackingTests) { // add fails ASSERT_FALSE(outputThread.addTrackingData(NULL)); ASSERT_FALSE( - outputThread.addTrackingData(new json::Object(json::Deserialize(BADTRACKING1)))); // NOLINT + outputThread.addTrackingData(std::make_shared(json::Object(json::Deserialize(BADTRACKING1))))); // NOLINT ASSERT_FALSE( - outputThread.addTrackingData(new json::Object(json::Deserialize(BADTRACKING2)))); // NOLINT + outputThread.addTrackingData(std::make_shared(json::Object(json::Deserialize(BADTRACKING2))))); // NOLINT + + std::shared_ptr tracking4 = std::make_shared( + json::Object(json::Deserialize(TRACKING1))); + std::shared_ptr tracking5 = std::make_shared( + json::Object(json::Deserialize(TRACKING2))); // have successes - ASSERT_TRUE(outputThread.haveTrackingData(tracking1)); - ASSERT_TRUE(outputThread.haveTrackingData(tracking2)); + ASSERT_TRUE(outputThread.haveTrackingData(tracking4)); + ASSERT_TRUE(outputThread.haveTrackingData(tracking5)); ASSERT_TRUE(outputThread.haveTrackingData(std::string(ID1))); // have fails - ASSERT_FALSE(outputThread.haveTrackingData(NULL)); + ASSERT_FALSE(outputThread.haveTrackingData(nullTrack)); ASSERT_FALSE(outputThread.haveTrackingData("")); // remove successes - ASSERT_TRUE(outputThread.removeTrackingData(tracking1)); - ASSERT_FALSE(outputThread.haveTrackingData(tracking1)); + ASSERT_TRUE(outputThread.removeTrackingData(tracking4)); + + std::shared_ptr tracking6 = std::make_shared( + json::Object(json::Deserialize(TRACKING1))); + + ASSERT_FALSE(outputThread.haveTrackingData(tracking6)); // remove fail - ASSERT_FALSE(outputThread.removeTrackingData(NULL)); + ASSERT_FALSE(outputThread.removeTrackingData(nullTrack)); ASSERT_FALSE(outputThread.removeTrackingData("")); // clear diff --git a/parse/include/ccparser.h b/parse/include/ccparser.h index d2be8eea..6801eec3 100644 --- a/parse/include/ccparser.h +++ b/parse/include/ccparser.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace parse { /** @@ -52,7 +53,7 @@ class CCParser : public Parser { * \return Returns a pointer to the json::Object containing * the data. */ - json::Object* parse(const std::string &input) override; + std::shared_ptr parse(const std::string &input) override; /** * \brief cross correlation validation function @@ -63,7 +64,7 @@ class CCParser : public Parser { * validate. * \return Returns true if valid, false otherwise. */ - bool validate(json::Object* input) override; + bool validate(std::shared_ptr &input) override; }; } // namespace parse #endif // CCPARSER_H diff --git a/parse/include/convert.h b/parse/include/convert.h index db84ee6a..07a12674 100644 --- a/parse/include/convert.h +++ b/parse/include/convert.h @@ -9,6 +9,7 @@ #include #include +#include namespace parse { @@ -25,7 +26,7 @@ namespace parse { * \return Returns a string containing the converted json detection, empty * string otherwise */ -std::string hypoToJSONDetection(json::Object *data, +std::string hypoToJSONDetection(std::shared_ptr, const std::string &outputAgencyID, const std::string &outputAuthor); @@ -43,7 +44,7 @@ std::string hypoToJSONDetection(json::Object *data, * \return Returns a string containing the converted json detection, empty * string otherwise */ -std::string cancelToJSONRetract(json::Object *data, +std::string cancelToJSONRetract(std::shared_ptr, const std::string &outputAgencyID, const std::string &outputAuthor); @@ -58,7 +59,7 @@ std::string cancelToJSONRetract(json::Object *data, * \return Returns a string containing the converted json detection, empty * string otherwise */ -std::string siteListToStationList(json::Object *data); +std::string siteListToStationList(std::shared_ptr); /** * \brief json station list conversion function @@ -74,7 +75,7 @@ std::string siteListToStationList(json::Object *data); * \return Returns a string containing the converted json detection, empty * string otherwise */ -std::string siteLookupToStationInfoRequest(json::Object *data, +std::string siteLookupToStationInfoRequest(std::shared_ptr, const std::string &outputAgencyID, const std::string &outputAuthor); diff --git a/parse/include/gpickparser.h b/parse/include/gpickparser.h index b1f08e59..d2b8007c 100644 --- a/parse/include/gpickparser.h +++ b/parse/include/gpickparser.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace parse { /** @@ -52,7 +53,7 @@ class GPickParser : public Parser { * \return Returns a pointer to the json::Object containing * the data. */ - json::Object* parse(const std::string &input) override; + std::shared_ptr parse(const std::string &input) override; /** * \brief pick validation function @@ -63,7 +64,7 @@ class GPickParser : public Parser { * validate. * \return Returns true if valid, false otherwise. */ - bool validate(json::Object* input) override; + bool validate(std::shared_ptr &input) override; }; } // namespace parse #endif // GPICKPARSER_H diff --git a/parse/include/jsonparser.h b/parse/include/jsonparser.h index fb8181eb..be94e386 100644 --- a/parse/include/jsonparser.h +++ b/parse/include/jsonparser.h @@ -10,6 +10,7 @@ #include #include #include +#include namespace parse { /** @@ -52,7 +53,7 @@ class JSONParser : public Parser { * \return Returns a pointer to the json::Object containing * the data. */ - json::Object* parse(const std::string &input) override; + std::shared_ptr parse(const std::string &input) override; // NOLINT /** * \brief json validation function @@ -63,7 +64,7 @@ class JSONParser : public Parser { * validate. * \return Returns true if valid, false otherwise. */ - bool validate(json::Object* input) override; + bool validate(std::shared_ptr &input) override; }; } // namespace parse #endif // JSONPARSER_H diff --git a/parse/include/parser.h b/parse/include/parser.h index edab400f..7b4dbadd 100644 --- a/parse/include/parser.h +++ b/parse/include/parser.h @@ -9,6 +9,7 @@ #include #include +#include namespace parse { /** @@ -50,7 +51,7 @@ class Parser { * \return Returns a pointer to the json::Object containing * the data. */ - virtual json::Object* parse(const std::string &input) = 0; + virtual std::shared_ptr parse(const std::string &input) = 0; /** * \brief validation function @@ -61,7 +62,7 @@ class Parser { * validate. * \return Returns true if valid, false otherwise. */ - virtual bool validate(json::Object* input) = 0; + virtual bool validate(std::shared_ptr &input) = 0; // NOLINT /** * \brief getter for the agencyid configuration variable diff --git a/parse/src/ccparser.cpp b/parse/src/ccparser.cpp index 0dfe1647..8e3e9f87 100644 --- a/parse/src/ccparser.cpp +++ b/parse/src/ccparser.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace parse { CCParser::CCParser(const std::string &newAgencyID, const std::string &newAuthor) @@ -15,7 +16,7 @@ CCParser::~CCParser() { } // parse a json object from an input string -json::Object* CCParser::parse(const std::string &input) { +std::shared_ptr CCParser::parse(const std::string &input) { // make sure we got something if (input.length() == 0) return (NULL); @@ -119,8 +120,9 @@ json::Object* CCParser::parse(const std::string &input) { // make sure we got valid json if (deserializedJSON.GetType() != json::ValueType::NULLVal) { - json::Object* newjsoncorrelation = new json::Object( - deserializedJSON.ToObject()); + std::shared_ptr newjsoncorrelation = std::make_shared< + json::Object>(json::Object(deserializedJSON.ToObject())); + logger::log( "trace", "ccparser::parse: Output JSON: " @@ -136,7 +138,7 @@ json::Object* CCParser::parse(const std::string &input) { } // validate a json object -bool CCParser::validate(json::Object* input) { +bool CCParser::validate(std::shared_ptr &input) { // nullcheck if (input == NULL) { return (false); diff --git a/parse/src/convert.cpp b/parse/src/convert.cpp index 69edd032..f02139bf 100644 --- a/parse/src/convert.cpp +++ b/parse/src/convert.cpp @@ -7,10 +7,11 @@ #include #include #include +#include namespace parse { -std::string hypoToJSONDetection(json::Object *data, +std::string hypoToJSONDetection(std::shared_ptr data, const std::string &outputAgencyID, const std::string &outputAuthor) { if (data == NULL) { @@ -384,14 +385,11 @@ std::string hypoToJSONDetection(json::Object *data, detection.tojson(detectiondocument, detectiondocument.GetAllocator())); - // cleanup - delete (data); - // done return (OutputData); } -std::string cancelToJSONRetract(json::Object *data, +std::string cancelToJSONRetract(std::shared_ptr data, const std::string &outputAgencyID, const std::string &outputAuthor) { if (data == NULL) { @@ -452,14 +450,11 @@ std::string cancelToJSONRetract(json::Object *data, OutputData = detectionformats::ToJSONString( retract.tojson(retractdocument, retractdocument.GetAllocator())); - // cleanup - delete (data); - // done return (OutputData); } -std::string siteListToStationList(json::Object *data) { +std::string siteListToStationList(std::shared_ptr data) { if (data == NULL) { logger::log( "error", @@ -543,14 +538,11 @@ std::string siteListToStationList(json::Object *data) { OutputData = json::Serialize(stationListObj); - // cleanup - delete (data); - // done return (OutputData); } -std::string siteLookupToStationInfoRequest(json::Object *data, +std::string siteLookupToStationInfoRequest(std::shared_ptr data, const std::string &outputAgencyID, const std::string &outputAuthor) { if (data == NULL) { @@ -651,9 +643,6 @@ std::string siteLookupToStationInfoRequest(json::Object *data, "message: " + errorstring); } - // cleanup - delete (data); - // done return (OutputString); } diff --git a/parse/src/gpickparser.cpp b/parse/src/gpickparser.cpp index 97f9888d..5f756de9 100644 --- a/parse/src/gpickparser.cpp +++ b/parse/src/gpickparser.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace parse { GPickParser::GPickParser(const std::string &newAgencyID, @@ -16,7 +17,7 @@ GPickParser::~GPickParser() { } // parse a json object from an input string -json::Object* GPickParser::parse(const std::string &input) { +std::shared_ptr GPickParser::parse(const std::string &input) { // make sure we got something if (input.length() == 0) return (NULL); @@ -174,8 +175,9 @@ json::Object* GPickParser::parse(const std::string &input) { // make sure we got valid json if (deserializedJSON.GetType() != json::ValueType::NULLVal) { - json::Object* newjsonpick = new json::Object( - deserializedJSON.ToObject()); + std::shared_ptr newjsonpick = std::make_shared< + json::Object>(json::Object(deserializedJSON.ToObject())); + logger::log( "trace", "gpickparser::parse: Output JSON: " @@ -194,7 +196,7 @@ json::Object* GPickParser::parse(const std::string &input) { } // validate a json object -bool GPickParser::validate(json::Object* input) { +bool GPickParser::validate(std::shared_ptr &input) { // nullcheck if (input == NULL) { return (false); diff --git a/parse/src/jsonparser.cpp b/parse/src/jsonparser.cpp index 46997e63..295efe24 100644 --- a/parse/src/jsonparser.cpp +++ b/parse/src/jsonparser.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace parse { JSONParser::JSONParser(const std::string &newAgencyID, @@ -15,7 +16,7 @@ JSONParser::~JSONParser() { } // parse a json object from an input string -json::Object* JSONParser::parse(const std::string &input) { +std::shared_ptr JSONParser::parse(const std::string &input) { // make sure we got something if (input.length() == 0) { return (NULL); @@ -26,7 +27,7 @@ json::Object* JSONParser::parse(const std::string &input) { // JSON format // JSON doesn't have a fixed format // try to convert the string to a json object - json::Object *newobject = NULL; + std::shared_ptr newobject; try { json::Value deserializedvalue = json::Deserialize(input); @@ -39,7 +40,8 @@ json::Object* JSONParser::parse(const std::string &input) { } // convert our resulting value to a json object - newobject = new json::Object(deserializedvalue.ToObject()); + newobject = std::make_shared( + json::Object(deserializedvalue.ToObject())); } catch (const std::runtime_error &e) { // oopse std::string exceptionstring = e.what(); @@ -67,7 +69,7 @@ json::Object* JSONParser::parse(const std::string &input) { } // validate a json object -bool JSONParser::validate(json::Object* input) { +bool JSONParser::validate(std::shared_ptr &input) { // nullcheck if (input == NULL) { return (false); diff --git a/parse/tests/ccparser_unittest.cpp b/parse/tests/ccparser_unittest.cpp index 411ab5a5..cb6dd2aa 100644 --- a/parse/tests/ccparser_unittest.cpp +++ b/parse/tests/ccparser_unittest.cpp @@ -2,6 +2,7 @@ #include #include +#include #define TESTCCSTRING "2015/03/23 23:53:47.630 36.769 -98.019 5.0 1.2677417 mblg GS OK032 HHZ 00 P 2015/03/23 23:53:50.850 0.7663822 0.65" // NOLINT #define TESTFAILSTRING "2015/03/23 -98.019 5.0 1.2677417 mblg GS OK032 HHZ 00 P 2015/03/23 23:53:50.850 0.7663822 0.65" // NOLINT @@ -31,7 +32,7 @@ class CCParser : public ::testing::Test { TEST_F(CCParser, Construction) { // assert that agencyid is ok ASSERT_STREQ(Parser->getAgencyid().c_str(), agencyid.c_str())<< - "AgencyID check"; + "AgencyID check"; // assert that author is ok ASSERT_STREQ(Parser->getAuthor().c_str(), author.c_str()) @@ -42,28 +43,28 @@ TEST_F(CCParser, Construction) { TEST_F(CCParser, CorrelationParsing) { std::string ccstring = std::string(TESTCCSTRING); - json::Object * CCObject = Parser->parse(ccstring); + std::shared_ptr CCObject = Parser->parse(ccstring); // parse the origin ASSERT_FALSE(CCObject == NULL)<< "Parsed cross correlation not null."; // validate the origin ASSERT_TRUE(Parser->validate(CCObject))<< - "Parsed cross correlation is valid"; + "Parsed cross correlation is valid"; } // test failure TEST_F(CCParser, FailTest) { std::string failstring = std::string(TESTFAILSTRING); - json::Object * FailObject = Parser->parse(failstring); + std::shared_ptr FailObject = Parser->parse(failstring); // parse the bad data ASSERT_TRUE(FailObject == NULL)<< "Parsed fail string is null."; // validate the bad data ASSERT_FALSE(Parser->validate(FailObject))<< - "Parsed failstring is not valid"; + "Parsed failstring is not valid"; // parse empty string FailObject = Parser->parse(""); @@ -73,5 +74,5 @@ TEST_F(CCParser, FailTest) { // validate the bad data ASSERT_FALSE(Parser->validate(FailObject))<< - "Parsed empty string is not valid"; + "Parsed empty string is not valid"; } diff --git a/parse/tests/convert_unittest.cpp b/parse/tests/convert_unittest.cpp index 63733d1e..d3989a7d 100644 --- a/parse/tests/convert_unittest.cpp +++ b/parse/tests/convert_unittest.cpp @@ -6,6 +6,7 @@ #include #include +#include #define HYPOSTRING "{\"Bayes\":2.087726,\"Cmd\":\"Hypo\",\"Data\":[{\"Type\":\"Correlation\",\"ID\":\"12GFH48776857\",\"Site\":{\"Station\":\"BMN\",\"Network\":\"LB\",\"Channel\":\"HHZ\",\"Location\":\"01\"},\"Source\":{\"AgencyID\":\"US\",\"Author\":\"TestAuthor\"},\"Phase\":\"P\",\"Time\":\"2015-12-28T21:32:24.017Z\",\"Correlation\":2.65,\"Hypocenter\":{\"Latitude\":40.3344,\"Longitude\":-121.44,\"Depth\":32.44,\"Time\":\"2015-12-28T21:30:44.039Z\"},\"EventType\":\"earthquake\",\"Magnitude\":2.14,\"SNR\":3.8,\"ZScore\":33.67,\"DetectionThreshold\":1.5,\"ThresholdType\":\"minimum\",\"AssociationInfo\":{\"Phase\":\"P\",\"Distance\":0.442559,\"Azimuth\":0.418479,\"Residual\":-0.025393,\"Sigma\":0.086333}},{\"Amplitude\":{\"Amplitude\":0.000000,\"Period\":0.000000,\"SNR\":3.410000},\"AssociationInfo\":{\"Azimuth\":146.725914,\"Distance\":0.114828,\"Phase\":\"P\",\"Residual\":0.000904,\"Sigma\":1.000000},\"Filter\":[{\"HighPass\":1.050000,\"LowPass\":2.650000}],\"ID\":\"100725\",\"Phase\":\"P\",\"Picker\":\"raypicker\",\"Polarity\":\"up\",\"Site\":{\"Channel\":\"BHZ\",\"Location\":\"--\",\"Network\":\"AK\",\"Station\":\"SSN\"},\"Source\":{\"AgencyID\":\"US\",\"Author\":\"228041013\"},\"Time\":\"2015-08-14T03:35:25.947Z\",\"Type\":\"Pick\"}],\"Depth\":24.717898,\"Gap\":110.554774,\"ID\":\"20311B8E10AF5649BDC52ED099CF173E\",\"IsUpdate\":false,\"Latitude\":61.559315,\"Longitude\":-150.877897,\"MinimumDistance\":0.110850,\"Source\":{\"AgencyID\":\"US\",\"Author\":\"glass\"},\"T\":\"20150814033521.219\",\"Time\":\"2015-08-14T03:35:21.219Z\",\"Type\":\"Hypo\"}" // NOLINT #define BADHYPOSTRING1 "{\"Bayes\":2.087726,\"Cmd\":\"Hypo\",\"Data\":[{\"Amplitude\":{\"Amplitude\":0.000000,\"Period\":0.000000,\"SNR\":3.410000},\"AssociationInfo\":{\"Azimuth\":146.725914,\"Distance\":0.114828,\"Phase\":\"P\",\"Residual\":0.000904,\"Sigma\":1.000000},\"Filter\":[{\"HighPass\":1.050000,\"LowPass\":2.650000}],\"ID\":\"100725\",\"Phase\":\"P\",\"Picker\":\"raypicker\",\"Polarity\":\"up\",\"Site\":{\"Channel\":\"BHZ\",\"Location\":\"--\",\"Network\":\"AK\",\"Station\":\"SSN\"},\"Source\":{\"AgencyID\":\"US\",\"Author\":\"228041013\"},\"Time\":\"2015-08-14T03:35:25.947Z\",\"Type\":\"Pick\"}],\"Depth\":24.717898,\"Gap\":110.554774,\"ID\":\"20311B8E10AF5649BDC52ED099CF173E\",\"IsUpdate\":false,\"Latitude\":61.559315,\"Longitude\":-150.877897,\"MinimumDistance\":0.110850,\"Source\":{\"AgencyID\":\"US\",\"Author\":\"glass\"},\"T\":\"20150814033521.219\",\"Time\":\"2015-08-14T03:35:21.219Z\"}" // NOLINT @@ -35,18 +36,20 @@ TEST(Convert, HypoTest) { ASSERT_STREQ(parse::hypoToJSONDetection(NULL, agencyid, author).c_str(), ""); ASSERT_STREQ( - parse::hypoToJSONDetection(new json::Object(json::Deserialize(BADHYPOSTRING1)), agencyid, author).c_str(), // NOLINT + parse::hypoToJSONDetection(std::make_shared(json::Object(json::Deserialize(BADHYPOSTRING1))), agencyid, author).c_str(), // NOLINT ""); ASSERT_STREQ( - parse::hypoToJSONDetection(new json::Object( json::Deserialize(BADHYPOSTRING2)), agencyid, author).c_str(), // NOLINT + parse::hypoToJSONDetection(std::make_shared(json::Object(json::Deserialize(BADHYPOSTRING2))), agencyid, author).c_str(), // NOLINT ""); ASSERT_STREQ( - parse::hypoToJSONDetection(new json::Object( json::Deserialize(CANCELSTRING)), agencyid, author).c_str(), // NOLINT + parse::hypoToJSONDetection(std::make_shared(json::Object(json::Deserialize(CANCELSTRING))), agencyid, author).c_str(), // NOLINT ""); // Hypo std::string detectionoutput = parse::hypoToJSONDetection( - new json::Object(json::Deserialize(HYPOSTRING)), agencyid, author); + std::make_shared( + json::Object(json::Deserialize(HYPOSTRING))), + agencyid, author); // build detection object rapidjson::Document detectiondocument; detectionformats::detection detectionobject( @@ -121,19 +124,20 @@ TEST(Convert, CancelTest) { ASSERT_STREQ(parse::cancelToJSONRetract(NULL, agencyid, author).c_str(), ""); ASSERT_STREQ( - parse::cancelToJSONRetract(new json::Object(json::Deserialize(BADCANCELSTRING1)), agencyid, author).c_str(), // NOLINT + parse::cancelToJSONRetract(std::make_shared(json::Object(json::Deserialize(BADCANCELSTRING1))), agencyid, author).c_str(), // NOLINT ""); ASSERT_STREQ( - parse::cancelToJSONRetract(new json::Object( json::Deserialize(BADCANCELSTRING2)), agencyid, author).c_str(), // NOLINT + parse::cancelToJSONRetract(std::make_shared(json::Object(json::Deserialize(BADCANCELSTRING2))), agencyid, author).c_str(), // NOLINT ""); ASSERT_STREQ( - parse::cancelToJSONRetract(new json::Object( json::Deserialize(HYPOSTRING)), agencyid, author).c_str(), // NOLINT + parse::cancelToJSONRetract(std::make_shared(json::Object(json::Deserialize(HYPOSTRING))), agencyid, author).c_str(), // NOLINT ""); // Cancel std::string retractoutput = parse::cancelToJSONRetract( - new json::Object(json::Deserialize(CANCELSTRING)), agencyid, - author); + std::make_shared( + json::Object(json::Deserialize(CANCELSTRING))), + agencyid, author); // build detection object rapidjson::Document retractdocument; detectionformats::retract retractobject( @@ -163,10 +167,10 @@ TEST(Convert, SiteListTest) { // failure cases ASSERT_STREQ(parse::siteListToStationList(NULL).c_str(), ""); ASSERT_STREQ( - parse::siteListToStationList(new json::Object( json::Deserialize(BADSITELISTSTRING1))).c_str(), // NOLINT + parse::siteListToStationList(std::make_shared(json::Object( json::Deserialize(BADSITELISTSTRING1)))).c_str(), // NOLINT ""); ASSERT_STREQ( - parse::siteListToStationList(new json::Object( json::Deserialize(BADSITELISTSTRING2))).c_str(), // NOLINT + parse::siteListToStationList(std::make_shared(json::Object( json::Deserialize(BADSITELISTSTRING2)))).c_str(), // NOLINT ""); std::string sitelistfile = "./" + std::string(TESTPATH) + "/" @@ -182,14 +186,15 @@ TEST(Convert, SiteListTest) { inFile.close(); - json::Object* sitelistobject = new json::Object( - json::Deserialize(sitelist)); + std::shared_ptr sitelistobject = + std::make_shared( + json::Object(json::Deserialize(sitelist))); int numsites = (*sitelistobject)["SiteList"].ToArray().size(); std::string stationlist = parse::siteListToStationList(sitelistobject); - json::Object* stationlistobject = new json::Object( - json::Deserialize(stationlist)); + std::shared_ptr stationlistobject = std::make_shared< + json::Object>(json::Object(json::Deserialize(stationlist))); ASSERT_TRUE(stationlistobject->HasKey("Type")); ASSERT_STREQ((*stationlistobject)["Type"].ToString().c_str(), @@ -209,16 +214,17 @@ TEST(Convert, SiteLookupTest) { parse::siteLookupToStationInfoRequest(NULL, agencyid, author).c_str(), ""); ASSERT_STREQ( - parse::siteLookupToStationInfoRequest(new json::Object(json::Deserialize(BADSITELOOKUPSTRING1)), agencyid, author).c_str(), // NOLINT + parse::siteLookupToStationInfoRequest(std::make_shared( json::Object(json::Deserialize(BADSITELOOKUPSTRING1))), agencyid, author).c_str(), // NOLINT ""); ASSERT_STREQ( - parse::siteLookupToStationInfoRequest(new json::Object( json::Deserialize(CANCELSTRING)), agencyid, author).c_str(), // NOLINT + parse::siteLookupToStationInfoRequest(std::make_shared( json::Object( json::Deserialize(CANCELSTRING))), agencyid, author).c_str(), // NOLINT ""); // sitelookup std::string stationinforequestoutput = parse::siteLookupToStationInfoRequest( - new json::Object(json::Deserialize(SITELOOKUPSTRING)), + std::make_shared( + json::Object(json::Deserialize(SITELOOKUPSTRING))), agencyid, author); // build detection object rapidjson::Document stationdocument; diff --git a/parse/tests/gpickparser_unittest.cpp b/parse/tests/gpickparser_unittest.cpp index 30f81365..38ade7d7 100644 --- a/parse/tests/gpickparser_unittest.cpp +++ b/parse/tests/gpickparser_unittest.cpp @@ -2,6 +2,7 @@ #include #include +#include #define TESTGPICKSTRING1 "228041013 22637648 1 BOZ BHZ US 00 20150303000044.175 P -1.0000 U ? m 1.050 2.650 0.0 0.000000 3.49 0.000000 0.000000" // NOLINT #define TESTGPICKSTRING2 "228041013 22637649 1 BOZ BHZ US 00 20150303000045.175 P -1.0000 D i r 1.050 2.650 0.0 0.000000 3.49 0.000000 0.000000" // NOLINT @@ -9,7 +10,6 @@ #define TESTGPICKSTRING4 "228041013 22637651 1 BOZ BHZ US 00 20150303000047.175 P -1.0000 U q e 1.050 2.650 0.0 0.000000 3.49 0.000000 0.000000" // NOLINT #define TESTGPICKSTRING5 "228041013 22637652 1 BOZ BHZ US 00 20150303000048.175 P -1.0000 U q U 1.050 2.650 0.0 0.000000 3.49 0.000000 0.000000" // NOLINT - #define TESTFAILSTRING "228041013 22637648 1 BOZ BHZ US 00 P -1.0000 U ? r 1.050 2.650 0.0 0.000000 3.49 0.000000 0.000000" // NOLINT #define TESTAGENCYID "US" #define TESTAUTHOR "glasstest" @@ -37,7 +37,7 @@ class GPickParser : public ::testing::Test { TEST_F(GPickParser, Construction) { // assert that agencyid is ok ASSERT_STREQ(Parser->getAgencyid().c_str(), agencyid.c_str())<< - "AgencyID check"; + "AgencyID check"; // assert that author is ok ASSERT_STREQ(Parser->getAuthor().c_str(), author.c_str()) @@ -53,7 +53,7 @@ TEST_F(GPickParser, PickParsing) { std::string pickstring5 = std::string(TESTGPICKSTRING5); // pick 1 - json::Object * PickObject = Parser->parse(pickstring1); + std::shared_ptr PickObject = Parser->parse(pickstring1); // parse the origin ASSERT_FALSE(PickObject == NULL)<< "Parsed pick 1 not null."; @@ -62,54 +62,54 @@ TEST_F(GPickParser, PickParsing) { ASSERT_TRUE(Parser->validate(PickObject))<< "Parsed pick 1 is valid"; // pick 2 - PickObject = Parser->parse(pickstring2); + std::shared_ptr PickObject2 = Parser->parse(pickstring2); // parse the origin - ASSERT_FALSE(PickObject == NULL)<< "Parsed pick 2 not null."; + ASSERT_FALSE(PickObject2 == NULL)<< "Parsed pick 2 not null."; // validate the pick - ASSERT_TRUE(Parser->validate(PickObject))<< "Parsed pick 2 is valid"; + ASSERT_TRUE(Parser->validate(PickObject2))<< "Parsed pick 2 is valid"; // pick 3 - PickObject = Parser->parse(pickstring3); + std::shared_ptr PickObject3 = Parser->parse(pickstring3); // parse the origin - ASSERT_FALSE(PickObject == NULL)<< "Parsed pick 3 not null."; + ASSERT_FALSE(PickObject3 == NULL)<< "Parsed pick 3 not null."; // validate the pick - ASSERT_TRUE(Parser->validate(PickObject))<< "Parsed pick 3 is valid"; + ASSERT_TRUE(Parser->validate(PickObject3))<< "Parsed pick 3 is valid"; // pick 4 - PickObject = Parser->parse(pickstring4); + std::shared_ptr PickObject4 = Parser->parse(pickstring4); // parse the origin - ASSERT_FALSE(PickObject == NULL)<< "Parsed pick 4 not null."; + ASSERT_FALSE(PickObject4 == NULL)<< "Parsed pick 4 not null."; // validate the pick - ASSERT_TRUE(Parser->validate(PickObject))<< "Parsed pick 4 is valid"; + ASSERT_TRUE(Parser->validate(PickObject4))<< "Parsed pick 4 is valid"; // pick 5 - PickObject = Parser->parse(pickstring5); + std::shared_ptr PickObject5 = Parser->parse(pickstring5); // parse the origin - ASSERT_FALSE(PickObject == NULL)<< "Parsed pick 2 not null."; + ASSERT_FALSE(PickObject5 == NULL)<< "Parsed pick 2 not null."; // validate the pick - ASSERT_TRUE(Parser->validate(PickObject))<< "Parsed pick 2 is valid"; + ASSERT_TRUE(Parser->validate(PickObject5))<< "Parsed pick 2 is valid"; } // test failure TEST_F(GPickParser, FailTest) { std::string failstring = std::string(TESTFAILSTRING); - json::Object * FailObject = Parser->parse(failstring); + std::shared_ptr FailObject = Parser->parse(failstring); // parse the bad data ASSERT_TRUE(FailObject == NULL)<< "Parsed fail string is null."; // validate the bad data ASSERT_FALSE(Parser->validate(FailObject))<< - "Parsed failstring is not valid"; + "Parsed failstring is not valid"; // parse empty string FailObject = Parser->parse(""); @@ -119,5 +119,5 @@ TEST_F(GPickParser, FailTest) { // validate the bad data ASSERT_FALSE(Parser->validate(FailObject))<< - "Parsed empty string is not valid"; + "Parsed empty string is not valid"; } diff --git a/parse/tests/jsonparser_unittest.cpp b/parse/tests/jsonparser_unittest.cpp index 8ae8953a..eeda7bbf 100644 --- a/parse/tests/jsonparser_unittest.cpp +++ b/parse/tests/jsonparser_unittest.cpp @@ -3,6 +3,7 @@ #include #include +#include #define TESTDETECTIONSTRING "{\"Type\":\"Detection\",\"ID\":\"12GFH48776857\",\"Source\":{\"AgencyID\":\"US\",\"Author\":\"TestAuthor\"},\"Hypocenter\":{\"Latitude\":40.3344,\"Longitude\":-121.44,\"Depth\":32.44,\"Time\":\"2015-12-28T21:32:24.017Z\"},\"DetectionType\":\"New\",\"EventType\":\"earthquake\",\"Bayes\":2.65,\"MinimumDistance\":2.14,\"RMS\":3.8,\"Gap\":33.67,\"Data\":[{\"Type\":\"Pick\",\"ID\":\"12GFH48776857\",\"Site\":{\"Station\":\"BMN\",\"Network\":\"LB\",\"Channel\":\"HHZ\",\"Location\":\"01\"},\"Source\":{\"AgencyID\":\"US\",\"Author\":\"TestAuthor\"},\"Time\":\"2015-12-28T21:32:24.017Z\",\"Phase\":\"P\",\"Polarity\":\"up\",\"Onset\":\"questionable\",\"Picker\":\"manual\",\"Filter\":[{\"HighPass\":1.05,\"LowPass\":2.65}],\"Amplitude\":{\"Amplitude\":21.5,\"Period\":2.65,\"SNR\":3.8},\"AssociationInfo\":{\"Phase\":\"P\",\"Distance\":0.442559,\"Azimuth\":0.418479,\"Residual\":-0.025393,\"Sigma\":0.086333}},{\"Type\":\"Correlation\",\"ID\":\"12GFH48776857\",\"Site\":{\"Station\":\"BMN\",\"Network\":\"LB\",\"Channel\":\"HHZ\",\"Location\":\"01\"},\"Source\":{\"AgencyID\":\"US\",\"Author\":\"TestAuthor\"},\"Phase\":\"P\",\"Time\":\"2015-12-28T21:32:24.017Z\",\"Correlation\":2.65,\"Hypocenter\":{\"Latitude\":40.3344,\"Longitude\":-121.44,\"Depth\":32.44,\"Time\":\"2015-12-28T21:30:44.039Z\"},\"EventType\":\"earthquake\",\"Magnitude\":2.14,\"SNR\":3.8,\"ZScore\":33.67,\"DetectionThreshold\":1.5,\"ThresholdType\":\"minimum\",\"AssociationInfo\":{\"Phase\":\"P\",\"Distance\":0.442559,\"Azimuth\":0.418479,\"Residual\":-0.025393,\"Sigma\":0.086333}}]}" // NOLINT #define TESTCORRELATIONSTRING "{\"Type\":\"Correlation\",\"ID\":\"12GFH48776857\",\"Site\":{\"Station\":\"BMN\",\"Network\":\"LB\",\"Channel\":\"HHZ\",\"Location\":\"01\"},\"Source\":{\"AgencyID\":\"US\",\"Author\":\"TestAuthor\"},\"Phase\":\"P\",\"Time\":\"2015-12-28T21:32:24.017Z\",\"Correlation\":2.65,\"Hypocenter\":{\"Latitude\":40.3344,\"Longitude\":-121.44,\"Depth\":32.44,\"Time\":\"2015-12-28T21:30:44.039Z\"},\"EventType\":\"earthquake\",\"Magnitude\":2.14,\"SNR\":3.8,\"ZScore\":33.67,\"DetectionThreshold\":1.5,\"ThresholdType\":\"minimum\",\"AssociationInfo\":{\"Phase\":\"P\",\"Distance\":0.442559,\"Azimuth\":0.418479,\"Residual\":-0.025393,\"Sigma\":0.086333}}" // NOLINT @@ -53,7 +54,8 @@ TEST_F(JSONParser, Construction) { TEST_F(JSONParser, DetectionParsing) { std::string detectionstring = std::string(TESTDETECTIONSTRING); - json::Object * DetectionObject = Parser->parse(detectionstring); + std::shared_ptr DetectionObject = Parser->parse( + detectionstring); // parse the detection ASSERT_FALSE(DetectionObject == NULL)<< "Parsed detection not null."; @@ -67,7 +69,8 @@ TEST_F(JSONParser, DetectionParsing) { TEST_F(JSONParser, CorrelationParsing) { std::string correlationstring = std::string(TESTCORRELATIONSTRING); - json::Object * CorrelationObject = Parser->parse(correlationstring); + std::shared_ptr CorrelationObject = Parser->parse( + correlationstring); // parse the corrleation ASSERT_FALSE(CorrelationObject == NULL)<< "Parsed correlation not null."; @@ -81,7 +84,7 @@ TEST_F(JSONParser, CorrelationParsing) { TEST_F(JSONParser, PickParsing) { std::string pickstring = std::string(TESTPICKSTRING); - json::Object * PickObject = Parser->parse(pickstring); + std::shared_ptr PickObject = Parser->parse(pickstring); // parse the pick ASSERT_FALSE(PickObject == NULL)<< "Parsed pick not null."; @@ -94,7 +97,7 @@ TEST_F(JSONParser, PickParsing) { TEST_F(JSONParser, StationParsing) { std::string stationstring = std::string(TESTSTATIONSTRING); - json::Object * StationObject = Parser->parse(stationstring); + std::shared_ptr StationObject = Parser->parse(stationstring); // parse the pick ASSERT_FALSE(StationObject == NULL)<< "Parsed station not null."; @@ -111,7 +114,8 @@ TEST_F(JSONParser, FailTests) { std::string stationfailstring = std::string(TESTFAILSTATIONSTRING); // detection failure - json::Object * FailObject = Parser->parse(detectionfailstring); + std::shared_ptr FailObject = Parser->parse( + detectionfailstring); // parse the bad data ASSERT_FALSE(FailObject == NULL)<< "Parsed detection fail object not null."; diff --git a/parse/tests/parser_unittest.cpp b/parse/tests/parser_unittest.cpp index 562f99d7..a5734764 100644 --- a/parse/tests/parser_unittest.cpp +++ b/parse/tests/parser_unittest.cpp @@ -2,6 +2,7 @@ #include #include +#include #define TESTAGENCYID "US" #define TESTAUTHOR "glasstest" @@ -15,11 +16,11 @@ class parserstub : public parse::Parser { ~parserstub() { } - json::Object* parse(const std::string &input) override { + std::shared_ptr parse(const std::string &input) override { return (NULL); } - bool validate(json::Object* input) override { + bool validate(std::shared_ptr &input) override { return (true); } }; @@ -33,7 +34,7 @@ TEST(ParserTest, Construction) { // assert that agencyid is ok ASSERT_STREQ(Parser->getAgencyid().c_str(), agencyid.c_str())<< - "AgencyID check"; + "AgencyID check"; // assert that author is ok ASSERT_STREQ(Parser->getAuthor().c_str(), author.c_str())<< "Author check"; diff --git a/process/include/associator.h b/process/include/associator.h index b4dd6c00..c58b9abf 100644 --- a/process/include/associator.h +++ b/process/include/associator.h @@ -17,6 +17,7 @@ #include #include #include +#include /** * \namespace glass @@ -103,7 +104,7 @@ class Associator : public glasscore::IGlassSend, public util::iAssociator, * \param communication - A json::Object containing the message from * glasscore. */ - void Send(json::Object *communication) override; + void Send(std::shared_ptr communication) override; /** * \brief glasscore message sending function @@ -113,7 +114,7 @@ class Associator : public glasscore::IGlassSend, public util::iAssociator, * \param message - A json::Object containing the message to send to * glasscore. */ - void sendToAssociator(json::Object* message) override; + void sendToAssociator(std::shared_ptr &message) override; /** * \brief thread pool check function @@ -166,7 +167,7 @@ class Associator : public glasscore::IGlassSend, public util::iAssociator, * glasscore. * \return returns true if the dispatch was successful, false otherwise. */ - bool dispatch(json::Object *communication); + bool dispatch(std::shared_ptr communication); /** * \brief glasscore logging function @@ -192,9 +193,20 @@ class Associator : public glasscore::IGlassSend, public util::iAssociator, int m_iWorkCounter; /** - * \brief The duration of time spent getting data from the input queue. + * \brief Integer holding the count of input data sent to glasscore overall */ - std::chrono::duration tQueueDuration; + int m_iTotalWorkCounter; + + /** + * \brief Integer holding the count of used to compute the running average + * of data per second + */ + int m_iRunningAverageCounter; + + /** + * \brief Integer holding the the running average of data per second + */ + double m_dRunningAverage; /** * \brief The duration of time spent sending data to the glasscore. diff --git a/process/src/associator.cpp b/process/src/associator.cpp index cc70d3ab..5eb565b2 100644 --- a/process/src/associator.cpp +++ b/process/src/associator.cpp @@ -2,8 +2,11 @@ #include #include #include +#include #include #include +#include +#include namespace glass { // Construction/Destruction @@ -12,6 +15,10 @@ Associator::Associator() logger::log("debug", "associator::Associator(): Construction."); m_iWorkCounter = 0; + m_iTotalWorkCounter = 0; + m_iRunningAverageCounter = 0; + m_dRunningAverage = 0; + ReportInterval = 60; std::time(&tLastWorkReport); @@ -22,7 +29,6 @@ Associator::Associator() m_iCheckInterval = 600; - tQueueDuration = std::chrono::duration::zero(); tGlassDuration = std::chrono::duration::zero(); // clear / create object(s) @@ -36,6 +42,9 @@ Associator::Associator(util::iInput* inputint, util::iOutput* outputint) m_pGlass = NULL; m_MessageQueue = NULL; m_iWorkCounter = 0; + m_iTotalWorkCounter = 0; + m_iRunningAverageCounter = 0; + m_dRunningAverage = 0; ReportInterval = 60; std::time(&tLastWorkReport); @@ -49,7 +58,6 @@ Associator::Associator(util::iInput* inputint, util::iOutput* outputint) m_iCheckInterval = 600; - tQueueDuration = std::chrono::duration::zero(); tGlassDuration = std::chrono::duration::zero(); } @@ -89,9 +97,10 @@ bool Associator::setup(json::Object *config) { "associator::setup(): Class Core interface is NULL ."); return (false); } - + std::shared_ptr pConfig = std::make_shared( + *config); // send the config to glass - m_pGlass->dispatch(config); + m_pGlass->dispatch(pConfig); logger::log("debug", "associator::setup(): Done Passing in provided config."); @@ -136,13 +145,13 @@ void Associator::logGlass(glassutil::logMessageStruct message) { } } -void Associator::Send(json::Object *communication) { +void Associator::Send(std::shared_ptr communication) { // this probably could be the same function as dispatch... // ...except the interface won't let it be dispatch(communication); } -void Associator::sendToAssociator(json::Object* message) { +void Associator::sendToAssociator(std::shared_ptr &message) { if (m_MessageQueue != NULL) { m_MessageQueue->addDataToQueue(message); } @@ -162,37 +171,23 @@ bool Associator::work() { } // first check to see if we have any messages to send - json::Object* message = m_MessageQueue->getDataFromQueue(); + std::shared_ptr message = m_MessageQueue->getDataFromQueue(); if (message != NULL) { - logger::log( - "debug", - "associator::work: Got message:" + json::Serialize(*message)); - // send the message into glass m_pGlass->dispatch(message); } - time_t tNow; + std::time_t tNow; std::time(&tNow); - std::chrono::high_resolution_clock::time_point tQueueStartTime = - std::chrono::high_resolution_clock::now(); // now grab whatever input might have for us and send it into glass - json::Object* data = Input->getData(); - std::chrono::high_resolution_clock::time_point tQueueEndTime = - std::chrono::high_resolution_clock::now(); - - tQueueDuration += std::chrono::duration_cast>( - tQueueEndTime - tQueueStartTime); + std::shared_ptr data = Input->getData(); // only send in something if we got something if (data != NULL) { m_iWorkCounter++; - logger::log("debug", - "Associator::work: Got data:" + json::Serialize(*data)); - std::chrono::high_resolution_clock::time_point tGlassStartTime = std::chrono::high_resolution_clock::now(); // glass can sort things out from here @@ -204,44 +199,64 @@ bool Associator::work() { tGlassDuration += std::chrono::duration_cast< std::chrono::duration>(tGlassEndTime - tGlassStartTime); - - // logger::log("debug", "associator::work(): Sent data to glass."); } if ((tNow - tLastWorkReport) >= ReportInterval) { int pendingdata = Input->dataCount(); - double averagequeuetime = tQueueDuration.count() / m_iWorkCounter; double averageglasstime = tGlassDuration.count() / m_iWorkCounter; - if (m_iWorkCounter == 0) + + if (m_iWorkCounter == 0) { logger::log( "warning", "associator::work(): Sent NO data to glass in the last " + std::to_string( static_cast(tNow - tLastWorkReport)) + " seconds."); - else + } else { + int hypoListSize = 0; + int pickListSize = 0; + if (m_pGlass->getHypoList()) { + hypoListSize = m_pGlass->getHypoList()->getVHypoSize(); + } + if (m_pGlass->getPickList()) { + pickListSize = m_pGlass->getPickList()->getVPickSize(); + } + + m_iTotalWorkCounter += m_iWorkCounter; + + // calculate data per second average + double dataAverage = static_cast(m_iWorkCounter) + / static_cast((tNow - tLastWorkReport)); + + // calculate running average + m_iRunningAverageCounter++; + if (m_iRunningAverageCounter == 1) { + m_dRunningAverage = dataAverage; + } + + m_dRunningAverage = (m_dRunningAverage + * (m_iRunningAverageCounter - 1) + dataAverage) + / m_iRunningAverageCounter; + logger::log( "info", "Associator::work(): Sent " + std::to_string(m_iWorkCounter) + " data to glass (" + std::to_string(pendingdata) - + " pending) in the last " + + " in queue, " + std::to_string(m_iTotalWorkCounter) + + " total) in " + std::to_string( static_cast(tNow - tLastWorkReport)) - + " seconds. (" - + std::to_string( - static_cast(m_iWorkCounter) - / static_cast((tNow - - tLastWorkReport))) - + " data per second) (" - + std::to_string(averagequeuetime) - + " average queue time; " + + " seconds. (" + std::to_string(dataAverage) + + " dps) (" + std::to_string(m_dRunningAverage) + + " avg dps) (" + std::to_string(averageglasstime) - + " average glass time)."); + + " avg glass time) (" + "vPickSize: " + + std::to_string(pickListSize) + " vHypoSize: " + + std::to_string(hypoListSize) + ")."); + } tLastWorkReport = tNow; m_iWorkCounter = 0; - - tQueueDuration = std::chrono::duration::zero(); tGlassDuration = std::chrono::duration::zero(); } @@ -268,7 +283,7 @@ bool Associator::check() { } // process any messages glasscore sends us -bool Associator::dispatch(json::Object *communication) { +bool Associator::dispatch(std::shared_ptr communication) { // tell base class we're still alive ThreadBaseClass::setWorkCheck(); @@ -282,7 +297,7 @@ bool Associator::dispatch(json::Object *communication) { if (Output != NULL) { // Allocate a new json object to avoid // multi-thread pointer issues. - Output->sendToOutput(new json::Object(*communication)); + Output->sendToOutput(communication); } else { logger::log("error", "associator::dispatch(): Output interface is NULL, nothing " diff --git a/util/include/associatorinterface.h b/util/include/associatorinterface.h index 4cd46135..53e2bba6 100644 --- a/util/include/associatorinterface.h +++ b/util/include/associatorinterface.h @@ -8,6 +8,7 @@ #define ASSOCINTERFACE_H #include +#include /** * \namespace util @@ -40,7 +41,7 @@ class iAssociator { * \param message - A pointer to a json::object containing the data * to send to the associator library. */ - virtual void sendToAssociator(json::Object* message) = 0; + virtual void sendToAssociator(std::shared_ptr &message) = 0; // NOLINT }; } // namespace util #endif // ASSOCINTERFACE_H diff --git a/util/include/cache.h b/util/include/cache.h index 0a7299aa..eeec9d8a 100644 --- a/util/include/cache.h +++ b/util/include/cache.h @@ -14,6 +14,7 @@ #include #include #include +#include namespace util { /** @@ -81,8 +82,8 @@ class Cache : public util::BaseClass { * Defaults to true * \return returns true if successful, false otherwise. */ - virtual bool addToCache(json::Object * data, std::string id, bool lock = - true); + virtual bool addToCache(std::shared_ptr data, std::string id, + bool lock = true); /** *\brief remove data from cache @@ -123,8 +124,8 @@ class Cache : public util::BaseClass { * if the data * was not found */ - virtual json::Object * getFromCache(std::string id, bool lock = true, - bool copy = false); + virtual std::shared_ptr getFromCache(std::string id, + bool lock = true); /** * \brief get next data from cache @@ -138,8 +139,8 @@ class Cache : public util::BaseClass { * NULL if there is no * more data available. */ - virtual json::Object * getNextFromCache(bool restart = false, bool lock = - true); + virtual std::shared_ptr getNextFromCache(bool restart = false, + bool lock = true); /** *\brief clear data from cache @@ -216,7 +217,7 @@ class Cache : public util::BaseClass { /** * \brief the std::map used to store the cache */ - std::map m_Cache; + std::map> m_Cache; /** * \brief a boolean flag indicating whether the cache has @@ -227,7 +228,7 @@ class Cache : public util::BaseClass { /** * \brief a std::map iterator used to output the cache */ - std::map::iterator m_CacheDumpItr; + std::map>::iterator m_CacheDumpItr; /** * \brief the mutex for the cache diff --git a/util/include/inputinterface.h b/util/include/inputinterface.h index 68905cf8..6dfc056b 100644 --- a/util/include/inputinterface.h +++ b/util/include/inputinterface.h @@ -8,6 +8,7 @@ #define INPUTINTERFACE_H #include +#include namespace util { @@ -31,7 +32,7 @@ class iInput { * \return Returns a pointer to a json::object containing the input * data. */ - virtual json::Object* getData() = 0; + virtual std::shared_ptr getData() = 0; /** * \brief Get count of remaining input data diff --git a/util/include/outputinterface.h b/util/include/outputinterface.h index dda23397..740f8cf6 100644 --- a/util/include/outputinterface.h +++ b/util/include/outputinterface.h @@ -2,6 +2,7 @@ #define OUTPUTINTERFACE_H #include +#include namespace util { @@ -24,7 +25,7 @@ struct iOutput { * \param data - A pointer to a json::object containing the output * data. */ - virtual void sendToOutput(json::Object* data) = 0; + virtual void sendToOutput(std::shared_ptr &data) = 0; // NOLINT }; } // namespace util #endif // OUTPUTINTERFACE_H diff --git a/util/include/queue.h b/util/include/queue.h index 0c9fc38b..a1fe35b5 100644 --- a/util/include/queue.h +++ b/util/include/queue.h @@ -9,6 +9,7 @@ #include +#include #include #include #include @@ -45,7 +46,7 @@ class Queue { * Defaults to true * \return returns true if successful, false otherwise. */ - bool addDataToQueue(json::Object * data, bool lock = true); + bool addDataToQueue(std::shared_ptr data, bool lock = true); /** *\brief get data from queue @@ -60,7 +61,7 @@ class Queue { * there was no * data in the queue */ - json::Object * getDataFromQueue(bool lock = true, bool copy = false); + std::shared_ptr getDataFromQueue(bool lock = true); /** *\brief clear data from queue @@ -86,7 +87,7 @@ class Queue { /** * \brief the std::queue used to store the queue */ - std::queue m_DataQueue; + std::queue> m_DataQueue; /** * \brief the mutex for the queue diff --git a/util/src/cache.cpp b/util/src/cache.cpp index d8861b31..ea0631f1 100644 --- a/util/src/cache.cpp +++ b/util/src/cache.cpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace util { @@ -107,7 +108,8 @@ void Cache::clear() { } // cache managment -bool Cache::addToCache(json::Object * data, std::string id, bool lock) { +bool Cache::addToCache(std::shared_ptr data, std::string id, + bool lock) { if (data == NULL) { logger::log("error", "cache::addtocache(): Bad json object passed in."); return (false); @@ -127,16 +129,9 @@ bool Cache::addToCache(json::Object * data, std::string id, bool lock) { // see if we have it already if (m_Cache.find(id) != m_Cache.end()) { // we do, replace what we have - // grab the old - json::Object * olddata = m_Cache[id]; - // update the cache m_Cache[id] = data; - // cleanup - if (olddata != NULL) - delete (olddata); - if (lock) { m_CacheMutex.unlock(); } @@ -195,16 +190,9 @@ bool Cache::removeFromCache(std::string id, bool lock) { return (false); } - // grab the old - json::Object * olddata = m_Cache[id]; - // erase the element from the map m_Cache.erase(m_Cache.find(id)); - // cleanup - if (olddata != NULL) - delete (olddata); - if (lock) { m_CacheMutex.unlock(); } @@ -247,7 +235,7 @@ bool Cache::isInCache(std::string id, bool lock) { return (true); } -json::Object * Cache::getFromCache(std::string id, bool lock, bool copy) { +std::shared_ptr Cache::getFromCache(std::string id, bool lock) { // don't do anything if we didn't get an id if (id == "") { logger::log("error", "cache::getfromcache(): Bad ID passed in."); @@ -276,11 +264,7 @@ json::Object * Cache::getFromCache(std::string id, bool lock, bool copy) { } // get result from cache - json::Object *data; - if (copy) - data = new json::Object(*m_Cache[id]); - else - data = m_Cache[id]; + std::shared_ptr data = m_Cache[id]; if (lock) { m_CacheMutex.unlock(); @@ -295,7 +279,7 @@ json::Object * Cache::getFromCache(std::string id, bool lock, bool copy) { return (data); } -json::Object * Cache::getNextFromCache(bool restart, bool lock) { +std::shared_ptr Cache::getNextFromCache(bool restart, bool lock) { // lock in case someone else is using the cache if (lock) { m_CacheMutex.lock(); @@ -322,7 +306,8 @@ json::Object * Cache::getNextFromCache(bool restart, bool lock) { } // get current data from the iterator - json::Object * data = (json::Object *) m_CacheDumpItr->second; + std::shared_ptr data = + (std::shared_ptr) m_CacheDumpItr->second; // advance the iterator ++m_CacheDumpItr; @@ -390,7 +375,7 @@ bool Cache::loadCacheFromDisk(bool lock) { // make sure we've not got the empty line at the end of the file if (line.length() > 0) { // try to convert the line to a json object - json::Object *datatoadd = NULL; + std::shared_ptr datatoadd; try { json::Value deserializeddata = json::Deserialize(line); @@ -405,7 +390,8 @@ bool Cache::loadCacheFromDisk(bool lock) { } // convert our resulting value to a json object - datatoadd = new json::Object(deserializeddata.ToObject()); + datatoadd = std::make_shared( + json::Object(deserializeddata.ToObject())); } catch (const std::runtime_error &e) { // oopse std::string exceptionstring = e.what(); @@ -564,11 +550,12 @@ bool Cache::writeCacheToDisk(bool lock) { } // now go through the whole station cache - std::map::iterator CacheItr; + std::map>::iterator CacheItr; for (CacheItr = m_Cache.begin(); CacheItr != m_Cache.end(); ++CacheItr) { // get the current station - json::Object * data = (json::Object *) CacheItr->second; + std::shared_ptr data = + (std::shared_ptr) CacheItr->second; std::string id = CacheItr->first; // make sure we have an id diff --git a/util/src/queue.cpp b/util/src/queue.cpp index 6df75785..eaef97f2 100644 --- a/util/src/queue.cpp +++ b/util/src/queue.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -21,7 +22,7 @@ Queue::~Queue() { clearQueue(); } -bool Queue::addDataToQueue(json::Object * data, bool lock) { +bool Queue::addDataToQueue(std::shared_ptr data, bool lock) { if (lock) { m_QueueMutex.lock(); } @@ -36,7 +37,7 @@ bool Queue::addDataToQueue(json::Object * data, bool lock) { return (true); } -json::Object * Queue::getDataFromQueue(bool lock, bool copy) { +std::shared_ptr Queue::getDataFromQueue(bool lock) { if (lock) { m_QueueMutex.lock(); } @@ -50,12 +51,8 @@ json::Object * Queue::getDataFromQueue(bool lock, bool copy) { } // get the next element - json::Object *data; - if (copy) { - data = new json::Object(*m_DataQueue.front()); - } else { - data = m_DataQueue.front(); - } + std::shared_ptr data; + data = m_DataQueue.front(); // remove that element now that we got it m_DataQueue.pop(); diff --git a/util/tests/cache_unittest.cpp b/util/tests/cache_unittest.cpp index b936a19c..a23b88bc 100644 --- a/util/tests/cache_unittest.cpp +++ b/util/tests/cache_unittest.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #define TESTDATA1 "{\"HighPass\":1.000000,\"LowPass\":1.000000,\"cacheid\":\"test1\"}" // NOLINT #define TESTDATA1ID "test1" @@ -59,18 +60,18 @@ TEST(CacheTest, CombinedTest) { // create input data std::string inputstring1 = std::string(TESTDATA1); - json::Object* inputdata1 = new json::Object( - json::Deserialize(inputstring1)); + std::shared_ptr inputdata1 = std::make_shared( + json::Object(json::Deserialize(inputstring1))); std::string inputid1 = std::string(TESTDATA1ID); std::string inputstring2 = std::string(TESTDATA2); - json::Object* inputdata2 = new json::Object( - json::Deserialize(inputstring2)); + std::shared_ptr inputdata2 = std::make_shared( + json::Object(json::Deserialize(inputstring2))); std::string inputid2 = std::string(TESTDATA2ID); std::string inputstring3 = std::string(TESTDATA3); - json::Object* inputdata3 = new json::Object( - json::Deserialize(inputstring3)); + std::shared_ptr inputdata3 = std::make_shared( + json::Object(json::Deserialize(inputstring3))); std::string inputid3 = std::string(TESTDATA3ID); // add data to cache @@ -93,9 +94,12 @@ TEST(CacheTest, CombinedTest) { // get data from cache ASSERT_TRUE(NULL == TestCache->getFromCache("")); - json::Object* outputobject1 = TestCache->getFromCache(inputid1); - json::Object* outputobject2 = TestCache->getFromCache(inputid2); - json::Object* outputobject3 = TestCache->getFromCache(inputid3); + std::shared_ptr outputobject1 = TestCache->getFromCache( + inputid1); + std::shared_ptr outputobject2 = TestCache->getFromCache( + inputid2); + std::shared_ptr outputobject3 = TestCache->getFromCache( + inputid3); // assert that we got something ASSERT_TRUE(outputobject1 != NULL)<< "non-null cache data 1 (getfromcache)"; diff --git a/util/tests/queue_unittest.cpp b/util/tests/queue_unittest.cpp index 1c1119b4..c04a5ff6 100644 --- a/util/tests/queue_unittest.cpp +++ b/util/tests/queue_unittest.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #define TESTDATA1 "{\"HighPass\":1.000000,\"LowPass\":1.000000}" #define TESTDATA2 "{\"HighPass\":2.000000,\"LowPass\":2.000000}" @@ -16,24 +17,27 @@ TEST(QueueTest, CombinedTest) { // create input data std::string inputstring1 = std::string(TESTDATA1); - json::Object inputdata1 = json::Deserialize(inputstring1); + std::shared_ptr inputdata1 = std::make_shared( + json::Deserialize(inputstring1)); std::string inputstring2 = std::string(TESTDATA2); - json::Object inputdata2 = json::Deserialize(inputstring2); + std::shared_ptr inputdata2 = std::make_shared( + json::Deserialize(inputstring2)); std::string inputstring3 = std::string(TESTDATA3); - json::Object inputdata3 = json::Deserialize(inputstring3); + std::shared_ptr inputdata3 = std::make_shared( + json::Deserialize(inputstring3)); // add data to queue - TestQueue->addDataToQueue(&inputdata1); - TestQueue->addDataToQueue(&inputdata2); - TestQueue->addDataToQueue(&inputdata3); + TestQueue->addDataToQueue(inputdata1); + TestQueue->addDataToQueue(inputdata2); + TestQueue->addDataToQueue(inputdata3); // assert three items in the queue ASSERT_EQ(TestQueue->size(), 3)<< "3 items in queue"; // get data from queue - json::Object* outputobject = TestQueue->getDataFromQueue(); + std::shared_ptr outputobject = TestQueue->getDataFromQueue(); // assert that we got something ASSERT_TRUE(outputobject != NULL)<< "non-null queue data";