File indexing completed on 2024-12-22 04:18:04

0001 /***************************************************************************
0002  *                                                                         *
0003  *   copyright : (C) 2007 The University of Toronto                        *
0004  *                   netterfield@astro.utoronto.ca                         *
0005  *   copyright : (C) 2005  University of British Columbia                  *
0006  *                   dscott@phas.ubc.ca                                    *
0007  *                                                                         *
0008  *   This program is free software; you can redistribute it and/or modify  *
0009  *   it under the terms of the GNU General Public License as published by  *
0010  *   the Free Software Foundation; either version 2 of the License, or     *
0011  *   (at your option) any later version.                                   *
0012  *                                                                         *
0013  ***************************************************************************/
0014 
0015 
0016 #include "effectivebandwidth.h"
0017 #include "objectstore.h"
0018 #include "ui_effectivebandwidthconfig.h"
0019 
0020 static const QString& VECTOR_IN_X = "Vector In X";
0021 static const QString& VECTOR_IN_Y = "Vector In Y";
0022 static const QString& SCALAR_IN_MIN = "Min. White Noise Freq.";
0023 static const QString& SCALAR_IN_FREQ = "Sampling Frequency (Hz)";
0024 static const QString& SCALAR_IN_K = "K";
0025 
0026 static const QString& SCALAR_OUT_LIMIT = "White Noise Limit";
0027 static const QString& SCALAR_OUT_SIGMA = "White Noise Sigma";
0028 static const QString& SCALAR_OUT_BANDWIDTH = "Effective Bandwidth";
0029 
0030 class ConfigEffectiveBandwidthPlugin : public Kst::DataObjectConfigWidget, public Ui_EffectiveBandwidthConfig {
0031   public:
0032     ConfigEffectiveBandwidthPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_EffectiveBandwidthConfig() {
0033       _store = 0;
0034       setupUi(this);
0035     }
0036 
0037     ~ConfigEffectiveBandwidthPlugin() {}
0038 
0039     void setObjectStore(Kst::ObjectStore* store) { 
0040       _store = store; 
0041       _vectorX->setObjectStore(store);
0042       _vectorY->setObjectStore(store);
0043       _scalarMin->setObjectStore(store);
0044       _scalarFreq->setObjectStore(store);
0045       _scalarK->setObjectStore(store);
0046       _scalarMin->setDefaultValue(0);
0047       _scalarFreq->setDefaultValue(0);
0048       _scalarK->setDefaultValue(0);
0049     }
0050 
0051     void setupSlots(QWidget* dialog) {
0052       if (dialog) {
0053         connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
0054         connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
0055         connect(_scalarMin, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
0056         connect(_scalarFreq, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
0057         connect(_scalarK, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
0058       }
0059     }
0060 
0061     Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); };
0062     void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); };
0063 
0064     Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); };
0065     void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); };
0066 
0067     Kst::ScalarPtr selectedScalarMin() { return _scalarMin->selectedScalar(); };
0068     void setSelectedScalarMin(Kst::ScalarPtr scalar) { return _scalarMin->setSelectedScalar(scalar); };
0069 
0070     Kst::ScalarPtr selectedScalarFreq() { return _scalarFreq->selectedScalar(); };
0071     void setSelectedScalarFreq(Kst::ScalarPtr scalar) { return _scalarFreq->setSelectedScalar(scalar); };
0072 
0073     Kst::ScalarPtr selectedScalarK() { return _scalarK->selectedScalar(); };
0074     void setSelectedScalarK(Kst::ScalarPtr scalar) { return _scalarK->setSelectedScalar(scalar); };
0075 
0076 
0077     virtual void setupFromObject(Kst::Object* dataObject) {
0078       if (EffectiveBandwidthSource* source = static_cast<EffectiveBandwidthSource*>(dataObject)) {
0079         setSelectedVectorX(source->vectorX());
0080         setSelectedVectorY(source->vectorY());
0081         setSelectedScalarMin(source->scalarMin());
0082         setSelectedScalarFreq(source->scalarFreq());
0083         setSelectedScalarK(source->scalarK());
0084       }
0085     }
0086 
0087     virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) {
0088       Q_UNUSED(store);
0089       Q_UNUSED(attrs);
0090 
0091       bool validTag = true;
0092 
0093 //       QStringRef av;
0094 //       av = attrs.value("value");
0095 //       if (!av.isNull()) {
0096 //         _configValue = QVariant(av.toString()).toBool();
0097 //       }
0098 
0099       return validTag;
0100     }
0101 
0102   public slots:
0103     virtual void save() {
0104       if (_cfg) {
0105         _cfg->beginGroup("Effective Bandwidth DataObject Plugin");
0106         _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name());
0107         _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name());
0108         _cfg->setValue("Input Scalar Min. White Noise Freq.", _scalarMin->selectedScalar()->Name());
0109         _cfg->setValue("Input Scalar Sampling Frequency (Hz)", _scalarFreq->selectedScalar()->Name());
0110         _cfg->setValue("Input Scalar K", _scalarK->selectedScalar()->Name());
0111         _cfg->endGroup();
0112       }
0113     }
0114 
0115     virtual void load() {
0116       if (_cfg && _store) {
0117         _cfg->beginGroup("Effective Bandwidth DataObject Plugin");
0118         QString vectorName = _cfg->value("Input Vector X").toString();
0119         Kst::Object* object = _store->retrieveObject(vectorName);
0120         Kst::Vector* vectorX = static_cast<Kst::Vector*>(object);
0121         if (vectorX) {
0122           setSelectedVectorX(vectorX);
0123         }
0124         vectorName = _cfg->value("Input Vector Y").toString();
0125         object = _store->retrieveObject(vectorName);
0126         Kst::Vector* vectorY = static_cast<Kst::Vector*>(object);
0127         if (vectorY) {
0128           setSelectedVectorY(vectorY);
0129         }
0130         QString scalarName = _cfg->value("Input Scalar Min. White Noise Freq.").toString();
0131         object = _store->retrieveObject(scalarName);
0132         Kst::Scalar* scalarMin = static_cast<Kst::Scalar*>(object);
0133         if (scalarMin) {
0134           setSelectedScalarMin(scalarMin);
0135         }
0136         scalarName = _cfg->value("Input Scalar Sampling Frequency (Hz)").toString();
0137         object = _store->retrieveObject(scalarName);
0138         Kst::Scalar* scalarFreq = static_cast<Kst::Scalar*>(object);
0139         if (scalarFreq) {
0140           setSelectedScalarFreq(scalarFreq);
0141         }
0142         scalarName = _cfg->value("Input Scalar K").toString();
0143         object = _store->retrieveObject(scalarName);
0144         Kst::Scalar* scalarK = static_cast<Kst::Scalar*>(object);
0145         if (scalarK) {
0146           setSelectedScalarK(scalarK);
0147         }
0148         _cfg->endGroup();
0149       }
0150     }
0151 
0152   private:
0153     Kst::ObjectStore *_store;
0154 
0155 };
0156 
0157 
0158 EffectiveBandwidthSource::EffectiveBandwidthSource(Kst::ObjectStore *store)
0159 : Kst::BasicPlugin(store) {
0160 }
0161 
0162 
0163 EffectiveBandwidthSource::~EffectiveBandwidthSource() {
0164 }
0165 
0166 
0167 QString EffectiveBandwidthSource::_automaticDescriptiveName() const {
0168   return tr("Effective Bandwidth Plugin Object");
0169 }
0170 
0171 
0172 void EffectiveBandwidthSource::change(Kst::DataObjectConfigWidget *configWidget) {
0173   if (ConfigEffectiveBandwidthPlugin* config = static_cast<ConfigEffectiveBandwidthPlugin*>(configWidget)) {
0174     setInputVector(VECTOR_IN_X, config->selectedVectorX());
0175     setInputVector(VECTOR_IN_Y, config->selectedVectorY());
0176     setInputScalar(SCALAR_IN_MIN, config->selectedScalarMin());
0177     setInputScalar(SCALAR_IN_FREQ, config->selectedScalarFreq());
0178     setInputScalar(SCALAR_IN_K, config->selectedScalarK());
0179   }
0180 }
0181 
0182 
0183 void EffectiveBandwidthSource::setupOutputs() {
0184   setOutputScalar(SCALAR_OUT_LIMIT, "");
0185   setOutputScalar(SCALAR_OUT_SIGMA, "");
0186   setOutputScalar(SCALAR_OUT_BANDWIDTH, "");
0187 }
0188 
0189 
0190 bool EffectiveBandwidthSource::algorithm() {
0191   Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X];
0192   Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y];
0193   Kst::ScalarPtr inputScalarMin = _inputScalars[SCALAR_IN_MIN];
0194   Kst::ScalarPtr inputScalarFreq = _inputScalars[SCALAR_IN_FREQ];
0195   Kst::ScalarPtr inputScalarK = _inputScalars[SCALAR_IN_K];
0196 
0197   Kst::ScalarPtr outputScalarLimit = _outputScalars[SCALAR_OUT_LIMIT];
0198   Kst::ScalarPtr outputScalarSigma = _outputScalars[SCALAR_OUT_SIGMA];
0199   Kst::ScalarPtr outputScalarBandwidth = _outputScalars[SCALAR_OUT_BANDWIDTH];
0200 
0201   //Make sure there is at least 1 element in the input vector
0202   if (inputVectorX->length() < 1) {
0203     _errorString = tr("Error:  Input Vector X invalid size");
0204     return false;
0205   }
0206 
0207   // Make sure the input vectors match.
0208   if (inputVectorX->length() != inputVectorY->length()) {
0209     _errorString = tr("Error:  Input Vector X and Input Vector Y are not the same length");
0210     return false;
0211   }
0212 
0213   double minWhiteNoiseFreq, samplingFrequency, radiometerConstantK;
0214 
0215   minWhiteNoiseFreq = inputScalarMin->value();
0216   samplingFrequency = inputScalarFreq->value();
0217   radiometerConstantK = inputScalarK->value();
0218 
0219   int minWhiteNoiseIndex;
0220 
0221   //fast calculation of index for minWhiteNoiseFreq
0222   int i_bot, i_top;
0223   i_bot = 0;
0224   i_top = inputVectorX->length() - 1;
0225 
0226   while (i_bot + 1 < i_top) {
0227     int i0 = (i_top + i_bot)/2;
0228     if (minWhiteNoiseFreq < inputVectorX->value()[i0]) {
0229       i_top = i0;
0230     } else {
0231       i_bot = i0;
0232     }
0233   }
0234   minWhiteNoiseIndex = i_top;
0235 
0236   //verify calculated indices.
0237   if ( !(minWhiteNoiseIndex>0) || !(minWhiteNoiseIndex<(inputVectorX->length()-1)) ) {
0238     _errorString = tr("Error:  Calculated Indices invalid");
0239     return false;
0240   }
0241 
0242   // calculate white noise limit
0243   double sumY, sumY2;
0244   sumY = sumY2 = 0;
0245 
0246   int i;
0247   double yi;
0248 
0249   for (i = minWhiteNoiseIndex; i < inputVectorX->length(); i++) {
0250     yi = inputVectorY->value()[i];
0251     sumY    +=  yi;
0252     sumY2   +=  pow(yi,2);
0253   }
0254 
0255   double ybar, ysigma;
0256   ybar = sumY/(inputVectorX->length() - minWhiteNoiseIndex);
0257   ysigma = sqrt((sumY2 - 2*ybar*sumY + pow(ybar,2)*(inputVectorX->length() - minWhiteNoiseIndex))/(inputVectorX->length() - minWhiteNoiseIndex));
0258   // end calculate white noise limit
0259 
0260   double effectiveBandwidth = 2*samplingFrequency*pow(radiometerConstantK*inputVectorY->value()[0]/ysigma,2);
0261 
0262   // output fit data
0263   outputScalarLimit->setValue(ybar);
0264   outputScalarSigma->setValue(ysigma);
0265   outputScalarBandwidth->setValue(effectiveBandwidth);
0266 
0267   return true;
0268 }
0269 
0270 
0271 Kst::VectorPtr EffectiveBandwidthSource::vectorX() const {
0272   return _inputVectors[VECTOR_IN_X];
0273 }
0274 
0275 
0276 Kst::VectorPtr EffectiveBandwidthSource::vectorY() const {
0277   return _inputVectors[VECTOR_IN_Y];
0278 }
0279 
0280 
0281 Kst::ScalarPtr EffectiveBandwidthSource::scalarMin() const {
0282   return _inputScalars[SCALAR_IN_MIN];
0283 }
0284 
0285 
0286 Kst::ScalarPtr EffectiveBandwidthSource::scalarFreq() const {
0287   return _inputScalars[SCALAR_IN_FREQ];
0288 }
0289 
0290 
0291 Kst::ScalarPtr EffectiveBandwidthSource::scalarK() const {
0292   return _inputScalars[SCALAR_IN_K];
0293 }
0294 
0295 
0296 QStringList EffectiveBandwidthSource::inputVectorList() const {
0297   QStringList vectors(VECTOR_IN_X);
0298   vectors += VECTOR_IN_Y;
0299   return vectors;
0300 }
0301 
0302 
0303 QStringList EffectiveBandwidthSource::inputScalarList() const {
0304   QStringList scalars(SCALAR_IN_MIN);
0305   scalars += SCALAR_IN_FREQ;
0306   scalars += SCALAR_IN_K;
0307   return scalars;
0308 }
0309 
0310 
0311 QStringList EffectiveBandwidthSource::inputStringList() const {
0312   return QStringList( /*STRING_IN*/ );
0313 }
0314 
0315 
0316 QStringList EffectiveBandwidthSource::outputVectorList() const {
0317   return QStringList( /*VECTOR_OUT*/ );
0318 }
0319 
0320 
0321 QStringList EffectiveBandwidthSource::outputScalarList() const {
0322   QStringList scalars(SCALAR_OUT_LIMIT);
0323   scalars += SCALAR_OUT_SIGMA;
0324   scalars += SCALAR_OUT_BANDWIDTH;
0325   return scalars;
0326 }
0327 
0328 
0329 QStringList EffectiveBandwidthSource::outputStringList() const {
0330   return QStringList( /*STRING_OUT*/ );
0331 }
0332 
0333 
0334 void EffectiveBandwidthSource::saveProperties(QXmlStreamWriter &s) {
0335   Q_UNUSED(s);
0336 //   s.writeAttribute("value", _configValue);
0337 }
0338 
0339 
0340 QString EffectiveBandwidthPlugin::pluginName() const { return tr("Effective Bandwidth"); }
0341 QString EffectiveBandwidthPlugin::pluginDescription() const { return tr("Calculates effective bandwidth from an amplitude spectrum."); }
0342 
0343 
0344 Kst::DataObject *EffectiveBandwidthPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const {
0345 
0346   if (ConfigEffectiveBandwidthPlugin* config = static_cast<ConfigEffectiveBandwidthPlugin*>(configWidget)) {
0347 
0348     EffectiveBandwidthSource* object = store->createObject<EffectiveBandwidthSource>();
0349 
0350     if (setupInputsOutputs) {
0351       object->setInputScalar(SCALAR_IN_MIN, config->selectedScalarMin());
0352       object->setInputScalar(SCALAR_IN_FREQ, config->selectedScalarFreq());
0353       object->setInputScalar(SCALAR_IN_K, config->selectedScalarK());
0354       object->setupOutputs();
0355       object->setInputVector(VECTOR_IN_X, config->selectedVectorX());
0356       object->setInputVector(VECTOR_IN_Y, config->selectedVectorY());
0357     }
0358 
0359     object->setPluginName(pluginName());
0360 
0361     object->writeLock();
0362     object->registerChange();
0363     object->unlock();
0364 
0365     return object;
0366   }
0367   return 0;
0368 }
0369 
0370 
0371 Kst::DataObjectConfigWidget *EffectiveBandwidthPlugin::configWidget(QSettings *settingsObject) const {
0372   ConfigEffectiveBandwidthPlugin *widget = new ConfigEffectiveBandwidthPlugin(settingsObject);
0373   return widget;
0374 }
0375 
0376 #ifndef QT5
0377 Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, EffectiveBandwidthPlugin)
0378 #endif
0379 
0380 // vim: ts=2 sw=2 et