File indexing completed on 2025-01-05 04:12:57

0001 /***************************************************************************
0002  *                                                                         *
0003  *   copyright : (C) 2016 C. Barth Netterfield
0004  *                   netterfield@astro.utoronto.ca                         *
0005  *   copyright : (C) 2007 The University of Toronto                        *
0006  *                   netterfield@astro.utoronto.ca                         *
0007  *   copyright : (C) 2005  University of British Columbia                  *
0008  *                   dscott@phas.ubc.ca                                    *
0009  *                                                                         *
0010  *   This program is free software; you can redistribute it and/or modify  *
0011  *   it under the terms of the GNU General Public License as published by  *
0012  *   the Free Software Foundation; either version 2 of the License, or     *
0013  *   (at your option) any later version.                                   *
0014  *                                                                         *
0015  ***************************************************************************/
0016 
0017 
0018 #include "filterflag.h"
0019 #include "objectstore.h"
0020 #include "ui_filterflagconfig.h"
0021 #include "math_kst.h"
0022 
0023 
0024 static const QString& VECTOR_IN = "Y Vector";
0025 static const QString& VECTOR_FLAG_IN = "Flag Vector";
0026 static const QString& VECTOR_OUT = "Y";
0027 
0028 class ConfigWidgetFilterFlagPlugin : public Kst::DataObjectConfigWidget, public Ui_FilterFlagConfig {
0029   public:
0030     ConfigWidgetFilterFlagPlugin(QSettings* cfg) : DataObjectConfigWidget(cfg), Ui_FilterFlagConfig() {
0031       _store = 0;
0032       setupUi(this);
0033     }
0034 
0035     ~ConfigWidgetFilterFlagPlugin() {}
0036 
0037     void setObjectStore(Kst::ObjectStore* store) {
0038       _store = store;
0039       _vector->setObjectStore(store);
0040       _flag->setObjectStore(store);
0041       _mask->setText("0xffff");
0042       _validIsZero->setChecked(true);
0043     }
0044 
0045     void setupSlots(QWidget* dialog) {
0046       if (dialog) {
0047         connect(_vector, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
0048         connect(_flag, SIGNAL(selectionChanged(QString)), dialog, SIGNAL(modified()));
0049         connect(_mask, SIGNAL(textChanged(QString)), dialog, SIGNAL(modified()));
0050         connect(_validIsZero, SIGNAL(clicked(bool)), dialog, SIGNAL(modified()));
0051       }
0052     }
0053 
0054     void setVectorX(Kst::VectorPtr vector) {
0055       setSelectedVector(vector);
0056     }
0057 
0058     void setVectorY(Kst::VectorPtr vector) {
0059       setSelectedVector(vector);
0060     }
0061 
0062     void setVectorsLocked(bool locked = true) {
0063       _vector->setEnabled(!locked);
0064     }
0065 
0066     Kst::VectorPtr selectedVector() { return _vector->selectedVector(); };
0067     void setSelectedVector(Kst::VectorPtr vector) { return _vector->setSelectedVector(vector); };
0068 
0069     Kst::VectorPtr selectedFlag() { return _flag->selectedVector(); };
0070     void setSelectedFlag(Kst::VectorPtr vector) { return _flag->setSelectedVector(vector); };
0071 
0072     unsigned long long mask() {bool ok; return _mask->text().toULongLong(&ok, 0);}
0073     void setMask(unsigned long long mask_in) {_mask->setText("0x" + QString::number( mask_in, 16 ));}
0074 
0075     bool validIsZero() {return _validIsZero->isChecked();}
0076     void setValidIsZero(bool valid_is_zero) { _validIsZero->setChecked(valid_is_zero);}
0077 
0078     virtual void setupFromObject(Kst::Object* dataObject) {
0079       if (FilterFlagSource* source = static_cast<FilterFlagSource*>(dataObject)) {
0080         setSelectedVector(source->vector());
0081         setSelectedFlag(source->flagVector());
0082         setMask(source->mask());
0083         setValidIsZero(source->validIsZero());
0084       }
0085     }
0086 
0087     virtual bool configurePropertiesFromXml(Kst::ObjectStore *store, QXmlStreamAttributes& attrs) {
0088       Q_UNUSED(store);
0089 
0090       bool validTag = true;
0091 
0092       QStringRef av;
0093       av = attrs.value("Mask");
0094       if (!av.isNull()) {
0095         _mask->setText(av.toString());
0096       } else {
0097         _mask->setText("0xffff");
0098       }
0099 
0100       av = attrs.value("ValidIsZero");
0101       if (!av.isNull()) {
0102         setValidIsZero(QVariant(av.toString()).toBool());
0103       } else {
0104         setValidIsZero(true);
0105       }
0106 
0107       return validTag;
0108     }
0109 
0110   public slots:
0111     virtual void save() {
0112       if (_cfg) {
0113         _cfg->beginGroup("Filter Flag Plugin");
0114         _cfg->setValue("Input Vector", _vector->selectedVector()->Name());
0115         _cfg->setValue("Flag Vector", _flag->selectedVector()->Name());
0116         _cfg->setValue("Mask", QString::number( mask(), 16 ));
0117         _cfg->setValue("ValidIsZero", validIsZero());
0118         _cfg->endGroup();
0119       }
0120     }
0121 
0122     virtual void load() {
0123       if (_cfg && _store) {
0124         _cfg->beginGroup("Filter Flag Plugin");
0125         QString vectorName = _cfg->value("Input Vector").toString();
0126         Kst::Object* object = _store->retrieveObject(vectorName);
0127         Kst::Vector* vector = static_cast<Kst::Vector*>(object);
0128         if (vector) {
0129           setSelectedVector(vector);
0130         }
0131 
0132         vectorName = _cfg->value("Flag Vector").toString();
0133         object = _store->retrieveObject(vectorName);
0134         vector = static_cast<Kst::Vector*>(object);
0135         if (vector) {
0136           _flag->setSelectedVector(vector);
0137         }
0138 
0139         bool ok;
0140         setMask(_cfg->value("Mask", "0xffff").toString().toULongLong(&ok, 0));
0141 
0142         setValidIsZero(_cfg->value("ValidIsZero", true).toBool());
0143 
0144         _cfg->endGroup();
0145       }
0146     }
0147 
0148   private:
0149     Kst::ObjectStore *_store;
0150 
0151 };
0152 
0153 
0154 FilterFlagSource::FilterFlagSource(Kst::ObjectStore *store)
0155 : Kst::BasicPlugin(store) {
0156 }
0157 
0158 
0159 FilterFlagSource::~FilterFlagSource() {
0160 }
0161 
0162 
0163 QString FilterFlagSource::_automaticDescriptiveName() const {
0164   if (vector()) {
0165     return tr("%1 Flagged", "arg 1 is the name of the vector which has been Flagged").arg(vector()->descriptiveName());
0166   } else {
0167     return tr("Flagged");
0168   }
0169 }
0170 
0171 
0172 QString FilterFlagSource::descriptionTip() const {
0173   QString tip;
0174 
0175   tip = tr("Flag Filter: %1\n  Flag: %2").arg(Name()).arg(flagVector()->Name());
0176 
0177   tip += tr("\nInput: %1").arg(vector()->descriptionTip());
0178   return tip;
0179 }
0180 
0181 void FilterFlagSource::change(Kst::DataObjectConfigWidget *configWidget) {
0182   if (ConfigWidgetFilterFlagPlugin* config = static_cast<ConfigWidgetFilterFlagPlugin*>(configWidget)) {
0183     setInputVector(VECTOR_IN, config->selectedVector());
0184     setInputVector(VECTOR_FLAG_IN, config->selectedFlag());
0185     _mask = config->mask();
0186     _validIsZero = config->validIsZero();
0187   }
0188 }
0189 
0190 
0191 void FilterFlagSource::setupOutputs() {
0192   setOutputVector(VECTOR_OUT, "");
0193 }
0194 
0195 
0196 bool FilterFlagSource::algorithm() {
0197   Kst::VectorPtr inputVector = _inputVectors[VECTOR_IN];
0198   Kst::VectorPtr flagVector = _inputVectors[VECTOR_FLAG_IN];
0199   Kst::VectorPtr outputVector;
0200   // maintain kst file compatibility if the output vector name is changed.
0201   if (_outputVectors.contains(VECTOR_OUT)) {
0202     outputVector = _outputVectors[VECTOR_OUT];
0203   } else {
0204     outputVector = _outputVectors.values().at(0);
0205   }
0206 
0207   int N = inputVector->length();
0208   int i;
0209   if (N < 1) {
0210     return false;
0211   }
0212 
0213   // resize the output array
0214   outputVector->resize(inputVector->length(), false);
0215 
0216   if (_validIsZero) {
0217     for (i=0; i<N; ++i) {
0218       if ((unsigned long)flagVector->value(i) & _mask) { // invalid if flag & mask != 0
0219         outputVector->raw_V_ptr()[i] = Kst::NOPOINT;
0220       } else {
0221         outputVector->raw_V_ptr()[i] = inputVector->value(i);
0222       }
0223     }
0224   } else { // valid is nonzero
0225     for (i=0; i<N; ++i) {
0226       if ((unsigned long)flagVector->value(i) & _mask) { // valid if flag & mask != 0
0227         outputVector->raw_V_ptr()[i] = inputVector->value(i);
0228       } else {
0229         outputVector->raw_V_ptr()[i] = Kst::NOPOINT;
0230       }
0231     }
0232   }
0233 
0234 
0235   Kst::LabelInfo label_info = inputVector->labelInfo();
0236   label_info.name = tr("Flagged %1").arg(label_info.name);
0237   outputVector->setLabelInfo(label_info);
0238 
0239   return true;
0240 }
0241 
0242 
0243 Kst::VectorPtr FilterFlagSource::vector() const {
0244   return _inputVectors[VECTOR_IN];
0245 }
0246 
0247 
0248 Kst::VectorPtr FilterFlagSource::flagVector() const {
0249   return _inputVectors[VECTOR_FLAG_IN];
0250 }
0251 
0252 
0253 QStringList FilterFlagSource::inputVectorList() const {
0254   QStringList input_vectors (VECTOR_IN);
0255   input_vectors += VECTOR_FLAG_IN;
0256 
0257   return input_vectors;
0258 }
0259 
0260 
0261 QStringList FilterFlagSource::inputScalarList() const {
0262   return QStringList(  );
0263 }
0264 
0265 
0266 QStringList FilterFlagSource::inputStringList() const {
0267   return QStringList( /*STRING_IN*/ );
0268 }
0269 
0270 
0271 QStringList FilterFlagSource::outputVectorList() const {
0272   return QStringList( VECTOR_OUT );
0273 }
0274 
0275 
0276 QStringList FilterFlagSource::outputScalarList() const {
0277   return QStringList( /*SCALAR_OUT*/ );
0278 }
0279 
0280 
0281 QStringList FilterFlagSource::outputStringList() const {
0282   return QStringList( /*STRING_OUT*/ );
0283 }
0284 
0285 void FilterFlagSource::setProperty(const QString &key, const QString &val) {
0286   if (key == "Mask") {
0287     bool ok;
0288     setMask(val.toLongLong(&ok, 0));
0289   } else if (key == "ValidIsZero") {
0290     if (val.toLower() == "true") {
0291       setValidIsZero(true);
0292     } else if (val.toLower() == "false") {
0293       setValidIsZero(false);
0294     }
0295   }
0296 }
0297 
0298 
0299 void FilterFlagSource::saveProperties(QXmlStreamWriter &s) {
0300   s.writeAttribute("Mask", "0x"+QString::number( mask(), 16 ));
0301   s.writeAttribute("ValidIsZero", QString::number(validIsZero()));
0302 }
0303 
0304 
0305 // Name used to identify the plugin.  Used when loading the plugin.
0306 QString FilterFlagPlugin::pluginName() const { return tr("Flag Filter"); }
0307 QString FilterFlagPlugin::pluginDescription() const { return tr("Outputs the input vector flagged NaN when flag is non-zero."); }
0308 
0309 
0310 Kst::DataObject *FilterFlagPlugin::create(Kst::ObjectStore *store, Kst::DataObjectConfigWidget *configWidget, bool setupInputsOutputs) const {
0311 
0312   if (ConfigWidgetFilterFlagPlugin* config = static_cast<ConfigWidgetFilterFlagPlugin*>(configWidget)) {
0313 
0314     FilterFlagSource* object = store->createObject<FilterFlagSource>();
0315 
0316     if (setupInputsOutputs) {
0317       object->setupOutputs();
0318       object->setInputVector(VECTOR_IN, config->selectedVector());
0319       object->setInputVector(VECTOR_FLAG_IN, config->selectedFlag());
0320     }
0321 
0322     object->setMask(config->mask());
0323     object->setValidIsZero(config->validIsZero());
0324 
0325     object->setPluginName(pluginName());
0326 
0327     object->writeLock();
0328     object->registerChange();
0329     object->unlock();
0330 
0331     return object;
0332   }
0333   return 0;
0334 }
0335 
0336 
0337 Kst::DataObjectConfigWidget *FilterFlagPlugin::configWidget(QSettings *settingsObject) const {
0338   ConfigWidgetFilterFlagPlugin *widget = new ConfigWidgetFilterFlagPlugin(settingsObject);
0339   return widget;
0340 }
0341 
0342 #ifndef QT5
0343 Q_EXPORT_PLUGIN2(kstplugin_FilterFlagPlugin, FilterFlagPlugin)
0344 #endif
0345 
0346 // vim: ts=2 sw=2 et