diff --git a/src/backend/hypothesis_test/HypothesisTest.cpp b/src/backend/hypothesis_test/HypothesisTest.cpp index 2ad938f75..ee2fb117c 100644 --- a/src/backend/hypothesis_test/HypothesisTest.cpp +++ b/src/backend/hypothesis_test/HypothesisTest.cpp @@ -1,318 +1,318 @@ /*************************************************************************** File : HypothesisTest.cpp Project : LabPlot Description : Doing T-Test on data provided -------------------------------------------------------------------- Copyright : (C) 2019 Alexander Semke(alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "HypothesisTest.h" #include "HypothesisTestPrivate.h" #include "kdefrontend/hypothesis_test/HypothesisTestView.h" #include "backend/spreadsheet/Spreadsheet.h" #include "backend/core/column/Column.h" #include "backend/lib/macros.h" #include "QDebug" extern "C" { #include "backend/nsl/nsl_stats.h" } #include #include #include #include #include #include HypothesisTest::HypothesisTest(const QString &name) : AbstractPart(name), d(new HypothesisTestPrivate(this)) { } HypothesisTest::~HypothesisTest() { delete d; } QAbstractItemModel* HypothesisTest::dataModel() { return d->dataModel; } QAbstractItemModel* HypothesisTest::horizontalHeaderModel() { return d->horizontalHeaderModel; } void HypothesisTest::setDataSourceType(DataSourceType type) { if (type != d->dataSourceType) { d->dataSourceType = type; } } void HypothesisTest::setDataSourceSpreadsheet(Spreadsheet *spreadsheet) { if (spreadsheet != d->dataSourceSpreadsheet) d->setDataSourceSpreadsheet(spreadsheet); } QStringList HypothesisTest::allColumns() { return d->all_columns; } void HypothesisTest::setColumns(QVector cols) { d->m_columns = cols; } void HypothesisTest::setColumns(QStringList cols) { return d->setColumns(cols); } HypothesisTest::DataSourceType HypothesisTest::dataSourceType() const { return d->dataSourceType; } void HypothesisTest::performTwoSampleTTest() { d->performTwoSampleTTest(); } +QString HypothesisTest::testName() { + return d->m_currTestName; +} + /****************************************************************************** * Private Implementations * ****************************************************************************/ HypothesisTestPrivate::HypothesisTestPrivate(HypothesisTest* owner) : q(owner) , dataModel(new QStandardItemModel) , horizontalHeaderModel(new QStandardItemModel) { } HypothesisTestPrivate::~HypothesisTestPrivate() { } void HypothesisTestPrivate::setDataSourceSpreadsheet(Spreadsheet *spreadsheet) { dataSourceSpreadsheet = spreadsheet; //setting rows and columns count; m_rowCount = dataSourceSpreadsheet->rowCount(); m_columnCount = dataSourceSpreadsheet->columnCount(); for (auto* col : dataSourceSpreadsheet->children()) { all_columns << col->name(); } } void HypothesisTestPrivate::setColumns(QStringList cols) { m_columns.clear(); Column* column = new Column("column"); for (QString col : cols) { if (col != "") { column = dataSourceSpreadsheet->column(col); // qDebug() << "col is " << col; m_columns.append(column); } } } void HypothesisTestPrivate::performTwoSampleTTest() { dataModel->clear(); -// horizontalHeaderModel->clear(); + horizontalHeaderModel->clear(); + m_currTestName = i18n("Independent Two Sample T Test"); QMessageBox* msg_box = new QMessageBox(); // checking for cols; if (m_columns.size() != 2) { msg_box->setText(i18n("Inappropriate number of columns selected")); msg_box->exec(); return; } bool modeOk = true; bool allColumnsValid = true; for (int i = 0; i < 2; i++) { if(m_columns[i]->columnMode() == AbstractColumn::Numeric || m_columns[i]->columnMode() == AbstractColumn::Integer) continue; modeOk = false; } if(!allColumnsValid) { msg_box->setText(i18n("one of the selected columns is invalid")); msg_box->exec(); return; } if (!modeOk) { msg_box->setText(i18n("select only columns with numbers")); msg_box->exec(); return; } dataModel->setRowCount(1); dataModel->setColumnCount(3); horizontalHeaderModel->setColumnCount(3); int n[2]; double sum[2], mean[2], std[2]; for (int i = 0; i < 2; i++) { findStats(m_columns[i], n[i], sum[i], mean[i], std[i]); DEBUG("for " << i); DEBUG("n is "<setText(i18n("atleast one of selected column empty")); + msg_box->setText(i18n("atleast one of selected column is empty")); msg_box->exec(); return; } } int df = n[0] + n[1] - 2; //Assuming equal variance double sp = qSqrt( ((n[0]-1)*qPow(std[0],2) + (n[1]-1)*qPow(std[1],2))/df); QDEBUG("sp is " << sp); double t = (mean[0] - mean[1])/(sp*qSqrt(1.0/n[0] + 1.0/n[1])); // now finding p value from t value double p_value = nsl_stats_tdist_p(t, df); // QString text = i18n("T value for test is %1 and\n p value is %2",t, p_value); // msg_box->setText(text); // msg_box->exec(); //setting dataModel dataModel->setItem(0, 0, new QStandardItem(QString::number(t))); dataModel->setItem(0, 1, new QStandardItem(QString::number(df))); dataModel->setItem(0, 2, new QStandardItem(QString::number(p_value))); //setting horizontal header model horizontalHeaderModel->setHeaderData(0, Qt::Horizontal, "t value"); horizontalHeaderModel->setHeaderData(1, Qt::Horizontal, "dof"); horizontalHeaderModel->setHeaderData(2, Qt::Horizontal, "p value"); -// horizontalHeaderModel->setItem(0, 0, new QStandardItem("T Value")); -// horizontalHeaderModel->setItem(0, 1, new QStandardItem("dof")); -// horizontalHeaderModel->setItem(0, 2, new QStandardItem("P value")); + emit q->changed(); return; - -// double t_value = - } void HypothesisTestPrivate::findStats(Column* column, int &count, double &sum, double &mean, double &std) { sum = 0; mean = 0; std = 0; count = column->rowCount(); for (int i = 0; i < count; i++) { double row = column->valueAt(i); if ( std::isnan(row)) { count = i; break; } sum += row; } if (count < 1) return; mean = sum/count; for (int i = 0; i < count; i++) { double row = column->valueAt(i); std += qPow((row - mean),2); } if (count > 1) std = std / (count-1); std = qSqrt(std); return; } /********************************************************************************** * virtual functions implementations * ********************************************************************************/ /*! Saves as XML. */ void HypothesisTest::save(QXmlStreamWriter* writer) const { writer->writeStartElement("hypothesisTest"); writeBasicAttributes(writer); writeCommentElement(writer); //TODO: writer->writeEndElement(); } /*! Loads from XML. */ bool HypothesisTest::load(XmlStreamReader* reader, bool preview) { Q_UNUSED(preview); if (!readBasicAttributes(reader)) return false; //TODO: return !reader->hasError(); } Spreadsheet *HypothesisTest::dataSourceSpreadsheet() const { return d->dataSourceSpreadsheet; } bool HypothesisTest::exportView() const { return true; } bool HypothesisTest::printView() { return true; } bool HypothesisTest::printPreview() const { return true; } /*! Constructs a primary view on me. This method may be called multiple times during the life time of an Aspect, or it might not get called at all. Aspects must not depend on the existence of a view for their operation. */ QWidget* HypothesisTest::view() const { if (!m_partView) { m_view = new HypothesisTestView(const_cast(this)); m_partView = m_view; } return m_partView; } /*! Returns a new context menu. The caller takes ownership of the menu. */ QMenu* HypothesisTest::createContextMenu() { QMenu* menu = AbstractPart::createContextMenu(); // Q_ASSERT(menu); // emit requestProjectContextMenu(menu); return menu; } diff --git a/src/backend/hypothesis_test/HypothesisTest.h b/src/backend/hypothesis_test/HypothesisTest.h index eafa14a6b..f04056d57 100644 --- a/src/backend/hypothesis_test/HypothesisTest.h +++ b/src/backend/hypothesis_test/HypothesisTest.h @@ -1,90 +1,91 @@ /*************************************************************************** File : HypothesisTest.h Project : LabPlot Description : Doing T-Test on data provided -------------------------------------------------------------------- Copyright : (C) 2019 Alexander Semke(alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef HYPOTHESISTEST_H #define HYPOTHESISTEST_H #include #include "backend/core/AbstractPart.h" #include "backend/lib/macros.h" class HypothesisTestPrivate; class HypothesisTestView; class Spreadsheet; class QAbstractItemModel; class QString; class Column; class HypothesisTest : public AbstractPart { Q_OBJECT public: explicit HypothesisTest(const QString& name); ~HypothesisTest() override; enum DataSourceType {DataSourceSpreadsheet, DataSourceDatabase}; QAbstractItemModel* dataModel(); QAbstractItemModel *horizontalHeaderModel(); + QString testName(); void setDataSourceSpreadsheet(Spreadsheet* spreadsheet); void setColumns(QVector cols); void setColumns(QStringList cols); void performTwoSampleTTest(); DataSourceType dataSourceType() const; //virtual methods // QIcon icon() const override; QMenu* createContextMenu() override; QWidget* view() const override; bool exportView() const override; bool printView() override; bool printPreview() const override; void save(QXmlStreamWriter*) const override; bool load(XmlStreamReader*, bool preview) override; Spreadsheet* dataSourceSpreadsheet() const; void setDataSourceType(DataSourceType type); QStringList allColumns(); private: HypothesisTestPrivate* const d; mutable HypothesisTestView* m_view{nullptr}; friend class HypothesisTestPrivate; signals: void changed(); void requestProjectContextMenu(QMenu*); void dataSourceTypeChanged(HypothesisTest::DataSourceType); void dataSourceSpreadsheetChanged(Spreadsheet*); }; #endif // HypothesisTest_H diff --git a/src/backend/hypothesis_test/HypothesisTestPrivate.h b/src/backend/hypothesis_test/HypothesisTestPrivate.h index 8f413a212..3e8e4a4e5 100644 --- a/src/backend/hypothesis_test/HypothesisTestPrivate.h +++ b/src/backend/hypothesis_test/HypothesisTestPrivate.h @@ -1,67 +1,68 @@ /*************************************************************************** File : HypothesisTestPrivate.h Project : LabPlot Description : Private members of Hypothesis Test -------------------------------------------------------------------- Copyright : (C) 2019 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef HYPOTHESISTESTPRIVATE_H #define HYPOTHESISTESTPRIVATE_H #include class QStandardItemModel; class HypothesisTestPrivate { public: explicit HypothesisTestPrivate(HypothesisTest*); virtual ~HypothesisTestPrivate(); QString name() const; HypothesisTest* const q; HypothesisTest::DataSourceType dataSourceType{HypothesisTest::DataSourceSpreadsheet}; Spreadsheet* dataSourceSpreadsheet{nullptr}; void setDataSourceSpreadsheet(Spreadsheet* spreadsheet); void setColumns(QStringList cols); QVector m_columns; QStringList all_columns; QStandardItemModel* dataModel{nullptr}; QStandardItemModel* horizontalHeaderModel{nullptr}; bool m_dbCreated{false}; int m_rowCount{0}; int m_columnCount{0}; - + QString m_currTestName{"Result Table"}; + void performTwoSampleTTest(); private: void findStats(Column* column, int &count, double &sum, double &mean, double &std); // QMap m_members; }; #endif diff --git a/src/kdefrontend/hypothesis_test/HypothesisTestView.cpp b/src/kdefrontend/hypothesis_test/HypothesisTestView.cpp index b20c093ca..8c27f78da 100644 --- a/src/kdefrontend/hypothesis_test/HypothesisTestView.cpp +++ b/src/kdefrontend/hypothesis_test/HypothesisTestView.cpp @@ -1,197 +1,220 @@ /*************************************************************************** - File : PivotTableView.cpp + File : HypothesisTestView.cpp Project : LabPlot - Description : View class for PivotTable + Description : View class for Hypothesis Tests' Table -------------------------------------------------------------------- Copyright : (C) 2019 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "HypothesisTestView.h" #include "backend/hypothesis_test/HypothesisTest.h" #include "backend/lib/macros.h" #include "backend/lib/trace.h" #include #include +#include #include #include #include #include #include #include #include -#include +#include #include #include #include #include #include /*! \class HypothesisTestView \brief View class for Hypothesis Test \ingroup kdefrontend */ HypothesisTestView::HypothesisTestView(HypothesisTest* hypothesisTest) : QWidget(), m_hypothesisTest(hypothesisTest), m_tableView(new QTableView(this)), - m_horizontalHeaderView(new QHeaderView(Qt::Horizontal, m_tableView)) { + m_horizontalHeaderView(new QHeaderView(Qt::Horizontal, m_tableView)), + m_testName(new QLabel()) { + + //setting alignments and fonts of testname label; + m_testName->setText(m_hypothesisTest->testName()); +// m_testName->setAlignment(Qt::AlignCenter); + QFont font = m_testName->font(); + font.setPointSize(15); + m_testName->setFont(font); + + //setting properties for table view + m_tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); +// m_tableView->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + +// QHBoxLayout* tableLayout = new QHBoxLayout(m_tableView); +// m_tableView->setLayout(tableLayout); +// m_tableView->setLayout(Qt::ho) auto* layout = new QVBoxLayout(this); layout->setContentsMargins(0,0,0,0); + layout->addWidget(m_testName); + layout->addSpacing(5); layout->addWidget(m_tableView); +// layout->setAlignment(m_testName, Qt::AlignHCenter); +// layout->setAlignment(m_tableView, Qt::AlignJustify); + m_horizontalHeaderView->setVisible(true); m_horizontalHeaderView->setEnabled(true); m_horizontalHeaderView->setSectionsClickable(true); m_tableView->setSelectionMode(QAbstractItemView::ExtendedSelection); - + m_tableView->setHorizontalHeader(m_horizontalHeaderView); + m_tableView->verticalHeader()->setVisible(false); init(); } HypothesisTestView::~HypothesisTestView() = default; void HypothesisTestView::init() { initActions(); initMenus(); m_tableView->setModel(m_hypothesisTest->dataModel()); m_horizontalHeaderView->setModel(m_hypothesisTest->horizontalHeaderModel()); -// connect(m_hypothesisTest, &HypothesisTest::changed, this, &HypothesisTestView::changed); + connect(m_hypothesisTest, &HypothesisTest::changed, this, &HypothesisTestView::changed); } void HypothesisTestView::initActions() { } void HypothesisTestView::initMenus() { } void HypothesisTestView::connectActions() { } void HypothesisTestView::fillToolBar(QToolBar* toolBar) { Q_UNUSED(toolBar); } /*! * Populates the menu \c menu with the pivot table and pivot table view relevant actions. * The menu is used * - as the context menu in PivotTableView * - as the "pivot table menu" in the main menu-bar (called form MainWin) * - as a part of the pivot table context menu in project explorer */ void HypothesisTestView::createContextMenu(QMenu* menu) { Q_ASSERT(menu); } void HypothesisTestView::goToCell() { bool ok; int col = QInputDialog::getInt(nullptr, i18n("Go to Cell"), i18n("Enter column"), 1, 1, m_tableView->model()->columnCount(), 1, &ok); if (!ok) return; int row = QInputDialog::getInt(nullptr, i18n("Go to Cell"), i18n("Enter row"), 1, 1, m_tableView->model()->rowCount(), 1, &ok); if (!ok) return; goToCell(row-1, col-1); } void HypothesisTestView::goToCell(int row, int col) { QModelIndex index = m_tableView->model()->index(row, col); m_tableView->scrollTo(index); m_tableView->setCurrentIndex(index); } bool HypothesisTestView::exportView() { return true; } bool HypothesisTestView::printView() { QPrinter printer; auto* dlg = new QPrintDialog(&printer, this); dlg->setWindowTitle(i18nc("@title:window", "Print Spreadsheet")); bool ret; if ((ret = dlg->exec()) == QDialog::Accepted) { print(&printer); } delete dlg; return ret; } bool HypothesisTestView::printPreview() { QPrintPreviewDialog* dlg = new QPrintPreviewDialog(this); connect(dlg, &QPrintPreviewDialog::paintRequested, this, &HypothesisTestView::print); return dlg->exec(); } /*! prints the complete spreadsheet to \c printer. */ void HypothesisTestView::print(QPrinter* printer) const { WAIT_CURSOR; QPainter painter (printer); RESET_CURSOR; } void HypothesisTestView::changed() { - + m_testName->setText(m_hypothesisTest->testName()); } void HypothesisTestView::exportToFile(const QString& path, const bool exportHeader, const QString& separator, QLocale::Language language) const { Q_UNUSED(exportHeader); Q_UNUSED(separator); Q_UNUSED(language); QFile file(path); if (!file.open(QFile::WriteOnly | QFile::Truncate)) return; PERFTRACE("export pivot table to file"); } void HypothesisTestView::exportToLaTeX(const QString & path, const bool exportHeaders, const bool gridLines, const bool captions, const bool latexHeaders, const bool skipEmptyRows, const bool exportEntire) const { Q_UNUSED(exportHeaders); Q_UNUSED(gridLines); Q_UNUSED(captions); Q_UNUSED(latexHeaders); Q_UNUSED(skipEmptyRows); Q_UNUSED(exportEntire); QFile file(path); if (!file.open(QFile::WriteOnly | QFile::Truncate)) return; PERFTRACE("export pivot table to latex"); } diff --git a/src/kdefrontend/hypothesis_test/HypothesisTestView.h b/src/kdefrontend/hypothesis_test/HypothesisTestView.h index 653aad133..0f8c3e4cd 100644 --- a/src/kdefrontend/hypothesis_test/HypothesisTestView.h +++ b/src/kdefrontend/hypothesis_test/HypothesisTestView.h @@ -1,87 +1,89 @@ /*************************************************************************** File : PivotTableView.h Project : LabPlot Description : View class for PivotTable -------------------------------------------------------------------- Copyright : (C) 2019 by Alexander Semke (alexander.semke@web.de) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef HYPOTHESISTESTVIEW_H #define HYPOTHESISTESTVIEW_H #include #include "backend/core/AbstractColumn.h" #include "backend/lib/IntervalAttribute.h" class Column; class HypothesisTest; class HypothesisTestModel; class AbstractAspect; class QTableView; class QHeaderView; class QPrinter; class QMenu; class QToolBar; class QModelIndex; class QItemSelection; +class QLabel; class HypothesisTestView : public QWidget { Q_OBJECT public: explicit HypothesisTestView(HypothesisTest*); ~HypothesisTestView() override; bool exportView(); bool printView(); bool printPreview(); private: void init(); void initActions(); void initMenus(); void connectActions(); void exportToFile(const QString&, const bool, const QString&, QLocale::Language) const; void exportToLaTeX(const QString&, const bool exportHeaders, const bool gridLines, const bool captions, const bool latexHeaders, const bool skipEmptyRows,const bool exportEntire) const; HypothesisTest* m_hypothesisTest; QTableView* m_tableView; QHeaderView* m_horizontalHeaderView; + QLabel* m_testName; public slots: void createContextMenu(QMenu*); void fillToolBar(QToolBar*); void print(QPrinter*) const; void changed(); private slots: void goToCell(); void goToCell(int row, int col); }; #endif