예제 #1
0
KstObject::UpdateType KstEquation::update(int update_counter) {
  Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED);

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

  bool xUpdated = false;
  bool usedUpdated = false;

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

  if (!_pe) {
    return setLastUpdateResult(NO_CHANGE);
  }

  assert(update_counter >= 0);

  if (_xInVector == _inputVectors.end()) {
    _xInVector = _inputVectors.find(XINVECTOR);
    if (!*_xInVector) { // This is technically sort of fatal
      return setLastUpdateResult(NO_CHANGE);
    }
  }

  writeLockInputsAndOutputs();

  KstVectorPtr v = *_xInVector;

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

  Equation::Context ctx;
  ctx.sampleCount = _ns;
  ctx.xVector = v;
  usedUpdated = _pe && KstObject::UPDATE == _pe->update(update_counter, &ctx);

  KstObject::UpdateType rc = NO_CHANGE; // if force, rc = UPDATE anyway.
  if (force || xUpdated || usedUpdated) {
    _isValid = FillY(force);
    rc = UPDATE;
  }
  v = *_yOutVector;
  if (rc == UPDATE) {
    v->setDirty();
  }
  v->update(update_counter);

  unlockInputsAndOutputs();

  return setLastUpdateResult(rc);
}
예제 #2
0
KstObject::UpdateType KstCSD::update(int update_counter) {

  KstVectorPtr inVector = _inputVectors[INVECTOR];

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

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

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

  bool xUpdated = KstObject::UPDATE == inVector->update(update_counter);
  // if vector was not changed, don't update the CSD
  if (!xUpdated && !force) {
    return setLastUpdateResult(NO_CHANGE);
  }

  double *tempOutput, *input;
  int tempOutputLen = PSDCalculator::calculateOutputVectorLength(_windowSize, _average, _averageLength);
  _PSDLen = tempOutputLen;
  tempOutput = new double[tempOutputLen];

  input = inVector->value();

  int xSize = 0;
  for (int i=0; i < inVector->length(); i+= _windowSize) {
    //ensure there is enough data left.
    if (i + _windowSize >= inVector->length()) {
        break; //If there isn't enough left for a complete window.
    }

    _psdCalculator.calculatePowerSpectrum(input + i, _windowSize, tempOutput, tempOutputLen, _removeMean,  false, _average, _averageLength, _apodize, _apodizeFxn, _gaussianSigma, _outputType, _frequency);
    
    // resize output matrix
    (*_outMatrix)->resize(xSize+1, tempOutputLen);

    if ((*_outMatrix)->sampleCount() == (xSize+1)*tempOutputLen) { // all is well.
      // copy elements to output matrix
      for (int j=0; j < tempOutputLen; j++) {
        (*_outMatrix)->setValueRaw(xSize, j, tempOutput[j]);
      }
    } else {
      KstDebug::self()->log(i18n("Could not allocate sufficient memory for CSD."), KstDebug::Error);
      break;
    }

    xSize++;
  }

  delete tempOutput;

  double frequencyStep = .5*_frequency/(double)(tempOutputLen-1);

  (*_outMatrix)->change((*_outMatrix)->tagName(), xSize, tempOutputLen, 0, 0, _windowSize, frequencyStep);
  (*_outMatrix)->update(update_counter);

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

  if (!isValid()) {
    return setLastUpdateResult(NO_CHANGE);
  }

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

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

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

#define CLEANUP() do {\
  for (unsigned i = 0; i < _outStringCnt; ++i) { \
    if (_outStrings[i]) { \
      free(_outStrings[i]); \
      _outStrings[i] = 0L; \
    } \
  } \
  for (unsigned i = 0; i < _inStringCnt; ++i) { \
    if (_inStrings[i]) { \
      free(_inStrings[i]); \
      _inStrings[i] = 0L; \
    } \
  } \
  } while(0)


  writeLockInputsAndOutputs();

  const QValueList<Plugin::Data::IOValue>& itable = _plugin->data()._inputs;
  const QValueList<Plugin::Data::IOValue>& otable = _plugin->data()._outputs;
  int itcnt = 0, vitcnt = 0, sitcnt = 0;
  bool doUpdate = force;

  // Populate the input scalars and vectors
  for (QValueList<Plugin::Data::IOValue>::ConstIterator it = itable.begin(); it != itable.end(); ++it) {
    if ((*it)._type == Plugin::Data::IOValue::TableType) {
      if (!_inputVectors.contains((*it)._name)) {
        KstDebug::self()->log(i18n("Input vector [%1] for plugin %2 not found.  Unable to continue.").arg((*it)._name).arg(tagName()), KstDebug::Error);
        CLEANUP();
        return setLastUpdateResult(NO_CHANGE);
      }
      KstVectorPtr iv = _inputVectors[(*it)._name];
      if (!iv) {
        kstdFatal() << "Input vector \"" << (*it)._name << "\" for plugin " << tag().displayString() << " is invalid." << endl;
      }
      doUpdate = (UPDATE == iv->update(update_counter)) || doUpdate;
      _inVectors[vitcnt] = iv->value();
      _inArrayLens[vitcnt++] = iv->length();
    } else if ((*it)._type == Plugin::Data::IOValue::FloatType) {
      KstScalarPtr is = _inputScalars[(*it)._name];
      if (!is) {
        kstdFatal() << "Input scalar \"" << (*it)._name << "\" for plugin " << tag().displayString() << " is invalid." << endl;
      }
      doUpdate = (UPDATE == is->update(update_counter)) || doUpdate;
      _inScalars[itcnt++] = is->value();
    } else if ((*it)._type == Plugin::Data::IOValue::StringType) {
      KstStringPtr is = _inputStrings[(*it)._name];
      if (!is) {
        kstdFatal() << "Input string \"" << (*it)._name << "\" for plugin " << tag().displayString() << " is invalid." << endl;
      }
      doUpdate = (UPDATE == is->update(update_counter)) || doUpdate;
      // Maybe we should use UTF-8 instead?
      _inStrings[sitcnt++] = strdup(is->value().latin1());
    } else if ((*it)._type == Plugin::Data::IOValue::PidType) {
      _inScalars[itcnt++] = getpid();
    }
  }

  if (!doUpdate) {
    CLEANUP();
    unlockInputsAndOutputs();
    return setLastUpdateResult(NO_CHANGE);
  }

  vitcnt = 0;
  // Populate the output vectors
  for (QValueList<Plugin::Data::IOValue>::ConstIterator it = otable.begin();
                                                         it != otable.end();
                                                                        ++it) {
    if ((*it)._type == Plugin::Data::IOValue::TableType) {
      if (!_outputVectors.contains((*it)._name)) {
        KstDebug::self()->log(i18n("Output vector [%1] for plugin %2 not found.  Unable to continue.").arg((*it)._name).arg(tagName()), KstDebug::Error);
        CLEANUP();
        unlockInputsAndOutputs();
        return setLastUpdateResult(NO_CHANGE);
      }
      _outVectors[vitcnt] = _outputVectors[(*it)._name]->value();
      _outArrayLens[vitcnt++] = _outputVectors[(*it)._name]->length();
    }
  }

  if (_outStringCnt > 0) {
    memset(_outStrings, 0, _outStringCnt*sizeof(char *));
  }

  int rc;
  if (_inStringCnt > 0 || _outStringCnt > 0) {
    if (_plugin->data()._localdata) {
      rc = _plugin->call(_inVectors, _inArrayLens, _inScalars,
          _outVectors, _outArrayLens, _outScalars,
          const_cast<const char**>(_inStrings), _outStrings, &_localData);
    } else {
      rc = _plugin->call(_inVectors, _inArrayLens, _inScalars,
          _outVectors, _outArrayLens, _outScalars,
          const_cast<const char**>(_inStrings), _outStrings);
    }
  } else {
    if (_plugin->data()._localdata) {
      rc = _plugin->call(_inVectors, _inArrayLens, _inScalars,
          _outVectors, _outArrayLens, _outScalars, &_localData);
    } else {
      rc = _plugin->call(_inVectors, _inArrayLens, _inScalars,
          _outVectors, _outArrayLens, _outScalars);
    }
  }

  if (rc == 0) {
    itcnt = 0;
    vitcnt = 0;
    sitcnt = 0;
    setLastUpdateResult(UPDATE); // make sure that provider callbacks work
    // Read back the output vectors and scalars
    for (QValueList<Plugin::Data::IOValue>::ConstIterator it = otable.begin();
        it != otable.end();
        ++it) {
      if ((*it)._type == Plugin::Data::IOValue::TableType) {
        KstVectorPtr vp = _outputVectors[(*it)._name];
        vectorRealloced(vp, _outVectors[vitcnt], _outArrayLens[vitcnt]);
        vp->setDirty();
        // Inefficient, but do we have any other choice?  We don't really know
        // from the plugin how much of this vector is "new" or "shifted"
        vp->setNewAndShift(vp->length(), vp->numShift());
        vp->update(update_counter);
        vitcnt++;
      } else if ((*it)._type == Plugin::Data::IOValue::FloatType) {
        KstScalarPtr sp = _outputScalars[(*it)._name];
        sp->setValue(_outScalars[itcnt++]);
        sp->update(update_counter);
      } else if ((*it)._type == Plugin::Data::IOValue::StringType) {
        KstStringPtr sp = _outputStrings[(*it)._name];
        sp->setValue(_outStrings[sitcnt++]);
        sp->update(update_counter);
      }
    }

    // if we have a fit plugin then create the necessary scalars from the parameter vector
    createFitScalars();
    _lastError = QString::null;
  } else if (rc > 0) {
    if (_lastError.isEmpty()) {
      const char *err = _plugin->errorCode(rc);
      if (err && *err) {
        _lastError = err;
        KstDebug::self()->log(i18n("Plugin %1 produced error: %2.").arg(tagName()).arg(_lastError), KstDebug::Error);
      } else {
        _lastError = QString::null;
      }
    }
  } else {
    bool doSend = _lastError.isEmpty() ? true : false;

    switch (rc) {
      case -1:
        _lastError = i18n("Generic Error");
        break;
      case -2:
        _lastError = i18n("Input Error");
        break;
      case -3:
        _lastError = i18n("Memory Error");
        break;
      default:
        _lastError = i18n("Unknown Error");
        break;
    }

    if (doSend) {
      KstDebug::self()->log(i18n("Plugin %2 produced error: %1.").arg(_lastError).arg(tagName()), KstDebug::Error);
    }
  }

  unlockInputsAndOutputs();

  CLEANUP();
#undef CLEANUP
  return setLastUpdateResult(UPDATE);
}
예제 #4
0
KstObject::UpdateType EventMonitorEntry::update(int updateCounter) {
  Q_ASSERT(myLockStatus() == KstRWLock::WRITELOCKED);

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

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

  writeLockInputsAndOutputs();

  if (!_pExpression) {
    reparse();
  }

  KstVectorPtr xv = *_xVector;
  KstVectorPtr yv = *_yVector;
  int ns = 1;

  for (KstVectorMap::ConstIterator i = _vectorsUsed.begin(); i != _vectorsUsed.end(); ++i) {
    ns = qMax(ns, i.value()->length());
  }

  double *rawValuesX = 0L;
  double *rawValuesY = 0L;
  if (xv && yv) {
    if (xv->resize(ns)) {
      rawValuesX = xv->value();
    }

    if (yv->resize(ns)) {
      rawValuesY = yv->value();
    }
  }

  Equation::Context ctx;
  ctx.sampleCount = ns;
  ctx.x = 0.0;

  if (needToEvaluate()) {
    if (_pExpression) {
      for (ctx.i = _numDone; ctx.i < ns; ++ctx.i) {
        const double value = _pExpression->value(&ctx);
        if (value != 0.0) { // The expression evaluates to true
          log(ctx.i);
          if (rawValuesX && rawValuesY) {
            rawValuesX[ctx.i] = ctx.i;
            rawValuesY[ctx.i] = 1.0;
          }
        } else {
          if (rawValuesX && rawValuesY) {
            rawValuesX[ctx.i] = ctx.i;
            rawValuesY[ctx.i] = 0.0;
          }
        }
      }
      _numDone = ns;
      logImmediately();
    }
  } else {
    _numDone = ns;
  }

  if (xv) {
    xv->setDirty();
    xv->update(updateCounter);
  }

  if (yv) {
    yv->setDirty();
    yv->update(updateCounter);
  }

  unlockInputsAndOutputs();

  return setLastUpdateResult(NO_CHANGE);
}
예제 #5
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;
}
예제 #6
0
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);
}
예제 #7
0
KstObject::UpdateType KstCSD::update(int update_counter) {
  
  KstVectorPtr inVector = _inputVectors[INVECTOR];

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

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

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

  bool xUpdated = KstObject::UPDATE == inVector->update(update_counter);
  // if vector was not changed, don't update the CSD
  if ((!xUpdated) && !force ) {
    return setLastUpdateResult(NO_CHANGE);
  }
  
  // create a psd generator
  KstPSDGenerator psdGenerator(0L, _frequency, _average, _length,
                               _apodize, _removeMean, _apodizeFxn, _gaussianSigma);
  int xSize = 0;
  for (int i=0; i < inVector->length(); i+= _windowSize + 1) {
    int vectorSize = _windowSize;
    // determine size of actual input data
    if (i + _windowSize >= inVector->length()) {
      if (i == 0) {
        // if this is the one and only window, get a PSD
        vectorSize = i + _windowSize - inVector->length();
      } else {
        // don't PSD the last window if it is chopped off
        break;  
      }
    }
    
    // copy input vector elements into subvector
    QValueVector<double> psdInputVector(_windowSize, 0);
    double* inVectorArray = inVector->value();
    for (int j=0; j < vectorSize; j++) {
      psdInputVector[j] = inVectorArray[i+j];
    }

    // set the vector and calculate PSD
    psdGenerator.setInputVector(&psdInputVector);
    psdGenerator.updateNow();
    
    // resize output matrix
    (*_outMatrix)->resize(xSize+1, psdGenerator.powerVector()->size());
    
    // copy elements to output matrix
    for (uint j=0; j < psdGenerator.powerVector()->size(); j++) {
      (*_outMatrix)->setValueRaw(xSize, j, psdGenerator.powerVector()->at(j));
    }
    xSize++;
  }
 
  (*_outMatrix)->change((*_outMatrix)->tagName(), xSize, psdGenerator.frequencyVector()->size(), 0, 0, _windowSize, psdGenerator.frequencyVectorStep());
  
  (*_outMatrix)->update(update_counter);
      
  return setLastUpdateResult(UPDATE);
}