[Kst] kdeextragear-2/kst/kst
Barth Netterfield
netterfield at astro.utoronto.ca
Sat Nov 20 07:06:34 CET 2004
CVS commit by netterfield:
BUG:
Fix psd normalization and special case bugs.
The normalization is now such that an input time stream with a 1 hz sample rate of white
Gaussian noise with unit rms produces a psd with an rms amplitude of sqrt(2)/rtHz, from
0 to 0.5Hz, independent of apodization, mean removal, or averaging.
Approved by George
M +36 -23 kstpsd.cpp 1.12
M +3 -3 kstpsd.h 1.5
--- kdeextragear-2/kst/kst/kstpsd.cpp #1.11:1.12
@@ -139,5 +139,5 @@ void KstPSD::commonConstructor(const QSt
_a = new double[_ALen];
_w = new double[_ALen];
- GenW();
+ _WLen = 0;
_last_f0 = 0;
@@ -174,21 +174,23 @@ KstPSD::~KstPSD() {
}
-void KstPSD::GenW() {
+void KstPSD::GenW(int len) {
int i;
double sW = 0;
- for (i = 0; i < _ALen; i++) {
- //w[i] = 4;
- _w[i] = (1 - cos(2*M_PI*double(i)/double(_ALen)));
+ if (len != _WLen) {
+ for (i = 0; i < len; i++) {
+ _w[i] = (1 - cos(2*M_PI*double(i)/double(len)));
sW += _w[i] * _w[i];
}
- sW = sqrt(sW/double(_ALen));
- for (i = 0; i < _ALen; i++) {
+ sW = sqrt(sW/double(len));
+ for (i = 0; i < len; i++) {
_w[i] /= sW;
}
+ _WLen = len;
+ }
}
-inline double cabs(double r, double i) {
- return sqrt(r*r + i*i);
+inline double cabs2(double r, double i) {
+ return (r*r + i*i);
}
@@ -204,6 +206,8 @@ KstObject::UpdateType KstPSD::update(int
double *psd, *f;
double mean;
+ double nf;
bool force = false;
KstVectorPtr iv = _inputVectors[INVECTOR];
+ bool done;
if (update_counter <= 0) {
@@ -217,4 +221,6 @@ KstObject::UpdateType KstPSD::update(int
v_len = iv->sampleCount();
n_subsets = v_len/_PSDLen+1;
+ if (v_len%_PSDLen==0) n_subsets--;
+
_last_n_new += iv->numNew();
@@ -234,11 +240,16 @@ KstObject::UpdateType KstPSD::update(int
}
- for (i_subset = 0; i_subset < n_subsets; i_subset++) {
+ nf = 0;
+ done = false;
+
+ for (i_subset = 0; !done; i_subset++) {
/* copy each chunk into a[] and find mean */
- if (i_subset*_PSDLen + _ALen <= v_len) {
+ if (i_subset*_PSDLen + _ALen < v_len) {
copyLen = _ALen;
} else {
copyLen = v_len - i_subset*_PSDLen;
+ done = true;
}
+
mean = 0;
for (i_samp = 0; i_samp < copyLen; i_samp++) {
@@ -252,4 +263,5 @@ KstObject::UpdateType KstPSD::update(int
}
+ if (apodize()) GenW(copyLen);
/* Remove Mean and apodize */
if (removeMean() && apodize()) {
@@ -266,4 +278,8 @@ KstObject::UpdateType KstPSD::update(int
}
}
+
+ nf += copyLen;
+
+
for (;i_samp < _ALen; i_samp++) {
_a[i_samp] = 0.0;
@@ -272,9 +288,8 @@ KstObject::UpdateType KstPSD::update(int
/* fft a */
rdft(_ALen, 1, _a);
- /* sum each bin into psd[] */
- psd[0] += _a[0];
- psd[_PSDLen-1] += fabs(_a[1]);
+ psd[0] += _a[0]*_a[0];
+ psd[_PSDLen-1] += _a[1]*_a[1];
for (i_samp=1; i_samp<_PSDLen-1; i_samp++) {
- psd[i_samp]+= cabs(_a[i_samp*2], _a[i_samp*2+1]);
+ psd[i_samp]+= cabs2(_a[i_samp*2], _a[i_samp*2+1]);
}
}
@@ -284,8 +299,7 @@ KstObject::UpdateType KstPSD::update(int
_last_n_new = 0;
- _norm_factor = 1.0/(sqrt(double(_Freq)*double(_PSDLen))*double(n_subsets));
-
+ nf = 1.0/(double(_Freq)*double(nf/2.0));
for ( i_samp = 0; i_samp<_PSDLen; i_samp++ ) {
- psd[i_samp] *= _norm_factor;
+ psd[i_samp] = sqrt(psd[i_samp]*nf);
}
@@ -373,5 +387,4 @@ void KstPSD::_adjustLengths() {
delete[] _w;
_w = new double[_ALen];
- GenW();
_last_f0 = 0;
--- kdeextragear-2/kst/kst/kstpsd.h #1.4:1.5
@@ -71,5 +71,5 @@ class KstPSD : public KstDataObject {
private:
- void GenW();
+ void GenW(int len);
void commonConstructor(const QString& in_tag, KstVectorPtr in_V,
double freq, bool average, int len,
@@ -86,9 +86,9 @@ class KstPSD : public KstDataObject {
double _Freq;
int _Len;
- double _norm_factor;
double *_w;
int _PSDLen;
double *_a;
int _ALen;
+ int _WLen;
KstVectorMap::Iterator _sVector, _fVector;
More information about the Kst
mailing list