// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> void Picker::process(const Record *record, const DoubleArray &) { // Sampling frequency has not been set yet if ( _stream.fsamp == 0.0 ) { terminate(); return; } // Error occured while feeding a record or already finished? if ( isFinished() ) return; // Process unless the available time window does not include the // requested time window if ( !dataTimeWindow().contains(timeWindow())) return; // data window relative to continuous()->startTime() double relTriggerTime = _trigger - dataTimeWindow().startTime(); double dt1 = relTriggerTime + _config.signalBegin; double dt2 = relTriggerTime + _config.signalEnd; double snr = -1; // Calculate data array indicies of requested time window int i1 = int(dt1*_stream.fsamp); int i2 = int(dt2*_stream.fsamp); // Calculate the initial trigger time int triggerIdx = relTriggerTime*_stream.fsamp; int lowerUncertainty = -1; int upperUncertainty = -1; OPT(Polarity) polarity; if ( !calculatePick(continuousData().size(), continuousData().typedData(), i1, i2, triggerIdx, lowerUncertainty, upperUncertainty, snr, polarity) ) { setStatus(Error, 0.0); return; } Core::Time pickTime = dataTimeWindow().startTime() + Core::TimeSpan(triggerIdx/_stream.fsamp); // Debug: print the time difference between the pick and the initial trigger SEISCOMP_DEBUG("Picker::process repick result: dt=%.3f snr=%.2f", (double)(pickTime - _trigger), snr); if ( snr >= _config.snrMin ) { setStatus(Finished, 100.); Result res; res.record = record; res.snr = snr; res.time = pickTime; res.timeLowerUncertainty = (double)lowerUncertainty / _stream.fsamp; res.timeUpperUncertainty = (double)upperUncertainty / _stream.fsamp; res.timeWindowBegin = (double)(timeWindow().startTime() - pickTime); res.timeWindowEnd = (double)(timeWindow().endTime() - pickTime); res.polarity = polarity; emitPick(res); } else setStatus(LowSNR, snr); }
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> bool AmplitudeProcessor::handleGap(Filter *filter, const Core::TimeSpan& span, double lastSample, double nextSample, size_t missingSamples) { if ( _stream.dataTimeWindow.endTime()+span < timeWindow().startTime() ) { // Save trigger, because reset will unset it Core::Time t = _trigger; reset(); _trigger = t; return true; } //TODO: Handle gaps setStatus(QCError, 1); return false; }
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> void AmplitudeProcessor::process(const Record *record) { // Sampling frequency has not been set yet if ( _stream.fsamp == 0.0 ) return; int n = (int)_data.size(); // signal and noise window relative to _continuous->startTime() double dt0 = _trigger - dataTimeWindow().startTime(); double dt1 = dataTimeWindow().endTime() - dataTimeWindow().startTime(); double dtw1 = timeWindow().endTime() - dataTimeWindow().startTime(); double dtn1 = dt0 + _config.noiseBegin; double dtn2 = dt0 + _config.noiseEnd; double dts1 = dt0 + _config.signalBegin; double dts2 = dt0 + _config.signalEnd; // Noise indicies int ni1 = int(dtn1*_stream.fsamp+0.5); int ni2 = int(dtn2*_stream.fsamp+0.5); if ( ni1 < 0 || ni2 < 0 ) { SEISCOMP_DEBUG("Noise data not available -> abort"); setStatus(Error, 1); return; } if ( n < ni2 ) { // the noise window is not complete return; } // **** compute signal amplitude ******************************** // these are the offsets of the beginning and end // of the signal window relative to the start of // the continuous record in samples int i1 = int(dts1*_stream.fsamp+0.5); int i2 = int(dts2*_stream.fsamp+0.5); //int progress = int(100.*(n-i1)/(i2-i1)); //int progress = int(100.*(dt1-dts1)/(dts2-dts1)); int progress = int(100.*(dt1-dts1)/(std::max(dtw1,dts2)-dts1)); if ( progress > 100 ) progress = 100; setStatus(InProgress, progress); if ( i1 < 0 ) i1 = 0; if ( i2 > n ) i2 = n; bool unlockCalculation = ((_enableUpdates && !_enableResponses) && progress > 0) || progress >= 100; if ( unlockCalculation ) { if ( _streamConfig[_usedComponent].gain == 0.0 ) { setStatus(MissingGain, 0); return; } // **** prepare the data to compute the noise prepareData(_data); if ( isFinished() ) return; // **** compute noise amplitude ********************************* // if the noise hasn't been measured yet... if ( !_noiseAmplitude ) { // compute pre-arrival data offset and noise amplitude double off = 0., amp = 0.; if ( !computeNoise(_data, ni1, ni2, &off, &) ) { SEISCOMP_DEBUG("Noise computation failed -> abort"); setStatus(Error, 2); return; } _noiseOffset = off; _noiseAmplitude = amp; } AmplitudeIndex index; Result res; res.component = _usedComponent; res.record = record; res.period = -1; res.snr = -1; res.amplitude.value = -1; res.amplitude.lowerUncertainty = Core::None; res.amplitude.upperUncertainty = Core::None; index.index = -1; index.begin = 0; index.end = 0; double dtsw1, dtsw2; if ( _searchBegin ) { dtsw1 = dt0 + *_searchBegin; if ( dtsw1 < dts1 ) dtsw1 = dts1; if ( dtsw1 > dts2 ) dtsw1 = dts2; } else dtsw1 = dts1; if ( _searchEnd ) { dtsw2 = dt0 + *_searchEnd; if ( dtsw2 < dts1 ) dtsw2 = dts1; if ( dtsw2 > dts2 ) dtsw2 = dts2; } else dtsw2 = dts2; int si1 = int(dtsw1*_stream.fsamp+0.5); int si2 = int(dtsw2*_stream.fsamp+0.5); si1 = std::max(si1, i1); si2 = std::min(si2, i2); if ( !computeAmplitude(_data, i1, i2, si1, si2, *_noiseOffset, &index, &res.amplitude, &res.period, &res.snr) ) { if ( progress >= 100 ) { if ( status() == LowSNR ) SEISCOMP_DEBUG("Amplitude %s computation for stream %s failed because of low SNR (%.2f < %.2f)", _type.c_str(), record->streamID().c_str(), res.snr, _config.snrMin); else { SEISCOMP_DEBUG("Amplitude %s computation for stream %s failed -> abort", _type.c_str(), record->streamID().c_str()); setStatus(Error, 3); } _lastAmplitude = Core::None; } return; } if ( _lastAmplitude ) { if ( res.amplitude.value <= *_lastAmplitude ) { if ( progress >= 100 ) { setStatus(Finished, 100.); _lastAmplitude = Core::None; } return; } } _lastAmplitude = res.amplitude.value; double dt = index.index / _stream.fsamp; res.period /= _stream.fsamp; if ( index.begin > index.end ) std::swap(index.begin, index.end); // Update status information res.time.reference = dataTimeWindow().startTime() + Core::TimeSpan(dt); //res.time.begin = index.begin / _stream.fsamp; //res.time.end = index.end / _stream.fsamp; res.time.begin = (si1 - index.index) / _stream.fsamp; res.time.end = (si2 - index.index) / _stream.fsamp; if ( progress >= 100 ) { setStatus(Finished, 100.); _lastAmplitude = Core::None; } emitAmplitude(res); } }