void process(double *buffer) { detrend(buffer); update_pwelch(buffer); display_signal_power(buffer); // display_spectrum(buffer); }
void normalize( int n , float vec[] ) { register int ii ; register float sqsum ; detrend( n , vec ) ; sqsum = 0.0 ; for( ii=0 ; ii < n ; ii++ ) sqsum += vec[ii] * vec[ii] ; if( sqsum < 1.e-10 ){ for( ii=0 ; ii < n ; ii++ ) vec[ii] = 0.0 ; } else { sqsum = 1.0 / sqrt(sqsum) ; for( ii=0 ; ii < n ; ii++ ) vec[ii] *= sqsum ; } }
int main(int argc, char* argv[]){ int c, index; char* str; unsigned short opt = 0; std::string outfile, infile, value; std::stringstream input; std::ifstream ifs; std::ofstream ofs; unsigned int numLags, d; double* differenced; double* detrended; double a, b; while ((c = getopt (argc, argv, "pd:o:x:t")) != -1){ switch(c){ case 'p': if(!(opt & PACF_OPT_FILEIN)){ opt |= PACF_OPT_PIPE; }else{ printUsage(argv[0]); return 1; } break; case 'd': index = optind-1; str = argv[index]; index++; if(str[0] != '-' && !(opt & PACF_OPT_PIPE)){ infile = std::string(str); opt |= PACF_OPT_FILEIN; }else{ printUsage(argv[0]); return 1; } optind = index; break; case 'o': index = optind-1; str = argv[index]; index++; if(str[0] != '-'){ outfile = std::string(str); opt |= PACF_OPT_FILEOUT; }else{ printUsage(argv[0]); return 1; } optind = index; break; case 'x': index = optind-1; str = argv[index]; index++; if(str[0] != '-'){ d = atoi(str); opt |= PACF_OPT_DIFFERENCE; }else{ printUsage(argv[0]); return 1; } optind = index; break; case 't': opt |= PACF_OPT_DETREND; break; } } index = optind; if(index < argc){ str = argv[index]; index++; numLags = atoi(str); }else{ printUsage(argv[0]); return 1; } if(opt & PACF_OPT_PIPE){ char byte; while(std::cin.get(byte)){ input << byte; } }else if(opt & PACF_OPT_FILEIN){ ifs.open(infile.c_str(),std::ios::in); char byte; while(ifs.get(byte)){ input << byte; } ifs.close(); }else{ printUsage(argv[0]); return 1; } std::vector<double> data; while(getline(input,value,'\n')){ data.push_back(atof(value.c_str())); } double* pacf = new double[numLags]; if(opt & PACF_OPT_DIFFERENCE){ differenced = new double[data.size()-d]; difference(&(data[0]),data.size(),d,differenced); double m = mean(differenced,data.size()-d); if(opt & PACF_OPT_DETREND){ detrended = new double[data.size()-d]; detrend(differenced,data.size()-d,&a,&b,detrended); partial_autocorrelation_function(detrended,data.size()-d,numLags,0,pacf); delete[] detrended; }else{ partial_autocorrelation_function(differenced,data.size()-d,numLags,m,pacf); } delete[] differenced; }else{ double m = mean(&(data[0]),data.size()); if(opt & PACF_OPT_DETREND){ detrended = new double[data.size()]; detrend(&(data[0]),data.size(),&a,&b,detrended); partial_autocorrelation_function(detrended,data.size(),numLags,0,pacf); delete[] detrended; }else{ partial_autocorrelation_function(&(data[0]),data.size(),numLags,m,pacf); } } if(opt & PACF_OPT_FILEOUT) ofs.open(outfile.c_str(),std::ios::out); unsigned int i; for(i=0;i<numLags;i++){ std::stringstream line; line << pacf[i] << "\n"; if(opt & PACF_OPT_FILEOUT){ ofs << line.rdbuf(); }else{ std::cout << line.rdbuf(); } } if(opt & PACF_OPT_FILEOUT) ofs.close(); delete[] pacf; return 0; }
void detrend(std::vector<double> &data, double m, double n) { detrend((int)data.size(), &data[0], m, n); }
PlotLine * LOWPASS::getLowpass (PlotLine *in, double fre, double wid) { PlotLine *out = new PlotLine; if (in->getSize() == 0) return out; // ---------------------------------------------------------------------- double slope = 0; // will be modified on call to detrend double intercept = 0; int length = 0; // original caller size int n = 0; // size raised to next power of 2 for fft int i = 0; length = in->getSize(); // Detrend input series PlotLine *series = detrend(in, slope, intercept, true); // Raise length to next power of 2, pad with zero PlotLine *series2 = raise2Power(series, 0); n = series2->getSize(); //qtsFFT fft(n); // construct fft object fft = new qtsFFT(n); // do fft PlotLine * fftFreq = fft->do_FFTqts(series2); //PlotLine * fftFreq = fft.do_FFTqts(series2); // apply low pass filter double f = 0; double dist = 0; double wt = 0; int halfn = n/2; double freqSave = fftFreq->getData(halfn); for (i = 0 ; i < halfn ; i++) { f = (double) i / (double) n ; // Frequency if (f <= fre) // Flat response wt = 1.0 ; else { dist = (f - fre) / wid; wt = exp ( -dist * dist ) ; } fftFreq->setData(i, fftFreq->getData(i) * wt) ; fftFreq->setData(halfn + i, fftFreq->getData(halfn + i) * wt) ; } dist = (0.5 - fre) / wid; // Do Nyquist in fftFreq[0] fftFreq->setData(halfn, freqSave * exp ( -dist * dist )) ; // Do inverse FFT to recover real domain PlotLine *fftReal = fft->do_iFFTqts(fftFreq); //PlotLine *fftReal = fft.do_iFFTqts(fftFreq); // Retrend input series, n.b. original length PlotLine *series3 = detrend(fftReal, slope, intercept, false); for (i = 0; i < length; i++) out->append(series3->getData(i)); delete series; delete series2; delete series3; delete fftReal; delete fftFreq; delete fft; return out; }
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 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; }
int hilbert(int numsamp,const double *f,double *fhilb) { void cfft(); int find_length(); void detrend(); int i, j,npts_max; double bpfilt; dcomplex imag; dcomplex *x; if(numsamp<=0) { fprintf(stderr,"%s\n","No data points read ...."); return (1); } npts_max = find_length(numsamp); if (npts_max == 0) { fprintf(stderr,"Too long input time series \n"); return (2); } x = (dcomplex *) malloc(npts_max * sizeof(dcomplex)); if ( x == NULL ) { fprintf(stderr,"Incorrect allocation\n"); return (3); } imag.re = 0.; imag.im = 1.0; for( i=0; i<numsamp; i++) { x[i].re = f[i]; x[i].im = 0.; } for(i=numsamp; i<npts_max; i++) x[i].re = x[i].im = 0.; cfft( x,npts_max,-1 ); for (i=1; i<=npts_max/2; ++i) { x[i] = dcmult(x[i],imag); } x[0].re = 0.; x[0].im = 0.; for( i=(npts_max/2)+1; i<npts_max; i++ ) x[i] = dconj(x[npts_max-i]); cfft( x,npts_max,1 ); for( i=0; i<numsamp; i++) fhilb[i] = x[i].re/npts_max; detrend(fhilb, numsamp); free(x); return (0); }
int main(int argc, char* argv[]){ int c, index; char* str; unsigned short opt = 0; std::string outfile, infile, modelfile, value; std::stringstream input; std::ifstream ifs; std::ofstream ofs; unsigned int max_lags, d; double* differenced; double* detrended; double a, b; while ((c = getopt (argc, argv, "pd:o:x:t")) != -1){ switch(c){ case 'p': if(!(opt & OPT_FILEIN)){ opt |= OPT_PIPE; }else{ printUsage(argv[0]); return 1; } break; case 'd': index = optind-1; str = argv[index]; index++; if(str[0] != '-' && !(opt & OPT_PIPE)){ infile = std::string(str); opt |= OPT_FILEIN; }else{ printUsage(argv[0]); return 1; } optind = index; break; case 'o': index = optind-1; str = argv[index]; index++; if(str[0] != '-'){ outfile = std::string(str); opt |= OPT_FILEOUT; }else{ printUsage(argv[0]); return 1; } optind = index; break; case 'x': index = optind-1; str = argv[index]; index++; if(str[0] != '-'){ d = atoi(str); opt |= OPT_DIFFERENCE; }else{ printUsage(argv[0]); return 1; } optind = index; break; case 't': opt |= OPT_DETREND; break; } } index = optind; if(index < argc){ str = argv[index]; index++; max_lags = atoi(str); }else{ printUsage(argv[0]); return 1; } if(opt & OPT_PIPE){ char byte; while(std::cin.get(byte)){ input << byte; } }else if(opt & OPT_FILEIN){ ifs.open(infile.c_str(),std::ios::in); char byte; while(ifs.get(byte)){ input << byte; } ifs.close(); }else{ printUsage(argv[0]); return 1; } std::vector<double> data; while(getline(input,value,'\n')){ data.push_back(atof(value.c_str())); } double p, q; if(opt & OPT_DIFFERENCE){ differenced = new double[data.size()-d]; if(opt & OPT_DETREND){ detrended = new double[data.size()-d]; detrend(differenced,data.size()-d,&a,&b,detrended); infer_lags(detrended,data.size()-d,max_lags,&p,&q); delete[] detrended; }else{ infer_lags(differenced,data.size()-d,max_lags,&p,&q); } delete[] differenced; }else{ if(opt & OPT_DETREND){ detrended = new double[data.size()]; detrend(&(data[0]),data.size(),&a,&b,detrended); infer_lags(detrended,data.size(),max_lags,&p,&q); delete[] detrended; }else{ infer_lags(&(data[0]),data.size(),max_lags,&p,&q); } } if(opt & OPT_FILEOUT){ ofs.open(outfile.c_str(),std::ios::out); ofs << p << " " << q << "\n"; ofs.close(); }else{ std::cout << p << " " << q << "\n"; } return 0; }