// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
int PluginRegistry::loadPlugins() {
	for ( NameList::const_iterator it = _pluginNames.begin();
	      it != _pluginNames.end(); ++it ) {
		if ( it->empty() ) continue;
		std::string filename = find(*it);
		if ( filename.empty() ) {
			SEISCOMP_ERROR("Did not find plugin %s", it->c_str());
			return -1;
		}

		SEISCOMP_DEBUG("Trying to open plugin at %s", filename.c_str());
		PluginEntry e = open(filename);
		if ( e.plugin == NULL ) {
			if ( e.handle == NULL ) {
				SEISCOMP_ERROR("Unable to load plugin %s", it->c_str());
				return -1;
			}
			else
				SEISCOMP_WARNING("The plugin %s has been loaded already",
				                 it->c_str());
			continue;
		}

		SEISCOMP_INFO("Plugin %s registered", it->c_str());
		_plugins.push_back(e);
	}

	return _plugins.size();
}
Beispiel #2
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void Import::readSinkMessages()
{
	while ( !_exitRequested ) {
		int error;
		Communication::NetworkMessagePtr networkMsgPtr;
		networkMsgPtr = _sink->receive(true, &error);
		if ( error != Core::Status::SEISCOMP_SUCCESS ) {
			bool first = true;

			while ( !_exitRequested ) {
				if ( first )
					SEISCOMP_WARNING("Connection lost to sink, trying to reconnect");

				_sink->reconnect();
				if ( _sink->isConnected() ) {
					SEISCOMP_INFO("Reconnected successfully to sink");
					break;
				}
				else {
					if ( first ) {
						first = false;
						SEISCOMP_INFO("Reconnecting to sink failed, trying again every 2 seconds");
					}
					Core::sleep(2);
				}
			}
		}
	}

	SEISCOMP_INFO("Leaving sink message thread");
}
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
PluginRegistry::PluginEntry PluginRegistry::open(const std::string &file) const {
	// Load shared library
#ifdef WIN32
	void *handle = LoadLibrary(file.c_str());
#else
	void *handle = dlopen(file.c_str(), RTLD_NOW | RTLD_GLOBAL);
#endif
	if ( !handle ) {
		SEISCOMP_ERROR("Loading plugin %s failed: %s", file.c_str(), sysLastError().c_str());
		return PluginEntry(NULL, NULL, file);
	}

	if ( findLibrary(handle) ) {
		return PluginEntry(handle, NULL, file);
	}

#ifndef WIN32
	// Reset errors
	dlerror();

	// Load factory
	Core::Plugin::CreateFunc func;
	*(void **)(&func) = dlsym(handle, "createSCPlugin");
#else
	Core::Plugin::CreateFunc func = (Core::Plugin::CreateFunc)GetProcAddress((HMODULE)handle, "createSCPlugin");
#endif
	if ( !func ) {
		SEISCOMP_ERROR("Could not load symbol createPlugin: %s", sysLastError().c_str());
#ifndef WIN32
		dlclose(handle);
#else
		FreeLibrary((HMODULE)handle);
#endif
		return PluginEntry(NULL, NULL, file);
	}

	Core::Plugin *plugin = func();
	if ( !plugin ) {
		SEISCOMP_ERROR("No plugin return from %s", file.c_str());
#ifndef WIN32
		dlclose(handle);
#else
		FreeLibrary((HMODULE)handle);
#endif
		return PluginEntry(NULL, NULL, file);
	}

	// Do not warn for different patch versions. They must be binary compatible
	// by definition.
	if ( (SC_API_VERSION_MAJOR(plugin->description().apiVersion) != SC_API_VERSION_MAJOR(SC_API_VERSION)) ||
	     (SC_API_VERSION_MINOR(plugin->description().apiVersion) > SC_API_VERSION_MINOR(SC_API_VERSION)) ) {
		SEISCOMP_WARNING("API version mismatch (%d.%d != %d.%d) can lead to unpredicted behaviour: %s",
		                 SC_API_VERSION_MAJOR(plugin->description().apiVersion),
		                 SC_API_VERSION_MINOR(plugin->description().apiVersion),
		                 SC_API_VERSION_MAJOR(SC_API_VERSION), SC_API_VERSION_MINOR(SC_API_VERSION),
		                 file.c_str());
	}

	return PluginEntry(handle, plugin, file);
}
Beispiel #4
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
string allocateEventID(DatabaseArchive *ar, const Origin *origin,
                       const string &prefix, const string &pattern,
                       const Client::Config::StringSet *blackList) {
	if ( !origin )
		return "";

	int year, yday, hour, min, sec, usec;

	if ( !origin->time().value().get2(&year, &yday, &hour, &min, &sec, &usec) )
		return "";

	uint64_t width;
	// Maximum precission is 1 millisecond
	uint64_t x = uint64_t((((yday*24)+hour)*60+min)*60+sec)*1000 + usec/1000;

	string text;
	string eventID = generateEventID(year, x, prefix, pattern, text, &width);
	ObjectPtr o = ar?ar->getObject(Event::TypeInfo(), eventID):Event::Find(eventID);
	bool blocked = (blackList != NULL) && (blackList->find(text) != blackList->end());

	if ( !o && !blocked )
		return eventID;

	if ( blocked ) SEISCOMP_WARNING("Blocked ID: %s (rejected %s)", eventID.c_str(), text.c_str());

	for ( int i = 1; i < 5; ++i ) {
		eventID = generateEventID(year, x+i*width, prefix, pattern, text);
		blocked = (blackList != NULL) && (blackList->find(text) != blackList->end());
		o = ar?ar->getObject(Event::TypeInfo(), eventID):Event::Find(eventID);
		if ( !o && !blocked )
			return eventID;
		if ( blocked ) SEISCOMP_WARNING("Blocked ID: %s (rejected %s)", eventID.c_str(), text.c_str());
	}

	for ( int i = 1; i < 5; ++i ) {
		eventID = generateEventID(year, x-i*width, prefix, pattern, text);
		blocked = (blackList != NULL) && (blackList->find(text) != blackList->end());
		o = ar?ar->getObject(Event::TypeInfo(), eventID):Event::Find(eventID);
		if ( !o && !blocked )
			return eventID;
		if ( blocked ) SEISCOMP_WARNING("Blocked ID: %s (rejected %s)", eventID.c_str(), text.c_str());
	}

	return "";
}
Beispiel #5
0
bool PolyRegions::readFepBoundaries(const std::string& filename) {
	SEISCOMP_DEBUG("reading boundary polygons from file: %s", filename.c_str());

	std::ifstream infile(filename.c_str());

	if (infile.bad())
		return false;

	boost::regex vertexLine("^\\s*([-+]?[0-9]*\\.?[0-9]+)\\s+([-+]?[0-9]*\\.?[0-9]+)(?:\\s+([^\\d\\s].*)$|\\s*$)");
	boost::regex LLine("^\\s*L\\s+(.*)$");
	boost::smatch what;

	std::string line;
	bool newPolygon = true;
	GeoFeature *pr = NULL;
	OPT(Vertex) last;

	while(std::getline(infile, line)) {

		if (newPolygon){
			pr = new GeoFeature();
			newPolygon = false;
		}

		if ( boost::regex_match(line, what, vertexLine) ) {
			if ( last ) pr->addVertex(*last);
			last = Vertex(atof(what.str(2).c_str()), atof(what.str(1).c_str()));
		}
		else if (boost::regex_match(line, what, LLine)) {
			if ( last && pr->vertices().size() > 0 ) {
				if ( *last != pr->vertices().back() )
					pr->addVertex(*last);
			}

			if ( pr->vertices().size() < 3 )
				delete pr;
			else {
				pr->setName(what.str(1));
				pr->setClosedPolygon(true);
				addRegion(pr);

				if ( pr->area() < 0 )
					SEISCOMP_WARNING("Polygon %s is defined clockwise", pr->name().c_str());
			}

			last = Core::None;
			newPolygon = true;
		}
		else {
			//std::cout << "Warning: line ignored: " << line << std::endl;
		}
		
	}

	return true;

}
Beispiel #6
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
int priority(const Origin *origin) {
	EvaluationMode mode = AUTOMATIC;
	try {
		mode = origin->evaluationMode();
	}
	catch ( ValueException& ) {}

	switch ( mode ) {
		case MANUAL:

			try {

				switch ( origin->evaluationStatus() ) {
					case PRELIMINARY: return 0;
					case CONFIRMED: return 1;
					case REVIEWED: return 2;
					case FINAL: return 3;
					case REPORTED: return -1;
					case REJECTED: return -100;
					default: break;
				}

			}
			catch ( ValueException& ) {
				return 1;
			}

			break;

		case AUTOMATIC:
		default:

			try {

				switch ( origin->evaluationStatus() ) {
					case PRELIMINARY: return 0;
					case CONFIRMED: return 1;
					case REVIEWED: return 2;
					case FINAL: return 3;
					case REPORTED: return -1;
					case REJECTED: return -100;
					default: break;
				}

			}
			catch ( ValueException& ) {
				return 0;
			}

			break;
	}

	SEISCOMP_WARNING("Origin %s has unknown evaluation mode", origin->publicID().c_str());

	return 0;
}
Beispiel #7
0
void QLClient::listen() {
	IO::QuakeLink::RequestFormat rf = _config->gzip ?
	                                 (_config->native ? IO::QuakeLink::rfGZNative : IO::QuakeLink::rfGZXML) :
	                                 (_config->native ? IO::QuakeLink::rfNative : IO::QuakeLink::rfXML);
	// activate socket timeout if keepAlive was requested
	if ( _config->options & IO::QuakeLink::opKeepAlive ) {
		if ( _sock ) {
			_sock->setTimeout(60);
		}
		else {
			SEISCOMP_ERROR("%sinstance not initialized", _logPrefix.c_str());
			return;
		}
	}

	while ( !interrupted() ) {
		// determine start time of request
		Core::Time from;
		string filter = _config->filter;
		if ( _backLog > 0 ) {
			Core::Time minTime = Core::Time::GMT() - Core::TimeSpan(_backLog);
			from = lastUpdate();
			if ( !from.valid() || from < minTime )
				from = minTime;
			if ( !filter.empty() )
				filter += " AND ";
			filter += "UPDATED > " + from.toString(IO::QuakeLink::RequestTimeFormat);
		}

		// start request
		try {
			select(from.valid(), Core::Time(), Core::Time(), rf, filter);
		}
		catch ( Core::GeneralException& e) {
			if ( interrupted() )
				break;
			SEISCOMP_DEBUG("%sselect exception: %s", _logPrefix.c_str(), e.what());
		}

		_sock->close(); // clears interrupt flag
		SEISCOMP_WARNING("%sQuakeLink connection closed, trying to reconnect "
		                 "in 5s", _logPrefix.c_str());

		for ( int i = 0; i < 50; ++i ) {
			usleep(100000); // 100ms

			if ( interrupted() )
				break;
		}
	}

	if ( interrupted() )
		SEISCOMP_INFO("%sQuakeLink connection interrupted", _logPrefix.c_str());
	_sock->close();
}
Beispiel #8
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool Processor::handleGap(Filter *, const Core::TimeSpan &ts, double, double,
                          size_t missingSamples) {
	SEISCOMP_WARNING("%s: detected gap of %.6f secs or %lu samples: reset processing",
	                 Private::toStreamID(_waveformID).c_str(), (double)ts,
	                 (unsigned long)missingSamples);
	// Flush what is possible
	flush();
	// Reset the processor
	reset();
	return true;
}
Beispiel #9
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool DbPlugin::connectToDb() {
	int counter = 0;
	while ( operational() && !_db->connect(_dbWriteConnection.c_str()) ) {
		if ( counter == 0 )
			SEISCOMP_ERROR("Database check... connection refused, retry");
		++counter;
		Core::sleep(1);

		if ( counter > 10 ) {
			SEISCOMP_ERROR("Database check... connection not available, abort");
			return false;
		}
	}

	if ( !operational() ) return true;

	SEISCOMP_INFO("Database connection established");

	_dbArchive = new DataModel::DatabaseArchive(_db.get());

	if ( !_dbArchive ) {
		SEISCOMP_ERROR("DbPlugin: Could not create DBArchive");
		return false;
	}

	if ( _dbArchive->hasError() )
		return false;

	Core::Version localSchemaVersion = Core::Version(DataModel::Version::Major, DataModel::Version::Minor);
	if ( localSchemaVersion > _dbArchive->version() ) {
		SEISCOMP_WARNING("Database schema v%s is older than schema v%s "
		                 "currently supported. Information will be lost when "
		                 "saving objects to the database! This should be fixed!",
		                 _dbArchive->version().toString().c_str(),
		                 localSchemaVersion.toString().c_str());
		if ( _strictVersionMatch ) {
			SEISCOMP_ERROR("Strict version check is enabled and schema versions "
			               "do not match.");
			return false;
		}
		else
			SEISCOMP_INFO("Strict version check is disabled and different "
			              "schema versions are not treated as error");
	}
	else
		SEISCOMP_DEBUG("Database check... ok");

	return true;
}
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void AmplitudeProcessor::fill(size_t n, double *samples) {
	if ( _config.saturationThreshold > 0 ) {
		for ( size_t i = 0; i < n; ++i ) {
			if ( fabs(samples[i]) > _config.saturationThreshold ) {
				SEISCOMP_WARNING("%s: data clipped: %f > %f",
				                 _stream.lastRecord->streamID().c_str(),
				                 fabs(samples[i]), _config.saturationThreshold);
				setStatus(DataClipped, samples[i]);
				break;
			}
		}
	}

	TimeWindowProcessor::fill(n, samples);
}
Beispiel #11
0
Core::BaseObject *Importer::get(std::streambuf* buf) {
	if ( _typemap == NULL ) return NULL;
	if ( buf == NULL ) return NULL;

	_result = NULL;

	xmlDocPtr doc;
	doc = xmlReadIO(streamBufReadCallback,
	                streamBufCloseCallback,
	                buf, NULL, NULL, 0);

	if ( doc == NULL )
		return NULL;

	xmlNodePtr cur = xmlDocGetRootElement(doc);
	if ( cur == NULL ) {
		xmlFreeDoc(doc);
		return NULL;
	}

	_any.mapper = _typemap;

	bool saveStrictNsCheck = NodeHandler::strictNsCheck;

	if ( !_headerNode.empty() ) {
		// Check the root tag matching "seiscomp"
		if ( xmlStrcmp(cur->name, (const xmlChar*)_headerNode.c_str()) ) {
			SEISCOMP_WARNING("Invalid root tag: %s, expected: %s", cur->name, _headerNode.c_str());
			xmlFreeDoc(doc);
			return NULL;
		}

		NodeHandler::strictNsCheck = _strictNamespaceCheck;
		_hasErrors = traverse(&_any, cur, cur->children, NULL) == false;
	}
	else {
		NodeHandler::strictNsCheck = _strictNamespaceCheck;
		_hasErrors = traverse(&_any, NULL, cur, NULL) == false;
	}

	NodeHandler::strictNsCheck = saveStrictNsCheck;

	xmlFreeDoc(doc);

	return _result;
}
Beispiel #12
0
bool GenericHandler::get(Core::BaseObject *, void *n) {
	xmlNodePtr node = reinterpret_cast<xmlNodePtr>(n);

	const char *classname = mapper->getClassname((const char*)node->name, node->ns?(const char*)node->ns->href:"", strictNsCheck);
	if ( classname == NULL ) {
		SEISCOMP_DEBUG("No class mapping for %s, ns = '%s'", node->name, node->ns?(const char*)node->ns->href:"");
		return false;
	}

	Core::BaseObject *obj = mapper->createClass(classname);
	if ( obj == NULL ) {
		SEISCOMP_WARNING("Unable to create instance of %s", classname);
		return false;
	}

	propagate(obj, true, true);
	return true;
}
Beispiel #13
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void QcPlugin::generateAlert(const QcBuffer *shortBuffer,
                             const QcBuffer *longBuffer) const {
	if ( shortBuffer->empty() || longBuffer->empty() ) return;

	//shortBuffer->info(); Short Term buffer info
	//lta->info(); Long Term buffer info

	double sta = mean(shortBuffer);
	//double staStdDev = stdDev(shortBuffer, sta);

	double lta = mean(longBuffer);
	double ltaStdDev = stdDev(longBuffer, lta);

	double relative = 0.0;

	//! HACK
	if (ltaStdDev != 0.0)
		relative =  100.0 - ( (ltaStdDev - fabs(lta - sta)) / ltaStdDev ) * 100.0;

	string f = "\033[32m"; // green colour

	if (fabs(relative) > *(_qcConfig->alertThresholds().begin())) { // HACK multi thresholds not yet implemented!
		
		DataModel::WaveformQuality* obj = new DataModel::WaveformQuality();
		obj->setWaveformID(getWaveformID(_streamID));
		obj->setCreatorID(_app->creatorID());
		obj->setCreated(Core::Time::GMT());
		obj->setStart(shortBuffer->startTime());
		obj->setEnd(shortBuffer->endTime());
		obj->setType("alert");
		obj->setParameter(_parameterNames[0]);
		obj->setValue(sta);
		obj->setLowerUncertainty(relative);
		obj->setUpperUncertainty(lta);
		obj->setWindowLength((double)shortBuffer->length());

		pushObject(obj);
	
		f = "\033[31m"; // red colour
		SEISCOMP_WARNING("%s %s %s %.0f%% \033[30m  %.3f %.3f", _streamID.c_str(), _parameterNames[0].c_str(), f.c_str(), relative, fabs(relative), lta);
	}
}
Beispiel #14
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool SC3GF1DArchive::setSource(std::string source) {
	fs::path directory;
	try {
		directory = SC_FS_PATH(source);
	}
	catch ( ... ) {
		SEISCOMP_ERROR("Unable to open directory: %s", source.c_str());
		return false;
	}

	_baseDirectory = source;

	fs::directory_iterator end_itr;
	try {
		for ( fs::directory_iterator itr(directory); itr != end_itr; ++itr ) {
			if ( !fs::is_directory(*itr) ) continue;

			std::string name = SC_FS_IT_LEAF(itr);

			/*
			size_t pos = name.rfind("_efl");
			if ( pos == std::string::npos ) continue;
			*/

			std::string model = name/*.substr(0, pos)*/;

			std::ifstream ifDesc;

			int depthFrom = -1, depthTo = -1, depthSpacing = -1;
			int distanceFrom = -1, distanceTo = -1, distanceSpacing = -1;
			std::string line;

			ifDesc.open((_baseDirectory + "/" + name + ".desc").c_str());
			if ( !ifDesc.is_open() ) {
				SEISCOMP_WARNING("Unable to find model description, skipping directory: %s",
				                 name.c_str());
				continue;
			}

			bool validModel = true;

			DoubleList &depths = _models[model].depths;
			DoubleList &dists = _models[model].distances;

			while ( getline(ifDesc, line) ) {
				Core::trim(line);
				if ( line.empty() ) continue;
				if ( line[0] == '#' ) continue;
				std::stringstream ss(line);
				ss >> line;
				if ( line == "depth" ) {
					ss >> depthFrom >> depthTo >> depthSpacing;

					if ( (depthSpacing < 0) || (depthFrom > depthTo) ) {
						SEISCOMP_WARNING("Invalid description format, skipping directory: %s",
						                 name.c_str());
						validModel = false;
						break;
					}

					if ( depthSpacing == 0 )
						depths.insert(depthFrom);
					else {
						for ( int i = depthFrom; i <= depthTo; i += depthSpacing )
							depths.insert(i);
					}

				}
				else if ( line == "distance" ) {
					ss >> distanceFrom >> distanceTo >> distanceSpacing;

					if ( (distanceSpacing < 0) || (distanceFrom > distanceTo) ) {
						SEISCOMP_WARNING("Invalid description format, skipping directory: %s",
						                 name.c_str());
						validModel = false;
						break;
					}

					if ( distanceSpacing == 0 )
						dists.insert(distanceFrom);
					else {
						for ( int i = distanceFrom; i <= distanceTo; i += distanceSpacing )
							dists.insert(i);
					}
				}
			}
Beispiel #15
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
int priority(const DataModel::FocalMechanism *fm) {
	EvaluationMode mode = AUTOMATIC;
	try {
		mode = fm->evaluationMode();
	}
	catch ( ValueException& ) {}

	switch ( mode ) {
		case MANUAL:

			try {

				switch ( fm->evaluationStatus() ) {
					case PRELIMINARY: return 0;
					case CONFIRMED: return 1;
					case REVIEWED: return 2;
					case FINAL: return 3;
					case REPORTED: return -1;
					case REJECTED: return -100;
					default: break;
				}

			}
			catch ( ValueException& ) {
				return 1;
			}

			break;

		case AUTOMATIC:
		default:

			try {

				switch ( fm->evaluationStatus() ) {
					case PRELIMINARY: return 0;
					case CONFIRMED: return 1;
					case REVIEWED: return 2;
					case FINAL: return 3;
					case REPORTED: return -1;
					case REJECTED: return -100;
					default: break;
				}

			}
			catch ( ValueException& ) {
				return 0;
			}

			break;
	}

	/*
	EvaluationMode mode = AUTOMATIC;
	try {
		mode = fm->evaluationMode();
	}
	catch ( ValueException& ) {}

	switch ( mode ) {
		case MANUAL:
			return 1;

		case AUTOMATIC:
		default:
			return 0;
	}
	*/

	SEISCOMP_WARNING("FocalMechanism %s has unknown evaluation mode", fm->publicID().c_str());

	return 0;
}
Beispiel #16
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool Environment::init()
{
	const char* installDir = getenv("SEISCOMP_ROOT");
	if (installDir == NULL)
	{
#ifdef SEISCOMP_ROOT
		_installDir = SEISCOMP_ROOT;
		SEISCOMP_DEBUG("Setting predefined installdir: %s", _installDir.c_str());
#else
		_installDir = ".";
		SEISCOMP_DEBUG("Guessing installdir: %s", _installDir.c_str());
#endif
	}
	else
	{
		_installDir = installDir;
		SEISCOMP_DEBUG("Setting installdir from $SEISCOMP_ROOT: %s", _installDir.c_str());
	}


#ifdef SEISCOMP_SHARE_DIR
	_shareDir = _installDir + "/"SEISCOMP_SHARE_DIR;
#else
	_shareDir = _installDir + "/share";
#endif

#ifndef WIN32
	const char *homeDir = getenv("HOME");
	if (!homeDir)
	{
		SEISCOMP_WARNING("Could not read home directory!");
		_homeDir = ".";
	}
#else
	char homeDir[MAX_PATH];
	if ( SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, homeDir) != S_OK ) {
		SEISCOMP_WARNING("Could not get local application data path!");
		_homeDir = ".";
	}
#endif
	else
		_homeDir.assign(homeDir);


#ifdef SEISCOMP_CONFIG_DIR
	_globalConfigDir  = _installDir + "/"SEISCOMP_CONFIG_DIR;
#else
	_globalConfigDir  = _installDir + "/etc/defaults";
#endif

	_appConfigDir = _installDir + "/etc";

	const char* localConfigDir = getenv("SEISCOMP_LOCAL_CONFIG");
	if( localConfigDir == NULL ) {
#ifndef WIN32
		_localConfigDir  = _homeDir + "/.seiscomp3";
#else
		_localConfigDir  = _homeDir + "/seiscomp3";
#endif
	} else {
		_localConfigDir  = localConfigDir;
	}
	SEISCOMP_INFO("using local config dir: %s", _localConfigDir.c_str() );

	_logDir           = _localConfigDir + "/log";
	_archiveFileName  = "_archive.log";

	if (!createDir(_localConfigDir))
		SEISCOMP_WARNING( "Could not create directory: %s", _localConfigDir.c_str() );

	if (!createDir(_logDir))
		SEISCOMP_ERROR("Could not create directory: %s", _logDir.c_str());

	return true;
}
Beispiel #17
0
Origin* Locator::_sc3relocate(const Origin *origin, double fixedDepth)
{
	// convert origin to SC3, relocate, and convert the result back

	Seiscomp::DataModel::OriginPtr sc3origin = convertToSC3(origin);
	Seiscomp::DataModel::TimeQuantity sc3tq;
	Seiscomp::DataModel::RealQuantity sc3rq;

/*
	if(fixedDepth>=0) {
		setFixedDepth(fixedDepth);
	}
	else if(_useFixedDepth==true) {
		setFixedDepth(origin->dep);
	}
	else
		releaseDepth();
*/

	// Store SC3 Picks/Stations here so that they can be found
	// by LocSAT via SC3 PublicObject lookup
	vector<Seiscomp::DataModel::PublicObjectPtr> sc3objects;

	int arrivalCount = origin->arrivals.size();
	for (int i=0; i<arrivalCount; i++) {

		const Arrival &arr = origin->arrivals[i];
		const Seiscomp::DataModel::Phase phase(arr.phase);

		Seiscomp::DataModel::PickPtr
			sc3pick = Seiscomp::DataModel::Pick::Cast(
				Seiscomp::DataModel::PublicObject::Find(arr.pick->id));

		if ( sc3pick == NULL ) {
			sc3pick = Seiscomp::DataModel::Pick::Create(arr.pick->id);
			if ( sc3pick == NULL ) {
				SEISCOMP_ERROR_S("Locator::_sc3relocate(): Failed to create pick "+arr.pick->id+" - giving up");
				return NULL;
			}
			const Station *sta = arr.pick->station();
			Seiscomp::DataModel::WaveformStreamID wfid(sta->net, sta->code, "", "XYZ", "");
			sc3pick->setWaveformID(wfid);
			sc3tq.setValue(sc3time(arr.pick->time));
			sc3pick->setTime(sc3tq);
			sc3pick->setPhaseHint(phase);
			sc3pick->setEvaluationMode(Seiscomp::DataModel::EvaluationMode(Seiscomp::DataModel::AUTOMATIC));
		}
		sc3objects.push_back(sc3pick);
	}


	// 
	// try the actual relocation
	//
	Seiscomp::DataModel::OriginPtr sc3relo;
	try {
		// FIXME| It is strange: sometimes LocSAT requires a second
		// FIXME| invocation to produce a decent result. Reason TBD
		Seiscomp::DataModel::OriginPtr temp;
		temp    = Seiscomp::LocSAT::relocate(sc3origin.get());
		if (!temp) return NULL;
		sc3relo = Seiscomp::LocSAT::relocate(temp.get());
		if (!sc3relo) return NULL;
	}
	catch(Seiscomp::Seismology::LocatorException) {
		return NULL;
	}
	catch(Seiscomp::Seismology::PickNotFoundException) {
		SEISCOMP_WARNING("Unsuccessful location due to PickNotFoundException");
		return NULL;
	}



	// 
	// Now get the relocated origin back from SC3
	// TODO: put it into sc3adapters.cpp
	// HOWEVER: here a copy of the original origin is just updated
	//
	// A copy is made of the input origins, i.e. the Arrival attributes
	// don't get lost or have to be searched for in a complicated manner.
	// However, this relies on the order of the arrivals as returned by
	// LocSAT being the same as in the input. If not, this is absolutely
	// fatal.
	//
	Origin *relo = new Origin(*origin);
	if ( ! relo)
		return NULL;

	relo->lat     = sc3relo->latitude().value();
	try { relo->laterr  = 0.5*(sc3relo->latitude().lowerUncertainty()+sc3relo->latitude().upperUncertainty()); }
	catch ( ... ) { relo->laterr  = sc3relo->latitude().uncertainty(); }
	relo->lon     = sc3relo->longitude().value();
	try { relo->lonerr  = 0.5*(sc3relo->longitude().lowerUncertainty()+sc3relo->longitude().upperUncertainty()); }
	catch ( ... ) { relo->lonerr  = sc3relo->longitude().uncertainty(); }
	relo->dep     = sc3relo->depth().value();
	try { relo->deperr  = 0.5*(sc3relo->depth().lowerUncertainty()+sc3relo->depth().upperUncertainty()); }
	catch ( ... ) { relo->deperr  = sc3relo->depth().uncertainty(); }
	relo->time    = double(sc3relo->time().value() - Seiscomp::Core::Time());
	try { relo->timeerr = 0.5*(sc3relo->time().lowerUncertainty()+sc3relo->time().upperUncertainty()); }
	catch ( ... ) { relo->timeerr = sc3relo->time().uncertainty(); }

	relo->methodID = sc3relo->methodID();
	relo->earthModelID = sc3relo->earthModelID();

	for (int i=0; i<arrivalCount; i++) {

		Arrival &arr = relo->arrivals[i];
		const string &pickID = sc3relo->arrival(i)->pickID();

		if (arr.pick->id != pickID) {
			// If this should ever happen, let it bang loudly!
			SEISCOMP_ERROR("Locator: FATAL ERROR: Inconsistent arrival order");
			exit(1);
		}

		arr.residual = sc3relo->arrival(i)->timeResidual();
		arr.distance = sc3relo->arrival(i)->distance();
		arr.azimuth  = sc3relo->arrival(i)->azimuth();

		if ( (arr.phase == "P" || arr.phase == "P1") && arr.distance > 115)
			arr.phase = "PKP";

//		if (arr.residual == -999.)
//			arr.residual = 0; // FIXME preliminary cosmetics;

// We do not copy the weight back, because it is still there in the original arrival
//		arr.weight   = sc3relo->arrival(i)->weight();
/*
		if ( arr.residual > 800 && ( arr.phase=="P" || arr.phase=="Pdiff" ) && \
		     arr.distance > 104 && arr.distance < 112) {

			Seiscomp::TravelTime tt;
			if ( ! travelTimeP(arr.distance, origin->dep, tt))
				continue;
			arr.residual = arr.pick->time - (origin->time + tt.time);
		}
*/
	}

	return relo;
}
Beispiel #18
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void QcPlugin::timeoutTask() {
	// NOOP ----- if needed, implement this in derived classes
	SEISCOMP_WARNING("[%s] TimeOut specified, but no timeoutTask was defined for this QcPlugin.", registeredName().c_str());

}
Beispiel #19
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Record *Spectralizer::fft(const Record *rec) {
	Core::Time endTime;
	try {
		endTime = rec->endTime();
	}
	catch ( ... ) {
		SEISCOMP_WARNING("[dec] %s: invalid end time -> ignoring",
		                 rec->streamID().c_str());
		return NULL;
	}

	if ( _buffer->lastEndTime.valid() ) {
		double diff = rec->startTime() - _buffer->lastEndTime;
		if ( fabs(diff) > _buffer->dt*0.5 ) {
			SEISCOMP_DEBUG("[spec] %s: gap/overlap of %f secs -> reset processing",
			               rec->streamID().c_str(), diff);
			_buffer->reset(_filter);
		}
	}

	_buffer->lastEndTime = endTime;

	ArrayPtr tmp_ar;
	const DoubleArray *ar = DoubleArray::ConstCast(rec->data());
	if ( ar == NULL ) {
		tmp_ar = rec->data()->copy(Array::DOUBLE);
		ar = DoubleArray::ConstCast(tmp_ar);
		if ( ar == NULL ) {
			SEISCOMP_ERROR("[spec] internal error: doubles expected");
			return NULL;
		}
	}

	size_t data_len = (size_t)ar->size();
	const double *data = ar->typedData();
	double *buffer = &_buffer->buffer[0];

	if ( _buffer->filter )
		_buffer->filter->apply(data_len, (double*)data);

	if ( _buffer->missingSamples > 0 ) {
		size_t toCopy = std::min(_buffer->missingSamples, data_len);
		memcpy(buffer + _buffer->buffer.size() - _buffer->missingSamples,
		       data, toCopy*sizeof(double));
		data += toCopy;
		data_len -= toCopy;
		_buffer->missingSamples -= toCopy;

		if ( !_buffer->startTime.valid() ) {
			_buffer->startTime = rec->startTime();

			// align to timestep if not requested otherwise
			if ( !_noalign ) {
				double mod = fmod((double)_buffer->startTime, _timeStep);
				double skip = _timeStep - mod;
				_buffer->samplesToSkip = int(skip*_buffer->sampleRate+0.5);

				Core::Time nextStep(floor(double(_buffer->startTime)/_timeStep+(_buffer->samplesToSkip > 0?1:0))*_timeStep+5E-7);
				_buffer->startTime = nextStep - Core::TimeSpan(_buffer->samplesToSkip*_buffer->dt+5E-7);
			}
		}

		// Still samples missing and no more data available, return
		if ( _buffer->missingSamples > 0 ) return NULL;
	}

	do {
		if ( _buffer->samplesToSkip == 0 ) {
			ComplexDoubleArrayPtr spec;
			Core::Time startTime;

			// Calculate spectrum from ringbuffer
			startTime = _buffer->startTime;

			// Copy data
			copy(_buffer->tmp, _buffer->tmpOffset, _buffer->buffer, _buffer->front);

			size_t sampleCount = _buffer->buffer.size();

			// Demean data excluding the padding window
			demean(_buffer->tmp.size()-_buffer->tmpOffset*2, _buffer->tmp.typedData()+_buffer->tmpOffset);
			// Detrend data excluding the padding window
			detrend(_buffer->tmp.size()-_buffer->tmpOffset*2, _buffer->tmp.typedData()+_buffer->tmpOffset);
			// Apply Von-Hann window
			Math::HannWindow<double>().apply(_buffer->tmp.size()-_buffer->tmpOffset*2, _buffer->tmp.typedData()+_buffer->tmpOffset, _taperWidth);

			spec = new ComplexDoubleArray;
			Math::fft(spec->impl(), _buffer->tmp.size(), _buffer->tmp.typedData());

			if ( _specSamples > 0 )
				reduce<Mag>(*spec, _specSamples);

			if ( spec ) {
				Spectrum *spectrum;
				spectrum = new Spectrum(startTime, startTime + Core::TimeSpan(sampleCount*_buffer->dt),
				                        _timeStep, _buffer->sampleRate*0.5,
				                        (int)sampleCount/2);
				spectrum->setData(spec.get());
				_nextSpectra.push_back(spectrum);
			}

			// Still need to wait until N samples have been fed.
			_buffer->samplesToSkip = _buffer->sampleRate * _timeStep + 0.5;
		}

		size_t num_samples = std::min(_buffer->samplesToSkip, data_len);

		size_t chunk_size = std::min(num_samples, _buffer->buffer.size()-_buffer->front);
		memcpy(buffer + _buffer->front, data, chunk_size*sizeof(double));

		data += chunk_size;

		// Split chunks
		if ( chunk_size < num_samples ) {
			chunk_size = num_samples - chunk_size;

			memcpy(buffer, data, chunk_size*sizeof(double));

			_buffer->front = chunk_size;

			data += chunk_size;
		}
		else {
			_buffer->front += chunk_size;
			if ( _buffer->front >= _buffer->buffer.size() )
				_buffer->front -= _buffer->buffer.size();
		}

		_buffer->startTime += Core::TimeSpan(_buffer->dt*num_samples+5E-7);
		_buffer->samplesToSkip -= num_samples;

		data_len -= num_samples;
	}
	while ( data_len > 0 );

	return NULL;
}
Beispiel #20
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void Import::handleNetworkMessage(const Communication::NetworkMessage* networkMessage)
{
	if (networkMessage->type() > 0 )
	{
		RoutingTable::iterator it = _routingTable.find(networkMessage->destination());
		if ( it == _routingTable.end() ) return;

		Communication::NetworkMessagePtr newNetworkMessagePtr;
		DataModel::PublicObject::SetRegistrationEnabled(false);
		Seiscomp::Core::MessagePtr messagePtr = networkMessage->decode();
		DataModel::PublicObject::SetRegistrationEnabled(true);

		if (_filter)
		{
			if (Core::DataMessage* dataMessage = Core::DataMessage::Cast(messagePtr))
			{
				Core::DataMessage::iterator it = dataMessage->begin();
				while (it != dataMessage->end())
				{
					if ( filterObject((*it).get()) )
						it = dataMessage->detach(it);
					else
						++it;
				}
				newNetworkMessagePtr = Communication::NetworkMessage::Encode(
						messagePtr.get(), networkMessage->contentType(),
						_sink->schemaVersion().packed);
			}
			else if (DataModel::NotifierMessage* notifierMessage = DataModel::NotifierMessage::Cast(messagePtr))
			{
				// Process Notifier Message
				DataModel::NotifierMessage::iterator it = notifierMessage->begin();
				while ( it != notifierMessage->end() ) {
					if (filterObject((*it)->object()))
						it = notifierMessage->detach(it);
					else
						++it;
				}
				newNetworkMessagePtr = Communication::NetworkMessage::Encode(
						messagePtr.get(), networkMessage->contentType(),
						_sink->schemaVersion().packed);
			}
			else {
				// Unknown message
				return;
			}

			if (messagePtr->empty()) return;
		}
		else {
			newNetworkMessagePtr = Communication::NetworkMessage::Encode(
					messagePtr.get(), networkMessage->contentType(),
					_sink->schemaVersion().packed);
		}

		/*
		SEISCOMP_INFO(
			"Message (type: %d) from source %s with destination %s relayed to group %s on sink %s",
			newNetworkMessagePtr->type(), networkMessage->clientName().c_str(), networkMessage->destination().c_str(),
			it->second.c_str(), _sink->masterAddress().c_str());
		*/

		if ( !_test ) {
			bool first = true;
			int res;
			while ( (res = _sink->send(it->second, newNetworkMessagePtr.get())) !=
					Core::Status::SEISCOMP_SUCCESS && !_exitRequested ) {
				switch ( res ) {
					case Core::Status::SEISCOMP_INVALID_GROUP_ERROR:
						SEISCOMP_WARNING("Sink group %s does not exist, message ignored",
						                 it->second.c_str());
						return;

					case Core::Status::SEISCOMP_MESSAGE_SIZE_ERROR:
						SEISCOMP_WARNING("Sink says: message is too big, message ignored");
						return;
					default:
						break;
				}

				if ( first ) {
					SEISCOMP_WARNING("Sending message to %s failed, waiting for reconnect",
					                 _sink->masterAddress().c_str());
					first = false;
				}

				Core::sleep(2);
			}
		}
	}
}
Beispiel #21
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool Envelope::init() {
	if ( !Application::init() ) return false;

	// Construct stream firewall
	for ( size_t i = 0; i < _config.streamsWhiteList.size(); ++i ) {
		Core::trim(_config.streamsWhiteList[i]);
		if ( !_config.streamsWhiteList[i].empty() ) {
			SEISCOMP_DEBUG("Adding pattern to stream whitelist: %s",
			               _config.streamsWhiteList[i].c_str());
			_streamFirewall.allow.insert(_config.streamsWhiteList[i]);
		}
	}

	for ( size_t i = 0; i < _config.streamsBlackList.size(); ++i ) {
		Core::trim(_config.streamsBlackList[i]);
		if ( !_config.streamsBlackList[i].empty() ) {
			SEISCOMP_DEBUG("Adding pattern to stream blacklist: %s",
			               _config.streamsBlackList[i].c_str());
			_streamFirewall.deny.insert(_config.streamsBlackList[i]);
		}
	}

	Inventory *inv = Client::Inventory::Instance()->inventory();
	if ( inv == NULL ) {
		SEISCOMP_ERROR("Inventory not available");
		return false;
	}

	Core::Time now = Core::Time::GMT();

	for ( size_t n = 0; n < inv->networkCount(); ++n ) {
		Network *net = inv->network(n);
		try { if ( net->end() < now ) continue; }
		catch ( ... ) {}

		for ( size_t s = 0; s < net->stationCount(); ++s ) {
			Station *sta = net->station(s);
			try { if ( sta->end() < now ) continue; }
			catch ( ... ) {}

			// Find velocity and strong-motion streams
			DataModel::WaveformStreamID tmp(net->code(), sta->code(), "", "", "");

			Stream *maxVel, *maxAcc;
			maxVel = Private::findStreamMaxSR(sta, now,
			                                  Processing::WaveformProcessor::MeterPerSecond,
			                                  &_streamFirewall);
			maxAcc = Private::findStreamMaxSR(sta, now,
			                                  Processing::WaveformProcessor::MeterPerSecondSquared,
			                                  &_streamFirewall);

			if ( !maxAcc && !maxVel ) {
				SEISCOMP_WARNING("%s.%s: no usable velocity and acceleration channel found",
				                 net->code().c_str(), sta->code().c_str());
				continue;
			}

			// Add velocity data if available
			if ( maxVel ) {
				tmp.setLocationCode(maxVel->sensorLocation()->code());
				tmp.setChannelCode(maxVel->code().substr(0,2));
				addProcessor(maxVel->sensorLocation(), tmp, now, "velocity", "vel");
			}

			// Add velocity data if available
			if ( maxAcc ) {
				tmp.setLocationCode(maxAcc->sensorLocation()->code());
				tmp.setChannelCode(maxAcc->code().substr(0,2));
				addProcessor(maxAcc->sensorLocation(), tmp, now, "accelerometric", "acc");
			}
		}
	}

	if ( _config.ts.valid() ) recordStream()->setStartTime(_config.ts);
	if ( _config.te.valid() ) recordStream()->setEndTime(_config.te);

	_creationInfo.setAgencyID(agencyID());
	_creationInfo.setAuthor(author());

	// We do not need lookup objects by publicID
	PublicObject::SetRegistrationEnabled(false);

	_sentMessages = 0;
	_sentMessagesTotal = 0;

#ifndef SC3_SYNC_VERSION
	_mpsReset.setCallback(boost::bind(&Envelope::resetMPSCount, this));
	_mpsReset.setTimeout(1);
	_mpsReset.start();
#endif

	return true;
}
Beispiel #22
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
int Import::connectToSink(const std::string& sink) {
	std::string protocol = "spread";
	std::string server = sink;
	size_t pos = sink.find("://");

	if ( pos != std::string::npos ) {
		protocol = sink.substr(0,pos);
		server = sink.substr(pos+3);
	}

	Communication::NetworkInterfacePtr ni = Communication::NetworkInterface::Create(protocol.c_str());
	if (ni == NULL)
	{
		SEISCOMP_ERROR("Networkinterface \"%s\" not found", protocol.c_str());
		return Core::Status::SEISCOMP_FAILURE;
	}

	_sink = new Communication::SystemConnection(ni.get());

	// Connect to the sink master and use a default name
	int ret;
	bool first = true;
	while ( (ret = _sink->connect(server, "", Communication::Protocol::IMPORT_GROUP)) !=
			Core::Status::SEISCOMP_SUCCESS && !_exitRequested ) {
		if ( first ) {
			SEISCOMP_WARNING("Could not connect to the sink master %s : %s, trying again every 2s",
			                 sink.c_str(), Core::Status::StatusToStr(ret));
			first = false;
		}

		Core::sleep(2);
	}

	if (ret != Core::Status::SEISCOMP_SUCCESS)
		return ret;

	// Get rid of data messages and read commands that are may send.
	SEISCOMP_INFO("Successfully connected to sink master: %s", sink.c_str());

	// Build routing table
	if (_mode == RELAY) {
		buildRelayRoutingtable(_routeUnknownGroup);
	}
	else if (_mode == IMPORT) {
		if (!buildImportRoutingtable())
		{
			SEISCOMP_ERROR("Could not built routing table for IMPORT mode.\nThere are no routing entries in specified in the configuration file");
			return 0;
		}
	}
	else {
		SEISCOMP_ERROR("Unknown import mode: %i", _mode);
		return Core::Status::SEISCOMP_FAILURE;
	}

	_sinkMessageThread = new boost::thread(boost::bind(&Import::readSinkMessages, this));

	// Print routing table
	for (std::map<std::string,
		 std::string>::iterator it = _routingTable.begin();
		 it != _routingTable.end(); ++it)
		SEISCOMP_INFO("%s@%s -> %s@%s", it->first.c_str(), connection()->masterAddress().c_str(), it->second.c_str(), sink.c_str());

	// Subscribe to source message groups
	for (std::map<std::string, std::string>::iterator it = _routingTable.begin();
	        it != _routingTable.end(); ++it) {
		if (connection()->subscribe(it->first) != Core::Status::SEISCOMP_SUCCESS)
			SEISCOMP_INFO("Could subscribe to group: %s", it->first.c_str());
	}

	return Core::Status::SEISCOMP_SUCCESS;
}
Beispiel #23
0
Autoloc::Origin *Seiscomp::Applications::Autoloc::App::convertFromSC3(const Seiscomp::DataModel::Origin *sc3origin)
{
	double lat  = sc3origin->latitude().value();
	double lon  = sc3origin->longitude().value();
	double dep  = sc3origin->depth().value();
	double time = double(sc3origin->time().value() - Seiscomp::Core::Time());

	::Autoloc::Origin *origin = new ::Autoloc::Origin(lat, lon, dep, time);

	try { origin->laterr  = 0.5*(sc3origin->latitude().lowerUncertainty() + sc3origin->latitude().upperUncertainty()); }
	catch ( ... ) {
		try { origin->laterr  = sc3origin->latitude().uncertainty(); }
		catch ( ... ) { origin->laterr = 0; }
	}

	try { origin->lonerr  = 0.5*(sc3origin->longitude().lowerUncertainty()+ sc3origin->longitude().upperUncertainty()); }
	catch ( ... ) {
		try { origin->lonerr  = sc3origin->longitude().uncertainty(); }
		catch ( ... ) { origin->lonerr = 0; }
	}

	try { origin->deperr  = 0.5*(sc3origin->depth().lowerUncertainty()    + sc3origin->depth().upperUncertainty()); }
	catch ( ... ) {
		try { origin->deperr  = sc3origin->depth().uncertainty(); }
		catch ( ... ) { origin->deperr = 0; }
	}

	try { origin->timeerr = 0.5*(sc3origin->time().lowerUncertainty()     + sc3origin->time().upperUncertainty()); }
	catch ( ... ) {
		try { origin->timeerr = sc3origin->time().uncertainty(); }
		catch ( ... ) { origin->timeerr = 0; }
	}

	int arrivalCount = sc3origin->arrivalCount();
	for (int i=0; i<arrivalCount; i++) {

		const std::string &pickID = sc3origin->arrival(i)->pickID();
/*
		Seiscomp::DataModel::Pick *sc3pick = Seiscomp::DataModel::Pick::Cast( Seiscomp::DataModel::PublicObject::Find(pickID) );
		if ( ! sc3pick) {
			SEISCOMP_ERROR_S("Pick " + pickID + " not found - cannot convert origin");
			delete origin;
			return NULL;
			// TODO:
			// Trotzdem mal schauen, ob wir den Pick nicht
			// als Autoloc-Pick schon haben
		}
*/
		const ::Autoloc::Pick *pick = ::Autoloc::Autoloc3::pick(pickID);
		if ( ! pick ) {
			// XXX FIXME: This may also happen after Autoloc cleaned up older picks, so the pick isn't available any more!
			SEISCOMP_ERROR_S("Pick " + pickID + " not found in internal pick pool - SKIPPING this pick");
			if (Seiscomp::DataModel::PublicObject::Find(pickID))
				SEISCOMP_ERROR("HOWEVER, this pick is present in pool of public objects");
			// This actually IS an error but we try to work around
			// it instead of giving up in this origin completely.
			continue;
//			delete origin;
//			return NULL;
		}

		::Autoloc::Arrival arr(pick /* , const std::string &phase="P", double residual=0 */ );
		try { arr.residual = sc3origin->arrival(i)->timeResidual(); }
		catch(...) { arr.residual = 0; SEISCOMP_WARNING("got arrival with timeResidual not set"); }
		try { arr.distance = sc3origin->arrival(i)->distance(); }
		catch(...) { arr.distance = 0; SEISCOMP_WARNING("got arrival with distance not set"); }
		try { arr.azimuth  = sc3origin->arrival(i)->azimuth(); }
		catch(...) { arr.azimuth = 0; SEISCOMP_WARNING("got arrival with azimuth not set"); }

		if (sc3origin->evaluationMode() == DataModel::MANUAL) {
			// for manual origins we do allow secondary phases like pP
			arr.phase = sc3origin->arrival(i)->phase();

			if (sc3origin->arrival(i)->weight() < 0.5) {
				arr.excluded = ::Autoloc::Arrival::ManuallyExcluded;
//				arr.weight   = sc3origin->arrival(i)->weight();
			}
		}

		origin->arrivals.push_back(arr);
	}

	origin->publicID = sc3origin->publicID();
	try {
	// FIXME: In scolv the Origin::depthType is not set!
	Seiscomp::DataModel::OriginDepthType dtype = sc3origin->depthType();
	if ( dtype == Seiscomp::DataModel::OriginDepthType(Seiscomp::DataModel::FROM_LOCATION) )
		origin->depthType = ::Autoloc::Origin::DepthFree;
	
	else if ( dtype == Seiscomp::DataModel::OriginDepthType(Seiscomp::DataModel::OPERATOR_ASSIGNED) ) 
		origin->depthType = ::Autoloc::Origin::DepthManuallyFixed;
	}
	catch(...) {
		SEISCOMP_WARNING("Origin::depthType is not set!");
		if (sc3origin->evaluationMode() == DataModel::MANUAL &&
		    _config.adoptManualDepth == true) {
			// This is a hack! We cannot know wether the operator
			// assigned a depth manually, but we can assume the
			// depth to be opperator approved and this is better
			// than nothing.
			// TODO: Make this behavior configurable?
			origin->depthType = ::Autoloc::Origin::DepthManuallyFixed;
			SEISCOMP_WARNING("Treating depth as if it was manually fixed");
		}
		else {
			origin->depthType = ::Autoloc::Origin::DepthFree;
			SEISCOMP_WARNING("Leaving depth free");
		}
	}

	return origin;
}
Beispiel #24
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void Envelope::addProcessor(SensorLocation *loc, const WaveformStreamID &id,
                            const Core::Time &timestamp, const char *type,
                            const char *short_type) {
	DataModel::ThreeComponents tc;
	DataModel::WaveformStreamID tmp(id);
	try {
		DataModel::getThreeComponents(
			tc, loc, id.channelCode().c_str(), timestamp
		);
	}
	catch ( exception &e ) {
		SEISCOMP_ERROR("%s: cannot query three components: %s: "
		               "%s channels not used",
		               Private::toStreamID(tmp).c_str(),
		               e.what(), type);
	}

	for ( int i = 0; i < 3; ++i ) {
		if ( tc.comps[i] == NULL ) continue;
		tmp.setChannelCode(tc.comps[i]->code());
		if ( !_streamFirewall.isAllowed(Private::toStreamID(tmp)) ) continue;

		SEISCOMP_INFO("%s: +%s", Private::toStreamID(tmp).c_str(), short_type);
		recordStream()->addStream(tmp.networkCode(), tmp.stationCode(),
		                          tmp.locationCode(), tmp.channelCode());
		ProcessorPtr proc = new Processor(_config.baselineCorrectionBufferLength);
		switch ( i ) {
			case ThreeComponents::Vertical:
				proc->setUsedComponent(Processing::WaveformProcessor::Vertical);
				proc->setName("Z");
				break;
			case ThreeComponents::FirstHorizontal:
				proc->setUsedComponent(Processing::WaveformProcessor::FirstHorizontal);
				proc->setName("H1");
				break;
			case ThreeComponents::SecondHorizontal:
				proc->setUsedComponent(Processing::WaveformProcessor::SecondHorizontal);
				proc->setName("H2");
				break;
		}

		Processing::StreamPtr stream = new Processing::Stream;
		stream->init(tmp.networkCode(), tmp.stationCode(),
		             tmp.locationCode(), tmp.channelCode(),
		             timestamp);

		proc->streamConfig((Processing::WaveformProcessor::Component)proc->usedComponent()) = *stream;
		proc->setWaveformID(tmp);
		proc->setSaturationThreshold(_config.saturationThreshold);
		proc->useVSFilterImplementation(!_config.useSC3Filter);

		if ( proc->streamConfig((Processing::WaveformProcessor::Component)proc->usedComponent()).gain == 0.0 ) {
			SEISCOMP_WARNING("%s: -%s: gain not defined (= 0.0)",
			                 short_type, Private::toStreamID(tmp).c_str());
			continue;
		}

		proc->setPublishFunction(boost::bind(&Envelope::emitResult, this, _1, _2, _3, _4, _5, _6));
		_processors[Private::toStreamID(tmp)] = proc;
	}
}
Beispiel #25
0
bool Importer::traverse(NodeHandler *handler, void *n, void *c, Core::BaseObject *target) {
	xmlNodePtr node = reinterpret_cast<xmlNodePtr>(n);
	xmlNodePtr childs = reinterpret_cast<xmlNodePtr>(c);
	ChildList remaining;
	TagSet mandatory;

	handler->init(target, n, mandatory);

	bool result = true;

	for ( xmlNodePtr child = childs; child != NULL; child = child->next ) {
		if ( child->type != XML_ELEMENT_NODE ) continue;

		handler->propagate(NULL, false, true);

		try {
			handler->get(target, child);
		}
		catch ( std::exception &e ) {
			if ( handler->isOptional )
				SEISCOMP_WARNING("(optional) %s.%s: %s", node->name, child->name, e.what());
			else
				throw e;
		}

		if ( !handler->isOptional )
			mandatory.erase((const char*)child->name);

		if ( handler->object == NULL && handler->isAnyType ) {
			if ( _any.get(target, child) ) {
				handler->object = _any.object;
				handler->childHandler = _any.childHandler;
				handler->newInstance = _any.newInstance;
			}
		}

		Core::BaseObject *newTarget = handler->object;
		MemberNodeHandler *memberHandler = handler->memberHandler;
		NodeHandler *childHandler = handler->childHandler;
		bool newInstance = handler->newInstance;
		bool optional = handler->isOptional;

		if ( newTarget ) {
			if ( childHandler == NULL ) {
				childHandler = _typemap->getHandler(newTarget->className());
				if ( childHandler == NULL ) {
					SEISCOMP_WARNING("No class handler for %s", newTarget->className());
					if ( newInstance )
						delete newTarget;
					handler->object = NULL;
					newTarget = NULL;
					childHandler = &_none;
				}
			}
		}
		else
			childHandler = &_none;

		try {
			if ( traverse(childHandler, child, child->children, handler->object) ) {
				if ( newTarget && newInstance && !memberHandler )
					remaining.push_back(newTarget);

			}
			else {
				if ( newTarget && newInstance )
					delete newTarget;
				newTarget = NULL;
				if ( optional )
					SEISCOMP_INFO("Invalid %s element: ignoring", child->name);
				else {
					SEISCOMP_WARNING("%s is not optional within %s", child->name, node->name);
					result = false;
				}
			}
		}
		catch ( std::exception &e ) {
			SEISCOMP_WARNING("%s: %s", child->name, e.what());
			if ( newTarget ) {
				if ( newInstance )
					delete newTarget;

				if ( !optional ) {
					SEISCOMP_WARNING("%s is not optional within %s", child->name, node->name);
					result = false;
				}
				else
					SEISCOMP_WARNING("%s: ignoring optional member %s: invalid", node->name, child->name);

				newTarget = NULL;
			}
		}

		if ( memberHandler ) {
			if ( !memberHandler->finalize(target, newTarget) ) {
				if ( newTarget && newInstance )
					remaining.push_back(newTarget);
			}
		}
	}

	handler->finalize(target, &remaining);

	if ( target != NULL ) {
		for ( ChildList::iterator it = remaining.begin(); it != remaining.end(); ++it )
			if ( *it != NULL ) delete *it;
	}
	else {
		for ( ChildList::iterator it = remaining.begin(); it != remaining.end(); ++it ) {
			if ( *it != NULL ) {
				if ( _result == NULL )
					_result = *it;
				else
					delete *it;
			}
		}
	}

	if ( !mandatory.empty() ) {
		std::string attribs;
		for ( TagSet::iterator it = mandatory.begin(); it != mandatory.end(); ++it ) {
			if ( it != mandatory.begin() ) attribs += ", ";
			attribs += *it;
		}
		SEISCOMP_WARNING("%s: missing mandatory attribute%s: %s", node->name, mandatory.size() == 1?"":"s", attribs.c_str());
		return false;
	}

	return result;
}
Beispiel #26
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void Envelope::emitResult(const Processor *proc,
                          double acc, double vel, double disp,
                          const Core::Time &timestamp, bool clipped) {
	_creationInfo.setCreationTime(Core::Time::GMT());

	// Objects with empty publicID are created since they are currently
	// not sent as notifiers and stored in the database
	VS::EnvelopePtr envelope = new VS::Envelope("");
	envelope->setCreationInfo(_creationInfo);
	envelope->setNetwork(proc->waveformID().networkCode());
	envelope->setStation(proc->waveformID().stationCode());
	envelope->setTimestamp(timestamp);

	VS::EnvelopeChannelPtr cha = new VS::EnvelopeChannel("");
	cha->setName(proc->name());
	cha->setWaveformID(proc->waveformID());

	VS::EnvelopeValuePtr val;

	// Add acceleration value
	val = new VS::EnvelopeValue;
	val->setValue(acc);
	val->setType("acc");
	if ( clipped ) val->setQuality(VS::EnvelopeValueQuality(VS::clipped));
	cha->add(val.get());

	// Add velocity value
	val = new VS::EnvelopeValue;
	val->setValue(vel);
	val->setType("vel");
	if ( clipped ) val->setQuality(VS::EnvelopeValueQuality(VS::clipped));
	cha->add(val.get());

	// Add displacement value
	val = new VS::EnvelopeValue;
	val->setValue(disp);
	val->setType("disp");
	if ( clipped ) val->setQuality(VS::EnvelopeValueQuality(VS::clipped));
	cha->add(val.get());

	envelope->add(cha.get());

	Core::DataMessagePtr msg = new Core::DataMessage;
	msg->attach(envelope.get());

	/* -- DEBUG --
	Core::DataMessage *tmp = &msg;
	IO::XMLArchive ar;
	ar.create("-");
	ar.setFormattedOutput(true);
	ar << tmp;
	ar.close();
	*/

	if ( connection() ) {
		connection()->send(msg.get());
		++_sentMessages;
		++_sentMessagesTotal;

#ifndef SC3_SYNC_VERSION
		if ( _config.maxMessageCountPerSecond > 0 ) {
			bool first = true;
			while ( !isExitRequested() && _sentMessages > _config.maxMessageCountPerSecond ) {
				if ( first )
					SEISCOMP_WARNING("Throttling message output, more than %d allowed messages sent per second",
					                 _config.maxMessageCountPerSecond);
				first = false;
				Core::msleep(100);
			}
		}
#else
		// Request a sync token every 100 messages
		if ( _sentMessages > 100 ) {
			_sentMessages = 0;
			// Tell the record acquisition to request synchronization and to
			// stop sending records until the sync is completed.
			requestSync();
		}
#endif
	}
}