00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef DOUBLESIGNAL_H
00030 #define DOUBLESIGNAL_H
00031
00032 #include "GeopsyCoreDLLExport.h"
00033 #include "SignalTemplate.h"
00034 #include "ComplexSignal.h"
00035 #include "WindowingParameters.h"
00036
00037 namespace GeopsyCore {
00038
00039 class KeepSignal;
00040 class MorletParameters;
00041
00042 class GEOPSYCORE_EXPORT DoubleSignal: public SignalTemplate<double>
00043 {
00044 TRANSLATIONS("DoubleSignal")
00045 public:
00046 enum SignalType {
00047 Waveform=0,
00048 Spectrum=1,
00049 Phase=2,
00050 RealSpectrum=3,
00051 CAmpWaveform=4,
00052 CPhaseWaveform=5,
00053 ArrivalTime=6,
00054 UndefinedSignalType=7
00055 };
00056
00057 DoubleSignal( );
00058 DoubleSignal(int n);
00059 DoubleSignal(const DoubleSignal& o);
00060
00061 void lockProperties() const {_propertiesMutex.lockForWrite();}
00062 void constLockProperties() const {_propertiesMutex.lockForRead();}
00063 void unlockProperies() const {_propertiesMutex.unlock();}
00064
00065
00066 double deltaT() const {return _deltaT;}
00067 double deltaF() const {return _deltaT;}
00068 virtual void setDeltaT(double newval) {_deltaT=newval;}
00069 void setDeltaF(double newval) {setDeltaT(newval);}
00070 double samplingFrequency() const {return 1.0/_deltaT;}
00071 double duration() const {return _deltaT * _nSamples;}
00072 inline virtual void setNSamples(int n);
00073 SignalType type() const {return _type;}
00074 void setType(SignalType t) {if(t!=UndefinedSignalType) _type=t;}
00075 inline bool isReal() const;
00076 inline bool isComplex() const;
00077 inline bool isSpectrum() const;
00078 void copyBasicProperties(const DoubleSignal& o);
00079
00080 static SignalType type(QString t);
00081 static QString typeString(SignalType st);
00082
00083 inline void copySamplesFrom(const DoubleSignal * sig);
00084 void copySamplesFrom(const DoubleSignal * sig, double sigStart, double thisStart, double tToCopy);
00085 void copySamplesFrom(const DoubleSignal * sig, int isigStart, int ithisStart, int nToCopy);
00086 void copyAmplitudeFrom(const DoubleSignal * sig);
00087 int add(const DoubleSignal * sig, double sigStart, double thisStart,
00088 double tToCopy, bool checkInvalid=false, double invalidValue=1e99);
00089 int add(const DoubleSignal * sig);
00090
00091
00092 void fastFourierTransform(SignalType st);
00093
00094 SignalType saveType(SignalType st);
00095 void restoreType(SignalType st);
00096 const DoubleSignal * saveType(SignalType st) const;
00097 void restoreType(const DoubleSignal * sig) const;
00098
00099 bool subtractValue(double val=0.0);
00100 bool filter(const FilterParameters& param);
00101 bool whiten();
00102 bool stddevClip(double factor);
00103 bool agc(double width);
00104 bool taper(const TimeRange& t, const TaperParameters& param);
00105 bool taper(const TaperParameters& param);
00106 bool abs();
00107 bool square();
00108 bool sqrt();
00109 bool decimateAmplitude(double delta);
00110 bool shift(double dt);
00111 bool unglitch(double threshold);
00112 bool smooth(const SmoothingParameters& param, double minFreq, double maxFreq);
00113 bool setValue(double val);
00114
00115 bool discreteFourierTransform();
00116 bool overSample(double factor, const DoubleSignal * sig);
00117 bool decimateTime(int factor, const DoubleSignal * sig);
00118 bool hv(const DoubleSignal * zSig, const DoubleSignal * hSig);
00119
00120 ComplexSignal * morletWavelet(const MorletParameters& param) const;
00121 ComplexSignal * positiveComplexSpectrum(bool fullSize=false) const;
00122 ComplexSignal * complexSpectrum() const;
00123
00124 void stalta(double tsta, double tlta, DoubleSignal * ratio) const;
00125 void staltaToKeep(const WindowingParameters::ShortLongTermAverage& param, KeepSignal * keep, double delay) const;
00126 void clipMaxToKeep(double percentage, KeepSignal * keep, double delay) const;
00127 bool correlation(const DoubleSignal * s1, const DoubleSignal * s2, double maxDelay);
00128 bool normalizedCorrelation(const DoubleSignal * s1, const DoubleSignal * s2, double maxDelay);
00129 bool timeCorrelation(const DoubleSignal * s1, const DoubleSignal * s2, double maxDelay);
00130 double correlation(const DoubleSignal * sig, double sigStart, double thisStart, double length) const;
00131 bool convolution(const DoubleSignal * s1, const DoubleSignal * s2);
00132
00133 double amplitudeAt(double abscissa) const;
00134 double interpoleAt(double abscissa) const;
00135 double maximumAmplitude(int itmin, int itmax) const;
00136 int maximumAmplitudeAt(int itmin, int itmax) const;
00137 double averageAmplitude(int itmin, int itmax) const;
00138 double energy(double minF, double maxF) const;
00139 double power(double excludeBorderRatio=0.0) const;
00140
00141 inline Complex complex(const double * samples, int i) const;
00142 inline void setComplex(double * samples, int i, const Complex& value) const;
00143 inline double amplitude2(const double * samples, int i) const;
00144 double amplitude(const double * samples, int i) const;
00145 void setAmplitude(double * samples, int i, double val) const;
00146 inline double phase(const double * samples, int i) const;
00147 inline double re(const double * samples, int i) const;
00148 inline double im(const double * samples, int i) const;
00149 inline void setRe(double * samples, int i, double value) const;
00150 inline void setIm(double * samples, int i, double value) const;
00151
00152 void debugPrint() const;
00153 protected:
00154 mutable QReadWriteLock _propertiesMutex;
00155 double _deltaT;
00156 SignalType _type;
00157 int _nyquistIndex;
00158 private:
00159 bool correlationCheck(const DoubleSignal * s1, const DoubleSignal * s2, double& maxDelay);
00160 bool correlationProcess(const DoubleSignal * s1, const DoubleSignal * s2,
00161 DoubleSignal * s1t, DoubleSignal * s2t);
00162 bool correlationNormalization(const DoubleSignal * s, DoubleSignal * norm) const;
00163 bool smoothFixedTriang(double width, double minF, double maxF);
00164 bool smoothFreqDepTriang(double ratio, double minF, double maxF);
00165 bool smoothKonno(double constant, double minF, double maxF);
00166 static void filb3(double fc, int ak, double pas, double *a, double *b);
00167 static void frecur(int la, double *a, double *xa, int lb, double *b, double *yb,
00168 int ndeb, int nfin, int npas, int isens, double *x, double *y);
00169 static void filrec(double fc, int type, int ndeb, int nfin, int npas, double *x,
00170 double *y, int nfil, double pas);
00171 int commonSamples(double delay, int otherNSamples, int& thisStart, int& otherStart) const;
00172 };
00173
00174 inline void DoubleSignal::setNSamples(int n)
00175 {
00176 TRACE;
00177 SignalTemplate<double>::setNSamples(n);
00178 _nyquistIndex=_nSamples >> 1;
00179 }
00180
00181 inline double DoubleSignal::re(const double * samples, int i) const
00182 {
00183 TRACE;
00184 if(i<=_nyquistIndex) {
00185 return samples[i];
00186 } else {
00187 return samples[_nSamples-i];
00188 }
00189 }
00190
00191 inline double DoubleSignal::im(const double * samples, int i) const
00192 {
00193 TRACE;
00194 if(i==0) {
00195 return 0.0;
00196 } else if(i < _nyquistIndex) {
00197 return samples[ _nSamples -i ];
00198 } else if(i==_nyquistIndex && !(_nSamples & 0x00000001)) {
00199 return 0.0;
00200 } else {
00201 return -samples[ i ];
00202 }
00203 }
00204
00205 inline void DoubleSignal::setRe(double * samples, int i, double value) const
00206 {
00207 TRACE;
00208 if(i<=_nyquistIndex) {
00209 samples[i]=value;
00210 } else {
00211 samples[_nSamples-i]=value;
00212 }
00213 }
00214
00215 inline void DoubleSignal::setIm(double * samples, int i, double value) const
00216 {
00217 TRACE;
00218 if(i<_nyquistIndex && i>0) {
00219 samples[_nSamples-i]=value;
00220 }
00221
00222 }
00223
00224 inline Complex DoubleSignal::complex(const double * samples, int i) const
00225 {
00226 TRACE;
00227 if(i==0) {
00228 return samples[i];
00229 } else if(i<_nyquistIndex) {
00230 return Complex(samples[i], samples[_nSamples-i]);
00231 } else if(i==_nyquistIndex && !(_nSamples & 0x00000001) ) {
00232 return samples[i];
00233 } else {
00234 return Complex(samples[_nSamples-i], -samples[i]);
00235 }
00236 }
00237
00238 inline void DoubleSignal::setComplex(double * samples, int i, const Complex& value) const
00239 {
00240 TRACE;
00241 if(i>0 && i<_nyquistIndex) {
00242 samples[i]=value.re();
00243 samples[_nSamples-i]=value.im();
00244 } else {
00245 samples[i]=value.re();
00246 }
00247 }
00248
00249 inline double DoubleSignal::amplitude2(const double * samples, int i) const
00250 {
00251 TRACE;
00252 if(i==0) {
00253 return samples[i]*samples[i];
00254 } else if(i!=_nyquistIndex || (_nSamples & 0x00000001)) {
00255 return samples[i]*samples[i] +
00256 samples[_nSamples-i]*samples[_nSamples-i];
00257 } else {
00258 return samples[i]*samples[i];
00259 }
00260 }
00261
00262 inline double DoubleSignal::amplitude(const double * samples, int i) const
00263 {
00264 return ::sqrt(amplitude2(samples, i));
00265 }
00266
00267 inline double DoubleSignal::phase(const double * samples, int i) const
00268 {
00269 return complex(samples, i).phase();
00270 }
00271
00272 inline void DoubleSignal::setAmplitude(double * samples, int i, double val) const
00273 {
00274 if(i==0) {
00275 samples[i]=val;
00276 } else if(i!=_nyquistIndex || (_nSamples & 0x00000001)) {
00277 double ampl=::sqrt(samples[i]*samples[i]+
00278 samples[_nSamples-i]*samples[_nSamples-i]);
00279 if(ampl==0.0) return;
00280 double factor=val/ampl;
00281 samples[i ]*=factor;
00282 samples[_nSamples-i]*=factor;
00283 } else {
00284 samples[i]=val;
00285 }
00286 }
00287
00288 inline bool DoubleSignal::isComplex() const
00289 {
00290 TRACE;
00291 switch (_type) {
00292 case Spectrum:
00293 case Phase:
00294 case CAmpWaveform:
00295 case CPhaseWaveform:
00296 return true;
00297 default:
00298 return false;
00299 }
00300 }
00301
00302 inline bool DoubleSignal::isReal() const
00303 {
00304 TRACE;
00305 switch (_type) {
00306 case Waveform:
00307 case RealSpectrum:
00308 return true;
00309 default:
00310 return false;
00311 }
00312 }
00313
00314 inline bool DoubleSignal::isSpectrum() const
00315 {
00316 TRACE;
00317 switch (_type) {
00318 case Spectrum:
00319 case Phase:
00320 case RealSpectrum:
00321 return true;
00322 default:
00323 return false;
00324 }
00325 }
00326
00327 inline void DoubleSignal::copySamplesFrom(const DoubleSignal * sig)
00328 {
00329 SignalTemplate<double>::copySamplesFrom(sig);
00330 }
00331
00332 }
00333
00334 #endif // DOUBLESIGNAL_H