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 "fitgradient_unweighted.h"
17 #include "objectstore.h"
18 #include "ui_fitgradient_unweightedconfig.h"
19 
20 #include <gsl/gsl_fit.h>
21 #include "../common.h"
22 
23 static const QString& VECTOR_IN_X = "X Vector";
24 static const QString& VECTOR_IN_Y = "Y Vector";
25 static const QString& VECTOR_OUT_Y_FITTED = "Fit";
26 static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals";
27 static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector";
28 static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance";
29 static const QString& VECTOR_OUT_Y_LO = "Lo Vector";
30 static const QString& VECTOR_OUT_Y_HI = "Hi Vector";
31 static const QString& SCALAR_OUT = "chi^2/nu";
32 
33 class ConfigWidgetFitGradientUnweightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitGradient_UnweightedConfig {
34   public:
ConfigWidgetFitGradientUnweightedPlugin(QSettings * cfg)35     ConfigWidgetFitGradientUnweightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitGradient_UnweightedConfig() {
36       _store = 0;
37       setupUi(this);
38     }
39 
~ConfigWidgetFitGradientUnweightedPlugin()40     ~ConfigWidgetFitGradientUnweightedPlugin() {}
41 
setObjectStore(Kst::ObjectStore * store)42     void setObjectStore(Kst::ObjectStore* store) {
43       _store = store;
44       _vectorX->setObjectStore(store);
45       _vectorY->setObjectStore(store);
46     }
47 
setupSlots(QWidget * dialog)48     void setupSlots(QWidget* dialog) {
49       if (dialog) {
50         connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
51         connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
52       }
53     }
54 
setVectorX(Kst::VectorPtr vector)55     void setVectorX(Kst::VectorPtr vector) {
56       setSelectedVectorX(vector);
57     }
58 
setVectorY(Kst::VectorPtr vector)59     void setVectorY(Kst::VectorPtr vector) {
60       setSelectedVectorY(vector);
61     }
62 
setVectorsLocked(bool locked=true)63     void setVectorsLocked(bool locked = true) {
64       _vectorX->setEnabled(!locked);
65       _vectorY->setEnabled(!locked);
66     }
67 
selectedVectorX()68     Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); };
setSelectedVectorX(Kst::VectorPtr vector)69     void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); };
70 
selectedVectorY()71     Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); };
setSelectedVectorY(Kst::VectorPtr vector)72     void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); };
73 
setupFromObject(Kst::Object * dataObject)74     virtual void setupFromObject(Kst::Object* dataObject) {
75       if (FitGradientUnweightedSource* source = static_cast<FitGradientUnweightedSource*>(dataObject)) {
76         setSelectedVectorX(source->vectorX());
77         setSelectedVectorY(source->vectorY());
78       }
79     }
80 
configurePropertiesFromXml(Kst::ObjectStore * store,QXmlStreamAttributes & attrs)81     virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) {
82       Q_UNUSED(store);
83       Q_UNUSED(attrs);
84 
85       bool validTag = true;
86 
87 //       QStringRef av;
88 //       av = attrs.value("value");
89 //       if (!av.isNull()) {
90 //         _configValue = QVariant(av.toString()).toBool();
91 //       }
92 
93       return validTag;
94     }
95 
96   public slots:
save()97     virtual void save() {
98       if (_cfg) {
99         _cfg->beginGroup("Fit Gradient Plugin");
100         _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name());
101         _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name());
102         _cfg->endGroup();
103       }
104     }
105 
load()106     virtual void load() {
107       if (_cfg && _store) {
108         _cfg->beginGroup("Fit Gradient Plugin");
109         QString vectorName = _cfg->value("Input Vector X").toString();
110         Kst::Object* object = _store->retrieveObject(vectorName);
111         Kst::Vector* vectorx = static_cast<Kst::Vector*>(object);
112         if (vectorx) {
113           setSelectedVectorX(vectorx);
114         }
115         vectorName = _cfg->value("Input Vector Y").toString();
116         object = _store->retrieveObject(vectorName);
117         Kst::Vector* vectory = static_cast<Kst::Vector*>(object);
118         if (vectory) {
119           setSelectedVectorX(vectory);
120         }
121         _cfg->endGroup();
122       }
123     }
124 
125   private:
126     Kst::ObjectStore *_store;
127 
128 };
129 
130 
FitGradientUnweightedSource(Kst::ObjectStore * store)131 FitGradientUnweightedSource::FitGradientUnweightedSource(Kst::ObjectStore *store)
132 : Kst::BasicPlugin(store) {
133 }
134 
135 
~FitGradientUnweightedSource()136 FitGradientUnweightedSource::~FitGradientUnweightedSource() {
137 }
138 
139 
_automaticDescriptiveName() const140 QString FitGradientUnweightedSource::_automaticDescriptiveName() const {
141     return tr("%1 Unweighted Gradient").arg(vectorY()->descriptiveName());
142 }
143 
144 
change(Kst::DataObjectConfigWidget * configWidget)145 void FitGradientUnweightedSource::change(Kst::DataObjectConfigWidget *configWidget) {
146   if (ConfigWidgetFitGradientUnweightedPlugin* config = static_cast<ConfigWidgetFitGradientUnweightedPlugin*>(configWidget)) {
147     setInputVector(VECTOR_IN_X, config->selectedVectorX());
148     setInputVector(VECTOR_IN_Y, config->selectedVectorY());
149   }
150 }
151 
152 
setupOutputs()153 void FitGradientUnweightedSource::setupOutputs() {
154   setOutputVector(VECTOR_OUT_Y_FITTED, "");
155   setOutputVector(VECTOR_OUT_Y_RESIDUALS, "");
156   setOutputVector(VECTOR_OUT_Y_PARAMETERS, "");
157   setOutputVector(VECTOR_OUT_Y_COVARIANCE, "");
158   setOutputVector(VECTOR_OUT_Y_LO, "");
159   setOutputVector(VECTOR_OUT_Y_HI, "");
160   setOutputScalar(SCALAR_OUT, "");
161 }
162 
163 
algorithm()164 bool FitGradientUnweightedSource::algorithm() {
165   Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X];
166   Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y];
167 
168   Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED];
169   Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS];
170   Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS];
171   Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE];
172   Kst::VectorPtr outputVectorYLo = _outputVectors[VECTOR_OUT_Y_LO];
173   Kst::VectorPtr outputVectorYHi = _outputVectors[VECTOR_OUT_Y_HI];
174   Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT];
175 
176 
177   Kst::LabelInfo label_info = inputVectorY->labelInfo();
178   label_info.name = tr("Gradient Fit to %1").arg(label_info.name);
179   outputVectorYFitted->setLabelInfo(label_info);
180 
181   label_info.name = tr("Gradient Fit Residuals");
182   outputVectorYResiduals->setLabelInfo(label_info);
183 
184   label_info.name = tr("Gradient Fit Lower Limit");
185   outputVectorYLo->setLabelInfo(label_info);
186 
187   label_info.name = tr("Gradient Fit Upper Limit");
188   outputVectorYHi->setLabelInfo(label_info);
189 
190   int i = 0;
191   int iLength = 0;
192   bool bReturn = false;
193   double* pInputs[3];
194   double c0 = 0.0;
195   double cov00 = 0.0;
196   double dSumSq = 0.0;
197   double y;
198   double yErr;
199 
200   if( precursor( inputVectorX, inputVectorY, 0, &iLength, false, true, 2, pInputs, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputVectorYLo, outputVectorYHi ) ) {
201 
202     if( !gsl_fit_mul( pInputs[XVALUES], 1, pInputs[YVALUES], 1, iLength, &c0, &cov00, &dSumSq ) ) {
203       for( i=0; i<iLength; ++i ) {
204         gsl_fit_mul_est( pInputs[XVALUES][i], c0, cov00, &y, &yErr );
205 
206         outputVectorYFitted->raw_V_ptr()[i] = y;
207         outputVectorYResiduals->raw_V_ptr()[i] = pInputs[YVALUES][i] - y;
208         outputVectorYLo->raw_V_ptr()[i] = y - yErr;
209         outputVectorYHi->raw_V_ptr()[i] = y + yErr;
210       }
211 
212       outputVectorYParameters->raw_V_ptr()[0] = c0;
213       outputVectorYCovariance->raw_V_ptr()[0] = cov00;
214 
215       outputScalar->setValue(dSumSq / ( (double)iLength - 2.0 ));
216 
217       bReturn = true;
218     }
219   }
220 
221   postcursor( false, pInputs );
222 
223   return bReturn;
224 }
225 
226 
vectorX() const227 Kst::VectorPtr FitGradientUnweightedSource::vectorX() const {
228   return _inputVectors[VECTOR_IN_X];
229 }
230 
231 
vectorY() const232 Kst::VectorPtr FitGradientUnweightedSource::vectorY() const {
233   return _inputVectors[VECTOR_IN_Y];
234 }
235 
236 
inputVectorList() const237 QStringList FitGradientUnweightedSource::inputVectorList() const {
238   QStringList vectors(VECTOR_IN_X);
239   vectors += VECTOR_IN_Y;
240   return vectors;
241 }
242 
243 
inputScalarList() const244 QStringList FitGradientUnweightedSource::inputScalarList() const {
245   return QStringList();
246 }
247 
248 
inputStringList() const249 QStringList FitGradientUnweightedSource::inputStringList() const {
250   return QStringList( /*STRING_IN*/ );
251 }
252 
253 
outputVectorList() const254 QStringList FitGradientUnweightedSource::outputVectorList() const {
255   QStringList vectors(VECTOR_OUT_Y_FITTED);
256   vectors += VECTOR_OUT_Y_RESIDUALS;
257   vectors += VECTOR_OUT_Y_PARAMETERS;
258   vectors += VECTOR_OUT_Y_COVARIANCE;
259   vectors += VECTOR_OUT_Y_LO;
260   vectors += VECTOR_OUT_Y_HI;
261   vectors += VECTOR_OUT_Y_PARAMETERS;
262   return vectors;
263 }
264 
265 
outputScalarList() const266 QStringList FitGradientUnweightedSource::outputScalarList() const {
267   return QStringList( SCALAR_OUT );
268 }
269 
270 
outputStringList() const271 QStringList FitGradientUnweightedSource::outputStringList() const {
272   return QStringList( /*STRING_OUT*/ );
273 }
274 
275 
saveProperties(QXmlStreamWriter & s)276 void FitGradientUnweightedSource::saveProperties(QXmlStreamWriter &s) {
277   Q_UNUSED(s);
278 //   s.writeAttribute("value", _configValue);
279 }
280 
281 
parameterName(int index) const282 QString FitGradientUnweightedSource::parameterName(int index) const {
283   QString parameter;
284   switch (index) {
285     case 0:
286       parameter = "Gradient";
287       break;
288   }
289 
290   return parameter;
291 }
292 
293 
294 // Name used to identify the plugin.  Used when loading the plugin.
pluginName() const295 QString FitGradientUnweightedPlugin::pluginName() const { return tr("Gradient Fit"); }
pluginDescription() const296 QString FitGradientUnweightedPlugin::pluginDescription() const { return tr("Generates a gradient fit for a set of data."); }
297 
298 
create(Kst::ObjectStore * store,Kst::DataObjectConfigWidget * configWidget,bool setupInputsOutputs) const299 Kst::DataObject *FitGradientUnweightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const {
300 
301   if (ConfigWidgetFitGradientUnweightedPlugin* config = static_cast<ConfigWidgetFitGradientUnweightedPlugin*>(configWidget)) {
302 
303     FitGradientUnweightedSource* object = store->createObject<FitGradientUnweightedSource>();
304 
305     if (setupInputsOutputs) {
306       object->setupOutputs();
307       object->setInputVector(VECTOR_IN_X, config->selectedVectorX());
308       object->setInputVector(VECTOR_IN_Y, config->selectedVectorY());
309     }
310 
311     object->setPluginName(pluginName());
312 
313     object->writeLock();
314     object->registerChange();
315     object->unlock();
316 
317     return object;
318   }
319   return 0;
320 }
321 
322 
configWidget(QSettings * settingsObject) const323 Kst::DataObjectConfigWidget *FitGradientUnweightedPlugin::configWidget(QSettings *settingsObject) const {
324   ConfigWidgetFitGradientUnweightedPlugin *widget = new ConfigWidgetFitGradientUnweightedPlugin(settingsObject);
325   return widget;
326 }
327 
328 #ifndef QT5
329 Q_EXPORT_PLUGIN2(kstplugin_FitGradientUnweightedPlugin, FitGradientUnweightedPlugin)
330 #endif
331 
332 // vim: ts=2 sw=2 et
333