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