File indexing completed on 2024-12-22 04:18:12
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 "fitgradient_weighted.h" 0017 #include "objectstore.h" 0018 #include "ui_fitgradient_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 ConfigWidgetFitGradientWeightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitGradient_WeightedConfig { 0035 public: 0036 ConfigWidgetFitGradientWeightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitGradient_WeightedConfig() { 0037 _store = 0; 0038 setupUi(this); 0039 } 0040 0041 ~ConfigWidgetFitGradientWeightedPlugin() {} 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 (FitGradientWeightedSource* source = static_cast<FitGradientWeightedSource*>(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 Gradient 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 Gradient 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 FitGradientWeightedSource::FitGradientWeightedSource(Kst::ObjectStore *store) 0147 : Kst::BasicPlugin(store) { 0148 } 0149 0150 0151 FitGradientWeightedSource::~FitGradientWeightedSource() { 0152 } 0153 0154 0155 QString FitGradientWeightedSource::_automaticDescriptiveName() const { 0156 return tr("%1 Weighted Gradient").arg(vectorY()->descriptiveName()); 0157 } 0158 0159 0160 void FitGradientWeightedSource::change(Kst::DataObjectConfigWidget *configWidget) { 0161 if (ConfigWidgetFitGradientWeightedPlugin* config = static_cast<ConfigWidgetFitGradientWeightedPlugin*>(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 FitGradientWeightedSource::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 FitGradientWeightedSource::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("Gradient Fit to %1").arg(label_info.name); 0195 outputVectorYFitted->setLabelInfo(label_info); 0196 0197 label_info.name = tr("Gradient Fit Residuals"); 0198 outputVectorYResiduals->setLabelInfo(label_info); 0199 0200 label_info.name = tr("Gradient Fit Lower Limit"); 0201 outputVectorYLo->setLabelInfo(label_info); 0202 0203 label_info.name = tr("Gradient Fit Upper Limit"); 0204 outputVectorYHi->setLabelInfo(label_info); 0205 0206 0207 int i = 0; 0208 int iLength = 0; 0209 bool bReturn = false; 0210 double* pInputs[3]; 0211 double c0 = 0.0; 0212 double cov00 = 0.0; 0213 double dSumSq = 0.0; 0214 double y; 0215 double yErr; 0216 0217 if( precursor( inputVectorX, inputVectorY, inputVectorWeights, &iLength, true, true, 2, pInputs, outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, outputVectorYCovariance, outputVectorYLo, outputVectorYHi ) ) { 0218 0219 if( !gsl_fit_wmul( pInputs[XVALUES], 1, pInputs[WEIGHTS], 1, pInputs[YVALUES], 1, iLength, &c0, &cov00, &dSumSq ) ) { 0220 for( i=0; i<iLength; ++i ) { 0221 gsl_fit_mul_est( pInputs[XVALUES][i], c0, cov00, &y, &yErr ); 0222 0223 outputVectorYFitted->raw_V_ptr()[i] = y; 0224 outputVectorYResiduals->raw_V_ptr()[i] = pInputs[YVALUES][i] - y; 0225 outputVectorYLo->raw_V_ptr()[i] = y - yErr; 0226 outputVectorYHi->raw_V_ptr()[i] = y + yErr; 0227 } 0228 0229 outputVectorYParameters->raw_V_ptr()[0] = c0; 0230 outputVectorYCovariance->raw_V_ptr()[0] = cov00; 0231 0232 outputScalar->setValue(dSumSq / ( (double)iLength - 2.0 )); 0233 0234 bReturn = true; 0235 } 0236 } 0237 0238 postcursor( true, pInputs ); 0239 0240 return bReturn; 0241 } 0242 0243 0244 Kst::VectorPtr FitGradientWeightedSource::vectorX() const { 0245 return _inputVectors[VECTOR_IN_X]; 0246 } 0247 0248 0249 Kst::VectorPtr FitGradientWeightedSource::vectorY() const { 0250 return _inputVectors[VECTOR_IN_Y]; 0251 } 0252 0253 0254 Kst::VectorPtr FitGradientWeightedSource::vectorWeights() const { 0255 return _inputVectors[VECTOR_IN_WEIGHTS]; 0256 } 0257 0258 0259 QStringList FitGradientWeightedSource::inputVectorList() const { 0260 QStringList vectors(VECTOR_IN_X); 0261 vectors += VECTOR_IN_Y; 0262 vectors += VECTOR_IN_WEIGHTS; 0263 return vectors; 0264 } 0265 0266 0267 QStringList FitGradientWeightedSource::inputScalarList() const { 0268 return QStringList(); 0269 } 0270 0271 0272 QStringList FitGradientWeightedSource::inputStringList() const { 0273 return QStringList( /*STRING_IN*/ ); 0274 } 0275 0276 0277 QStringList FitGradientWeightedSource::outputVectorList() const { 0278 QStringList vectors(VECTOR_OUT_Y_FITTED); 0279 vectors += VECTOR_OUT_Y_RESIDUALS; 0280 vectors += VECTOR_OUT_Y_PARAMETERS; 0281 vectors += VECTOR_OUT_Y_COVARIANCE; 0282 vectors += VECTOR_OUT_Y_LO; 0283 vectors += VECTOR_OUT_Y_HI; 0284 vectors += VECTOR_OUT_Y_PARAMETERS; 0285 return vectors; 0286 } 0287 0288 0289 QStringList FitGradientWeightedSource::outputScalarList() const { 0290 return QStringList( SCALAR_OUT ); 0291 } 0292 0293 0294 QStringList FitGradientWeightedSource::outputStringList() const { 0295 return QStringList( /*STRING_OUT*/ ); 0296 } 0297 0298 0299 void FitGradientWeightedSource::saveProperties(QXmlStreamWriter &s) { 0300 Q_UNUSED(s); 0301 // s.writeAttribute("value", _configValue); 0302 } 0303 0304 0305 QString FitGradientWeightedSource::parameterName(int index) const { 0306 QString parameter; 0307 switch (index) { 0308 case 0: 0309 parameter = "Gradient"; 0310 break; 0311 } 0312 0313 return parameter; 0314 } 0315 0316 0317 // Name used to identify the plugin. Used when loading the plugin. 0318 QString FitGradientWeightedPlugin::pluginName() const { return tr("Gradient Weighted Fit"); } 0319 QString FitGradientWeightedPlugin::pluginDescription() const { return tr("Generates a gradient weighted fit for a set of data."); } 0320 0321 0322 Kst::DataObject *FitGradientWeightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { 0323 0324 if (ConfigWidgetFitGradientWeightedPlugin* config = static_cast<ConfigWidgetFitGradientWeightedPlugin*>(configWidget)) { 0325 0326 FitGradientWeightedSource* object = store->createObject<FitGradientWeightedSource>(); 0327 0328 if (setupInputsOutputs) { 0329 object->setupOutputs(); 0330 object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); 0331 object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); 0332 object->setInputVector(VECTOR_IN_WEIGHTS, config->selectedVectorWeights()); 0333 } 0334 0335 object->setPluginName(pluginName()); 0336 0337 object->writeLock(); 0338 object->registerChange(); 0339 object->unlock(); 0340 0341 return object; 0342 } 0343 return 0; 0344 } 0345 0346 0347 Kst::DataObjectConfigWidget *FitGradientWeightedPlugin::configWidget(QSettings *settingsObject) const { 0348 ConfigWidgetFitGradientWeightedPlugin *widget = new ConfigWidgetFitGradientWeightedPlugin(settingsObject); 0349 return widget; 0350 } 0351 0352 #ifndef QT5 0353 Q_EXPORT_PLUGIN2(kstplugin_FitGradientWeightedPlugin, FitGradientWeightedPlugin) 0354 #endif 0355 0356 // vim: ts=2 sw=2 et