Пример #1
0
int main (int    argc,
	  char** argv)
/* ------------------------------------------------------------------------- *
 * Driver routine.
 * ------------------------------------------------------------------------- */
{
  FILE *avgfile = 0, *fldfile = 0;
  Dump *heada   = 0, *headf   = 0;
  int  i, npts, ntot;

  getargs (argc, argv, &avgfile, &fldfile);

  /* -- Read in the average file. */

  if (fldfile) {		 /* -- Remove averages from fldfile. */
    heada = (Dump*) calloc (1, sizeof (Dump));
    headf = (Dump*) calloc (1, sizeof (Dump));

    getheader (avgfile, heada);
    getheader (fldfile, headf);

    if (heada -> np  != headf -> np  ||
	heada -> nz  != headf -> nz  ||
	heada -> nel != headf -> nel)
      message (prog, "structure of files don't match",           ERROR);

    for (i = 0; i < strlen(headf -> field); i++)
      if (!strchr (heada -> field, headf -> field[i]))
      message (prog, "average fields don't match dumped fields", ERROR);

    getdata   (avgfile, heada);
    getdata   (fldfile, headf);
    demean    (heada,   headf);
    printup   (stdout,  headf);

  } else {			 /* -- Reynolds stresses using avgfile. */
    heada = (Dump*) calloc (1, sizeof (Dump));

    getheader (avgfile, heada);
    chknames  (heada -> field);
    getdata   (avgfile, heada);
    covary    (heada);
    printup   (stdout, heada);
  }
    
  /* -- Printup. */

  return (EXIT_SUCCESS);
}
Пример #2
0
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Record *Spectralizer::fft(const Record *rec) {
	Core::Time endTime;
	try {
		endTime = rec->endTime();
	}
	catch ( ... ) {
		SEISCOMP_WARNING("[dec] %s: invalid end time -> ignoring",
		                 rec->streamID().c_str());
		return NULL;
	}

	if ( _buffer->lastEndTime.valid() ) {
		double diff = rec->startTime() - _buffer->lastEndTime;
		if ( fabs(diff) > _buffer->dt*0.5 ) {
			SEISCOMP_DEBUG("[spec] %s: gap/overlap of %f secs -> reset processing",
			               rec->streamID().c_str(), diff);
			_buffer->reset(_filter);
		}
	}

	_buffer->lastEndTime = endTime;

	ArrayPtr tmp_ar;
	const DoubleArray *ar = DoubleArray::ConstCast(rec->data());
	if ( ar == NULL ) {
		tmp_ar = rec->data()->copy(Array::DOUBLE);
		ar = DoubleArray::ConstCast(tmp_ar);
		if ( ar == NULL ) {
			SEISCOMP_ERROR("[spec] internal error: doubles expected");
			return NULL;
		}
	}

	size_t data_len = (size_t)ar->size();
	const double *data = ar->typedData();
	double *buffer = &_buffer->buffer[0];

	if ( _buffer->filter )
		_buffer->filter->apply(data_len, (double*)data);

	if ( _buffer->missingSamples > 0 ) {
		size_t toCopy = std::min(_buffer->missingSamples, data_len);
		memcpy(buffer + _buffer->buffer.size() - _buffer->missingSamples,
		       data, toCopy*sizeof(double));
		data += toCopy;
		data_len -= toCopy;
		_buffer->missingSamples -= toCopy;

		if ( !_buffer->startTime.valid() ) {
			_buffer->startTime = rec->startTime();

			// align to timestep if not requested otherwise
			if ( !_noalign ) {
				double mod = fmod((double)_buffer->startTime, _timeStep);
				double skip = _timeStep - mod;
				_buffer->samplesToSkip = int(skip*_buffer->sampleRate+0.5);

				Core::Time nextStep(floor(double(_buffer->startTime)/_timeStep+(_buffer->samplesToSkip > 0?1:0))*_timeStep+5E-7);
				_buffer->startTime = nextStep - Core::TimeSpan(_buffer->samplesToSkip*_buffer->dt+5E-7);
			}
		}

		// Still samples missing and no more data available, return
		if ( _buffer->missingSamples > 0 ) return NULL;
	}

	do {
		if ( _buffer->samplesToSkip == 0 ) {
			ComplexDoubleArrayPtr spec;
			Core::Time startTime;

			// Calculate spectrum from ringbuffer
			startTime = _buffer->startTime;

			// Copy data
			copy(_buffer->tmp, _buffer->tmpOffset, _buffer->buffer, _buffer->front);

			size_t sampleCount = _buffer->buffer.size();

			// Demean data excluding the padding window
			demean(_buffer->tmp.size()-_buffer->tmpOffset*2, _buffer->tmp.typedData()+_buffer->tmpOffset);
			// Detrend data excluding the padding window
			detrend(_buffer->tmp.size()-_buffer->tmpOffset*2, _buffer->tmp.typedData()+_buffer->tmpOffset);
			// Apply Von-Hann window
			Math::HannWindow<double>().apply(_buffer->tmp.size()-_buffer->tmpOffset*2, _buffer->tmp.typedData()+_buffer->tmpOffset, _taperWidth);

			spec = new ComplexDoubleArray;
			Math::fft(spec->impl(), _buffer->tmp.size(), _buffer->tmp.typedData());

			if ( _specSamples > 0 )
				reduce<Mag>(*spec, _specSamples);

			if ( spec ) {
				Spectrum *spectrum;
				spectrum = new Spectrum(startTime, startTime + Core::TimeSpan(sampleCount*_buffer->dt),
				                        _timeStep, _buffer->sampleRate*0.5,
				                        (int)sampleCount/2);
				spectrum->setData(spec.get());
				_nextSpectra.push_back(spectrum);
			}

			// Still need to wait until N samples have been fed.
			_buffer->samplesToSkip = _buffer->sampleRate * _timeStep + 0.5;
		}

		size_t num_samples = std::min(_buffer->samplesToSkip, data_len);

		size_t chunk_size = std::min(num_samples, _buffer->buffer.size()-_buffer->front);
		memcpy(buffer + _buffer->front, data, chunk_size*sizeof(double));

		data += chunk_size;

		// Split chunks
		if ( chunk_size < num_samples ) {
			chunk_size = num_samples - chunk_size;

			memcpy(buffer, data, chunk_size*sizeof(double));

			_buffer->front = chunk_size;

			data += chunk_size;
		}
		else {
			_buffer->front += chunk_size;
			if ( _buffer->front >= _buffer->buffer.size() )
				_buffer->front -= _buffer->buffer.size();
		}

		_buffer->startTime += Core::TimeSpan(_buffer->dt*num_samples+5E-7);
		_buffer->samplesToSkip -= num_samples;

		data_len -= num_samples;
	}
	while ( data_len > 0 );

	return NULL;
}