示例#1
0
KstObject::UpdateType KstPSDCurve::update(int update_counter) {
  int i_subset, i_samp;
  int n_subsets;
  int v_len;
  int copyLen;
  double mean;
  double y;
  bool force = false;
  KstVectorPtr iv = _inputVectors[INVECTOR];

  double *psd;

  if (KstObject::checkUpdateCounter(update_counter))
    return NO_CHANGE;

  if (update_counter <= 0) {
    force = true;
  } else {
    iv->update(update_counter);
  }

  v_len = iv->sampleCount();

  n_subsets = v_len/PSDLen+1;

  last_n_new += iv->numNew();

  if ((last_n_new < PSDLen/16) && (n_subsets - last_n_subsets < 1) && !force) {
    return NO_CHANGE;
  }

  psd = (*_sVector)->value();

  for (i_samp = 0; i_samp < PSDLen; i_samp++) {
    psd[i_samp] = 0;
  }

  for (i_subset = 0; i_subset < n_subsets; i_subset++) {
    /* copy each chunk into a[] and find mean */
    if (i_subset*PSDLen + ALen <= v_len) {
      copyLen = ALen;
    } else {
      copyLen = v_len - i_subset*PSDLen;
    }
    mean = 0;
    for (i_samp = 0; i_samp < copyLen; i_samp++) {
      mean += (
        a[i_samp] =
        iv->interpolate(i_samp + i_subset*PSDLen, v_len)
        );
    }
    if (copyLen>1) mean/=(double)copyLen;

    /* Remove Mean and apodize */
    if (removeMean() && appodize()) {
      for (i_samp=0; i_samp<copyLen; i_samp++) {
        a[i_samp]= (a[i_samp]-mean)*w[i_samp];
      }
    } else if (removeMean()) {
      for (i_samp=0; i_samp<copyLen; i_samp++) {
        a[i_samp] -= mean;
      }
    } else if (appodize()) {
      for (i_samp=0; i_samp<copyLen; i_samp++) {
        a[i_samp] *= w[i_samp];
      }
    }
    for (;i_samp < ALen; i_samp++) a[i_samp] = 0.0;

    /* fft a */
    rdft(ALen, 1, a);
    /* sum each bin into psd[] */
    psd[0]+=a[0];
    psd[PSDLen-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]);
    }
  }

  last_f0 = 0;
  last_n_subsets = n_subsets;
  last_n_new = 0;

  norm_factor = 1.0/(sqrt(double(Freq)*double(PSDLen))*double(n_subsets));

  psd[0]*=norm_factor;

  MaxY = MinY = mean = psd[0];
  if (psd[0]>0)
    MinPosY = psd[0];
  else (MinPosY = 1.0e300);

  /* normalize psd */
  for (i_samp=1; i_samp<PSDLen; i_samp++) {
    y = (psd[i_samp]*=norm_factor);
    if (y>MaxY)
      MaxY=y;
    if (y<MinY)
      MinY=y;
    if ((y>0) && (y<MinPosY))
      MinPosY = y;
    mean +=y;
  }

  if (PSDLen > 0)
    MeanY = mean/PSDLen;
  else MeanY = 0; // should never ever happen...

  NS = PSDLen;

  if (Freq <= 0)
    Freq = 1.0;

  MaxX = Freq/2.0;
  MinX = 0;
  MinPosX = 1.0/double(NS) * MaxX;
  MeanX = MaxX/2.0;

  double *f = (*_fVector)->value();
  f[0] = 0;
  f[1] = Freq/2.0;

  (*_sVector)->update(update_counter);
  (*_fVector)->update(update_counter);

  return UPDATE;
}
KstObject::UpdateType KstPSD::update(int update_counter) {
  Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED);

  bool force = dirty();
  setDirty(false);

  if (KstObject::checkUpdateCounter(update_counter) && !force) {
    return lastUpdateResult();
  }

  if (recursed()) {
    return setLastUpdateResult(NO_CHANGE);
  }

  writeLockInputsAndOutputs();

  KstVectorPtr iv = _inputVectors[INVECTOR];

  if (update_counter <= 0) {
    assert(update_counter == 0);
    force = true;
  }

  bool xUpdated = KstObject::UPDATE == iv->update(update_counter);

  const int v_len = iv->length();

  // Don't touch _last_n_new if !xUpdated since it will certainly be wrong.
  if (!xUpdated && !force) {
    unlockInputsAndOutputs();
    return setLastUpdateResult(NO_CHANGE);
  }

  _last_n_new += iv->numNew();
  assert(_last_n_new >= 0);

  int n_subsets = v_len/_PSDLen;

  // determine if the PSD needs to be updated. if not using averaging, then we need at least _PSDLen/16 new data points. if averaging, then we want enough new data for a complete subset.
  if ( ((_last_n_new < _PSDLen/16) || (_Average && (n_subsets - _last_n_subsets < 1))) &&  iv->length() != iv->numNew() && !force) {
    unlockInputsAndOutputs();
    return setLastUpdateResult(NO_CHANGE);
  }

  _adjustLengths();

  double *psd = (*_sVector)->value();
  double *f = (*_fVector)->value();

  int i_samp;
  for (i_samp = 0; i_samp < _PSDLen; ++i_samp) {
    f[i_samp] = i_samp * 0.5 * _Freq / (_PSDLen - 1);
  }

  _psdCalculator.calculatePowerSpectrum(iv->value(), v_len, psd, _PSDLen, _RemoveMean,  _interpolateHoles, _Average, _averageLen, _Apodize, _apodizeFxn, _gaussianSigma, _Output, _Freq);

  _last_n_subsets = n_subsets;
  _last_n_new = 0;

  updateVectorLabels();
  (*_sVector)->setDirty();
  (*_sVector)->update(update_counter);
  (*_fVector)->setDirty();
  (*_fVector)->update(update_counter);

  unlockInputsAndOutputs();

  return setLastUpdateResult(UPDATE);
}