Beispiel #1
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool AmpTool::run() {
	if ( !_originID.empty() ) {
		OriginPtr org = Origin::Cast(query()->getObject(Origin::TypeInfo(), _originID));
		if ( !org ) {
			cerr << "Origin not found!" << endl;
			return false;
		}

		_fetchMissingAmplitudes = false;
		query()->loadArrivals(org.get());
		process(org.get());
		return true;
	}

	if ( !_strTimeWindowStartTime.empty() || !_strTimeWindowEndTime.empty() ) {
		if ( database() == NULL ) {
			cerr << "No database currently active for time window reprocessing" << endl;
			return false;
		}

		Core::Time startTime, endTime;

		if ( !_strTimeWindowStartTime.empty()
		  && !startTime.fromString(_strTimeWindowStartTime.c_str(), "%F %T") ) {
			cerr << "Invalid start time: " << _strTimeWindowStartTime << endl;
			return false;
		}

		if ( !_strTimeWindowEndTime.empty()
		  && !endTime.fromString(_strTimeWindowEndTime.c_str(), "%F %T") ) {
			cerr << "Invalid end time: " << _strTimeWindowEndTime << endl;
			return false;
		}

		std::string dbQuery;
		dbQuery += "select PPick." + _T("publicID") + ", Pick.* from Pick,PublicObject as PPick,Amplitude "
		           "where Pick._oid=PPick._oid and Amplitude." + _T("pickID") + "=PPick." + _T("publicID");

		if ( startTime.valid() )
			 dbQuery += " and Pick." + _T("time_value") + ">='" + startTime.toString("%F %T") + "'";

		if ( endTime.valid() )
			 dbQuery += " and Pick." + _T("time_value") + "<'" + endTime.toString("%F %T") + "'";

		dbQuery += " group by Amplitude." + _T("pickID");

		if ( !commandline().hasOption("commit") )
			_testMode = true;

		EventParametersPtr ep;
		if ( _testMode )
			ep = new EventParameters;

		typedef list<PickPtr> PickList;
		PickList picks;

		cerr << "Collecting picks ... " << flush;
		DatabaseIterator db_it = query()->getObjectIterator(dbQuery, Pick::TypeInfo());
		ObjectPtr obj;
		while ( obj = db_it.get() ) {
			Pick *pick = static_cast<Pick*>(obj.get());
			try {
				pick->waveformID().networkCode();
				pick->waveformID().stationCode();
				pick->waveformID().locationCode();
				pick->waveformID().channelCode();

				pick->time().value();
			}
			catch ( ... ) {
				continue;
			}

			++db_it;

			picks.push_back(pick);
			if ( ep ) ep->add(pick);
		}

		db_it.close();

		cerr << picks.size() << endl;

		_report << std::endl;
		_report << "Reprocessing report" << std::endl;
		_report << "-------------------" << std::endl;

		_report << " + Picks" << std::endl;

		int errors = 0;
		int ampsRecomputed = 0;
		int messagesSent = 0;

		int idx = 1;
		for ( PickList::iterator it = picks.begin(); it != picks.end(); ++it, ++idx ) {
			PickPtr pick = *it;
			SingleAmplitudeMap dbAmps;

			if ( isExitRequested() ) break;

			// Clear all processors
			_processors.clear();

			// Clear all station time windows
			_stationRequests.clear();

			_report << "   + " << pick->publicID() << std::endl;
			cerr << "[" << idx << "]" << " " << (*it)->publicID() << endl;
			db_it = query()->getAmplitudesForPick((*it)->publicID());
			while ( obj = db_it.get() ) {
				Amplitude *amp = static_cast<Amplitude*>(obj.get());
				cerr << "  [" << setw(10) << left << amp->type() << "]  ";

				AmplitudeProcessorPtr proc = AmplitudeProcessorFactory::Create(amp->type().c_str());
				if ( !proc ) {
					if ( _amplitudeTypes.find(amp->type()) == _amplitudeTypes.end() )
						cerr << "No processor";
					else {
						cerr << "No processor but enabled";
						++errors;
					}
				}
				else {
					cerr << "Fetch data";
					dbAmps[amp->type()] = amp;
					proc->setTrigger(pick->time().value());
					proc->setReferencingPickID(pick->publicID());
					proc->setPublishFunction(boost::bind(&AmpTool::storeLocalAmplitude, this, _1, _2));
					_report << "     + Data" << std::endl;
					addProcessor(proc.get(), pick.get(), None, None);
				}

				cerr << endl;
				++db_it;
			}

			db_it.close();

			cerr << "  --------------------------------" << endl;

			if ( _stationRequests.empty() ) continue;

			for ( RequestMap::iterator it = _stationRequests.begin(); it != _stationRequests.end(); ++it ) {
				StationRequest &req = it->second;
				for ( WaveformIDSet::iterator wit = req.streams.begin(); wit != req.streams.end(); ++wit ) {
					const WaveformStreamID &wsid = *wit;
					recordStream()->addStream(wsid.networkCode(), wsid.stationCode(),
					                          wsid.locationCode(), wsid.channelCode(),
					                          req.timeWindow.startTime(),
					                          req.timeWindow.endTime());
				}

				_report << " + TimeWindow (" << it->first << "): " << req.timeWindow.startTime().toString("%F %T")
				        << ", " << req.timeWindow.endTime().toString("%F %T") << std::endl;
			}

			_reprocessMap.clear();
			readRecords(false);

			list<AmplitudePtr> updates;

			for ( AmplitudeMap::iterator it = dbAmps.begin();
			      it != dbAmps.end(); ++it ) {
				AmplitudePtr oldAmp = it->second;
				AmplitudePtr newAmp = _reprocessMap[oldAmp->type()];

				cerr << "  [" << setw(10) << left << oldAmp->type() << "]  " << oldAmp->amplitude().value() << "  ";
				if ( newAmp ) {
					if ( newAmp->amplitude().value() != oldAmp->amplitude().value() ) {
						*oldAmp = *newAmp;
						if ( ep )
							ep->add(oldAmp.get());
						else
							updates.push_back(oldAmp);
						cerr << "->  " << newAmp->amplitude().value();
					}
					else
						cerr << "  no changes";

					++ampsRecomputed;
				}
				else {
					cerr << "-";
					++errors;
				}
				cerr << endl;
			}

			if ( !updates.empty() ) {
				if ( !_testMode ) {
					NotifierMessagePtr nmsg = new NotifierMessage;
					for ( list<AmplitudePtr>::iterator it = updates.begin();
					      it != updates.end(); ++it ) {
						nmsg->attach(new Notifier("EventParameters", OP_UPDATE, it->get()));
					}

					connection()->send(nmsg.get());
					++messagesSent;

					if ( messagesSent % 100 == 0 )
						sync();
				}
				else {
					cerr << "  --------------------------------" << endl;
					cerr << "  Test mode, nothing sent" << endl;
				}
			}
		}

		if ( ep ) {
			IO::XMLArchive ar;
			ar.create("-");
			ar.setFormattedOutput(true);
			ar << ep;
			ar.close();
		}

		cerr << "----------------------------------" << endl;
		cerr << "Recomputed " << ampsRecomputed << " amplitudes" << endl;
		cerr << "Sent " << messagesSent << " messages" << endl;
		if ( errors )
			cerr << errors << " errors occurred, check the processing log" << endl;

		return true;
	}


	if ( !_epFile.empty() ) {
		_fetchMissingAmplitudes = false;

		// Disable database
		setDatabase(NULL);
		_cache.setDatabaseArchive(NULL);

		IO::XMLArchive ar;
		if ( !ar.open(_epFile.c_str()) ) {
			SEISCOMP_ERROR("Failed to open %s", _epFile.c_str());
			return false;
		}

		ar >> _ep;
		ar.close();

		if ( !_ep ) {
			SEISCOMP_ERROR("No event parameters found in %s", _epFile.c_str());
			return false;
		}

		if ( commandline().hasOption("reprocess") ) {
			for ( size_t i = 0; i < _ep->amplitudeCount(); ++i ) {
				AmplitudePtr amp = _ep->amplitude(i);
				feed(amp.get());
			}
		}

		for ( size_t i = 0; i < _ep->originCount(); ++i ) {
			OriginPtr org = _ep->origin(i);
			SEISCOMP_INFO("Processing origin %s", org->publicID().c_str());
			process(org.get());
		}

		ar.create("-");
		ar.setFormattedOutput(true);
		ar << _ep;
		ar.close();

		_ep = NULL;

		return true;
	}
bool CalculateAmplitudes::process() {
    //_ui.btnOK->setEnabled(false);

    _processors.clear();
    _ui.table->setRowCount(0);

    Core::TimeWindow acTimeWindow;

    if ( !_origin || (_recomputeAmplitudes && !_thread) )
        return false;

    if ( _amplitudeTypes.empty() )
        return false;

    _timeWindow = Core::TimeWindow();

    /*
    TypeSet wantedAmpTypes;

    wantedAmpTypes.insert("MLv");
    wantedAmpTypes.insert("mb");
    wantedAmpTypes.insert("mB");
    wantedAmpTypes.insert("Mwp");

    try {
    	vector<string> amps = SCApp->configGetStrings("amplitudes");
    	wantedAmpTypes.clear();
    	wantedAmpTypes.insert(amps.begin(), amps.end());
    }
    catch (...) {}
    */

    QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));

    if ( _thread )
        _thread->connect();

    typedef pair<PickCPtr, double> PickStreamEntry;

    // Typedef a pickmap that maps a streamcode to a pick
    typedef map<string, PickStreamEntry> PickStreamMap;

    // This map is needed to find the earliest P pick of
    // a certain stream
    PickStreamMap pickStreamMap;

    for ( size_t i = 0; i < _origin->arrivalCount(); ++i ) {
        Arrival *ar = _origin->arrival(i);

        double weight = 1.;
        try {
            weight = ar->weight();
        }
        catch (Seiscomp::Core::ValueException) {}

        if ( Util::getShortPhaseName(ar->phase().code()) != 'P' || weight < 0.5 ) {
            continue;
        }

        Pick *pick = Pick::Find(ar->pickID());
        if ( !pick ) {
// 			cerr << " - Skipping arrival " << i << " -> no pick found" << endl;
            continue;
        }

        double dist = -1;

        try {
            dist = ar->distance();
        }
        catch ( Core::ValueError &e ) {
            try {
                Client::StationLocation loc;
                double azi1, azi2;

                loc = Client::Inventory::Instance()->stationLocation(pick->waveformID().networkCode(), pick->waveformID().stationCode(), pick->time().value());
                Math::Geo::delazi(loc.latitude, loc.longitude, _origin->latitude(), _origin->longitude(), &dist, &azi1, &azi2);
            }
            catch ( Core::GeneralException &e ) {}
        }


        DataModel::WaveformStreamID wfid = pick->waveformID();
        // Strip the component code because every AmplitudeProcessor
        // will use its own component to pick the amplitude on
        wfid.setChannelCode(wfid.channelCode().substr(0,2));

        string streamID = waveformIDToStdString(wfid);
        PickStreamEntry &e = pickStreamMap[streamID];

        // When there is already a pick registered for this stream which has
        // been picked earlier, ignore the current pick
        if ( e.first && e.first->time().value() < pick->time().value() )
            continue;

        e.first = pick;
        e.second = dist;
    }

    for ( PickStreamMap::iterator it = pickStreamMap.begin(); it != pickStreamMap.end(); ++it ) {
        PickCPtr pick = it->second.first;
        double dist = it->second.second;

        _ui.comboFilterType->clear();
        _ui.comboFilterType->addItem("- Any -");
        for ( TypeSet::iterator ita = _amplitudeTypes.begin(); ita != _amplitudeTypes.end(); ++ita )
            _ui.comboFilterType->addItem(ita->c_str());

        if ( _recomputeAmplitudes ) {
            for ( TypeSet::iterator ita = _amplitudeTypes.begin(); ita != _amplitudeTypes.end(); ++ita )
                addProcessor(*ita, pick.get(), dist);
        }
        else {
            string streamID = waveformIDToStdString(pick->waveformID());

            TypeSet usedTypes;

            if ( !_amplitudes.empty() ) {
                iterator_range itp;
                itp = _amplitudes.equal_range(pick->publicID());

                for ( iterator it = itp.first; it != itp.second; ) {
                    AmplitudePtr amp = it->second.first;

                    // The amplitude type is not one of the wanted types
                    if ( _amplitudeTypes.find(amp->type()) == _amplitudeTypes.end() ) {
                        ++it;
                        continue;
                    }

                    // Already has an amplitude of this type processed
                    if ( usedTypes.find(amp->type()) != usedTypes.end() ) {
                        ++it;
                        continue;
                    }

                    usedTypes.insert(amp->type());

                    int row = addProcessingRow(waveformIDToStdString(amp->waveformID()), amp->type());
                    setMessage(row, "read from cache");
                    setValue(row, amp->amplitude().value());

                    ++it;
                }
            }

            bool foundAmplitudes = false;
            if ( _externalAmplitudeCache ) {
                iterator_range itp;
                itp = _externalAmplitudeCache->equal_range(pick->publicID());

                for ( iterator ita = itp.first; ita != itp.second; ++ita ) {
                    AmplitudePtr amp = ita->second.first;

                    // The amplitude type is not one of the wanted types
                    if ( _amplitudeTypes.find(amp->type()) == _amplitudeTypes.end() )
                        continue;

                    // Already has an amplitude of this type processed
                    if ( usedTypes.find(amp->type()) != usedTypes.end() ) {
                        checkPriority(ita->second);
                        continue;
                    }

                    usedTypes.insert(amp->type());

                    int row = addProcessingRow(waveformIDToStdString(amp->waveformID()), amp->type());
                    setMessage(row, "read from cache");
                    setValue(row, amp->amplitude().value());

                    _amplitudes.insert(PickAmplitudeMap::value_type(ita->first, ita->second));
                }
            }

            if ( _query && !foundAmplitudes ) {
                DatabaseIterator it = _query->getAmplitudesForPick(pick->publicID());
                for ( ; *it; ++it ) {
                    AmplitudePtr amp = Amplitude::Cast(*it);
                    if ( !amp ) continue;

                    foundAmplitudes = true;

                    // The amplitude type is not one of the wanted types
                    if ( _amplitudeTypes.find(amp->type()) == _amplitudeTypes.end() ) continue;

                    // Already has an amplitude of this type processed
                    if ( usedTypes.find(amp->type()) != usedTypes.end() ) {
                        checkPriority(AmplitudeEntry(amp, false));
                        continue;
                    }

                    usedTypes.insert(amp->type());

                    int row = addProcessingRow(waveformIDToStdString(amp->waveformID()), amp->type());
                    setMessage(row, "read from database");
                    setValue(row, amp->amplitude().value());
                    _amplitudes.insert(PickAmplitudeMap::value_type(pick->publicID(), AmplitudeEntry(amp, false)));
                }
            }

            if ( !foundAmplitudes ) {
                EventParameters *ep = EventParameters::Cast(PublicObject::Find("EventParameters"));
                if ( ep ) {
                    for ( size_t i = 0; i < ep->amplitudeCount(); ++i ) {
                        Amplitude *amp = ep->amplitude(i);
                        if ( amp->pickID() != pick->publicID() ) continue;

                        // The amplitude type is not one of the wanted types
                        if ( _amplitudeTypes.find(amp->type()) == _amplitudeTypes.end() ) continue;

                        // Already has an amplitude of this type processed
                        if ( usedTypes.find(amp->type()) != usedTypes.end() ) {
                            checkPriority(AmplitudeEntry(amp, false));
                            continue;
                        }

                        usedTypes.insert(amp->type());

                        int row = addProcessingRow(waveformIDToStdString(amp->waveformID()), amp->type());
                        setMessage(row, "read from memory");
                        setValue(row, amp->amplitude().value());
                        _amplitudes.insert(PickAmplitudeMap::value_type(pick->publicID(), AmplitudeEntry(amp, false)));
                    }
                }
            }

            TypeSet remainingTypes;
            set_difference(_amplitudeTypes.begin(), _amplitudeTypes.end(),
                           usedTypes.begin(), usedTypes.end(),
                           inserter(remainingTypes, remainingTypes.begin()));

            for ( TypeSet::iterator ita = remainingTypes.begin(); ita != remainingTypes.end(); ++ita ) {
                if ( _thread )
                    addProcessor(*ita, pick.get(), dist);
                else {
                    int row = addProcessingRow(streamID, *ita);
                    setError(row, "missing");
                }
            }
        }
    }

    _ui.table->resizeColumnsToContents();
    _ui.table->resizeRowsToContents();

    if ( _thread && _timeWindow ) {
        _thread->setTimeWindow(_timeWindow);
        _thread->start();
    }
    //else
    //	_ui.btnOK->setEnabled(true);

    QApplication::restoreOverrideCursor();

    return true;
}