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

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 "fitlinear_weighted.h"
0017 #include "objectstore.h"
0018 #include "ui_fitlinear_weightedconfig.h"
0019 
0020 #include <gsl/gsl_fit.h>
0021 #include "../common.h"
0022 
0023 static const QString& VECTOR_IN_X = "X Vector";
0024 static const QString& VECTOR_IN_Y = "Y Vector";
0025 static const QString& VECTOR_IN_WEIGHTS = "Weights Vector";
0026 static const QString& VECTOR_OUT_Y_FITTED = "Fit";
0027 static const QString& VECTOR_OUT_Y_RESIDUALS = "Residuals";
0028 static const QString& VECTOR_OUT_Y_PARAMETERS = "Parameters Vector";
0029 static const QString& VECTOR_OUT_Y_COVARIANCE = "Covariance";
0030 static const QString& VECTOR_OUT_Y_LO = "Lo Vector";
0031 static const QString& VECTOR_OUT_Y_HI = "Hi Vector";
0032 static const QString& SCALAR_OUT = "chi^2/nu";
0033 
0034 class ConfigWidgetFitLinearWeightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitLinear_WeightedConfig {
0035   public:
0036     ConfigWidgetFitLinearWeightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitLinear_WeightedConfig() {
0037       _store = 0;
0038       setupUi(this);
0039     }
0040 
0041     ~ConfigWidgetFitLinearWeightedPlugin() {}
0042 
0043     void setObjectStore(Kst::ObjectStore* store) { 
0044       _store = store; 
0045       _vectorX->setObjectStore(store);
0046       _vectorY->setObjectStore(store);
0047       _vectorWeights->setObjectStore(store);
0048     }
0049 
0050     void setupSlots(QWidget* dialog) {
0051       if (dialog) {
0052         connect(_vectorX, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
0053         connect(_vectorY, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
0054         connect(_vectorWeights, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
0055       }
0056     }
0057 
0058 
0059     void setVectorX(Kst::VectorPtr vector) {
0060       setSelectedVectorX(vector);
0061     }
0062 
0063     void setVectorY(Kst::VectorPtr vector) {
0064       setSelectedVectorY(vector);
0065     }
0066 
0067     void setVectorsLocked(bool locked = true) {
0068       _vectorX->setEnabled(!locked);
0069       _vectorY->setEnabled(!locked);
0070     }
0071 
0072     Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); };
0073     void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); };
0074 
0075     Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); };
0076     void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); };
0077 
0078     Kst::VectorPtr selectedVectorWeights() { return _vectorWeights->selectedVector(); };
0079     void setSelectedVectorWeights(Kst::VectorPtr vector) { return _vectorWeights->setSelectedVector(vector); };
0080 
0081     virtual void setupFromObject(Kst::Object* dataObject) {
0082       if (FitLinearWeightedSource* source = static_cast<FitLinearWeightedSource*>(dataObject)) {
0083         setSelectedVectorX(source->vectorX());
0084         setSelectedVectorY(source->vectorY());
0085         setSelectedVectorWeights(source->vectorWeights());
0086       }
0087     }
0088 
0089     virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) {
0090       Q_UNUSED(store);
0091       Q_UNUSED(attrs);
0092 
0093       bool validTag = true;
0094 
0095 //       QStringRef av;
0096 //       av = attrs.value("value");
0097 //       if (!av.isNull()) {
0098 //         _configValue = QVariant(av.toString()).toBool();
0099 //       }
0100 
0101       return validTag;
0102     }
0103 
0104   public slots:
0105     virtual void save() {
0106       if (_cfg) {
0107         _cfg->beginGroup("Fit Linear Weighted Plugin");
0108         _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name());
0109         _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name());
0110         _cfg->setValue("Input Vector Weights", _vectorWeights->selectedVector()->Name());
0111         _cfg->endGroup();
0112       }
0113     }
0114 
0115     virtual void load() {
0116       if (_cfg && _store) {
0117         _cfg->beginGroup("Fit Linear Weighted 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           setSelectedVectorX(vectory);
0129         }
0130         vectorName = _cfg->value("Input Vector Weights").toString();
0131         object = _store->retrieveObject(vectorName);
0132         Kst::Vector* vectorweights = static_cast<Kst::Vector*>(object);
0133         if (vectorweights) {
0134           setSelectedVectorX(vectorweights);
0135         }
0136         _cfg->endGroup();
0137       }
0138     }
0139 
0140   private:
0141     Kst::ObjectStore *_store;
0142 
0143 };
0144 
0145 
0146 FitLinearWeightedSource::FitLinearWeightedSource(Kst::ObjectStore *store)
0147 : Kst::BasicPlugin(store) {
0148 }
0149 
0150 
0151 FitLinearWeightedSource::~FitLinearWeightedSource() {
0152 }
0153 
0154 
0155 QString FitLinearWeightedSource::_automaticDescriptiveName() const {
0156   return tr("%1 Weighted Linear").arg(vectorY()->descriptiveName());
0157 }
0158 
0159 
0160 void FitLinearWeightedSource::change(Kst::DataObjectConfigWidget *configWidget) {
0161   if (ConfigWidgetFitLinearWeightedPlugin* config = static_cast<ConfigWidgetFitLinearWeightedPlugin*>(configWidget)) {
0162     setInputVector(VECTOR_IN_X, config->selectedVectorX());
0163     setInputVector(VECTOR_IN_Y, config->selectedVectorY());
0164     setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights());
0165   }
0166 }
0167 
0168 
0169 void FitLinearWeightedSource::setupOutputs() {
0170   setOutputVector(VECTOR_OUT_Y_FITTED, "");
0171   setOutputVector(VECTOR_OUT_Y_RESIDUALS, "");
0172   setOutputVector(VECTOR_OUT_Y_PARAMETERS, "");
0173   setOutputVector(VECTOR_OUT_Y_COVARIANCE, "");
0174   setOutputVector(VECTOR_OUT_Y_LO, "");
0175   setOutputVector(VECTOR_OUT_Y_HI, "");
0176   setOutputScalar(SCALAR_OUT, "");
0177 }
0178 
0179 
0180 bool FitLinearWeightedSource::algorithm() {
0181   Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X];
0182   Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y];
0183   Kst::VectorPtr inputVectorWeights = _inputVectors[VECTOR_IN_WEIGHTS];
0184 
0185   Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED];
0186   Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS];
0187   Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS];
0188   Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE];
0189   Kst::VectorPtr outputVectorYLo = _outputVectors[VECTOR_OUT_Y_LO];
0190   Kst::VectorPtr outputVectorYHi = _outputVectors[VECTOR_OUT_Y_HI];
0191   Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT];
0192 
0193   Kst::LabelInfo label_info = inputVectorY->labelInfo();
0194   label_info.name = tr("Linear Fit to %1").arg(label_info.name);
0195   outputVectorYFitted->setLabelInfo(label_info);
0196 
0197   label_info.name = tr("Linear Fit Residuals");
0198   outputVectorYResiduals->setLabelInfo(label_info);
0199 
0200   label_info.name = tr("Linear Fit Lower Limit");
0201   outputVectorYLo->setLabelInfo(label_info);
0202 
0203   label_info.name = tr("Linear Fit Upper Limit");
0204   outputVectorYHi->setLabelInfo(label_info);
0205 
0206   int i = 0;
0207   int iLength = 0;
0208   bool bReturn = false;
0209   double* pInputs[3];
0210   double c0 = 0.0;
0211   double c1 = 0.0;
0212   double cov00 = 0.0;
0213   double cov01 = 0.0;
0214   double cov11 = 0.0;
0215   double dSumSq = 0.0;
0216   double y;
0217   double yErr;
0218 
0219   if( precursor( inputVectorX, inputVectorY, inputVectorWeights, &iLength, true, true, 2, pInputs, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputVectorYLo, outputVectorYHi ) ) {
0220 
0221     if( !gsl_fit_wlinear( pInputs[XVALUES], 1, pInputs[WEIGHTS], 1, pInputs[YVALUES], 1, iLength, &c0, &c1, &cov00, &cov01, &cov11, &dSumSq ) ) {
0222       for( i=0; i<iLength; ++i ) {
0223         gsl_fit_linear_est( pInputs[XVALUES][i], c0, c1, cov00, cov01, cov11, &y, &yErr );
0224         outputVectorYFitted->raw_V_ptr()[i] = y;
0225         outputVectorYResiduals->raw_V_ptr()[i] = pInputs[YVALUES][i] - y;
0226         outputVectorYLo->raw_V_ptr()[i] = y - yErr;
0227         outputVectorYHi->raw_V_ptr()[i] = y + yErr;
0228       }
0229 
0230       outputVectorYParameters->raw_V_ptr()[0] = c0;
0231       outputVectorYParameters->raw_V_ptr()[1] = c1;
0232       outputVectorYCovariance->raw_V_ptr()[0] = cov00;
0233       outputVectorYCovariance->raw_V_ptr()[1] = cov01;
0234       outputVectorYCovariance->raw_V_ptr()[2] = cov11;
0235 
0236       outputScalar->setValue(dSumSq / ( (double)iLength - 2.0 ));
0237       bReturn = true;
0238     }
0239   }
0240 
0241   postcursor( true, pInputs );
0242 
0243   return bReturn;
0244 }
0245 
0246 
0247 Kst::VectorPtr FitLinearWeightedSource::vectorX() const {
0248   return _inputVectors[VECTOR_IN_X];
0249 }
0250 
0251 
0252 Kst::VectorPtr FitLinearWeightedSource::vectorY() const {
0253   return _inputVectors[VECTOR_IN_Y];
0254 }
0255 
0256 
0257 Kst::VectorPtr FitLinearWeightedSource::vectorWeights() const {
0258   return _inputVectors[VECTOR_IN_WEIGHTS];
0259 }
0260 
0261 
0262 QStringList FitLinearWeightedSource::inputVectorList() const {
0263   QStringList vectors(VECTOR_IN_X);
0264   vectors += VECTOR_IN_Y;
0265   vectors += VECTOR_IN_WEIGHTS;
0266   return vectors;
0267 }
0268 
0269 
0270 QStringList FitLinearWeightedSource::inputScalarList() const {
0271   return QStringList();
0272 }
0273 
0274 
0275 QStringList FitLinearWeightedSource::inputStringList() const {
0276   return QStringList( /*STRING_IN*/ );
0277 }
0278 
0279 
0280 QStringList FitLinearWeightedSource::outputVectorList() const {
0281   QStringList vectors(VECTOR_OUT_Y_FITTED);
0282   vectors += VECTOR_OUT_Y_RESIDUALS;
0283   vectors += VECTOR_OUT_Y_PARAMETERS;
0284   vectors += VECTOR_OUT_Y_COVARIANCE;
0285   vectors += VECTOR_OUT_Y_LO;
0286   vectors += VECTOR_OUT_Y_HI;
0287   vectors += VECTOR_OUT_Y_PARAMETERS;
0288   return vectors;
0289 }
0290 
0291 
0292 QStringList FitLinearWeightedSource::outputScalarList() const {
0293   return QStringList( SCALAR_OUT );
0294 }
0295 
0296 
0297 QStringList FitLinearWeightedSource::outputStringList() const {
0298   return QStringList( /*STRING_OUT*/ );
0299 }
0300 
0301 
0302 void FitLinearWeightedSource::saveProperties(QXmlStreamWriter &s) {
0303   Q_UNUSED(s);
0304 //   s.writeAttribute("value", _configValue);
0305 }
0306 
0307 
0308 QString FitLinearWeightedSource::parameterName(int index) const {
0309   QString parameter;
0310   switch (index) {
0311     case 0:
0312       parameter = "Intercept";
0313       break;
0314     case 1:
0315       parameter = "Gradient";
0316       break;
0317   }
0318 
0319   return parameter;
0320 }
0321 
0322 
0323 // Name used to identify the plugin.  Used when loading the plugin.
0324 QString FitLinearWeightedPlugin::pluginName() const { return tr("Linear Weighted Fit"); }
0325 QString FitLinearWeightedPlugin::pluginDescription() const { return tr("Generates a linear weighted fit for a set of data."); }
0326 
0327 
0328 Kst::DataObject *FitLinearWeightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const {
0329 
0330   if (ConfigWidgetFitLinearWeightedPlugin* config = static_cast<ConfigWidgetFitLinearWeightedPlugin*>(configWidget)) {
0331 
0332     FitLinearWeightedSource* object = store->createObject<FitLinearWeightedSource>();
0333 
0334     if (setupInputsOutputs) {
0335       object->setupOutputs();
0336       object->setInputVector(VECTOR_IN_X, config->selectedVectorX());
0337       object->setInputVector(VECTOR_IN_Y, config->selectedVectorY());
0338       object->setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights());
0339     }
0340 
0341     object->setPluginName(pluginName());
0342 
0343     object->writeLock();
0344     object->registerChange();
0345     object->unlock();
0346 
0347     return object;
0348   }
0349   return 0;
0350 }
0351 
0352 
0353 Kst::DataObjectConfigWidget *FitLinearWeightedPlugin::configWidget(QSettings *settingsObject) const {
0354   ConfigWidgetFitLinearWeightedPlugin *widget = new ConfigWidgetFitLinearWeightedPlugin(settingsObject);
0355   return widget;
0356 }
0357 
0358 #ifndef QT5
0359 Q_EXPORT_PLUGIN2(kstplugin_FitLinearWeightedPlugin, FitLinearWeightedPlugin)
0360 #endif
0361 
0362 // vim: ts=2 sw=2 et