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