From 4a50ada7bc9e03f65424ede1320179bfbb758c91 Mon Sep 17 00:00:00 2001 From: Olivier Langella <Olivier.Langella@moulon.inra.fr> Date: Fri, 7 Apr 2017 17:38:41 +0200 Subject: [PATCH] FDR computation OK --- src/core/identificationgroup.cpp | 52 +++++++++ src/core/identificationgroup.h | 7 ++ src/gui/project_view/project_view.ui | 146 ++++++++++++++++++++++++- src/gui/project_view/projectwindow.cpp | 29 ++++- src/gui/project_view/projectwindow.h | 2 + src/utils/proteinstore.cpp | 10 ++ src/utils/proteinstore.h | 5 + src/utils/types.h | 11 ++ 8 files changed, 254 insertions(+), 8 deletions(-) diff --git a/src/core/identificationgroup.cpp b/src/core/identificationgroup.cpp index a56976d9a..a2c3f253a 100644 --- a/src/core/identificationgroup.cpp +++ b/src/core/identificationgroup.cpp @@ -41,6 +41,58 @@ IdentificationGroup::~IdentificationGroup() } } + +unsigned int IdentificationGroup::countDecoyProtein(ValidationState state) const { + unsigned int i=0; + for (auto & p_protein_match : _protein_match_list) { + if (!p_protein_match->getProteinXtpSp().get()->isDecoy()) continue; + if (state == ValidationState::grouped) { + if (p_protein_match->isGrouped()) { + i++; + } + } + else if(state == ValidationState::valid) { + if (p_protein_match->isValid()) { + i++; + } + + } + else if (state == ValidationState::validAndChecked) { + if (p_protein_match->isValidAndChecked()) { + i++; + } + + } + } + return i; +} + +unsigned int IdentificationGroup::countProtein(ValidationState state) const { + unsigned int i=0; + if (state == ValidationState::grouped) { + for (auto & p_protein_match : _protein_match_list) { + if (p_protein_match->isGrouped()) { + i++; + } + } + } + else if(state == ValidationState::valid) { + for (auto & p_protein_match : _protein_match_list) { + if (p_protein_match->isValid()) { + i++; + } + } + } + else if (state == ValidationState::validAndChecked) { + for (auto & p_protein_match : _protein_match_list) { + if (p_protein_match->isValidAndChecked()) { + i++; + } + } + } + return i; +} + void IdentificationGroup::updateAutomaticFilters(const AutomaticFilterParameters & automatic_filter_parameters) { for (auto & p_protein_match : _protein_match_list) { p_protein_match->updateAutomaticFilters(automatic_filter_parameters); diff --git a/src/core/identificationgroup.h b/src/core/identificationgroup.h index 27986627f..767f8cc25 100644 --- a/src/core/identificationgroup.h +++ b/src/core/identificationgroup.h @@ -68,6 +68,13 @@ public: /** @brief count subgroups * */ std::size_t countSubGroup()const; + + /** @brief count proteins + * */ + unsigned int countProtein(ValidationState state) const; + /** @brief count decoy proteins + * */ + unsigned int countDecoyProtein(ValidationState state) const; /** @brief validate or invalidate peptides and proteins based automatic filters and manual checks diff --git a/src/gui/project_view/project_view.ui b/src/gui/project_view/project_view.ui index c2a73be55..eaad0707a 100644 --- a/src/gui/project_view/project_view.ui +++ b/src/gui/project_view/project_view.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>445</width> - <height>392</height> + <width>465</width> + <height>493</height> </rect> </property> <property name="windowTitle"> @@ -53,7 +53,121 @@ </attribute> <layout class="QGridLayout" name="gridLayout2"> <item row="0" column="0"> - <layout class="QFormLayout" name="formLayout_2"/> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QGroupBox" name="groupBox_3"> + <property name="title"> + <string>FDR</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>FDR on peptides</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="peptide_fdr_label"> + <property name="text"> + <string>0 %</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>FDR on proteins</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="protein_fdr_label"> + <property name="text"> + <string>0 %</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Decoy database files</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QListWidget" name="decoy_database_list_widget"/> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>add</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item row="1" column="0"> + <widget class="QGroupBox" name="groupBox_2"> + <property name="title"> + <string>Decoy protein regular expression</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QLineEdit" name="decoy_protein_regexp_line_edit"> + <property name="placeholderText"> + <string>.*\\|reversed$</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="3" column="0"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="pushButton_2"> + <property name="text"> + <string>OK</string> + </property> + </widget> + </item> + </layout> </item> </layout> </widget> @@ -76,13 +190,33 @@ <rect> <x>0</x> <y>0</y> - <width>445</width> - <height>23</height> + <width>465</width> + <height>25</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> - <connections/> + <connections> + <connection> + <sender>pushButton_2</sender> + <signal>clicked()</signal> + <receiver>ProjectView</receiver> + <slot>doFdrChanged()</slot> + <hints> + <hint type="sourcelabel"> + <x>403</x> + <y>329</y> + </hint> + <hint type="destinationlabel"> + <x>484</x> + <y>334</y> + </hint> + </hints> + </connection> + </connections> + <slots> + <slot>doFdrChanged()</slot> + </slots> </ui> diff --git a/src/gui/project_view/projectwindow.cpp b/src/gui/project_view/projectwindow.cpp index 551022b34..125b57b45 100644 --- a/src/gui/project_view/projectwindow.cpp +++ b/src/gui/project_view/projectwindow.cpp @@ -45,7 +45,7 @@ ProjectWindow::ProjectWindow(MainWindow *parent): _p_automatic_filter_widget = new AutomaticFilterWidget(this); ui->filter_parameter_layout->addWidget(_p_automatic_filter_widget); - + #if QT_VERSION >= 0x050000 // Qt5 code @@ -58,7 +58,7 @@ ProjectWindow::ProjectWindow(MainWindow *parent): // Qt4 code //connect (_protein_list_window, SIGNAL(proteinMatchClicked(ProteinMatch *)), this //,SLOT(doProteinMatchClicked(ProteinMatch *))); connect (_p_automatic_filter_widget, SIGNAL(automaticFilterParametersChanged(AutomaticFilterParameters)), this,SLOT(doAutomaticFilterParametersChanged(AutomaticFilterParameters))); - + #endif /* */ @@ -138,7 +138,29 @@ void ProjectWindow::refreshGroup(IdentificationGroup * p_ident_group) { qDebug() << "ProjectWindow::refreshGroup end"; } +void ProjectWindow::computeFdr() { + pappso::pappso_double total_prot=0; + pappso::pappso_double false_prot=0; + for (IdentificationGroup * identification_group : _project_sp.get()->getIdentificationGroupList()) { + total_prot += identification_group->countProtein(ValidationState::grouped); + false_prot += identification_group->countDecoyProtein(ValidationState::grouped); + } + ui->protein_fdr_label->setText(QString("%1 %").arg(false_prot/total_prot)); +} + +void ProjectWindow::doFdrChanged() { + qDebug() << "ProjectWindow::doFdrChanged begin "; + _project_sp.get()->getProteinStore().setRegexpDecoyPattern(ui->decoy_protein_regexp_line_edit->text()); + _project_sp.get()->updateAutomaticFilters(_project_sp.get()->getAutomaticFilterParameters()); + //re group + for (IdentificationGroup * identification_group : _project_sp.get()->getIdentificationGroupList()) { + doIdentificationGroupEdited(identification_group); + } + + computeFdr(); + qDebug() << "ProjectWindow::doFdrChanged end "; +} void ProjectWindow::doAutomaticFilterParametersChanged(AutomaticFilterParameters parameters) { qDebug() << "ProjectWindow::doAutomaticFilterParametersChanged begin "; _project_sp.get()->updateAutomaticFilters(parameters); @@ -312,5 +334,8 @@ void ProjectWindow::setProjectSp(ProjectSp project_sp) { _p_automatic_filter_widget->setAutomaticFilterParameters(params); //_protein_list_window->setIdentificationGroup(_project_sp.get()->getCurrentIdentificationGroupP()); //_protein_list_window->show(); + + ui->decoy_protein_regexp_line_edit->setText(_project_sp.get()->getProteinStore().getRegexpDecoy().pattern()); + computeFdr(); this->setEnabled(true); } diff --git a/src/gui/project_view/projectwindow.h b/src/gui/project_view/projectwindow.h index 6a47e2cb6..c9b140fdb 100644 --- a/src/gui/project_view/projectwindow.h +++ b/src/gui/project_view/projectwindow.h @@ -55,6 +55,7 @@ public slots: void doViewProteinList(IdentificationGroup* p_identification_group =nullptr); void setDefaultProteinListWindow(ProteinListWindow* p_protein_list_window); void doAutomaticFilterParametersChanged(AutomaticFilterParameters parameters); + void doFdrChanged(); // void setColor(const QColor &color); // void setShape(Shape shape); signals: @@ -67,6 +68,7 @@ protected : void doViewPeptideDetail(PeptideMatch * peptide_match); void doViewProteinDetail(ProteinMatch * protein_match); void doIdentificationGroupEdited(IdentificationGroup * p_identification_group); + void computeFdr(); private : void connectNewProteinListWindow(); diff --git a/src/utils/proteinstore.cpp b/src/utils/proteinstore.cpp index 7eab25a11..d2d95dc24 100644 --- a/src/utils/proteinstore.cpp +++ b/src/utils/proteinstore.cpp @@ -42,6 +42,16 @@ ProteinStore::~ProteinStore() { } +QRegExp ProteinStore::getRegexpDecoy() const { + return (_regexp_decoy); +} +void ProteinStore::setRegexpDecoyPattern(const QString & pattern) { + _regexp_decoy.setPattern(pattern); + + for (std::pair<const QString, ProteinXtpSp> & acc_protein :_map_accession_protein_list) { + setProteinInformations(acc_protein.second); + } +} ProteinXtpSp & ProteinStore::getInstance(ProteinXtpSp & peptide_in) { diff --git a/src/utils/proteinstore.h b/src/utils/proteinstore.h index 14d7f1945..93c755cea 100644 --- a/src/utils/proteinstore.h +++ b/src/utils/proteinstore.h @@ -33,6 +33,7 @@ #define PROTEINSTORE_H #include "../core/proteinxtp.h" +#include "types.h" #include <QString> #include <QRegExp> #include <map> @@ -44,6 +45,10 @@ public: ~ProteinStore(); ProteinXtpSp & getInstance(ProteinXtpSp & protein_in); + + void setRegexpDecoyPattern(const QString & pattern); + + QRegExp getRegexpDecoy() const; private : void setProteinInformations(ProteinXtpSp & protein_in); diff --git a/src/utils/types.h b/src/utils/types.h index 7a5be71be..e3cbf9b1c 100644 --- a/src/utils/types.h +++ b/src/utils/types.h @@ -46,6 +46,17 @@ enum class MzFormat { mzXML, ///< mzXML }; +/** \def ValidationState + * + */ + +enum class ValidationState { + valid, ///< valid : automatic filter validation passed + validAndChecked, ///< validAndChecked : automatic filter validation passed + manual checking + grouped, ///< grouped : automatic filter validation passed + manual checking + grouped +}; + + /** \def ProteinListColumn list of available fields to display in protein list * */ -- GitLab