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; }
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; }
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; }