Beispiel #1
0
bool StationConfig::read(const std::string &fname)
{
	string line;
	string defaultkey = "* *";
	_entry[defaultkey] = Entry();

	ifstream ifile(fname.c_str());
	if ( ! ifile.good()) {
		SEISCOMP_ERROR_S("Failed to open station config file "+fname);
		return false;
	}

	Entry entry;
	while( ! ifile.eof()) {
		getline(ifile, line);
		line.erase(0,line.find_first_not_of(" \n\r\t"));
		if (line[0] == '#')
			continue;
		char net[10],sta[10];
		int n = sscanf(line.c_str(), "%8s %8s %d %f", net, sta, &entry.usage, &entry.maxNucDist);
		if (n!=4) break;
		string key = string(net)+string(" ")+string(sta);
		_entry[key] = entry;
	}

	return true;
}
Beispiel #2
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 #3
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;
}