1 /***************************************************************************
2  *                                                                         *
3  *   copyright : (C) 2007 The University of Toronto                        *
4  *                   netterfield@astro.utoronto.ca                         *
5  *   copyright : (C) 2005  University of British Columbia                  *
6  *                   dscott@phas.ubc.ca                                    *
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  ***************************************************************************/
14 
15 
16 #include "butterworth_highpass.h"
17 #include "objectstore.h"
18 #include "ui_filterbutterworthhighpassconfig.h"
19 
20 #include "../filters.h"
21 
22 static const QString& VECTOR_IN = "Y Vector";
23 static const QString& SCALAR_ORDER_IN = "Order Scalar";
24 static const QString& SCALAR_CUTOFF_IN = "Cutoff / Spacing Scalar";
25 static const QString& VECTOR_OUT = "Y";
26 
27 class ConfigFilterButterworthHighPassPlugin : public Kst::DataObjectConfigWidget, public Ui_FilterButterworthHighPassConfig {
28   public:
ConfigFilterButterworthHighPassPlugin(QSettings * cfg)29     ConfigFilterButterworthHighPassPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FilterButterworthHighPassConfig() {
30       _store = 0;
31       setupUi(this);
32 
33       _scalarCutoff->setIsFOverSR(true);
34     }
35 
~ConfigFilterButterworthHighPassPlugin()36     ~ConfigFilterButterworthHighPassPlugin() {}
37 
setObjectStore(Kst::ObjectStore * store)38     void setObjectStore(Kst::ObjectStore* store) {
39       _store = store;
40       _vector->setObjectStore(store);
41       _scalarOrder->setObjectStore(store);
42       _scalarCutoff->setObjectStore(store);
43       _scalarOrder->setDefaultValue(4);
44       _scalarCutoff->setDefaultValue(0.02);
45     }
46 
setupSlots(QWidget * dialog)47     void setupSlots(QWidget* dialog) {
48       if (dialog) {
49         connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
50         connect(_scalarOrder, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
51         connect(_scalarCutoff, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
52       }
53     }
54 
setVectorX(Kst::VectorPtr vector)55     void setVectorX(Kst::VectorPtr vector) {
56       setSelectedVector(vector);
57     }
58 
setVectorY(Kst::VectorPtr vector)59     void setVectorY(Kst::VectorPtr vector) {
60       setSelectedVector(vector);
61     }
62 
setVectorsLocked(bool locked=true)63     void setVectorsLocked(bool locked = true) {
64       _vector->setEnabled(!locked);
65     }
66 
selectedVector()67     Kst::VectorPtr selectedVector() { return _vector->selectedVector(); };
setSelectedVector(Kst::VectorPtr vector)68     void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); };
69 
selectedOrderScalar()70     Kst::ScalarPtr selectedOrderScalar() { return _scalarOrder->selectedScalar(); };
setSelectedOrderScalar(Kst::ScalarPtr scalar)71     void setSelectedOrderScalar(Kst::ScalarPtr scalar) { return _scalarOrder->setSelectedScalar(scalar); };
72 
selectedCutoffScalar()73     Kst::ScalarPtr selectedCutoffScalar() { return _scalarCutoff->selectedScalar(); };
setSelectedCutoffScalar(Kst::ScalarPtr scalar)74     void setSelectedCutoffScalar(Kst::ScalarPtr scalar) { return _scalarCutoff->setSelectedScalar(scalar); };
75 
setupFromObject(Kst::Object * dataObject)76     virtual void setupFromObject(Kst::Object* dataObject) {
77       if (FilterButterworthHighPassSource* source = static_cast<FilterButterworthHighPassSource*>(dataObject)) {
78         setSelectedVector(source->vector());
79         setSelectedOrderScalar(source->orderScalar());
80         setSelectedCutoffScalar(source->cutoffScalar());
81       }
82     }
83 
configurePropertiesFromXml(Kst::ObjectStore * store,QXmlStreamAttributes & attrs)84     virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) {
85       Q_UNUSED(store);
86       Q_UNUSED(attrs);
87 
88       bool validTag = true;
89 
90 //       QStringRef av;
91 //       av = attrs.value("value");
92 //       if (!av.isNull()) {
93 //         _configValue = QVariant(av.toString()).toBool();
94 //       }
95 
96       return validTag;
97     }
98 
99   public slots:
save()100     virtual void save() {
101       if (_cfg) {
102         _cfg->beginGroup("Filter High Pass Plugin");
103         _cfg->setValue("Input Vector", _vector->selectedVector()->Name());
104         _cfg->setValue("Order Scalar", _scalarOrder->selectedScalar()->Name());
105         _cfg->setValue("Cutoff / Spacing Scalar", _scalarCutoff->selectedScalar()->Name());
106         _cfg->setValue("Sample Rate", _scalarCutoff->SR());
107         _cfg->endGroup();
108       }
109     }
110 
load()111     virtual void load() {
112       if (_cfg && _store) {
113         _cfg->beginGroup("Filter High Pass Plugin");
114         QString vectorName = _cfg->value("Input Vector").toString();
115         Kst::Object* object = _store->retrieveObject(vectorName);
116         Kst::Vector* vector = static_cast<Kst::Vector*>(object);
117         if (vector) {
118           setSelectedVector(vector);
119         }
120         QString scalarName = _cfg->value("Order Scalar").toString();
121         _scalarOrder->setSelectedScalar(scalarName);
122 
123         // set the SR before the cutoff/SampleRate so frequency is updated correctly.
124         _scalarCutoff->setSR(_cfg->value("Sample Rate", "1.0").toString());
125 
126         scalarName = _cfg->value("Cutoff / Spacing Scalar").toString();
127         _scalarCutoff->setSelectedScalar(scalarName);
128 
129         _cfg->endGroup();
130       }
131     }
132 
133   private:
134     Kst::ObjectStore *_store;
135 
136 };
137 
138 
FilterButterworthHighPassSource(Kst::ObjectStore * store)139 FilterButterworthHighPassSource::FilterButterworthHighPassSource(Kst::ObjectStore *store)
140 : Kst::BasicPlugin(store) {
141 }
142 
143 
~FilterButterworthHighPassSource()144 FilterButterworthHighPassSource::~FilterButterworthHighPassSource() {
145 }
146 
147 
_automaticDescriptiveName() const148 QString FilterButterworthHighPassSource::_automaticDescriptiveName() const {
149   return tr("%1 High Pass").arg(vector()->descriptiveName());
150 }
151 
152 
change(Kst::DataObjectConfigWidget * configWidget)153 void FilterButterworthHighPassSource::change(Kst::DataObjectConfigWidget *configWidget) {
154   if (ConfigFilterButterworthHighPassPlugin* config = static_cast<ConfigFilterButterworthHighPassPlugin*>(configWidget)) {
155     setInputVector(VECTOR_IN, config->selectedVector());
156     setInputScalar(SCALAR_ORDER_IN, config->selectedOrderScalar());
157     setInputScalar(SCALAR_CUTOFF_IN, config->selectedCutoffScalar());
158   }
159 }
160 
161 
setupOutputs()162 void FilterButterworthHighPassSource::setupOutputs() {
163   setOutputVector(VECTOR_OUT, "");
164 }
165 
166 
min_pad(Kst::ScalarList scalars)167 int min_pad(Kst::ScalarList scalars) {
168    double hp = scalars.at(1)->value();
169    if (hp >0) {
170      return int (1.0/hp);
171    } else {
172      return 0.0;
173    }
174 }
175 
filter_calculate(double f,Kst::ScalarList scalars)176 double filter_calculate( double f, Kst::ScalarList scalars ) {
177   double gain;
178 
179   if (f > 0.0) {
180     gain = 1.0 / ( 1.0 + pow( scalars.at(1)->value() / f, 2.0 * scalars.at(0)->value() ) );
181   } else {
182     gain = 0.0;
183   }
184 
185   return gain;
186 }
187 
188 
algorithm()189 bool FilterButterworthHighPassSource::algorithm() {
190 
191   Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN];
192   Kst::ScalarPtr orderScalar = _inputScalars[SCALAR_ORDER_IN];
193   Kst::ScalarPtr cutoffScalar = _inputScalars[SCALAR_CUTOFF_IN];
194   Kst::VectorPtr outputVector;
195   // maintain kst file compatibility if the output vector name is changed.
196   if (_outputVectors.contains(VECTOR_OUT)) {
197     outputVector = _outputVectors[VECTOR_OUT];
198   } else {
199     outputVector = _outputVectors.values().at(0);
200   }
201 
202 
203   Kst::ScalarList scalars;
204   scalars.insert(0, orderScalar);
205   scalars.insert(1, cutoffScalar);
206 
207   Kst::LabelInfo label_info = inputVector->labelInfo();
208   label_info.name = tr("Filtered %1").arg(label_info.name);
209   outputVector->setLabelInfo(label_info);
210 
211   return kst_pass_filter( inputVector, scalars, outputVector);
212 }
213 
214 
vector() const215 Kst::VectorPtr FilterButterworthHighPassSource::vector() const {
216   return _inputVectors[VECTOR_IN];
217 }
218 
219 
cutoffScalar() const220 Kst::ScalarPtr FilterButterworthHighPassSource::cutoffScalar() const {
221   return _inputScalars[SCALAR_CUTOFF_IN];
222 }
223 
224 
orderScalar() const225 Kst::ScalarPtr FilterButterworthHighPassSource::orderScalar() const {
226   return _inputScalars[SCALAR_ORDER_IN];
227 }
228 
229 
inputVectorList() const230 QStringList FilterButterworthHighPassSource::inputVectorList() const {
231   return QStringList( VECTOR_IN );
232 }
233 
234 
inputScalarList() const235 QStringList FilterButterworthHighPassSource::inputScalarList() const {
236   QStringList inputScalars( SCALAR_CUTOFF_IN );
237   inputScalars += SCALAR_ORDER_IN;
238   return inputScalars;
239 }
240 
241 
inputStringList() const242 QStringList FilterButterworthHighPassSource::inputStringList() const {
243   return QStringList( /*STRING_IN*/ );
244 }
245 
246 
outputVectorList() const247 QStringList FilterButterworthHighPassSource::outputVectorList() const {
248   return QStringList( VECTOR_OUT );
249 }
250 
251 
outputScalarList() const252 QStringList FilterButterworthHighPassSource::outputScalarList() const {
253   return QStringList( /*SCALAR_OUT*/ );
254 }
255 
256 
outputStringList() const257 QStringList FilterButterworthHighPassSource::outputStringList() const {
258   return QStringList( /*STRING_OUT*/ );
259 }
260 
261 
saveProperties(QXmlStreamWriter & s)262 void FilterButterworthHighPassSource::saveProperties(QXmlStreamWriter &s) {
263   Q_UNUSED(s);
264 //   s.writeAttribute("value", _configValue);
265 }
266 
267 
268 // Name used to identify the plugin.  Used when loading the plugin.
pluginName() const269 QString ButterworthHighPassPlugin::pluginName() const { return tr("High Pass Filter"); }
pluginDescription() const270 QString ButterworthHighPassPlugin::pluginDescription() const { return tr("Filters a vector with a zero phase high pass filter with a butterworth amplitude response."); }
271 
272 
create(Kst::ObjectStore * store,Kst::DataObjectConfigWidget * configWidget,bool setupInputsOutputs) const273 Kst::DataObject *ButterworthHighPassPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const {
274 
275   if (ConfigFilterButterworthHighPassPlugin* config = static_cast<ConfigFilterButterworthHighPassPlugin*>(configWidget)) {
276 
277     FilterButterworthHighPassSource* object = store->createObject<FilterButterworthHighPassSource>();
278 
279     if (setupInputsOutputs) {
280       object->setInputScalar(SCALAR_CUTOFF_IN, config->selectedCutoffScalar());
281       object->setInputScalar(SCALAR_ORDER_IN, config->selectedOrderScalar());
282       object->setupOutputs();
283       object->setInputVector(VECTOR_IN, config->selectedVector());
284     }
285 
286     object->setPluginName(pluginName());
287 
288     object->writeLock();
289     object->registerChange();
290     object->unlock();
291 
292     return object;
293   }
294   return 0;
295 }
296 
297 
configWidget(QSettings * settingsObject) const298 Kst::DataObjectConfigWidget *ButterworthHighPassPlugin::configWidget(QSettings *settingsObject) const {
299   ConfigFilterButterworthHighPassPlugin *widget = new ConfigFilterButterworthHighPassPlugin(settingsObject);
300   return widget;
301 }
302 
303 #ifndef QT5
304 Q_EXPORT_PLUGIN2(kstplugin_ButterworthHighPassPlugin, ButterworthHighPassPlugin)
305 #endif
306 
307 // vim: ts=2 sw=2 et
308