File indexing completed on 2025-01-12 04:09:50
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 "fitpolynomial_unweighted.h" 0017 #include "objectstore.h" 0018 #include "ui_fitpolynomial_unweightedconfig.h" 0019 0020 #include <gsl/gsl_fit.h> 0021 // #include "../common.h" 0022 #include "../linear.h" 0023 0024 static const QString& VECTOR_IN_X = "X Vector"; 0025 static const QString& VECTOR_IN_Y = "Y 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& SCALAR_IN = "Order Scalar"; 0031 static const QString& SCALAR_OUT = "chi^2/nu"; 0032 0033 class ConfigWidgetFitPolynomialUnweightedPlugin : public Kst::DataObjectConfigWidget, public Ui_FitPolynomial_UnweightedConfig { 0034 public: 0035 ConfigWidgetFitPolynomialUnweightedPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FitPolynomial_UnweightedConfig() { 0036 _store = 0; 0037 setupUi(this); 0038 } 0039 0040 ~ConfigWidgetFitPolynomialUnweightedPlugin() {} 0041 0042 void setObjectStore(Kst::ObjectStore* store) { 0043 _store = store; 0044 _vectorX->setObjectStore(store); 0045 _vectorY->setObjectStore(store); 0046 _scalarOrder->setObjectStore(store); 0047 _scalarOrder->setDefaultValue(2); 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(_scalarOrder, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); 0055 } 0056 } 0057 0058 void setVectorX(Kst::VectorPtr vector) { 0059 setSelectedVectorX(vector); 0060 } 0061 0062 void setVectorY(Kst::VectorPtr vector) { 0063 setSelectedVectorY(vector); 0064 } 0065 0066 void setVectorsLocked(bool locked = true) { 0067 _vectorX->setEnabled(!locked); 0068 _vectorY->setEnabled(!locked); 0069 } 0070 0071 Kst::VectorPtr selectedVectorX() { return _vectorX->selectedVector(); }; 0072 void setSelectedVectorX(Kst::VectorPtr vector) { return _vectorX->setSelectedVector(vector); }; 0073 0074 Kst::VectorPtr selectedVectorY() { return _vectorY->selectedVector(); }; 0075 void setSelectedVectorY(Kst::VectorPtr vector) { return _vectorY->setSelectedVector(vector); }; 0076 0077 Kst::ScalarPtr selectedScalarOrder() { return _scalarOrder->selectedScalar(); }; 0078 void setSelectedScalarOrder(Kst::ScalarPtr scalar) { return _scalarOrder->setSelectedScalar(scalar); }; 0079 0080 virtual void setupFromObject(Kst::Object* dataObject) { 0081 if (FitPolynomialUnweightedSource* source = static_cast<FitPolynomialUnweightedSource*>(dataObject)) { 0082 setSelectedVectorX(source->vectorX()); 0083 setSelectedVectorY(source->vectorY()); 0084 setSelectedScalarOrder(source->scalarOrder()); 0085 } 0086 } 0087 0088 virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { 0089 Q_UNUSED(store); 0090 Q_UNUSED(attrs); 0091 0092 bool validTag = true; 0093 0094 // QStringRef av; 0095 // av = attrs.value("value"); 0096 // if (!av.isNull()) { 0097 // _configValue = QVariant(av.toString()).toBool(); 0098 // } 0099 0100 return validTag; 0101 } 0102 0103 public slots: 0104 virtual void save() { 0105 if (_cfg) { 0106 _cfg->beginGroup("Fit Polynomial Plugin"); 0107 _cfg->setValue("Input Vector X", _vectorX->selectedVector()->Name()); 0108 _cfg->setValue("Input Vector Y", _vectorY->selectedVector()->Name()); 0109 _cfg->setValue("Input Scalar Order", _scalarOrder->selectedScalar()->Name()); 0110 _cfg->endGroup(); 0111 } 0112 } 0113 0114 virtual void load() { 0115 if (_cfg && _store) { 0116 _cfg->beginGroup("Fit Polynomial Plugin"); 0117 QString vectorName = _cfg->value("Input Vector X").toString(); 0118 Kst::Object* object = _store->retrieveObject(vectorName); 0119 Kst::Vector* vectorx = static_cast<Kst::Vector*>(object); 0120 if (vectorx) { 0121 setSelectedVectorX(vectorx); 0122 } 0123 vectorName = _cfg->value("Input Vector Y").toString(); 0124 object = _store->retrieveObject(vectorName); 0125 Kst::Vector* vectory = static_cast<Kst::Vector*>(object); 0126 if (vectory) { 0127 setSelectedVectorX(vectory); 0128 } 0129 QString scalarName = _cfg->value("Input Order Scalar").toString(); 0130 object = _store->retrieveObject(scalarName); 0131 Kst::Scalar* orderScalar = static_cast<Kst::Scalar*>(object); 0132 if (orderScalar) { 0133 setSelectedScalarOrder(orderScalar); 0134 } 0135 _cfg->endGroup(); 0136 } 0137 } 0138 0139 private: 0140 Kst::ObjectStore *_store; 0141 0142 }; 0143 0144 0145 FitPolynomialUnweightedSource::FitPolynomialUnweightedSource(Kst::ObjectStore *store) 0146 : Kst::BasicPlugin(store) { 0147 } 0148 0149 0150 FitPolynomialUnweightedSource::~FitPolynomialUnweightedSource() { 0151 } 0152 0153 0154 QString FitPolynomialUnweightedSource::_automaticDescriptiveName() const { 0155 return tr("%1 Polynomial").arg(vectorY()->descriptiveName());; 0156 } 0157 0158 0159 void FitPolynomialUnweightedSource::change(Kst::DataObjectConfigWidget *configWidget) { 0160 if (ConfigWidgetFitPolynomialUnweightedPlugin* config = static_cast<ConfigWidgetFitPolynomialUnweightedPlugin*>(configWidget)) { 0161 setInputVector(VECTOR_IN_X, config->selectedVectorX()); 0162 setInputVector(VECTOR_IN_Y, config->selectedVectorY()); 0163 setInputScalar(SCALAR_IN, config->selectedScalarOrder()); 0164 } 0165 } 0166 0167 0168 void FitPolynomialUnweightedSource::setupOutputs() { 0169 setOutputVector(VECTOR_OUT_Y_FITTED, ""); 0170 setOutputVector(VECTOR_OUT_Y_RESIDUALS, ""); 0171 setOutputVector(VECTOR_OUT_Y_PARAMETERS, ""); 0172 setOutputVector(VECTOR_OUT_Y_COVARIANCE, ""); 0173 setOutputScalar(SCALAR_OUT, ""); 0174 } 0175 0176 0177 double calculate_matrix_entry( double dX, int iPos ) { 0178 double dY; 0179 0180 dY = pow( dX, (double)iPos ); 0181 0182 return dY; 0183 } 0184 0185 0186 bool FitPolynomialUnweightedSource::algorithm() { 0187 Kst::VectorPtr inputVectorX = _inputVectors[VECTOR_IN_X]; 0188 Kst::VectorPtr inputVectorY = _inputVectors[VECTOR_IN_Y]; 0189 Kst::ScalarPtr inputScalarOrder = _inputScalars[SCALAR_IN]; 0190 0191 Kst::VectorPtr outputVectorYFitted = _outputVectors[VECTOR_OUT_Y_FITTED]; 0192 Kst::VectorPtr outputVectorYResiduals = _outputVectors[VECTOR_OUT_Y_RESIDUALS]; 0193 Kst::VectorPtr outputVectorYParameters = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; 0194 Kst::VectorPtr outputVectorYCovariance = _outputVectors[VECTOR_OUT_Y_COVARIANCE]; 0195 Kst::ScalarPtr outputScalar = _outputScalars[SCALAR_OUT]; 0196 0197 Kst::LabelInfo label_info = inputVectorY->labelInfo(); 0198 label_info.name = tr("Polynomial Fit to %1").arg(label_info.name); 0199 outputVectorYFitted->setLabelInfo(label_info); 0200 0201 label_info.name = tr("Polynomial Fit Residuals"); 0202 outputVectorYResiduals->setLabelInfo(label_info); 0203 0204 bool bReturn = false; 0205 0206 int iNumParams; 0207 0208 iNumParams = 1 + (int)floor( inputScalarOrder->value() ); 0209 if( iNumParams > 0 ) { 0210 bReturn = kstfit_linear_unweighted( inputVectorX, inputVectorY, 0211 outputVectorYFitted, outputVectorYResiduals, outputVectorYParameters, 0212 outputVectorYCovariance, outputScalar, iNumParams ); 0213 } 0214 0215 return bReturn; 0216 } 0217 0218 0219 // TODO merge with FitPolynomialWeightedSource 0220 QString FitPolynomialUnweightedSource::parameterVectorToString() const { 0221 0222 QString str = Name(); 0223 0224 if (hasParameterVector()) { 0225 Kst::VectorPtr vectorParam = _outputVectors[VECTOR_OUT_Y_PARAMETERS]; 0226 for (int i = 0; i < vectorParam->length(); i++) { 0227 QString paramName = parameterName(i); 0228 if (!paramName.isEmpty()) { 0229 if (_outputScalars.contains(paramName)) { 0230 QString name = _outputScalars[paramName]->Name(); 0231 double value = _outputScalars[paramName]->value(); 0232 QString sign(' '); 0233 if (value >= 0) { 0234 sign += '+'; 0235 } 0236 if (i == 0) { 0237 str += QString("\n[%1]").arg(name); 0238 } else if (i == 1) { // Special case x^1 to x 0239 str += QString("%1[%2]x").arg(sign).arg(name); 0240 } else { 0241 str += QString("%1[%2]%3").arg(sign).arg(name).arg(paramName); 0242 } 0243 } 0244 } 0245 } 0246 } 0247 0248 return str; 0249 } 0250 0251 0252 Kst::VectorPtr FitPolynomialUnweightedSource::vectorX() const { 0253 return _inputVectors[VECTOR_IN_X]; 0254 } 0255 0256 0257 Kst::VectorPtr FitPolynomialUnweightedSource::vectorY() const { 0258 return _inputVectors[VECTOR_IN_Y]; 0259 } 0260 0261 0262 Kst::ScalarPtr FitPolynomialUnweightedSource::scalarOrder() const { 0263 return _inputScalars[SCALAR_IN]; 0264 } 0265 0266 0267 QStringList FitPolynomialUnweightedSource::inputVectorList() const { 0268 QStringList vectors(VECTOR_IN_X); 0269 vectors += VECTOR_IN_Y; 0270 return vectors; 0271 } 0272 0273 0274 QStringList FitPolynomialUnweightedSource::inputScalarList() const { 0275 return QStringList(SCALAR_IN); 0276 } 0277 0278 0279 QStringList FitPolynomialUnweightedSource::inputStringList() const { 0280 return QStringList( /*STRING_IN*/ ); 0281 } 0282 0283 0284 QStringList FitPolynomialUnweightedSource::outputVectorList() const { 0285 QStringList vectors(VECTOR_OUT_Y_FITTED); 0286 vectors += VECTOR_OUT_Y_RESIDUALS; 0287 vectors += VECTOR_OUT_Y_PARAMETERS; 0288 vectors += VECTOR_OUT_Y_COVARIANCE; 0289 vectors += VECTOR_OUT_Y_PARAMETERS; 0290 return vectors; 0291 } 0292 0293 0294 QStringList FitPolynomialUnweightedSource::outputScalarList() const { 0295 return QStringList( SCALAR_OUT ); 0296 } 0297 0298 0299 QStringList FitPolynomialUnweightedSource::outputStringList() const { 0300 return QStringList( /*STRING_OUT*/ ); 0301 } 0302 0303 0304 void FitPolynomialUnweightedSource::saveProperties(QXmlStreamWriter &s) { 0305 Q_UNUSED(s); 0306 // s.writeAttribute("value", _configValue); 0307 } 0308 0309 0310 QString FitPolynomialUnweightedSource::parameterName(int index) const { 0311 return QString("x^%1").arg(index); 0312 } 0313 0314 0315 // Name used to identify the plugin. Used when loading the plugin. 0316 QString FitPolynomialUnweightedPlugin::pluginName() const { return tr("Polynomial Fit"); } 0317 QString FitPolynomialUnweightedPlugin::pluginDescription() const { return tr("Generates a polynomial fit for a set of data."); } 0318 0319 0320 Kst::DataObject *FitPolynomialUnweightedPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { 0321 0322 if (ConfigWidgetFitPolynomialUnweightedPlugin* config = static_cast<ConfigWidgetFitPolynomialUnweightedPlugin*>(configWidget)) { 0323 0324 Kst::ScalarPtr order; 0325 0326 // access/create scalars before creating plugin 0327 // in order to preserve continuous scalar shortnames 0328 if (setupInputsOutputs) { 0329 order = config->selectedScalarOrder(); 0330 } 0331 0332 FitPolynomialUnweightedSource* object = store->createObject<FitPolynomialUnweightedSource>(); 0333 0334 if (setupInputsOutputs) { 0335 object->setInputScalar(SCALAR_IN, order); 0336 object->setupOutputs(); 0337 object->setInputVector(VECTOR_IN_X, config->selectedVectorX()); 0338 object->setInputVector(VECTOR_IN_Y, config->selectedVectorY()); 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 *FitPolynomialUnweightedPlugin::configWidget(QSettings *settingsObject) const { 0354 ConfigWidgetFitPolynomialUnweightedPlugin *widget = new ConfigWidgetFitPolynomialUnweightedPlugin(settingsObject); 0355 return widget; 0356 } 0357 0358 #ifndef QT5 0359 Q_EXPORT_PLUGIN2(kstplugin_FitPolynomialUnweightedPlugin, FitPolynomialUnweightedPlugin) 0360 #endif 0361 0362 // vim: ts=2 sw=2 et