Esempio n. 1
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void AmplitudeProcessor::prepareData(DoubleArray &data) {
	Sensor *sensor = _streamConfig[_usedComponent].sensor();

	// When using full responses then all information needs to be set up
	// correctly otherwise an error is set
	if ( _enableResponses ) {
		if ( !sensor ) {
			setStatus(MissingResponse, 1);
			return;
		}

		if ( !sensor->response() ) {
			setStatus(MissingResponse, 2);
			return;
		}

		// If the unit cannot be converted into the internal
		// enum (what basically means "unknown") then the deconvolution
		// cannot be correctly. We do not want to assume a unit here
		// to prevent computation errors in case of bad configuration.
		SignalUnit unit;
		if ( !unit.fromString(sensor->unit().c_str()) ) {
			// Invalid unit string
			setStatus(IncompatibleUnit, 2);
			return;
		}

		int intSteps = 0;
		switch ( unit ) {
			case MeterPerSecond:
				break;
			case MeterPerSecondSquared:
				intSteps = 1;
				break;
			default:
				setStatus(IncompatibleUnit, 1);
				return;
		}

		if ( _responseApplied ) return;

		_responseApplied = true;

		if ( !deconvolveData(sensor->response(), _data, intSteps) ) {
			setStatus(DeconvolutionFailed, 0);
			return;
		}
	}
	else {
		// If the sensor is known then check the unit and skip
		// non velocity streams. Otherwise simply use the data
		// to be compatible to the old version. This will be
		// changed in the future and checked more strictly.
		if ( sensor ) {
			SignalUnit unit;
			if ( !unit.fromString(sensor->unit().c_str()) ) {
				// Invalid unit string
				setStatus(IncompatibleUnit, 4);
				return;
			}

			if ( unit != MeterPerSecond ) {
				setStatus(IncompatibleUnit, 3);
				return;
			}
		}
	}
}
Esempio n. 2
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void Processor::flush() {
	size_t n = _samplePool.size();
	double *data = _samplePool.samples;
	bool clipped = false;

	// Skip empty sample pool
	if ( n == 0 ) return;

	// -------------------------------------------------------------------
	// Saturation check
	// -------------------------------------------------------------------
	if ( _config.saturationThreshold >= 0 ) {
		double maxCounts = (_config.saturationThreshold * 0.01) * (2 << 23);
		for ( size_t i = 0; i < n; ++i ) {
			if ( fabs(data[i]) > maxCounts ) clipped = true;
		}
	}

	// -------------------------------------------------------------------
	// Sensitivity correction
	// -------------------------------------------------------------------
	double scorr = 1.0 / _streamConfig[_usedComponent].gain;
	for ( size_t i = 0; i < n; ++i ) data[i] *= scorr;

	// -------------------------------------------------------------------
	// Baseline correction and filtering
	// -------------------------------------------------------------------
	double amp0 = getValue(n, data, NULL, _baselineCorrection0, _filter0.get());

	// -------------------------------------------------------------------
	// Conversion to ACC, VEL, DISP
	// -------------------------------------------------------------------
	SignalUnit unit;
	if ( !unit.fromString(_streamConfig[_usedComponent].gainUnit.c_str()) ) {
		SEISCOMP_ERROR("%s: internal error: invalid gain unit '%s'",
		               Private::toStreamID(_waveformID).c_str(),
		               _streamConfig[_usedComponent].gainUnit.c_str());
		return;
	}

	double vel, acc, disp;
	std::vector<double> tmp;
	double *vel_data;

	switch ( unit ) {
		case MeterPerSecond:
			vel = amp0;
			tmp.assign(data, data+n);
			vel_data = &tmp[0];
			acc = getAcceleration(n, data);
			break;
		case MeterPerSecondSquared:
			acc = amp0;
			vel = getVelocity(n, data);
			vel_data = data;
			break;
		default:
			SEISCOMP_ERROR("%s: internal error: unsupported gain unit '%s'",
			               Private::toStreamID(_waveformID).c_str(),
			               _streamConfig[_usedComponent].gainUnit.c_str());
			return;
	}

	disp = getDisplacement(n, vel_data);

	// Publish result
	if ( _func )
		_func(this, acc, vel, disp, _currentStartTime, clipped);

	_samplePool.clear();
}