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 /* shift a vector by an integer number of samples */
0017 
0018 #include "shift.h"
0019 #include "objectstore.h"
0020 #include "ui_shiftconfig.h"
0021 #include "math_kst.h"
0022 
0023 static const QString& VECTOR_IN = "Vector In";
0024 static const QString& SCALAR_IN = "dX";
0025 static const QString& VECTOR_OUT = "Shifted Vector";
0026 
0027 class ConfigWidgetShiftPlugin : public Kst::DataObjectConfigWidget, public Ui_ShiftConfig {
0028   public:
0029     ConfigWidgetShiftPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_ShiftConfig() {
0030       _store = 0;
0031       setupUi(this);
0032     }
0033 
0034     ~ConfigWidgetShiftPlugin() {}
0035 
0036     void setObjectStore(Kst::ObjectStore* store) { 
0037       _store = store; 
0038       _vector->setObjectStore(store); 
0039       _scalarShift->setObjectStore(store);
0040       _scalarShift->setDefaultValue(0);
0041     }
0042 
0043     void setupSlots(QWidget* dialog) {
0044       if (dialog) {
0045         connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
0046         connect(_scalarShift, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
0047       }
0048     }
0049 
0050     void setVectorX(Kst::VectorPtr vector) {
0051       setSelectedVector(vector);
0052     }
0053 
0054     void setVectorY(Kst::VectorPtr vector) {
0055       setSelectedVector(vector);
0056     }
0057 
0058     void setVectorsLocked(bool locked = true) {
0059       _vector->setEnabled(!locked);
0060     }
0061 
0062     Kst::VectorPtr selectedVector() { return _vector->selectedVector(); };
0063     void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); };
0064 
0065     Kst::ScalarPtr selectedScalar() { return _scalarShift->selectedScalar(); };
0066     void setSelectedScalar(Kst::ScalarPtr scalar) { return _scalarShift->setSelectedScalar(scalar); };
0067 
0068     virtual void setupFromObject(Kst::Object* dataObject) {
0069       if (ShiftSource* source = static_cast<ShiftSource*>(dataObject)) {
0070         setSelectedVector(source->vector());
0071         setSelectedScalar(source->scalar());
0072       }
0073     }
0074 
0075     virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) {
0076       Q_UNUSED(store);
0077       Q_UNUSED(attrs);
0078 
0079       bool validTag = true;
0080 
0081 //       QStringRef av;
0082 //       av = attrs.value("value");
0083 //       if (!av.isNull()) {
0084 //         _configValue = QVariant(av.toString()).toBool();
0085 //       }
0086 
0087       return validTag;
0088     }
0089 
0090   public slots:
0091     virtual void save() {
0092       if (_cfg) {
0093         _cfg->beginGroup("Shift DataObject Plugin");
0094         _cfg->setValue("Input Vector", _vector->selectedVector()->Name());
0095         _cfg->setValue("Input Scalar Shift", _scalarShift->selectedScalar()->Name());
0096         _cfg->endGroup();
0097       }
0098     }
0099 
0100     virtual void load() {
0101       if (_cfg && _store) {
0102         _cfg->beginGroup("Shift DataObject Plugin");
0103         QString vectorName = _cfg->value("Input Vector").toString();
0104         Kst::Object* object = _store->retrieveObject(vectorName);
0105         Kst::Vector* vector = static_cast<Kst::Vector*>(object);
0106         if (vector) {
0107           setSelectedVector(vector);
0108         }
0109         QString scalarName = _cfg->value("Input Scalar Shift").toString();
0110         object = _store->retrieveObject(scalarName);
0111         Kst::Scalar* scalar = static_cast<Kst::Scalar*>(object);
0112         if (scalar) {
0113           setSelectedScalar(scalar);
0114         }
0115         _cfg->endGroup();
0116       }
0117     }
0118 
0119   private:
0120     Kst::ObjectStore *_store;
0121 
0122 };
0123 
0124 
0125 ShiftSource::ShiftSource(Kst::ObjectStore *store)
0126 : Kst::BasicPlugin(store) {
0127 }
0128 
0129 
0130 ShiftSource::~ShiftSource() {
0131 }
0132 
0133 
0134 QString ShiftSource::_automaticDescriptiveName() const {
0135   return tr("Shift Plugin Object");
0136 }
0137 
0138 QString ShiftSource::descriptionTip() const {
0139   QString tip;
0140 
0141   tip = tr("Shift: %1\n  dX: %2\n", "Phase shift.  dX is the amount of the shift").arg(Name()).arg(scalar()->value());
0142 
0143   tip += tr("\nInput: %1").arg(vector()->descriptionTip());
0144   return tip;
0145 }
0146 
0147 
0148 void ShiftSource::change(Kst::DataObjectConfigWidget *configWidget) {
0149   if (ConfigWidgetShiftPlugin* config = static_cast<ConfigWidgetShiftPlugin*>(configWidget)) {
0150     setInputVector(VECTOR_IN, config->selectedVector());
0151     setInputScalar(SCALAR_IN, config->selectedScalar());
0152   }
0153 }
0154 
0155 
0156 void ShiftSource::setupOutputs() {
0157   setOutputVector(VECTOR_OUT, "");
0158 }
0159 
0160 
0161 bool ShiftSource::algorithm() {
0162   Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN];
0163   Kst::ScalarPtr inputScalar = _inputScalars[SCALAR_IN];
0164   Kst::VectorPtr outputVector = _outputVectors[VECTOR_OUT];
0165 
0166   int delay = 0;
0167 
0168   /* Memory allocation */
0169   outputVector->resize(inputVector->length(), false);
0170 
0171   delay = (int)inputScalar->value();
0172   /* Protect against invalid inputs */
0173   if (delay > inputVector->length()) {
0174     delay = inputVector->length();
0175   } else if (delay < -inputVector->length()) {
0176     delay = -inputVector->length();
0177   }
0178 
0179   /* First case: positive shift (forwards/right shift)*/
0180   if (delay >= 0) {
0181     /* Pad beginning with zeros */
0182     for (int i = 0; i < delay; i++) {
0183       outputVector->raw_V_ptr()[i] = NAN;
0184     }
0185     /* Then, copy values with the right offset */
0186     for (int i = delay; i < inputVector->length(); i++) {
0187       outputVector->raw_V_ptr()[i] = inputVector->raw_V_ptr()[i-delay];
0188     }
0189   }
0190 
0191   /* Second case: negative shift (backwards/left shift)*/
0192   else if (delay < 0) {
0193     delay = -delay; /* Easier to visualize :-) */
0194     /* Copy values with the right offset */
0195     for (int i = 0; i < inputVector->length()-delay; i++) {
0196       outputVector->raw_V_ptr()[i] = inputVector->raw_V_ptr()[i+delay];
0197     }
0198     /* Pad end with zeros */
0199     for (int i = inputVector->length()-delay; i < inputVector->length(); i++) {
0200       outputVector->raw_V_ptr()[i] = NAN;
0201     }
0202   }
0203   return true;
0204 }
0205 
0206 
0207 Kst::VectorPtr ShiftSource::vector() const {
0208   return _inputVectors[VECTOR_IN];
0209 }
0210 
0211 
0212 Kst::ScalarPtr ShiftSource::scalar() const {
0213   return _inputScalars[SCALAR_IN];
0214 }
0215 
0216 
0217 QStringList ShiftSource::inputVectorList() const {
0218   return QStringList( VECTOR_IN );
0219 }
0220 
0221 
0222 QStringList ShiftSource::inputScalarList() const {
0223   return QStringList( SCALAR_IN );
0224 }
0225 
0226 
0227 QStringList ShiftSource::inputStringList() const {
0228   return QStringList( /*STRING_IN*/ );
0229 }
0230 
0231 
0232 QStringList ShiftSource::outputVectorList() const {
0233   return QStringList( VECTOR_OUT );
0234 }
0235 
0236 
0237 QStringList ShiftSource::outputScalarList() const {
0238   return QStringList( /*SCALAR_OUT*/ );
0239 }
0240 
0241 
0242 QStringList ShiftSource::outputStringList() const {
0243   return QStringList( /*STRING_OUT*/ );
0244 }
0245 
0246 
0247 void ShiftSource::saveProperties(QXmlStreamWriter &s) {
0248   Q_UNUSED(s);
0249 //   s.writeAttribute("value", _configValue);
0250 }
0251 
0252 
0253 QString ShiftPlugin::pluginName() const { return tr("Shift"); }
0254 QString ShiftPlugin::pluginDescription() const { return tr("Shifts (and truncates) a vector."); }
0255 
0256 
0257 Kst::DataObject *ShiftPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const {
0258 
0259   if (ConfigWidgetShiftPlugin* config = static_cast<ConfigWidgetShiftPlugin*>(configWidget)) {
0260 
0261     ShiftSource* object = store->createObject<ShiftSource>();
0262 
0263     if (setupInputsOutputs) {
0264       object->setInputScalar(SCALAR_IN, config->selectedScalar());
0265       object->setupOutputs();
0266       object->setInputVector(VECTOR_IN, config->selectedVector());
0267     }
0268 
0269     object->setPluginName(pluginName());
0270 
0271     object->writeLock();
0272     object->registerChange();
0273     object->unlock();
0274 
0275     return object;
0276   }
0277   return 0;
0278 }
0279 
0280 
0281 Kst::DataObjectConfigWidget *ShiftPlugin::configWidget(QSettings *settingsObject) const {
0282   ConfigWidgetShiftPlugin *widget = new ConfigWidgetShiftPlugin(settingsObject);
0283   return widget;
0284 }
0285 
0286 #ifndef QT5
0287 Q_EXPORT_PLUGIN2(kstplugin_BinPlugin, ShiftPlugin)
0288 #endif
0289 
0290 // vim: ts=2 sw=2 et