File indexing completed on 2024-12-22 04:18:07
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 "statistics.h" 0017 #include "objectstore.h" 0018 #include "ui_statisticsconfig.h" 0019 0020 static const QString& VECTOR_IN = "Vector In"; 0021 static const QString& SCALAR_OUT_MEAN = "Mean"; 0022 static const QString& SCALAR_OUT_MINIMUM = "Minimum"; 0023 static const QString& SCALAR_OUT_MAXIMUM = "Maximum"; 0024 static const QString& SCALAR_OUT_VARIANCE = "Variance"; 0025 static const QString& SCALAR_OUT_STANDARD_DEVIATION = "Standard deviation"; 0026 static const QString& SCALAR_OUT_MEDIAN = "Median"; 0027 static const QString& SCALAR_OUT_ABSOLUTE_DEVIATION = "Absolute deviation"; 0028 static const QString& SCALAR_OUT_SKEWNESS = "Skewness"; 0029 static const QString& SCALAR_OUT_KURTOSIS = "Kurtosis"; 0030 0031 class ConfigWidgetStatisticsPlugin : public Kst::DataObjectConfigWidget, public Ui_StatisticsConfig { 0032 public: 0033 ConfigWidgetStatisticsPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_StatisticsConfig() { 0034 _store = 0; 0035 setupUi(this); 0036 } 0037 0038 ~ConfigWidgetStatisticsPlugin() {} 0039 0040 void setObjectStore(Kst::ObjectStore* store) { 0041 _store = store; 0042 _vector->setObjectStore(store); 0043 } 0044 0045 void setupSlots(QWidget* dialog) { 0046 if (dialog) { 0047 connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified())); 0048 } 0049 } 0050 0051 Kst::VectorPtr selectedVector() { return _vector->selectedVector(); }; 0052 void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); }; 0053 0054 virtual void setupFromObject(Kst::Object* dataObject) { 0055 if (StatisticsSource* source = static_cast<StatisticsSource*>(dataObject)) { 0056 setSelectedVector(source->vector()); 0057 } 0058 } 0059 0060 virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) { 0061 Q_UNUSED(store); 0062 Q_UNUSED(attrs); 0063 0064 bool validTag = true; 0065 0066 // QStringRef av; 0067 // av = attrs.value("value"); 0068 // if (!av.isNull()) { 0069 // _configValue = QVariant(av.toString()).toBool(); 0070 // } 0071 0072 return validTag; 0073 } 0074 0075 public slots: 0076 virtual void save() { 0077 if (_cfg) { 0078 _cfg->beginGroup("Statistics DataObject Plugin"); 0079 _cfg->setValue("Input Vector", _vector->selectedVector()->Name()); 0080 _cfg->endGroup(); 0081 } 0082 } 0083 0084 virtual void load() { 0085 if (_cfg && _store) { 0086 _cfg->beginGroup("Statistics DataObject Plugin"); 0087 QString vectorName = _cfg->value("Input Vector").toString(); 0088 Kst::Object* object = _store->retrieveObject(vectorName); 0089 Kst::Vector* vector = static_cast<Kst::Vector*>(object); 0090 if (vector) { 0091 setSelectedVector(vector); 0092 } 0093 _cfg->endGroup(); 0094 } 0095 } 0096 0097 private: 0098 Kst::ObjectStore *_store; 0099 0100 }; 0101 0102 0103 StatisticsSource::StatisticsSource(Kst::ObjectStore *store) 0104 : Kst::BasicPlugin(store) { 0105 } 0106 0107 0108 StatisticsSource::~StatisticsSource() { 0109 } 0110 0111 0112 QString StatisticsSource::_automaticDescriptiveName() const { 0113 return tr("%1 Statistics", "arg1 is a vector").arg(_inputVectors[VECTOR_IN]->descriptiveName()); 0114 } 0115 0116 0117 void StatisticsSource::change(Kst::DataObjectConfigWidget *configWidget) { 0118 if (ConfigWidgetStatisticsPlugin* config = static_cast<ConfigWidgetStatisticsPlugin*>(configWidget)) { 0119 setInputVector(VECTOR_IN, config->selectedVector()); 0120 } 0121 } 0122 0123 0124 void StatisticsSource::setupOutputs() { 0125 setOutputScalar(SCALAR_OUT_MEAN, ""); 0126 setOutputScalar(SCALAR_OUT_MINIMUM, ""); 0127 setOutputScalar(SCALAR_OUT_MAXIMUM, ""); 0128 setOutputScalar(SCALAR_OUT_VARIANCE, ""); 0129 setOutputScalar(SCALAR_OUT_STANDARD_DEVIATION, ""); 0130 setOutputScalar(SCALAR_OUT_MEDIAN, ""); 0131 setOutputScalar(SCALAR_OUT_ABSOLUTE_DEVIATION, ""); 0132 setOutputScalar(SCALAR_OUT_SKEWNESS, ""); 0133 setOutputScalar(SCALAR_OUT_KURTOSIS, ""); 0134 } 0135 0136 0137 bool StatisticsSource::algorithm() { 0138 Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN]; 0139 Kst::ScalarPtr outputScalarMean = _outputScalars[SCALAR_OUT_MEAN]; 0140 Kst::ScalarPtr outputScalarMin = _outputScalars[SCALAR_OUT_MINIMUM]; 0141 Kst::ScalarPtr outputScalarMax = _outputScalars[SCALAR_OUT_MAXIMUM]; 0142 Kst::ScalarPtr outputScalarVariance = _outputScalars[SCALAR_OUT_VARIANCE]; 0143 Kst::ScalarPtr outputScalarSD = _outputScalars[SCALAR_OUT_STANDARD_DEVIATION]; 0144 Kst::ScalarPtr outputScalarMedian = _outputScalars[SCALAR_OUT_MEDIAN]; 0145 Kst::ScalarPtr outputScalarAD = _outputScalars[SCALAR_OUT_ABSOLUTE_DEVIATION]; 0146 Kst::ScalarPtr outputScalarSkewness = _outputScalars[SCALAR_OUT_SKEWNESS]; 0147 Kst::ScalarPtr outputScalarKurtosis = _outputScalars[SCALAR_OUT_KURTOSIS]; 0148 0149 //Make sure there is at least 1 element in the input vector 0150 if (inputVector->length() < 1) { 0151 _errorString = tr("Error: Input Vector invalid size"); 0152 return false; 0153 } 0154 0155 double* pCopy; 0156 double dMean = 0.0; 0157 double dMedian = 0.0; 0158 double dStandardDeviation = 0.0; 0159 double dTotal = 0.0; 0160 double dSquaredTotal = 0.0; 0161 double dMinimum = 0.0; 0162 double dMaximum = 0.0; 0163 double dVariance = 0.0; 0164 double dAbsoluteDeviation = 0.0; 0165 double dSkewness = 0.0; 0166 double dKurtosis = 0.0; 0167 int iLength = inputVector->length(); 0168 0169 for (int i=0; i<iLength; i++) { 0170 if (i == 0 || inputVector->value()[i] < dMinimum) { 0171 dMinimum = inputVector->value()[i]; 0172 } 0173 if (i == 0 || inputVector->value()[i] > dMaximum) { 0174 dMaximum = inputVector->value()[i]; 0175 } 0176 dTotal += inputVector->value()[i]; 0177 dSquaredTotal += inputVector->value()[i] * inputVector->value()[i]; 0178 } 0179 0180 dMean = dTotal / (double)iLength; 0181 if (iLength > 1) { 0182 dVariance = 1.0 / ( (double)iLength - 1.0 ); 0183 dVariance *= dSquaredTotal - ( dTotal * dTotal / (double)iLength ); 0184 if (dVariance > 0.0) { 0185 dStandardDeviation = sqrt( dVariance ); 0186 } else { 0187 dVariance = 0.0; 0188 dStandardDeviation = 0.0; 0189 } 0190 } 0191 0192 for (int i=0; i<iLength; i++) { 0193 dAbsoluteDeviation += fabs( inputVector->value()[i] - dMean ); 0194 dSkewness += pow( inputVector->value()[i] - dMean, 3.0 ); 0195 dKurtosis += pow( inputVector->value()[i] - dMean, 4.0 ); 0196 } 0197 dAbsoluteDeviation /= (double)iLength; 0198 dSkewness /= (double)iLength * pow( dStandardDeviation, 3.0 ); 0199 dKurtosis /= (double)iLength * pow( dStandardDeviation, 4.0 ); 0200 dKurtosis -= 3.0; 0201 0202 /* 0203 sort by phase... 0204 */ 0205 pCopy = (double*)calloc( iLength, sizeof( double ) ); 0206 if (pCopy != NULL) { 0207 memcpy( pCopy, inputVector->value(), iLength * sizeof( double ) ); 0208 quicksort( pCopy, 0, iLength-1 ); 0209 dMedian = pCopy[ iLength / 2 ]; 0210 0211 free( pCopy ); 0212 } 0213 0214 outputScalarMean->setValue(dMean); 0215 outputScalarMin->setValue(dMinimum); 0216 outputScalarMax->setValue(dMaximum); 0217 outputScalarVariance->setValue(dVariance); 0218 outputScalarSD->setValue(dStandardDeviation); 0219 outputScalarMedian->setValue(dMedian); 0220 outputScalarAD->setValue(dAbsoluteDeviation); 0221 outputScalarSkewness->setValue(dSkewness); 0222 outputScalarKurtosis->setValue(dKurtosis); 0223 0224 return true; 0225 } 0226 0227 0228 void StatisticsSource::swap( double* pData, int iOne, int iTwo) { 0229 double dTemp; 0230 0231 dTemp = pData[iOne]; 0232 pData[iOne] = pData[iTwo]; 0233 pData[iTwo] = dTemp; 0234 } 0235 0236 0237 void StatisticsSource::quicksort( double* pData, int iLeft, int iRight) { 0238 0239 double dVal = pData[iRight]; 0240 int i = iLeft - 1; 0241 int j = iRight; 0242 0243 if (iRight <= iLeft) { 0244 return; 0245 } 0246 0247 while (1) { 0248 while (pData[++i] < dVal) { 0249 } 0250 0251 while(dVal < pData[--j]) { 0252 if (j == iLeft) { 0253 break; 0254 } 0255 } 0256 if (i >= j) { 0257 break; 0258 } 0259 swap( pData, i, j ); 0260 } 0261 swap( pData, i, iRight ); 0262 quicksort( pData, iLeft, i-1 ); 0263 quicksort( pData, i+1, iRight ); 0264 } 0265 0266 0267 Kst::VectorPtr StatisticsSource::vector() const { 0268 return _inputVectors[VECTOR_IN]; 0269 } 0270 0271 0272 QStringList StatisticsSource::inputVectorList() const { 0273 return QStringList( VECTOR_IN ); 0274 } 0275 0276 0277 QStringList StatisticsSource::inputScalarList() const { 0278 return QStringList( /*SCALAR_IN*/ ); 0279 } 0280 0281 0282 QStringList StatisticsSource::inputStringList() const { 0283 return QStringList( /*STRING_IN*/ ); 0284 } 0285 0286 0287 QStringList StatisticsSource::outputVectorList() const { 0288 return QStringList( /*VECTOR_OUT*/ ); 0289 } 0290 0291 0292 QStringList StatisticsSource::outputScalarList() const { 0293 QStringList scalars(SCALAR_OUT_MEAN); 0294 scalars += SCALAR_OUT_MINIMUM; 0295 scalars += SCALAR_OUT_MAXIMUM; 0296 scalars += SCALAR_OUT_VARIANCE; 0297 scalars += SCALAR_OUT_STANDARD_DEVIATION; 0298 scalars += SCALAR_OUT_MEDIAN; 0299 scalars += SCALAR_OUT_ABSOLUTE_DEVIATION; 0300 scalars += SCALAR_OUT_SKEWNESS; 0301 scalars += SCALAR_OUT_KURTOSIS; 0302 return scalars; 0303 } 0304 0305 0306 QStringList StatisticsSource::outputStringList() const { 0307 return QStringList( /*STRING_OUT*/ ); 0308 } 0309 0310 0311 void StatisticsSource::saveProperties(QXmlStreamWriter &s) { 0312 Q_UNUSED(s); 0313 // s.writeAttribute("value", _configValue); 0314 } 0315 0316 0317 QString StatisticsPlugin::pluginName() const { return tr("Statistics"); } 0318 QString StatisticsPlugin::pluginDescription() const { return tr("Determines statistics for a given inputVector set."); } 0319 0320 0321 Kst::DataObject *StatisticsPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const { 0322 0323 if (ConfigWidgetStatisticsPlugin* config = static_cast<ConfigWidgetStatisticsPlugin*>(configWidget)) { 0324 0325 StatisticsSource* object = store->createObject<StatisticsSource>(); 0326 0327 if (setupInputsOutputs) { 0328 object->setupOutputs(); 0329 object->setInputVector(VECTOR_IN, config->selectedVector()); 0330 } 0331 0332 object->setPluginName(pluginName()); 0333 0334 object->writeLock(); 0335 object->registerChange(); 0336 object->unlock(); 0337 0338 return object; 0339 } 0340 return 0; 0341 } 0342 0343 0344 Kst::DataObjectConfigWidget *StatisticsPlugin::configWidget(QSettings *settingsObject) const { 0345 ConfigWidgetStatisticsPlugin *widget = new ConfigWidgetStatisticsPlugin(settingsObject); 0346 return widget; 0347 } 0348 0349 #ifndef QT5 0350 Q_EXPORT_PLUGIN2(kstplugin_ChopPlugin, StatisticsPlugin) 0351 #endif 0352 0353 // vim: ts=2 sw=2 et