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