// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 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; } } } }
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 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(); }