Beispiel #1
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool AmplitudeProcessor_Mjma::deconvolveData(Response *resp,
                                             DoubleArray &data,
                                             int numberOfIntegrations) {
	Math::Restitution::FFT::TransferFunctionPtr tf =
		resp->getTransferFunction(numberOfIntegrations);

	if ( tf == NULL ) {
		setStatus(DeconvolutionFailed, 0);
		return false;
	}

	
	Math::SeismometerResponse::Seismometer5sec paz(Math::Velocity);
	Math::Restitution::FFT::PolesAndZeros seis5sec(paz);

	Math::Restitution::FFT::TransferFunctionPtr cascade =
		*tf / seis5sec;

	// Remove linear trend
	double m,n;
	Math::Statistics::computeLinearTrend(data.size(), data.typedData(), m, n);
	Math::Statistics::detrend(data.size(), data.typedData(), m, n);

	return Math::Restitution::transformFFT(data.size(), data.typedData(),
	                                         _stream.fsamp, cascade.get(),
	                                         _config.respTaper, _config.respMinFreq, _config.respMaxFreq);
}
Beispiel #2
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool AmplitudeProcessor_Md::deconvolveData(Response* resp,
                                           DoubleArray& data,
                                           int numberOfIntegrations) {
	if ( numberOfIntegrations < -1 )
		return false;

	SEISCOMP_DEBUG("Inside deconvolve function");

	double m, n;
	Math::Restitution::FFT::TransferFunctionPtr tf =
		resp->getTransferFunction(numberOfIntegrations < 0 ? 0 : numberOfIntegrations);

	if ( !tf )
		return false;

	Math::GroundMotion gm;

	if ( numberOfIntegrations < 0 )
		gm = Math::Displacement;
	else
		gm = Math::Velocity;

	Math::Restitution::FFT::TransferFunctionPtr cascade;
	Math::SeismometerResponse::WoodAnderson woodAndersonResp(gm, _config.woodAndersonResponse);
	Math::SeismometerResponse::Seismometer5sec seis5sResp(gm);
	Math::SeismometerResponse::L4C_1Hz l4c1hzResp(gm);

	Math::Restitution::FFT::PolesAndZeros woodAnderson(woodAndersonResp);
	Math::Restitution::FFT::PolesAndZeros seis5sec(seis5sResp);
	Math::Restitution::FFT::PolesAndZeros l4c1hz(l4c1hzResp);

	SEISCOMP_DEBUG("SEISMO = %d", aFile.SEISMO);

	switch ( aFile.SEISMO ) {
		case 1:
			cascade = *tf / woodAnderson;
		break;
		case 2:
			cascade = *tf / seis5sec;
		break;
		case 9:
			SEISCOMP_INFO("%s Applying filter L4C 1Hz to data", AMPTAG);
			cascade = *tf / l4c1hz;
		break;
		default:
			cascade = tf;
			SEISCOMP_INFO("%s No seismometer specified, no signal reconvolution performed", AMPTAG);
			return false;
		break;
	}

	// Remove linear trend
	Math::Statistics::computeLinearTrend(data.size(), data.typedData(), m, n);
	Math::Statistics::detrend(data.size(), data.typedData(), m, n);

	return Math::Restitution::transformFFT(data.size(), data.typedData(),
	    _stream.fsamp, cascade.get(), _config.respTaper, _config.respMinFreq,
	    _config.respMaxFreq);
}
Beispiel #3
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void SpectrumWidget::updateData() {
	_powerSpectrum.clear();
	_responseCorrectedPowerSpectrum.clear();
	_responsePowerSpectrum.clear();

	if ( (_spec.size() < 2) || (_freqNyquist <= 0) ) {
		_xAxis.setRange(_powerSpectrum.x);
		return;
	}

	// Ignore the first value, this is the offset
	_powerSpectrum.y.resize(_spec.size()-1);
	if ( _phaseSpectrum ) {
		for ( size_t i = 1; i < _spec.size(); ++i )
			_powerSpectrum.y[i-1] = rad2deg(arg(_spec[i]));
	}
	else {
		for ( size_t i = 1; i < _spec.size(); ++i )
			_powerSpectrum.y[i-1] = abs(_spec[i]);
	}

	_powerSpectrum.x.lower = _freqNyquist / _powerSpectrum.count();
	_powerSpectrum.x.upper = _freqNyquist;

	if ( (_powerSpectrum.count() > 1) && _resp ) {
		Math::Restitution::FFT::TransferFunctionPtr tf = _resp->getTransferFunction();
		if ( tf ) {
			_responseCorrectedPowerSpectrum.y.resize(_spec.size()-1);
			_responseCorrectedPowerSpectrum.x = _powerSpectrum.x;

			_responsePowerSpectrum.y.resize(_spec.size()-1);
			_responsePowerSpectrum.x = _powerSpectrum.x;

			double dx = _responseCorrectedPowerSpectrum.x.length() / (_spec.size()-1);
			double px = _responseCorrectedPowerSpectrum.x.lower;

			if ( _phaseSpectrum ) {
				for ( size_t i = 1; i < _spec.size(); ++i, px += dx ) {
					Math::Complex r;
					tf->evaluate(&r, 1, &px);
					_responsePowerSpectrum.y[i-1] = rad2deg(arg(r));
					_responseCorrectedPowerSpectrum.y[i-1] = rad2deg(arg(_spec[i] / r));
				}
			}
			else {
				for ( size_t i = 1; i < _spec.size(); ++i, px += dx ) {
					Math::Complex r;
					tf->evaluate(&r, 1, &px);
					_responsePowerSpectrum.y[i-1] = abs(r);
					_responseCorrectedPowerSpectrum.y[i-1] = abs(_spec[i] / r);
				}
			}
		}
	}

	_xAxis.setRange(_powerSpectrum.x);
}
Beispiel #4
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void SpectrumWidget::exportSpectra() {
	if ( (_spec.size() < 1) || (_freqNyquist <= 0) ) {
		QMessageBox::critical(this, tr("Save spectra"), tr("No data"));
		return;
	}

	QString fn = QFileDialog::getSaveFileName(this, tr("Save spectra"), "spec-" + _exportBasename + ".txt");
	if ( fn.isEmpty() ) return;

	ofstream ofs;
	ofs.open(fn.toAscii());
	if ( !ofs.is_open() ) {
		QMessageBox::critical(this, tr("Save spectra"), tr("Failed to open/create %1").arg(fn));
		return;
	}

	ofs << "# This is an ASCII representation of a spectrum. The first column is" << endl
	    << "# the frequency is Hz. The second and third column represent the" << endl
	    << "# complex value (real, imag) at that frequency of the raw spectrum." << endl
	    << "# The amplitude and phase can be found in column four and five." << endl;

	Math::Restitution::FFT::TransferFunctionPtr tf = _resp ? _resp->getTransferFunction() : NULL;
	if ( (_spec.size() > 1) && tf ) {
		ofs
		<< "# The sixth and seventh column represent the complex value of the response" << endl
		<< "# corrected spectrum. Column eight and nine the amplitude and phase" << endl
		<< "# respectively." << endl;
	}
	ofs << "#" << endl
	    << "# Note that phases are output in degrees!" << endl;

	double f = 0;
	double df = _freqNyquist / (_spec.size()-1);

	for ( size_t i = 0; i < _spec.size(); ++i, f += df ) {
		ofs << f << "\t" << _spec[i].real() << "\t" << _spec[i].imag()
		    << "\t" << abs(_spec[i]) << "\t" << deg2rad(arg(_spec[i]));
		if ( tf ) {
			ofs << "\t";
			if ( i ) {
				Math::Complex r;
				tf->evaluate(&r, 1, &f);
				r = _spec[i] / r;
				ofs << r.real() << "\t" << r.imag() << "\t" << abs(r) << "\t" << deg2rad(arg(r));
			}
			else
				ofs << _spec[i].real() << "\t" << _spec[i].imag() << "\t" << abs(_spec[i]) << "\t" << deg2rad(arg(_spec[i]));
		}
		ofs << endl;
	}
}