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