File indexing completed on 2025-01-05 04:12:53
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 "genericfilter.h" 0017 #include "objectstore.h" 0018 #include "ui_genericfilterconfig.h" 0019 0020 #include "polynom.h" 0021 #include "filter.h" 0022 0023 static const QString& VECTOR_IN = "Vector In"; 0024 static const QString& SCALAR_IN = "Scalar In"; 0025 static const QString& STRING_IN_NUMERATOR = "String In Numerator"; 0026 static const QString& STRING_IN_DENOMINATOR = "String In Denominator"; 0027 0028 static const QString& VECTOR_OUT = "Filtered"; 0029 0030 class ConfigGenericFilterPlugin : public Kst::DataObjectConfigWidget, public Ui_GenericFilterConfig { 0031 public: 0032 ConfigGenericFilterPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_GenericFilterConfig() { 0033 _store = 0; 0034 setupUi(this); 0035 } 0036 0037 ~ConfigGenericFilterPlugin() {} 0038 0039 void setObjectStore(Kst::ObjectStore* store) { 0040 _store = store; 0041 _vector->setObjectStore(store); 0042 _scalarInterval->setObjectStore(store); 0043 _stringNumerator->setObjectStore(store); 0044 _stringDenominator->setObjectStore(store); 0045 _scalarInterval->setDefaultValue(0); 0046 } 0047 0048 void setupSlots(QWidget* dialog) { 0049 if (dialog) { 0050 connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); 0051 connect(_scalarInterval, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); 0052 connect(_stringNumerator, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); 0053 connect(_stringDenominator, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); 0054 } 0055 } 0056 0057 Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; 0058 void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; 0059 0060 Kst::ScalarPtr selectedScalar() { return _scalarInterval->selectedScalar(); }; 0061 void setSelectedScalar(Kst::ScalarPtr scalar) { return _scalarInterval->setSelectedScalar(scalar); }; 0062 0063 Kst::StringPtr selectedStringNumerator() { return _stringNumerator->selectedString(); }; 0064 void setSelectedStringNumerator(Kst::StringPtr string) { return _stringNumerator->setSelectedString(string); }; 0065 0066 Kst::StringPtr selectedStringDenominator() { return _stringDenominator->selectedString(); }; 0067 void setSelectedStringDenominator(Kst::StringPtr string) { return _stringDenominator->setSelectedString(string); }; 0068 0069 virtual void setupFromObject(Kst::Object* dataObject) { 0070 if (GenericFilterSource* source = static_cast<GenericFilterSource*>(dataObject)) { 0071 setSelectedVector(source->vector()); 0072 setSelectedScalar(source->scalarInterval()); 0073 setSelectedStringNumerator(source->stringNumerator()); 0074 setSelectedStringDenominator(source->stringDenominator()); 0075 } 0076 } 0077 0078 virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { 0079 Q_UNUSED(store); 0080 Q_UNUSED(attrs); 0081 0082 bool validTag = true; 0083 0084 // QStringRef av; 0085 // av = attrs.value("value"); 0086 // if (!av.isNull()) { 0087 // _configValue = QVariant(av.toString()).toBool(); 0088 // } 0089 0090 return validTag; 0091 } 0092 0093 public slots: 0094 virtual void save() { 0095 if (_cfg) { 0096 _cfg->beginGroup("Generic Filter DataObject Plugin"); 0097 _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); 0098 _cfg->setValue("Input Scalar Interval", _scalarInterval->selectedScalar()->Name()); 0099 if (_stringNumerator->selectedString()) { 0100 _cfg->setValue("Input String Numerator", _stringNumerator->selectedString()->Name()); 0101 } 0102 if (_stringDenominator->selectedString()) { 0103 _cfg->setValue("Input String Denominator", _stringDenominator->selectedString()->Name()); 0104 } 0105 _cfg->endGroup(); 0106 } 0107 } 0108 0109 virtual void load() { 0110 if (_cfg && _store) { 0111 _cfg->beginGroup("Generic Filter DataObject Plugin"); 0112 QString vectorName = _cfg->value("Input Vector").toString(); 0113 Kst::Object* object = _store->retrieveObject(vectorName); 0114 Kst::Vector* vector = static_cast<Kst::Vector*>(object); 0115 if (vector) { 0116 setSelectedVector(vector); 0117 } 0118 QString scalarName = _cfg->value("Input Scalar Interval").toString(); 0119 object = _store->retrieveObject(scalarName); 0120 Kst::Scalar* binScalar = static_cast<Kst::Scalar*>(object); 0121 if (binScalar) { 0122 setSelectedScalar(binScalar); 0123 } 0124 QString stringName = _cfg->value("Input String Numerator").toString(); 0125 object = _store->retrieveObject(stringName); 0126 Kst::String* stringNum = static_cast<Kst::String*>(object); 0127 if (stringNum) { 0128 setSelectedStringNumerator(stringNum); 0129 } 0130 stringName = _cfg->value("Input String Denominator").toString(); 0131 object = _store->retrieveObject(stringName); 0132 Kst::String* stringDenom = static_cast<Kst::String*>(object); 0133 if (stringDenom) { 0134 setSelectedStringDenominator(stringDenom); 0135 } 0136 _cfg->endGroup(); 0137 } 0138 } 0139 0140 private: 0141 Kst::ObjectStore *_store; 0142 0143 }; 0144 0145 0146 GenericFilterSource::GenericFilterSource(Kst::ObjectStore *store) 0147 : Kst::BasicPlugin(store) { 0148 } 0149 0150 0151 GenericFilterSource::~GenericFilterSource() { 0152 } 0153 0154 0155 QString GenericFilterSource::_automaticDescriptiveName() const { 0156 return tr("Generic Filter Plugin Object"); 0157 } 0158 0159 0160 void GenericFilterSource::change(Kst::DataObjectConfigWidget *configWidget) { 0161 if (ConfigGenericFilterPlugin* config = static_cast<ConfigGenericFilterPlugin*>(configWidget)) { 0162 setInputVector(VECTOR_IN, config->selectedVector()); 0163 setInputScalar(SCALAR_IN, config->selectedScalar()); 0164 setInputString(STRING_IN_NUMERATOR, config->selectedStringNumerator()); 0165 setInputString(STRING_IN_DENOMINATOR, config->selectedStringDenominator()); 0166 } 0167 } 0168 0169 0170 void GenericFilterSource::setupOutputs() { 0171 setOutputVector(VECTOR_OUT, ""); 0172 } 0173 0174 0175 bool GenericFilterSource::algorithm() { 0176 Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; 0177 Kst::ScalarPtr inputScalar = _inputScalars[SCALAR_IN]; 0178 Kst::StringPtr inputStringNumerator = _inputStrings[STRING_IN_NUMERATOR]; 0179 Kst::StringPtr inputStringDenominator = _inputStrings[STRING_IN_DENOMINATOR]; 0180 Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT]; 0181 0182 //Validate the Numerator. 0183 if (!inputStringNumerator || inputStringNumerator->value().isEmpty()) { 0184 _errorString = tr("Error: Input String Numerator is Empty"); 0185 return false; 0186 } 0187 0188 //Validate the Denominator. 0189 if (!inputStringDenominator || inputStringDenominator->value().isEmpty()) { 0190 _errorString = tr("Error: Input String Denominator is Empty"); 0191 return false; 0192 } 0193 0194 int length = inputVector->length(); 0195 0196 // Extract polynom coefficients and instantiate polynoms 0197 QStringList numCoeffs = inputStringNumerator->value().split(QRegExp("\\s*(,|;|:)\\s*")); 0198 QStringList denCoeffs = inputStringDenominator->value().split(QRegExp("\\s*(,|;|:)\\s*")); 0199 int numDegree = numCoeffs.count() - 1, denDegree = denCoeffs.count() - 1; 0200 polynom<double> Num(numDegree), Den(denDegree); 0201 double tmpDouble = 0.0; 0202 bool ok = false; 0203 for (int i=0; i<=numDegree; i++) { 0204 tmpDouble = numCoeffs[i].toDouble(&ok); 0205 if (ok) Num[i]= tmpDouble; 0206 else Num[i] = 0.0; 0207 } 0208 for (int i=0; i<=denDegree; i++) { 0209 tmpDouble = denCoeffs[i].toDouble(&ok); 0210 if (ok) Den[i] = tmpDouble; 0211 else Den[i] = 0.0; 0212 } 0213 0214 // Time step 0215 double DeltaT = inputScalar->value(); 0216 0217 // Allocate storage for output vectors 0218 outputVector->resize(length, true); 0219 0220 // Create filter 0221 filter<double> theFilter(Num,Den,DeltaT); 0222 double in = 0.0; 0223 theFilter.ConnectTo(in); // the filter keeps a pointer to "in" 0224 theFilter.Reset(); 0225 0226 double const *v_in = inputVector->noNanValue(); 0227 double *v_out = outputVector->raw_V_ptr(); 0228 for (int i=0; i<length; i++) { 0229 in = v_in[i]; 0230 theFilter.NextTimeStep(); 0231 v_out[i] = theFilter.out; 0232 } 0233 0234 return true; 0235 } 0236 0237 0238 Kst::VectorPtr GenericFilterSource::vector() const { 0239 return _inputVectors[VECTOR_IN]; 0240 } 0241 0242 0243 Kst::ScalarPtr GenericFilterSource::scalarInterval() const { 0244 return _inputScalars[SCALAR_IN]; 0245 } 0246 0247 0248 Kst::StringPtr GenericFilterSource::stringNumerator() const { 0249 return _inputStrings[STRING_IN_NUMERATOR]; 0250 } 0251 0252 0253 Kst::StringPtr GenericFilterSource::stringDenominator() const { 0254 return _inputStrings[STRING_IN_DENOMINATOR]; 0255 } 0256 0257 0258 QStringList GenericFilterSource::inputVectorList() const { 0259 return QStringList( VECTOR_IN ); 0260 } 0261 0262 0263 QStringList GenericFilterSource::inputScalarList() const { 0264 return QStringList( SCALAR_IN ); 0265 } 0266 0267 0268 QStringList GenericFilterSource::inputStringList() const { 0269 QStringList strings(STRING_IN_NUMERATOR); 0270 strings += STRING_IN_DENOMINATOR; 0271 return strings; 0272 } 0273 0274 0275 QStringList GenericFilterSource::outputVectorList() const { 0276 return QStringList( VECTOR_OUT ); 0277 } 0278 0279 0280 QStringList GenericFilterSource::outputScalarList() const { 0281 return QStringList( /*SCALAR_OUT*/ ); 0282 } 0283 0284 0285 QStringList GenericFilterSource::outputStringList() const { 0286 return QStringList( /*STRING_OUT*/ ); 0287 } 0288 0289 0290 void GenericFilterSource::saveProperties(QXmlStreamWriter &s) { 0291 Q_UNUSED(s); 0292 // s.writeAttribute("value", _configValue); 0293 } 0294 0295 0296 QString GenericFilterPlugin::pluginName() const { return tr("Generic Filter"); } 0297 QString GenericFilterPlugin::pluginDescription() const { return tr("Generates a discrete filter from a continuous-time definition."); } 0298 0299 0300 Kst::DataObject *GenericFilterPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { 0301 0302 if (ConfigGenericFilterPlugin* config = static_cast<ConfigGenericFilterPlugin*>(configWidget)) { 0303 0304 GenericFilterSource* object = store->createObject<GenericFilterSource>(); 0305 0306 if (setupInputsOutputs) { 0307 object->setInputScalar(SCALAR_IN, config->selectedScalar()); 0308 object->setInputString(STRING_IN_NUMERATOR, config->selectedStringNumerator()); 0309 object->setInputString(STRING_IN_DENOMINATOR, config->selectedStringDenominator()); 0310 object->setupOutputs(); 0311 object->setInputVector(VECTOR_IN, config->selectedVector()); 0312 } 0313 0314 object->setPluginName(pluginName()); 0315 0316 object->writeLock(); 0317 object->registerChange(); 0318 object->unlock(); 0319 0320 return object; 0321 } 0322 return 0; 0323 } 0324 0325 0326 Kst::DataObjectConfigWidget *GenericFilterPlugin::configWidget(QSettings *settingsObject) const { 0327 ConfigGenericFilterPlugin *widget = new ConfigGenericFilterPlugin(settingsObject); 0328 return widget; 0329 } 0330 0331 #ifndef QT5 0332 Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, GenericFilterPlugin) 0333 #endif 0334 0335 // vim: ts=2 sw=2 et