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