コード例 #1
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool AmplitudeProcessor::computeNoise(const DoubleArray &data, int i1, int i2, double *offset, double *amplitude) {
	// compute offset and rms within the time window
	if(i1<0) i1=0;
	if(i2<0) return false;
	if(i2>(int)data.size()) i2=(int)data.size();

	// If noise window is zero return an amplitude and offset of zero as well.
	if ( i2-i1 == 0 ) {
		*amplitude = 0;
		*offset = 0;
		return true;
	}

	DoubleArrayPtr d = static_cast<DoubleArray*>(data.slice(i1, i2));

	double ofs, amp;

	// compute pre-arrival offset
	ofs = d->median();
	// compute rms after removing offset
	amp = 2 * d->rms(ofs);

	if ( offset ) *offset = ofs;
	if ( amplitude ) *amplitude = amp;

	return true;
}
コード例 #2
0
ファイル: md.cpp プロジェクト: Fran89/seiscomp3
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool AmplitudeProcessor_Md::computeAmplitude(const DoubleArray& data, size_t i1,
                                             size_t i2, size_t si1, size_t si2,
                                             double offset, AmplitudeIndex* dt,
                                             AmplitudeValue* amplitude,
                                             double* period, double* snr) {

	double amax, Imax, ofs_sig, amp_sig;
	DoubleArrayPtr d;

    if ( *snr < aFile.SNR_MIN )
        SEISCOMP_DEBUG("%s computed SNR is under configured SNR MIN", AMPTAG);

	if ( _computeAbsMax ) {
		size_t imax = find_absmax(data.size(), data.typedData(), si1, si2, offset);
		amax = fabs(data[imax] - offset);
		dt->index = imax;
	}
	else {
		int lmin, lmax;
		find_minmax(lmin, lmax, data.size(), data.typedData(), si1, si2, offset);
		amax = data[lmax] - data[lmin];
		dt->index = (lmin + lmax) * 0.5;
		dt->begin = lmin - dt->index;
		dt->end = lmax - dt->index;
	}

	Imax = dt->index;

	SEISCOMP_DEBUG("%s Amplitude max: %.2f", AMPTAG, amax);

	//! searching for Coda second by second through the end of the window
	//! if snrMin config is not 0 (config file or waveform review window)
	//! TODO: elevate accuracy by using a nanometers scale (maybe)
	if ( _config.snrMin != 0 ) {

		unsigned int i = si1;
		bool hasEndSignal = false;
		double calculatedSnr = -1;

		for (i = (int) Imax; i < i2; i = i + 1 * (int) _stream.fsamp) {

			int window_end = i + 1 * (int) _stream.fsamp;
			d = static_cast<DoubleArray*>(data.slice(i, window_end));

			//! computes pre-arrival offset
			ofs_sig = d->median();

			//! computes rms after removing offset
			amp_sig = 2 * d->rms(ofs_sig);

			if ( amp_sig / *_noiseAmplitude <= _config.snrMin ) {
				SEISCOMP_DEBUG("%s End of signal found! (%.2f <= %.2f)", AMPTAG,
				    (amp_sig / *_noiseAmplitude), _config.snrMin);
				hasEndSignal = true;
				calculatedSnr = amp_sig / *_noiseAmplitude;
				break;
			}
		}

		if ( !hasEndSignal ) {
			SEISCOMP_ERROR("%s SNR stayed over configured SNR_MIN! (%.2f > %.2f), "
				"skipping magnitude calculation for this station", AMPTAG,
			    calculatedSnr, _config.snrMin);
			return false;
		}

		dt->index = i;
	}
	else dt->index = Imax;

	//amplitude->value = 2 * amp_sig; //! actually it would have to be max. peak-to-peak
	amplitude->value = amp_sig;

	if ( _streamConfig[_usedComponent].gain != 0.0 )
		amplitude->value /= _streamConfig[_usedComponent].gain;
	else {
		setStatus(MissingGain, 0.0);
		return false;
	}

	// Convert m/s to nm/s
	amplitude->value *= 1.E09;

	*period = dt->index - i1 + (_config.signalBegin * _stream.fsamp);

	SEISCOMP_DEBUG("%s calculated event amplitude = %.2f", AMPTAG, amplitude->value);
	SEISCOMP_DEBUG("%s calculated signal end at %.2f ms from P phase", AMPTAG, *period);

	return true;
}
コード例 #3
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool WaveformProcessor::store(const Record *record) {
	if ( _status > InProgress ) return false;
	if ( record->data() == NULL ) return false;

	DoubleArrayPtr arr = (DoubleArray*)record->data()->copy(Array::DOUBLE);

	if ( _stream.lastRecord ) {
		if ( record == _stream.lastRecord ) return false;

		Core::TimeSpan gap = record->startTime() - _stream.dataTimeWindow.endTime() - Core::TimeSpan(0,1);
		double gapSecs = (double)gap;

		if ( gap > _gapThreshold ) {
			size_t gapsize = static_cast<size_t>(ceil(_stream.fsamp * gapSecs));
			bool handled = handleGap(_stream.filter, gap, _stream.lastSample, (*arr)[0], gapsize);
			if ( handled )
				SEISCOMP_DEBUG("[%s] detected gap of %.6f secs or %lu samples (handled)",
				               record->streamID().c_str(), (double)gap, (unsigned long)gapsize);
			else {
				SEISCOMP_DEBUG("[%s] detected gap of %.6f secs or %lu samples (NOT handled): status = %s",
				               record->streamID().c_str(), (double)gap, (unsigned long)gapsize,
				               status().toString());
				if ( _status > InProgress ) return false;
			}
		}
		else if ( gapSecs < 0 ) {
			size_t gapsize = static_cast<size_t>(ceil(-_stream.fsamp * gapSecs));
			if ( gapsize > 1 ) return false;
		}

		// update the received data timewindow
		_stream.dataTimeWindow.setEndTime(record->endTime());
	}

	// NOTE: Do not use else here, because lastRecord can be set NULL
	//       when calling reset() in handleGap(...)
	if ( !_stream.lastRecord ) {
		initFilter(record->samplingFrequency());

		// update the received data timewindow
		_stream.dataTimeWindow = record->timeWindow();
		/*
		std::cerr << "Received first record for " << record->streamID() << ", "
		          << className() << " [" << record->startTime().iso() << " - " << record->endTime().iso() << std::endl;
		*/
		if ( _stream.filter ) {
			_stream.filter->setStartTime(record->startTime());
			_stream.filter->setStreamID(record->networkCode(), record->stationCode(),
			                            record->locationCode(), record->channelCode());
		}
	}

	// Fill the values and do the actual filtering
	fill(arr->size(), arr->typedData());
	if ( _status > InProgress ) return false;

	if ( !_stream.initialized ) {
		if ( _stream.receivedSamples > _stream.neededSamples ) {
			//_initialized = true;
			process(record, *arr);
			// NOTE: To allow derived classes to notice modification of the variable 
			//       _initialized, it is necessary to set this after calling process.
			_stream.initialized = true;
		}
	}
	else
		// Call process to cause a derived processor to work on the data.
		process(record, *arr);

	_stream.lastRecord = record;
	_stream.lastSample = (*arr)[arr->size()-1];

	return true;
}