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